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 e2640977be..6bd7a1994b 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 @@ -21,7 +21,7 @@ card: 本页面显示如何安装 `kubeadm` 工具箱。 有关在执行此安装过程后如何使用 kubeadm 创建集群的信息,请参见 @@ -414,8 +414,9 @@ Install CNI plugins (required for most pod network): ```bash CNI_VERSION="v0.8.2" +ARCH="amd64" sudo mkdir -p /opt/cni/bin -curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz +curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-${ARCH}-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz ``` 这可能是由许多问题引起的。最常见的是: - 网络连接问题。在继续之前,请检查你的计算机是否具有全部联通的网络连接。 -- kubelet 的默认 cgroup 驱动程序配置不同于 Docker 使用的配置。 - 检查系统日志文件 (例如 `/var/log/message`) 或检查 `journalctl -u kubelet` 的输出。 如果你看见以下内容: - - ```shell - error: failed to run Kubelet: failed to create kubelet: - misconfiguration: kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs" - ``` - - 有两种常见方法可解决 cgroup 驱动程序问题: - - 1. 按照[此处](/zh/docs/setup/production-environment/container-runtimes/#docker) 的说明 - 重新安装 Docker。 - - 1. 更改 kubelet 配置以手动匹配 Docker cgroup 驱动程序,你可以参考 - [在主节点上配置 kubelet 要使用的 cgroup 驱动程序](/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#configure-cgroup-driver-used-by-kubelet-on-control-plane-node) - +- 容器运行时的 cgroup 驱动不同于 kubelet 使用的 cgroup 驱动。要了解如何正确配置 cgroup 驱动, + 请参阅[配置 cgroup 驱动](/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/)。 - 控制平面上的 Docker 容器持续进入崩溃状态或(因其他原因)挂起。你可以运行 `docker ps` 命令来检查以及 `docker logs` 命令来检视每个容器的运行日志。 + 对于其他容器运行时,请参阅[使用 crictl 对 Kubernetes 节点进行调试](/zh/docs/tasks/debug-application-cluster/crictl/)。 ## 无法通过其服务 IP 访问 Pod -- 许多网络附加组件尚未启用 [hairpin 模式](/zh/docs/tasks/debug-application-cluster/debug-service/#a-pod-cannot-reach-itself-via-service-ip) +- 许多网络附加组件尚未启用 [hairpin 模式](/zh/docs/tasks/debug-application-cluster/debug-service/#a-pod-fails-to-reach-itself-via-the-service-ip) 该模式允许 Pod 通过其服务 IP 进行访问。这是与 [CNI](https://github.com/containernetworking/cni/issues/476) 有关的问题。 请与网络附加组件提供商联系,以获取他们所提供的 hairpin 模式的最新状态。 @@ -378,6 +353,51 @@ Error from server (NotFound): the server could not find the requested resource This may lead to problems with flannel, which defaults to the first interface on a host. This leads to all hosts thinking they have the same public IP address. To prevent this, pass the `-iface eth1` flag to flannel so that the second interface is chosen. --> + + +## Kubelet 客户端证书轮换失败 {#kubelet-client-cert} + +默认情况下,kubeadm 使用 `/etc/kubernetes/kubelet.conf` 中指定的 `/var/lib/kubelet/pki/kubelet-client-current.pem` 符号链接 +来配置 kubelet 自动轮换客户端证书。如果此轮换过程失败,你可能会在 kube-apiserver 日志中看到 +诸如 `x509: certificate has expired or is not yet valid` 之类的错误。要解决此问题,你必须执行以下步骤: + +1. 从故障节点备份和删除 `/etc/kubernetes/kubelet.conf` 和 `/var/lib/kubelet/pki/kubelet-client*`。 +2. 在集群中具有 `/etc/kubernetes/pki/ca.key` 的、正常工作的控制平面节点上 + 执行 `kubeadm kubeconfig user --org system:nodes --client-name system:node:$NODE > kubelet.conf`。 + `$NODE` 必须设置为集群中现有故障节点的名称。 + 手动修改生成的 `kubelet.conf` 以调整集群名称和服务器端点, + 或传递 `kubeconfig user --config`(此命令接受 `InitConfiguration`)。 + 如果你的集群没有 `ca.key`,你必须在外部对 `kubelet.conf` 中的嵌入式证书进行签名。 + +3. 将得到的 `kubelet.conf` 文件复制到故障节点上,作为 `/etc/kubernetes/kubelet.conf`。 +4. 在故障节点上重启 kubelet(`systemctl restart kubelet`),等待 `/var/lib/kubelet/pki/kubelet-client-current.pem` 重新创建。 + +5. 在故障节点上运行 `kubeadm init phase kubelet-finalize all`。 + 这将使新的 `kubelet.conf` 文件使用 `/var/lib/kubelet/pki/kubelet-client-current.pem` 并将重新启动 kubelet。 +6. 确保节点状况变为 `Ready`。 + ## 在 Vagrant 中使用 flannel 作为 pod 网络时的默认 NIC 以下错误可能表明 Pod 网络中出现问题: @@ -411,8 +431,13 @@ Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc6 curl http://169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address ``` - The workaround is to tell `kubelet` which IP to use using `-node-ip`. When using Digital Ocean, it can be the public one (assigned to `eth0`) or the private one (assigned to `eth1`) should you want to use the optional private network. The [`KubeletExtraArgs` section of the kubeadm `NodeRegistrationOptions` structure](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kubeadm/app/apis/kubeadm/v1beta1/types.go) can be used for this. - + The workaround is to tell `kubelet` which IP to use using `--node-ip`. + When using DigitalOcean, it can be the public one (assigned to `eth0`) or + the private one (assigned to `eth1`) should you want to use the optional + private network. The `kubeletExtraArgs` section of the kubeadm + [`NodeRegistrationOptions` structure](/docs/reference/config-api/kubeadm-config.v1beta2/#kubeadm-k8s-io-v1beta2-NodeRegistrationOptions) + can be used for this. + Then restart `kubelet`: ```sh @@ -443,7 +468,8 @@ 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` 结构的 `KubeletExtraArgs` 部分](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kubeadm/app/apis/kubeadm/v1beta1/types.go) 被用来处理这种情况。 + [kubadm `NodeRegistrationOptions` 结构](/zh/docs/reference/config-api/kubeadm-config.v1beta2/#kubeadm-k8s-io-v1beta2-NodeRegistrationOptions) + 的 `KubeletExtraArgs` 部分被用来处理这种情况。 然后重启 `kubelet`: @@ -569,7 +595,7 @@ Alternatively, you can try separating the `key=value` pairs like so: `-apiserver-extra-args "enable-admission-plugins=LimitRanger,enable-admission-plugins=NamespaceExists"` but this will result in the key `enable-admission-plugins` only having the value of `NamespaceExists`. -A known workaround is to use the kubeadm [configuration file](/docs/setup/production-environment/tools/kubeadm/control-plane-flags/#apiserver-flags). +A known workaround is to use the kubeadm [configuration file](/docs/reference/config-api/kubeadm-config.v1beta2/). --> ## 无法将以逗号分隔的值列表传递给 `--component-extra-args` 标志内的参数 @@ -587,7 +613,7 @@ kube-apiserver 这样的控制平面组件。然而,由于解析 (`mapStringSt 但这将导致键 `enable-admission-plugins` 仅有值 `NamespaceExists`。 已知的解决方法是使用 kubeadm -[配置文件](/zh/docs/setup/production-environment/tools/kubeadm/control-plane-flags/#apiserver-flags)。 +[配置文件](/zh/docs/reference/config-api/kubeadm-config.v1beta2/)。 -## NodeRegistration.Taints 字段在编组 kubeadm 配置时丢失 - -*注意:这个 [问题](https://github.com/kubernetes/kubeadm/issues/1358) -仅适用于操控 kubeadm 数据类型的工具(例如,YAML 配置文件)。它将在 kubeadm API v1beta2 修复。* - -默认情况下,kubeadm 将 `node-role.kubernetes.io/master:NoSchedule` 污点应用于控制平面节点。 -如果你希望 kubeadm 不污染控制平面节点,并将 `InitConfiguration.NodeRegistration.Taints` 设置成空切片,则应在编组时省略该字段。 -如果省略该字段,则 kubeadm 将应用默认污点。 - -至少有两种解决方法: - -1. 使用 `node-role.kubernetes.io/master:PreferNoSchedule` 污点代替空切片。 - 除非其他节点具有容量,[否则将在主节点上调度 Pods](/zh/docs/concepts/scheduling-eviction/taint-and-toleration/)。 - -2. 在 kubeadm init 退出后删除污点: - - ```shell - kubectl taint nodes NODE_NAME node-role.kubernetes.io/master:NoSchedule- - ``` - -为了解决这个问题,你可以使用 kubeadm 的[配置文件](https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2) +为了解决这个问题,你可以使用 kubeadm 的[配置文件](https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3) 来配置 FlexVolume 的目录。 在(使用 `kubeadm init` 创建的)主控制节点上,使用 `-config` 参数传入如下文件: ```yaml -apiVersion: kubeadm.k8s.io/v1beta2 +apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration nodeRegistration: kubeletExtraArgs: volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/" --- -apiVersion: kubeadm.k8s.io/v1beta2 +apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration controllerManager: extraArgs: @@ -722,7 +710,7 @@ On joining Nodes: 在加入到集群中的节点上,使用下面的文件: ```yaml -apiVersion: kubeadm.k8s.io/v1beta2 +apiVersion: kubeadm.k8s.io/v1beta3 kind: JoinConfiguration nodeRegistration: kubeletExtraArgs: