要想完全概念化并理解 Kubernetes 的工作原理,必须用实际的 Kubernetes 集群进行实验。而幸运的是,现在并不缺乏使用 Kubernetes 的工具 — 通常情况下,这可以在几分钟内实现。无论是用 minikube 这样的工具在笔记本电脑上进行本地安装,还是从任何一个主要的公共云提供商那里进行管理部署,几乎任何人都可以拥有一个 Kubernetes 集群。
虽然这些项目和服务中的许多项目和服务极大地帮助了集群的商品化部署,但有许多情况下不允许这种程度的灵活性。也许有内部的合规性或监管限制阻止了公共云的使用。或者您的组织已经在自己的数据中心上进行了大量投资。无论在什么情况下,你都很难找到不适合部署 Kubernetes 的环境。
除了在哪里以及如何消费 Kubernetes 的物流之外,为了充分理解 Kubernetes 的分布式组件是如何运行的,了解使生产就绪的容器化应用交付成为现实的架构也很重要。在本章中,我们将探讨所涉及的服务以及它们的安装方式。
kubeadm
在琳琅满目的 Kubernetes 安装方案中,有一个社区支持的 kubeadm 实用程序。这个应用程序提供了安装 Kubernetes 所需的所有功能。事实上,在最简单的情况下,用户只需一个命令就可以在几分钟内完成 Kubernetes 的安装。这种简单性使得它对于开发者和有生产级需求的人来说是一个非常引人注目的工具。因为 kubeadm 的代码是以树为单位的,并且是与 Kubernetes 版本一起发布的,所以它借用了常见的基本元素,并针对大量的用例进行了彻底的测试。
:::info
由于 kubeadm 提供的简单性和强大的实用性,许多其他安装工具实际上都在幕后利用了 kubeadm。而跟随这种趋势的项目数量也在定期增加。所以,无论你最终是否选择 kubeadm 作为你的首选安装工具,了解它的工作原理很可能会帮助你进一步了解你所选择的工具。
:::
Kubernetes 的生产级部署可以确保数据在传输过程中和静止状态下都是安全的,Kubernetes 组件与它们的依赖关系匹配良好,与环境的集成定义良好,所有集群组件的配置都能很好地协同工作。理想的情况下,这些集群也很容易升级,并且由此产生的配置也能不断反映这些最佳实践,kubeadm 可以帮助你实现这一切。
使用要求
kubeadm,就像所有的 Kubernetes 二进制文件一样,是静态链接的,因此,不需要依赖任何共享库,kubeadm 可以安装在任何 x86_64、ARM或 PowerPC Linux发行版上。因此,不需要依赖任何共享库,kubeadm 可以安装在几乎任何 x86_64、ARM 或 PowerPC Linux 发行版上。
幸运的是,从主机应用的角度来看,我们需要的东西也不多。最根本的是,我们需要一个容器运行时和 Kubernetes kubelet,但也有一些必要的标准 Linux 实用程序。
在安装容器运行时时,你应该确保它遵守容器运行时接口(CRI)。这个开放标准定义了 kubelet 用来与主机上可用的运行时对话的接口。在撰写本文时,一些最流行的符合 CRI 的运行时是 Docker、rkt 和 CRI-O。对于其中的每一个,开发者应该查阅各自项目提供的安装说明。
:::info 在选择容器运行时,一定要参考 Kubernetes 发布说明。每个版本都会明确指出哪些容器运行时已经过测试。这样你就知道哪些运行时和版本是已知的,既兼容又有性能。 :::
kubelet
正如您在第 3 章中所回顾的那样,kubelet 是负责与容器运行时进行接口的节点进程。在最常见的情况下,这项工作通常相当于向 API Server 报告节点状态,并管理已排到它所居住的主机上的 Pod 的整个生命周期。
kubelet 的安装通常就像为目标发行版下载并安装相应的包一样简单。在所有情况下,你应该确保安装 kubelet 的版本与你打算运行的 Kubernetes 版本相匹配。kubelet 是由主机服务管理器管理的单一 Kubernetes 进程。几乎在所有情况下,这可能是 systemd。
如果你使用社区构建和提供的系统包(目前是 deb 和 rpm)安装 kubelet,kubelet 将由 systemd 管理。就像任何以这种方式管理的进程一样,一个单元文件定义了服务运行的用户,命令行选项是什么,服务依赖链是如何定义的,以及重启策略应该是什么。
[Unit]Description=kubelet: The Kubernetes Node AgentDocumentation=http://kubernetes.io/docs/[Service]ExecStart=/usr/bin/kubeletRestart=alwaysStartLimitInterval=0RestartSec=10[Install]WantedBy=multi-user.target
:::info 即使你没有使用社区提供的包来安装 kubelet,检查所提供的单元文件通常也有助于理解运行 kubelet 守护进程的常见最佳实践。这些单元文件经常变化,所以一定要参考与你的部署目标相匹配的版本。 :::
kubelet 的行为可以通过在 /etc/systemd/system/kubelet.service.d/ 路径中添加额外的单元文件来操作。这些单元文件是以词法读取的(所以要适当地命名它们),并允许你覆盖包如何配置 kubelet。如果你的环境需要特定的需求(即容器注册表代理),可能需要这样做。
例如,当将 Kubernetes 部署到支持的云提供商时,你需要在 kubelet上设置 --cloud-provider 参数。
$ cat /etc/systemd/system/kubelet.service.d/09-extra-args.conf
[Service]
Environment="KUBELET_EXTRA_ARGS= --cloud-provider=aws"
有了这个附加文件,我们只需执行守护进程重载,然后重新启动服务即可:
$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet
大体上,社区提供的默认配置通常是足够的,通常不需要修改。然而,通过这种技术,我们可以利用社区的默认配置,同时保持我们在适用时覆盖的能力。
:::info kubelet 和容器运行时在集群中的所有主机上都是必要的。 :::
安装控制平面
在 Kubernetes 中,指挥工作节点行动的组件被称为控制平面。正如我们在第 3 章中所介绍的,这些组件包括 API Server、控制器管理器和调度器。这些守护进程中的每一个都会指导集群最终如何运行的某一部分。
除了 Kubernetes 组件之外,我们还需要一个地方来存储我们的集群状态。这个数据存储就是 etcd。
幸运的是,kubeadm 能够将所有这些守护进程安装在我们作为管理员委托的主机(或主机)上,作为控制平面节点。kubeadm 通过为每个我们需要的守护进程创建静态清单来实现。
:::info 通过静态清单,我们可以直接将 Pod 规格写入磁盘,kubelet 在启动时,会立即尝试启动其中指定的容器。事实上,kubelet 也会监控这些文件的变化,并试图协调任何指定的变化。但是,请注意,由于这些 Pod 不 由控制平面管理的,所以不能用 kubectl 命令行界面来操作它们。 :::
除了守护进程,我们还需要用传输层安全(TLS)保护组件的安全,创建一个可以与 API 交互的用户,并为工人节点提供加入集群的能力。kubeadm 做到了这一切。
在最简单的情况下,我们可以在一个已经准备好运行的 kubelet 和功能容器运行时的节点上安装控制平面组件,比如这样:
$ kubeadmin init
在详细描述了 kubeadm 代表用户采取的步骤后,输出的结尾可能是这样的:
...
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join --token 878b76.ddab3219269370b2 10.1.2.15:6443 \
--discovery-token-ca-cert-hash \
sha256:312ce807a9e98d544f5a53b36ae3bb95cdcbe50cf8d1294d22ab5521ddb54d68
kubeadm 配置
虽然 kubeadm init 是最简单的配置控制器节点的案例,但 kubeadm 能够管理各种配置。这可以通过各种有限的 kubeadm 命令行标志来实现,也可以通过更强大的 kubeadm API 来实现。
API 看起来是这样的:
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
api:
advertiseAddress: <address|string>
bindPort: <int>
etcd:
endpoints:
- <endpoint1|string>
- <endpoint2|string>
caFile: <path|string>
certFile: <path|string>
keyFile: <path|string>
networking:
dnsDomain: <string>
serviceSubnet: <cidr>
podSubnet: <cidr>
kubernetesVersion: <string>
cloudProvider: <string>
authorizationModes:
- <authorizationMode1|string>
- <authorizationMode2|string>
token: <string>
tokenTTL: <time duration>
selfHosted: <bool>
apiServerExtraArgs:
<argument>: <value|string>
<argument>: <value|string>
controllerManagerExtraArgs:
<argument>: <value|string>
<argument>: <value|string>
schedulerExtraArgs:
<argument>: <value|string>
<argument>: <value|string>
apiServerCertSANs:
- <name1|string>
- <name2|string>
certificatesDir: <string>
它可以通过 --config 标志提供给 kubeadm 命令行。无论你作为管理员是否决定明确使用这种配置格式,在执行 kubeadm init 时,总会在内部生成一个配置格式。而且,这个配置会以 ConfigMap 的形式保存到刚刚提供的集群中。这个功能有两个目的 — 首先,为那些需要了解群集是如何配置的人提供一个参考,其次,在升级群集时可以利用它。在升级集群的时候,用户修改这个 ConfigMap 的值,然后执行 kubeadm 升级。
:::info
kubeadm 配置也可以通过标准的 kubectl ConfigMap 查询访问,按照惯例,它被命名为 kube-public 命名空间中的 cluster-info ConfigMap。
:::
预航检查
当我们运行这个命令后,kubeadm 首先会执行一系列的预航检查。这些理智性检查确保我们的系统适合安装。“kubelet 是否正在运行?”,“是否已经禁用了 swap ?”,以及 “是否安装了基线系统实用程序?” 这些都是这里要问的问题类型。而如果不满足这些基线条件,kubeadm 自然会以错误的方式退出。
:::info
虽然不建议使用,但可以使用 --skip-preflight-checks 命令行选项来回避飞行前检查。只有高级管理员才可以使用这个选项。
:::
证书
在所有的飞行前检查被满足后,kubeadm 默认会生成自己的证书授权(CA)和密钥。然后,这个 CA 会被用来,随后,对其签署各种证书。这些证书中的一些被API服务器用于保护入站请求、验证用户、发出出站请求(即,到一个聚合 API Server),以及 API Server 和所有下游 kubelet 之间的相互 TLS。其他的则用于保护服务账户的安全。
所有这些公钥基础设施(PKI)资产都被放置在控制平面节点上的 /etc/kubernetes/pki 目录中。
$ ls -al /etc/kubernetes/pki/
total 56
drwxr-xr-x 2 root root 4096 Mar 15 02:42 .
drwxr-xr-x 4 root root 4096 Mar 15 02:42 ..
-rw-r--r-- 1 root root 1229 Mar 15 02:42 apiserver.crt
-rw------- 1 root root 1675 Mar 15 02:42 apiserver.key
-rw-r--r-- 1 root root 1099 Mar 15 02:42 apiserver-kubelet-client.crt
-rw------- 1 root root 1679 Mar 15 02:42 apiserver-kubelet-client.key
-rw-r--r-- 1 root root 1025 Mar 15 02:42 ca.crt
-rw------- 1 root root 1675 Mar 15 02:42 ca.key
-rw-r--r-- 1 root root 1025 Mar 15 02:42 front-proxy-ca.crt
-rw------- 1 root root 1675 Mar 15 02:42 front-proxy-ca.key
-rw-r--r-- 1 root root 1050 Mar 15 02:42 front-proxy-client.crt
-rw------- 1 root root 1675 Mar 15 02:42 front-proxy-client.key
-rw------- 1 root root 1675 Mar 15 02:42 sa.key
-rw------- 1 root root 451 Mar 15 02:42 sa.pub
:::info
由于这个默认的 CA 是自签名的,所以任何第三方消费者在尝试使用客户端证书时,也需要提供 CA 证书链。幸运的是,对于 Kubernetes 用户来说,这通常不是问题,因为一个 kubeconfig 文件能够嵌入这些数据,并且由 kubeadm 自动完成。
:::
:::tips
自签证书虽然非常方便,但有时并不是首选方法。在企业环境中,或者对于那些有更严格的合规性要求的环境中,这种情况往往尤为突出。在这种情况下,用户可能会在执行 kubeadm init 之前,在 /etc/kubernetes/pki 目录下预先填充这些资产。在这种情况下,kubeadm 会尝试使用可能已经存在的密钥和证书,并生成那些可能尚未存在的密钥和证书。
:::
etcd
除了通过 kubeadm 方式配置的 Kubernetes 组件外,默认情况下,如果没有另外指定,kubeadm 会尝试启动一个本地 etcd 服务器实例。该守护进程的启动方式与 Kubernetes 组件相同(静态清单),并通过本地主机卷挂载将其数据持久化到控制平面节点的文件系统中。
:::info
在写这篇文章的时候,kubeadm init 本身并没有用 TLS 来保证 kubeadm 管理的 etcd 服务器的安全。这个基本命令只用于配置一个控制平面节点,而且通常只用于开发目的。
需要 kubeadm 用于生产安装的用户应该在本章前面描述的 --config 选项中提供一个 TLS 安全的 etcd 端点列表。
:::
虽然拥有一个易于部署的 etcd 实例有利于简单的 Kubernetes 安装过程,但它并不适合生产级部署。在生产级部署中,管理员会部署一个多节点且高可用的 etcd 集群,该集群与 Kubernetes 部署相邻。由于 etcd 数据存储将包含集群的所有状态,因此必须谨慎对待它。虽然 Kubernetes 组件很容易被替换,但 etcd 却不是。而且,因此,etcd 的组件生命周期(安装、升级、维护等)是完全不同的。因此,生产型 Kubernetes 集群应该将这些责任分开。
秘密数据
所有写入 etcd 的数据默认都是未加密的。如果有人获得了对备份 etcd 的磁盘的特权访问,数据就会很容易获得。幸运的是,Kubernetes 持久化到磁盘的大部分数据都不是敏感数据。
然而,Secret 数据是个例外。顾名思义,Secret 数据应该保持,秘密。为了确保这些数据在进入 etcd 的过程中被加密,管理员应该使用 --experimental-encryption-provider-config API Server 参数。通过这个参数,管理员可以定义对称密钥来加密所有的 Secret 数据。
:::info
在写这篇文章的时候,--experimental-encryption-provider-config 仍然是一个实验性的 kube-apiserver 命令行参数。由于这个参数可能会发生变化,所以 kubeadm 对这个功能的本地支持是有限的。你仍然可以通过在所有控制平面节点的 /etc/kubernetes/pki 目录中添加 encryption.conf,以及在 kubeadm init 之前将此配置参数添加到 kubeadm MasterConfig 中的 apiServerExtraArgs 字段来使用此功能。
:::
通过 EncryptionConfig 来实现的方式可以例如:
# encryption.conf
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- identity: {}
- aescbc:
keys:
- name: encryptionkey
secret: BHk4lSZnaMjPYtEHR/jRmLp+ymazbHirgxBHoJZqU/Y=
对于推荐的 aescbc 加密类型,secret 字段应该是随机生成的 32 字节密钥。现在,通过在 kube-apiserver 命令行参数中添加 --experimental-encryption-provider-config=/path/to/encryption.conf,所有的 Secret 都会在写入 etcd 之前进行加密。这可能有助于防止敏感数据的泄露。
您可能已经注意到,EncryptionConfig 还包括一个资源字段。对于我们的用例,秘密是我们要加密的唯一资源,但这里可以包含任何资源类型。根据你的组织的需求使用这个,但请记住,加密这些数据确实会稍微影响API服务器的写入性能。作为一般的经验法则,只对您认为敏感的数据进行加密。
此配置支持多种加密类型,其中一些类型可能或多或少适合您的特定需求。同样,此配置也支持密钥轮换,这是确保强大安全立场的必要措施。请务必查阅 Kubernetes 文档,以了解这一实验性功能的其他细节。
:::info 你对数据静止时的要求将取决于你的架构。如果你选择将你的 etcd 实例安置在控制平面节点上,利用这个功能可能无法满足你的需求,因为加密密钥也会与数据安置在一起。一旦获得对磁盘的特权访问,密钥可能会被用来解密 etcd 数据,从而破坏了保护这些资源的努力。这是另一个令人信服的理由,将 etcd 与你的 Kubernetes 控制平面节点隔离。 :::
kubeconfig
除了创建 PKI 资产和配置服务于 Kubernetes 组件的静态清单外,kubeadm 还生成一些 kubeconfig 文件。这些文件中的每一个都将用于一些认证手段。这些文件中的大部分将用于针对 API 对每个 Kubernetes 服务进行身份验证,但 kubeadm 也会在 /etc/kubernetes/admin.conf 中创建一个主管理员 kubeconfig 文件。
:::info
因为 kubeadm 很容易用群集管理员凭证创建这个 kubeconfig,所以很多用户倾向于将这些生成的凭证用于远远超出他们预期的用途。这些凭证应该只用于引导集群。任何生产部署都应该始终配置额外的身份机制,这些将在第 7 章中讨论。
:::
污点
对于生产用例,我们建议将用户工作负载与控制平面组件隔离。因此,kubeadm 会用 node-role.kubernetes.io/master 污点污染所有控制平面节点。这指示调度器在决定 Pod 的位置时,忽略所有带有该污点的节点。
如果你的用例是单节点主站,你可以通过从节点上删除污点来消除这个限制。
安装工作节点
工作者节点遵循一个非常相似的安装机制。同样,我们需要在每个节点上安装容器运行时和 kubelet。但是,对于工作节点,我们需要的唯一其他 Kubernetes 组件是 kube-proxy 守护进程。而且,就像控制平面节点一样,kubeadm 通过另一个静态清单的方式启动这个过程。
最重要的是,这个过程会执行一个 TLS 引导序列。通过共享令牌交换过程,kubeadm 暂时对 API Server 进行节点认证,然后尝试对控制平面 CA 执行证书签署请求(CSR)。节点的证书被签署后,这些证书在运行时作为认证机制。
这听起来很复杂,但是,kubeadm 又将这个过程变得异常简单。
$ kubeadm join --token <token> --discovery-token-ca-cert-hash <hash> \
<api endpoint>
虽然没有控制平面的情况下那么简单,但还是很直接的,在你手动使用 kubeadm 的情况下,kubeadm init 命令的输出甚至提供了需要在工作节点上运行的精确命令。而且,在你手动使用 kubeadm 的情况下,kubeadm init 命令的输出甚至提供了需要在工作节点上运行的精确命令。
很显然,如果我们要求一个工作节点将自己加入到 Kubernetes 集群中,我们需要告诉它在哪里注册自己。这就是 <api endpoint> 参数的作用。这包括 API Server 的 IP(或域名)和端口。
由于这个机制允许一个节点发起加入,我们要确保这个操作是安全的。出于显而易见的原因,我们不希望任何节点都能够加入集群,同样,我们也希望工作者节点能够验证控制平面的真实性。这就是 --token 和 --discovery-token-ca-cert-hash 参数发挥作用的地方。
--token 参数是一个与控制平面一起预定义的引导令牌。在我们简单的使用案例中,启动令牌已经通过 kubeadm init 调用的方式自动分配。用户也可以在运行中创建这些引导令牌。
$ kubeadm token create [--ttl <duration>]
当向集群中添加新的工作节点时,这种机制特别方便。在这种情况下,步骤很简单,使用 kubeadm token create 定义一个新的启动令牌,然后在新工作节点上的 kubeadm join 命令中使用该令牌。
--discovery-token-ca-cert-hash 为工作节点提供了一个验证控制平面 CA 的机制。通过预共享 CA 的 SHA256 哈希值,工作节点可以验证它所收到的凭证实际上是来自预定的控制平面。
整个命令可能是这样的:
$ kubeadm join --token 878b76.ddab3219269370b2 \
--discovery-token-ca-cert-hash sha256:312ce807a9e98d544f5a53b36ae3bb95cdcbe50cf8d1294d22ab5521ddb54d68 \
10.1.2.15:6443
附加组件
在安装控制平面并带起几个工作节点后,明显的下一步是让一些工作负载部署起来。在这样做之前,我们需要部署一些附加组件。
最起码,我们需要安装一个容器网络接口(CNI)插件。这个插件提供了 Pod-to-Pod(也称为东西向)的网络连接。有众多的选择,每个选择都有自己特定的生命周期,所以 kubeadm 不参与尝试管理它们的业务。在最简单的情况下,这是由你的 CNI 提供商概述的 DaemonSet 清单的问题。
在生产集群中,您可能需要的其他附加组件可能包括日志聚合、监控,甚至可能是服务网状功能。同样,由于这些可能很复杂,kubeadm 并不试图管理它们。
kubeadm 管理的一个特殊附加功能是集群 DNS。kubeadm 目前支持 KubeDNS 和 CoreDNS,其中 CoreDNS 是默认的。和 kubeadm 的所有部分一样,你甚至可以选择放弃这些标准选项,安装你所选择的集群 DNS 提供商。
阶段
正如我们在本章前面提到的,kubeadm 是其他各种K ubernetes 安装工具的基础。正如你所想象的那样,如果我们试图以这种方式使用 kubeadm,我们可能希望安装的某些部分由 kubeadm 管理,而其他部分则由封装安装框架处理。kubeadm 也支持这种用例,它有一个叫做 Phase 的功能。
通过阶段(Phase),用户可以利用 kubeadm 来执行安装过程中的离散操作。例如,也许包装工具希望使用 kubeadm 来生成 PKI 资产。或者,该工具希望利用 kubeadm 的预检功能,以确保集群的最佳实践到位。所有这些 — 以及更多 — 都可以通过 Phase 来实现。
高可用性
如果你一直在密切关注,你可能会注意到,我们还没有谈到一个高度可用的控制平面。这有点刻意为之。
由于 kubeadm 的权限主要是从一个节点的角度出发,因此将 kubeadm 演变成一个通用的管理高可用安装的工具会相对复杂。这样做会开始模糊 “做一件事,而且要做好” 的 Unix 哲学的界限。
也就是说,kubeadm 可以(并且正在)用来提供高可用控制平面所需的组件。尽管用户需要采取一些精确的(有时是细微的)操作来创建一个高可用的控制平面,但基本的步骤是:
- 创建一个高可用的 etcd 集群
- 使用
kubeadm init和利用步骤 1 中创建的 etcd 集群的配置来初始化一个主控制平面节点 - 将 PKI 资产安全地转移到所有其他控制平面节点上
- 用负载均衡器将控制平面 API Server 前置
- 通过负载均衡端点的方式将所有工作节点加入到集群中
如果这是你的用例,并且你想使用 kubeadm 安装一个生产级的高可用集群,请务必参考 kubeadm 高可用文档。这个文档会随着 Kubernetes 的每个版本进行维护。
升级
与任何部署一样,总有一天你会想利用 Kubernetes 提供的所有新功能。同样,如果你需要一个关键的安全更新,你希望能够在尽可能少的干扰下启用它。幸运的是,Kubernetes 提供了零宕机升级。当底层基础架构被修改时,你的应用程序继续运行。
虽然有无数种方法可以升级集群,但我们将重点关注 kubeadm 使用案例 — 从 1.8 版本开始就有的功能。
在任何 Kubernetes 集群中都有很多移动的部件,这可能会使协调升级变得复杂。kubeadm 大大简化了这一点,因为它能够跟踪 kubelet、etcd 和服务于 Kubernetes 控制平面的容器映像的经过良好测试的版本组合。
执行升级时的操作顺序很简单。首先,我们计划升级,然后应用我们确定的计划。
在计划阶段,kubeadm 会分析正在运行的集群并确定可能的升级路径。在最简单的情况下,我们升级到一个次要版本或补丁版本(例如,从 1.10.3 升级到 1.10.4)。稍微复杂一点的是升级到一个全新的次要版本,它是两个(或更多)向前的版本(例如,1.8 到 1.10)。在这种情况下,我们需要通过每个连续的次要版本进行升级,直到达到我们所需的状态。
kubeadm 会执行一些预航检查,以确保集群是健康的,然后检查 kube-system 命名空间中的 kubeadm-config ConfigMap。这个 ConfigMap 可以帮助 kubeadm 确定可用的升级路径,并确保任何自定义的配置项目都能被继承。
虽然很多繁重的工作都是自动发生的,但你可能还记得,kubelet(以及 kubeadm 本身)并不是由 kubeadm 管理的。在执行计划时,kubeadm 会指出哪些未管理的组件也需要升级:
root@control1:~# kubeadm upgrade plan
[preflight] Running pre-flight checks.
[upgrade] Making sure the cluster is healthy:
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with
'kubectl -n kube-system get cm kubeadm-config -oyaml'
[upgrade/plan] computing upgrade possibilities
[upgrade] Fetching available versions to upgrade to
[upgrade/versions] Cluster version: v1.9.5
[upgrade/versions] kubeadm version: v1.10.4
[upgrade/versions] Latest stable version: v1.10.4
[upgrade/versions] Latest version in the v1.9 series: v1.9.8
Components that must be upgraded manually after you have upgraded
the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 4 x v1.9.3 v1.9.8
Upgrade to the latest version in the v1.9 series:
COMPONENT CURRENT AVAILABLE
API Server v1.9.5 v1.9.8
Controller Manager v1.9.5 v1.9.8
Scheduler v1.9.5 v1.9.8
Kube Proxy v1.9.5 v1.9.8
Kube DNS 1.14.8 1.14.8
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.9.8
_____________________________________________________________________
Components that must be upgraded manually after you have upgraded
the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 4 x v1.9.3 v1.10.4
Upgrade to the latest stable version:
COMPONENT CURRENT AVAILABLE
API Server v1.9.5 v1.10.4
Controller Manager v1.9.5 v1.10.4
Scheduler v1.9.5 v1.10.4
Kube Proxy v1.9.5 v1.10.4
Kube DNS 1.14.8 1.14.8
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.10.4
_____________________________________________________________________
你应该按照安装系统组件的方式(通常是用操作系统软件包管理器)进行升级。
在你确定了计划中的升级方式后,开始按照 kubeadm 指定的顺序执行升级。如果升级路径中有多个版本,则按照指示在每个节点上执行这些版本:
root@control1:~# kubeadm upgrade apply v1.10.4
再次,进行预航检查,主要是确保集群仍然健康,备份各种静态 Pod 清单,然后进行升级。
在节点顺序上,要保证先升级控制平面节点,然后再对每个工作节点进行升级。控制平面节点应该取消注册任何前端负载均衡器的上行,升级,然后,在整个控制平面升级成功后,所有控制平面节点应该重新注册为负载均衡器的上行。这样做可能会引入一段短暂的 API 不可用的时间,但可以确保所有客户的体验一致。
如果您对每个在位的工作节点进行升级,则可以并行升级工作节点。请注意,这可能会导致一段时间内没有可用的 kubelet 来调度 Pods。或者,您可以以滚动方式升级工作节点。这样可以确保始终有一个节点可以部署到。
:::info
如果您的升级还涉及到同时在工作节点上执行破坏性升级(如升级内核),建议使用 kubectl cordon 和/或 kubectl drain 语义来确保您的用户工作负载在维护之前被重新安排。
:::
总结
在本章中,我们探讨了如何在一些用例中轻松安装 Kubernetes。虽然我们只是对 kubeadm 的能力做了一些简单的介绍,但我们希望我们已经展示了它可以成为一个多功能的工具。
由于今天的许多部署工具都有 kubeadm 作为基础,了解它的工作原理应该有助于你了解更高阶的工具在代表你做什么。而且,如果你愿意,这种理解可以帮助你开发自己的内部部署工具。
