Kubernetes 笔记 / 入门 / 生产环境 / 用部署工具安装 Kubernetes / 用 kubeadm 启动集群 / 用 kubeadm 创建集群

目录、参考文献


使用 kubeadm,可以创建一个符合最佳实践的最小可行的 Kubernetes 集群
实际上,可以使用 kubeadm 设置一个能够通过 Kubernetes Conformance tests 的集群
kubeadm 还支持其他集群生命周期功能,例如 bootstrap tokens 和集群升级

kubeadm 工具能够满足以下需求:

  • 尝试 Kubernetes
  • 现有用户自动设置集群并测试应用程序
  • 其它生态中的和/或具有更大范围的安装工具中的构建块

可以在各种机器上安装 kubeadm:笔记本电脑、云服务器、树莓派等等
无论是部署到云端还是本地,都可以将 kubeadm 集成到配置系统中,如 Ansible 或 Terraform

1 前提条件

  • 运行 deb/rpm 兼容的 Linux 操作系统的一台或多台机器
  • 每台机器 2 GiB 或更多的 RAM
  • 作为控制平面的机器至少 2 核 CPU
  • 集群中所有机器之间的完整网络连接,可以使用公有或私有网络

kubeadm 的版本必须有能力部署想要在集群中使用的 Kubernetes 版本

Kubernetes 的版本与版本差异支持策略适用于 kubeadm 以及整个 Kubernetes
本文适用于 Kubernetes v1.24

kubeadm 工具的功能特性在整体上是普遍可用的(General Availability (GA))
一些子特性仍在积极开发中
随着工具的发展,创建集群的实现可能会有一些变化,但整体实现应该是相当稳定的

注意:
任何在 kubeadm alpha 下的命令,都是在 alpha 级别下得到支持的

2 目标

  • 安装一个具有单个控制平面的 Kubernetes 集群
  • 在集群上安装一个 Pod 网络,让集群上的 Pod 能够互相通信

3 操作指南

3.1 在主机上做好准备工作

在所有主机上安装一个容器运行时和 kubeadm
有关的详细说明和其它的先决条件,请参阅安装 kubeadm

注意:
如果已安装 kubeadm
则运行 apt-get update && apt-get upgradeyum update 获取 kubeadm 的最新版本

升级完成之后,kubelet 每隔几秒钟就会重启一次
kubelet 会在 crashloop 中等待 kubeadm 告诉它要做什么,crashloop 是正常的
在初始化控制平面之后,kubelet 就可以正常运行了

3.2 准备好必要的容器镜像

这一步是可选的
只有在希望 kubeadm initkubeadm join 不要下载 k8s.gcr.io 上的默认容器镜像时才执行

kubeadm 有命令可以预先拉取必要的镜像,从而可以在没有互联网的节点上创建集群
详见:在没有互联网的情况下运行 kubeadm

kubeadm 允许使用自定义的镜像仓库
详见:使用自定义镜像

3.3 初始化控制平面节点

