Merge branch 'master' into hyq-0427

This commit is contained in:
Cria Hu
2021-04-30 15:48:11 +08:00
committed by GitHub
125 changed files with 5935 additions and 4254 deletions
+4
View File
@@ -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/)
<!--
+20 -12
View File
@@ -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" %}}
+6 -6
View File
@@ -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
```