Merge branch 'main' into zh-secure-cluster

This commit is contained in:
Qiming Teng
2022-03-25 14:41:11 +08:00
committed by GitHub
187 changed files with 8938 additions and 7739 deletions
@@ -1,4 +1,4 @@
---
---
title: 访问集群
weight: 20
content_type: concept
@@ -50,10 +50,10 @@ kubectl config view
<!--
Many of the [examples](/docs/user-guide/kubectl-cheatsheet) provide an introduction to using
kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl-overview).
`kubectl` and complete documentation is found in the [kubectl reference](/docs/reference/kubectl/).
-->
有许多 [例子](/zh/docs/reference/kubectl/cheatsheet/) 介绍了如何使用 kubectl
可以在 [kubectl手册](/zh/docs/reference/kubectl/overview/) 中找到更完整的文档。
可以在 [kubectl 参考](/zh/docs/reference/kubectl/overview/) 中找到更完整的文档。
<!--
## Directly accessing the REST API
@@ -139,18 +139,47 @@ curl http://localhost:8080/api/
<!--
### Without kubectl proxy
In Kubernetes version 1.3 or later, `kubectl config view` no longer displays the token. Use `kubectl describe secret...` to get the token for the default service account, like this:
In Kubernetes version 1.3 or later, `kubectl config view` no longer displays the token. Use `kubectl apply` and `kubectl describe secret...` to create a token for the default service account with grep/cut:
First, create the Secret, requesting a token for the default ServiceAccount:
-->
### 不使用 kubectl proxy
在 Kubernetes 1.3 或更高版本中,`kubectl config view` 不再显示 token。
使用 `kubectl describe secret ...` 来获取默认服务帐户的 token,如下所示:
使用 `kubectl apply``kubectl describe secret ...` 及 grep 和剪切操作来为 default 服务帐户创建令牌,如下所示:
`grep/cut` 方法实现:
首先,创建 Secret,请求默认 ServiceAccount 的令牌:
```shell
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: default-token
annotations:
kubernetes.io/service-account.name: default
type: kubernetes.io/service-account-token
EOF
```
<!--
Next, wait for the token controller to populate the Secret with a token:
Capture and use the generated token:
-->
接下来,等待令牌控制器使用令牌填充 Secret:
```shell
while ! kubectl describe secret default-token | grep -E '^token' >/dev/null; do
echo "waiting for token..." >&2
sleep 1
done
```
捕获并使用生成的令牌:
```shell
APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d ' ')
TOKEN=$(kubectl describe secret default-token | grep -E '^token' | cut -f2 -d':' | tr -d ' ')
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
```
```json
@@ -172,7 +201,7 @@ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
```shell
APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
TOKEN=$(kubectl get secret $(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode )
TOKEN=$(kubectl get secret default-token -o jsonpath='{.data.token}' | base64 --decode )
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
```
@@ -9,7 +9,9 @@ card:
---
<!--
reviewers:
- bryk
- floreks
- maciaszczykm
- shu-mutou
- mikedanese
title: Deploy and Access the Kubernetes Dashboard
content_type: concept
@@ -55,7 +57,7 @@ The Dashboard UI is not deployed by default. To deploy it, run the following com
默认情况下不会部署 Dashboard。可以通过以下命令部署:
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml
```
<!--
@@ -151,7 +151,17 @@ See [Access Clusters Using the Kubernetes API](/docs/tasks/administer-cluster/ac
As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you append to the service's proxy URL:
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`[https:]service_name[:port_name]`*`/proxy`
If you haven't specified a name for your port, you don't have to specify *port_name* in the URL.
If you haven't specified a name for your port, you don't have to specify *port_name* in the URL. You can also use the port number in place of the *port_name* for both named and unnamed ports.
By default, the API server proxies to your service using HTTP. To use HTTPS, prefix the service name with `https:`:
`http://<kubernetes_master_address>/api/v1/namespaces/<namespace_name>/services/<service_name>/proxy`
The supported formats for the `<service_name>` segment of the URL are:
* `<service_name>` - proxies to the default or unnamed port using http
* `<service_name>:<port_name>` - proxies to the specified port name or port number using http
* `https:<service_name>:` - proxies to the default or unnamed port using https (note the trailing colon)
* `https:<service_name>:<port_name>` - proxies to the specified port name or port number using https
-->
#### 手动构建 API 服务器代理 URLs {#manually-constructing-apiserver-proxy-urls}
@@ -160,6 +170,15 @@ If you haven't specified a name for your port, you don't have to specify *port_n
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*`/proxy`
如果还没有为你的端口指定名称,你可以不用在 URL 中指定 *port_name*
对于命名和未命名端口,你还可以使用端口号代替 *port_name*
默认情况下,API 服务器使用 HTTP 为你的服务提供代理。 要使用 HTTPS,请在服务名称前加上 `https:`
`http://<kubernetes_master_address>/api/v1/namespaces/<namespace_name>/services/<service_name>/proxy`
URL 的 `<service_name>` 段支持的格式为:
* `<service_name>` - 使用 http 代理到默认或未命名端口
* `<service_name>:<port_name>` - 使用 http 代理到指定的端口名称或端口号
* `https:<service_name>:` - 使用 https 代理到默认或未命名端口(注意尾随冒号)
* `https:<service_name>:<port_name>` - 使用 https 代理到指定的端口名称或端口号
<!--
##### Examples
@@ -672,3 +672,20 @@ ETCDCTL_API=3 etcdctl --data-dir <data-dir-location> snapshot restore snapshotdb
依赖一些过时的数据。请注意,实际中还原会花费一些时间。
在还原过程中,关键组件将丢失领导锁并自行重启。
{{< /note >}}
<!--
## Upgrading etcd clusters
For more details on etcd upgrade, please refer to the [etcd upgrades](https://etcd.io/docs/latest/upgrades/) documentation.
{{< note >}}
Before you start an upgrade, please back up your etcd cluster first.
{{< /note >}}
-->
## 升级 etcd 集群
有关 etcd 升级的更多详细信息,请参阅 [etcd 升级](https://etcd.io/docs/latest/upgrades/)文档。
{{< note >}}
在开始升级之前,请先备份你的 etcd 集群。
{{< /note >}}
@@ -16,7 +16,7 @@ content_type: concept
{{< feature-state for_k8s_version="v1.11" state="beta" >}}
{{< glossary_definition term_id="cloud-controller-manager" length="all" prepend="组件 cloud-controller-manager 是">}}
{{< glossary_definition term_id="cloud-controller-manager" length="all">}}
<!-- body -->
@@ -27,44 +27,43 @@ Since cloud providers develop and release at a different pace compared to the Ku
-->
## 背景
由于云驱动的开发和发布与 Kubernetes 项目本身步调不同,将特定于云环境
的代码抽象到 `cloud-controller-manager` 二进制组件有助于云厂商独立于
Kubernetes 核心代码推进其驱动开发。
由于云驱动的开发和发布与 Kubernetes 项目本身步调不同,将特定于云环境的代码抽象到
`cloud-controller-manager` 二进制组件有助于云厂商独立于 Kubernetes
核心代码推进其驱动开发。
<!--
The Kubernetes project provides skeleton cloud-controller-manager code with Go interfaces to allow you (or your cloud provider) to plug in your own implementations. This means that a cloud provider can implement a cloud-controller-manager by importing packages from Kubernetes core; each cloudprovider will register their own code by calling `cloudprovider.RegisterCloudProvider` to update a global variable of available cloud providers.
-->
Kubernetes 项目提供 cloud-controller-manager 的框架代码,其中包含 Go
语言的接口,便于你(或者你的云驱动提供者)接驳你自己的实现。
这意味着每个云驱动可以通过从 Kubernetes 核心代码导入软件包来实现一个
cloud-controller-manager每个云驱动会通过调用
`cloudprovider.RegisterCloudProvider` 接口来注册其自身实现代码,从而更新
记录可用云驱动的全局变量。
Kubernetes 项目提供 cloud-controller-manager 的框架代码,其中包含 Go 语言的接口,
便于你(或者你的云驱动提供者)接驳你自己的实现。这意味着每个云驱动可以通过从
Kubernetes 核心代码导入软件包来实现一个 cloud-controller-manager
每个云驱动会通过调用 `cloudprovider.RegisterCloudProvider` 接口来注册其自身实现代码,
从而更新一个用来记录可用云驱动的全局变量。
<!--
## Developing
-->
## 开发
### Out of Tree
### 树外(Out of Tree
<!--
To build an out-of-tree cloud-controller-manager for your cloud, follow these steps:
-->
要为你的云环境构建一个 out-of-tree 云控制器管理器:
要为你的云环境构建一个树外(Out-of-Tree云控制器管理器:
<!--
1. Create a go package with an implementation that satisfies [cloudprovider.Interface](https://github.com/kubernetes/cloud-provider/blob/master/cloud.go).
2. Use [main.go in cloud-controller-manager](https://github.com/kubernetes/kubernetes/blob/master/cmd/cloud-controller-manager/main.go) from Kubernetes core as a template for your main.go. As mentioned above, the only difference should be the cloud package that will be imported.
3. Import your cloud package in `main.go`, ensure your package has an `init` block to run [cloudprovider.RegisterCloudProvider](https://github.com/kubernetes/cloud-provider/blob/master/plugins.go).
-->
1. 使用满足 [cloudprovider.Interface](https://github.com/kubernetes/cloud-provider/blob/master/cloud.go)
的实现创建一个 Go 语言包。
1. 使用满足 [`cloudprovider.Interface`](https://github.com/kubernetes/cloud-provider/blob/master/cloud.go)
接口的实现创建一个 Go 语言包。
2. 使用来自 Kubernetes 核心代码库的
[cloud-controller-manager 中的 main.go](https://github.com/kubernetes/kubernetes/blob/master/cmd/cloud-controller-manager/main.go)
作为 main.go 的模板。如上所述,唯一的区别应该是将导入的云包。
作为 `main.go` 的模板。如上所述,唯一的区别应该是将导入的云包不同
3. 在 `main.go` 中导入你的云包,确保你的包有一个 `init` 块来运行
[cloudprovider.RegisterCloudProvider](https://github.com/kubernetes/cloud-provider/blob/master/plugins.go)。
[`cloudprovider.RegisterCloudProvider`](https://github.com/kubernetes/cloud-provider/blob/master/plugins.go)。
<!--
Many cloud providers publish their controller manager code as open source. If you are creating
@@ -72,15 +71,15 @@ a new cloud-controller-manager from scratch, you could take an existing out-of-t
controller manager as your starting point.
-->
很多云驱动都将其控制器管理器代码以开源代码的形式公开。
如果你在开发一个新的 cloud-controller-manager,你可以选择某个 out-of-tree
如果你在开发一个新的 cloud-controller-manager,你可以选择某个树外(Out-of-Tree
云控制器管理器作为出发点。
### In Tree
### 树内(In Tree
<!--
For in-tree cloud providers, you can run the in-tree cloud controller manager as a {{< glossary_tooltip term_id="daemonset" >}} in your cluster. See [Cloud Controller Manager Administration](/docs/tasks/administer-cluster/running-cloud-controller/) for more details.
-->
对于 in-tree 驱动,你可以将 in-tree 云控制器管理器作为集中的
{{< glossary_tooltip term_id="daemonset" text="Daemonset" >}} 来运行。
对于树内(In-Tree驱动,你可以将树内云控制器管理器作为集中的
{{< glossary_tooltip term_id="daemonset" text="DaemonSet" >}} 来运行。
有关详细信息,请参阅[云控制器管理器管理](/zh/docs/tasks/administer-cluster/running-cloud-controller/)。
@@ -289,10 +289,10 @@ Install-WindowsFeature -Name containers
```
<!--
Install Docker
Instructions to do so are available at [Install Docker Engine - Enterprise on Windows Servers](https://hub.docker.com/editions/enterprise/docker-ee-server-windows).
Instructions to do so are available at [Install Docker Engine - Enterprise on Windows Servers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=Windows-Server#install-docker).
-->
安装 Docker
操作指南在 [Install Docker Engine - Enterprise on Windows Servers](https://hub.docker.com/editions/enterprise/docker-ee-server-windows)。
操作指南在 [Install Docker Engine - Enterprise on Windows Servers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=Windows-Server#install-docker)。
<!--
#### Install wins, kubelet, and kubeadm.
@@ -287,7 +287,8 @@ Kubernetes 调度器在优化 Pod 调度过程时,会考虑“可分配的”
并完成跨 NUMA 节点的预留操作。
<!--
The flag specifies a comma-separated list of memory reservations per NUMA node.
The flag specifies a comma-separated list of memory reservations of different memory types per NUMA node.
Memory reservations across multiple NUMA nodes can be specified using semicolon as separator.
This parameter is only useful in the context of the Memory Manager feature.
The Memory Manager will not use this reserved memory for the allocation of container workloads.
@@ -295,7 +296,8 @@ For example, if you have a NUMA node "NUMA0" with `10Gi` of memory available, an
the `--reserved-memory` was specified to reserve `1Gi` of memory at "NUMA0",
the Memory Manager assumes that only `9Gi` is available for containers.
-->
标志设置的值是一个按 NUMA 节点所给的内存预留的值的列表,用逗号分开。
标志设置的值是一个按 NUMA 节点的不同内存类型所给的内存预留的值的列表,用逗号分开。
可以使用分号作为分隔符来指定跨多个 NUMA 节点的内存预留。
只有在内存管理器特性被启用的语境下,这个参数才有意义。
内存管理器不会使用这些预留的内存来为容器负载分配内存。
@@ -426,7 +428,7 @@ Here is an example of a correct configuration:
--kube-reserved=cpu=4,memory=4Gi
--system-reserved=cpu=1,memory=1Gi
--memory-manager-policy=Static
--reserved-memory 0:memory=3Gi --reserved-memory 1:memory=2148Mi
--reserved-memory '0:memory=3Gi;1:memory=2148Mi'
```
<!--
@@ -20,13 +20,13 @@ dockershim to other container runtimes.
<!--
Since the announcement of [dockershim deprecation](/blog/2020/12/08/kubernetes-1-20-release-announcement/#dockershim-deprecation)
in Kubernetes 1.20, there were questions on how this will affect various workloads and Kubernetes
installations. You can find this blog post useful to understand the problem better: [Dockershim Deprecation FAQ](/blog/2020/12/02/dockershim-faq/)
installations. Our [Dockershim Removal FAQ](/blog/2022/02/17/dockershim-faq/) is there to help you
to understand the problem better.
-->
自从 Kubernetes 1.20 宣布
[弃用 dockershim](/zh/blog/2020/12/08/kubernetes-1-20-release-announcement/#dockershim-deprecation)
各类疑问随之而来:这对各类工作负载和 Kubernetes 部署会产生什么影响。
你会发现这篇博文对于更好地理解此问题非常有用:
[弃用 Dockershim 常见问题](/zh/blog/2020/12/02/dockershim-faq/)
我们的[弃用 Dockershim 常见问题](/blog/2022/02/17/dockershim-faq/)可以帮助你更好地理解这个问题。
<!-- It is recommended to migrate from dockershim to alternative container runtimes.
Check out [container runtimes](/docs/setup/production-environment/container-runtimes/)
@@ -29,7 +29,7 @@ you can take to check whether any workloads could be affected by `dockershim` de
-->
本页讲解你的集群把 Docker 用作容器运行时的运作机制,
并提供使用 `dockershim` 时,它所扮演角色的详细信息,
继而展示了一组验证步骤,可用来检查弃用 `dockershim` 对你的工作负载影响。
继而展示了一组操作,可用来检查弃用 `dockershim` 对你的工作负载是否有影响。
<!--
## Finding if your app has a dependencies on Docker {#find-docker-dependencies}
@@ -41,16 +41,16 @@ If you are using Docker for building your application containers, you can still
run these containers on any container runtime. This use of Docker does not count
as a dependency on Docker as a container runtime.
-->
虽然你通过 Docker 创建应用容器,但这些容器却可以运行于所有容器运行时
所以这种使用 Docker 容器运行时的方式并不构成对 Docker 的依赖。
即使你是通过 Docker 创建应用容器,也不妨碍你在其他任何容器运行时上运行这些容器
这种使用 Docker 的方式并不构成对 Docker 作为一个容器运行时的依赖。
<!--
When alternative container runtime is used, executing Docker commands may either
not work or yield unexpected output. This is how you can find whether you have a
dependency on Docker:
-->
当用了替代的容器运行时之后,Docker 命令可能不工作,甚至产生意外的输出。
这才是判定你是否依赖于 Docker 的方法。
当用了的容器运行时之后,Docker 命令可能不工作,或者产生意外的输出。
下面是判定你是否依赖于 Docker 的方法。
<!--
1. Make sure no privileged Pods execute Docker commands (like `docker ps`),
@@ -75,20 +75,21 @@ dependency on Docker:
cluster before migration.
-->
1. 确认没有特权 Pod 执行 Docker 命令(如 `docker ps`)、重新启动 Docker
服务(如 `systemctl restart docker.service`)或修改
Docker 配置文件 `/etc/docker/daemon.json`
服务(如 `systemctl restart docker.service`)或修改 Docker 配置文件
`/etc/docker/daemon.json`
2. 检查 Docker 配置文件(如 `/etc/docker/daemon.json`)中容器镜像仓库的镜像(mirror)站点设置。
这些配置通常需要针对不同容器运行时来重新设置。
3. 检查确保在 Kubernetes 基础设施之外的节点上运行的脚本和应用程序没有执行Docker命令。
3. 检查确保在 Kubernetes 基础设施之外的节点上运行的脚本和应用程序没有执行 Docker 命令。
可能的情况如:
- SSH 到节点排查故障;
- 节点启动脚本;
- 直接安装在节点上的监控和安全代理。
4. 检查执行上述特权操作的第三方工具。详细操作请参考
[从 dockershim 迁移遥测和安全代理](/zh/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents)
4. 检查执行上述特权操作的第三方工具。详细操作请参考
[从 dockershim 迁移遥测和安全代理](/zh/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents)
5. 确认没有对 dockershim 行为的间接依赖。这是一种极端情况,不太可能影响你的应用。
一些工具很可能被配置为使用了 Docker 特性,比如,基于特定指标发警报,或者在故障排查指令的一个环节中搜索特定的日志信息。
如果你有此类配置的工具,需要在迁移之前,在测试集群上完成功能验证
一些工具很可能被配置为使用了 Docker 特性,比如,基于特定指标发警报,
或者在故障排查指令的一个环节中搜索特定的日志信息
如果你有此类配置的工具,需要在迁移之前,在测试集群上测试这类行为。
<!--
## Dependency on Docker explained {#role-of-dockershim}
@@ -103,8 +104,7 @@ uses the container runtime interface as an abstraction so that you can use any c
container runtime.
-->
[容器运行时](/zh/docs/concepts/containers/#container-runtimes)是一个软件,用来运行组成 Kubernetes Pod 的容器。
Kubernetes 负责编排和调度 Pod;在每一个节点上,
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}
Kubernetes 负责编排和调度 Pod;在每一个节点上,{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}
使用抽象的容器运行时接口,所以你可以任意选用兼容的容器运行时。
<!--
@@ -118,14 +118,14 @@ if Docker were a CRI compatible runtime.
在早期版本中,Kubernetes 提供的兼容性支持一个容器运行时:Docker。
在 Kubernetes 发展历史中,集群运营人员希望采用更多的容器运行时。
于是 CRI 被设计出来满足这类灵活性需要 - 而 kubelet 亦开始支持 CRI。
然而,因为 Docker 在 CRI 规范创建之前就已经存在,Kubernetes 就创建了一个适配器组件`dockershim`
dockershim 适配器允许 kubelet 与 Docker交互,就好像 Docker 是一个 CRI 兼容的运行时一样。
然而,因为 Docker 在 CRI 规范创建之前就已经存在,Kubernetes 就创建了一个适配器组件 `dockershim`
dockershim 适配器允许 kubelet 与 Docker 交互,就好像 Docker 是一个 CRI 兼容的运行时一样。
<!--
You can read about it in [Kubernetes Containerd integration goes GA](/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/) blog post.
-->
你可以阅读博文
[Kubernetes 容器集成功能的正式发布](/zh/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/)
[Kubernetes 正式支持集成 Containerd](/zh/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/)
<!-- Dockershim vs. CRI with Containerd -->
![Dockershim 和 Containerd CRI 的实现对比图](/images/blog/2018-05-24-kubernetes-containerd-integration-goes-ga/cri-containerd.png)
@@ -138,8 +138,8 @@ So any Docker tooling or fancy UI you might have used
before to check on these containers is no longer available.
-->
切换到容器运行时 Containerd 可以消除掉中间环节。
所有以前遗留的容器可由 Containerd 这类容器运行时来运行和管理,操作体验也和以前一样
但是现在,由于直接用容器运行时调度容器,所以它们对 Docker 来说是不可见的。
所有相同的容器可由 Containerd 这类容器运行时来运行。
但是现在,由于直接用容器运行时调度容器,它们对 Docker 是不可见的。
因此,你以前用来检查这些容器的 Docker 工具或漂亮的 UI 都不再可用。
<!--
@@ -156,10 +156,9 @@ the Kubernetes API rather than directly through the container runtime (this advi
for all container runtimes, not only Docker).
-->
{{< note >}}
如果你用 Kubernetes 运行工作负载,最好通过 Kubernetes API停止容器,而不是通过容器运行时
如果你在用 Kubernetes 运行工作负载,最好通过 Kubernetes API 停止容器,
而不是通过容器运行时来停止它们
(此建议适用于所有容器运行时,不仅仅是针对 Docker)。
{{< /note >}}
<!--
@@ -170,4 +169,5 @@ by Kubernetes.
-->
你仍然可以下载镜像,或者用 `docker build` 命令创建它们。
但用 Docker 创建、下载的镜像,对于容器运行时和 Kubernetes,均不可见。
为了在 Kubernetes 中使用,需要把镜像推送(push)到某注册中心
为了在 Kubernetes 中使用,需要把镜像推送(push)到某镜像仓库
@@ -1,18 +1,13 @@
---
reviewers:
- bowei
- zihongz
title: 在 Kubernetes 集群中使用 NodeLocal DNSCache
content_type: task
---
<!--
---
reviewers:
- bowei
- zihongz
title: Using NodeLocal DNSCache in Kubernetes clusters
content_type: task
---
-->
<!-- overview -->
@@ -22,14 +17,10 @@ This page provides an overview of NodeLocal DNSCache feature in Kubernetes.
-->
本页概述了 Kubernetes 中的 NodeLocal DNSCache 功能。
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
<!-- steps -->
<!--
@@ -40,11 +31,11 @@ This page provides an overview of NodeLocal DNSCache feature in Kubernetes.
<!--
NodeLocal DNSCache improves Cluster DNS performance by running a dns caching agent on cluster nodes as a DaemonSet. In today's architecture, Pods in ClusterFirst DNS mode reach out to a kube-dns serviceIP for DNS queries. This is translated to a kube-dns/CoreDNS endpoint via iptables rules added by kube-proxy. With this new architecture, Pods will reach out to the dns caching agent running on the same node, thereby avoiding iptables DNAT rules and connection tracking. The local caching agent will query kube-dns service for cache misses of cluster hostnames(cluster.local suffix by default).
-->
NodeLocal DNSCache 通过在集群节点上作为 DaemonSet 运行 dns 缓存代理来提高集群 DNS 性能。
在当今的体系结构中,处于 ClusterFirst DNS 模式的 Pod 可以连接到 kube-dns serviceIP 进行 DNS 查询。
NodeLocal DNSCache 通过在集群节点上作为 DaemonSet 运行 DNS 缓存代理来提高集群 DNS 性能。
在当今的体系结构中,运行在 ClusterFirst DNS 模式的 Pod 可以连接到 kube-dns `serviceIP` 进行 DNS 查询。
通过 kube-proxy 添加的 iptables 规则将其转换为 kube-dns/CoreDNS 端点。
借助这种新架构,Pods 将可以访问在同一节点上运行的 dns 缓存代理,从而避免 iptables DNAT 规则和连接跟踪。
本地缓存代理将查询 kube-dns 服务以获取集群主机名的缓存缺失(默认为 cluster.local 后缀)。
借助这种新架构,Pods 将可以访问在同一节点上运行的 DNS 缓存代理,从而避免 iptables DNAT 规则和连接跟踪。
本地缓存代理将查询 kube-dns 服务以获取集群主机名的缓存缺失(默认为 "`cluster.local`" 后缀)。
<!--
## Motivation
@@ -55,29 +46,36 @@ NodeLocal DNSCache 通过在集群节点上作为 DaemonSet 运行 dns 缓存代
* With the current DNS architecture, it is possible that Pods with the highest DNS QPS have to reach out to a different node, if there is no local kube-dns/CoreDNS instance.
Having a local cache will help improve the latency in such scenarios.
-->
* 使用当前的 DNS 体系结构,如果没有本地 kube-dns/CoreDNS 实例,则具有最高 DNS QPS 的 Pod 可能必须延伸到另一个节点。
在这种脚本下,拥有本地缓存将有助于改善延迟
* 使用当前的 DNS 体系结构,如果没有本地 kube-dns/CoreDNS 实例,则具有最高 DNS QPS
的 Pod 可能必须延伸到另一个节点
在这种场景下,拥有本地缓存将有助于改善延迟。
<!--
* Skipping iptables DNAT and connection tracking will help reduce [conntrack races](https://github.com/kubernetes/kubernetes/issues/56903) and avoid UDP DNS entries filling up conntrack table.
-->
* 跳过 iptables DNAT 和连接跟踪将有助于减少 [conntrack 竞争](https://github.com/kubernetes/kubernetes/issues/56903)并避免 UDP DNS 条目填满 conntrack 表。
* 跳过 iptables DNAT 和连接跟踪将有助于减少
[conntrack 竞争](https://github.com/kubernetes/kubernetes/issues/56903)
并避免 UDP DNS 条目填满 conntrack 表。
<!--
* Connections from local caching agent to kube-dns servie can be upgraded to TCP. TCP conntrack entries will be removed on connection close in contrast with UDP entries that have to timeout ([default](https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt) `nf_conntrack_udp_timeout` is 30 seconds)
-->
* 从本地缓存代理到 kube-dns 服务的连接可以升级 TCP 。
TCP conntrack 条目将在连接关闭时被删除,相反 UDP 条目必须超时([默认](https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt) `nf_conntrack_udp_timeout` 是 30 秒)
* 从本地缓存代理到 kube-dns 服务的连接可以升级 TCP 。
TCP conntrack 条目将在连接关闭时被删除,相反 UDP 条目必须超时
[默认](https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt)
`nf_conntrack_udp_timeout` 是 30 秒)。
<!--
* Upgrading DNS queries from UDP to TCP would reduce tail latency attributed to dropped UDP packets and DNS timeouts usually up to 30s (3 retries + 10s timeout). Since the nodelocal cache listens for UDP DNS queries, applications don't need to be changed.
-->
* 将 DNS 查询从 UDP 升级到 TCP 将减少归因于丢弃的 UDP 数据包和 DNS 超时的尾部等待时间,通常长达 30 秒(3 次重试+ 10 秒超时)。
* 将 DNS 查询从 UDP 升级到 TCP 将减少由于被丢弃的 UDP 包和 DNS 超时而带来的尾部等待时间
这类延时通常长达 30 秒(3 次重试 + 10 秒超时)。
由于 nodelocal 缓存监听 UDP DNS 查询,应用不需要变更。
<!--
* Metrics & visibility into dns requests at a node level.
-->
* 在节点级别对 dns 请求的度量和可见性。
* 在节点级别对 DNS 请求的度量和可见性。
<!--
* Negative caching can be re-enabled, thereby reducing number of queries to kube-dns service.
@@ -92,13 +90,12 @@ TCP conntrack 条目将在连接关闭时被删除,相反 UDP 条目必须超
<!--
This is the path followed by DNS Queries after NodeLocal DNSCache is enabled:
-->
启用 NodeLocal DNSCache 之后,这是 DNS 查询所遵循的路径:
启用 NodeLocal DNSCache 之后,DNS 查询所遵循的路径如下
<!--
{{< figure src="/images/docs/nodelocaldns.svg" alt="NodeLocal DNSCache flow" title="Nodelocal DNSCache flow" caption="This image shows how NodeLocal DNSCache handles DNS queries." >}}
{{< figure src="/images/docs/nodelocaldns.svg" alt="NodeLocal DNSCache flow" title="Nodelocal DNSCache flow" caption="This image shows how NodeLocal DNSCache handles DNS queries." class="diagram-medium" >}}
-->
{{< figure src="/images/docs/nodelocaldns.svg" alt="NodeLocal DNSCache 流" title="Nodelocal DNSCache 流" caption="此图显示了 NodeLocal DNSCache 如何处理 DNS 查询。" >}}
{{< figure src="/images/docs/nodelocaldns.svg" alt="NodeLocal DNSCache 流" title="Nodelocal DNSCache 流" caption="此图显示了 NodeLocal DNSCache 如何处理 DNS 查询。" class="diagram-medium" >}}
<!--
## Configuration
@@ -110,8 +107,8 @@ This is the path followed by DNS Queries after NodeLocal DNSCache is enabled:
-->
{{< note >}}
NodeLocal DNSCache 的本地侦听 IP 地址可以是任何地址,只要该地址不和你的集群里现有的 IP 地址发生冲突。
推荐使用本地范围内的地址,例如,IPv4 链路本地区段 169.254.0.0/16 内的地址,
或者 IPv6 唯一本地地址区段 fd00::/8 内的地址。
推荐使用本地范围内的地址,例如,IPv4 链路本地区段 '169.254.0.0/16' 内的地址,
或者 IPv6 唯一本地地址区段 'fd00::/8' 内的地址。
{{< /note >}}
<!--
@@ -129,7 +126,8 @@ This feature can be enabled using the following steps:
If you are using the sample manifest from the previous point, this will require to modify [the configuration line L70](https://github.com/kubernetes/kubernetes/blob/b2ecd1b3a3192fbbe2b9e348e095326f51dc43dd/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml#L70) like this `health [__PILLAR__LOCAL__DNS__]:8080`
-->
* 如果使用 IPv6,在使用 IP:Port 格式的时候需要把 CoreDNS 配置文件里的所有 IPv6 地址用方括号包起来。
如果你使用上述的示例清单,需要把 [配置行 L70](https://github.com/kubernetes/kubernetes/blob/b2ecd1b3a3192fbbe2b9e348e095326f51dc43dd/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml#L70)
如果你使用上述的示例清单,需要把
[配置行 L70](https://github.com/kubernetes/kubernetes/blob/b2ecd1b3a3192fbbe2b9e348e095326f51dc43dd/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml#L70)
修改为 `health [__PILLAR__LOCAL__DNS__]:8080`
<!--
* Substitute the variables in the manifest with the right values:
@@ -143,13 +141,15 @@ If you are using the sample manifest from the previous point, this will require
`<cluster-domain>` is "cluster.local" by default. `<node-local-address>` is the local listen IP address chosen for NodeLocal DNSCache.
-->
* 把清单里的变量更改为正确的值:
* kubedns=`kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}`
* domain=`<cluster-domain>`
```
kubedns=`kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}`
domain=<cluster-domain>
localdns=<node-local-address>
```
* localdns=`<node-local-address>`
`<cluster-domain>` 的默认值是 "cluster.local"。 `<node-local-address>` 是 NodeLocal DNSCache 选择的本地侦听 IP 地址。
`<cluster-domain>` 的默认值是 "`cluster.local`"。`<node-local-address>`
NodeLocal DNSCache 选择的本地侦听 IP 地址。
<!--
* If kube-proxy is running in IPTABLES mode:
@@ -161,16 +161,16 @@ If you are using the sample manifest from the previous point, this will require
`__PILLAR__CLUSTER__DNS__` and `__PILLAR__UPSTREAM__SERVERS__` will be populated by the node-local-dns pods.
In this mode, node-local-dns pods listen on both the kube-dns service IP as well as `<node-local-address>`, so pods can lookup DNS records using either IP address.
-->
* 如果 kube-proxy 运行在 IPTABLES 模式:
* 如果 kube-proxy 运行在 IPTABLES 模式:
``` bash
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml
```
``` bash
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml
```
node-local-dns Pods 会设置 `__PILLAR__CLUSTER__DNS__``__PILLAR__UPSTREAM__SERVERS__`
在此模式下, node-local-dns Pods 会同时侦听 kube-dns 服务的 IP 地址和 `<node-local-address>` 的地址,
以便 Pods 可以使用其中任何一个 IP 地址来查询 DNS 记录。
<!--
node-local-dns Pods 会设置 `__PILLAR__CLUSTER__DNS__``__PILLAR__UPSTREAM__SERVERS__`
在此模式下, node-local-dns Pods 会同时侦听 kube-dns 服务的 IP 地址和
`<node-local-address>` 的地址,以便 Pods 可以使用其中任何一个 IP 地址来查询 DNS 记录。
<!--
* If kube-proxy is running in IPVS mode:
``` bash
@@ -179,16 +179,16 @@ If you are using the sample manifest from the previous point, this will require
In this mode, node-local-dns pods listen only on `<node-local-address>`. The node-local-dns interface cannot bind the kube-dns cluster IP since the interface used for IPVS loadbalancing already uses this address.
`__PILLAR__UPSTREAM__SERVERS__` will be populated by the node-local-dns pods.
-->
* 如果 kube-proxy 运行在 IPVS 模式:
* 如果 kube-proxy 运行在 IPVS 模式:
``` bash
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml
```
``` bash
sed -i "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml
```
在此模式下,node-local-dns Pods 只会侦听 `<node-local-address>` 的地址。
node-local-dns 接口不能绑定 kube-dns 的集群 IP 地址,因为 IPVS 负载均衡
使用的接口已经占用了该地址。
node-local-dns Pods 会设置 `__PILLAR__UPSTREAM__SERVERS__`
在此模式下,node-local-dns Pods 只会侦听 `<node-local-address>` 的地址。
node-local-dns 接口不能绑定 kube-dns 的集群 IP 地址,因为 IPVS 负载均衡
使用的接口已经占用了该地址。
node-local-dns Pods 会设置 `__PILLAR__UPSTREAM__SERVERS__`
<!--
* Run `kubectl create -f nodelocaldns.yaml`
@@ -196,8 +196,10 @@ If you are using the sample manifest from the previous point, this will require
Otherwise, there is no need to modify the value of the `--cluster-dns` flag, since NodeLocal DNSCache listens on both the kube-dns service IP as well as `<node-local-address>`.
-->
* 运行 `kubectl create -f nodelocaldns.yaml`
* 如果 kube-proxy 运行在 IPVS 模式,需要修改 kubelet 的 `--cluster-dns` 参数为 NodeLocal DNSCache 正在侦听的 `<node-local-address>` 地址。
否则,不需要修改 `--cluster-dns` 参数,因为 NodeLocal DNSCache 会同时侦听 kube-dns 服务的 IP 地址和 `<node-local-address>` 地址。
* 如果 kube-proxy 运行在 IPVS 模式,需要修改 kubelet 的 `--cluster-dns` 参数
NodeLocal DNSCache 正在侦听的 `<node-local-address>` 地址。
否则,不需要修改 `--cluster-dns` 参数,因为 NodeLocal DNSCache 会同时侦听
kube-dns 服务的 IP 地址和 `<node-local-address>` 的地址。
<!--
Once enabled, node-local-dns Pods will run in the kube-system namespace on each of the cluster nodes. This Pod runs [CoreDNS](https://github.com/coredns/coredns) in cache mode, so all CoreDNS metrics exposed by the different plugins will be available on a per-node basis.
@@ -205,6 +207,93 @@ Once enabled, node-local-dns Pods will run in the kube-system namespace on each
You can disable this feature by removing the DaemonSet, using `kubectl delete -f <manifest>` . You should also revert any changes you made to the kubelet configuration.
-->
启用后,node-local-dns Pods 将在每个集群节点上的 kube-system 名字空间中运行。
此 Pod 在缓存模式下运行 [CoreDNS](https://github.com/coredns/coredns) 因此每个节点都可以使用不同插件公开的所有 CoreDNS 指标。
此 Pod 在缓存模式下运行 [CoreDNS](https://github.com/coredns/coredns)
因此每个节点都可以使用不同插件公开的所有 CoreDNS 指标。
如果要禁用该功能,你可以使用 `kubectl delete -f <manifest>` 来删除 DaemonSet。
你还应该回滚你对 kubelet 配置所做的所有改动。
<!--
## StubDomains and Upstream server Configuration
-->
## StubDomains 和上游服务器配置
<!--
StubDomains and upstream servers specified in the `kube-dns` ConfigMap in the `kube-system` namespace
are automatically picked up by `node-local-dns` pods. The ConfigMap contents need to follow the format
shown in [the example](/docs/tasks/administer-cluster/dns-custom-nameservers/#example-1).
The `node-local-dns` ConfigMap can also be modified directly with the stubDomain configuration
in the Corefile format. Some cloud providers might not allow modifying `node-local-dns` ConfigMap directly.
In those cases, the `kube-dns` ConfigMap can be updated.
-->
`node-local-dns` Pod 能够自动读取 `kube-system` 名字空间中 `kube-dns` ConfigMap
中保存的 StubDomains 和上游服务器信息。ConfigMap 中的内容需要遵从
[此示例](/zh/docs/tasks/administer-cluster/dns-custom-nameservers/#example-1)
中所给的格式。
`node-local-dns` ConfigMap 也可被直接修改,使用 Corefile 格式设置 stubDomain 配置。
某些云厂商可能不允许直接修改 `node-local-dns` ConfigMap 的内容。
在这种情况下,可以更新 `kube-dns` ConfigMap。
<!--
## Setting memory limits
-->
## 设置内存限制
<!--
node-local-dns pods use memory for storing cache entries and processing queries. Since they do not watch Kubernetes objects, the cluster size or the number of Services/Endpoints do not directly affect memory usage. Memory usage is influenced by the DNS query pattern.
From [CoreDNS docs](https://github.com/coredns/deployment/blob/master/kubernetes/Scaling_CoreDNS.md),
> The default cache size is 10000 entries, which uses about 30 MB when completely filled.
-->
`node-local-dns` Pod 使用内存来保存缓存项并处理查询。
由于它们并不监视 Kubernetes 对象变化,集群规模或者 Service/Endpoints
的数量都不会直接影响内存用量。内存用量会受到 DNS 查询模式的影响。
根据 [CoreDNS 文档](https://github.com/coredns/deployment/blob/master/kubernetes/Scaling_CoreDNS.md),
> The default cache size is 10000 entries, which uses about 30 MB when completely filled.
> (默认的缓存大小是 10000 个表项,当完全填充时会使用约 30 MB 内存)
<!--
This would be the memory usage for each server block (if the cache gets completely filled).
Memory usage can be reduced by specifying smaller cache sizes.
The number of concurrent queries is linked to the memory demand, because each extra
goroutine used for handling a query requires an amount of memory. You can set an upper limit
using the `max_concurrent` option in the forward plugin.
-->
这一数值是(缓存完全被填充时)每个服务器块的内存用量。
通过设置小一点的缓存大小可以降低内存用量。
并发查询的数量会影响内存需求,因为用来处理查询请求而创建的 Go 协程都需要一定量的内存。
你可以在 forward 插件中使用 `max_concurrent` 选项设置并发查询数量上限。
<!--
If a node-local-dns pod attempts to use more memory than is available (because of total system
resources, or because of a configured
[resource limit](/docs/concepts/configuration/manage-resources-containers/)), the operating system
may shut down that pod's container.
If this happens, the container that is terminated (“OOMKilled”) does not clean up the custom
packet filtering rules that it previously added during startup.
The node-local-dns container should get restarted (since managed as part of a DaemonSet), but this
will lead to a brief DNS downtime each time that the container fails: the packet filtering rules direct
DNS queries to a local Pod that is unhealthy.
-->
如果一个 `node-local-dns` Pod 尝试使用的内存超出可提供的内存量
(因为系统资源总量的,或者所配置的[资源约束](/zh/docs/concepts/configuration/manage-resources-containers/))的原因,
操作系统可能会关闭这一 Pod 的容器。
发生这种情况时,被终止的("OOMKilled")容器不会清理其启动期间所添加的定制包过滤规则。
`node-local-dns` 容器应该会被重启(因其作为 DaemonSet 的一部分被管理),
但因上述原因可能每次容器失败时都会导致 DNS 有一小段时间不可用:
the packet filtering rules direct DNS queries to a local Pod that is unhealthy
(包过滤器规则将 DNS 查询转发到本地某个不健康的 Pod)。
<!--
You can determine a suitable memory limit by running node-local-dns pods without a limit and
measuring the peak usage. You can also set up and use a
[VerticalPodAutoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler)
in _recommender mode_, and then check its recommendations.
-->
通过不带限制地运行 `node-local-dns` Pod 并度量其内存用量峰值,你可以为其确定一个合适的内存限制值。
你也可以安装并使用一个运行在 “Recommender Mode(建议者模式)” 的
[VerticalPodAutoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler)
并查看该组件输出的建议信息。
如果要禁用该功能,你可以使用 `kubectl delete -f <manifest>` 来删除 DaemonSet。你还应该恢复你对 kubelet 配置所做的所有改动。
@@ -166,7 +166,7 @@ flag.
It is recommended that the kubernetes system daemons are placed under a top
level control group (`runtime.slice` on systemd machines for example). Each
system daemon should ideally run within its own child control group. Refer to
[the design proposal](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md#recommended-cgroups-setup)
[the design proposal](https://git.k8s.io/design-proposals-archive/node/node-allocatable.md#recommended-cgroups-setup)
for more details on recommended control group hierarchy.
Note that Kubelet **does not** create `--kube-reserved-cgroup` if it doesn't
@@ -179,7 +179,7 @@ exist. Kubelet will fail if an invalid cgroup is specified.
`runtime.slice`)。
理想情况下每个系统守护进程都应该在其自己的子控制组中运行。
请参考
[这个设计方案](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md#recommended-cgroups-setup)
[这个设计方案](https://git.k8s.io/design-proposals-archive/node/node-allocatable.md#recommended-cgroups-setup)
进一步了解关于推荐控制组层次结构的细节。
请注意,如果 `--kube-reserved-cgroup` 不存在,Kubelet 将 **不会** 创建它。
@@ -174,154 +174,16 @@ replicas to fall below the specified budget are blocked.
If you prefer not to use [kubectl drain](/docs/reference/generated/kubectl/kubectl-commands/#drain) (such as
to avoid calling to an external command, or to get finer control over the pod
eviction process), you can also programmatically cause evictions using the eviction API.
eviction process), you can also programmatically cause evictions using the
eviction API.
For more information, see [API-initiated eviction](/docs/concepts/scheduling-eviction/api-eviction/).
-->
## 驱逐 API {#the-eviction-api}
如果你不喜欢使用
[kubectl drain](/docs/reference/generated/kubectl/kubectl-commands/#drain)
(比如避免调用外部命令,或者更细化地控制 pod 驱逐过程),
你也可以用驱逐 API 通过编程的方式达到驱逐的效果。
<!--
You should first be familiar with using [Kubernetes language clients](/docs/tasks/administer-cluster/access-cluster-api/#programmatic-access-to-the-api).
The eviction subresource of a
pod can be thought of as a kind of policy-controlled DELETE operation on the pod
itself. To attempt an eviction (perhaps more REST-precisely, to attempt to
*create* an eviction), you POST an attempted operation. Here's an example:
-->
首先应该熟悉使用
[Kubernetes 语言客户端](/zh/docs/tasks/administer-cluster/access-cluster-api/#programmatic-access-to-the-api)。
Pod 的 Eviction 子资源可以看作是一种策略控制的 DELETE 操作,作用于 Pod 本身。
要尝试驱逐(更准确地说,尝试 *创建* 一个 Eviction),需要用 POST 发出所尝试的操作。这里有一个例子:
{{< tabs name="Eviction_example" >}}
{{% tab name="policy/v1" %}}
<!--
{{< note >}}
`policy/v1` Eviction is available in v1.22+. Use `policy/v1beta1` with prior releases.
{{< /note >}}
-->
{{< note >}}
`policy/v1` 驱逐在 v1.22+ 中可用。在之前版本中请使用 `policy/v1beta1`
{{< /note >}}
```json
{
"apiVersion": "policy/v1",
"kind": "Eviction",
"metadata": {
"name": "quux",
"namespace": "default"
}
}
```
{{% /tab %}}
{{% tab name="policy/v1beta1" %}}
<!--
{{< note >}}
Deprecated in v1.22 in favor of `policy/v1`
{{< /note >}}
-->
{{< note >}}
在 v1.22 中已弃用,以 `policy/v1` 取代
{{< /note >}}
```json
{
"apiVersion": "policy/v1beta1",
"kind": "Eviction",
"metadata": {
"name": "quux",
"namespace": "default"
}
}
```
{{% /tab %}}
{{< /tabs >}}
<!--
You can attempt an eviction using `curl`:
-->
你可以使用 `curl` 尝试驱逐:
```bash
curl -v -H 'Content-type: application/json' http://127.0.0.1:8080/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json
```
<!--
The API can respond in one of three ways:
- If the eviction is granted, then the Pod is deleted as if you sent
a `DELETE` request to the Pod's URL and received back `200 OK`.
- If the current state of affairs wouldn't allow an eviction by the rules set
forth in the budget, you get back `429 Too Many Requests`. This is
typically used for generic rate limiting of *any* requests, but here we mean
that this request isn't allowed *right now* but it may be allowed later.
Currently, callers do not get any `Retry-After` advice, but they may in
future versions.
- If there is some kind of misconfiguration, like multiple budgets pointing at
the same pod, you will get `500 Internal Server Error`.
-->
API 可以通过以下三种方式之一进行响应:
- 如果驱逐被授权,那么 Pod 将被删掉,并且你会收到 `200 OK`
就像你向 Pod 的 URL 发送了 `DELETE` 请求一样。
- 如果按照预算中规定,目前的情况不允许的驱逐,你会收到 `429 Too Many Requests`
这通常用于对 *一些* 请求进行通用速率限制,
但这里我们的意思是:此请求 *现在* 不允许,但以后可能会允许。
目前,调用者不会得到任何 `Retry-After` 的提示,但在将来的版本中可能会得到。
- 如果有一些错误的配置,比如多个预算指向同一个 Pod,你将得到 `500 Internal Server Error`
<!--
For a given eviction request, there are two cases:
- There is no budget that matches this pod. In this case, the server always
returns `200 OK`.
- There is at least one budget. In this case, any of the three above responses may
apply.
-->
对于一个给定的驱逐请求,有两种情况:
- 没有匹配这个 Pod 的预算。这种情况,服务器总是返回 `200 OK`
- 至少匹配一个预算。在这种情况下,上述三种回答中的任何一种都可能适用。
<!--
## Stuck evictions
In some cases, an application may reach a broken state, one where unless you intervene the
eviction API will never return anything other than 429 or 500.
For example: this can happen if ReplicaSet is creating Pods for your application but
the replacement Pods do not become `Ready`. You can also see similar symptoms if the
last Pod evicted has a very long termination grace period.
-->
## 驱逐阻塞
在某些情况下,应用程序可能会到达一个中断状态,除了 429 或 500 之外,它将永远不会返回任何内容。
例如 ReplicaSet 创建的替换 Pod 没有变成就绪状态,或者被驱逐的最后一个
Pod 有很长的终止宽限期,就会发生这种情况。
<!--
In this case, there are two potential solutions:
- Abort or pause the automated operation. Investigate the reason for the stuck application,
and restart the automation.
- After a suitably long wait, `DELETE` the Pod from your cluster's control plane, instead
of using the eviction API.
Kubernetes does not specify what the behavior should be in this case; it is up to the
application owners and cluster owners to establish an agreement on behavior in these cases.
-->
在这种情况下,有两种可能的解决方案:
- 中止或暂停自动操作。调查应用程序卡住的原因,并重新启动自动化。
- 经过适当的长时间等待后,从集群中删除 Pod 而不是使用驱逐 API。
Kubernetes 并没有具体说明在这种情况下应该采取什么行为,
这应该由应用程序所有者和集群所有者紧密沟通,并达成对行动一致意见。
更多信息,请参阅 [API 发起的驱逐](/zh/docs/concepts/scheduling-eviction/api-eviction/)。
## {{% heading "whatsnext" %}}
@@ -257,10 +257,10 @@ to the metadata API, and avoid using provisioning data to deliver secrets.
-->
### 限制云元数据 API 访问
云平台(AWSAzureGCE 等)经常将元数据服务暴露给本地实例。
默认情况下,这些 API 可由运行在实例上的 Pod 访问,且其中可能包含该云节点的凭据或配置数据
(如 kubelet 凭据)。
这些凭据可以用于在集群内提升权限或获得权限访问同一账户的其他云服务。
云平台(AWS, Azure, GCE 等)经常将 metadata 本地服务暴露给实例。
默认情况下,这些 API 可由运行在实例上的 Pod 访问,并且可以包含
该云节点的凭据或配置数据(如 kubelet 凭据)。
这些凭据可以用于在集群内升级或在同一账户下升级到其他云服务。
在云平台上运行 Kubernetes 时,需要限制对实例凭据的权限,使用
[网络策略](/zh/docs/tasks/administer-cluster/declare-network-policy/)
@@ -122,7 +122,7 @@ The following sysctls are supported in the _safe_ set:
- `net.ipv4.ip_local_port_range`
- `net.ipv4.tcp_syncookies`
- `net.ipv4.ping_group_range` (从 Kubernetes 1.18 开始)
- `net.ipv4.ip_unprivileged_port_start` (从 Kubernetes 1.22 开始).
- `net.ipv4.ip_unprivileged_port_start` 从 Kubernetes 1.22 开始)。
<!--
The example `net.ipv4.tcp_syncookies` is not namespaced on Linux kernel version 4.4 or lower.
@@ -46,7 +46,7 @@ as Windows server containers, meaning that the version of the base images does n
to match that of the host. It is, however, recommended that you use the same base image
version as your Windows Server container workloads to ensure you do not have any unused
images taking up space on the node. HostProcess containers also support
[volume mounts](./create-hostprocess-pod#volume-mounts) within the container volume.
[volume mounts](#volume-mounts) within the container volume.
-->
类似于安装安全补丁、事件日志收集等这类管理性质的任务可以在不需要集群操作员登录到每个
Windows 节点的前提下执行。HostProcess 容器可以以主机上存在的任何用户账户来运行,
@@ -58,7 +58,7 @@ Windows 节点的前提下执行。HostProcess 容器可以以主机上存在的
这意味着基础镜像的版本不必与主机操作系统的版本匹配。
不过,仍然建议你像使用 Windows 服务器容器负载那样,使用相同的基础镜像版本,
这样你就不会有一些未使用的镜像占用节点上的存储空间。HostProcess 容器也支持
在容器卷内执行[卷挂载](./create-hostprocess-pod#volume-mounts)。
在容器卷内执行[卷挂载](#volume-mounts)。
<!--
### When should I use a Windows HostProcess container?
@@ -130,12 +130,12 @@ These limitations are relevant for Kubernetes v{{< skew currentVersion >}}:
<!--
- HostProcess containers require containerd 1.6 or higher
{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}}.
{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}}.
- HostProcess pods can only contain HostProcess containers. This is a current limitation
of the Windows OS; non-privileged Windows containers cannot share a vNIC with the host IP namespace.
of the Windows OS; non-privileged Windows containers cannot share a vNIC with the host IP namespace.
- HostProcess containers run as a process on the host and do not have any degree of
isolation other than resource constraints imposed on the HostProcess user account. Neither
filesystem or Hyper-V isolation are supported for HostProcess containers.
isolation other than resource constraints imposed on the HostProcess user account. Neither
filesystem or Hyper-V isolation are supported for HostProcess containers.
-->
- HostProcess 容器需要 containerd 1.6 或更高版本的
{{< glossary_tooltip text="容器运行时" term_id="container-runtime" >}}。
@@ -145,13 +145,14 @@ filesystem or Hyper-V isolation are supported for HostProcess containers.
用户账号所实施的资源约束外,不提供任何形式的隔离。HostProcess 容器不支持文件系统或
Hyper-V 隔离。
<!--
- Volume mounts are supported and are mounted under the container volume. See [Volume Mounts](#volume-mounts)
- Volume mounts are supported and are mounted under the container volume. See
[Volume Mounts](#volume-mounts)
- A limited set of host user accounts are available for HostProcess containers by default.
See [Choosing a User Account](#choosing-a-user-account).
- Resource limits (disk, memory, cpu count) are supported in the same fashion as processes
on the host.
on the host.
- Both Named pipe mounts and Unix domain sockets are **not** supported and should instead
be accessed via their path on the host (e.g. \\\\.\\pipe\\\*)
be accessed via their path on the host (e.g. \\\\.\\pipe\\\*)
-->
- 卷挂载是被支持的,并且要花在到容器卷下。参见[卷挂载](#volume-mounts)。
- 默认情况下有一组主机用户账户可供 HostProcess 容器使用。
@@ -1,5 +1,5 @@
---
title: 为 Pod 或容器配置安全上下文
title: 为 Pod 或容器配置安全上下文
content_type: task
weight: 80
---
@@ -21,7 +21,8 @@ a Pod or Container. Security context settings include, but are not limited to:
* Discretionary Access Control: Permission to access an object, like a file, is based on
[user ID (UID) and group ID (GID)](https://wiki.archlinux.org/index.php/users_and_groups).
* [Security Enhanced Linux (SELinux)](https://en.wikipedia.org/wiki/Security-Enhanced_Linux): Objects are assigned security labels.
* [Security Enhanced Linux (SELinux)](https://en.wikipedia.org/wiki/Security-Enhanced_Linux):
Objects are assigned security labels.
* Running as privileged or unprivileged.
* [Linux Capabilities](https://linux-audit.com/linux-capabilities-hardening-linux-binaries-by-removing-setuid/):
Give a process some privileges, but not all the privileges of the root user.
@@ -29,8 +30,8 @@ a Pod or Container. Security context settings include, but are not limited to:
安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置。
安全上下文包括但不限于:
* 自主访问控制(Discretionary Access Control):基于
[用户 IDUID)和组 IDGID](https://wiki.archlinux.org/index.php/users_and_groups).
* 自主访问控制(Discretionary Access Control):
基于[用户 IDUID)和组 IDGID](https://wiki.archlinux.org/index.php/users_and_groups)
来判定对对象(例如文件)的访问权限。
* [安全性增强的 LinuxSELinux](https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E5%A2%9E%E5%BC%BA%E5%BC%8FLinux)
为对象赋予安全性标签。
@@ -38,21 +39,31 @@ a Pod or Container. Security context settings include, but are not limited to:
* [Linux 权能](https://linux-audit.com/linux-capabilities-hardening-linux-binaries-by-removing-setuid/):
为进程赋予 root 用户的部分特权而非全部特权。
<!--
* [AppArmor](/docs/tutorials/clusters/apparmor/): Use program profiles to restrict the capabilities of individual programs.
* [Seccomp](/docs/tutorials/clusters/seccomp/): Filter a process's system calls.
* AllowPrivilegeEscalation: Controls whether a process can gain more
privileges than its parent process. This bool directly controls whether the
* [AppArmor](/docs/tutorials/security/apparmor/):
Use program profiles to restrict the capabilities of individual programs.
* [Seccomp](/docs/tutorials/security/seccomp/): Filter a process's system calls.
* `allowPrivilegeEscalation`: Controls whether a process can gain more privileges than
its parent process. This bool directly controls whether the
[`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt)
flag gets set on the container process. AllowPrivilegeEscalation is true
always when the container is: 1) run as Privileged OR 2) has `CAP_SYS_ADMIN`.
flag gets set on the container process.
`allowPrivilegeEscalation` is always true
when the container:
- is run as privileged, or
- has `CAP_SYS_ADMIN`
* readOnlyRootFilesystem: Mounts the container's root filesystem as read-only.
-->
* [AppArmor](/zh/docs/tutorials/clusters/apparmor/):使用程序框架来限制个别程序的权能。
* [Seccomp](/zh/docs/tutorials/clusters/seccomp/):过滤进程的系统调用。
* AllowPrivilegeEscalation:控制进程是否可以获得超出其父进程的特权。
* [AppArmor](/zh/docs/tutorials/security/apparmor/):使用程序配置来限制个别程序的权能。
* [Seccomp](/zh/docs/tutorials/security/seccomp/):过滤进程的系统调用。
* `allowPrivilegeEscalation`:控制进程是否可以获得超出其父进程的特权。
此布尔值直接控制是否为容器进程设置
[`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt)标志。
当容器以特权模式运行或者具有 `CAP_SYS_ADMIN` 权能时,AllowPrivilegeEscalation 总是为 true
当容器满足一下条件之一时,`allowPrivilegeEscalation` 总是为 true
- 以特权模式运行,或者
- 具有 `CAP_SYS_ADMIN` 权能
* readOnlyRootFilesystem:以只读方式加载容器的根文件系统。
<!--
@@ -213,19 +224,24 @@ Run the following command:
id
```
输出为:
```
<!--
The output is similar to this:
-->
输出类似于:
```none
uid=1000 gid=3000 groups=2000
```
<!--
You will see that gid is 3000 which is same as `runAsGroup` field. If the `runAsGroup` was omitted the gid would
remain as 0(root) and the process will be able to interact with files that are owned by root(0) group and that have
the required group permissions for root(0) group.
From the output, you can see that `gid` is 3000 which is same as the `runAsGroup` field.
If the `runAsGroup` was omitted, the `gid` would remain as 0 (root) and the process will
be able to interact with files that are owned by the root(0) group and groups that have
the required group permissions for the root (0) group.
Exit your shell:
-->
你会看到 `gid` 值为 3000,也就是 `runAsGroup` 字段的值。
从输出中你会看到 `gid` 值为 3000,也就是 `runAsGroup` 字段的值。
如果 `runAsGroup` 被忽略,则 `gid` 会取值 0(root),而进程就能够与 root
用户组所拥有以及要求 root 用户组访问权限的文件交互。
@@ -251,18 +267,21 @@ slowing Pod startup. You can use the `fsGroupChangePolicy` field inside a `secur
to control the way that Kubernetes checks and manages ownership and permissions
for a volume.
-->
默认情况下,Kubernetes 在挂载一个卷时,会递归地更改每个卷中的内容的属主和访问权限,使之与 Pod
`securityContext` 中指定的 `fsGroup` 匹配。
默认情况下,Kubernetes 在挂载一个卷时,会递归地更改每个卷中的内容的属主和访问权限,
使之与 Pod `securityContext` 中指定的 `fsGroup` 匹配。
对于较大的数据卷,检查和变更属主与访问权限可能会花费很长时间,降低 Pod 启动速度。
你可以在 `securityContext` 中使用 `fsGroupChangePolicy` 字段来控制 Kubernetes
检查和管理卷属主和访问权限的方式。
<!--
**fsGroupChangePolicy** - `fsGroupChangePolicy` defines behavior for changing ownership and permission of the volume
before being exposed inside a Pod. This field only applies to volume types that support
`fsGroup` controlled ownership and permissions. This field has two possible values:
**fsGroupChangePolicy** - `fsGroupChangePolicy` defines behavior for changing ownership
and permission of the volume before being exposed inside a Pod.
This field only applies to volume types that support `fsGroup` controlled ownership and permissions.
This field has two possible values:
* _OnRootMismatch_: Only change permissions and ownership if permission and ownership of root directory does not match with expected permissions of the volume. This could help shorten the time it takes to change ownership and permission of a volume.
* _OnRootMismatch_: Only change permissions and ownership if permission and ownership of
root directory does not match with expected permissions of the volume.
This could help shorten the time it takes to change ownership and permission of a volume.
* _Always_: Always change permission and ownership of the volume when volume is mounted.
For example:
@@ -293,7 +312,7 @@ This field has no effect on ephemeral volume types such as
and [`emptydir`](/docs/concepts/storage/volumes/#emptydir).
-->
{{< note >}}
此字段对于[`secret`](/zh/docs/concepts/storage/volumes/#secret)、
此字段对于 [`secret`](/zh/docs/concepts/storage/volumes/#secret)、
[`configMap`](/zh/docs/concepts/storage/volumes/#configmap)
和 [`emptydir`](/zh/docs/concepts/storage/volumes/#emptydir)
这类临时性存储无效。
@@ -316,23 +335,24 @@ ownership and permission change, `fsGroupChangePolicy` does not take effect, and
as specified by CSI, the driver is expected to mount the volume with the
provided `fsGroup`, resulting in a volume that is readable/writable by the
`fsGroup`.
-->
如果你部署了一个[容器存储接口 (CSI)](https://github.com/container-storage-interface/spec/blob/master/spec.md)
驱动,而该驱动支持 `VOLUME_MOUNT_GROUP` `NodeServiceCapability`
`securityContext` 中指定 `fsGroup` 来设置文件所有权和权限的过程将由 CSI
驱动而不是 Kubernetes 来执行,前提是 Kubernetes 的 `DelegateFSGroupToCSIDriver`
特性门控已启用。在这种情况下,由于 Kubernetes 不执行任何所有权和权限更改,
`fsGroupChangePolicy` 不会生效,并且按照 CSI 的规定,CSI 驱动应该使用所指定的
`fsGroup` 来挂载卷,从而生成了一个对 `fsGroup` 可读/可写的卷.
<!--
Please refer to the [KEP](https://github.com/gnufied/enhancements/blob/master/keps/sig-storage/2317-fsgroup-on-mount/README.md)
and the description of the `VolumeCapability.MountVolume.volume_mount_group`
field in the [CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume)
for more information.
-->
如果你部署了一个[容器存储接口 (CSI)](https://github.com/container-storage-interface/spec/blob/master/spec.md)
驱动支持 `VOLUME_MOUNT_GROUP` `NodeServiceCapability`
`securityContext` 中指定 `fsGroup` 来设置文件所有权和权限的过程将由 CSI 驱动
而不是 Kubernetes 来执行,前提是 Kubernetes 的 `DelegateFSGroupToCSIDriver`
特性门控已启用。在这种情况下,由于 Kubernetes 不执行任何
所有权和权限更改,`fsGroupChangePolicy` 不会生效,并且
按照 CSI 的规定,CSI 驱动应该使用所指定的 `fsGroup` 来挂载卷,从而生成了一个对 `fsGroup` 可读/可写的卷.
更多的信息请参考 [KEP](https://github.com/gnufied/enhancements/blob/master/keps/sig-storage/2317-fsgroup-on-mount/README.md)
和 [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume) 中的字
`VolumeCapability.MountVolume.volume_mount_group` 的描述
和 [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume)
中的字`VolumeCapability.MountVolume.volume_mount_group` 的描述。
<!--
## Set the security context for a Container
@@ -352,9 +372,8 @@ and the Container have a `securityContext` field:
若要为 Container 设置安全性配置,可以在 Container 清单中包含 `securityContext`
字段。`securityContext` 字段的取值是一个
[SecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)
对象。你为 Container 设置的安全性配置仅适用于该容器本身,并且所指定的设置
在与 Pod 层面设置的内容发生重叠时,会重载后者。Container 层面的设置不会影响
到 Pod 的卷。
对象。你为 Container 设置的安全性配置仅适用于该容器本身,并且所指定的设置在与
Pod 层面设置的内容发生重叠时,会重载后者。Container 层面的设置不会影响到 Pod 的卷。
下面是一个 Pod 的配置文件,其中包含一个 Container。Pod 和 Container 都有
`securityContext` 字段:
@@ -402,7 +421,7 @@ The output shows that the processes are running as user 2000. This is the value
of `runAsUser` specified for the Container. It overrides the value 1000 that is
specified for the Pod.
-->
输出显示进程以用户 2000 账号运行。该值是在 Container 的 `runAsUser` 中设置的。
输出显示进程以用户 2000 运行。该值是在 Container 的 `runAsUser` 中设置的。
该设置值重载了 Pod 层面所设置的值 1000。
```
@@ -434,12 +453,12 @@ Here is configuration file that does not add or remove any Container capabilitie
-->
## 为 Container 设置权能 {#set-capabilities-for-a-container}
使用 [Linux 权能](https://man7.org/linux/man-pages/man7/capabilities.7.html)你可以
赋予进程 root 用户所拥有的某些特权,但不必赋予其全部特权。
要为 Container 添加或移除 Linux 权能,可以在 Container 清单的 `securityContext`
包含 `capabilities` 字段。
使用 [Linux 权能](https://man7.org/linux/man-pages/man7/capabilities.7.html)
你可以赋予进程 root 用户所拥有的某些特权,但不必赋予其全部特权。
要为 Container 添加或移除 Linux 权能,可以在 Container 清单的 `securityContext`
包含 `capabilities` 字段。
首先,看不包含 `capabilities` 字段时候会发生什么。
首先,看一下不包含 `capabilities` 字段时候会发生什么。
下面是一个配置文件,其中没有添加或移除容器的权能:
{{< codenew file="pods/security/security-context-3.yaml" >}}
@@ -598,12 +617,15 @@ for definitions of the capability constants.
了解权能常数的定义。
<!--
Linux capability constants have the form `CAP_XXX`. But when you list capabilities in your Container manifest, you must omit the `CAP_` portion of the constant. For example, to add `CAP_SYS_TIME`, include `SYS_TIME` in your list of capabilities.
Linux capability constants have the form `CAP_XXX`.
But when you list capabilities in your Container manifest, you must
omit the `CAP_` portion of the constant.
For example, to add `CAP_SYS_TIME`, include `SYS_TIME` in your list of capabilities.
-->
{{< note >}}
Linux 权能常数定义的形式为 `CAP_XXX`。但是你在 Container 清单中列举权能时,
要将权能名称中的 `CAP_` 部分去掉。例如,要添加 `CAP_SYS_TIME`可在权能
列表中添加 `SYS_TIME`
要将权能名称中的 `CAP_` 部分去掉。例如,要添加 `CAP_SYS_TIME`
可在权能列表中添加 `SYS_TIME`
{{< /note >}}
<!--
@@ -623,18 +645,18 @@ flag).
Here is an example that sets the Seccomp profile to the node's container runtime
default profile:
-->
## 为容器设置 Seccomp 样板
## 为容器设置 Seccomp 配置
若要为容器设置 Seccomp 样板Profile),可在你的 Pod 或 Container 清单的
若要为容器设置 Seccomp 配置Profile),可在你的 Pod 或 Container 清单的
`securityContext` 节中包含 `seccompProfile` 字段。该字段是一个
[SeccompProfile](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#seccompprofile-v1-core)
对象,包含 `type``localhostProfile` 属性。
`type` 的合法选项包括 `RuntimeDefault``Unconfined``Localhost`
`localhostProfile` 只能在 `type: Localhost` 配置下才需要设置。
该字段标明节点上预先配置的样板的路径,路径是相对于 kubelet 所配置的
Seccomp 样板路径(使用 `--root-dir` 置)而言的。
`localhostProfile` 只能在 `type: Localhost` 配置下才可以设置。
该字段标明节点上预先设定的配置的路径,路径是相对于 kubelet 所配置的
Seccomp 配置路径(使用 `--root-dir` 置)而言的。
下面是一个例子,设置容器使用节点上容器运行时的默认样板作为 Seccomp 样板
下面是一个例子,设置容器使用节点上容器运行时的默认配置作为 Seccomp 配置
```yaml
...
@@ -704,15 +726,15 @@ Pod 的安全上下文适用于 Pod 中的容器,也适用于 Pod 所挂载的
<!--
* `fsGroup`: Volumes that support ownership management are modified to be owned
and writable by the GID specified in `fsGroup`. See the
[Ownership Management design document](https://git.k8s.io/community/contributors/design-proposals/storage/volume-ownership-management.md)
for more details.
and writable by the GID specified in `fsGroup`. See the
[Ownership Management design document](https://git.k8s.io/community/contributors/design-proposals/storage/volume-ownership-management.md)
for more details.
* `seLinuxOptions`: Volumes that support SELinux labeling are relabeled to be accessible
by the label specified under `seLinuxOptions`. Usually you only
need to set the `level` section. This sets the
[Multi-Category Security (MCS)](https://selinuxproject.org/page/NB_MLS)
label given to all Containers in the Pod as well as the Volumes.
by the label specified under `seLinuxOptions`. Usually you only
need to set the `level` section. This sets the
[Multi-Category Security (MCS)](https://selinuxproject.org/page/NB_MLS)
label given to all Containers in the Pod as well as the Volumes.
-->
* `fsGroup`:支持属主管理的卷会被修改,将其属主变更为 `fsGroup` 所指定的 GID
并且对该 GID 可写。进一步的细节可参阅
@@ -763,9 +785,9 @@ kubectl delete pod security-context-demo-4
-->
* [PodSecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritycontext-v1-core) API 定义
* [SecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core) API 定义
* [使用最新的安全性增强来调优 Docker](https://github.com/containerd/containerd/blob/main/docs/cri/config.md)
* [安全上下文的设计文档](https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md)
* [属主管理的设计文档](https://git.k8s.io/community/contributors/design-proposals/storage/volume-ownership-management.md)
* [使用最新的安全性增强来调优 Docker(英文)](https://github.com/containerd/containerd/blob/main/docs/cri/config.md)
* [安全上下文的设计文档(英文)](https://git.k8s.io/community/contributors/design-proposals/auth/security_context.md)
* [属主管理的设计文档(英文)](https://git.k8s.io/community/contributors/design-proposals/storage/volume-ownership-management.md)
* [Pod 安全策略](/zh/docs/concepts/policy/pod-security-policy/)
* [AllowPrivilegeEscalation 的设计文档](https://git.k8s.io/community/contributors/design-proposals/auth/no-new-privs.md)
* [AllowPrivilegeEscalation 的设计文档(英文)](https://git.k8s.io/community/contributors/design-proposals/auth/no-new-privs.md)
@@ -285,10 +285,7 @@ you need is an existing `docker-compose.yml` file.
<!--
- CLI
- [`kompose convert`](#kompose-convert)
- [`kompose up`](#kompose-up)
- [`kompose down`](#kompose-down)
- Documentation
- [Build and Push Docker Images](#build-and-push-docker-images)
- [Alternative Conversions](#alternative-conversions)
- [Labels](#labels)
- [Restart](#restart)
@@ -296,11 +293,8 @@ you need is an existing `docker-compose.yml` file.
-->
- CLI
- [`kompose convert`](#kompose-convert)
- [`kompose up`](#kompose-up)
- [`kompose down`](#kompose-down)
- 文档
- [构建和推送 Docker 镜像](#build-and-push-docker-images)
- [其他转换方式](#其他转换方式)
- [标签](#labels)
- [重启](#restart)
@@ -447,219 +441,6 @@ If you are manually pushing the Openshift artifacts using ``oc create -f``, you
imagestream 工件,以解决 Openshift 的这个问题:https://github.com/openshift/origin/issues/4518 。
{{< /note >}}
## `kompose up`
<!--
Kompose supports a straightforward way to deploy your "composed" application to Kubernetes or OpenShift via `kompose up`.
-->
Kompose 支持通过 `kompose up` 直接将你的"复合的(composed" 应用程序
部署到 Kubernetes 或 OpenShift。
<!--
### Kubernetes `kompose up` example
-->
### Kubernetes `kompose up` 示例
```shell
kompose --file ./examples/docker-guestbook.yml up
```
```none
We are going to create Kubernetes deployments and services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
INFO Successfully created service: redis-master
INFO Successfully created service: redis-slave
INFO Successfully created service: frontend
INFO Successfully created deployment: redis-master
INFO Successfully created deployment: redis-slave
INFO Successfully created deployment: frontend
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods' for details.
```
```shell
kubectl get deployment,svc,pods
```
```
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.extensions/frontend 1 1 1 1 4m
deployment.extensions/redis-master 1 1 1 1 4m
deployment.extensions/redis-slave 1 1 1 1 4m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frontend ClusterIP 10.0.174.12 <none> 80/TCP 4m
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 13d
service/redis-master ClusterIP 10.0.202.43 <none> 6379/TCP 4m
service/redis-slave ClusterIP 10.0.1.85 <none> 6379/TCP 4m
NAME READY STATUS RESTARTS AGE
pod/frontend-2768218532-cs5t5 1/1 Running 0 4m
pod/redis-master-1432129712-63jn8 1/1 Running 0 4m
pod/redis-slave-2504961300-nve7b 1/1 Running 0 4m
```
{{< note >}}
<!--
- You must have a running Kubernetes cluster with a pre-configured kubectl context.
- Only deployments and services are generated and deployed to Kubernetes. If you need different kind of resources, use the `kompose convert` and `kubectl create -f` commands instead.
-->
- 你必须有一个运行正常的 Kubernetes 集群,该集群具有预先配置的 kubectl 上下文。
- 此操作仅生成 Deployment 和 Service 对象并将其部署到 Kubernetes。
如果需要部署其他不同类型的资源,请使用 `kompose convert``kubectl create -f` 命令。
{{< /note >}}
<!--
### OpenShift `kompose up` example
-->
### OpenShift `kompose up` 示例
```shell
kompose --file ./examples/docker-guestbook.yml --provider openshift up
```
```none
We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead.
INFO Successfully created service: redis-slave
INFO Successfully created service: frontend
INFO Successfully created service: redis-master
INFO Successfully created deployment: redis-slave
INFO Successfully created ImageStream: redis-slave
INFO Successfully created deployment: frontend
INFO Successfully created ImageStream: frontend
INFO Successfully created deployment: redis-master
INFO Successfully created ImageStream: redis-master
Your application has been deployed to OpenShift. You can run 'oc get dc,svc,is' for details.
```
```shell
oc get dc,svc,is
```
```none
NAME REVISION DESIRED CURRENT TRIGGERED BY
dc/frontend 0 1 0 config,image(frontend:v4)
dc/redis-master 0 1 0 config,image(redis-master:e2e)
dc/redis-slave 0 1 0 config,image(redis-slave:v1)
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/frontend 172.30.46.64 <none> 80/TCP 8s
svc/redis-master 172.30.144.56 <none> 6379/TCP 8s
svc/redis-slave 172.30.75.245 <none> 6379/TCP 8s
NAME DOCKER REPO TAGS UPDATED
is/frontend 172.30.12.200:5000/fff/frontend
is/redis-master 172.30.12.200:5000/fff/redis-master
is/redis-slave 172.30.12.200:5000/fff/redis-slave v1
```
{{< note >}}
<!--
You must have a running OpenShift cluster with a pre-configured `oc` context (`oc login`)
-->
你必须有一个运行正常的 OpenShift 集群,该集群具有预先配置的 `oc` 上下文 (`oc login`)。
{{< /note >}}
## `kompose down`
<!--
Once you have deployed "composed" application to Kubernetes, `$ kompose down` will help you to take the application out by deleting its deployments and services. If you need to remove other resources, use the 'kubectl' command.
-->
你一旦将"复合(composed)" 应用部署到 Kubernetes`kompose down`
命令将能帮你通过删除 Deployment 和 Service 对象来删除应用。
如果需要删除其他资源,请使用 'kubectl' 命令。
```shell
kompose --file docker-guestbook.yml down
```
```
INFO Successfully deleted service: redis-master
INFO Successfully deleted deployment: redis-master
INFO Successfully deleted service: redis-slave
INFO Successfully deleted deployment: redis-slave
INFO Successfully deleted service: frontend
INFO Successfully deleted deployment: frontend
```
{{< note >}}
<!--
You must have a running Kubernetes cluster with a pre-configured kubectl context.
-->
- 你必须有一个运行正常的 Kubernetes 集群,该集群具有预先配置的 kubectl 上下文。
{{< /note >}}
<!--
## Build and Push Docker Images
Kompose supports both building and pushing Docker images. When using the `build` key within your Docker Compose file, your image will:
- Automatically be built with Docker using the `image` key specified within your file
- Be pushed to the correct Docker repository using local credentials (located at `.docker/config`)
Using an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/buildconfig/docker-compose.yml):
-->
## 构建和推送 Docker 镜像 {#build-and-push-docker-images}
Kompose 支持构建和推送 Docker 镜像。如果 Docker Compose 文件中使用了 `build`
关键字,你的镜像将会:
- 使用文档中指定的 `image` 键自动构建 Docker 镜像
- 使用本地凭据推送到正确的 Docker 仓库
使用 [Docker Compose 文件示例](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/buildconfig/docker-compose.yml)
```yaml
version: "2"
services:
foo:
build: "./build"
image: docker.io/foo/bar
```
<!--
Using `kompose up` with a `build` key:
-->
使用带有 `build` 键的 `kompose up` 命令:
```shell
kompose up
```
```none
INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar'
INFO Building image 'docker.io/foo/bar' from directory 'build'
INFO Image 'docker.io/foo/bar' from directory 'build' built successfully
INFO Pushing image 'foo/bar:latest' to registry 'docker.io'
INFO Attempting authentication credentials 'https://index.docker.io/v1/
INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io'
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
INFO Deploying application in "default" namespace
INFO Successfully created Service: foo
INFO Successfully created Deployment: foo
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
```
<!--
In order to disable the functionality, or choose to use BuildConfig generation (with OpenShift) `--build (local|build-config|none)` can be passed.
-->
要想禁用该功能,或者使用 BuildConfig 中的版本(在 OpenShift 中),
可以通过传递 `--build (local|build-config|none)` 参数来实现。
```shell
# 禁止构造和推送 Docker 镜像
kompose up --build none
# 为 OpenShift 生成 Build Config 工件
kompose up --provider openshift --build build-config
```
<!--
## Alternative Conversions
@@ -46,8 +46,7 @@ with your new arguments.
如果在配置文件中设置了容器启动时要执行的命令及其参数,那么容器镜像中自带的命令与参数将会被覆盖而不再执行。如果配置文件中只是设置了参数,却没有设置其对应的命令,那么容器镜像中自带的命令会使用该新参数作为其执行时的参数。
<!--
The `command` field corresponds to `entrypoint` in some container
runtimes. Refer to the [Notes](#notes) below.
The `command` field corresponds to `entrypoint` in some container runtimes.
-->
{{< note >}}
在有些容器运行时中,`command` 字段对应 `entrypoint`,请参阅下面的
@@ -161,73 +160,6 @@ command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
```
<!--
## Notes
This table summarizes the field names used by Docker and Kubernetes.
| Description | Docker field name | Kubernetes field name |
|----------------------------------------|------------------------|---------------------|
| The command run by the container | Entrypoint | command |
| The arguments passed to the command | Cmd | args |
-->
## 说明事项 {#notes}
下表给出了 Docker 与 Kubernetes 中对应的字段名称。
| 描述 | Docker 字段名称 | Kubernetes 字段名称 |
|--------------------|--------------------|-----------------------|
| 容器执行的命令 | Entrypoint | command |
| 传给命令的参数 | Cmd | args |
<!--
When you override the default Entrypoint and Cmd, these rules apply:
* If you do not supply `command` or `args` for a Container, the defaults defined
in the Docker image are used.
* If you supply a `command` but no `args` for a Container, only the supplied
`command` is used. The default EntryPoint and the default Cmd defined in the Docker
image are ignored.
* If you supply only `args` for a Container, the default Entrypoint defined in
the Docker image is run with the `args` that you supplied.
* If you supply a `command` and `args`, the default Entrypoint and the default
Cmd defined in the Docker image are ignored. Your `command` is run with your
`args`.
-->
如果要覆盖默认的 Entrypoint 与 Cmd,需要遵循如下规则:
* 如果在容器配置中没有设置 `command` 或者 `args`,那么将使用 Docker 镜像自带的命令及其参数。
* 如果在容器配置中只设置了 `command` 但是没有设置 `args`,那么容器启动时只会执行该命令,
Docker 镜像中自带的命令及其参数会被忽略。
* 如果在容器配置中只设置了 `args`,那么 Docker 镜像中自带的命令会使用该新参数作为其执行时的参数。
* 如果在容器配置中同时设置了 `command``args`,那么 Docker 镜像中自带的命令及其参数会被忽略。
容器启动时只会执行配置中设置的命令,并使用配置中设置的参数作为命令的参数。
<!--
Here are some examples:
| 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]` |
-->
下面是一些例子:
| 镜像 Entrypoint | 镜像 Cmd | 容器 command | 容器 args | 命令执行 |
|--------------------|------------------|---------------------|--------------------|------------------|
| `[/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]` |
## {{% heading "whatsnext" %}}
@@ -30,6 +30,7 @@ Cron jobs can also schedule individual tasks for a specific time, such as if you
-->
在Kubernetes v1.21 版本中,CronJob 被提升为通用版本。如果你使用的是旧版本的 Kubernetes,请参考你正在使用的 Kubernetes 版本的文档,这样你就能看到准确的信息。旧的 Kubernetes 版本不支持`batch/v1` CronJob API。
你可以利用 [CronJobs](/zh/docs/concepts/workloads/controllers/cron-jobs) 执行基于时间调度的任务。这些自动化任务和 Linux 或者 Unix 系统的 [Cron](https://en.wikipedia.org/wiki/Cron) 任务类似。
CronJobs 在创建周期性以及重复性的任务时很有帮助,例如执行备份操作或者发送邮件。CronJobs 也可以在特定时间调度单个任务,例如你想调度低活跃周期的任务。
@@ -43,6 +44,7 @@ For more limitations, see [CronJobs](/docs/concepts/workloads/controllers/cron-j
CronJobs 有一些限制和特点。
例如,在特定状况下,同一个 CronJob 可以创建多个任务。
因此,任务应该是幂等的。
查看更多限制,请参考 [CronJobs](/zh/docs/concepts/workloads/controllers/cron-jobs)。
## {{% heading "prerequisites" %}}
@@ -134,16 +136,14 @@ hello */1 * * * * False 0 50s 75s
```
<!--
You should see that the cron job "hello" successfully scheduled a job at the time specified in `LAST-SCHEDULE`.
There are currently 0 active jobs, meaning that the job has completed or failed.
You should see that the cron job `hello` successfully scheduled a job at the time specified in `LAST SCHEDULE`. There are currently 0 active jobs, meaning that the job has completed or failed.
Now, find the pods that the last scheduled job created and view the standard output of one of the pods.
Note that the job name and pod name are different.
-->
你应该能看到 hello CronJob 在 `LAST-SCHEDULE` 声明的时间点成功的调度了一次任务。
你应该能看到 `hello` CronJob 在 `LAST SCHEDULE` 声明的时间点成功的调度了一次任务。
有 0 个活跃的任务意味着任务执行完毕或者执行失败。
现在,找到最后一次调度任务创建的 Pod 并查看一个 Pod 的标准输出。请注意任务名称和 Pod 名称是不同的。
现在,找到最后一次调度任务创建的 Pod 并查看一个 Pod 的标准输出。
<!--
The job name and pod name are different.
@@ -165,6 +165,10 @@ Show pod log:
```shell
kubectl logs $pods
```
<!--
The output is similar to this:
-->
输出与此类似:
```
Fri Feb 22 11:02:09 UTC 2019
@@ -359,6 +363,6 @@ By default, they are set to 3 and 1 respectively. Setting a limit to `0` corres
`.spec.successfulJobsHistoryLimit``.spec.failedJobsHistoryLimit`是可选的。
这两个字段指定应保留多少已完成和失败的任务。
默认设置为3和1。限制设置为0代表相应类型的任务完成后不会保留。
默认设置为3和1。限制设置为 `0` 代表相应类型的任务完成后不会保留。
@@ -279,13 +279,13 @@ First, copy and paste the following template of a Job object, into a file called
首先,复制下面的 Job 对象模板到一个名为 `job.yaml.jinja2` 的文件。
```liquid
{%- set params = [{ "name": "apple", "url": "http://dbpedia.org/resource/Apple", },
{% set params = [{ "name": "apple", "url": "http://dbpedia.org/resource/Apple", },
{ "name": "banana", "url": "http://dbpedia.org/resource/Banana", },
{ "name": "cherry", "url": "http://dbpedia.org/resource/Cherry" }]
%}
{%- for p in params %}
{%- set name = p["name"] %}
{%- set url = p["url"] %}
{% for p in params %}
{% set name = p["name"] %}
{% set url = p["url"] %}
---
apiVersion: batch/v1
kind: Job
@@ -305,7 +305,7 @@ spec:
image: busybox
command: ["sh", "-c", "echo Processing URL {{ url }} && sleep 5"]
restartPolicy: Never
{%- endfor %}
{% endfor %}
```
<!--
@@ -66,13 +66,15 @@ You may want to set
(default to 1),
[`.spec.minReadySeconds`](/docs/concepts/workloads/controllers/deployment/#min-ready-seconds)
(default to 0) and
[`.spec.maxSurge`](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-surge)
(a beta feature and defaults to 25%) as well.
[`.spec.updateStrategy.rollingUpdate.maxSurge`](/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec)
(a beta feature and defaults to 0) as well.
-->
你可能想设置
[`.spec.updateStrategy.rollingUpdate.maxUnavailable`](/zh/docs/concepts/workloads/controllers/deployment/#max-unavailable) (默认为 1)
[`.spec.minReadySeconds`](/zh/docs/concepts/workloads/controllers/deployment/#min-ready-seconds) (默认为 0) 和
[`.spec.maxSurge`](/zh/docs/concepts/workloads/controllers/deployment/#max-surge) (一种 Beta 阶段的特性,默认为 25%)
[`.spec.updateStrategy.rollingUpdate.maxSurge`](/zh/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec)
(一种 Beta 阶段的特性,默认为 0)。
<!--
### Creating a DaemonSet with `RollingUpdate` update strategy
@@ -254,7 +254,7 @@ Patch your Deployment:
对 Deployment 执行 patch 操作:
```
kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"
kubectl patch deployment patch-demo --patch-file patch-file-tolerations.yaml"
```
<!--
@@ -368,7 +368,7 @@ In your patch command, set `type` to `merge`:
在 patch 命令中,将 `type` 设置为 `merge`
```shell
kubectl patch deployment patch-demo --type merge --patch "$(cat patch-file-2.yaml)"
kubectl patch deployment patch-demo --type merge --patch-file patch-file-2.yaml
```
<!--
@@ -450,14 +450,9 @@ spec:
<!-- Patch your Deployment: -->
修补你的 Deployment:
{{< tabs name="kubectl_retainkeys_example" >}}
{{{< tab name="Bash" codelang="bash" >}}
kubectl patch deployment retainkeys-demo --type merge --patch "$(cat patch-file-no-retainkeys.yaml)"
{{< /tab >}}
{{< tab name="PowerShell" codelang="posh" >}}
kubectl patch deployment retainkeys-demo --type merge --patch $(Get-Content patch-file-no-retainkeys.yaml -Raw)
{{< /tab >}}}
{{< /tabs >}}
```shell
kubectl patch deployment patch-demo --patch-file patch-file.yaml
```
<!--
In the output, you can see that it is not possible to set `type` as `Recreate` when a value is defined for `spec.strategy.rollingUpdate`:
@@ -497,14 +492,9 @@ Patch your Deployment again with this new patch:
使用新的 patch 重新修补 Deployment
{{< tabs name="kubectl_retainkeys2_example" >}}
{{{< tab name="Bash" codelang="bash" >}}
kubectl patch deployment retainkeys-demo --type merge --patch "$(cat patch-file-retainkeys.yaml)"
{{< /tab >}}
{{< tab name="PowerShell" codelang="posh" >}}
kubectl patch deployment retainkeys-demo --type merge --patch $(Get-Content patch-file-retainkeys.yaml -Raw)
{{< /tab >}}}
{{< /tabs >}}
```shell
kubectl patch deployment retainkeys-demo --type merge --patch-file patch-file-no-retainkeys.yaml
```
<!-- Examine the content of the Deployment: -->
检查 Deployment 的内容:
@@ -625,10 +615,10 @@ The following commands are equivalent:
以下命令是等价的:
```shell
kubectl patch deployment patch-demo --patch "$(cat patch-file.yaml)"
kubectl patch deployment patch-demo --patch-file patch-file.yaml"
kubectl patch deployment patch-demo --patch 'spec:\n template:\n spec:\n containers:\n - name: patch-demo-ctr-2\n image: redis'
kubectl patch deployment patch-demo --patch "$(cat patch-file.json)"
kubectl patch deployment patch-demo --patch-file patch-file.json"
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'
```
@@ -681,6 +671,3 @@ Strategic merge patch is not supported for custom resources.
* [使用配置文件执行 Kubernetes 对象的指令式管理](/zh/docs/tasks/manage-kubernetes-objects/imperative-config)
* [使用配置文件对 Kubernetes 对象进行声明式管理](/zh/docs/tasks/manage-kubernetes-objects/declarative-config/)
@@ -106,17 +106,23 @@ The following methods exist for installing kubectl on Windows:
```
<!--
1. Add the binary in to your `PATH`.
1. Append or prepend the kubectl binary folder to your `PATH` environment variable.
1. Test to ensure the version of `kubectl` is the same as downloaded:
Or use this for detailed view of version:
-->
1. 将可执行文件的路径添加到 `PATH`
1. 将 kubectl 二进制文件夹附加或添加到你的 `PATH` 环境变量中
1. 测试一下,确保此 `kubectl` 的版本和期望版本一致:
```cmd
kubectl version --client
```
或者使用下面命令来查看版本的详细信息:
```cmd
kubectl version --client --output=yaml
```
<!--
[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/#kubernetes) adds its own version of `kubectl` to `PATH`.
@@ -289,11 +295,11 @@ kubectl 为 Bash、Zsh、Fish 和 PowerShell 提供自动补全功能,可以
```
<!--
1. Add the binary in to your `PATH`.
1. Append or prepend the kubectl binary folder to your `PATH` environment variable.
1. Verify plugin is successfully installed
-->
1. 将可执行文件添加到你的 `PATH` 环境变量。
1. 将 kubectl 二进制文件夹附加或添加到你的 `PATH` 环境变量
1. 验证插件是否安装成功