控制平面节点是控制平面组件运行的机器
包括:etcd(集群数据库)、API 服务器([kubectl](https://kubernetes.io/docs/reference/kubectl/) 命令行工具与其通信)

  1. (推荐)如果计划将单个控制平面 kubeadm 集群升级为高可用的
    则应该用 --control-plane-endpoint 参数为所有控制平面节点指定共享端点
    共享端点是一个负载均衡器的 DNS 名称或 IP 地址
  2. 选择一个 Pod 网络插件,确定该插件是否需要给 kubeadm init 传参
    根据选择的三方供应商,可能需要设置 --pod-network-cidr 参数为一个特定于供应商的值
  3. (可选)kubeadm 会尝试通过一个常见的端点列表来探测容器运行时
    要使用另外的容器运行时,或在节点上安装了多个容器运行时
    需要指定 kubeadm 参数 --cri-socket,见安装运行时
  4. (可选)除非另有说明,否则 kubeadm 使用与默认网关关联的网络接口来设置此特定控制平面节点的 API 服务器的公布地址
    要使用不同的网络接口,需指定 kubeadm init 参数 --apiserver-advertise-address=
    要使用 IPv6 地址部署一个 IPv6 Kubernetes 集群,必须指定 IPv6 地址
    如:--apiserver-advertise-address=fd00::101

初始化控制平面节点:

kubeadm init <args>

3.4 关于 apiserver-advertise-address 与控制平面端点的注意事项

--apiserver-advertise-address 用来为特定控制平面节点的 API 服务器设置公布地址
--control-plane-endpoint 用来为所有控制平面节点设置共享端点

--control-plane-endpoint 允许使用 IP 地址和能够映射 IP 地址的 DNS 名称
请联系网络管理员来验证这些映射的可能解决方案

映射的例子:

192.168.0.102 cluster-endpoint

192.168.0.102 为节点的 IP 地址,cluster-endpoint 为映射这个 IP 地址的自定义 DNS 名称
可以设置 kubeadm init 参数 --control-plane-endpoint=cluster-endpoint
以及 kubeadm join 参数 cluster-endpoint
今后可以通过修改 cluster-endpoint 映射的 IP 地址,使其在高可用场景下指向负载均衡器

kubeadm 不支持将一个创建时没有使用 --control-plane-endpoint 指定共享端点的单个控制平面集群转换为一个高可用集群

3.5 更多信息

关于 kubeadm init 参数的更多信息见:kubeadm 参考指南

用配置文件配置 kubeadm init 的方法见:通过配置文件使用 kubeadm init

要自定义控制平面组件,需要为每个组件提供额外的参数,见:自定义参数
例如:为控制平面组件与 etcd 服务器的存活状态监测探针分配可选的 IPv6 地址

对一个已经创建好的集群进行配置,见:重新配置一个 kubeadm 集群

要再次运行 kubeadm init,必须先拆除集群

要将具有不同架构的节点加入集群
请确保部署的 DaemonSet 具有该架构的容器映像支持

kubeadm init 首先会运行一系列的预监测,以确保机器准备好运行 Kubernetes
这些预检测会显示警告并在遇到错误时退出
然后 kubeadm init 会下载并安装集群控制平面组件
完成后你应该看到:

Your Kubernetes control-plane 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:
  /docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

要让非 root 用户也可以使用 kubectl,请运行 kubeadm init 输出的这些命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

或者,root 用户可以运行:

export KUBECONFIG=/etc/kubernetes/admin.conf

警告:
kubeadmadmin.conf 中的证书进行签名时
将其配置为 Subject: O = system:masters, CN = kubernetes-admin system:masters 是一个例外的超级用户组,可以绕过鉴权层(如 RBAC)
不要将 admin.conf 文件与任何人共享
应该通过 kubeadm kubeconfig user 命令为其他用户生成 kubeconfig 文件,以授予他们自定义权限
详见为其他用户生成 kubeconfig 文件

可以将 kubeadm init 输出的 kubeadm join 命令记录下来
这些命令可以用来向集群添加节点

可以使用令牌(token)手动地在控制平面节点与正在加入的节点之间进行鉴权
这里的令牌是密钥,请确保它的安全,因为拥有令牌的人可以将已鉴权的节点添加到集群中
可以用 kubeadm token 命令列出、创建、删除令牌
见 kubeadm 参考指南

3.6 安装 Pod 网络插件

必须部署一个基于容器网络接口(Container Network Interface (CNI))的 Pod 网络插件
这样 Pod 才能互相通信
在网络安装完成之前,容器 DNS(CoreDNS)无法启动

1)Pod 网络不能与任何主机网络重叠,如果有任何重叠,可能会出现问题
如果发现网络插件的首选 Pod 网络与某些主机网络之间存在冲突
应该考虑使用合适的 CIDR 块
kubeadm init 上使用 --pod-network-cidr 参数来代替网络插件 YAML 中的配置

2)kubeadm 默认将集群设置为强制使用基于角色的访问控制(role based access conrol (RBAC))
请确保 Pod 网络插件支持 RBAC,任何用来部署 Pod 网络插件的清单也必须支持 RBAC

3)如果要使用 IPv6,无论是双协议栈还是单 IPv6 协议栈
请确保集群的 Pod 网络插件支持 IPv6
CNI 在 v0.6.0 开始支持 IPv6

注意:
kubeadm 应该与 CNI 解耦,对 CNI 供应商的验证目前不在 kubeadm 的端到端测试范围之内
如果发现与 CNI 插件相关的问题,应该在插件供应商对应的 issue 跟踪器中记录
而不是在 kubeadmkubernetes 的 issue 跟踪器中记录

一些外部项目使用 CNI 来提供 Kubernetes Pod 网络,其中一些还支持网络策略

请参阅实现了 Kubernetes 网络模型的插件列表

可以使用以下命令在控制平面节点或具有 kubeconfig 凭据的节点上安装 Pod 网络插件:

kubectl apply -f <add-on.yaml>

可以在每个集群上只安装一个 Pod 网络

安装 Pod 网络后,可以通过检查在 kubectl get pods --all-namespaces 的输出中 CoreDNS Pod 是否为 Running 来确认 Pod 网络是否正常运行
一旦 CoreDNS Pod 启用并运行,就可以继续向集群加入节点

如果网络没有正常工作或 CoreDNS 不在 Running 状态
请查看 kubeadm 的故障排除指南

3.7 管理节点标签

kubeadm 会默认启用 NodeRestriction 准入控制器来限制 kubelet 在节点注册时可以应用哪些标签
准入控制器文档描述了 kubelet--node-labels 选项可以使用哪些标签
其中 node-role.kubernetes.io/control-plane 标签就是一个受限制的标签
kubeadm 在节点创建后使用特权客户端手动应用此标签
可以使用一个有特权的 kubeconfig,比如由 kubeadm 管理的 /etc/kubernetes/admin.conf
通过执行 kubectl label 来手动应用标签

3.8 控制平面节点隔离

默认情况下,出于安全原因,集群不会在控制平面节点上调度 Pod
如果希望能够在控制平面节点上调度 Pod,如单机 Kubernetes 集群,请运行:

kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-

输出:

node "test-01" untainted
...

这将从拥有 node-role.kubernetes.io/control-planenode-role.kubernetes.io/master 污点(taint)的节点上移除它们,包括控制平面节点
这意味着调度程序将能够在任何地方调度 Pod

注意:
node-role.kubernetes.io/master 污点(taint)已弃用
kubeadm 将在 1.25 版本中停止使用它

3.9 添加节点

节点是工作负载(容器与 Pod 等)运行的地方
要添加节点,请对待添加的机器执行以下操作:

SSH 连接机器

