diff --git a/content/zh/docs/tutorials/_index.md b/content/zh/docs/tutorials/_index.md index 42415cafe2..821855b712 100644 --- a/content/zh/docs/tutorials/_index.md +++ b/content/zh/docs/tutorials/_index.md @@ -51,10 +51,14 @@ Kubernetes 文档的这一部分包含教程。每个教程展示了如何完成 ## 配置 +* [示例:配置 Java 微服务](/zh/docs/tutorials/configuration/configure-java-microservice/) + * [使用一个 ConfigMap 配置 Redis](/zh/docs/tutorials/configuration/configure-redis-using-configmap/) @@ -17,11 +19,15 @@ content_type: tutorial -Apparmor 是一个 Linux 内核安全模块,它补充了标准的基于 Linux 用户和组的安全模块将程序限制为有限资源集的权限。AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提供更加深入的防御。AppArmor 是通过配置文件进行配置的,这些配置文件被调整为报名单,列出了特定程序或者容器所需要的访问权限,如 Linux 功能、网络访问、文件权限等。每个配置文件都可以在*强制*模式(阻止访问不允许的资源)或*投诉*模式(仅报告冲突)下运行。 +Apparmor 是一个 Linux 内核安全模块,它补充了标准的基于 Linux 用户和组的安全模块将程序限制为有限资源集的权限。 +AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提供更加深入的防御。 +AppArmor 是通过配置文件进行配置的,这些配置文件被调整为允许特定程序或者容器访问,如 Linux 功能、网络访问、文件权限等。 +每个配置文件都可以在*强制(enforcing)*模式(阻止访问不允许的资源)或*投诉(complain)*模式 +(仅报告冲突)下运行。 @@ -244,9 +250,8 @@ k8s-apparmor-example-deny-write (enforce) *本例假设您已经使用 AppArmor 支持设置了一个集群。* - -首先,我们需要将要使用的配置文件加载到节点上。我们将使用的配置文件仅拒绝所有文件写入: + +首先,我们需要将要使用的配置文件加载到节点上。配置文件拒绝所有文件写入: ```shell #include @@ -259,9 +264,12 @@ profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { ``` -由于我们不知道 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 ``` - -注意 pod 呈现失败状态,并且显示一条有用的错误信息:`Pod Cannot enforce AppArmor: profile +注意 pod 呈现 Pending 状态,并且显示一条有用的错误信息:`Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" 未加载`。还用相同的消息记录了一个事件。 diff --git a/content/zh/docs/tutorials/clusters/seccomp.md b/content/zh/docs/tutorials/clusters/seccomp.md index 693eb57645..9f8d7dc2f3 100644 --- a/content/zh/docs/tutorials/clusters/seccomp.md +++ b/content/zh/docs/tutorials/clusters/seccomp.md @@ -52,14 +52,14 @@ Kubernetes 允许你将加载到节点上的 seccomp 配置文件自动应用于 为了完成本教程中的所有步骤,你必须安装 [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)了集群。 @@ -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" >}}
diff --git a/content/zh/docs/tutorials/hello-minikube.md b/content/zh/docs/tutorials/hello-minikube.md index c07f99998b..0fc6b828d7 100644 --- a/content/zh/docs/tutorials/hello-minikube.md +++ b/content/zh/docs/tutorials/hello-minikube.md @@ -112,7 +112,7 @@ This tutorial provides a container image that uses NGINX to echo back all the re @@ -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. 查看你刚刚创建的 Service: +2. 查看你创建的 Service: ```shell kubectl get services @@ -391,9 +391,9 @@ Minikube 有一组内置的 {{< glossary_tooltip text="插件" term_id="addons" ``` -3. 查看刚才创建的 Pod 和 Service: +3. 查看创建的 Pod 和 Service: ```shell kubectl get pod,svc -n kube-system diff --git a/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md b/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md index 0dd5ddcf1a..4fe30daece 100644 --- a/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md @@ -120,6 +120,8 @@ Headless Service and StatefulSet defined in `web.yaml`. ```shell kubectl apply -f web.yaml +``` +``` service/nginx created statefulset.apps/web created ``` @@ -134,10 +136,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 80/TCP 12s - +``` + +...然后获取 `web` StatefulSet,以验证两者均已成功创建: +```shell kubectl get statefulset web +``` +``` NAME DESIRED CURRENT AGE web 2 1 20s ``` @@ -159,6 +170,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 @@ -200,10 +213,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 - ``` +这将启动一个新的 shell。在新 shell 中,运行: +```shell +# Run this in the dns-test container shell nslookup web-0.nginx +``` + +输出类似于: +``` Server: 10.0.0.10 Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local @@ -284,6 +313,8 @@ the Pods in the StatefulSet. ```shell kubectl delete pod -l app=nginx +``` +``` pod "web-0" deleted pod "web-1" deleted ``` @@ -297,6 +328,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 @@ -316,11 +349,32 @@ DNS entries. ```shell for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done +``` +``` web-0 web-1 - +``` + +然后,运行: +``` kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm /bin/sh +``` + +这将启动一个新的 shell。在新 shell 中,运行: +```shell +# Run this in the dns-test container shell nslookup web-0.nginx +``` + +输出类似于: +``` Server: 10.0.0.10 Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local @@ -377,6 +431,12 @@ Get the PersistentVolumeClaims for `web-0` and `web-1`. ```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 48s www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 48s @@ -405,30 +465,35 @@ NGINX web 服务器默认会加载位于 `/usr/share/nginx/html/index.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 >}} -请注意,如果你看见上面的 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 -``` -在你重新尝试上面的 curl 命令之前。 +在你重新尝试上面的 `curl` 命令之前。 {{< /note >}} ```shell kubectl scale sts web --replicas=5 +``` +``` statefulset.apps/web scaled ``` +输出类似于: +``` NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 7m web-1 1/1 Running 0 7m @@ -761,7 +850,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 @@ -798,6 +889,8 @@ Patch `web` StatefulSet 来对 `updateStrategy` 字段添加一个分区。 ```shell kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}' +``` +``` statefulset.apps/web patched ``` @@ -809,6 +902,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 ``` @@ -819,7 +914,9 @@ Delete a Pod in the StatefulSet. 删除 StatefulSet 中的 Pod。 ```shell -kubectl delete po web-2 +kubectl delete pod web-2 +``` +``` pod "web-2" deleted ``` @@ -830,7 +927,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 @@ -845,10 +944,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 - - ``` +输出类似于: +``` NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 6m web-1 0/1 Terminating 0 6m @@ -952,7 +1065,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 ``` @@ -986,6 +1101,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 ``` @@ -996,7 +1113,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 +``` + +输出类似于: +``` NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 3m web-1 0/1 ContainerCreating 0 11s @@ -1020,11 +1143,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 - ``` -当重新创建 `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 ``` @@ -1229,11 +1370,17 @@ In one terminal window, watch the Pods in the StatefulSet. kubectl get pods -w -l app=nginx ``` + 在另一个窗口中再次删除这个 StatefulSet。这次省略 `--cascade=false` 参数。 ```shell kubectl delete statefulset web +``` + +``` statefulset.apps "web" deleted ``` @@ -1246,6 +1393,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 @@ -1279,6 +1429,9 @@ must delete the `nginx` Service manually. ```shell kubectl delete service nginx +``` + +``` service "nginx" deleted ``` @@ -1290,9 +1443,11 @@ Recreate the StatefulSet and Headless Service one more time. ```shell kubectl apply -f web.yaml +``` + +``` service/nginx created statefulset.apps/web created - ``` ## Pod 管理策略 -对于某些分布式系统来说,StatefulSet 的顺序性保证是不必要和/或者不应该的。这些系统仅仅要求唯一性和身份标志。为了解决这个问题,在 Kubernetes 1.7 中我们针对 StatefulSet API Object 引入了 `.spec.podManagementPolicy`。 - +对于某些分布式系统来说,StatefulSet 的顺序性保证是不必要和/或者不应该的。 +这些系统仅仅要求唯一性和身份标志。为了解决这个问题,在 Kubernetes 1.7 中 +我们针对 StatefulSet API 对象引入了 `.spec.podManagementPolicy`。 +此选项仅影响扩缩操作的行为。更新不受影响。 ### OrderedReady Pod 管理策略 @@ -1372,7 +1536,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" >}} @@ -1398,16 +1563,17 @@ kubectl get po -lapp=nginx -w ``` -在另一个终端窗口创建清单中的 StatefulSet 和 Service。 +在另一个终端窗口创建清单中的 StatefulSet 和 Service: ```shell kubectl apply -f web-parallel.yaml +``` +``` service/nginx created statefulset.apps/web created - ``` -StatefulSet 控制器启动了两个新的 Pod,而且在启动第二个之前并没有等待第一个变成 Running 和 Ready 状态。 +StatefulSet 启动了两个新的 Pod,而且在启动第二个之前并没有等待第一个变成 Running 和 Ready 状态。 -保持这个终端打开,并在另一个终端删除 `web` StatefulSet。 +## {{% heading "cleanup" %}} + +您应该打开两个终端,准备在清理过程中运行 `kubectl` 命令。 ```shell kubectl delete sts web +# sts is an abbreviation for statefulset ``` -在另一个终端里再次检查 `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 @@ -1530,10 +1709,12 @@ kubectl delete svc nginx 你需要删除本教程中用到的 PersistentVolumes 的持久化存储介质。基于你的环境、存储配置和提供方式,按照必须的步骤保证回收所有的存储。 diff --git a/content/zh/docs/tutorials/stateless-application/expose-external-ip-address.md b/content/zh/docs/tutorials/stateless-application/expose-external-ip-address.md index 0e38afc1d6..8fe79a9a5d 100644 --- a/content/zh/docs/tutorials/stateless-application/expose-external-ip-address.md +++ b/content/zh/docs/tutorials/stateless-application/expose-external-ip-address.md @@ -20,7 +20,7 @@ external IP address. ## {{% heading "prerequisites" %}} - * 安装 [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/), 需要云供应商。