Merge branch 'master' into hyq-0427
This commit is contained in:
@@ -51,10 +51,14 @@ Kubernetes 文档的这一部分包含教程。每个教程展示了如何完成
|
||||
<!--
|
||||
## Configuration
|
||||
|
||||
* [Example: Configuring a Java Microservice](/docs/tutorials/configuration/configure-java-microservice/)
|
||||
|
||||
* [Configuring Redis Using a ConfigMap](/docs/tutorials/configuration/configure-redis-using-configmap/)
|
||||
-->
|
||||
## 配置
|
||||
|
||||
* [示例:配置 Java 微服务](/zh/docs/tutorials/configuration/configure-java-microservice/)
|
||||
|
||||
* [使用一个 ConfigMap 配置 Redis](/zh/docs/tutorials/configuration/configure-redis-using-configmap/)
|
||||
|
||||
<!--
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
---
|
||||
title: AppArmor
|
||||
title: 使用 AppArmor 限制容器对资源的访问
|
||||
content_type: tutorial
|
||||
weight: 10
|
||||
---
|
||||
<!-- ---
|
||||
reviewers:
|
||||
- stclair
|
||||
title: AppArmor
|
||||
title: Restrict a Container's Access to Resources with AppArmor
|
||||
content_type: tutorial
|
||||
weight: 10
|
||||
--- -->
|
||||
|
||||
<!-- overview -->
|
||||
@@ -17,11 +19,15 @@ content_type: tutorial
|
||||
<!-- AppArmor is a Linux kernel security module that supplements the standard Linux user and group based
|
||||
permissions to confine programs to a limited set of resources. AppArmor can be configured for any
|
||||
application to reduce its potential attack surface and provide greater in-depth defense. It is
|
||||
configured through profiles tuned to whitelist the access needed by a specific program or container,
|
||||
configured through profiles tuned to allow the access needed by a specific program or container,
|
||||
such as Linux capabilities, network access, file permissions, etc. Each profile can be run in either
|
||||
*enforcing* mode, which blocks access to disallowed resources, or *complain* mode, which only reports
|
||||
violations. -->
|
||||
Apparmor 是一个 Linux 内核安全模块,它补充了标准的基于 Linux 用户和组的安全模块将程序限制为有限资源集的权限。AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提供更加深入的防御。AppArmor 是通过配置文件进行配置的,这些配置文件被调整为报名单,列出了特定程序或者容器所需要的访问权限,如 Linux 功能、网络访问、文件权限等。每个配置文件都可以在*强制*模式(阻止访问不允许的资源)或*投诉*模式(仅报告冲突)下运行。
|
||||
Apparmor 是一个 Linux 内核安全模块,它补充了标准的基于 Linux 用户和组的安全模块将程序限制为有限资源集的权限。
|
||||
AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提供更加深入的防御。
|
||||
AppArmor 是通过配置文件进行配置的,这些配置文件被调整为允许特定程序或者容器访问,如 Linux 功能、网络访问、文件权限等。
|
||||
每个配置文件都可以在*强制(enforcing)*模式(阻止访问不允许的资源)或*投诉(complain)*模式
|
||||
(仅报告冲突)下运行。
|
||||
|
||||
|
||||
|
||||
@@ -244,9 +250,8 @@ k8s-apparmor-example-deny-write (enforce)
|
||||
<!-- *This example assumes you have already set up a cluster with AppArmor support.* -->
|
||||
*本例假设您已经使用 AppArmor 支持设置了一个集群。*
|
||||
|
||||
<!-- First, we need to load the profile we want to use onto our nodes. The profile we'll use simply
|
||||
denies all file writes: -->
|
||||
首先,我们需要将要使用的配置文件加载到节点上。我们将使用的配置文件仅拒绝所有文件写入:
|
||||
<!-- First, we need to load the profile we want to use onto our nodes. This profile denies all file writes: -->
|
||||
首先,我们需要将要使用的配置文件加载到节点上。配置文件拒绝所有文件写入:
|
||||
|
||||
```shell
|
||||
#include <tunables/global>
|
||||
@@ -259,9 +264,12 @@ profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
|
||||
```
|
||||
|
||||
<!-- Since we don't know where the Pod will be scheduled, we'll need to load the profile on all our
|
||||
nodes. For this example we'll just use SSH to install the profiles, but other approaches are
|
||||
discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles). -->
|
||||
由于我们不知道 Pod 将被安排在那里,我们需要在所有节点上加载配置文件。在本例中,我们将只使用 SSH 来安装概要文件,但是在[使用配置文件设置节点](#setting-up-nodes-with-profiles)中讨论了其他方法。
|
||||
nodes. For this example we'll use SSH to install the profiles, but other approaches are
|
||||
discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles).
|
||||
-->
|
||||
由于我们不知道 Pod 将被调度到哪里,我们需要在所有节点上加载配置文件。
|
||||
在本例中,我们将使用 SSH 来安装概要文件,但是在[使用配置文件设置节点](#setting-up-nodes-with-profiles)
|
||||
中讨论了其他方法。
|
||||
|
||||
```shell
|
||||
NODES=(
|
||||
@@ -403,9 +411,9 @@ Events:
|
||||
23s 23s 1 {kubelet e2e-test-stclair-node-pool-t1f5} Warning AppArmor Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded
|
||||
```
|
||||
|
||||
<!-- Note the pod status is Failed, with a helpful error message: `Pod Cannot enforce AppArmor: profile
|
||||
<!-- Note the pod status is Pending, with a helpful error message: `Pod Cannot enforce AppArmor: profile
|
||||
"k8s-apparmor-example-allow-write" is not loaded`. An event was also recorded with the same message. -->
|
||||
注意 pod 呈现失败状态,并且显示一条有用的错误信息:`Pod Cannot enforce AppArmor: profile
|
||||
注意 pod 呈现 Pending 状态,并且显示一条有用的错误信息:`Pod Cannot enforce AppArmor: profile
|
||||
"k8s-apparmor-example-allow-write" 未加载`。还用相同的消息记录了一个事件。
|
||||
|
||||
<!-- ## Administration -->
|
||||
|
||||
@@ -52,14 +52,14 @@ Kubernetes 允许你将加载到节点上的 seccomp 配置文件自动应用于
|
||||
<!--
|
||||
In order to complete all steps in this tutorial, you must install
|
||||
[kind](https://kind.sigs.k8s.io/docs/user/quick-start/) and
|
||||
[kubectl](/docs/tasks/tools/install-kubectl/). This tutorial will show examples
|
||||
[kubectl](/docs/tasks/tools/). This tutorial will show examples
|
||||
with both alpha (pre-v1.19) and generally available seccomp functionality, so
|
||||
make sure that your cluster is [configured
|
||||
correctly](https://kind.sigs.k8s.io/docs/user/quick-start/#setting-kubernetes-version)
|
||||
for the version you are using.
|
||||
-->
|
||||
为了完成本教程中的所有步骤,你必须安装 [kind](https://kind.sigs.k8s.io/docs/user/quick-start/)
|
||||
和 [kubectl](/zh/docs/tasks/tools/install-kubectl/)。本教程将显示同时具有 alpha(v1.19 之前的版本)
|
||||
和 [kubectl](/zh/docs/tasks/tools/)。本教程将显示同时具有 alpha(v1.19 之前的版本)
|
||||
和通常可用的 seccomp 功能的示例,因此请确保为所使用的版本[正确配置](https://kind.sigs.k8s.io/docs/user/quick-start/#setting-kubernetes-version)了集群。
|
||||
|
||||
<!-- steps -->
|
||||
@@ -91,8 +91,8 @@ into the cluster.
|
||||
|
||||
For simplicity, [kind](https://kind.sigs.k8s.io/) can be used to create a single
|
||||
node cluster with the seccomp profiles loaded. Kind runs Kubernetes in Docker,
|
||||
so each node of the cluster is actually just a container. This allows for files
|
||||
to be mounted in the filesystem of each container just as one might load files
|
||||
so each node of the cluster is a container. This allows for files
|
||||
to be mounted in the filesystem of each container similar to loading files
|
||||
onto a node.
|
||||
|
||||
Download the example above, and save it to a file named `kind.yaml`. Then create
|
||||
@@ -101,8 +101,8 @@ the cluster with the configuration.
|
||||
## 使用 Kind 创建一个本地 Kubernetes 集群
|
||||
|
||||
为简单起见,可以使用 [kind](https://kind.sigs.k8s.io/) 创建一个已经加载 seccomp 配置文件的单节点集群。
|
||||
Kind 在 Docker 中运行 Kubernetes,因此集群的每个节点实际上只是一个容器。这允许将文件挂载到每个容器的文件系统中,
|
||||
就像将文件挂载到节点上一样。
|
||||
Kind 在 Docker 中运行 Kubernetes,因此集群的每个节点都是一个容器。这允许将文件挂载到每个容器的文件系统中,
|
||||
类似于将文件挂载到节点上。
|
||||
|
||||
{{< codenew file="pods/security/seccomp/kind.yaml" >}}
|
||||
<br>
|
||||
|
||||
@@ -19,17 +19,13 @@ This page provides a real world example of how to configure Redis using a Config
|
||||
|
||||
|
||||
<!--
|
||||
* * Create a `kustomization.yaml` file containing:
|
||||
* a ConfigMap generator
|
||||
* a Pod resource config using the ConfigMap
|
||||
* Apply the directory by running `kubectl apply -k ./`
|
||||
* Create a ConfigMap with Redis configuration values
|
||||
* Create a Redis Pod that mounts and uses the created ConfigMap
|
||||
* Verify that the configuration was correctly applied.
|
||||
-->
|
||||
|
||||
* * 创建一个包含以下内容的 `kustomization.yaml` 文件:
|
||||
* 一个 ConfigMap 生成器
|
||||
* 一个使用 ConfigMap 的 Pod 资源配置
|
||||
* 使用 `kubectl apply -k ./` 应用整个路径的配置
|
||||
* 使用 Redis 配置的值创建一个 ConfigMap
|
||||
* 创建一个 Redis Pod,挂载并使用创建的 ConfigMap
|
||||
* 验证配置已经被正确应用。
|
||||
|
||||
|
||||
@@ -55,106 +51,312 @@ This page provides a real world example of how to configure Redis using a Config
|
||||
<!--
|
||||
## Real World Example: Configuring Redis using a ConfigMap
|
||||
|
||||
You can follow the steps below to configure a Redis cache using data stored in a ConfigMap.
|
||||
Follow the steps below to configure a Redis cache using data stored in a ConfigMap.
|
||||
|
||||
First create a `kustomization.yaml` containing a ConfigMap from the `redis-config` file:
|
||||
First create a ConfigMap with an empty configuration block:
|
||||
-->
|
||||
## 真实世界的案例:使用 ConfigMap 来配置 Redis
|
||||
|
||||
按照下面的步骤,您可以使用ConfigMap中的数据来配置Redis缓存。
|
||||
按照下面的步骤,使用 ConfigMap 中的数据来配置 Redis 缓存。
|
||||
|
||||
1. 根据`docs/user-guide/configmap/redis/redis-config`来创建一个ConfigMap:
|
||||
|
||||
|
||||
{{< codenew file="pods/config/redis-config" >}}
|
||||
首先创建一个配置模块为空的 ConfigMap:
|
||||
|
||||
```shell
|
||||
curl -OL https://k8s.io/examples/pods/config/redis-config
|
||||
|
||||
cat <<EOF >./kustomization.yaml
|
||||
configMapGenerator:
|
||||
- name: example-redis-config
|
||||
files:
|
||||
- redis-config
|
||||
cat <<EOF >./example-redis-config.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: example-redis-config
|
||||
data:
|
||||
redis-config: ""
|
||||
EOF
|
||||
```
|
||||
|
||||
<!--
|
||||
Add the pod resource config to the `kustomization.yaml`:
|
||||
Apply the ConfigMap created above, along with a Redis pod manifest:
|
||||
-->
|
||||
将 pod 的资源配置添加到 `kustomization.yaml` 文件中:
|
||||
应用上面创建的 ConfigMap 以及 Redis pod 清单:
|
||||
|
||||
```shell
|
||||
kubectl apply -f example-redis-config.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/pods/config/redis-pod.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
Examine the contents of the Redis pod manifest and note the following:
|
||||
|
||||
* A volume named `config` is created by `spec.volumes[1]`
|
||||
* The `key` and `path` under `spec.volumes[1].items[0]` exposes the `redis-config` key from the
|
||||
`example-redis-config` ConfigMap as a file named `redis.conf` on the `config` volume.
|
||||
* The `config` volume is then mounted at `/redis-master` by `spec.containers[0].volumeMounts[1]`.
|
||||
|
||||
This has the net effect of exposing the data in `data.redis-config` from the `example-redis-config`
|
||||
ConfigMap above as `/redis-master/redis.conf` inside the Pod.
|
||||
-->
|
||||
检查 Redis pod 清单的内容,并注意以下几点:
|
||||
|
||||
* 由 `spec.volumes[1]` 创建一个名为 `config` 的卷。
|
||||
* `spec.volumes[1].items[0]` 下的 `key` 和 `path` 会将来自 `example-redis-config`
|
||||
ConfigMap 中的 `redis-config` 密钥公开在 `config` 卷上一个名为 `redis-config` 的文件中。
|
||||
* 然后 `config` 卷被 `spec.containers[0].volumeMounts[1]` 挂载在 `/redis-master`。
|
||||
|
||||
这样做的最终效果是将上面 `example-redis-config` 配置中 `data.redis-config` 的数据作为 Pod 中的 `/redis-master/redis.conf` 公开。
|
||||
|
||||
{{< codenew file="pods/config/redis-pod.yaml" >}}
|
||||
|
||||
```shell
|
||||
curl -OL https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/pods/config/redis-pod.yaml
|
||||
<!--
|
||||
Examine the created objects:
|
||||
-->
|
||||
检查创建的对象:
|
||||
|
||||
cat <<EOF >>./kustomization.yaml
|
||||
resources:
|
||||
- redis-pod.yaml
|
||||
EOF
|
||||
```shell
|
||||
kubectl get pod/redis configmap/example-redis-config
|
||||
```
|
||||
|
||||
<!--
|
||||
Apply the kustomization directory to create both the ConfigMap and Pod objects:
|
||||
You should see the following output:
|
||||
-->
|
||||
应用整个 kustomization 文件夹以创建 ConfigMap 和 Pod 对象:
|
||||
你应该可以看到以下输出:
|
||||
|
||||
```shell
|
||||
kubectl apply -k .
|
||||
```
|
||||
|
||||
<!--
|
||||
Examine the created objects by
|
||||
-->
|
||||
使用以下命令检查创建的对象
|
||||
|
||||
```shell
|
||||
> kubectl get -k .
|
||||
NAME DATA AGE
|
||||
configmap/example-redis-config-dgh9dg555m 1 52s
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/redis 1/1 Running 0 52s
|
||||
pod/redis 1/1 Running 0 8s
|
||||
|
||||
NAME DATA AGE
|
||||
configmap/example-redis-config 1 14s
|
||||
```
|
||||
|
||||
<!--
|
||||
In the example, the config volume is mounted at `/redis-master`.
|
||||
It uses `path` to add the `redis-config` key to a file named `redis.conf`.
|
||||
The file path for the redis config, therefore, is `/redis-master/redis.conf`.
|
||||
This is where the image will look for the config file for the redis master.
|
||||
Recall that we left `redis-config` key in the `example-redis-config` ConfigMap blank:
|
||||
-->
|
||||
在示例中,配置卷挂载在 `/redis-master` 下。
|
||||
它使用 `path` 将 `redis-config` 密钥添加到名为 `redis.conf` 的文件中。
|
||||
因此,redis配置的文件路径为 `/redis-master/redis.conf`。
|
||||
这是镜像将在其中查找 redis master 的配置文件的位置。
|
||||
回顾一下,我们在 `example-redis-config` ConfigMap 保留了空的 `redis-config` 键:
|
||||
|
||||
```shell
|
||||
kubectl describe configmap/example-redis-config
|
||||
```
|
||||
|
||||
<!--
|
||||
Use `kubectl exec` to enter the pod and run the `redis-cli` tool to verify that
|
||||
the configuration was correctly applied:
|
||||
You should see an empty `redis-config` key:
|
||||
-->
|
||||
使用 `kubectl exec` 进入 pod 并运行 `redis-cli` 工具来验证配置已正确应用:
|
||||
你应该可以看到一个空的 `redis-config` 键:
|
||||
|
||||
```shell
|
||||
Name: example-redis-config
|
||||
Namespace: default
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
|
||||
Data
|
||||
====
|
||||
redis-config:
|
||||
```
|
||||
|
||||
<!--
|
||||
Use `kubectl exec` to enter the pod and run the `redis-cli` tool to check the current configuration:
|
||||
-->
|
||||
使用 `kubectl exec` 进入 pod,运行 `redis-cli` 工具检查当前配置:
|
||||
|
||||
```shell
|
||||
kubectl exec -it redis -- redis-cli
|
||||
```
|
||||
|
||||
<!--
|
||||
Check `maxmemory`:
|
||||
-->
|
||||
查看 `maxmemory`:
|
||||
|
||||
```shell
|
||||
127.0.0.1:6379> CONFIG GET maxmemory
|
||||
```
|
||||
|
||||
<!--
|
||||
It should show the default value of 0:
|
||||
-->
|
||||
它应该显示默认值 0:
|
||||
|
||||
```shell
|
||||
1) "maxmemory"
|
||||
2) "0"
|
||||
```
|
||||
|
||||
<!--
|
||||
Similarly, check `maxmemory-policy`:
|
||||
-->
|
||||
同样,查看 `maxmemory-policy`:
|
||||
|
||||
```shell
|
||||
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
||||
```
|
||||
|
||||
<!--
|
||||
Which should also yield its default value of `noeviction`:
|
||||
-->
|
||||
它也应该显示默认值 `noeviction`:
|
||||
|
||||
```shell
|
||||
1) "maxmemory-policy"
|
||||
2) "noeviction"
|
||||
```
|
||||
|
||||
<!--
|
||||
Now let's add some configuration values to the `example-redis-config` ConfigMap:
|
||||
-->
|
||||
现在,向 `example-redis-config` ConfigMap 添加一些配置:
|
||||
|
||||
{{< codenew file="pods/config/example-redis-config.yaml" >}}
|
||||
|
||||
<!--
|
||||
Apply the updated ConfigMap:
|
||||
-->
|
||||
应用更新的 ConfigMap:
|
||||
|
||||
```shell
|
||||
kubectl apply -f example-redis-config.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
Confirm that the ConfigMap was updated:
|
||||
-->
|
||||
确认 ConfigMap 已更新:
|
||||
|
||||
```shell
|
||||
kubectl describe configmap/example-redis-config
|
||||
```
|
||||
|
||||
<!--
|
||||
You should see the configuration values we just added:
|
||||
-->
|
||||
你应该可以看到我们刚刚添加的配置:
|
||||
|
||||
```shell
|
||||
Name: example-redis-config
|
||||
Namespace: default
|
||||
Labels: <none>
|
||||
Annotations: <none>
|
||||
|
||||
Data
|
||||
====
|
||||
redis-config:
|
||||
----
|
||||
maxmemory 2mb
|
||||
maxmemory-policy allkeys-lru
|
||||
```
|
||||
|
||||
<!--
|
||||
Check the Redis Pod again using `redis-cli` via `kubectl exec` to see if the configuration was applied:
|
||||
-->
|
||||
通过 `kubectl exec` 使用 `redis-cli` 再次检查 Redis Pod,查看是否已应用配置:
|
||||
|
||||
```shell
|
||||
kubectl exec -it redis -- redis-cli
|
||||
```
|
||||
|
||||
<!--
|
||||
Check `maxmemory`:
|
||||
-->
|
||||
查看 `maxmemory`:
|
||||
|
||||
```shell
|
||||
127.0.0.1:6379> CONFIG GET maxmemory
|
||||
```
|
||||
|
||||
<!--
|
||||
It remains at the default value of 0:
|
||||
-->
|
||||
它保持默认值 0:
|
||||
|
||||
```shell
|
||||
1) "maxmemory"
|
||||
2) "0"
|
||||
```
|
||||
|
||||
<!--
|
||||
Similarly, `maxmemory-policy` remains at the `noeviction` default setting:
|
||||
-->
|
||||
同样,`maxmemory-policy` 保留为默认设置 `noeviction`:
|
||||
|
||||
```shell
|
||||
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
||||
```
|
||||
|
||||
<!--
|
||||
Returns:
|
||||
-->
|
||||
返回:
|
||||
|
||||
```shell
|
||||
1) "maxmemory-policy"
|
||||
2) "noeviction"
|
||||
```
|
||||
|
||||
<!--
|
||||
The configuration values have not changed because the Pod needs to be restarted to grab updated
|
||||
values from associated ConfigMaps. Let's delete and recreate the Pod:
|
||||
-->
|
||||
配置值未更改,因为需要重新启动 Pod 才能从关联的 ConfigMap 中获取更新的值。
|
||||
让我们删除并重新创建 Pod:
|
||||
|
||||
```shell
|
||||
kubectl delete pod redis
|
||||
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/pods/config/redis-pod.yaml
|
||||
```
|
||||
|
||||
<!--
|
||||
Now re-check the configuration values one last time:
|
||||
-->
|
||||
现在,最后一次重新检查配置值:
|
||||
|
||||
```shell
|
||||
kubectl exec -it redis -- redis-cli
|
||||
```
|
||||
|
||||
<!--
|
||||
Check `maxmemory`:
|
||||
-->
|
||||
查看 `maxmemory`:
|
||||
|
||||
```shell
|
||||
127.0.0.1:6379> CONFIG GET maxmemory
|
||||
```
|
||||
|
||||
<!--
|
||||
It should now return the updated value of 2097152:
|
||||
-->
|
||||
现在,它应该返回更新后的值 2097152:
|
||||
|
||||
```shell
|
||||
1) "maxmemory"
|
||||
2) "2097152"
|
||||
```
|
||||
|
||||
<!--
|
||||
Similarly, `maxmemory-policy` has also been updated:
|
||||
-->
|
||||
同样,`maxmemory-policy` 也已更新:
|
||||
|
||||
```shell
|
||||
127.0.0.1:6379> CONFIG GET maxmemory-policy
|
||||
```
|
||||
|
||||
<!--
|
||||
It now reflects the desired value of `allkeys-lru`:
|
||||
-->
|
||||
现在它反映了期望值 `allkeys-lru`:
|
||||
|
||||
```shell
|
||||
1) "maxmemory-policy"
|
||||
2) "allkeys-lru"
|
||||
```
|
||||
|
||||
<!--
|
||||
Delete the created pod:
|
||||
Clean up your work by deleting the created resources:
|
||||
-->
|
||||
删除创建的 pod:
|
||||
删除创建的资源,清理你的工作:
|
||||
|
||||
```shell
|
||||
kubectl delete pod redis
|
||||
kubectl delete pod/redis configmap/example-redis-config
|
||||
```
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ This tutorial provides a container image that uses NGINX to echo back all the re
|
||||
<!--
|
||||
The `dashboard` command enables the dashboard add-on and opens the proxy in the default web browser. You can create Kubernetes resources on the dashboard such as Deployment and Service.
|
||||
|
||||
If you are running in an environment as root, see [Open Dashboard with URL](/docs/tutorials/hello-minikube#open-dashboard-with-url).
|
||||
If you are running in an environment as root, see [Open Dashboard with URL](#open-dashboard-with-url).
|
||||
|
||||
To stop the proxy, run `Ctrl+C` to exit the process. The dashboard remains running.
|
||||
-->
|
||||
@@ -120,7 +120,7 @@ To stop the proxy, run `Ctrl+C` to exit the process. The dashboard remains runni
|
||||
`dashboard` 命令启用仪表板插件,并在默认的 Web 浏览器中打开代理。你可以在仪表板上创建 Kubernetes 资源,例如 Deployment 和 Service。
|
||||
|
||||
如果你以 root 用户身份在环境中运行,
|
||||
请参见[使用 URL 打开仪表板](/zh/docs/tutorials/hello-minikube#open-dashboard-with-url)。
|
||||
请参见[使用 URL 打开仪表板](#open-dashboard-with-url)。
|
||||
|
||||
要停止代理,请运行 `Ctrl+C` 退出该进程。仪表板仍在运行中。
|
||||
{{< /note >}}
|
||||
@@ -273,9 +273,9 @@ Kubernetes [*Service*](/docs/concepts/services-networking/service/).
|
||||
如果你用 `kubectl expose` 暴露了其它的端口,客户端将不能访问其它端口。
|
||||
|
||||
<!--
|
||||
2. View the Service you just created:
|
||||
2. View the Service you created:
|
||||
-->
|
||||
2. 查看你刚刚创建的 Service:
|
||||
2. 查看你创建的 Service:
|
||||
|
||||
```shell
|
||||
kubectl get services
|
||||
@@ -391,9 +391,9 @@ Minikube 有一组内置的 {{< glossary_tooltip text="插件" term_id="addons"
|
||||
```
|
||||
|
||||
<!--
|
||||
3. View the Pod and Service you just created:
|
||||
3. View the Pod and Service you created:
|
||||
-->
|
||||
3. 查看刚才创建的 Pod 和 Service:
|
||||
3. 查看创建的 Pod 和 Service:
|
||||
|
||||
```shell
|
||||
kubectl get pod,svc -n kube-system
|
||||
|
||||
@@ -133,6 +133,8 @@ Headless Service and StatefulSet defined in `web.yaml`.
|
||||
|
||||
```shell
|
||||
kubectl apply -f web.yaml
|
||||
```
|
||||
```
|
||||
service/nginx created
|
||||
statefulset.apps/web created
|
||||
```
|
||||
@@ -148,10 +150,19 @@ The command above creates two Pods, each running an
|
||||
|
||||
```shell
|
||||
kubectl get service nginx
|
||||
```
|
||||
```
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
nginx ClusterIP None <none> 80/TCP 12s
|
||||
|
||||
```
|
||||
<!--
|
||||
...then get the `web` StatefulSet, to verify that both were created successfully:
|
||||
-->
|
||||
...然后获取 `web` StatefulSet,以验证两者均已成功创建:
|
||||
```shell
|
||||
kubectl get statefulset web
|
||||
```
|
||||
```
|
||||
NAME DESIRED CURRENT AGE
|
||||
web 2 1 20s
|
||||
```
|
||||
@@ -174,6 +185,8 @@ look like the example below.
|
||||
|
||||
```shell
|
||||
kubectl get pods -w -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 0/1 Pending 0 0s
|
||||
web-0 0/1 Pending 0 0s
|
||||
@@ -215,10 +228,11 @@ StatefulSet 中的 Pod 拥有一个唯一的顺序索引和稳定的网络身份
|
||||
|
||||
```shell
|
||||
kubectl get pods -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 1m
|
||||
web-1 1/1 Running 0 1m
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -247,7 +261,9 @@ Pod 的名称的形式为`<statefulset name>-<ordinal index>`。
|
||||
每个 Pod 都拥有一个基于其顺序索引的稳定的主机名。使用[`kubectl exec`](/zh/docs/reference/generated/kubectl/kubectl-commands/#exec)在每个 Pod 中执行`hostname`。
|
||||
|
||||
```shell
|
||||
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
|
||||
for i in 0 1; do kubectl exec "web-$i" -- sh -c 'hostname'; done
|
||||
```
|
||||
```
|
||||
web-0
|
||||
web-1
|
||||
```
|
||||
@@ -265,7 +281,20 @@ addresses.
|
||||
|
||||
```shell
|
||||
kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm
|
||||
```
|
||||
<!--
|
||||
which starts a new shell. In that new shell, run:
|
||||
-->
|
||||
这将启动一个新的 shell。在新 shell 中,运行:
|
||||
```shell
|
||||
# Run this in the dns-test container shell
|
||||
nslookup web-0.nginx
|
||||
```
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
```
|
||||
Server: 10.0.0.10
|
||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||
|
||||
@@ -306,6 +335,8 @@ the Pods in the StatefulSet.
|
||||
|
||||
```shell
|
||||
kubectl delete pod -l app=nginx
|
||||
```
|
||||
```
|
||||
pod "web-0" deleted
|
||||
pod "web-1" deleted
|
||||
```
|
||||
@@ -319,6 +350,8 @@ Running and Ready.
|
||||
|
||||
```shell
|
||||
kubectl get pod -w -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 0/1 ContainerCreating 0 0s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
@@ -338,11 +371,32 @@ DNS entries.
|
||||
|
||||
```shell
|
||||
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
|
||||
```
|
||||
```
|
||||
web-0
|
||||
web-1
|
||||
|
||||
```
|
||||
<!--
|
||||
then, run:
|
||||
-->
|
||||
然后,运行:
|
||||
```
|
||||
kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm /bin/sh
|
||||
```
|
||||
<!--
|
||||
which starts a new shell.
|
||||
In that new shell, run:
|
||||
-->
|
||||
这将启动一个新的 shell。在新 shell 中,运行:
|
||||
```shell
|
||||
# Run this in the dns-test container shell
|
||||
nslookup web-0.nginx
|
||||
```
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
```
|
||||
Server: 10.0.0.10
|
||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||
|
||||
@@ -401,6 +455,12 @@ Get the PersistentVolumeClaims for `web-0` and `web-1`.
|
||||
|
||||
```shell
|
||||
kubectl get pvc -l app=nginx
|
||||
```
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
```
|
||||
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
|
||||
www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 48s
|
||||
www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 48s
|
||||
@@ -430,31 +490,35 @@ StatefulSets `spec` 中的 `volumeMounts` 字段保证了 `/usr/share/nginx/html
|
||||
将 Pod 的主机名写入它们的`index.html`文件并验证 NGINX web 服务器使用该主机名提供服务。
|
||||
|
||||
```shell
|
||||
for i in 0 1; do kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html'; done
|
||||
for i in 0 1; do kubectl exec "web-$i" -- sh -c 'echo "$(hostname)" > /usr/share/nginx/html/index.html'; done
|
||||
|
||||
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
|
||||
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
|
||||
```
|
||||
```
|
||||
web-0
|
||||
web-1
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
<!--
|
||||
If you instead see 403 Forbidden responses for the above curl command,
|
||||
If you instead see **403 Forbidden** responses for the above curl command,
|
||||
you will need to fix the permissions of the directory mounted by the `volumeMounts`
|
||||
(due to a [bug when using hostPath volumes](https://github.com/kubernetes/kubernetes/issues/2630)) with:
|
||||
(due to a [bug when using hostPath volumes](https://github.com/kubernetes/kubernetes/issues/2630)),
|
||||
by running:
|
||||
-->
|
||||
|
||||
请注意,如果你看见上面的 curl 命令返回了 403 Forbidden 的响应,
|
||||
你需要像这样修复使用 `volumeMounts`(due to a [bug when using hostPath volumes](https://github.com/kubernetes/kubernetes/issues/2630))挂载的目录的权限:
|
||||
请注意,如果你看见上面的 curl 命令返回了 **403 Forbidden** 的响应,你需要像这样修复使用 `volumeMounts`
|
||||
(原因归咎于[使用 hostPath 卷时存在的缺陷](https://github.com/kubernetes/kubernetes/issues/2630))
|
||||
挂载的目录的权限
|
||||
运行:
|
||||
|
||||
`for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done`
|
||||
|
||||
```shell
|
||||
for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done
|
||||
```
|
||||
<!--
|
||||
before retrying the curl command above.
|
||||
before retrying the `curl` command above.
|
||||
-->
|
||||
|
||||
在你重新尝试上面的 curl 命令之前。
|
||||
在你重新尝试上面的 `curl` 命令之前。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
@@ -475,6 +539,8 @@ In a second terminal, delete all of the StatefulSet's Pods.
|
||||
|
||||
```shell
|
||||
kubectl delete pod -l app=nginx
|
||||
```
|
||||
```
|
||||
pod "web-0" deleted
|
||||
pod "web-1" deleted
|
||||
```
|
||||
@@ -487,6 +553,8 @@ for all of the Pods to transition to Running and Ready.
|
||||
|
||||
```shell
|
||||
kubectl get pod -w -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 0/1 ContainerCreating 0 0s
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
@@ -504,7 +572,9 @@ Verify the web servers continue to serve their hostnames.
|
||||
验证所有 web 服务器在继续使用它们的主机名提供服务。
|
||||
|
||||
```
|
||||
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
|
||||
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
|
||||
```
|
||||
```
|
||||
web-0
|
||||
web-1
|
||||
```
|
||||
@@ -555,6 +625,8 @@ to 5.-->
|
||||
|
||||
```shell
|
||||
kubectl scale sts web --replicas=5
|
||||
```
|
||||
```
|
||||
statefulset.apps/web scaled
|
||||
```
|
||||
<!--
|
||||
@@ -566,6 +638,8 @@ for the three additional Pods to transition to Running and Ready.
|
||||
|
||||
```shell
|
||||
kubectl get pods -w -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 2h
|
||||
web-1 1/1 Running 0 2h
|
||||
@@ -617,8 +691,9 @@ three replicas.
|
||||
|
||||
```shell
|
||||
kubectl patch sts web -p '{"spec":{"replicas":3}}'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -627,8 +702,10 @@ Wait for `web-4` and `web-3` to transition to Terminating.
|
||||
|
||||
等待 `web-4` 和 `web-3` 状态变为 Terminating。
|
||||
|
||||
```
|
||||
```shell
|
||||
kubectl get pods -w -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 3h
|
||||
web-1 1/1 Running 0 3h
|
||||
@@ -663,6 +740,8 @@ Get the StatefulSet's PersistentVolumeClaims.
|
||||
|
||||
```shell
|
||||
kubectl get pvc -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
|
||||
www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 13h
|
||||
www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 13h
|
||||
@@ -718,6 +797,8 @@ Patch `web` StatefulSet 来执行 `RollingUpdate` 更新策略。
|
||||
|
||||
```shell
|
||||
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
```
|
||||
<!--
|
||||
@@ -729,8 +810,9 @@ image again.
|
||||
|
||||
```shell
|
||||
kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.8"}]'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -741,6 +823,12 @@ In another terminal, watch the Pods in the StatefulSet.
|
||||
|
||||
```shell
|
||||
kubectl get po -l app=nginx -w
|
||||
```
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 7m
|
||||
web-1 1/1 Running 0 7m
|
||||
@@ -798,7 +886,9 @@ StatefulSet 里的 Pod 采用和序号相反的顺序更新。在更新下一个
|
||||
获取 Pod 来查看他们的容器镜像。
|
||||
|
||||
```shell
|
||||
for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
|
||||
for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
|
||||
```
|
||||
```
|
||||
k8s.gcr.io/nginx-slim:0.8
|
||||
k8s.gcr.io/nginx-slim:0.8
|
||||
k8s.gcr.io/nginx-slim:0.8
|
||||
@@ -836,6 +926,8 @@ Patch `web` StatefulSet 来对 `updateStrategy` 字段添加一个分区。
|
||||
|
||||
```shell
|
||||
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
```
|
||||
|
||||
@@ -847,6 +939,8 @@ Patch the StatefulSet again to change the container's image.
|
||||
|
||||
```shell
|
||||
kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"k8s.gcr.io/nginx-slim:0.7"}]'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
```
|
||||
|
||||
@@ -857,7 +951,9 @@ Delete a Pod in the StatefulSet.
|
||||
删除 StatefulSet 中的 Pod。
|
||||
|
||||
```shell
|
||||
kubectl delete po web-2
|
||||
kubectl delete pod web-2
|
||||
```
|
||||
```
|
||||
pod "web-2" deleted
|
||||
```
|
||||
|
||||
@@ -868,7 +964,9 @@ Wait for the Pod to be Running and Ready.
|
||||
等待 Pod 变成 Running 和 Ready。
|
||||
|
||||
```shell
|
||||
kubectl get po -lapp=nginx -w
|
||||
kubectl get pod -l app=nginx -w
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 4m
|
||||
web-1 1/1 Running 0 4m
|
||||
@@ -883,10 +981,10 @@ Get the Pod's container.
|
||||
获取 Pod 的容器。
|
||||
|
||||
```shell
|
||||
kubectl get po web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
|
||||
kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
|
||||
```
|
||||
```
|
||||
k8s.gcr.io/nginx-slim:0.8
|
||||
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -915,6 +1013,8 @@ Patch the StatefulSet to decrement the partition.
|
||||
|
||||
```shell
|
||||
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":2}}}}'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
```
|
||||
|
||||
@@ -925,7 +1025,9 @@ Wait for `web-2` to be Running and Ready.
|
||||
等待 `web-2` 变成 Running 和 Ready。
|
||||
|
||||
```shell
|
||||
kubectl get po -lapp=nginx -w
|
||||
kubectl get pod -l app=nginx -w
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 4m
|
||||
web-1 1/1 Running 0 4m
|
||||
@@ -940,7 +1042,9 @@ Get the Pod's container.
|
||||
获取 Pod 的容器。
|
||||
|
||||
```shell
|
||||
kubectl get po web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
|
||||
kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
|
||||
```
|
||||
```
|
||||
k8s.gcr.io/nginx-slim:0.7
|
||||
|
||||
```
|
||||
@@ -959,7 +1063,9 @@ Delete the `web-1` Pod.
|
||||
删除 `web-1` Pod。
|
||||
|
||||
```shell
|
||||
kubectl delete po web-1
|
||||
kubectl delete pod web-1
|
||||
```
|
||||
```
|
||||
pod "web-1" deleted
|
||||
```
|
||||
|
||||
@@ -970,7 +1076,13 @@ Wait for the `web-1` Pod to be Running and Ready.
|
||||
等待 `web-1` 变成 Running 和 Ready。
|
||||
|
||||
```shell
|
||||
kubectl get po -lapp=nginx -w
|
||||
kubectl get pod -l app=nginx -w
|
||||
```
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 6m
|
||||
web-1 0/1 Terminating 0 6m
|
||||
@@ -991,7 +1103,9 @@ Get the `web-1` Pods container.
|
||||
获取 `web-1` Pod 的容器。
|
||||
|
||||
```shell
|
||||
kubectl get po web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
|
||||
kubectl get pod web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
|
||||
```
|
||||
```
|
||||
k8s.gcr.io/nginx-slim:0.8
|
||||
```
|
||||
|
||||
@@ -1027,6 +1141,8 @@ The partition is currently set to `2`. Set the partition to `0`.
|
||||
|
||||
```shell
|
||||
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":0}}}}'
|
||||
```
|
||||
```
|
||||
statefulset.apps/web patched
|
||||
```
|
||||
|
||||
@@ -1037,7 +1153,13 @@ Wait for all of the Pods in the StatefulSet to become Running and Ready.
|
||||
等待 StatefulSet 中的所有 Pod 变成 Running 和 Ready。
|
||||
|
||||
```shell
|
||||
kubectl get po -lapp=nginx -w
|
||||
kubectl get pod -l app=nginx -w
|
||||
```
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 3m
|
||||
web-1 0/1 ContainerCreating 0 11s
|
||||
@@ -1061,11 +1183,12 @@ Get the Pod's containers.
|
||||
获取 Pod 的容器。
|
||||
|
||||
```shell
|
||||
for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
|
||||
for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
|
||||
```
|
||||
```
|
||||
k8s.gcr.io/nginx-slim:0.7
|
||||
k8s.gcr.io/nginx-slim:0.7
|
||||
k8s.gcr.io/nginx-slim:0.7
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -1126,6 +1249,8 @@ not delete any of its Pods.
|
||||
|
||||
```shell
|
||||
kubectl delete statefulset web --cascade=false
|
||||
```
|
||||
```
|
||||
statefulset.apps "web" deleted
|
||||
```
|
||||
|
||||
@@ -1137,6 +1262,8 @@ Get the Pods to examine their status.
|
||||
|
||||
```shell
|
||||
kubectl get pods -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 6m
|
||||
web-1 1/1 Running 0 7m
|
||||
@@ -1153,6 +1280,8 @@ Delete `web-0`.
|
||||
|
||||
```shell
|
||||
kubectl delete pod web-0
|
||||
```
|
||||
```
|
||||
pod "web-0" deleted
|
||||
```
|
||||
|
||||
@@ -1164,6 +1293,8 @@ Get the StatefulSet's Pods.
|
||||
|
||||
```shell
|
||||
kubectl get pods -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-1 1/1 Running 0 10m
|
||||
web-2 1/1 Running 0 7m
|
||||
@@ -1193,9 +1324,10 @@ an error indicating that the Service already exists.
|
||||
|
||||
```shell
|
||||
kubectl apply -f web.yaml
|
||||
```
|
||||
```
|
||||
statefulset.apps/web created
|
||||
service/nginx unchanged
|
||||
|
||||
```
|
||||
<!--
|
||||
Ignore the error. It only indicates that an attempt was made to create the nginx
|
||||
@@ -1211,6 +1343,8 @@ Examine the output of the `kubectl get` command running in the first terminal.
|
||||
|
||||
```shell
|
||||
kubectl get pods -w -l app=nginx
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-1 1/1 Running 0 16m
|
||||
web-2 1/1 Running 0 2m
|
||||
@@ -1228,24 +1362,28 @@ web-2 0/1 Terminating 0 3m
|
||||
<!--
|
||||
When the `web` StatefulSet was recreated, it first relaunched `web-0`.
|
||||
Since `web-1` was already Running and Ready, when `web-0` transitioned to
|
||||
Running and Ready, it simply adopted this Pod. Since you recreated the StatefulSet
|
||||
with `replicas` equal to 2, once `web-0` had been recreated, and once
|
||||
`web-1` had been determined to already be Running and Ready, `web-2` was
|
||||
terminated.
|
||||
Running and Ready, it adopted this Pod. Since you recreated the StatefulSet
|
||||
with `replicas` equal to 2, once `web-0` had been recreated, and once
|
||||
`web-1` had been determined to already be Running and Ready, `web-2` was
|
||||
terminated.
|
||||
|
||||
Let's take another look at the contents of the `index.html` file served by the
|
||||
Pods' webservers.
|
||||
Pods' webservers:
|
||||
-->
|
||||
|
||||
当重新创建 `web` StatefulSet 时,`web-0`被第一个重新启动。
|
||||
由于 `web-1` 已经处于 Running 和 Ready 状态,当 `web-0` 变成 Running 和 Ready 时,StatefulSet 会直接接收这个 Pod。
|
||||
由于你重新创建的 StatefulSet 的 `replicas` 等于 2,一旦 `web-0` 被重新创建并且 `web-1` 被认为已经处于 Running 和 Ready 状态时,`web-2`将会被终止。
|
||||
当重新创建 `web` StatefulSet 时,`web-0` 被第一个重新启动。
|
||||
由于 `web-1` 已经处于 Running 和 Ready 状态,当 `web-0` 变成 Running 和 Ready 时,
|
||||
StatefulSet 会接收这个 Pod。由于你重新创建的 StatefulSet 的 `replicas` 等于 2,
|
||||
一旦 `web-0` 被重新创建并且 `web-1` 被认为已经处于 Running 和 Ready 状态时,`web-2` 将会被终止。
|
||||
|
||||
|
||||
让我们再看看被 Pod 的 web 服务器加载的 `index.html` 的内容。
|
||||
让我们再看看被 Pod 的 web 服务器加载的 `index.html` 的内容:
|
||||
|
||||
```shell
|
||||
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
|
||||
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
|
||||
```
|
||||
|
||||
```
|
||||
web-0
|
||||
web-1
|
||||
```
|
||||
@@ -1276,11 +1414,17 @@ In one terminal window, watch the Pods in the StatefulSet.
|
||||
kubectl get pods -w -l app=nginx
|
||||
```
|
||||
|
||||
<!--
|
||||
In another terminal, delete the StatefulSet again. This time, omit the
|
||||
-->
|
||||
|
||||
在另一个窗口中再次删除这个 StatefulSet。这次省略 `--cascade=false` 参数。
|
||||
|
||||
```shell
|
||||
kubectl delete statefulset web
|
||||
```
|
||||
|
||||
```
|
||||
statefulset.apps "web" deleted
|
||||
```
|
||||
|
||||
@@ -1293,6 +1437,9 @@ and wait for all of the Pods to transition to Terminating.
|
||||
|
||||
```shell
|
||||
kubectl get pods -w -l app=nginx
|
||||
```
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 1/1 Running 0 11m
|
||||
web-1 1/1 Running 0 27m
|
||||
@@ -1327,6 +1474,9 @@ must delete the `nginx` Service manually.
|
||||
|
||||
```shell
|
||||
kubectl delete service nginx
|
||||
```
|
||||
|
||||
```
|
||||
service "nginx" deleted
|
||||
```
|
||||
|
||||
@@ -1338,9 +1488,11 @@ Recreate the StatefulSet and Headless Service one more time.
|
||||
|
||||
```shell
|
||||
kubectl apply -f web.yaml
|
||||
```
|
||||
|
||||
```
|
||||
service/nginx created
|
||||
statefulset.apps/web created
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -1351,7 +1503,10 @@ the contents of their `index.html` files.
|
||||
当 StatefulSet 所有的 Pod 变成 Running 和 Ready 时,获取它们的 `index.html` 文件的内容。
|
||||
|
||||
```shell
|
||||
for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
|
||||
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
|
||||
```
|
||||
|
||||
```
|
||||
web-0
|
||||
web-1
|
||||
```
|
||||
@@ -1372,13 +1527,17 @@ Finally delete the `web` StatefulSet and the `nginx` service.
|
||||
```shell
|
||||
kubectl delete service nginx
|
||||
```
|
||||
|
||||
```
|
||||
service "nginx" deleted
|
||||
```
|
||||
|
||||
... 并且删除 `web` StatefulSet:
|
||||
|
||||
```shell
|
||||
kubectl delete statefulset web
|
||||
```
|
||||
|
||||
```
|
||||
statefulset "web" deleted
|
||||
```
|
||||
@@ -1402,15 +1561,17 @@ above.
|
||||
`Parallel` pod management tells the StatefulSet controller to launch or
|
||||
terminate all Pods in parallel, and not to wait for Pods to become Running
|
||||
and Ready or completely terminated prior to launching or terminating another
|
||||
Pod.
|
||||
Pod. This option only affects the behavior for scaling operations. Updates are not affected.
|
||||
-->
|
||||
|
||||
## Pod 管理策略
|
||||
|
||||
|
||||
对于某些分布式系统来说,StatefulSet 的顺序性保证是不必要和/或者不应该的。这些系统仅仅要求唯一性和身份标志。
|
||||
为了解决这个问题,在 Kubernetes 1.7 中我们针对 StatefulSet API Object 引入了 `.spec.podManagementPolicy`。
|
||||
|
||||
对于某些分布式系统来说,StatefulSet 的顺序性保证是不必要和/或者不应该的。
|
||||
这些系统仅仅要求唯一性和身份标志。为了解决这个问题,在 Kubernetes 1.7 中
|
||||
我们针对 StatefulSet API 对象引入了 `.spec.podManagementPolicy`。
|
||||
此选项仅影响扩缩操作的行为。更新不受影响。
|
||||
|
||||
### OrderedReady Pod 管理策略
|
||||
|
||||
@@ -1421,7 +1582,8 @@ Pod.
|
||||
### Parallel Pod 管理策略
|
||||
|
||||
|
||||
`Parallel` pod 管理策略告诉 StatefulSet 控制器并行的终止所有 Pod,在启动或终止另一个 Pod 前,不必等待这些 Pod 变成 Running 和 Ready 或者完全终止状态。
|
||||
`Parallel` pod 管理策略告诉 StatefulSet 控制器并行的终止所有 Pod,
|
||||
在启动或终止另一个 Pod 前,不必等待这些 Pod 变成 Running 和 Ready 或者完全终止状态。
|
||||
|
||||
{{< codenew file="application/web/web-parallel.yaml" >}}
|
||||
|
||||
@@ -1447,16 +1609,17 @@ kubectl get po -lapp=nginx -w
|
||||
```
|
||||
|
||||
<!--
|
||||
In another terminal, create the StatefulSet and Service in the manifest.
|
||||
In another terminal, create the StatefulSet and Service in the manifest:
|
||||
-->
|
||||
|
||||
在另一个终端窗口创建清单中的 StatefulSet 和 Service。
|
||||
在另一个终端窗口创建清单中的 StatefulSet 和 Service:
|
||||
|
||||
```shell
|
||||
kubectl apply -f web-parallel.yaml
|
||||
```
|
||||
```
|
||||
service/nginx created
|
||||
statefulset.apps/web created
|
||||
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -1466,7 +1629,9 @@ Examine the output of the `kubectl get` command that you executed in the first t
|
||||
查看你在第一个终端中运行的 `kubectl get` 命令的输出。
|
||||
|
||||
```shell
|
||||
kubectl get po -lapp=nginx -w
|
||||
kubectl get pod -l app=nginx -w
|
||||
```
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-0 0/1 Pending 0 0s
|
||||
web-0 0/1 Pending 0 0s
|
||||
@@ -1491,6 +1656,8 @@ StatefulSet 控制器同时启动了 `web-0` 和 `web-1`。
|
||||
|
||||
```shell
|
||||
kubectl scale statefulset/web --replicas=4
|
||||
```
|
||||
```
|
||||
statefulset.apps/web scaled
|
||||
```
|
||||
|
||||
@@ -1500,7 +1667,7 @@ Examine the output of the terminal where the `kubectl get` command is running.
|
||||
|
||||
在 `kubectl get` 命令运行的终端里检查它的输出。
|
||||
|
||||
```shell
|
||||
```
|
||||
web-3 0/1 Pending 0 0s
|
||||
web-3 0/1 Pending 0 0s
|
||||
web-3 0/1 Pending 0 7s
|
||||
@@ -1510,27 +1677,36 @@ web-3 1/1 Running 0 26s
|
||||
```
|
||||
|
||||
<!--
|
||||
The StatefulSet controller launched two new Pods, and it did not wait for
|
||||
The StatefulSet launched two new Pods, and it did not wait for
|
||||
the first to become Running and Ready prior to launching the second.
|
||||
|
||||
Keep this terminal open, and in another terminal delete the `web` StatefulSet.
|
||||
## {{% heading "cleanup" %}}
|
||||
|
||||
You should have two terminals open, ready for you to run `kubectl` commands as
|
||||
part of cleanup.
|
||||
-->
|
||||
|
||||
StatefulSet 控制器启动了两个新的 Pod,而且在启动第二个之前并没有等待第一个变成 Running 和 Ready 状态。
|
||||
StatefulSet 启动了两个新的 Pod,而且在启动第二个之前并没有等待第一个变成 Running 和 Ready 状态。
|
||||
|
||||
保持这个终端打开,并在另一个终端删除 `web` StatefulSet。
|
||||
## {{% heading "cleanup" %}}
|
||||
|
||||
您应该打开两个终端,准备在清理过程中运行 `kubectl` 命令。
|
||||
|
||||
```shell
|
||||
kubectl delete sts web
|
||||
# sts is an abbreviation for statefulset
|
||||
```
|
||||
|
||||
<!--
|
||||
Again, examine the output of the `kubectl get` command running in the other terminal.
|
||||
You can watch `kubectl get` to see those Pods being deleted.
|
||||
-->
|
||||
|
||||
在另一个终端里再次检查 `kubectl get` 命令的输出。
|
||||
你可以监测 `kubectl get` 来查看那些 Pod 被删除
|
||||
|
||||
```shell
|
||||
kubectl get pod -l app=nginx -w
|
||||
```
|
||||
```
|
||||
web-3 1/1 Terminating 0 9m
|
||||
web-2 1/1 Terminating 0 9m
|
||||
web-3 1/1 Terminating 0 9m
|
||||
@@ -1579,10 +1755,12 @@ kubectl delete svc nginx
|
||||
|
||||
|
||||
<!--
|
||||
You will need to delete the persistent storage media for the PersistentVolumes
|
||||
used in this tutorial. Follow the necessary steps, based on your environment,
|
||||
storage configuration, and provisioning method, to ensure that all storage is
|
||||
reclaimed.
|
||||
You also need to delete the persistent storage media for the PersistentVolumes
|
||||
used in this tutorial.
|
||||
|
||||
|
||||
Follow the necessary steps, based on your environment, storage configuration,
|
||||
and provisioning method, to ensure that all storage is reclaimed.
|
||||
-->
|
||||
|
||||
你需要删除本教程中用到的 PersistentVolumes 的持久化存储介质。基于你的环境、存储配置和提供方式,按照必须的步骤保证回收所有的存储。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ external IP address.
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
<!--
|
||||
* Install [kubectl](/docs/tasks/tools/install-kubectl/).
|
||||
* Install [kubectl](/docs/tasks/tools/).
|
||||
* Use a cloud provider like Google Kubernetes Engine or Amazon Web Services to
|
||||
create a Kubernetes cluster. This tutorial creates an
|
||||
[external load balancer](/docs/tasks/access-application-cluster/create-external-load-balancer/),
|
||||
@@ -28,7 +28,7 @@ external IP address.
|
||||
* Configure `kubectl` to communicate with your Kubernetes API server. For instructions, see the
|
||||
documentation for your cloud provider.
|
||||
-->
|
||||
* 安装 [kubectl](/zh/docs/tasks/tools/install-kubectl/).
|
||||
* 安装 [kubectl](/zh/docs/tasks/tools/).
|
||||
* 使用 Google Kubernetes Engine 或 Amazon Web Services 等云供应商创建 Kubernetes 集群。
|
||||
本教程创建了一个[外部负载均衡器](/zh/docs/tasks/access-application-cluster/create-external-load-balancer/),
|
||||
需要云供应商。
|
||||
|
||||
@@ -100,16 +100,15 @@ The manifest file, included below, specifies a Deployment controller that runs a
|
||||
1. 在下载清单文件的目录中启动终端窗口。
|
||||
2. 从 `mongo-deployment.yaml` 文件中应用 MongoDB Deployment:
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/mongo-deployment.yaml
|
||||
-->
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/guestbook/mongo-deployment.yaml
|
||||
```
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/mongo-deployment.yaml
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
1. Query the list of Pods to verify that the MongoDB Pod is running:
|
||||
-->
|
||||
@@ -156,15 +155,15 @@ The guestbook application needs to communicate to the MongoDB to write its data.
|
||||
-->
|
||||
1. 使用下面的 `mongo-service.yaml` 文件创建 MongoDB 的服务:
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/mongo-service.yaml
|
||||
-->
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/guestbook/mongo-service.yaml
|
||||
```
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/mongo-service.yaml
|
||||
-->
|
||||
|
||||
<!--
|
||||
1. Query the list of Services to verify that the MongoDB Service is running:
|
||||
-->
|
||||
@@ -182,7 +181,7 @@ kubectl apply -f ./content/en/examples/application/guestbook/mongo-service.yaml
|
||||
```shell
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 1m
|
||||
mongo ClusterIP 10.0.0.151 <none> 6379/TCP 8s
|
||||
mongo ClusterIP 10.0.0.151 <none> 27017/TCP 8s
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -216,15 +215,15 @@ The guestbook application has a web frontend serving the HTTP requests written i
|
||||
-->
|
||||
1. 从 `frontend-deployment.yaml` 应用前端 Deployment 文件:
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/frontend-deployment.yaml
|
||||
-->
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
|
||||
```
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/frontend-deployment.yaml
|
||||
-->
|
||||
|
||||
<!--
|
||||
1. Query the list of Pods to verify that the three frontend replicas are running:
|
||||
-->
|
||||
@@ -253,10 +252,11 @@ kubectl apply -f ./content/en/examples/application/guestbook/frontend-deployment
|
||||
### 创建前端服务
|
||||
|
||||
<!--
|
||||
The `mongo` Services you applied is only accessible within the Kubernetes cluster because the default type for a Service is [ClusterIP](/docs/concepts/services-networking/service/#publishing-services---service-types). `ClusterIP` provides a single IP address for the set of Pods the Service is pointing to. This IP address is accessible only within the cluster.
|
||||
The `mongo` Services you applied is only accessible within the Kubernetes cluster because the default type for a Service is [ClusterIP](/docs/concepts/services-networking/service/#publishing-services-service-types). `ClusterIP` provides a single IP address for the set of Pods the Service is pointing to. This IP address is accessible only within the cluster.
|
||||
-->
|
||||
应用的 `mongo` 服务只能在 Kubernetes 集群中访问,因为服务的默认类型是
|
||||
[ClusterIP](/zh/docs/concepts/services-networking/service/#publishing-services---service-types)。`ClusterIP` 为服务指向的 Pod 集提供一个 IP 地址。这个 IP 地址只能在集群中访问。
|
||||
[ClusterIP](/zh/docs/concepts/services-networking/service/#publishing-services-service-types)。
|
||||
`ClusterIP` 为服务指向的 Pod 集提供一个 IP 地址。这个 IP 地址只能在集群中访问。
|
||||
|
||||
<!--
|
||||
If you want guests to be able to access your guestbook, you must configure the frontend Service to be externally visible, so a client can request the Service from outside the Kubernetes cluster. However a Kubernetes user you can use `kubectl port-forward` to access the service even though it uses a `ClusterIP`.
|
||||
@@ -278,15 +278,15 @@ Some cloud providers, like Google Compute Engine or Google Kubernetes Engine, su
|
||||
-->
|
||||
1. 从 `frontend-service.yaml` 文件中应用前端服务:
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/frontend-service.yaml
|
||||
-->
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
|
||||
```
|
||||
|
||||
<!---
|
||||
for local testing of the content via relative file path
|
||||
kubectl apply -f ./content/en/examples/application/guestbook/frontend-service.yaml
|
||||
-->
|
||||
|
||||
<!--
|
||||
1. Query the list of Services to verify that the frontend Service is running:
|
||||
-->
|
||||
@@ -303,7 +303,7 @@ kubectl apply -f ./content/en/examples/application/guestbook/frontend-service.ya
|
||||
|
||||
```
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
frontend ClusterIP 10.0.0.112 <none> 80/TCP 6s
|
||||
frontend ClusterIP 10.0.0.112 <none> 80/TCP 6s
|
||||
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 4m
|
||||
mongo ClusterIP 10.0.0.151 <none> 6379/TCP 2m
|
||||
```
|
||||
@@ -364,8 +364,8 @@ If you deployed the `frontend-service.yaml` manifest with type: `LoadBalancer` y
|
||||
响应应该与此类似:
|
||||
|
||||
```
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
frontend ClusterIP 10.51.242.136 109.197.92.229 80:32372/TCP 1m
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
frontend LoadBalancer 10.51.242.136 109.197.92.229 80:32372/TCP 1m
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -414,7 +414,7 @@ Scaling up or down is easy because your servers are defined as a Service that us
|
||||
frontend-3823415956-k22zn 1/1 Running 0 54m
|
||||
frontend-3823415956-w9gbt 1/1 Running 0 54m
|
||||
frontend-3823415956-x2pld 1/1 Running 0 5s
|
||||
mongo-1068406935-3lswp 1/1 Running 0 56m
|
||||
mongo-1068406935-3lswp 1/1 Running 0 56m
|
||||
```
|
||||
|
||||
<!--
|
||||
@@ -444,7 +444,7 @@ Scaling up or down is easy because your servers are defined as a Service that us
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-3823415956-k22zn 1/1 Running 0 1h
|
||||
frontend-3823415956-w9gbt 1/1 Running 0 1h
|
||||
mongo-1068406935-3lswp 1/1 Running 0 1h
|
||||
mongo-1068406935-3lswp 1/1 Running 0 1h
|
||||
```
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user