成为 root 用户(即:sudo su -

必要时安装一个运行时

运行 kubeadm init 输出的命令,如:

kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>

如果没有 token,可以通过在控制平面运行以下命令获取:

kubeadm token list

输出:

TOKEN                    TTL  EXPIRES              USAGES           DESCRIPTION            EXTRA GROUPS
8ewj1p.9r9hcjoqgajrj4gi  23h  2018-06-12T02:51:28Z authentication,  The default bootstrap  system:
                                                   signing          token generated by     bootstrappers:
                                                                    'kubeadm init'.        kubeadm:
                                                                                           default-node-token

默认情况下,token 24 小时失效
如果在将节点加入到集群时,token 失效了
可以通过在控制平面运行下边的命令创建一个新 token

kubeadm token create

输出:

5didvk.d09sbcov8ph2amjw

如果没有 --discovery-token-ca-cert-hash
可以通过在控制平面节点运行下边的命令获得:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
   openssl dgst -sha256 -hex | sed 's/^.* //'

输出:

8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78

注意:
: 指定 IPv6 元组
必须将 IPv6 地址括在方括号中,如:[fd00::101]:2073

输出:

[preflight] Running pre-flight checks

... (log output of join workflow) ...

Node join complete:
* Certificate signing request sent to control-plane and response
  received.
* Kubelet informed of new secure connection details.

Run 'kubectl get nodes' on control-plane to see this machine join.

几秒钟后,在控制平面节点上执行 kubectl get nodes 时,会注意到该节点出现在输出中

注意:
由于集群节点通常是按顺序初始化的,CoreDNS Pod 很可能都运行在第一个控制平面节点上
为了提供更高的可用性
请在加入新节点后使用 kubectl -n kube-system rollout restart deployment coredns 命令
以重新平衡这些 CoreDNS Pod

3.10(可选的)从控制平面节点以外的计算机控制集群

为了使 kubectl 在其它计算机(如笔记本电脑)上与集群通信
需要将管理员 kubeconfig 文件从控制平面节点复制到工作站:

scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf get nodes

注意:
上面的示例假设为 root 用户启用了 SSH 访问权限
如果没有,可以先将 admin.conf 复制一份,让复制可以被其它用户访问
然后 scp 命令用这个用户来进行远程复制

admin.conf 文件为用户提供了对集群的超级用户特权,应谨慎使用
对于普通用户,建议生成一个为其授予特权的唯一证书
可以使用 kubeadm alpha kubeconfig user --client-name 命令执行此操作
该命令会将 KubeConfig 文件打印到标准输出,应该将其保存到文件并分发给用户
之后,使用 kubectl create (cluster)rolebinding 授予特权

3.11(可选的)将 API 服务器代理到本地主机

想要从集群外部连接到 API 服务器,可以用 kubectl proxy

scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy

现在可以在本地访问 API 服务器 http://localhost:8001/api/v1

4 清理

如果集群中使用了一次性服务器进行测试,可以关闭这些服务器,而无需进一步的清理
可以使用 kubectl config delete-cluster 删除对集群的本地引用

如果要更干净地撤销集群配置, 则应首先清空节点并确保该节点为空, 然后再取消节点配置

4.1 删除节点

用正确的凭证与控制平面通信:

kubectl drain <node name> --delete-emptydir-data --force --ignore-daemonsets

在删除节点前,先重置 kubeadm 安装的状态:

kubeadm reset

重置进程不会重置或清理 iptables 规则或 IPVS 表
如想重置 iptables,必须手动执行:

iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

要重置 IPVS 表,必须运行:

ipvsadm -C

删除节点:

kubectl delete node <node name>

如想重新开始,只需运行 kubeadm initkubeadm join 并加上适当的参数

4.2 清理控制平面

可以在控制平面主机上使用 kubeadm reset 来触发尽力而为的清理

有关 reset 子命令及其选项的更多信息,见 kubeadm reset 参考文献

5 版本偏差策略

虽然 kubeadm 允许所管理的组件有一定程度的版本差异
但建议将 kubeadm 的版本与控制平面组件、kube-proxykubelet 的版本相匹配

5.1 kubeadm 中的 Kubernetes 版本差异

kubeadm 可用于与自己相同版本的或旧一个版本的 Kubernetes 组件
Kubernetes 的版本可以通过使用 kubeadm init--kubernetes-version 标志
或使用 --config 时的 [ClusterConfiguration.kubernetesVersion](https://kubernetes.io/docs/reference/config-api/kubeadm-config.v1beta3/) 字段指定给 kubeadm
这个选项将控制 kube-apiserverkube-controller-managerkube-schedulerkube-proxy 的版本

例如:

  • kubeadm 的版本为 1.24
  • kubernetesVersion 必须为 1.24 或者 1.23

5.2 kubeadm 与 kubelet 的版本差异

kubeadm 命令如何在现有节点或由 kubeadm 管理的整个集群上运行,存在着一些限制

如果有新的节点要加入集群
用于 kubeadm joinkubeadm 二进制文件必须与用 kubeadm init 创建集群时
或用 kubeadm upgrade 升级同一节点时所用的 kubeadm 版本一致
类似的规则也适用于除了 kubeadm upgrade 以外的其他 kubeadm 命令

kubeadm join 的例子:

  • 使用 kubeadm init 创建集群时使用的版本为 1.24 的 kubeadm
  • 添加节点时必须使用版本为 1.24 的 kubeadm 二进制文件

对于正在升级的节点
使用的 kubeadm 版本必须与管理该节点的 kubeadm 有相同的小版本或新一个小版本

kubeadm upgrade 的例子:

  • 用版本为 1.23 的 kubeadm 创建的某个节点或升级过该节点
  • 用于升级该节点的 kubeadm 版本必须为 1.23 或 1.24

要了解更多关于不同 Kubernetes 组件之间的版本差异,见版本差异策略

6 局限性

6.1 集群弹性

前边创建的集群只有一个控制平面节点,上边运行了一个 etcd 数据库
如果控制平面节点挂了,集群可能会丢失数据,并且可能需要从头开始重新创建集群

解决方法:

定期备份 etcd
kubeadm 配置的 etcd 数据目录位于控制平面节点上的 /var/lib/etcd

使用多个控制平面节点
请阅读两种高可用拓扑选择一个提供了高可用性的集群拓扑

6.2 平台兼容性

kubeadm deb/rpm 软件包和二进制文件是为 amd64、arm (32-bit)、arm64、ppc64le 和 s390x 构建的
遵循多平台提案

从 v1.12 开始还支持用于控制平面和插件的多平台容器镜像

只有部分网络提供商为所有平台提供了解决方案
请查阅上方的网络供应商清单或每个供应商的文档以确定供应商是否支持对应的平台

7 下一步

  • 使用 Sonobuoy 验证集群是否正常运行
  • 有关使用 kubeadm 升级集群的详细信息,见升级 kubeadm 集群
  • 在 kubeadm 参考文档中了解有关 kubeadm 的进阶用法
  • 了解有关 Kubernetes 概念和 kubectl 的更多信息
  • 有关 Pod 网络插件的更多列表,见集群网络页面
  • 其它插件见插件列表, 包括用于 Kubernetes 集群的日志、监视、网络策略、可视化和控制的工具
  • 配置集群如何处理集群事件的日志以及在 Pod 中运行的应用程序的日志
    有关所涉及内容的概述,见日志架构

目录、参考文献

你可能感兴趣的:(Kubernetes,笔记,kubernetes,容器)