diff --git a/content/zh/docs/tasks/inject-data-application/podpreset.md b/content/zh/docs/tasks/inject-data-application/podpreset.md index 54efeee257..2765869e40 100644 --- a/content/zh/docs/tasks/inject-data-application/podpreset.md +++ b/content/zh/docs/tasks/inject-data-application/podpreset.md @@ -1,29 +1,80 @@ --- -approvers: +title: 使用 PodPreset 将信息注入 Pod +min-kubernetes-server-version: v1.6 +content_type: task +weight: 60 +--- + -在 pod 创建时,用户可以使用 `podpreset` 对象将 secrets、卷挂载和环境变量等信息注入其中。 -本文展示了一些 `PodPreset` 资源使用的示例。 -用户可以从[理解 Pod Presets](/docs/concepts/workloads/pods/podpreset/) 中了解 PodPresets 的整体情况。 +{{< feature-state for_k8s_version="v1.6" state="alpha" >}} -{{< toc >}} + +本页展示如何在创建 Pod 时 使用 PodPreset 对象将类似 +{{< glossary_tooltip text="Secret" term_id="secret" >}}、卷挂载和 +{{< glossary_tooltip text="环境变量" term_id="container-env-variables" >}} +这类信息注入到 Pod 中。 -## 创建 Pod Preset +## {{% heading "prerequisites" %}} -### 简单的 Pod Spec 示例 + +你需要一个运行的 Kubernetes 集群以及配置好与集群通信的 kubectl 命令行工具。 +如果你还没有集群,可以使用 [Minikube](/zh/docs/setup/learning-environment/minikube/) +安装一个。 +确保你已经在集群中[启用了 PodPreset](/docs/concepts/workloads/pods/podpreset/#enable-pod-preset)。 -这里是一个简单的示例,展示了如何通过 Pod Preset 修改 Pod spec 。 + +## 使用 PodPreset 来注入环境变量和卷 + +在这一步中,你要创建一个 PodPreset 对象,其中包含卷挂载和一个环境变量。 +下面是 PodPreset 的清单: {{< codenew file="podpreset/preset.yaml" >}} + +PodPreset 对象的名称必须是一个合法的 +[DNS 子域名](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)。 + + +在清单中,你可以看到 PodPreset 有一个名为 `DB_PORT` 的环境变量定义, +和一个名为 `cache-volume` 的卷挂载定义,该卷挂载于 `/cache` 下。 +{{< glossary_tooltip text="选择算符" term_id="selector" >}} 设定此 PodPreset +将应用于所有匹配 `role:frontend` 标签的 Pods。 + 创建 PodPreset: ```shell kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml ``` + 检查所创建的 PodPreset: ```shell @@ -34,130 +85,427 @@ NAME AGE allow-database 1m ``` -新的 PodPreset 会对所有具有标签 `role: frontend` 的 Pods 采取行动。 - -**用户提交的 pod spec:** + +下面的清单定义了一个带有标签 `role: frontend` 的 Pod(与 PodPreset +的选择算符匹配): {{< codenew file="podpreset/pod.yaml" >}} + 创建 Pod: ```shell kubectl create -f https://k8s.io/examples/podpreset/pod.yaml ``` -列举运行中的 Pods: + +验证 Pod 出于运行状态: ```shell kubectl get pods ``` + ``` NAME READY STATUS RESTARTS AGE website 1/1 Running 0 4m ``` -**通过准入控制器后的 Pod 规约:** - -{{< codenew file="podpreset/merged.yaml" >}} - -要查看如上输出,运行下面的命令: + +查看被准入控制器更改过的 Pod 规约,以了解 PodPreset 在 Pod 上执行过的操作: ```shell kubectl get pod website -o yaml ``` +{{< codenew file="podpreset/merged.yaml" >}} + + +Pod 的环境变量 `DB_PORT`,`volumeMount` 和 `podpreset.admission.kubernetes.io` 注解 +表明 PodPreset 确实起了作用。 + + ### 带有 ConfigMap 的 Pod Spec 示例 这里的示例展示了如何通过 PodPreset 修改 Pod 规约,PodPreset 中定义了 `ConfigMap` 作为环境变量取值来源。 -**用户提交的 pod spec:** - -{{< codenew file="podpreset/pod.yaml" >}} - -**用户提交的 `ConfigMap`:** + +包含 ConfigMap 定义的清单: {{< codenew file="podpreset/configmap.yaml" >}} -**PodPreset 示例:** + +创建 ConfigMap: + +```shell +kubectl create -f https://k8s.io/examples/podpreset/configmap.yaml +``` + + +引用该 ConfigMap 的 PodPreset 的清单: {{< codenew file="podpreset/allow-db.yaml" >}} -**通过准入控制器后的 Pod spec:** + +创建 PodPreset: -{{< codenew file="podpreset/allow-db-merged.yaml" >}} +```shell +kubectl create -f https://k8s.io/examples/podpreset/allow-db.yaml +``` -### 带有 Pod Spec 的 ReplicaSet 示例 - -以下示例展示了(通过 ReplicaSet 创建 pod 后)只有 pod spec 会被 Pod Preset 所修改。 - -**用户提交的 ReplicaSet:** - -{{< codenew file="podpreset/replicaset.yaml" >}} - -**PodPreset 示例:** - -{{< codenew file="podpreset/preset.yaml" >}} - -**通过准入控制器后的 Pod spec:** - -注意 ReplicaSet spec 没有改变,用户必须检查单独的 pod 来验证 PodPreset 已被应用。 - -{{< codenew file="podpreset/replicaset-merged.yaml" >}} - -### 多 PodPreset 示例 - -这里的示例展示了如何通过多个 Pod 注入策略修改 Pod spec。 - -**用户提交的 Pod 规约:** + +下面的清单包含与 PodPreset 匹配的 Pod: {{< codenew file="podpreset/pod.yaml" >}} -**PodPreset 示例:** + +创建 Pod: + +```shell +kubectl create -f https://k8s.io/examples/podpreset/pod.yaml +``` + + +查看 Pod 规约被准入控制器修改后的结果,了解 PodPreset 应用之后的效果: + +```shell +kubectl get pod website -o yaml +``` + +{{< codenew file="podpreset/allow-db-merged.yaml" >}} + + +Pod 的环境变量 `DB_PORT` 和 `podpreset.admission.kubernetes.io` 注解 +表明 PodPreset 确实起了作用。 + +### 带有 Pod Spec 的 ReplicaSet 示例 + +以下示例展示了(通过 ReplicaSet 创建 Pod 后)只有 Pod 规约会被 PodPreset 所修改, +其他资源类型(如 ReplicaSet、Deployment)不受影响。 + +下面是本例所用 PodPreset 的清单: {{< codenew file="podpreset/preset.yaml" >}} -**另一个 Pod Preset 示例:** + +创建 Preset: + +```shell +kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml +``` + + +此清单定义了一个管理三个应用 Pod 的 ReplicaSet: + +{{< codenew file="podpreset/replicaset.yaml" >}} + + +创建 ReplicaSet: + +```shell +kubectl create -f https://k8s.io/examples/podpreset/replicaset.yaml +``` + + +验证 ReplicaSet 所创建的 Pod 处于运行状态: + +```shell +kubectl get pods +``` + + +输出显示 Pod 正在运行: + +``` +NAME READY STATUS RESTARTS AGE +frontend-2l94q 1/1 Running 0 2m18s +frontend-6vdgn 1/1 Running 0 2m18s +frontend-jzt4p 1/1 Running 0 2m18s +``` + + +查看 ReplicaSet 的 `spec` 内容: + +```shell +kubectl get replicasets frontend -o yaml +``` + + +{{< note >}} +ReplicaSet 对象的 `spec` 未被改变,ReplicaSet 也没有被添加 +`podpreset.admission.kubernetes.io` 注解。这是因为,PodPreset 只针对 +Pod 对象起作用。 + +要查看 PodPreset 的应用效果,你需要逐个地查看 Pod。 +{{< /note >}} + + +查看被影响的 Pod 的规约的命令是: + +```shell +kubectl get pod --selector=role=frontend -o yaml +``` + +{{< codenew file="podpreset/replicaset-merged.yaml" >}} + + +再一次,Pod 的 `podpreset.admission.kubernetes.io` 注解表明 PodPreset +已经被应用过。 + + +### 多 PodPreset 示例 + +这里的示例展示了如何通过多个 PodPreset 对象修改 Pod 规约。 + +第一个 PodPreset 的清单如下: + +{{< codenew file="podpreset/preset.yaml" >}} + + +为此例创建第一个 PodPreset: + +```shell +kubectl apply -f https://k8s.io/examples/podpreset/preset.yaml +``` + + +下面是第二个 PodPreset 的清单: {{< codenew file="podpreset/proxy.yaml" >}} -**通过准入控制器后的 Pod 规约:** + +创建第二个 PodPreset: + +```shell +kubectl apply -f https://k8s.io/examples/podpreset/proxy.yaml +``` + + +下面是包含可被修改的 Pod 定义的清单(此 Pod 同时被两个 PodPreset 匹配到): + +{{< codenew file="podpreset/pod.yaml" >}} + + +创建 Pod: + +```shell +kubectl create -f https://k8s.io/examples/podpreset/pod.yaml +``` + + +查看被准入控制器更改后的 Pod 规约,以了解被两个 PodPreset 一同修改 +后的效果: + +```shell +kubectl get pod website -o yaml +``` {{< codenew file="podpreset/multi-merged.yaml" >}} + +Pod 定义中的 `DB_PORT` 环境变量、`proxy-volume` 卷挂载以及 +两个 `podpreset.admission.kubernetes.io` 可以证明两个 Preset 都被应用了。 + + ### 冲突示例 -这里的示例展示了 PodPreset 与原 Pod 存在冲突时,Pod spec 不会被修改。 +这里的示例展示了 PodPreset 与原 Pod 存在冲突时,Pod 规约不会被修改。 +本例中的冲突是指 PodPreset 中的 `volumeMount` 与 Pod 中定义的卷挂载在 +`mountPath` 上有冲突。 -**用户提交的 Pod 规约:** - -{{< codenew file="podpreset/conflict-pod.yaml" >}} - -**PodPreset 示例:** +下面是 PodPreset 的清单: {{< codenew file="podpreset/conflict-preset.yaml" >}} -**因存在冲突,通过准入控制器后的 Pod spec 不会改变:** + +注意 `mountPath` 的取值是 `/cache`。 +创建 PodPreset: + +```shell +kubectl apply -f https://k8s.io/examples/podpreset/conflict-preset.yaml +``` + + +下面是 Pod 的清单: {{< codenew file="podpreset/conflict-pod.yaml" >}} -**如果运行 `kubectl describe...` 用户会看到以下事件:** + +注意清单中 `volumeMount` 元素的取值与 PodPreset 中的路径值相同。 + +创建 Pod: + +```shell +kubectl create -f https://k8s.io/examples/podpreset/conflict-pod.yaml ``` + +查看 Pod 规约: + +```shell +kubectl get pod website -o yaml +``` + +{{< codenew file="podpreset/conflict-pod.yaml" >}} + + +这里你可以看到 Pod 上并没有 PodPreset 的注解 podpreset.admission.kubernetes.io`。 +这意味着没有 PodPreset 被应用到 Pod 之上。 + +不过 [PodPreset 准入控制器](/zh/docs/reference/access-authn-authz/admission-controllers/#podpreset) +还是为所发生的冲突留下了一条警告性质的日志。 +你可以通过 `kubectl` 来查看此警告信息: + +```shell +kubectl -n kube-system logs -l=component=kube-apiserver +``` + + +输出类似于: + +``` +W1214 13:00:12.987884 1 admission.go:147] conflict occurred while applying podpresets: allow-database on pod: err: merging volume mounts for allow-database has a conflict on mount path /cache: +v1.VolumeMount{Name:"other-volume", ReadOnly:false, MountPath:"/cache", SubPath:"", MountPropagation:(*v1.MountPropagationMode)(nil), SubPathExpr:""} +does not match +core.VolumeMount{Name:"cache-volume", ReadOnly:false, MountPath:"/cache", SubPath:"", MountPropagation:(*core.MountPropagationMode)(nil), SubPathExpr:""} + in container +``` + +注意这里关于卷挂载路径冲突的消息。 + + ## 删除 Pod Preset -一旦用户不再需要 pod preset,可以使用 `kubectl` 进行删除: +一旦用户不再需要 PodPreset,可以使用 `kubectl` 将其删除: ```shell kubectl delete podpreset allow-database ``` + + +输出显示 PodPreset 已经被删除: + ``` podpreset "allow-database" deleted ```