From 058989e4f71cdbb4d5d8d637df81ccf2f5de47e3 Mon Sep 17 00:00:00 2001 From: zaunist Date: Thu, 12 May 2022 22:36:47 +0800 Subject: [PATCH] docs: Rsyc content/zh/docs/setup/production-environment/tools/kubeadm/ setup-1 --- .../tools/kubeadm/install-kubeadm.md | 122 +++++++++------- .../kubeadm/setup-ha-etcd-with-kubeadm.md | 134 +++++++++++------- .../tools/kubeadm/troubleshooting-kubeadm.md | 55 +++---- 3 files changed, 164 insertions(+), 147 deletions(-) diff --git a/content/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm.md b/content/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm.md index 51f9fd7758..411ac955b9 100644 --- a/content/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm.md +++ b/content/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm.md @@ -27,7 +27,6 @@ For information on how to create a cluster with kubeadm once you have performed 有关在执行此安装过程后如何使用 kubeadm 创建集群的信息,请参见 [使用 kubeadm 创建集群](/zh/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) 页面。 - ## {{% heading "prerequisites" %}} @@ -138,86 +136,103 @@ documentation for the plugins about what port(s) those need. 请参阅他们各自文档中对端口的要求。 -## 安装 runtime{#installing-runtime} +## 安装容器运行时{#installing-runtime} 为了在 Pod 中运行容器,Kubernetes 使用 {{< glossary_tooltip term_id="container-runtime" text="容器运行时(Container Runtime)" >}}。 -{{< tabs name="container-runtimes" >}} -{{% tab name="Linux 节点" %}} 默认情况下,Kubernetes 使用 {{< glossary_tooltip term_id="cri" text="容器运行时接口(Container Runtime Interface,CRI)" >}} 来与你所选择的容器运行时交互。 -如果你不指定运行时,则 kubeadm 会自动尝试检测到系统上已经安装的运行时, -方法是扫描一组众所周知的 Unix 域套接字。 -下面的表格列举了一些 kubeadm 查找的容器运行时及其对应的套接字路径: - -| 运行时 | 域套接字 | -|------------|----------------------------------| -| Docker Engine | `/var/run/dockershim.sock` | -| containerd | `/run/containerd/containerd.sock` | -| CRI-O | `/var/run/crio/crio.sock` | +如果你不指定运行时,kubeadm 会自动尝试通过扫描已知的端点列表来检测已安装的容器运行时。 -
-如果同时检测到 Docker Engine 和 containerd,kubeadm 将优先考虑 Docker Engine。 -这是必然的,因为 Docker 18.09 附带了 containerd 并且两者都是可以检测到的, -即使你仅安装了 Docker。 -**如果检测到其他两个或多个运行时,kubeadm 输出错误信息并退出。** - -kubelet 可以使用已弃用的 dockershim 适配器与 Docker Engine 集成(dockershim 是 kubelet 本身的一部分)。 +如果检测到有多个或者没有容器运行时,kubeadm 将抛出一个错误并要求你指定一个想要使用的运行时。 参阅[容器运行时](/zh/docs/setup/production-environment/container-runtimes/) 以了解更多信息。 -{{% /tab %}} -{{% tab name="其它操作系统" %}} -默认情况下, kubeadm 使用 {{< glossary_tooltip term_id="docker" >}} 作为容器运行时。 -kubelet 可以使用已弃用的 dockershim 适配器与 Docker Engine 集成(dockershim 是 kubelet 本身的一部分)。 -参阅[容器运行时](/zh/docs/setup/production-environment/container-runtimes/) -以了解更多信息。 -{{% /tab %}} -{{< /tabs >}} +{{< note >}} +Docker Engine 没有实现 [CRI](/zh/docs/concepts/architecture/cri/),而这是容器运行时在 Kubernetes 中工作所需要的。 +为此,必须安装一个额外的服务 [cri-dockerd](https://github.com/Mirantis/cri-dockerd)。 +cri-dockerd 是一个基于传统的内置Docker引擎支持的项目,它在 1.24 版本从 kubelet 中[移除](/zh/dockershim)。 +{{< /note >}} + + +下面的表格包括被支持的操作系统的已知端点。 + +{{< tabs name="container_runtime" >}} +{{% tab name="Linux" %}} + + +{{< table >}} +| 运行时 | Unix 域套接字 | +|------------------------------------|----------------------------------------------| +| containerd | `unix:///var/run/containerd/containerd.sock` | +| CRI-O | `unix:///var/run/crio/crio.sock` | +| Docker Engine (使用 cri-dockerd) | `unix:///var/run/cri-dockerd.sock` | +{{< /table >}} + + +{{% tab name="Windows" %}} + +{{< table >}} +| 运行时 | Windows 命名管道路径 | +|------------------------------------|----------------------------------------------| +| containerd | `npipe:////./pipe/containerd-containerd` | +| Docker Engine (使用 cri-dockerd) | `npipe:////./pipe/cri-dockerd` | +{{< /table >}} 定义要下载命令文件的目录。 @@ -475,7 +490,7 @@ for the management of cgroups on Linux machines. --> ## 配置 cgroup 驱动程序 {#configure-cgroup-driver} -容器运行时和 kubelet 都具有名字为 +容器运行时和 kubelet 都具有名字为 ["cgroup driver"](/zh/docs/setup/production-environment/container-runtimes/) 的属性,该属性对于在 Linux 机器上管理 CGroups 而言非常重要。 @@ -507,4 +522,3 @@ If you are running into difficulties with kubeadm, please consult our [troublesh * [Using kubeadm to Create a Cluster](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) --> * [使用 kubeadm 创建集群](/zh/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) - diff --git a/content/zh/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md b/content/zh/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md index fc30729efd..da6a3b0c18 100644 --- a/content/zh/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md +++ b/content/zh/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md @@ -7,7 +7,7 @@ weight: 70 @@ -22,46 +22,46 @@ or upgrades for such nodes. The long term plan is to empower the tool [etcdadm](https://github.com/kubernetes-sigs/etcdadm) to manage these aspects. --> -在本指南中,当 kubeadm 用作为外部 etcd 节点管理工具,请注意 kubeadm 不计划支持此类节点的证书更换或升级。对于长期规划是使用 [etcdadm](https://github.com/kubernetes-sigs/etcdadm) 增强工具来管理这方面。 +在本指南中,使用 kubeadm 作为外部 etcd 节点管理工具,请注意 kubeadm 不计划支持此类节点的证书更换或升级。 +对于长期规划是使用 [etcdadm](https://github.com/kubernetes-sigs/etcdadm) 增强工具来管理这些方面。 {{< /note >}} -默认情况下,kubeadm 运行单成员的 etcd 集群,该集群由控制面节点上的 kubelet 以静态 Pod 的方式进行管理。由于 etcd 集群只包含一个成员且不能在任一成员不可用时保持运行,所以这不是一种高可用设置。本任务,将告诉你如何在使用 kubeadm 创建一个 kubernetes 集群时创建一个外部 etcd:有三个成员的高可用 etcd 集群。 +默认情况下,kubeadm 在每个控制平面节点上运行一个本地 etcd 实例。也可以使用外部的 etcd 集群,并在不同的主机上提供 etcd 实例。 +这两种方法的区别在 [高可用拓扑的选项](/zh/docs/setup/production-environment/tools/kubeadm/ha-topology) 页面中阐述。 + + +这个任务将指导你创建一个由三个成员组成的高可用外部 etcd 集群,该集群在创建过程中可被 kubeadm 使用。 ## {{% heading "prerequisites" %}} - * 三个可以通过 2379 和 2380 端口相互通信的主机。本文档使用这些作为默认端口。不过,它们可以通过 kubeadm 的配置文件进行自定义。 -* 每个主机必须 [安装有 docker、kubelet 和 kubeadm][工具箱]。 +* 每个主机必须安装 systemd 和 bash 兼容的 shell。 +* 每台主机必须[安装有容器运行时、kubelet 和 kubeadm](/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)。 * 一些可以用来在主机间复制文件的基础设施。例如 `ssh` 和 `scp` 就可以满足需求。 - -[工具箱]: /docs/setup/production-environment/tools/kubeadm/install-kubeadm/ - - - + +{{< note >}} +下面的例子使用 IPv4 地址,但是你也可以使用 IPv6 地址配置 kubeadm、kubelet 和 etcd。一些 Kubernetes 选项支持双协议栈,但是 etcd 不支持。 +关于 Kubernetes 双协议栈支持的更多细节,请参见 [kubeadm 的双栈支持](/zh/docs/setup/production-environment/tools/kubeadm/dual-stack-support/)。 +{{< /note >}} + - 检查 kubelet 的状态以确保其处于运行状态: + 检查 kubelet 的状态以确保其处于运行状态: ```shell systemctl status kubelet @@ -131,39 +145,52 @@ kubeadm 包含生成下述证书所需的所有必要的密码学工具;在这 使用以下脚本为每个将要运行 etcd 成员的主机生成一个 kubeadm 配置文件。 ```sh - # 使用 IP 或可解析的主机名替换 HOST0、HOST1 和 HOST2 + # 使用你的主机 IP 替换 HOST0、HOST1 和 HOST2 的 IP 地址 export HOST0=10.0.0.6 export HOST1=10.0.0.7 export HOST2=10.0.0.8 + # 使用你的主机名更新 NAME0, NAME1 和 NAME2 + export NAME0="infra0" + export NAME1="infra1" + export NAME2="infra2" + # 创建临时目录来存储将被分发到其它主机上的文件 mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/ - ETCDHOSTS=(${HOST0} ${HOST1} ${HOST2}) - NAMES=("infra0" "infra1" "infra2") + HOSTS=(${HOST0} ${HOST1} ${HOST2}) + NAMES=(${NAME0} ${NAME1} ${NAME2}) - for i in "${!ETCDHOSTS[@]}"; do - HOST=${ETCDHOSTS[$i]} - NAME=${NAMES[$i]} - cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml - apiVersion: "kubeadm.k8s.io/v1beta3" - kind: ClusterConfiguration - etcd: - local: - serverCertSANs: - - "${HOST}" - peerCertSANs: - - "${HOST}" - extraArgs: - initial-cluster: infra0=https://${ETCDHOSTS[0]}:2380,infra1=https://${ETCDHOSTS[1]}:2380,infra2=https://${ETCDHOSTS[2]}:2380 - initial-cluster-state: new - name: ${NAME} - listen-peer-urls: https://${HOST}:2380 - listen-client-urls: https://${HOST}:2379 - advertise-client-urls: https://${HOST}:2379 - initial-advertise-peer-urls: https://${HOST}:2380 - EOF - done + for i in "${!HOSTS[@]}"; do + HOST=${HOSTS[$i]} + NAME=${NAMES[$i]} + cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml + --- + apiVersion: "kubeadm.k8s.io/v1beta3" + kind: InitConfiguration + nodeRegistration: + name: ${NAME} + localAPIEndpoint: + advertiseAddress: ${HOST} + --- + apiVersion: "kubeadm.k8s.io/v1beta3" + kind: ClusterConfiguration + etcd: + local: + serverCertSANs: + - "${HOST}" + peerCertSANs: + - "${HOST}" + extraArgs: + initial-cluster: ${NAMES[0]}=https://${HOSTS[0]}:2380,${NAMES[1]}=https://${HOSTS[1]}:2380,${NAMES[2]}=https://${HOSTS[2]}:2380 + initial-cluster-state: new + name: ${NAME} + listen-peer-urls: https://${HOST}:2380 + listen-client-urls: https://${HOST}:2379 + advertise-client-urls: https://${HOST}:2379 + initial-advertise-peer-urls: https://${HOST}:2380 + EOF + done ``` 如果你还没有 CA,则在 `$HOST0`(你为 kubeadm 生成配置文件的位置)上运行此命令。 - ``` + ```shell kubeadm init phase certs etcd-ca ``` @@ -280,7 +307,7 @@ kubeadm 包含生成下述证书所需的所有必要的密码学工具;在这 --> 在 `$HOST1` 上: - ``` + ```console $HOME └── kubeadmcfg.yaml --- @@ -302,7 +329,7 @@ kubeadm 包含生成下述证书所需的所有必要的密码学工具;在这 --> 在 `$HOST2` 上: - ``` + ```console $HOME └── kubeadmcfg.yaml --- @@ -332,9 +359,9 @@ kubeadm 包含生成下述证书所需的所有必要的密码学工具;在这 在每台主机上运行 `kubeadm` 命令来生成 etcd 使用的静态清单。 ```shell - root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml - root@HOST1 $ kubeadm init phase etcd local --config=/tmp/${HOST1}/kubeadmcfg.yaml - root@HOST2 $ kubeadm init phase etcd local --config=/tmp/${HOST2}/kubeadmcfg.yaml + root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml + root@HOST1 $ kubeadm init phase etcd local --config=$HOME/kubeadmcfg.yaml + root@HOST2 $ kubeadm init phase etcd local --config=$HOME/kubeadmcfg.yaml ``` ## 当删除托管容器时 kubeadm 阻塞 -如果 Docker 停止并且不删除 Kubernetes 所管理的所有容器,可能发生以下情况: +如果容器运行时停止并且未删除 Kubernetes 所管理的容器,可能发生以下情况: ```shell sudo kubeadm reset @@ -152,17 +143,8 @@ sudo kubeadm reset ``` 一个可行的解决方案是重新启动 Docker 服务,然后重新运行 `kubeadm reset`: - -```shell -sudo systemctl restart docker.service -sudo kubeadm reset -``` - -检查 docker 的日志也可能有用: - -```shell -journalctl -ul docker -``` +你也可以使用 `crictl` 来调试容器运行时的状态。 +参见[使用 CRICTL 调试 Kubernetes 节点](/zh/docs/tasks/debug/debug-cluster/crictl/)。 ## Pods 处于 `RunContainerError`、`CrashLoopBackOff` 或者 `Error` 状态 @@ -446,7 +424,7 @@ Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc6 private network. The `kubeletExtraArgs` section of the kubeadm [`NodeRegistrationOptions` structure](/docs/reference/config-api/kubeadm-config.v1beta3/#kubeadm-k8s-io-v1beta3-NodeRegistrationOptions) can be used for this. - + Then restart `kubelet`: ```sh @@ -477,7 +455,7 @@ Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc6 解决方法是通知 `kubelet` 使用哪个 `--node-ip`。当使用 Digital Ocean 时,可以是公网IP(分配给 `eth0`的), 或者是私网IP(分配给 `eth1` 的)。私网 IP 是可选的。 - [kubadm `NodeRegistrationOptions` 结构](/zh/docs/reference/config-api/kubeadm-config.v1beta3/#kubeadm-k8s-io-v1beta3-NodeRegistrationOptions) + [kubadm `NodeRegistrationOptions` 结构](/zh/docs/reference/config-api/kubeadm-config.v1beta3/#kubeadm-k8s-io-v1beta3-NodeRegistrationOptions) 的 `KubeletExtraArgs` 部分被用来处理这种情况。 然后重启 `kubelet`: @@ -565,7 +543,7 @@ yum install docker-ce-18.06.1.ce-3.el7.x86_64 如果你遇到以下错误: -``` +```console rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:110: decoding init error from pipe caused \"read parent: connection reset by peer\"" ``` @@ -642,7 +620,7 @@ A known solution is to patch the kube-proxy DaemonSet to allow scheduling it on nodes regardless of their conditions, keeping it off of other nodes until their initial guarding conditions abate: ``` -kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" } ] } } } }' +kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/control-plane" } ] } } } }' ``` The tracking issue for this problem is [here](https://github.com/kubernetes/kubeadm/issues/1027). @@ -654,7 +632,7 @@ The tracking issue for this problem is [here](https://github.com/kubernetes/kube 在 kube-proxy Pod 中可以看到以下错误: -``` +```console server.go:610] Failed to retrieve node IP: host IP unknown; known addresses: [] proxier.go:340] invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP ``` @@ -663,7 +641,7 @@ proxier.go:340] invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP 而不管它们的条件如何,将其与其他节点保持隔离,直到它们的初始保护条件消除: ```shell -kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" } ] } } } }' +kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/control-plane" } ] } } } }' ``` 此问题的跟踪[在这里](https://github.com/kubernetes/kubeadm/issues/1027)。 @@ -681,7 +659,7 @@ for the feature to work. ## 节点上的 `/usr` 被以只读方式挂载 {#usr-mounted-read-only} 在类似 Fedora CoreOS 或者 Flatcar Container Linux 这类 Linux 发行版本中, -目录 `/usr` 是以只读文件系统的形式挂载的。 +目录 `/usr` 是以只读文件系统的形式挂载的。 在支持 [FlexVolume](https://github.com/kubernetes/community/blob/ab55d85/contributors/devel/sig-storage/flexvolume.md)时, 类似 kubelet 和 kube-controller-manager 这类 Kubernetes 组件使用默认路径 `/usr/libexec/kubernetes/kubelet-plugins/volume/exec/`, @@ -789,7 +767,7 @@ on the side of the metrics-server: kubeadm 为 kubelet 部署的是自签名的服务证书。这可能会导致 metrics-server 端报告下面的错误信息: -``` +```console x509: certificate signed by unknown authority x509: certificate is valid for IP-foo not IP-bar ``` @@ -804,4 +782,3 @@ Also see [How to run the metrics-server securely](https://github.com/kubernetes- 以进一步了解如何在 kubeadm 集群中配置 kubelet 使用正确签名了的服务证书。 另请参阅[How to run the metrics-server securely](https://github.com/kubernetes-sigs/metrics-server/blob/master/FAQ.md#how-to-run-metrics-server-securely)。 -