Update localization guidelines (#10485)

* Update localization guidelines for language labels

Continuing work

Continuing work

Continuing work

More work in progress

Add local OWNERS folders

Add an OWNERS file to Chinese

Remove shortcode for repos

Add Japanese

Alphabetize languages, change weights accordingly

More updates

Add Korean in Korean

Add English to languageName

Feedback from gochist

Move Chinese content from cn/ to zh/

Move OWNERS from cn/ to zh/

Resolve merge conflicts by updating from master

Add files back in to prep for resolution

After rebase on upstream/master, remove files

Review and update localization guidelines

Feedback from gochist, tnir, cstoku

Add a trailing newline to content/ja/OWNERS

Add a trailing newline to content/zh/OWNERS

Drop requirement for GH repo project

Clarify language about forks/branches

Edits and typos

Remove a shortcode specific to a multi-repo language setup

Update aliases and owners

Add explicit OWNERS for content/en

Migrate content from Chinese repo, update regex in config.toml

Remove untranslated strings

Add trailing newline to content/en/OWNERS

Add trailing newlines to OWNERS files

add Jaguar project description (#10433)

* add Jaguar project description

[Jaguar](https://gitlab.com/sdnlab/jaguar) is an open source solution for Kubernetes's network based on OpenDaylight.
Jaguar provides overlay network using vxlan and Jaguar CNIPlugin provides one IP address per pod.

* Minor newline tweak

blog post for azure vmss (#10538)

Add microk8s to pick-right-solution.md (#10542)

* Add microk8s to pick-right-solution.md

Microk8s is a single-command installation of upstream Kubernetes on any Linux and should be included in the list of local-machine solutions.

* capitalized Istio

Add microk8s to foundational.md (#10543)

* Add microk8s to foundational.md

Adding microk8s as credible and stable alternative to get started with Kubernetes on a local machine. This is especially attractive for those not wanting to incur the overhead of running a VM for a local cluster.

* Update foundational.md

Thank you for your suggestions! LMK if this works now?

* Rewrote first paragraph

And included a bullet list of features of microk8s

* Copyedit

fix typo (#10545)

Fix the kubectl subcommands links. (#10550)

Signed-off-by: William Zhang <warmchang@outlook.com>

Fix command issue (#10515)

Signed-off-by: mooncake <xcoder@tenxcloud.com>

remove imported community files per issue 10184 (#10501)

networking.md: Markdown fix (#10498)

Fix front matter, federation command-line tools (#10500)

Clean up glossary entry (#10399)

update slack link (#10536)

typo in StatefulSet docs (#10558)

fix discription about horizontal pod autoscale (#10557)

Remove redundant symbols (#10556)

Fix issue #10520 (#10554)

Signed-off-by: William Zhang <warmchang@outlook.com>

Update api-concepts.md (#10534)

Revert "Fix command issue (#10515)"

This reverts commit c02a7fb9f9.

Update memory-constraint-namespace.md (#10530)

update memory request to 100MiB corresponding the yaml content

Blog: Introducing Volume Snapshot Alpha for Kubernetes (#10562)

* blog post for azure vmss

* snapshot blog post

Resolve merge conflicts in OWNERS*

Minor typo fix (#10567)

Not sure what's supposed to be here, proposing removing it.

* Feedback from gochist

Tweaks to feedback

* Feedback from ClaudiaJKang
This commit is contained in:
Zach Corleissen
2018-10-12 14:25:01 -07:00
committed by k8s-ci-robot
parent 753f57f0e6
commit abcee2dccd
316 changed files with 9227 additions and 169 deletions
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: command-demo
labels:
purpose: demonstrate-command
spec:
containers:
- name: command-demo-container
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
@@ -0,0 +1,45 @@
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never
@@ -0,0 +1,38 @@
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
@@ -0,0 +1,54 @@
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox:1.24
command: ["sh", "-c"]
args:
- while true; do
echo -en '\n';
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/cpu_request ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/mem_limit ]]; then
echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/mem_request ]]; then
echo -en '\n'; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
@@ -0,0 +1,39 @@
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: k8s.gcr.io/busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
@@ -0,0 +1,130 @@
---
title: 为容器设置启动时要执行的命令及其入参
content_template: templates/task
---
{{% capture overview %}}
本页将展示如何为Kubernetes Pod下的容器设置启动时要执行的命令及其入参。
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 创建Pod时为其下的容器设置启动时要执行的命令及其入参
创建Pod时,可以为其下的容器设置启动时要执行的命令及其入参。如果要设置命令,就
填写在配置文件的`command`字段下,如果要设置命令的入参,就填写在配置文件的`args
`字段下。一旦Pod创建完成,该命令及其入参就无法再进行更改了。
如果在配置文件中设置了容器启动时要执行的命令及其入参,那么容器镜像中自带的命令
与入参将会被覆盖而不再执行。如果配置文件中只是设置了入参,却没有设置其对应的命
令,那么容器镜像中自带的命令会使用该新入参作为其执行时的入参。
本示例中,将创建一个只包含单个容器的Pod。在Pod配置文件中设置了一个命令与两个入参:
{{< code file="commands.yaml" >}}
1. 基于YAML文件创建一个Pod
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/commands.yaml
1. 获取一下当前正在运行的Pods信息:
kubectl get pods
查询结果显示在command-demo这个Pod下运行的容器已经启动完成
1. 如果要获取容器启动时执行命令的输出结果,可以通过Pod的日志进行查看
kubectl logs command-demo
日志中显示了HOSTNAME 与KUBERNETES_PORT 这两个环境变量的值:
command-demo
tcp://10.3.240.1:443
## 使用环境变量来设置入参
在上面的示例中,我们直接将一串字符作为命令的入参。除此之外,我们还可以
将环境变量作为命令的入参。
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
这样一来,我们就可以将那些用来设置环境变量的方法应用于设置命令的入参,其
中包括了[ConfigMaps](/docs/tasks/configure-pod-container/configure-pod-configmap/)
[Secrets](/docs/concepts/configuration/secret/).
{{< note >}}
**注意:** 环境变量需要加上括号,类似于`"$(VAR)"`。这是在`command`
`args`字段使用变量的格式要求。
{{< /note >}}
## 通过shell来执行命令
有时候,需要通过shell来执行命令。 例如,命令可能由多个命令组合而成,抑或包含
在一个shell脚本中。这时,就可以通过如下方式在shell中执行命令:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
## 注意
下表给出了Docker 与 Kubernetes中对应的字段名称。
| Description | Docker field name | Kubernetes field name |
|----------------------------------------|------------------------|-----------------------|
| The command run by the container | Entrypoint | command |
| The arguments passed to the command | Cmd | args |
如果要覆盖默认的Entrypoint 与 Cmd,需要遵循如下规则:
* 如果在容器配置中没有设置`command` 或者 `args`,那么将使用Docker镜像自带的命
令及其入参。
* 如果在容器配置中只设置了`command`但是没有设置`args`,那么容器启动时只会执行该
命令,Docker镜像中自带的命令及其入参会被忽略。
* 如果在容器配置中只设置了`args`,那么Docker镜像中自带的命令会使用该新入参作为
其执行时的入参。
* 如果在容器配置中同时设置了`command``args`,那么Docker镜像中自带的命令及
其入参会被忽略。容器启动时只会执行配置中设置的命令,并使用配置中设置的入参作为
命令的入参。
下表涵盖了各类设置场景:
| Image Entrypoint | Image Cmd | Container command | Container args | Command run |
|--------------------|------------------|---------------------|--------------------|------------------|
| `[/ep-1]` | `[foo bar]` | &lt;not set&gt; | &lt;not set&gt; | `[ep-1 foo bar]` |
| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | &lt;not set&gt; | `[ep-2]` |
| `[/ep-1]` | `[foo bar]` | &lt;not set&gt; | `[zoo boo]` | `[ep-1 zoo boo]` |
| `[/ep-1]` | `[foo bar]` | `[/ep-2]` | `[zoo boo]` | `[ep-2 zoo boo]` |
{{% /capture %}}
{{% capture whatsnext %}}
* 获取更多资讯可参考 [containers and commands](/docs/user-guide/containers/).
* 获取更多资讯可参考 [configuring pods and containers](/docs/tasks/).
* 获取更多资讯可参考 [running commands in a container](/docs/tasks/debug-application-cluster/get-shell-running-container/).
* 参考 [Container](/docs/api-reference/{{< param "version" >}}/#container-v1-core).
{{% /capture %}}
@@ -0,0 +1,73 @@
---
title: 为容器设置环境变量
content_template: templates/task
---
{{% capture overview %}}
本页将展示如何为kubernetes Pod下的容器设置环境变量。
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 为容器设置一个环境变量
创建Pod时,可以为其下的容器设置环境变量。通过配置文件的`env`或者`envFrom` 字段来设置环境变量。
本示例中,将创建一个只包含单个容器的Pod。Pod的配置文件中设置环境变量的名称为`DEMO_GREETING`
其值为`"Hello from the environment"`。下面是Pod的配置文件内容:
{{< code file="envars.yaml" >}}
1. 基于YAML文件创建一个Pod:
kubectl create -f https://k8s.io/docs/tasks/inject-data-application/envars.yaml
1. 获取一下当前正在运行的Pods信息:
kubectl get pods -l purpose=demonstrate-envars
查询结果应为:
NAME READY STATUS RESTARTS AGE
envar-demo 1/1 Running 0 9s
1. 进入该Pod下的容器并打开一个命令终端:
kubectl exec -it envar-demo -- /bin/bash
1. 在命令终端中通过执行`printenv`打印出环境变量。
root@envar-demo:/# printenv
打印结果应为:
NODE_VERSION=4.4.2
EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237
HOSTNAME=envar-demo
...
DEMO_GREETING=Hello from the environment
1. 通过键入`exit`退出命令终端。
{{% /capture %}}
{{% capture whatsnext %}}
* 有关环境变量的更多信息,请参阅[这里](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/)。
* 有关如何通过环境变量来使用Secret,请参阅[这里](/docs/user-guide/secrets/#using-secrets-as-environment-variables)。
* 关于[EnvVarSource](/docs/api-reference/{{< param "version" >}}/#envvarsource-v1-core)资源的信息。
{{% /capture %}}
@@ -0,0 +1,167 @@
---
title: 使用 Secret 安全地分发凭证
content_template: templates/task
---
{{% capture overview %}}
本文展示如何安全地将敏感数据(如密码和加密密钥)注入到 Pods 中。
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 将 secret 数据转换为 base-64 形式
假设用户想要有两条 secret 数据:用户名 `my-app` 和密码
`39528$vdg7Jb`。 首先使用 [Base64 编码](https://www.base64encode.org/) 将用户名和密码转化为 base-64 形式。 这里是一个 Linux 示例:
echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64
结果显示 base-64 形式的用户名为 `bXktYXBw`
base-64 形式的密码为 `Mzk1MjgkdmRnN0pi`
## 创建 Secret
这里是一个配置文件,可以用来创建存有用户名和密码的 Secret:
{{< code file="secret.yaml" >}}
1. 创建 Secret
kubectl create -f secret.yaml
{{< note >}}
**注意:** 如果想要跳过 Base64 编码的步骤,可以使用 `kubectl create secret` 命令来创建 Secret
{{< /note >}}
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
1. 查看 Secret 相关信息:
kubectl get secret test-secret
输出:
NAME TYPE DATA AGE
test-secret Opaque 2 1m
1. 查看 Secret 相关的更多详细信息:
kubectl describe secret test-secret
输出:
Name: test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 13 bytes
username: 7 bytes
## 创建可以通过卷访问 secret 数据的 Pod
这里是一个可以用来创建 pod 的配置文件:
{{< code file="secret-pod.yaml" >}}
1. 创建 Pod
kubectl create -f secret-pod.yaml
1. 确认 Pod 正在运行:
kubectl get pod secret-test-pod
输出:
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 42m
1. 在 Pod 中运行的容器中获取一个 shell:
kubectl exec -it secret-test-pod -- /bin/bash
1. secret 数据通过挂载在 `/etc/secret-volume` 目录下的卷暴露在容器中。
在 shell 中,进入 secret 数据被暴露的目录:
root@secret-test-pod:/# cd /etc/secret-volume
1. 在 shell 中,列出 `/etc/secret-volume` 目录的文件:
root@secret-test-pod:/etc/secret-volume# ls
输出显示了两个文件,每个对应一条 secret 数据:
password username
1. 在 shell 中,显示 `username``password` 文件的内容:
root@secret-test-pod:/etc/secret-volume# cat username; echo; cat password; echo
输出为用户名和密码:
my-app
39528$vdg7Jb
## 创建通过环境变量访问 secret 数据的 Pod
这里是一个可以用来创建 pod 的配置文件:
{{< code file="secret-envars-pod.yaml" >}}
1. 创建 Pod
kubectl create -f secret-envars-pod.yaml
1. 确认 Pod 正在运行:
kubectl get pod secret-envars-test-pod
输出:
NAME READY STATUS RESTARTS AGE
secret-envars-test-pod 1/1 Running 0 4m
1. 在 Pod 中运行的容器中获取一个 shell:
kubectl exec -it secret-envars-test-pod -- /bin/bash
1. 在 shell 中,显示环境变量:
root@secret-envars-test-pod:/# printenv
输出包括用户名和密码:
...
SECRET_USERNAME=my-app
...
SECRET_PASSWORD=39528$vdg7Jb
{{% /capture %}}
{{% capture whatsnext %}}
* 了解更多关于 [Secrets](/docs/concepts/configuration/secret/)。
* 了解 [Volumes](/docs/concepts/storage/volumes/)。
### 参考
* [Secret](/docs/api-reference/{{< param "version" >}}/#secret-v1-core)
* [Volume](/docs/api-reference/{{< param "version" >}}/#volume-v1-core)
* [Pod](/docs/api-reference/{{< param "version" >}}/#pod-v1-core)
{{% /capture %}}
@@ -0,0 +1,212 @@
---
title: 通过文件将Pod信息呈现给容器
content_template: templates/task
---
{{% capture overview %}}
此页面描述Pod如何使用DownwardAPIVolumeFile把自己的信息呈现给pod中运行的容器。DownwardAPIVolumeFile可以呈现pod的字段和容器字段。
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Downward API
有两种方式可以将Pod和Container字段呈现给运行中的容器:
* [环境变量](/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/)
* DownwardAPIVolumeFile
这两种呈现Pod和Container字段的方式都称为*Downward API*。
## 存储Pod字段
在这个练习中,你将创建一个包含一个容器的pod。这是该pod的配置文件:
{{< code file="dapi-volume.yaml" >}}
在配置文件中,你可以看到Pod有一个`downwardAPI`类型的Volume,并且挂载到容器中的`/etc`
查看`downwardAPI`下面的`items`数组。每个数组元素都是一个[DownwardAPIVolumeFile](/docs/resources-reference/{{< param "version" >}}/#downwardapivolumefile-v1-core)。
第一个元素指示Pod的`metadata.labels`字段的值保存在名为`labels`的文件中。
第二个元素指示Pod的`annotations`字段的值保存在名为`annotations`的文件中。
{{< note >}}
**注意:** 本示例中的字段是Pod字段,不是Pod中容器的字段。
{{< /note >}}
创建Pod
```shell
kubectl create -f https://k8s.io/cn/docs/tasks/inject-data-application/dapi-volume.yaml
```
验证Pod中的容器运行正常:
```shell
kubectl get pods
```
查看容器的日志:
```shell
kubectl logs kubernetes-downwardapi-volume-example
```
输出显示`labels``annotations`文件的内容:
```shell
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
```
进入Pod中运行的容器,打开一个shell:
```
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
```
在该shell中,查看`labels`文件:
```shell
/# cat /etc/labels
```
输出显示Pod的所有labels都已写入`labels`文件。
```shell
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
```
同样,查看`annotations`文件:
```shell
/# cat /etc/annotations
```
查看`/etc`目录下的文件:
```shell
/# ls -laR /etc
```
在输出中可以看到,`labels``annotations`文件都在一个临时子目录中:这个例子,`..2982_06_02_21_47_53.299460680`。在`/etc`目录中,`..data`是一个指向临时子目录
的符号链接。`/etc`目录中,`labels``annotations`也是符号链接。
```
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
```
用符号链接可实现元数据的动态原子刷新;更新将写入一个新的临时目录,然后`..data`符号链接完成原子更新,通过使用[rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html)。
退出shell
```shell
/# exit
```
## 存储容器字段
前面的练习中,你将Pod字段保存到DownwardAPIVolumeFile中。接下来这个练习,你将存储容器字段。这里是包含一个容器的pod的配置文件:
{{< code file="dapi-volume-resources.yaml" >}}
在这个配置文件中,你可以看到Pod有一个`downwardAPI`类型的Volume,并且挂载到容器的`/etc`目录。
查看`downwardAPI`下面的`items`数组。每个数组元素都是一个DownwardAPIVolumeFile。
第一个元素指定名为`client-container`的容器中`limits.cpu`字段的值应保存在名为`cpu_limit`的文件中。
创建Pod
```shell
kubectl create -f https://k8s.io/cn/docs/tasks/inject-data-application/dapi-volume-resources.yaml
```
进入Pod中运行的容器,打开一个shell:
```
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
```
在shell中,查看`cpu_limit`文件:
```shell
/# cat /etc/cpu_limit
```
你可以使用同样的命令查看`cpu_request`, `mem_limit``mem_request` 文件.
{{% /capture %}}
{{% capture discussion %}}
## Capabilities of the Downward API
下面这些信息可以通过环境变量和DownwardAPIVolumeFiles提供给容器:
* 节点名称
* 节点IP
* Pod名称
* Pod名字空间
* Pod IP地址
* Pod服务帐号名称
* Pod的UID
* 容器的CPU约束
* 容器的CPU请求值
* 容器的内存约束
* 容器的内存请求值
此外,以下信息可通过DownwardAPIVolumeFiles获得:
* Pod的标签
* Pod的注释
{{< note >}}
**Note:** 如果容器未指定CPU和memory limits,则Downward API默认为节点可分配值。
{{< /note >}}
## 投射密钥到指定路径并且指定文件权限
你可以将密钥投射到指定路径并且指定每个文件的访问权限。更多信息,请参阅[Secrets](/docs/concepts/configuration/secret/).
## Downward API的动机
对于容器来说,有时候拥有自己的信息是很有用的,可避免与Kubernetes过度耦合。Downward API使得容器使用自己或者集群的信息,而不必通过Kubernetes客户端或API服务器。
一个例子是有一个现有的应用假定要用一个非常熟悉的环境变量来保存一个唯一标识。一种可能是给应用增加处理层,但这样是冗余和易出错的,而且它违反了低耦合的目标。更好的选择是使用Pod名称作为标识,把Pod名称注入这个环境变量中。
{{% /capture %}}
{{% capture whatsnext %}}
* [PodSpec](/docs/resources-reference/{{< param "version" >}}/#podspec-v1-core)
* [Volume](/docs/resources-reference/{{< param "version" >}}/#volume-v1-core)
* [DownwardAPIVolumeSource](/docs/resources-reference/{{< param "version" >}}/#downwardapivolumesource-v1-core)
* [DownwardAPIVolumeFile](/docs/resources-reference/{{< param "version" >}}/#downwardapivolumefile-v1-core)
* [ResourceFieldSelector](/docs/resources-reference/{{< param "version" >}}/#resourcefieldselector-v1-core)
{{% /capture %}}
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
@@ -0,0 +1,155 @@
---
title: 通过环境变量将Pod信息呈现给容器
content_template: templates/task
---
{{% capture overview %}}
此页面显示了Pod如何使用环境变量把自己的信息呈现给pod中运行的容器。环境变量可以呈现pod的字段和容器字段。
有两种方式可以将Pod和Container字段呈现给运行中的容器:
环境变量 和[DownwardAPIVolumeFiles](/docs/resources-reference/{{< param "version" >}}/#downwardapivolumefile-v1-core).
这两种呈现Pod和Container字段的方式都称为*Downward API*。
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## Downward API
有两种方式可以将Pod和Container字段呈现给运行中的容器:
* 环境变量
* [DownwardAPIVolumeFiles](/docs/resources-reference/{{< param "version" >}}/#downwardapivolumefile-v1-core)
这两种呈现Pod和Container字段的方式都称为*Downward API*。
## 用Pod字段作为环境变量的值
在这个练习中,你将创建一个包含一个容器的pod。这是该pod的配置文件:
{{< code file="dapi-envars-pod.yaml" >}}
这个配置文件中,你可以看到五个环境变量。`env`字段是一个[EnvVars](/docs/resources-reference/{{< param "version" >}}/#envvar-v1-core)类型的数组。
数组中第一个元素指定`MY_NODE_NAME`这个环境变量从Pod的`spec.nodeName`字段获取变量值。同样,其它环境变量也是从Pod的字段获取它们的变量值。
{{< note >}}
**注意:** 本示例中的字段是Pod字段,不是Pod中容器的字段。
{{< /note >}}
创建Pod
```shell
kubectl create -f https://k8s.io/cn/docs/tasks/inject-data-application/dapi-envars-pod.yaml
```
验证Pod中的容器运行正常:
```
kubectl get pods
```
查看容器日志:
```
kubectl logs dapi-envars-fieldref
```
输出信息显示了所选择的环境变量的值:
```
minikube
dapi-envars-fieldref
default
172.17.0.4
default
```
要了解为什么这些值在日志中,请查看配置文件中的`command``args`字段。 当容器启动时,它将五个环境变量的值写入stdout。每十秒重复执行一次。
接下来,进入Pod中运行的容器,打开一个shell:
```
kubectl exec -it dapi-envars-fieldref -- sh
```
在shell中,查看环境变量:
```
/# printenv
```
输出信息显示环境变量已经指定为Pod的字段的值。
```
MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref
```
## 用容器字段作为环境变量的值
前面的练习中,你将Pod字段作为环境变量的值。接下来这个练习,你将用容器字段作为环境变量的值。这里是包含一个容器的pod的配置文件:
{{< code file="dapi-envars-container.yaml" >}}
这个配置文件中,你可以看到四个环境变量。`env`字段是一个[EnvVars](/docs/resources-reference/{{< param "version" >}}/#envvar-v1-core)
类型的数组。数组中第一个元素指定`MY_CPU_REQUEST`这个环境变量从容器的`requests.cpu`字段获取变量值。同样,其它环境变量也是从容器的字段获取它们的变量值。
创建Pod
```shell
kubectl create -f https://k8s.io/cn/docs/tasks/inject-data-application/dapi-envars-container.yaml
```
验证Pod中的容器运行正常:
```
kubectl get pods
```
查看容器日志:
```
kubectl logs dapi-envars-resourcefieldref
```
输出信息显示了所选择的环境变量的值:
```
1
1
33554432
67108864
```
{{% /capture %}}
{{% capture whatsnext %}}
* [给容器定义环境变量](/docs/tasks/configure-pod-container/define-environment-variable-container/)
* [PodSpec](/docs/resources-reference/{{< param "version" >}}/#podspec-v1-core)
* [Container](/docs/resources-reference/{{< param "version" >}}/#container-v1-core)
* [EnvVar](/docs/resources-reference/{{< param "version" >}}/#envvar-v1-core)
* [EnvVarSource](/docs/resources-reference/{{< param "version" >}}/#envvarsource-v1-core)
* [ObjectFieldSelector](/docs/resources-reference/{{< param "version" >}}/#objectfieldselector-v1-core)
* [ResourceFieldSelector](/docs/resources-reference/{{< param "version" >}}/#resourcefieldselector-v1-core)
{{% /capture %}}
@@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: website
image: ecorp/website
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/app/config.json
readOnly: true
name: secret-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
- name: duplicate_key
value: FROM_ENV
- name: expansion
value: $(REPLACE_ME)
envFrom:
- configMapRef:
name: etcd-env-config
volumes:
- name: cache-volume
emptyDir: {}
- name: secret-volume
secret:
secretName: config-details
@@ -0,0 +1,31 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: 6379
- name: duplicate_key
value: FROM_ENV
- name: expansion
value: $(REPLACE_ME)
envFrom:
- configMapRef:
name: etcd-env-config
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/app/config.json
readOnly: true
name: secret-volume
volumes:
- name: cache-volume
emptyDir: {}
- name: secret-volume
secret:
secretName: config-details
@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: etcd-env-config
data:
number_of_members: "1"
initial_cluster_state: new
initial_cluster_token: DUMMY_ETCD_INITIAL_CLUSTER_TOKEN
discovery_token: DUMMY_ETCD_DISCOVERY_TOKEN
discovery_url: http://etcd_discovery:2379
etcdctl_peers: http://etcd:2379
duplicate_key: FROM_CONFIG_MAP
REPLACE_ME: "a value"
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: ecorp/website
volumeMounts:
- mountPath: /cache
name: cache-volume
ports:
volumes:
- name: cache-volume
emptyDir: {}
- containerPort: 80
@@ -0,0 +1,19 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: other-volume
volumes:
- name: other-volume
emptyDir: {}
@@ -0,0 +1,25 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: website
image: ecorp/website
volumeMounts:
- mountPath: /cache
name: cache-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,29 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
podpreset.admission.kubernetes.io/podpreset-proxy: "resource version"
spec:
containers:
- name: website
image: ecorp/website
volumeMounts:
- mountPath: /cache
name: cache-volume
- mountPath: /etc/proxy/configs
name: proxy-volume
ports:
- containerPort: 80
env:
- name: DB_PORT
value: "6379"
volumes:
- name: cache-volume
emptyDir: {}
- name: proxy-volume
emptyDir: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: ecorp/website
ports:
- containerPort: 80
@@ -0,0 +1,18 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,15 @@
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: proxy
namespace: myns
spec:
selector:
matchLabels:
role: frontend
volumeMounts:
- mountPath: /etc/proxy/configs
name: proxy-volume
volumes:
- name: proxy-volume
emptyDir: {}
@@ -0,0 +1,30 @@
apiVersion: v1
kind: Pod
metadata:
labels:
app: guestbook
tier: frontend
annotations:
podpreset.admission.kubernetes.io/podpreset-allow-database: "resource version"
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- mountPath: /cache
name: cache-volume
env:
- name: GET_HOSTS_FROM
value: dns
- name: DB_PORT
value: "6379"
ports:
- containerPort: 80
volumes:
- name: cache-volume
emptyDir: {}
@@ -0,0 +1,29 @@
apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
@@ -0,0 +1,123 @@
---
approvers:
- jessfraz
title: 使用 PodPreset 将信息注入 Pods
---
在 pod 创建时,用户可以使用 `podpreset` 对象将 secrets、卷挂载和环境变量等信息注入其中。
本文展示了一些 `PodPreset` 资源使用的示例。
用户可以从[理解 Pod Presets](/docs/concepts/workloads/pods/podpreset/) 中了解 PodPresets 的整体情况。
{{< toc >}}
## 创建 Pod Preset
### 简单的 Pod Spec 示例
这里是一个简单的示例,展示了如何通过 Pod Preset 修改 Pod spec 。
**用户提交的 pod spec**
{{< code file="podpreset-pod.yaml" >}}
**Pod Preset 示例:**
{{< code file="podpreset-preset.yaml" >}}
**通过准入控制器后的 Pod spec:**
{{< code file="podpreset-merged.yaml" >}}
### 带有 `ConfigMap` 的 Pod Spec 示例
这里的示例展示了如何通过 Pod Preset 修改 Pod specPod Preset 中定义了 `ConfigMap` 作为环境变量取值来源。
**用户提交的 pod spec**
{{< code file="podpreset-pod.yaml" >}}
**用户提交的 `ConfigMap`**
{{< code file="podpreset-configmap.yaml" >}}
**Pod Preset 示例:**
{{< code file="podpreset-allow-db.yaml" >}}
**通过准入控制器后的 Pod spec:**
{{< code file="podpreset-allow-db-merged.yaml" >}}
### 带有 Pod Spec 的 ReplicaSet 示例
以下示例展示了(通过 ReplicaSet 创建 pod 后)只有 pod spec 会被 Pod Preset 所修改。
**用户提交的 ReplicaSet**
{{< code file="podpreset-replicaset.yaml" >}}
**Pod Preset 示例:**
{{< code file="podpreset-preset.yaml" >}}
**通过准入控制器后的 Pod spec:**
注意 ReplicaSet spec 没有改变,用户必须检查单独的 pod 来验证 PodPreset 已被应用。
{{< code file="podpreset-replicaset-merged.yaml" >}}
### 多 PodPreset 示例
这里的示例展示了如何通过多个 Pod 注入策略修改 Pod spec。
**用户提交的 pod spec**
{{< code file="podpreset-pod.yaml" >}}
**Pod Preset 示例:**
{{< code file="podpreset-preset.yaml" >}}
**另一个 Pod Preset 示例:**
{{< code file="podpreset-proxy.yaml" >}}
**通过准入控制器后的 Pod spec:**
{{< code file="podpreset-multi-merged.yaml" >}}
### 冲突示例
这里的示例展示了 Pod Preset 与原 Pod 存在冲突时,Pod spec 不会被修改。
**用户提交的 pod spec**
{{< code file="podpreset-conflict-pod.yaml" >}}
**Pod Preset 示例:**
{{< code file="podpreset-conflict-preset.yaml" >}}
**因存在冲突,通过准入控制器后的 Pod spec 不会改变:**
{{< code file="podpreset-conflict-pod.yaml" >}}
**如果运行 `kubectl describe...` 用户会看到以下事件:**
```
$ kubectl describe ...
....
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Feb 2017 16:56:12 -0700 Tue, 07 Feb 2017 16:56:12 -0700 1 {podpreset.admission.kubernetes.io/podpreset-allow-database } conflict Conflict on pod preset. Duplicate mountPath /cache.
```
## 删除 Pod Preset
一旦用户不再需要 pod preset,可以使用 `kubectl` 进行删除:
```shell
$ kubectl delete podpreset allow-database
podpreset "allow-database" deleted
```
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: secret-envars-test-pod
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: test-secret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: test-secret
key: password
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# name must match the volume name below
- name: secret-volume
mountPath: /etc/secret-volume
# The secret data is exposed to Containers in the Pod through a Volume.
volumes:
- name: secret-volume
secret:
secretName: test-secret
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBwCg==
password: Mzk1MjgkdmRnN0piCg==