kubeadm_k8s_v1.31高可用部署教程
注意:开始之前需要明确部署服务器的架构(x86或者arm64),因为这个会关系到下面对应下载的镜像、软件版本,本文以ubuntu(arm64)为操作环境。查看当前操作系统架构输入命令:uname -a
实验环境
- ubuntu 20.04.5 LTS (aarch64)
- kubeadm:v1.31
- kubectl:v1.31
- kubelet:v1.31
- containerd:1.7.22
- etcd:3.5.15-0
- 集群架构规划:2个master节点高可用、3个worker节点、3个etcd节点集群、2组keepalive+haproxy高可用
注意:
- 查看操作系统版本、架构:uname -a
- kubeadm、kubectl、kubelet三者的版本尽量都一致,但是0.01版本差之内应该问题不大。具体版本对照可以参考官网点击查看
- containerd版本下载安装点击查看
- etcd的版本下载安装点击查看
- 官方集群部署教程参考点击查看
部署拓扑图
部署署架构
- Stacked etcd topology(内置自动部署ETCD集群)
- External etcd topology(外部独立部署ETCD集群)(推荐方案,本文采用方案)
Load Balance
如上图黄色区域所示:关于多master的高可用方案本文采用keepalive+haproxy来实现。
Control plane node
这个表示k8s里面的master节点,如图有3个但是本文因为虚拟机有限就拿2个来演示。用来管理操控整个集群的节点,一般kubectl命令会在此类节点操作。
Worker node
表示非master节点,一般用来实际被调度到需要部署POD的节点。
资源分配(8台虚拟机)
hostname | ip | role | 必装基础软件 | 操作系统 | 系统架构 | 备注 |
---|---|---|---|---|---|---|
ubuntu0 | 192.168.17.247 | master1 | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | |
ubuntu1 | 192.168.17.68 | master2 | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | |
ubuntu2 | 192.168.17.40 | worker1 | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | |
ubuntu3 | 192.168.17.54 | worker2 | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | |
ubuntu4 | 192.168.17.83 | worker3 | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | |
ubuntu5 | 192.168.17.219 | etcd1(兼keepalive+haproxy) | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | 虚拟机有限,在该ETCD节点也部署了keepalive+haproxy |
ubuntu6 | 192.168.17.203 | etcd1(兼keepalive+haproxy) | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 | 虚拟机有限,在该ETCD节点也部署了keepalive+haproxy |
ubuntu7 | 192.168.17.79 | etcd1 | containerd:V1.7.22kubeadm:V1.31kubectl:V1.31kubelet:V1.31 | Ubuntu 20.04.5 LTS | aarch64 |
1、上面的containerd:V1.7.22、kubeadm:V1.31、kubectl:V1.31的软件安装细节会在下文详细描述。
2、ubuntu5和ubuntu6上由于虚拟机资源有限就同时用来部署etcd和keepalive+haproxy。
集群列表
root@ubuntu1:~/kubernetes/argocd# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ubuntu0 Ready control-plane 2d2h v1.31.1 192.168.17.247 <none> Ubuntu 24.04.1 LTS 6.8.0-49-generic containerd://1.7.22
ubuntu1 Ready control-plane 2d2h v1.31.1 192.168.17.68 <none> Ubuntu 20.04.5 LTS 5.4.0-200-generic containerd://1.7.22
ubuntu2 Ready <none> 2d v1.31.1 192.168.17.40 <none> Ubuntu 20.04.6 LTS 5.4.0-200-generic containerd://1.7.22
ubuntu3 Ready <none> 2d v1.31.1 192.168.17.54 <none> Ubuntu 20.04.6 LTS 5.4.0-200-generic containerd://1.7.22
ubuntu4 Ready <none> 2d v1.31.3 192.168.17.83 <none> Ubuntu 24.04.1 LTS 6.8.0-49-generic containerd://1.7.22
前置准备
- 系统设置
以下所有操作需要在所有(master|worker|etcd)角色节点服务器上执行相同的操作。
关闭swap
# 永久设置
sudo sed -i '/swap/s/^\([^#]\)/#\1/' /etc/fstab
# 重启
sudo reboot
# 验证 swap 已被禁用(如果没有输出,则表示 swap 已被成功禁用)
swapon --show
解释:
/swap/
:匹配包含swap
的行。s/^\([^#]\)/#\1/
:将行首没有#
的字符替换为#
,即注释掉该行。
开启ipv4转发
要永久启用 IPv4 转发,需要修改系统配置文件。
- 打开配置文件:
sudo vim /etc/sysctl.conf
- 找到或添加以下行:
net.ipv4.ip_forward=1
- 保存并退出编辑器。
- 使修改生效:
sudo sysctl -p
或者
sudo sysctl --system
- 运行以下命令确认设置是否生效:
cat /proc/sys/net/ipv4/ip_forward
如果输出为 1
,表示 IPv4 转发已启用。
以上是将所有的节点服务器的swap关闭和ipv4转发开启,其实官网说明还有其他需要关注的点但是这些基本可以不用关注对于自己本地虚拟机环境,除非公司生产级别机房网络防火墙环境可以关注。
更多设置
1、Verify the MAC address and product_uuid are unique for every node2、Check network adapters3、Check required ports4、Swap configuration
- 软件安装
以下所有操作需要在所有(master|worker|etcd)角色节点服务器上执行相同的操作。
下面的内容本文会以当前环境ubuntu为例,说明kubeadm、kubectl、kubelet的安装过程。
具体更多可以参考官网:官网教程
安装 kubeadm、kubelet 和 kubectl
你需要在每台机器上安装以下的软件包:
kubeadm:用来初始化集群的指令。
kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
kubectl:用来与集群通信的命令行工具。
kubeadm 不能帮你安装或者管理 kubelet 或 kubectl, 所以你需要确保它们与通过 kubeadm 安装的控制平面的版本相匹配。 如果不这样做,则存在发生版本偏差的风险,可能会导致一些预料之外的错误和问题。 然而,控制平面与 kubelet 之间可以存在一个次要版本的偏差,但 kubelet 的版本不可以超过 API 服务器的版本。 例如,1.7.0 版本的 kubelet 可以完全兼容 1.8.0 版本的 API 服务器,反之则不可以。
以下指令适用于 Kubernetes 1.31.
- 更新
apt
包索引并安装使用 Kubernetesapt
仓库所需要的包:
sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
- 下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本:
# 如果 `/etc/apt/keyrings` 目录不存在,则应在 curl 命令之前创建它,请阅读下面的注释。# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
- 添加 Kubernetes
apt
仓库。 请注意,此仓库仅包含适用于 Kubernetes 1.31 的软件包; 对于其他 Kubernetes 次要版本,则需要更改 URL 中的 Kubernetes 次要版本以匹配你所需的次要版本 (你还应该检查正在阅读的安装文档是否为你计划安装的 Kubernetes 版本的文档)。
# 此操作会覆盖 /etc/apt/sources.list.d/kubernetes.list 中现存的所有配置。
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
- 更新
apt
包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。
官方软件对照表
Kubernetes 为每个组件提供二进制文件以及一组标准的客户端应用来引导集群或与集群交互。 像 API 服务器这样的组件能够在集群内的容器镜像中运行。 这些组件作为官方发布过程的一部分,也以容器镜像的形式提供。 所有二进制文件和容器镜像都可用于多种操作系统和硬件架构。
- 镜像下载
【matser】节点必备镜像
以下所有操作需要在所有(master)角色节点服务器上执行相同的操作。
第1个控制面板
镜像列表
docker.io/calico/cni v3.26.0 54cd67220700c 85.5MB
docker.io/calico/kube-controllers v3.26.0 aebf438b736fc 29.2MB
docker.io/calico/node v3.26.0 0259a80e0f442 84.6MB
registry.k8s.io/kube-apiserver v1.31.0 cd0f0ae0ec9e0 25.6MB
registry.k8s.io/kube-controller-manager v1.31.0 fcb0683e6bdbd 23.9MB
registry.k8s.io/kube-proxy v1.31.0 71d55d66fd4ee 26.8MB
registry.k8s.io/kube-scheduler v1.31.0 fbbbd428abb4d 18.4MB
registry.k8s.io/pause 3.10 afb61768ce381 266kB
以下是第1个控制面板最终部署成功之后的POD以及容器的状态。
POD列表
root@ubuntu1:~/kubernetes/deploy# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-7f764f4f68-zdppk 1/1 Running 2 (123m ago) 4d
kube-system calico-node-fbljp 1/1 Running 2 (123m ago) 4d
kube-system calico-node-jcm24 1/1 Running 2 (122m ago) 4d
kube-system calico-node-n6ljm 1/1 Running 2 (123m ago) 4d
kube-system calico-node-w9jzw 1/1 Running 2 (122m ago) 4d
kube-system calico-node-wwxdt 1/1 Running 2 (122m ago) 4d
kube-system coredns-7c65d6cfc9-lwmwq 1/1 Running 3 (123m ago) 4d2h
kube-system coredns-7c65d6cfc9-tjwxq 1/1 Running 3 (123m ago) 4d2h
kube-system kube-apiserver-ubuntu0 1/1 Running 4 (123m ago) 4d1h
kube-system kube-apiserver-ubuntu1 1/1 Running 4 (123m ago) 4d2h
kube-system kube-controller-manager-ubuntu0 1/1 Running 4 (123m ago) 4d1h
kube-system kube-controller-manager-ubuntu1 1/1 Running 12 (123m ago) 4d2h
kube-system kube-proxy-5cmpq 1/1 Running 3 (123m ago) 4d1h
kube-system kube-proxy-9dl6q 1/1 Running 2 (122m ago) 4d
kube-system kube-proxy-lklxl 1/1 Running 2 (122m ago) 4d
kube-system kube-proxy-v8xbj 1/1 Running 3 (123m ago) 4d2h
kube-system kube-proxy-zwqvf 1/1 Running 2 (122m ago) 4d
kube-system kube-scheduler-ubuntu0 1/1 Running 4 (123m ago) 4d1h
kube-system kube-scheduler-ubuntu1 1/1 Running 12 (123m ago) 4d2h
容器列表
root@ubuntu1:~/kubernetes/deploy# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
c62f0512e1008 aebf438b736fc 2 hours ago Running calico-kube-controllers 2 37f46550b1ab8 calico-kube-controllers-7f764f4f68-zdppk
b9ec1ab460b4a 0259a80e0f442 2 hours ago Running calico-node 2 ec6bba06380ae calico-node-fbljp
2c1805e953d0e 71d55d66fd4ee 2 hours ago Running kube-proxy 3 a929c6564380d kube-proxy-v8xbj
80cc0d9ca2347 fbbbd428abb4d 2 hours ago Running kube-scheduler 12 af41be53a5af8 kube-scheduler-ubuntu1
8852dbb8a1b2a cd0f0ae0ec9e0 2 hours ago Running kube-apiserver 4 0574d74be139b kube-apiserver-ubuntu1
2f7570ebf94d7 fcb0683e6bdbd 2 hours ago Running kube-controller-manager 12 0d6d06a832dae kube-controller-manager-ubuntu1
其他控制面板
镜像列表
docker.io/calico/cni v3.26.0 54cd67220700c 85.5MB
docker.io/calico/node v3.26.0 0259a80e0f442 84.6MB
registry.k8s.io/coredns/coredns v1.11.3 2f6c962e7b831 16.9MB
registry.k8s.io/kube-apiserver v1.31.0 cd0f0ae0ec9e0 25.6MB
registry.k8s.io/kube-controller-manager v1.31.0 fcb0683e6bdbd 23.9MB
registry.k8s.io/kube-proxy v1.31.0 71d55d66fd4ee 26.8MB
registry.k8s.io/kube-scheduler v1.31.0 fbbbd428abb4d 18.4MB
registry.k8s.io/pause 3.10 afb61768ce381 266kB
以下是其他控制面板最终部署成功之后的POD以及容器的状态。
POD列表
root@ubuntu1:~/kubernetes/deploy# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-7f764f4f68-zdppk 1/1 Running 2 (123m ago) 4d
kube-system calico-node-fbljp 1/1 Running 2 (123m ago) 4d
kube-system calico-node-jcm24 1/1 Running 2 (122m ago) 4d
kube-system calico-node-n6ljm 1/1 Running 2 (123m ago) 4d
kube-system calico-node-w9jzw 1/1 Running 2 (122m ago) 4d
kube-system calico-node-wwxdt 1/1 Running 2 (122m ago) 4d
kube-system coredns-7c65d6cfc9-lwmwq 1/1 Running 3 (123m ago) 4d2h
kube-system coredns-7c65d6cfc9-tjwxq 1/1 Running 3 (123m ago) 4d2h
kube-system kube-apiserver-ubuntu0 1/1 Running 4 (123m ago) 4d1h
kube-system kube-apiserver-ubuntu1 1/1 Running 4 (123m ago) 4d2h
kube-system kube-controller-manager-ubuntu0 1/1 Running 4 (123m ago) 4d1h
kube-system kube-controller-manager-ubuntu1 1/1 Running 12 (123m ago) 4d2h
kube-system kube-proxy-5cmpq 1/1 Running 3 (123m ago) 4d1h
kube-system kube-proxy-9dl6q 1/1 Running 2 (122m ago) 4d
kube-system kube-proxy-lklxl 1/1 Running 2 (122m ago) 4d
kube-system kube-proxy-v8xbj 1/1 Running 3 (123m ago) 4d2h
kube-system kube-proxy-zwqvf 1/1 Running 2 (122m ago) 4d
kube-system kube-scheduler-ubuntu0 1/1 Running 4 (123m ago) 4d1h
kube-system kube-scheduler-ubuntu1 1/1 Running 12 (123m ago) 4d2h
容器列表
root@ubuntu0:~/kubernetes/deploy# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
6c43c1474aa4d 2f6c962e7b831 2 hours ago Running coredns 3 ba5d080b5f862 coredns-7c65d6cfc9-lwmwq
0bc8ae67cf4d4 2f6c962e7b831 2 hours ago Running coredns 3 0dea1fe6c129e coredns-7c65d6cfc9-tjwxq
a7f14982bd6d6 0259a80e0f442 2 hours ago Running calico-node 2 aacda9063012b calico-node-n6ljm
8b7b203682f7b 71d55d66fd4ee 2 hours ago Running kube-proxy 3 74d686edd3de4 kube-proxy-5cmpq
c539180dae2e0 fbbbd428abb4d 2 hours ago Running kube-scheduler 4 b614e15187a44 kube-scheduler-ubuntu0
d873f0d9b675b fcb0683e6bdbd 2 hours ago Running kube-controller-manager 4 e1a43a0d72b4b kube-controller-manager-ubuntu0
08bebcabd7398 cd0f0ae0ec9e0 2 hours ago Running kube-apiserver 4 7adebc9f57e18 kube-apiserver-ubuntu0
【worker】节点必备镜像
以下所有操作需要在所有(worker)角色节点服务器上执行相同的操作。
镜像列表
docker.io/calico/cni v3.26.0 54cd67220700c 85.5MB
docker.io/calico/node v3.26.0 0259a80e0f442 84.6MB
registry.k8s.io/kube-proxy v1.31.0 71d55d66fd4ee 26.8MB
registry.k8s.io/pause 3.10 afb61768ce381 266kB
以下是所有worker工作节点最终部署成功之后的POD以及容器的状态。
POD列表
root@ubuntu1:~/kubernetes/deploy# kubectl get pods -A -o wide | grep 17.54
kube-system calico-node-wwxdt 1/1 Running 2 (136m ago) 4d 192.168.17.54 ubuntu3 <none> <none>
kube-system kube-proxy-lklxl 1/1 Running 2 (136m ago) 4d 192.168.17.54 ubuntu3 <none> <none>
容器列表
root@ubuntu3:~/kubernetes/deploy# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
07cb28b40db37 0259a80e0f442 2 hours ago Running calico-node 2 3d057133a4c1b calico-node-wwxdt
309338ec147ef 71d55d66fd4ee 2 hours ago Running kube-proxy 2 0930d4cab2756 kube-proxy-lklxl
【etcd】节点必备镜像、POD、容器
以下所有操作需要在所有(etcd)角色节点服务器上执行相同的操作。
镜像列表
registry.k8s.io/etcd 3.5.15-0 27e3830e14027 66.4MB
以下是所有ETCD最终部署成功之后的POD以及容器的状态。
POD列表
root@ubuntu5:~# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
eab9acc34da36 27e3830e14027 2 hours ago Running etcd 5 67442b056bbcf etcd-ubuntu5
容器列表
root@ubuntu5:~# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
eab9acc34da36 27e3830e14027 2 hours ago Running etcd 5 67442b056bbcf etcd-ubuntu5
【containerd】下载安装
以下操作需要在所有的集群节点(master|worker|etcd)执行。
- 下载安装
https://github.com/containerd/containerd/blob/main/docs/getting-started.md
大家按照上面文章Option1的step1→step2→step3操作,但是要注意大家下面下载的软件需要结合自己的操作系统架构来选择。我这边是ubuntu aarch64所以选择想相关的aarch64软件就好了。
https://r7qll1fhgt.feishu.cn/space/api/box/stream/download/asynccode/?code=ZjY2YmM2MzdjYzQzN2I4OWQ2MGUyMjgzMjA3ZWFiNWJfSzh2N0o5UGVKYVNWRlQ1MzNuZVVabEozU1V1a29XN0xfVG9rZW46T2NZN2JwcldDb3Fkc2F4WjlkN2NId0l0bkNjXzE3MzQ0MDM2MTE6MTczNDQwNzIxMV9WNA
- 配置containerd
如果本地没有可以创建:/etc/containerd/config.toml,把下面的内容复制到自己的机器上对应的文件/etc/containerd/config.toml中**。**
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
temp = ""
version = 2
[cgroup]
path = ""
[debug]
address = ""
format = ""
gid = 0
level = ""
uid = 0
[grpc]
address = "/run/containerd/containerd.sock"
gid = 0
max_recv_message_size = 16777216
max_send_message_size = 16777216
tcp_address = ""
tcp_tls_ca = ""
tcp_tls_cert = ""
tcp_tls_key = ""
uid = 0
[metrics]
address = ""
grpc_histogram = false
[plugins]
[plugins."io.containerd.gc.v1.scheduler"]
deletion_threshold = 0
mutation_threshold = 100
pause_threshold = 0.02
schedule_delay = "0s"
startup_delay = "100ms"
[plugins."io.containerd.grpc.v1.cri"]
cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"]
device_ownership_from_security_context = false
disable_apparmor = false
disable_cgroup = false
disable_hugetlb_controller = true
disable_proc_mount = false
disable_tcp_service = true
drain_exec_sync_io_timeout = "0s"
enable_cdi = false
enable_selinux = false
enable_tls_streaming = false
enable_unprivileged_icmp = false
enable_unprivileged_ports = false
ignore_deprecation_warnings = []
ignore_image_defined_volumes = false
image_pull_progress_timeout = "5m0s"
image_pull_with_sync_fs = false
max_concurrent_downloads = 3
max_container_log_line_size = 16384
netns_mounts_under_state_dir = false
restrict_oom_score_adj = false
# 注意这里需要根据pause实际版本记得调整
sandbox_image = "registry.k8s.io/pause:3.10"
selinux_category_range = 1024
stats_collect_period = 10
stream_idle_timeout = "4h0m0s"
stream_server_address = "127.0.0.1"
stream_server_port = "0"
systemd_cgroup = false
tolerate_missing_hugetlb_controller = true
unset_seccomp_profile = ""
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
conf_template = ""
ip_pref = ""
max_conf_num = 1
setup_serially = false
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
disable_snapshot_annotations = true
discard_unpacked_layers = false
ignore_blockio_not_enabled_errors = false
ignore_rdt_not_enabled_errors = false
no_pivot = false
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
privileged_without_host_devices_all_devices_allowed = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
sandbox_mode = ""
snapshotter = ""
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
privileged_without_host_devices_all_devices_allowed = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
sandbox_mode = "podsandbox"
snapshotter = ""
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
# 这个地方需要注意,要保持kubelet一致的cgroup方式。本文采用cgroups所以设置为true,如果不是需要改成true。
# 具体可以看下这里解释:https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-runtime:~:text=%E7%B3%BB%E7%BB%9F%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F%E3%80%82-,%E5%AE%89%E8%A3%85%E5%AE%B9%E5%99%A8%E8%BF%90%E8%A1%8C%E6%97%B6,-%E4%B8%BA%E4%BA%86%E5%9C%A8%20Pod**
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
privileged_without_host_devices_all_devices_allowed = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = ""
sandbox_mode = ""
snapshotter = ""
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]
[plugins."io.containerd.grpc.v1.cri".image_decryption]
key_model = "node"
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = ""
[plugins."io.containerd.grpc.v1.cri".registry.auths]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.headers]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
tls_cert_file = ""
tls_key_file = ""
[plugins."io.containerd.internal.v1.opt"]
path = "/opt/containerd"
[plugins."io.containerd.internal.v1.restart"]
interval = "10s"
[plugins."io.containerd.internal.v1.tracing"]
[plugins."io.containerd.metadata.v1.bolt"]
content_sharing_policy = "shared"
[plugins."io.containerd.monitor.v1.cgroups"]
no_prometheus = false
[plugins."io.containerd.nri.v1.nri"]
disable = true
disable_connections = false
plugin_config_path = "/etc/nri/conf.d"
plugin_path = "/opt/nri/plugins"
plugin_registration_timeout = "5s"
plugin_request_timeout = "2s"
socket_path = "/var/run/nri/nri.sock"
[plugins."io.containerd.runtime.v1.linux"]
no_shim = false
runtime = "runc"
runtime_root = ""
shim = "containerd-shim"
shim_debug = false
[plugins."io.containerd.runtime.v2.task"]
platforms = ["linux/arm64/v8"]
sched_core = false
[plugins."io.containerd.service.v1.diff-service"]
default = ["walking"]
[plugins."io.containerd.service.v1.tasks-service"]
blockio_config_file = ""
rdt_config_file = ""
[plugins."io.containerd.snapshotter.v1.aufs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.blockfile"]
fs_type = ""
mount_options = []
root_path = ""
scratch_file = ""
[plugins."io.containerd.snapshotter.v1.btrfs"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.devmapper"]
async_remove = false
base_image_size = ""
discard_blocks = false
fs_options = ""
fs_type = ""
pool_name = ""
root_path = ""
[plugins."io.containerd.snapshotter.v1.native"]
root_path = ""
[plugins."io.containerd.snapshotter.v1.overlayfs"]
mount_options = []
root_path = ""
sync_remove = false
upperdir_label = false
[plugins."io.containerd.snapshotter.v1.zfs"]
root_path = ""
[plugins."io.containerd.tracing.processor.v1.otlp"]
[plugins."io.containerd.transfer.v1.local"]
config_path = ""
max_concurrent_downloads = 3
max_concurrent_uploaded_layers = 3
[[plugins."io.containerd.transfer.v1.local".unpack_config]]
differ = ""
platform = "linux/arm64/v8"
snapshotter = "overlayfs"
[proxy_plugins]
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
path = "ctd-decoder"
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
[timeouts]
"io.containerd.timeout.bolt.open" = "0s"
"io.containerd.timeout.metrics.shimstats" = "2s"
"io.containerd.timeout.shim.cleanup" = "5s"
"io.containerd.timeout.shim.load" = "5s"
"io.containerd.timeout.shim.shutdown" = "3s"
"io.containerd.timeout.task.state" = "2s"
[ttrpc]
address = ""
gid = 0
uid = 0
也可以执行:containerd config default > config.toml,这样内容就可以直接复制到/etc/containerd/config.toml文件中不要手动复制了。但是文件上面2处改动点记得调整然后重启containerd。
- 查看containerd是否启动成功
# 重启
systemctl restart containerd.service
# 查看状态
systemctl status containerd.service
# 或者执行
journalctl -u containerd -f
https://r7qll1fhgt.feishu.cn/space/api/box/stream/download/asynccode/?code=MjAyN2U5ZTYwOGUzOTRmNmY3Y2YzOTNmNDVhMzI4NjRfb0R2T2w1UzlIUlUyRmFJSDFTdkFiV0luV3l3d2x3dzVfVG9rZW46Ums1RGJFQ2pKb1VCVFp4S1Zia2M1azRJblBlXzE3MzQ0MDM2MTE6MTczNDQwNzIxMV9WNA
注意需要保证所有机器上的containerd都要启动成哦。
【最终全部镜像】
以下拉取镜像按各自节点角色所需拉取对应的镜像就可以。
通过上面的各个节点的镜像列表可以看出,在部署集群之前需要全部准备的镜像列表有如下11个镜像。然后开始部署之前务必保证以下镜像出现在各自角色(master|worker|etcd)的节点上。
# master节点需要准备的镜像
crictl pull docker.io/calico/cni:v3.26.0
crictl pull docker.io/calico/kube-controllers:v3.26.0
crictl pull docker.io/calico/node:v3.26.0
crictl pull registry.k8s.io/kube-apiserver:v1.31.0
crictl pull registry.k8s.io/kube-controller-manager:v1.31.0
crictl pull registry.k8s.io/kube-proxy:v1.31.0
crictl pull registry.k8s.io/kube-scheduler:v1.31.0
crictl pull registry.k8s.io/pause:3.10
# worker节点需要准备的镜像
crictl pull crictl pull docker.io/calico/cni:v3.26.0
crictl pull docker.io/calico/node:v3.26.0
crictl pull registry.k8s.io/kube-proxy:v1.31.0
crictl pull registry.k8s.io/pause:3.10
# etcd节点需要准备的镜像
crictl pull registry.k8s.io/etcd:3.5.15-0
注意:以上镜像的拉取基本都需要科学上网,所以大家需要在有网络的环境提前将这些镜像下载好然后上传到自己的私有HUB或者某某云HUB仓库。在pull到对应的集群节点,否则集群启动大部分组件POD因为拉取不到镜像启动失败从而导致集群无法运行成功。
镜像转换参考如下:注意下面的镜像都是arm64架构的镜像,根据自己的环境下载不同架构镜像。本文中会用到containerd弃用docker,所以会出现crictl和ctr命令,不清楚的大家可以课后花时间去了解。
# crictl 拉取镜像 10个
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-apiserver:v1.31.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-controller-manager:v1.31.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-scheduler:v1.31.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-proxy:v1.31.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/coredns:v1.11.3
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/pause:3.10
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/etcd:3.5.15-0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/calico_cni:v3.26.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/calico_node:v3.26.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/calico_kube-controllers:v3.26.0
crictl pull registry.cn-hangzhou.aliyuncs.com/shouzhi/etcd:3.5.15-0
# 修改镜像名 10个
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-apiserver:v1.31.0 registry.k8s.io/kube-apiserver:v1.31.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-controller-manager:v1.31.0 registry.k8s.io/kube-controller-manager:v1.31.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-scheduler:v1.31.0 registry.k8s.io/kube-scheduler:v1.31.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/kube-proxy:v1.31.0 registry.k8s.io/kube-proxy:v1.31.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/coredns:v1.11.3 registry.k8s.io/coredns/coredns:v1.11.3
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/pause:3.10 registry.k8s.io/pause:3.10
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/etcd:3.5.15-0 registry.k8s.io/etcd:3.5.15-0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/calico_cni:v3.26.0 docker.io/calico/cni:v3.26.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/calico_node:v3.26.0 docker.io/calico/node:v3.26.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/calico_kube-controllers:v3.26.0 docker.io/calico/kube-controllers:v3.26.0
ctr --namespace k8s.io image tag registry.cn-hangzhou.aliyuncs.com/shouzhi/etcd:3.5.15-0 registry.k8s.io/etcd:3.5.15-0
开始部署
keepalive、haproxy
以下所有操作需要在所有(keepalive|haproxy)角色节点服务器上执行相同的操作。
部署ETC集群
以下操作会在etcd集群中选择其中1个服务器来作为总操作节点,用于生成以及分发其他etcd所需要的配置文件以及相关证书。
部署方式
使用 kubeadm 创建一个高可用 etcd 集群
默认情况下,kubeadm 在每个控制平面节点上运行一个本地 etcd 实例。也可以使用外部的 etcd 集群,并在不同的主机上提供 etcd 实例。 这两种方法的区别在高可用拓扑的选项页面中阐述。
这个任务将指导你创建一个由三个成员组成的高可用外部 etcd 集群,该集群在创建过程中可被 kubeadm 使用。
准备开始
三个可以通过 2379 和 2380 端口相互通信的主机。本文档使用这些作为默认端口。 不过,它们可以通过 kubeadm 的配置文件进行自定义。
每个主机必须安装 systemd 和 bash 兼容的 shell。
每台主机必须安装有容器运行时、kubelet 和 kubeadm。
每个主机都应该能够访问 Kubernetes 容器镜像仓库 (registry.k8s.io), 或者使用 kubeadm config images list/pull 列出/拉取所需的 etcd 镜像。 本指南将把 etcd 实例设置为由 kubelet 管理的静态 Pod。
一些可以用来在主机间复制文件的基础设施。例如 ssh 和 scp 就可以满足此需求。
准备机器
- 以上是3节点etcd集群的机器分配,其中192.168.17.219、192.168.17.203由于资源有限所以同时也会作为部署keepalive+haproxy的机器。
- 192.168.17.219也会作为部署etcd的总的部署操作机器,用于制作所有节点etcd集群证书和相关的配置文件以及分发相关证书和相关的证书到其他节点192.168.17.203、192.168.17.79机器上。我们把192.168.17.219称作etcd部署的操作节点。
- 将192.168.17.219都设置成可免密登陆其他etcd节点(192.168.17.203、192.168.17.79),如果免密登设置陆不了解可以自行度娘了解,很简单这里就不在文中讲解。
部署教程
# 打开官方地址写的很清晰,这里就不再赘述了。
https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/
确保证书文件都在
如下所示:(除非自己有自定义文件路径)
$HOST0
所需文件的完整列表如下
/tmp/${HOST0}
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
├── ca.crt
├── ca.key
├── healthcheck-client.crt
├── healthcheck-client.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key
在 $HOST1
上:
$HOME
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
├── ca.crt
├── healthcheck-client.crt
├── healthcheck-client.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key
在 $HOST2
上:
$HOME
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
├── ca.crt
├── healthcheck-client.crt
├── healthcheck-client.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key
以上任意节点的3个红色文件是后面要给k8s集群用到的。
- apiserver-etcd-client.crt
- apiserver-etcd-client.key
- ca.crt
部署成功你会看到每个节点都有
root@ubuntu5:~# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
eab9acc34da36 27e3830e14027 2 days ago Running etcd 5 67442b056bbcf etcd-ubuntu5
检查集群运行状况
- 执行
# 如果没有etcdctl终端命令执行下载就好了(apt或者yum)
ETCDCTL_API=3 etcdctl \
--cert /etc/kubernetes/pki/etcd/peer.crt \
--key /etc/kubernetes/pki/etcd/peer.key \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://192.168.17.219:2379,https://192.168.17.203:2379,https://192.168.17.79:2379 endpoint health
- 输出
输出以下表示集群成功启动
https://192.168.17.203:2379 is healthy: successfully committed proposal: took = 16.715546ms
https://192.168.17.219:2379 is healthy: successfully committed proposal: took = 18.348496ms
https://192.168.17.79:2379 is healthy: successfully committed proposal: took = 18.501066ms
init第1个matser
重要!重要!重要!确保这个matser节点上的以下内容一定是前置准备好的。
- 当前节点必备的镜像一定要都提前pull到本机了,请做好检查
- 当前节点containerd启动成功,请做好检查
- swap是关闭的
- ipv4转发是开启的
- 内存至少2G
- CPU至少2核
准备ETCD证书
# 这个操作需要在你的任意一个etcd的节点上操作都可以
export CONTROL_PLANE="root@192.168.17.247"scp /etc/kubernetes/pki/etcd/ca.crt "${CONTROL_PLANE}":
scp /etc/kubernetes/pki/apiserver-etcd-client.crt "${CONTROL_PLANE}":
scp /etc/kubernetes/pki/apiserver-etcd-client.key "${CONTROL_PLANE}":
- root@192.168.17.247:这个是你的第1个master控制面板的用户和IP。
- ca.crt**、apiserver-etcd-client.crt、apiserver-etcd-client.key这3个文件会传到你第1个master的root用户的目录下。**
# 这个操作在第1个matser上操作
root@ubuntu1:~# pwd
/root
root@ubuntu1:~# ls -l
-rw-r--r-- 1 root root 1123 Dec 9 14:16 apiserver-etcd-client.crt
-rw------- 1 root root 1675 Dec 9 14:16 apiserver-etcd-client.key
-rw-r--r-- 1 root root 1094 Dec 9 14:16 ca.crt
- 把文件放到第1个master对应的目录中
# 这个操作在第1个matser上操作
mkdir -p /etc/kubernetes/pki/etcd/
scp ca.crt /etc/kubernetes/pki/etcd/ca.crt
scp apiserver-etcd-client.key /etc/kubernetes/pki/apiserver-etcd-client.key
scp apiserver-etcd-client.crt /etc/kubernetes/pki/apiserver-etcd-client.crt
准备init config文件
以下红色内容需要注意调整
apiVersion: kubeadm.k8s.io/v1beta4
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
# 你的第1个master的IP.
advertiseAddress: 192.168.17.68
# 你的第1个master暴露ApiServer的端口,一般建议不要改除非端口环境有冲突否则就写6443.
bindPort: 6443
nodeRegistration:
# 你的第1个master上安装的containerd对应的containerd.sock文件目录。如有自定义记得调整.
# 如果不知道在哪里可以执行:cat /etc/containerd/config.toml | grep socket
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
imagePullSerial: true
# 你的第1个master节点的hostname,一定要按实际调整.
name: ubuntu1
taints: null
timeouts:
controlPlaneComponentHealthCheck: 4m0s
discovery: 5m0s
etcdAPICall: 2m0s
kubeletHealthCheck: 4m0s
kubernetesAPICall: 1m0s
tlsBootstrap: 5m0s
upgradeManifests: 5m0s
---
apiServer: {}
apiVersion: kubeadm.k8s.io/v1beta4
caCertificateValidityPeriod: 87600h0m0s
certificateValidityPeriod: 8760h0m0s
# 证书目录,一般都是这个目录,除非你有自定义
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
encryptionAlgorithm: RSA-2048
#etcd:
# local:
# dataDir: /var/lib/etcd
# 配置外部ETCD信息,这个记得以实际为准一定要调整
etcd:
external:
endpoints:
- https://192.168.17.219:2379 # 适当地更改 ETCD_0_IP
- https://192.168.17.203:2379 # 适当地更改 ETCD_1_IP
- https://192.168.17.79:2379 # 适当地更改 ETCD_2_IP
caFile: /etc/kubernetes/pki/etcd/ca.crt
certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
# 设置k8s的仓库地址,这个如果你把上文所有的镜像都上传到自己的私有HUB,你可以改成自己的HUB服务地址
# 记得把私有HUB设置成公开拉取方便快速部署,不要强制登陆才能pull
imageRepository: registry.k8s.io
kind: ClusterConfiguration
# 设置k8s版本,根据自己实际部署的版本调整
kubernetesVersion: 1.31.0
networking:
dnsDomain: cluster.local
# 集群中service的网段,可不修改,采用默认
serviceSubnet: 10.96.0.0/12
proxy: {}
scheduler: {}
# 这个192.168.17.100是你部署keepalive的虚拟IP,一定要根据实际调整
# 注意配置之前确保keepalive+haproxy已正常启动
controlPlaneEndpoint: "192.168.17.100:6443"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# 设置kubelet驱动,这个需要和containerd部署的配置文件保持一致
# containerd的配置文件/etc/containerd/config.toml中SystemdCgroup属性匹配,如果为true那么这里就得写cgroupDriver: systemd,否则写其他。更多了解请查看下面的地址
# https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/#:~:text=net.ipv4.ip_forward-,cgroup%20%E9%A9%B1%E5%8A%A8,-%E5%9C%A8%20Linux%20%E4%B8%8A
cgroupDriver: systemd
编辑好以上内容保存到kubeadm-config.yaml文件中,然后在你的第1个master节点上创建一个目录存放kubeadm-config.yaml文件。
例如:
root@ubuntu1:~/kubernetes/deploy# pwd
/root/kubernetes/deploy
root@ubuntu1:~/kubernetes/deploy# ll
drwxr-xr-x 2 root root 4096 Oct 8 14:44 calico/
-rw-r--r-- 1 root root 1717 Dec 9 17:11 kubeadm-config.yaml
执行kubeadm init
kubeadm init --config kubeadm-config.yaml --upload-certs
- kubeadm-config.yaml上面创建的文件
- -upload-certs表示在join的时候自动同步证书不需要手动。如果你喜欢折腾可以参考官网手动分发证书。地址如下:
# 手动分发证书说明
https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/high-availability/#:~:text=hash%20sha256%3A7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866-,%E6%89%8B%E5%8A%A8%E8%AF%81%E4%B9%A6%E5%88%86%E5%8F%91,-%E5%A6%82%E6%9E%9C%E4%BD%A0%E9%80%89%E6%8B%A9
- 证书同步目录(每个master和worker)
# 一般都会同步到各个节点/etc/kubernetes/目录下
root@ubuntu0:~/kubernetes/deploy# tree /etc/kubernetes/
/etc/kubernetes/
├── admin.conf
├── controller-manager.conf
├── kubelet.conf
├── manifests
│ ├── kube-apiserver.yaml
│ ├── kube-controller-manager.yaml
│ └── kube-scheduler.yaml
├── pki
│ ├── apiserver.crt
│ ├── apiserver-etcd-client.crt
│ ├── apiserver-etcd-client.key
│ ├── apiserver.key
│ ├── apiserver-kubelet-client.crt
│ ├── apiserver-kubelet-client.key
│ ├── ca.crt
│ ├── ca.key
│ ├── etcd
│ │ └── ca.crt
│ ├── front-proxy-ca.crt
│ ├── front-proxy-ca.key
│ ├── front-proxy-client.crt
│ ├── front-proxy-client.key
│ ├── sa.key
│ └── sa.pub
└── scheduler.conf
kubeadm init成功后操作
如果init成功,会出现如下内容:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
# 设置kubectl的配置文件用户级别目录
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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 the control-plane node running the following command on each as root:
# 用于其他控制面板节点加入集群的命令
kubeadm join 192.168.17.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c80dbc23372171f22ffd2308433234e310ae28b868e6a606dd2a48a46f497596 \
--control-plane --certificate-key 58659e557942e749d1dd30788a3ca18d6f0420f018bf7566471749a49498105f
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
# 用于其他worker节点加入集群的命令
kubeadm join 192.168.17.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c80dbc23372171f22ffd2308433234e310ae28b868e6a606dd2a48a46f497596
这些内容最好复制下来在记事本中保存下来,供后续使用。
会生成相关证书
root@ubuntu1:~# tree /etc/kubernetes/
/etc/kubernetes/
├── admin.conf
├── controller-manager.conf
├── kubelet.conf
├── manifests
│ ├── kube-apiserver.yaml
│ ├── kube-controller-manager.yaml
│ └── kube-scheduler.yaml
├── pki
│ ├── apiserver.crt
│ ├── apiserver-etcd-client.crt
│ ├── apiserver-etcd-client.key
│ ├── apiserver.key
│ ├── apiserver-kubelet-client.crt
│ ├── apiserver-kubelet-client.key
│ ├── ca.crt
│ ├── ca.key
│ ├── etcd
│ │ └── ca.crt
│ ├── front-proxy-ca.crt
│ ├── front-proxy-ca.key
│ ├── front-proxy-client.crt
│ ├── front-proxy-client.key
│ ├── sa.key
│ └── sa.pub
├── scheduler.conf
└── super-admin.conf
执行kubectl配置文件目录设置
# 在你的第1个master上执行如下操作:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
join其他master节点
重要!重要!重要!确保这个matser节点上的以下内容一定是前置准备好的。
- 当前节点必备的镜像一定要都提前pull到本机了,请做好检查
- 当前节点containerd启动成功,请做好检查
- swap是关闭的
- ipv4转发是开启的
- 内存至少2G
- CPU至少2核
执行join
# 在其他的master上执行,记得以实际命令执行,不要盲目复制。
kubeadm join 192.168.17.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c80dbc23372171f22ffd2308433234e310ae28b868e6a606dd2a48a46f497596 \
--control-plane --certificate-key 58659e557942e749d1dd30788a3ca18d6f0420f018bf7566471749a49498105f
会出现相关证书
root@ubuntu0:~# tree /etc/kubernetes/
/etc/kubernetes/
├── admin.conf
├── controller-manager.conf
├── kubelet.conf
├── manifests
│ ├── kube-apiserver.yaml
│ ├── kube-controller-manager.yaml
│ └── kube-scheduler.yaml
├── pki
│ ├── apiserver.crt
│ ├── apiserver-etcd-client.crt
│ ├── apiserver-etcd-client.key
│ ├── apiserver.key
│ ├── apiserver-kubelet-client.crt
│ ├── apiserver-kubelet-client.key
│ ├── ca.crt
│ ├── ca.key
│ ├── etcd
│ │ └── ca.crt
│ ├── front-proxy-ca.crt
│ ├── front-proxy-ca.key
│ ├── front-proxy-client.crt
│ ├── front-proxy-client.key
│ ├── sa.key
│ └── sa.pub
└── scheduler.conf
join其他worker节点
重要!重要!重要!确保这个matser节点上的以下内容一定是前置准备好的。
- 当前节点必备的镜像一定要都提前pull到本机了,请做好检查
- 当前节点containerd启动成功,请做好检查
- swap是关闭的
- ipv4转发是开启的
- 内存至少2G
- CPU至少2核
执行join
# 在其他的worker上执行,记得以实际命令执行,不要盲目复制。
kubeadm join 192.168.17.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c80dbc23372171f22ffd2308433234e310ae28b868e6a606dd2a48a46f497596
部署网络插件
更多网络插件参考以下地址:
https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/addons/#networking-and-network-policy:~:text=%E8%AF%A6%E5%B0%BD%E6%97%A0%E9%81%97%E3%80%82-,%E8%81%94%E7%BD%91%E5%92%8C%E7%BD%91%E7%BB%9C%E7%AD%96%E7%95%A5,-ACI%20%E9%80%9A%E8%BF%87%20Cisco
本文采用Calico作为网络部署说明。
部署calico
- 官方教程
https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart
- 前置条件
Before you begin
Required
- A Linux host that meets the following requirements:
- x86-64, arm64, ppc64le, or s390x processor
- 2CPU
- 2GB RAM
- 10GB free disk space
- RedHat Enterprise Linux 7.x+, CentOS 7.x+, Ubuntu 18.04+, or Debian 9.x+
- Calico can manage
cali
andtunl
interfaces on the host - If NetworkManager is present on the host, see Configure NetworkManager.
- Install Callico
- 获取calico.yaml部署文件
# 在你的第1个master上执行,其实其他的master也行,位了方便管理部署最好都在一个master上去操作
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
如果上面的calico.yaml文件下载慢,可以先在自己电脑上下载好然后上传到第1个master节点上去。
- 启动calico
kubectl apply -f calico.yaml
- 查看状态
root@ubuntu1:~/kubernetes/deploy/calico# kubectl get pods -A | grep calico
kube-system calico-kube-controllers-7f764f4f68-zdppk 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-fbljp 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-jcm24 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-n6ljm 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-w9jzw 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-wwxdt 1/1 Running 2 (3d2h ago) 7d
kube-system coredns-7c65d6cfc9-lwmwq 1/1 Running 3 (3d2h ago) 7d2h
kube-system coredns-7c65d6cfc9-tjwxq 1/1 Running 3 (3d2h ago) 7d2h
集群状态预览
- 集群列表
# 在其中任意一个master上执行
root@ubuntu1:~# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ubuntu0 Ready control-plane 7d1h v1.31.1 192.168.17.247 <none> Ubuntu 24.04.1 LTS 6.8.0-49-generic containerd://1.7.22
ubuntu1 Ready control-plane 7d2h v1.31.1 192.168.17.68 <none> Ubuntu 20.04.5 LTS 5.4.0-200-generic containerd://1.7.22
ubuntu2 Ready <none> 7d v1.31.1 192.168.17.40 <none> Ubuntu 20.04.6 LTS 5.4.0-202-generic containerd://1.7.22
ubuntu3 Ready <none> 7d v1.31.1 192.168.17.54 <none> Ubuntu 20.04.6 LTS 5.4.0-200-generic containerd://1.7.22
ubuntu4 Ready <none> 7d v1.31.3 192.168.17.83 <none> Ubuntu 24.04.1 LTS 6.8.0-50-generic containerd://1.7.22
- 基础POD列表
root@ubuntu1:~/kubernetes/deploy/calico# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-7f764f4f68-zdppk 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-fbljp 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-jcm24 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-n6ljm 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-w9jzw 1/1 Running 2 (3d2h ago) 7d
kube-system calico-node-wwxdt 1/1 Running 2 (3d2h ago) 7d
kube-system coredns-7c65d6cfc9-lwmwq 1/1 Running 3 (3d2h ago) 7d2h
kube-system coredns-7c65d6cfc9-tjwxq 1/1 Running 3 (3d2h ago) 7d2h
kube-system kube-apiserver-ubuntu0 1/1 Running 4 (3d2h ago) 7d2h
kube-system kube-apiserver-ubuntu1 1/1 Running 4 (3d2h ago) 7d2h
kube-system kube-controller-manager-ubuntu0 1/1 Running 4 (3d2h ago) 7d2h
kube-system kube-controller-manager-ubuntu1 1/1 Running 12 (3d2h ago) 7d2h
kube-system kube-proxy-5cmpq 1/1 Running 3 (3d2h ago) 7d2h
kube-system kube-proxy-9dl6q 1/1 Running 2 (3d2h ago) 7d
kube-system kube-proxy-lklxl 1/1 Running 2 (3d2h ago) 7d
kube-system kube-proxy-v8xbj 1/1 Running 3 (3d2h ago) 7d2h
kube-system kube-proxy-zwqvf 1/1 Running 2 (3d2h ago) 7d
kube-system kube-scheduler-ubuntu0 1/1 Running 4 (3d2h ago) 7d2h
kube-system kube-scheduler-ubuntu1 1/1 Running 12 (3d2h ago) 7d2h
出现以上的内容表示整个集群已部署成功,接下来你就可以去用它部署你想部署的所有容器。
集群用例冒烟
至此我们的k8s集群2master+3worker+3etcd集群部署成功,为了验证集群的可用性。我们准备部署一个nginx看看什么效果。
部署nginx
在 Kubernetes 集群中部署 Nginx 主要通过创建 Deployment 和 Service 完成,以下是完整的步骤:
- 创建 Nginx Deployment
使用 YAML 文件定义 Deployment
创建一个 nginx-deployment.yaml
文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # 副本数量,部署3个 Nginx 实例
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/shouzhi/nginx:latest # 使用 Nginx 官方镜像
ports:
- containerPort: 80 # 暴露容器的 80 端口
- 应用 Nginx Deployment
使用 kubectl
命令创建 Nginx Deployment:
kubectl apply -f nginx-deployment.yaml
验证 Deployment 是否成功创建
kubectl get deployments
kubectl get pods
输出示例:
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 2m
- 暴露 Nginx 服务
为了让外部访问 Nginx,可以通过 Kubernetes Service 将 Deployment 暴露出来。
创建 Nginx Service
编辑 nginx-service.yaml
文件:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort # 使用 NodePort 类型,让外部访问
selector:
app: nginx # 选择匹配标签为 app: nginx 的 Pod
ports:
- protocol: TCP
port: 80 # Service 端口
targetPort: 80 # Pod 中 Nginx 容器暴露的端口
nodePort: 30080 # 外部访问的端口(30000-32767之间)
应用 Nginx Service
kubectl apply -f nginx-service.yaml
验证 Nginx 服务状态
kubectl get services
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.96.12.34 <none> 80:30080/TCP 2m
- 访问 Nginx 服务
- 获取节点 IP 地址 运行以下命令查看节点的 IP 地址:
kubectl get nodes -o wide
- 示例输出:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP
worker-node1 Ready <none> 10m v1.31.0 192.168.1.10 <none>
- 访问 Nginx 服务 使用浏览器或
curl
访问节点 IP 和 NodePort:
http://<NodeIP>:30080
- 示例:
http://192.168.1.10:30080
- 验证 Nginx 页面
访问成功后,你将看到 Nginx 默认欢迎页面。
- 清理资源
如果你不再需要 Nginx,可以删除 Deployment 和 Service:
kubectl delete -f nginx-deployment.yaml
kubectl delete -f nginx-service.yaml
部署ArgoCD
ArgoCD 提供了一个强大的 GitOps 工具,可以高效地管理 Kubernetes 应用状态。你可以通过 Web 界面或 CLI 工具完成持续部署和监控。
以下是部署 ArgoCD 到 Kubernetes 集群的完整步骤:
- 环境准备
- Kubernetes 集群:
- Kubernetes 版本 >= 1.21。
- 确保可以通过
kubectl
连接到集群。
- 命令行工具:
- 已安装
kubectl
。 - 可选:安装
argocd
CLI(后续步骤会说明)。
- 已安装
- 命名空间准备:
- ArgoCD 会运行在单独的
argocd
命名空间。
- ArgoCD 会运行在单独的
- 安装 ArgoCD
方法 1: 使用官方安装 YAML
- 创建
argocd
命名空间:
kubectl create namespace argocd
- 应用 ArgoCD 安装 YAML 文件:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
- 验证安装是否成功: 查看
argocd
命名空间中的 Pod 状态:
kubectl get pods -n argocd
- 正常情况下,所有 Pod 的状态应该为
Running
。
方法 2: 使用 Helm Chart 安装
- 添加 ArgoCD Helm 仓库:
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
- 安装 ArgoCD:
helm install argocd argo/argo-cd -n argocd --create-namespace
- 验证安装:
kubectl get pods -n argocd
- 暴露 ArgoCD Server
ArgoCD Server 提供一个 Web 界面,用于管理应用。你可以选择多种方式暴露服务。
选项 1: 使用 NodePort
- 修改
argocd-server
服务类型为 NodePort:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
- 获取服务的 NodePort:
kubectl get svc argocd-server -n argocd
- 示例输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-server NodePort 10.96.236.55 <none> 80:31390/TCP,443:31443/TCP 10m
- 通过以下方式访问 Web 界面:
https://<NodeIP>:<NodePort>
选项 2: 使用 Ingress
如果集群已经安装了 Ingress Controller,可以通过 Ingress 暴露 ArgoCD。
- 创建 Ingress 配置: 创建一个名为
argocd-ingress.yaml
的文件:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 443
- 应用 Ingress 配置:
kubectl apply -f argocd-ingress.yaml
确保 argocd.example.com
能解析到 Ingress 控制器的 IP 地址。
- 登录 ArgoCD
获取初始管理员密码
默认管理员用户名是 admin
。初始密码存储在 Kubernetes Secret 中。
kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 -d
示例输出:
my-secret-password
登录 Web 界面
- 打开 Web 界面(根据暴露方式访问):
- NodePort 示例:
https://<NodeIP>:<NodePort>
- Ingress 示例:
https://argocd.example.com
- NodePort 示例:
- 输入用户名
admin
和上一步获取的密码。
登录 ArgoCD CLI
安装 ArgoCD CLI 并通过命令行登录:
- 安装 CLI:
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x /usr/local/bin/argocd
- 登录 CLI:
argocd login <ArgoCD-Server-IP>:<Port> --username admin --password <password>
- 部署一个示例应用
- 创建一个示例应用: 使用
argocd
CLI 创建一个示例应用:
argocd app create guestbook \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
- 同步应用: 将应用从 Git 仓库同步到 Kubernetes:
argocd app sync guestbook
- 检查应用状态:
argocd app get guestbook
- 验证部署: 使用
kubectl
查看guestbook
应用的资源:
kubectl get all -n default
- 升级和管理应用
- 更新应用:当 Git 仓库中的配置发生变化时,ArgoCD 可以自动或手动同步。
- 查看同步状态:
argocd app list
- 手动触发同步:
argocd app sync <app-name>