初始化主节点
概述
本章节主要介绍了 Kubernetes 集群主节点的初始化工作。Kubernetes 集群主节点在初始化时,有以下两种模式可以选:
- 普通模式:主节点只有一个,API Server 的入口地址就是这个节点的地址。
- 高可用模式:主节点有多个,并提供一个主节点的负载入口地址,API Server 的入口地址就是这个负载地址,再由这个负载地址将请求转发到这些主节点上。
个人建议统一按照高可用模式的方式去搭建 Kubernetes 集群。如果主节点没有多个,那么负载地址只需要将流量直接转发给该节点即可。如果后续有更多的主机资源加入进来之后,可以随时加这些主机加入主节点集群,让主节点集群变成高可用状态。
搭建高可用入口
搭建高可用集群需要 3 台或以上的主节点,并且提供 3 台主节点的统一访问入口。这个访问入口有多种实现思路,包括:
- 使用 NetScaler、F5 之类的硬件负载器,将流量转发到这些主节点。由于硬件负载器的工作稳定性非常高,因此一般认为已经达到高可用状态;
- 使用 Nginx、HAProxy 之类的软件负载器,将流量转发到这些主节点。Nginx、HAProxy 这些反向代理软件的工作稳定性也非常高,但是服务器层面可能无法保证是可高用,因此可能存在单点故障;
- 使用 Keepalived 生成虚拟 IP,当其中一台主节点挂了之后,虚拟 IP 自动切换到另一台主节点上。由于虚拟 IP 会自动在节点间切换,因此一般也认为已经达到高可用状态。如果使用 Keepalived 作为高可用方案,一般还要配合 Nginx 或 HAProxy 这些反向代理软件,将流量负载到所有主节点上,降低单点压力。
对于以上三种方案,有条件的可以使用硬件负载;如果可以申请到虚拟 IP(有些环境不允许使用虚拟 IP),可以使用 Keepalived;如果以上两个方案都没办法,可以选择使用软件负载器。
如果对高可用集群的拓扑结构还没有清晰认识的,可以回到概述文档[链接]里回顾一下。
如果没有 3 台或以上的主节点,可以搭建只有 1 台主节点的高可用入口,搭建过程完全一致。高可用入口建议使用域名/主机名来表示,不要直接使用 IP,这样将来高可用入口如果要发生变更的话,只需要修改一下 DNS 服务即可。
Keepalived + Nginx
Keepalived 方案虽然可以达到高可用,但是该方案会将所有流量都流向一个节点,其余的节点将处于「无事可做」的状态。为了让节点间的压力平衡一点,一般还要在这些节点上搭建反向代理软件,将流量平均到各个节点上,降低单点压力。在本文档里,反向代理软件我们使用 Nginx。
安装 Nginx
我们需要在三台主节点(master[x].cluster.k8s)上都安装 Nginx 服务,并且三台服务器的 Nginx 配置也是相同的。
# 安装 nginx 服务
$ yum install -y nginx
# 修改 nginx 配置文件
$ vi /etc/nginx/nginx.conf
Nginx 服务的配置文件的内容如下:
- /etc/nginx/nginx.conf
# 注意,这个 stream 节点在 http 节点下面,与 http 节点平级,不要写入 http 节点内
stream {
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log /var/log/nginx/stream-access.log basic buffer=32k;
error_log /var/log/nginx/stream-error.log notice;
# 包含 conf.d 目录下所有以 .stream 结尾的配置
include /etc/nginx/conf.d/*.stream;
}
- /etc/nginx/conf.d/kubernetes.stream
upstream lb_kubernetes {
server 10.10.20.11:6443 weight=1; # master1.cluster.k8s
# 下面两个节点的环境还没搭好,可以先设为备用服务器,不参与负载
# 如果希望下面两节点也参与负载,可以在所有主节点都完成初始化之后,把 backup 选项删除即可
server 10.10.20.12:6443 weight=1 backup; # master2.cluster.k8s
server 10.10.20.13:6443 weight=1 backup; # master3.cluster.k8s
}
server {
# 监听 16433 端口,后续通过此端口访问 kubernetes 集群
listen 16433;
ssl_preread on;
proxy_pass lb_kubernetes;
proxy_connect_timeout 300s;
proxy_timeout 300s;
}
# 启用 nginx 服务
$ systemctl start nginx && systemctl enable nginx
# 测试 nginx 服务是否正常可用
$ telnet 10.10.20.11 16433
Trying 10.10.20.11...
Connected to 10.10.20.11.
Escape character is '^]'.
Connection closed by foreign host.
安装 Keepalived
部署 Keepalived 后,会生成一个虚拟 IP,我们就可以通过这个虚似 IP 访问主节点,从而保证主节点的高可用。在本方案里,如果 nginx 挂了,或者整个服务器挂了,Keepalived 会自动切换到其它的节点。更多关于 Keepalived 的信息,可以参考我另一篇文档[链接]。
在三台主节点(master[x].cluster.k8s),执行以下命令,安装 Keepalived 服务。
# 安装 keepalived 服务
$ yum install -y keepalived
# 创建 nginx 进程检测脚本
$ vi /etc/keepalived/check_alived.sh
#!/bin/bash
# 检测 nginx 是否启正常
if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then
# nginx 不正常,则代表当前节点无法正常工作
echo "nginx is not alived";
# 尝试重启 nginx 服务
systemctl restart nginx;
exit 1;
else
echo "nginx is alived";
exit 0;
fi
# 给进程检测脚本添加可执行权限
$ chmod +x /etc/keepalived/check_alived.sh
在三台主节点中,选取其中一台作为 Keepalived 的主节点,其余为备用节点。在这里我们选用 master1.cluster.k8s 作为 Keepalived 的主节点,master2.cluster.k8s 和 master3.cluster.k8s 为备用节点。
修改 master1.cluster.k8s 节点的 Keepalived 配置文件。
- /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script check_alived {
script "/etc/keepalived/check_alived.sh"
interval 2
fail 1
rise 1
}
vrrp_instance VI_1 {
state MASTER # 主节点
interface ens192 # 虚拟 IP 绑定的网络接口
mcast_src_ip 10.10.20.11 # 主节点 IP 地址
virtual_router_id 51
priority 110 # 主节点的优先级最高
advert_int 2
authentication {
auth_type PASS
auth_pass KP_PASS
}
virtual_ipaddress { # 虚拟 IP 地址
10.10.20.10
}
track_script {
check_alived
}
}
修改 master2.cluster.k8s 节点和 master3.cluster.k8s 节点的 keepalived 配置文件。注意有注释的地方。
- /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script check_alived {
script "/etc/keepalived/check_alived.sh"
interval 2
fail 1
rise 1
}
vrrp_instance VI_1 {
state BACKUP # 备用节点
interface ens192 # 虚拟 IP 绑定的网络接口
mcast_src_ip 10.10.20.12 # 备用节点 IP 地址
virtual_router_id 51
priority 100 # 备用节点的优先级。比需比主节点要低。
advert_int 2
authentication {
auth_type PASS
auth_pass KP_PASS
}
virtual_ipaddress { # 虚拟 IP 地址
10.10.20.10
}
track_script {
check_alived
}
}
最后启用 Keepalived 服务即可。
# 启用 Keepalived 服务
$ systemctl start keepalived && systemctl enable keepalived
# 测试 Keepalived 服务是否正常
# PING 虚拟 IP,看看虚拟 IP 会不会响应
$ ping 10.10.20.10 -c 4
PING 10.10.20.10 (10.10.20.10) 56(84) bytes of data.
64 bytes from 10.10.20.10: icmp_seq=1 ttl=64 time=0.120 ms
64 bytes from 10.10.20.10: icmp_seq=2 ttl=64 time=0.083 ms
64 bytes from 10.10.20.10: icmp_seq=3 ttl=64 time=0.077 ms
64 bytes from 10.10.20.10: icmp_seq=4 ttl=64 time=0.127 ms
--- 10.10.20.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3070ms
rtt min/avg/max/mdev = 0.077/0.101/0.127/0.025 ms
# 测试虚拟 IP 的 Nginx 服务是否正常
# 如果测试不通过的话,需要检查一下防火墙、Nginx、Keepalived、SELinux 等的状态和配置是否有问题
$ telnet 10.10.20.10 16433
Trying 10.10.20.10...
Connected to 10.10.20.10.
Escape character is '^]'.
Connection closed by foreign host.
修改 DNS 服务
修改 svc.cluster.k8s 服务器上的 DNS 服务的 hosts 文件,将 master.cluster.k8s 映射为 10.10.20.10,这样就可以直接通过域名来访问 Kubernetes 的主节点集群。
# 修改 DNS 服务的 hosts 文件,添加一条 master.cluster.k8s 记录
$ nano docker-compose/svc-dns/hosts
# 添加以下记录后,保存退出即可(10.10.20.10 是 Keepalived 虚拟出来的 IP)
10.10.20.10 master.cluster.k8s
# 测试域名解析是否正常
$ telnet master.cluster.k8s 16443
Trying 10.10.20.10...
Connected to master.cluster.k8s.
Escape character is '^]'.
Connection closed by foreign host.
硬件负载器
不同的硬件负载器有不同的配置方式,总体思路是将流量转发到 master[x].cluster.k8s 节点上即可。
软件负载器
软件负载器相对基它方案来说,是最简单以及我们最熟悉的方案。本方案只需要找一台服务器部署 Nginx、HAProxy 这些反向代理软件,将流量负载到主节点上,即可完成软件负载器的搭建工作。
由于所有流量都要通过该软件负载器所在的服务器,因此我们要尽可能保证该服务器的稳定性。如果该服务器宕机,可能会让集群无法正常工作,因此我们最好不要在这台服务器上部署一些高负载的应用,确保该服务器正常运行。
本方案里,我们选用 Nginx 作为软件负载器。
安装 Nginx
找一台空闲的服务器(如果资源匮乏,复用 svc.cluster.k8s 节点也可以),安装 Nginx 并修改相关配置:
# 安装 nginx 服务
$ yum install -y nginx
# 修改 nginx 配置文件
$ vi /etc/nginx/nginx.conf
Nginx 服务的配置文件的内容如下:
- /etc/nginx/nginx.conf
# 注意,这个 stream 节点在 http 节点下面,与 http 节点平级,不要写入 http 节点内
stream {
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log /var/log/nginx/stream-access.log basic buffer=32k;
error_log /var/log/nginx/stream-error.log notice;
# 包含 conf.d 下所有以 .stream 结尾的配置
include /etc/nginx/conf.d/*.stream;
}
- /etc/nginx/conf.d/kubernetes.stream
upstream lb_kubernetes {
server 10.10.20.11:6443 weight=1; # master1.cluster.k8s
# 下面两个节点的环境还没搭好,可以先设为备用服务器,不参与负载
# 如果希望下面两节点也参与负载,可以在所有主节点都完成初始化之后,把 backup 选项删除即可
server 10.10.20.12:6443 weight=1 backup; # master2.cluster.k8s
server 10.10.20.13:6443 weight=1 backup; # master3.cluster.k8s
}
server {
# 监听 16433 端口,后续通过此端口访问 kubernetes 集群
listen 16433;
ssl_preread on;
proxy_pass lb_kubernetes;
proxy_connect_timeout 300s;
proxy_timeout 300s;
}
# 启用 nginx 服务
$ systemctl start nginx && systemctl enable nginx
# 测试 nginx 服务是否正常可用
$ telnet 10.10.20.11 16433
Trying 10.10.20.11...
Connected to 10.10.20.11.
Escape character is '^]'.
Connection closed by foreign host.
修改 DNS 服务
修改 svc.cluster.k8s 服务器上的 DNS 服务的 hosts 文件,将 master.cluster.k8s 映射为 Nginx 所在服务器,这样就可以直接通过域名来访问 Kubernetes 的主节点集群。
# 修改 DNS 服务的 hosts 文件
$ nano docker-compose/svc-dns/hosts
# 添加或修改 master.cluster.k8s 主机的解析信息后,保存退出即可(这里是复用了 svc.cluster.k8s 节点)
10.10.20.0 master.cluster.k8s
# 测试域名解析是否正常
$ telnet master.cluster.k8s 16443
Trying 10.10.20.0...
Connected to master.cluster.k8s.
Escape character is '^]'.
Connection closed by foreign host.
初始化
修改配置文件
在完成上面的步骤和测试之后,在主节点(master1.cluster.k8s)服务器上执行以下命令,导出默认的 Kubernetes 配置:
# 导出 kubeadm 的默认配置
$ kubeadm config print init-defaults > kubeadm-config.yaml
修改配置文件 kubeadm-config.yaml(主要修改有注释的地方)。
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.10.20.11 # 此处修改为当前主节点的 IP
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: master1.cluster.k8s # 修改为当前主节点的 hostname
taints: null
---
apiServer:
certSANs:
- master.cluster.k8s # 控制节点集群入口域名
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: master.cluster.k8s:16443 # 控制节点集群入口域名和反向代理端口
controllerManager: { }
dns: { }
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.k8s.io
kind: ClusterConfiguration
kubernetesVersion: 1.27.4 # 修改为当前要部署的 Kubernetes 版本
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 # 使用 flannel 模型通信,这个 IP 的值需要固定为这个值
serviceSubnet: 10.96.0.0/16 # 创建 Service 时的网段
scheduler: { }
---
# 指定使用 ipvs 网络通信
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
初始化主节点
开始初始化主节点:
# 初始化 master1 主节点,开始部署
$ kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log
# 如果发现最后输出以下信息,说明 master1 主节点初始化成功
# 注意保存好两个 token 和 certificate-key
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
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 master.cluster.k8s:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c74b6dcc0f3119703fcf08c444f13a01c77d8e649a398cb559bfb5cda257c583 \
--control-plane --certificate-key f6c03d58abd042750b8bcefd0a334c4fd449e7c83f5cec534fbfb39254d69080
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:
kubeadm join master.cluster.k8s:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c74b6dcc0f3119703fcf08c444f13a01c77d8e649a398cb559bfb5cda257c583
# 添加环境变量
$ nano ~/.bash_profile
# 在 ~/.bash_profile 文件最后面添加以下内容
# Kubernetes 默认使用 vi 作为编辑器,我不太会用 vi,习惯用 nano,根据情况可以选择不加 KUBE_EDITOR 环境变量
export KUBECONFIG=/etc/kubernetes/admin.conf
export KUBE_EDITOR=nano
# 使环境变量生效
$ source ~/.bash_profile
# 修改 kube-proxy 的配置,否则 kube-proxy 会一直处于 CrashLoopBackOff 状态
# 找到 featureGates: 和 SupportIPVSProxyMode: true 这两行,将其注释后保存退出即可
$ kubectl edit cm kube-proxy -n kube-system
# 获取节点信息
# 由于还没安装 flannel 网络插件导致 coredns 无法初始化,因此 master 节点还处于 NotReady 状态
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1.cluster.k8s NotReady control-plane 77s v1.27.4
# 获取系统命名空间的 pod 运行情况
$ kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5d78c9869d-56smn 0/1 Pending 0 95s
coredns-5d78c9869d-fmrv5 0/1 Pending 0 95s
etcd-master1.cluster.k8s 1/1 Running 0 101s
kube-apiserver-master1.cluster.k8s 1/1 Running 0 101s
kube-controller-manager-master1.cluster.k8s 1/1 Running 0 101s
kube-proxy-hcm5r 1/1 Running 4 (56s ago) 95s
kube-scheduler-master1.cluster.k8s 1/1 Running 0 101s
# 查看证书有效期,全部证书有效期为 10 年
$ kubeadm certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Jul 23, 2033 20:13 UTC 9y ca no
apiserver Jul 23, 2033 20:13 UTC 9y ca no
apiserver-etcd-client Jul 23, 2033 20:13 UTC 9y etcd-ca no
apiserver-kubelet-client Jul 23, 2033 20:13 UTC 9y ca no
controller-manager.conf Jul 23, 2033 20:13 UTC 9y ca no
etcd-healthcheck-client Jul 23, 2033 20:13 UTC 9y etcd-ca no
etcd-peer Jul 23, 2033 20:13 UTC 9y etcd-ca no
etcd-server Jul 23, 2033 20:13 UTC 9y etcd-ca no
front-proxy-client Jul 23, 2033 20:13 UTC 9y front-proxy-ca no
scheduler.conf Jul 23, 2033 20:13 UTC 9y ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Jul 23, 2033 20:13 UTC 9y no
etcd-ca Jul 23, 2033 20:13 UTC 9y no
front-proxy-ca Jul 23, 2033 20:13 UTC 9y no
安装 Helm
Helm 是 Kubernetes 的包管理器,通过 Helm 可以很方便地给集群安装或卸载资源包,后续部署包时,一般建议通过 helm 来管理。一般情况下,我们需要将 Helm 部署到主节点上。
# 将 helm 可执行文件下载到指定目录,并添加可执行权限
$ curl -o /usr/local/bin/helm http://mirror.cluster.k8s/repository/raw/helm-linux-amd64-v3.12.2
$ chmod +x /usr/local/bin/helm
# 查看是否正常
$ helm version
version.BuildInfo{Version:"v3.12.2", GitCommit:"1e210a2c8cc5117d1055bfaa5d40f51bbc2e345e", GitTreeState:"clean", GoVersion:"go1.20.5"}
# 查看是否能连接到集群
$ helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
# 添加 helm 仓库
$ helm repo add mirror http://mirror.cluster.k8s/repository/helm/
"mirror" has been added to your repositories
安装 flannel
flannel 是 Kubernetes 的网络插件。这里使用 helm 安装 flannel。
# 安装 kube-flannel 插件
$ helm install kube-flannel mirror/kube-flannel -n kube-system
NAME: kube-flannel
LAST DEPLOYED: Thu Jul 27 04:20:53 2023
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
# 获取 helm 列表
$ helm list -n kube-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kube-flannel kube-system 1 2023-07-27 04:20:53.353204291 +0800 CST deployed kube-flannel-v0.22.0 v0.22.0
# 安装 kube-flannel 插件后,再获取节点信息
# 可以发现节点已初始化
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1.cluster.k8s Ready control-plane 7m47s v1.27.4
# 获取系统命名空间的 pod 运行情况,全部正常运行
$ kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5d78c9869d-56smn 1/1 Running 0 7m51s
coredns-5d78c9869d-fmrv5 1/1 Running 0 7m51s
etcd-master1.cluster.k8s 1/1 Running 0 7m57s
kube-apiserver-master1.cluster.k8s 1/1 Running 0 7m57s
kube-controller-manager-master1.cluster.k8s 1/1 Running 0 7m57s
kube-flannel-ds-v4qwj 1/1 Running 0 48s
kube-proxy-hcm5r 1/1 Running 4 (7m12s ago) 7m51s
kube-scheduler-master1.cluster.k8s 1/1 Running 0 7m57s
初始化备用主节点
在其它备用主节点上,通过以下命令初始化并加入 Kubernetes 集群。
# 这个命令是在主节点(master1.cluster.k8s)初始化时打印在命令行里的
# 直接复制该命令到其它主节点(master2、master3)上执行即可
$ kubeadm join master.cluster.k8s:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:c74b6dcc0f3119703fcf08c444f13a01c77d8e649a398cb559bfb5cda257c583 \
--control-plane --certificate-key f6c03d58abd042750b8bcefd0a334c4fd449e7c83f5cec534fbfb39254d69080
# 如果输出以下内容,则表示已经初始化成功
This node has joined the cluster and a new control plane instance was created:
* Certificate signing request was sent to apiserver and approval was received.
* The Kubelet was informed of the new secure connection details.
* Control plane label and taint were applied to the new node.
* The Kubernetes control plane instances scaled up.
* A new etcd member was added to the local/stacked etcd cluster.
To start administering your cluster from this node, 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
Run 'kubectl get nodes' to see this node join the cluster.
# 如果你想在这个节点上也可以管理集群,那么通过以下命令完成配置即可(可以跳过)
# 添加环境变量
$ nano ~/.bash_profile
# 在 ~/.bash_profile 文件最后面添加以下内容
export KUBECONFIG=/etc/kubernetes/admin.conf
export KUBE_EDITOR=nano
# 使环境变量生效
$ source ~/.bash_profile
注意
初始化主节点时,需要逐个初始化,必须等待上一个主节点初始化成功之后,才能去初始化下一个主节点。
回到主节点(master1.cluster.k8s)上执行以下命令,查看各节点的状态。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master1.cluster.k8s Ready control-plane 10m v1.27.4
master2.cluster.k8s Ready control-plane 56s v1.27.4
master3.cluster.k8s Ready control-plane 6s v1.27.4
$ kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5d78c9869d-56smn 1/1 Running 0 11m
coredns-5d78c9869d-fmrv5 1/1 Running 0 11m
etcd-master1.cluster.k8s 1/1 Running 0 11m
etcd-master2.cluster.k8s 1/1 Running 0 2m28s
etcd-master3.cluster.k8s 1/1 Running 0 95s
kube-apiserver-master1.cluster.k8s 1/1 Running 0 11m
kube-apiserver-master2.cluster.k8s 1/1 Running 0 2m27s
kube-apiserver-master3.cluster.k8s 1/1 Running 1 (96s ago) 96s
kube-controller-manager-master1.cluster.k8s 1/1 Running 1 (2m17s ago) 11m
kube-controller-manager-master2.cluster.k8s 1/1 Running 0 2m27s
kube-controller-manager-master3.cluster.k8s 1/1 Running 0 18s
kube-flannel-ds-4xblf 1/1 Running 0 98s
kube-flannel-ds-ngrcr 1/1 Running 0 2m28s
kube-flannel-ds-v4qwj 1/1 Running 0 4m32s
kube-proxy-67v7k 1/1 Running 0 2m28s
kube-proxy-hcm5r 1/1 Running 4 (10m ago) 11m
kube-proxy-jjt2t 1/1 Running 0 98s
kube-scheduler-master1.cluster.k8s 1/1 Running 1 (2m13s ago) 11m
kube-scheduler-master2.cluster.k8s 1/1 Running 0 2m12s
kube-scheduler-master3.cluster.k8s 1/1 Running 0 97s
命令过期处理
因为主节点可以访问集群的敏感信息,因此主节点的 certificate-key 会在 2 个小时后过期,而 token 会在 24 小时后过期。如果后续还有新的主节点想加入集群,就需要通过以下命令生成新的 certificate-key 和 token。
# 生成新的 certificate-key
$ kubeadm init phase upload-certs --upload-certs
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
3a6c93a77e10a4f70064a488e11aced050567d3a1a746c73aa472d9178c4faf9
# 生成新的 token 及加入集群的命令
$ kubeadm token create --print-join-command
kubeadm join master.cluster.k8s:16443 --token 03hxhs.b0fmrcmg9m5e4thw --discovery-token-ca-cert-hash sha256:c74b6dcc0f3119703fcf08c444f13a01c77d8e649a398cb559bfb5cda257c583
# 将上面生成的新 certificate-key 拼接到命令后面,新节点就可以使用新的该命令来加入集群了
$ kubeadm join master.cluster.k8s:16443 --token 03hxhs.b0fmrcmg9m5e4thw \
--discovery-token-ca-cert-hash sha256:c74b6dcc0f3119703fcf08c444f13a01c77d8e649a398cb559bfb5cda257c583 \
--control-plane --certificate-key 3a6c93a77e10a4f70064a488e11aced050567d3a1a746c73aa472d9178c4faf9