当前位置: 首页 > news >正文

Kubernetes实战(十四)-k8s高可用集群扩容master节点

1 单master集群和多master节点集群方案

1.1 单Master集群

k8s 集群是由一组运行 k8s 的节点组成的,节点可以是物理机、虚拟机或者云服务器。k8s 集群中的节点分为两种角色:master 和 node。

  • master 节点:master 节点负责控制和管理整个集群,它运行着一些关键的组件,如 kube-apiserver、kube-scheduler、kube-controller-manager 等。master 节点可以有一个或多个,如果有多个 master 节点,那么它们之间需要通过 etcd 这个分布式键值存储来保持数据的一致性。
  • node 节点:node 节点是承载用户应用的工作节点,它运行着一些必要的组件,如 kubelet、kube-proxy、container runtime 等。node 节点可以有一个或多个,如果有多个 node 节点,那么它们之间需要通过网络插件来实现通信和路由。

一般情况下我们会搭建单master多node集群。它是一种常见的 k8s 集群架构,它只有一个 master 节点和多个 node 节点。这种架构的优点是简单易搭建,适合用于学习和测试 k8s 的功能和特性。这种架构的缺点是 master 节点成为了单点故障,如果 master 节点出现问题,那么整个集群就无法正常工作。

搭建 k8s 单 master 多 node 集群有多种方法,根据不同的需求和场景,可以选择合适的方式来搭建和运维node集群。一般来说,有以下几种常见的方式:

  • 使用kubeadm:这是一种使用官方提供的工具kubeadm来快速创建和管理node集群的方式。kubeadm可以自动安装和配置node节点上所需的组件,如kubelet、kube-proxy、容器运行时等。这种方式适用于学习和测试目的,或者简单的生产环境。
  • 使用kops:这是一种使用开源工具kops来在云服务商(如AWS、GCP等)上创建和管理node集群的方式。kops可以自动创建和配置云资源,如虚拟机、网络、存储等,并安装和配置node节点上所需的组件。这种方式适用于在云端部署高可用和可扩展的node集群。
  • 使用其他工具或平台:这是一种使用其他第三方提供的工具或平台来创建和管理node集群的方式。例如,你可以使用Ansible、Terraform、Rancher等工具来自动化和定制node集群的创建和配置过程。或者,你可以使用云服务商提供的托管服务(如EKS、GKE、AKS等)来直接创建和管理node集群。这种方式适用于不同的需求和偏好,但可能需要更多的学习和调试成本。

1.2 Master 高可用架构

kubernetes多master集群是指使用多个master节点来提高集群的可用性和容错性的方案。master节点是负责控制和管理集群中的资源和服务的节点,它运行着以下组件:

  • kube-apiserver:提供了HTTP REST接口的关键服务进程,是集群中所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程。
  • kube-scheduler:负责资源调度(Pod调度)的进程,相当于公交公司的“调度室”。
  • kube-controller-manager:集群中所有资源对象的自动化控制中心,可以将其理解为资源对象的“大总管”。

Kubernetes 作为容器集群系统,通过健康检查 + 重启策略实现了 Pod 故障自我修复能力,通过调度算法实现将 Pod 分布式部署,并保持预期副本数,根据 Node 失效状态自动在其他 Node 拉起 Pod,实现了应用层的高可用性。

针对 Kubernetes 集群,高可用性还应包含以下两个层面的考虑:Etcd 数据库的高可用性和 Kubernetes Master 组件的高可用性。

Master 节点扮演着总控中心的角色,通过不断与工作节点上的 Kubelet 和 kube-proxy 进行通信来维护整个集群的健康工作状态。如果 Master 节点故障,将无法使用 kubectl 工具或者 API 做任何集群管理。

Master 节点主要有三个服务 kube-apiserver、kube-controller-manager 和 kube-scheduler,其中 kube-controller-manager 和 kube-scheduler 组件自身通过选择机制已经实现了高可用,所以 Master 高可用主要针对 kube-apiserver 组件,而该组件是以 HTTP API 提供服务,因此对他高可用与 Web 服务器类似,增加负载均衡器对其负载均衡即可,并且可水平扩容。

多 Master 架构图:

实现kubernetes master集群有多种方式,根据不同的需求和场景,可以选择合适的方式来搭建和运维master集群。一般来说,根据实现方式,负载均衡集群可以分为以下几种方案:

  • 硬件负载均衡:硬件负载均衡是使用专门的硬件设备来实现负载均衡的方案,如 F5、Cisco 等。硬件负载均衡的优点是性能高、稳定性强,缺点是成本高、扩展性差。
  • 软件负载均衡:软件负载均衡是使用普通的服务器和软件来实现负载均衡的方案,如 Nginx、HAProxy 等。软件负载均衡的优点是成本低、扩展性好,缺点是性能低、稳定性差。
  • 混合负载均衡:混合负载均衡是结合硬件和软件来实现负载均衡的方案,如使用硬件设备作为全局入口,使用软件作为局部分发。混合负载均衡的优点是兼顾了性能和成本,缺点是复杂度高、维护难。

1.2.1 存储高可用集群

etcd:分布式键值存储系统,用于保存集群中所有资源对象的状态和元数据。

k8s配置高可用(HA)Kubernetes etcd集群。

可以设置 以下两种HA 集群:

  • 使用堆叠(stacked)控制平面节点,其中 etcd 节点与控制平面节点共存
  • 使用外部 etcd 节点,其中 etcd 在与控制平面不同的节点上运行
1.2.1.1 堆叠(Stacked)etcd 拓扑--内置etcd集群

堆叠(Stacked)HA集群是一种这样的拓扑,其中 etcd 分布式数据存储集群堆叠在 kubeadm 管理的控制平面节点上,作为控制平面的一个组件运行。

每个控制平面节点运行 kube-apiserver、kube-scheduler 和 kube-controller-manager 实例。 kube-apiserver 使用负载均衡器暴露给工作节点。

每个控制平面节点创建一个本地etcd成员(member),这个 etcd 成员只与该节点的 kube-apiserver 通信。 这同样适用于本地 kube-controller-manager 和 kube-scheduler 实例。

这种拓扑将控制平面和 etcd 成员耦合在同一节点上。相对使用外部 etcd 集群, 设置起来更简单,而且更易于副本管理。

然而,堆叠集群存在耦合失败的风险。如果一个节点发生故障,则etcd 成员和控制平面实例都将丢失, 并且冗余会受到影响。你可以通过添加更多控制平面节点来降低此风险。

因此应该为 HA 集群运行至少三个堆叠的控制平面节点。

这是 kubeadm 中的默认拓扑。当使用 kubeadm init 和 kubeadm join --control-plane 时, 在控制平面节点上会自动创建本地 etcd 成员。

 1.2.1.2 外部 etcd 拓扑--外部etcd集群

具有外部 etcd 的 HA 集群是一种这样的拓扑, 其中 etcd 分布式数据存储集群在独立于控制平面节点的其他节点上运行。

就像堆叠的 etcd 拓扑一样,外部 etcd 拓扑中的每个控制平面节点都会运行 kube-apiserver、kube-scheduler 和 kube-controller-manager 实例。 同样,kube-apiserver 使用负载均衡器暴露给工作节点。但是 etcd 成员在不同的主机上运行, 每个 etcd 主机与每个控制平面节点的 kube-apiserver 通信。

这种拓扑结构解耦了控制平面和 etcd 成员。因此它提供了一种 HA 设置, 其中失去控制平面实例或者 etcd 成员的影响较小,并且不会像堆叠的 HA 拓扑那样影响集群冗余。

但此拓扑需要两倍于堆叠 HA 拓扑的主机数量。 具有此拓扑的 HA 集群至少需要三个用于控制平面节点的主机和三个用于 etcd 节点的主机。

2 高可用集群部署实战

2.1 单master节点升级为高可用集群

2.1.1 部署负载均衡

nginx节点信息:10.220.43.211:16443

2.1.1.1 安装nginx

此处负载均衡以nginx为例。

$ yum install nginx -y
2.1.1.2 配置nginx
$ vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;include /usr/share/nginx/modules/*.conf;events {worker_connections 1024;
}# 四层负载均衡,为两台Master apiserver组件提供负载均衡
stream {log_format  main  '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';access_log  /var/log/nginx/k8s-access.log  main;upstream k8s-apiserver {server 10.220.43.203:6443;   # Master1 APISERVER IP:PORT}server {listen 16443;  # 由于nginx与master节点复用,这个监听端口不能是6443,否则会冲突proxy_pass k8s-apiserver;}
}http {log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile            on;tcp_nopush          on;tcp_nodelay         on;keepalive_timeout   65;types_hash_max_size 2048;include             /etc/nginx/mime.types;default_type        application/octet-stream;server {listen       80 default_server;server_name  _;location / {}}
}
2.1.1.3 启动nginx
$ nginx -t
$ systemctl start nginx

2.1.2 master切换

2.1.2.1 更新k8s证书 

ops-master-1操作。

如果是用kubeadm init 来创建的集群,那么需要导出一个kubeadm配置 。

$ kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' > kubeadm.yaml
$ cat kubeadm.yaml
apiServer:extraArgs:authorization-mode: Node,RBACtimeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:type: CoreDNS
etcd:local:dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.21.9
networking:dnsDomain: cluster.localpodSubnet: 172.25.0.0/16serviceSubnet: 192.168.0.0/16
scheduler: {}
2.1.2.2 添加证书SANs信息
$ vim kubeadm.yaml
apiServer:certSANs:- 10.220.43.211- 10.220.43.203- 10.220.43.204- 10.220.43.205extraArgs:authorization-mode: Node,RBACtimeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: 10.220.43.211:6443
controllerManager: {}
dns:type: CoreDNS
etcd:local:dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.21.9
networking:dnsDomain: cluster.localpodSubnet: 172.25.0.0/16serviceSubnet: 192.168.0.0/16
scheduler: {}
2.1.2.3 生成新证书
2.1.2.3.1 备份旧证书
$ mkdir bak
$ mv /etc/kubernetes/pki/apiserver.{crt,key} bak/
2.1.2.3.2 生成新证书
$ kubeadm init phase certs apiserver --config kubeadm.yaml
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local ops-master-1] and IPs [192.168.0.1 10.220.43.203 10.220.43.211 10.220.43.204 10.220.43.205]
2.1.2.3.3 验证证书

确定包含新添加的SAN列表。

$ openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text
......
X509v3 Subject Alternative Name: DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:ops-master-1, IP Address:192.168.0.1, IP Address:10.220.43.203, IP Address:10.220.43.211, IP Address:10.220.43.204, IP Address:10.220.43.205
......
2.1.2.3.5 重启apiserver
$ kubectl get pod -n kube-system  -o wide 
NAME                                       READY   STATUS    RESTARTS   AGE   IP              NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-5d4b78db86-rrgw4   1/1     Running   0          54m   172.25.13.1     ops-master-1   <none>           <none>
calico-node-jk7zc                          1/1     Running   0          51m   10.220.43.204   ops-worker-1   <none>           <none>
calico-node-p2c7d                          1/1     Running   0          54m   10.220.43.203   ops-master-1   <none>           <none>
calico-node-v8z5x                          1/1     Running   0          51m   10.220.43.205   ops-worker-2   <none>           <none>
coredns-59d64cd4d4-gkrz6                   1/1     Running   0          87m   172.25.13.2     ops-master-1   <none>           <none>
coredns-59d64cd4d4-nmdfh                   1/1     Running   0          87m   172.25.13.3     ops-master-1   <none>           <none>
etcd-ops-master-1                          1/1     Running   0          87m   10.220.43.203   ops-master-1   <none>           <none>
kube-apiserver-ops-master-1                1/1     Running   0          87m   10.220.43.203   ops-master-1   <none>           <none>
kube-controller-manager-ops-master-1       1/1     Running   0          87m   10.220.43.203   ops-master-1   <none>           <none>
kube-proxy-f7mct                           1/1     Running   0          51m   10.220.43.205   ops-worker-2   <none>           <none>
kube-proxy-j9bmp                           1/1     Running   0          51m   10.220.43.204   ops-worker-1   <none>           <none>
kube-proxy-pm77c                           1/1     Running   0          87m   10.220.43.203   ops-master-1   <none>           <none>
kube-scheduler-ops-master-1                1/1     Running   0          87m   10.220.43.203   ops-master-1   <none>           <none>
$ kubectl delete pod kube-controller-manager-ops-master-1 -n kube-system  
pod "kube-controller-manager-ops-master-1" deleted
2.1.2.3.6 保存新配置
$ kubeadm init phase upload-config kubeadm --config kubeadm.yaml
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
2.1.2.4 更新配置

证书更新完成了,负载均衡也部署好了,接下来就需要把所有用到旧地址的组件配置修改成负载均衡的地址。

2.1.2.4.1 kubelet.conf
$ vim /etc/kubernetes/kubelet.conf
...server: https://10.220.43.211:16443name: kubernetes
...
$ systemctl restart kubelet
2.1.2.4.2 controller-manager.conf
$ vim /etc/kubernetes/controller-manager.conf
...server: https://10.220.43.211:16443name: kubernetes
...
# 重启kube-controller-manager
$ kubectl delete pod -n kube-system kube-controller-manager-ops-master-1
2.1.2.4.3  scheduler.conf
$ vim /etc/kubernetes/scheduler.conf...server: https://10.220.43.211:16443name: kubernetes
...
# 重启kube-scheduler
$ kubectl delete pod -n kube-system kube-scheduler-ops-master-1
2.1.2.4.4 kube-proxy
$ kubectl edit configmap kube-proxy -n kube-system
...kubeconfig.conf: |-apiVersion: v1kind: Configclusters:- cluster:certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtserver: https://10.220.43.211:16443name: defaultcontexts:- context:cluster: defaultnamespace: defaultuser: defaultname: default
...
configmap/kube-proxy edited
$ kubectl rollout restart daemonset kube-proxy -n kube-system
2.1.2.4.5 修改kubeconfig

~/.kube/config 和 /etc/kubernetes/admin.conf都需要修改。 

$ vim /etc/kubernetes/admin.conf 
...server: https://10.220.43.211:16443name: kubernetes
...
$ vim /root/.kube/config
...server: https://10.220.43.211:16443name: kubernetes
...

2.1.3 worker切换apiserver

2.1.3.1 kubelet.conf
$ vim /etc/kubernetes/kubelet.conf
...server: https://10.220.43.211:16443name: kubernetes
...
$ systemctl restart kubelet
2.1.3.2 修改kubeconfig

只需要修改~/.kube/config 。

$ vim /etc/kubernetes/admin.conf 
...server: https://10.220.43.211:16443name: kubernetes
...

2.1.4 验证

2.1.4.1 master验证

ops-master-1验证。

$ cat /root/.kube/config  | grep server 
server: https://10.220.43.211:16443
$ kubectl get pod -n kube-system 
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-5d4b78db86-rrgw4   1/1     Running   0          65m
calico-node-jk7zc                          1/1     Running   0          62m
calico-node-p2c7d                          1/1     Running   0          65m
calico-node-v8z5x                          1/1     Running   0          62m
coredns-59d64cd4d4-gkrz6                   1/1     Running   0          97m
coredns-59d64cd4d4-nmdfh                   1/1     Running   0          97m
etcd-ops-master-1                          1/1     Running   0          98m
kube-apiserver-ops-master-1                1/1     Running   0          98m
kube-controller-manager-ops-master-1       1/1     Running   0          5m44s
kube-proxy-dhjxj                           1/1     Running   0          2m30s
kube-proxy-rm64j                           1/1     Running   0          2m32s
kube-proxy-xg6bp                           1/1     Running   0          2m35s
kube-scheduler-ops-master-1                1/1     Running   0          4m16s
$ kubectl get nodes
NAME           STATUS   ROLES                  AGE    VERSION
ops-master-1   Ready    control-plane,master   101m   v1.21.9
ops-worker-1   Ready    <none>                 65m    v1.21.9
ops-worker-2   Ready    <none>                 65m    v1.21.9
2.1.4.2 worker验证 

ops-worker-1节点验证。 

$ kubectl get pod -n kube-system 
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-5d4b78db86-rrgw4   1/1     Running   0          74m
calico-node-jk7zc                          1/1     Running   0          71m
calico-node-p2c7d                          1/1     Running   0          74m
calico-node-v8z5x                          1/1     Running   0          71m
coredns-59d64cd4d4-gkrz6                   1/1     Running   0          107m
coredns-59d64cd4d4-nmdfh                   1/1     Running   0          107m
etcd-ops-master-1                          1/1     Running   0          107m
kube-apiserver-ops-master-1                1/1     Running   0          107m
kube-controller-manager-ops-master-1       1/1     Running   0          14m
kube-proxy-dhjxj                           1/1     Running   0          11m
kube-proxy-rm64j                           1/1     Running   0          11m
kube-proxy-xg6bp                           1/1     Running   0          11m
kube-scheduler-ops-master-1                1/1     Running   0          13m
$ kubectl get nodes 
NAME           STATUS   ROLES                  AGE    VERSION
ops-master-1   Ready    control-plane,master   109m   v1.21.9
ops-worker-1   Ready    <none>                 74m    v1.21.9
ops-worker-2   Ready    <none>                 73m    v1.21.9

2.2  高可用集群新增master节点

新master节点:10.220.43.209 ops-master-2

2.2.1 新master部署k8s服务

2.2.1.1 各节点增加新master 信息
# ops-master-1/ops-worker-1/ops-worker-2:
echo "10.220.43.209 ops-master-2" >> /etc/hosts
2.2.1.2 k8s服务部署 

参考:Kubernetes实战(九)-kubeadm安装k8s集群-CSDN博客  

2.2.2  新master加入集群

$ kubeadm join 10.220.43.211:16443 --token 9puv2h.sr5dvg9skqlqhofm --discovery-token-ca-cert-hash sha256:b85555d7fdf2e1f28afe09dcb649117a34ac330ace38434fb604e2705b5df207   --control-plane --certificate-key a96e54087b299b962dae6321e519386fd9bdb1876a6cd4067c55484a0fe0c5e0
[preflight] Running pre-flight checks[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[preflight] Running pre-flight checks before initializing the new control plane instance
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost ops-master-2] and IPs [10.220.43.209 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost ops-master-2] and IPs [10.220.43.209 127.0.0.1 ::1]
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local ops-master-2] and IPs [192.168.0.1 10.220.43.209 10.220.43.211 10.220.43.203 10.220.43.204 10.220.43.205]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[certs] Using the existing "sa" key
[kubeconfig] Generating kubeconfig files
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "admin.conf" kubeconfig file
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[endpoint] WARNING: port specified in controlPlaneEndpoint overrides bindPort in the controlplane address
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[check-etcd] Checking that the etcd cluster is healthy
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
[etcd] Announced new etcd member joining to the existing etcd cluster
[etcd] Creating static Pod manifest for "etcd"
[etcd] Waiting for the new etcd member to join the cluster. This can take up to 40s
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[mark-control-plane] Marking the node ops-master-2 as control-plane by adding the labels: [node-role.kubernetes.io/master(deprecated) node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node ops-master-2 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]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 (master) 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/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configRun 'kubectl get nodes' to see this node join the cluster.

加入成功。

2.2.3 查看状态

$ kubectl get nodes
NAME           STATUS     ROLES                  AGE    VERSION
ops-master-1   Ready      control-plane,master   147m   v1.21.9
ops-master-2   NotReady   control-plane,master   27s    v1.21.9
ops-worker-1   Ready      <none>                 111m   v1.21.9
ops-worker-2   Ready      <none>                 111m   v1.21.9

状态更新需要等待,等到2-3分钟后再查看:

$ kubectl get nodes
NAME           STATUS   ROLES                  AGE     VERSION
ops-master-1   Ready    control-plane,master   150m    v1.21.9
ops-master-2   Ready    control-plane,master   3m46s   v1.21.9
ops-worker-1   Ready    <none>                 114m    v1.21.9
ops-worker-2   Ready    <none>                 114m    v1.21.9
$ kubectl get pod -n kube-system -o wide 
NAME                                       READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-5d4b78db86-rrgw4   1/1     Running   0          117m    172.25.13.1     ops-master-1   <none>           <none>
calico-node-f5s6w                          1/1     Running   0          4m1s    10.220.43.209   ops-master-2   <none>           <none>
calico-node-jk7zc                          1/1     Running   0          114m    10.220.43.204   ops-worker-1   <none>           <none>
calico-node-p2c7d                          1/1     Running   0          117m    10.220.43.203   ops-master-1   <none>           <none>
calico-node-v8z5x                          1/1     Running   0          114m    10.220.43.205   ops-worker-2   <none>           <none>
coredns-59d64cd4d4-gkrz6                   1/1     Running   0          150m    172.25.13.2     ops-master-1   <none>           <none>
coredns-59d64cd4d4-nmdfh                   1/1     Running   0          150m    172.25.13.3     ops-master-1   <none>           <none>
etcd-ops-master-1                          1/1     Running   0          150m    10.220.43.203   ops-master-1   <none>           <none>
etcd-ops-master-2                          1/1     Running   0          3m56s   10.220.43.209   ops-master-2   <none>           <none>
kube-apiserver-ops-master-1                1/1     Running   0          150m    10.220.43.203   ops-master-1   <none>           <none>
kube-apiserver-ops-master-2                1/1     Running   0          3m56s   10.220.43.209   ops-master-2   <none>           <none>
kube-controller-manager-ops-master-1       1/1     Running   1          5m9s    10.220.43.203   ops-master-1   <none>           <none>
kube-controller-manager-ops-master-2       1/1     Running   0          3m56s   10.220.43.209   ops-master-2   <none>           <none>
kube-proxy-dhjxj                           1/1     Running   0          54m     10.220.43.203   ops-master-1   <none>           <none>
kube-proxy-rm64j                           1/1     Running   0          54m     10.220.43.204   ops-worker-1   <none>           <none>
kube-proxy-xg6bp                           1/1     Running   0          54m     10.220.43.205   ops-worker-2   <none>           <none>
kube-proxy-zcvzs                           1/1     Running   0          4m1s    10.220.43.209   ops-master-2   <none>           <none>
kube-scheduler-ops-master-1                1/1     Running   1          56m     10.220.43.203   ops-master-1   <none>           <none>
kube-scheduler-ops-master-2                1/1     Running   0          3m56s   10.220.43.209   ops-master-2   <none>           <none>

新master节点各种组件已将安装完毕。 

2.2.4 验证高可用

2.2.4.1 停掉ops-master-1
[root@ops-master-1 ~]# init 0
2.2.4.2 其他节点验证
[root@ops-master-2 etc]# kubectl get nodes
Error from server: etcdserver: request timed out
[root@ops-worker-1 .kube]# kubectl get nodes
Error from server: rpc error: code = Unknown desc = OK: HTTP status code 200; transport: missing content-type field

 经分析,是因为coredns均分布在ops-master-1节点上,当ops-master-1节点挂掉后,无可用coredns。

2.2.4.3 coredns打散分布
$ kubectl delete pod coredns-59d64cd4d4-gkrz6 -n kube-system 
pod "coredns-59d64cd4d4-gkrz6" deleted
$ kubectl get pod -n kube-system -o wide 
NAME                                       READY   STATUS    RESTARTS   AGE    IP              NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-5d4b78db86-rrgw4   1/1     Running   1          125m   172.25.13.6     ops-master-1   <none>           <none>
calico-node-f5s6w                          1/1     Running   0          11m    10.220.43.209   ops-master-2   <none>           <none>
calico-node-jk7zc                          1/1     Running   0          122m   10.220.43.204   ops-worker-1   <none>           <none>
calico-node-p2c7d                          1/1     Running   1          125m   10.220.43.203   ops-master-1   <none>           <none>
calico-node-v8z5x                          1/1     Running   0          122m   10.220.43.205   ops-worker-2   <none>           <none>
coredns-59d64cd4d4-nmdfh                   1/1     Running   1          158m   172.25.13.5     ops-master-1   <none>           <none>
coredns-59d64cd4d4-zr4hd                   1/1     Running   0          40s    172.25.78.65    ops-worker-1   <none>           <none>
etcd-ops-master-1                          1/1     Running   1          158m   10.220.43.203   ops-master-1   <none>           <none>
etcd-ops-master-2                          1/1     Running   1          11m    10.220.43.209   ops-master-2   <none>           <none>
kube-apiserver-ops-master-1                1/1     Running   1          158m   10.220.43.203   ops-master-1   <none>           <none>
kube-apiserver-ops-master-2                1/1     Running   4          11m    10.220.43.209   ops-master-2   <none>           <none>
kube-controller-manager-ops-master-1       1/1     Running   2          12m    10.220.43.203   ops-master-1   <none>           <none>
kube-controller-manager-ops-master-2       1/1     Running   1          11m    10.220.43.209   ops-master-2   <none>           <none>
kube-proxy-dhjxj                           1/1     Running   1          62m    10.220.43.203   ops-master-1   <none>           <none>
kube-proxy-rm64j                           1/1     Running   0          62m    10.220.43.204   ops-worker-1   <none>           <none>
kube-proxy-xg6bp                           1/1     Running   0          62m    10.220.43.205   ops-worker-2   <none>           <none>
kube-proxy-zcvzs                           1/1     Running   0          11m    10.220.43.209   ops-master-2   <none>           <none>
kube-scheduler-ops-master-1                1/1     Running   2          64m    10.220.43.203   ops-master-1   <none>           <none>
kube-scheduler-ops-master-2                1/1     Running   1          11m    10.220.43.209   ops-master-2   <none>           <none>

coredns已打散。

此刻针对ops-master-1节点执行停机操作,但是集群仍然不可用。

经分析是etcd只有两个pod,由于etcd是分布式服务,必须保持基数格式才能完成选举。因此需要再部署一个master节点以保证etcd个数达到基数个。

此处建议使用外拓扑架构的etcd,而不是使用堆叠式的etcd部署架构。 

2.2.5 部署ops-master-3节点

参考:Kubernetes实战(九)-kubeadm安装k8s集群-CSDN博客  

2.2.6 验证

$ kubectl get nodes
NAME           STATUS   ROLES                  AGE     VERSION
ops-master-1   Ready    control-plane,master   168m    v1.21.9
ops-master-2   Ready    control-plane,master   21m     v1.21.9
ops-master-3   Ready    control-plane,master   2m28s   v1.21.9
ops-worker-1   Ready    <none>                 132m    v1.21.9
ops-worker-2   Ready    <none>                 132m    v1.21.9

ops-master-1节点下线。

$ kubectl get nodes
NAME           STATUS     ROLES                  AGE     VERSION
ops-master-1   NotReady   control-plane,master   168m    v1.21.9
ops-master-2   NotReady   control-plane,master   22m     v1.21.9
ops-master-3   NotReady   control-plane,master   2m47s   v1.21.9
ops-worker-1   Ready      <none>                 133m    v1.21.9
ops-worker-2   Ready      <none>                 132m    v1.21.9

三个master均离线。

经查是因为新master的kubelet.conf配置仍然配置的是:10.220.43.203:6443,当节点ops-master-1(10.220.43.203)挂掉,新master节点将无法集群链接,导致node下线。

解决方案:

$ vim kubelet.conf 
......server: https://10.220.43.211:16443
......
$ systemctl restart kubelet
$ kubectl get nodes
NAME           STATUS     ROLES                  AGE     VERSION
ops-master-1   NotReady   control-plane,master   4h15m   v1.21.9
ops-master-2   Ready      control-plane,master   108m    v1.21.9
ops-master-3   Ready      control-plane,master   88m     v1.21.9
ops-worker-1   Ready      <none>                 3h39m   v1.21.9
ops-worker-2   Ready      <none>                 3h39m   v1.21.9

 至此,高可用集群新增master节点完成。

相关文章:

Kubernetes实战(十四)-k8s高可用集群扩容master节点

1 单master集群和多master节点集群方案 1.1 单Master集群 k8s 集群是由一组运行 k8s 的节点组成的&#xff0c;节点可以是物理机、虚拟机或者云服务器。k8s 集群中的节点分为两种角色&#xff1a;master 和 node。 master 节点&#xff1a;master 节点负责控制和管理整个集群…...

Spring之容器:IOC(1)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…...

【.Net 6.0--通用帮助类--ConvertHelper】

前言 类型转换帮助类&#xff0c;包含下表中的方法&#xff1a; 方法名方法解释ObjToIntobject转intObjToMoneyobject转doubleObjToStringobject转stringObjToDecimalobject转decimalObjToDateobject转datetimeObjToDateSplitYMDobject转datetime&#xff08;yyyy-MM-dd&…...

【加解密】报文签名与加解密,MD5,RSA,AES使用案例(基于 Java)

需要考虑哪些问题&#xff1f; 在进行报文传输时&#xff0c;有两个问题需要考虑&#xff1a; 消息防篡改加密报文 定义消息结构 为了方便后面使用&#xff0c;这里定义消息结构&#xff1a; public static class Message {public String data; //消息public String sign;…...

新建vue3项目

三种方法 一. 第一种方式 1、操作步骤&#xff1a; 创建项目目录 vue create 项目名称选择配置方式 ? Please pick a preset: #选择一个配置 Default &#xff08;[Vue 3] babel, eslint&#xff09;Default &#xff08;[Vue 2] babel, eslint&#xff09;Manually select …...

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 执行Nacos中的startup.cmd的时候出现闪退,于是在该脚本的最后一行添加pause,查看因为什么原因闪退 出现的bug如下所示:Error:Unable to access jarfile xxxx\target\nacos-server.jar 截图如下所示: 查看内部文件夹,…...

记录一次API报文替换点滴

1. 需求 各位盆友在日常开发中&#xff0c;有没有遇到上游接口突然不合作了&#xff0c;临时需要切换其他接口的情况&#xff1f;这不巧了&#xff0c;博主团队近期遇到了&#xff0c;又尴尬又忐忑。 尴尬的是临时通知不合作了&#xff0c;事前没有任何提醒&#xff1b; 忐忑…...

PMP项目管理 - 沟通管理

系列文章目录 PMP项目管理 - 质量管理 PMP项目管理 - 采购管理 PMP项目管理 - 资源管理 PMP项目管理 - 风险管理 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in…...

fckeditor编辑器改造示例:增加PRE,CODE控件

查看专栏目录 Network 灰鸽宝典专栏主要关注服务器的配置&#xff0c;前后端开发环境的配置&#xff0c;编辑器的配置&#xff0c;网络服务的配置&#xff0c;网络命令的应用与配置&#xff0c;windows常见问题的解决等。 文章目录 修改方法&#xff1a;1&#xff09;修改fckco…...

风速预测(五)基于Pytorch的EMD-CNN-LSTM模型

目录 前言 1 风速数据EMD分解与可视化 1.1 导入数据 1.2 EMD分解 2 数据集制作与预处理 2.1 先划分数据集&#xff0c;按照8&#xff1a;2划分训练集和测试集 2.2 设置滑动窗口大小为96&#xff0c;制作数据集 3 基于Pytorch的EMD-CNN-LSTM模型预测 3.1 数据加载&…...

单元测试二(理论)-云计算2023.12-云南农业大学

文章目录 一、单选题1、三次握手、四次挥手发生在网络模型的哪一层上&#xff1f;2、互联网Internet的拓扑结构是什么&#xff1f;3、以下哪一种网络设备是工作在网络层的&#xff1f;4、以下哪种关于分组交换网络的说法是错误的&#xff1f;5、以下哪种协议是在TCP/IP模型中的…...

QModelIndex 是 Qt 框架中的一个类,用于表示数据模型中的索引位置

QModelIndex 是 Qt 框架中的一个类&#xff0c;用于表示数据模型中的索引位置。 在 Qt 中&#xff0c;数据模型是一种组织和管理数据的方式&#xff0c;常见的数据模型包括 QAbstractItemModel、QStandardItemModel 和 QSqlQueryModel 等。QModelIndex 类提供了一种标识数据模…...

前端实现一个时间区间内,再次单选功能,使用Antd组件库内日历组件Calendar

需求&#xff1a;需要先让用户选择一个时间区间&#xff0c;然后再这个时间区间中&#xff0c;让用户再次去单选其种特殊日期。 思路&#xff1a; 1.先用Antd组件库中日期选择DatePicker.RangePicker实现让用户选择时间区间 2.在选择完时间区间后&#xff0c;用这个时间区间…...

【运维笔记】Hyperf正常情况下Xdebug报错死循环解决办法

问题描述 在使用hyperf进行数据库迁移时&#xff0c;迁移报错&#xff1a; 查看报错信息&#xff0c;错误描述是Xdebug检测到死循环&#xff0c;可是打印的堆栈确实正常堆栈&#xff0c;没看到死循环。 寻求解决 gpt 说的跟没说一样。。 google一下 直接把报错信息粘贴上去…...

嵌入式开发中的总线与时钟

总线 AHB总线 AHB的全称是"Advanced High-performance Bus",中文翻译就是"高级高性能总线"。这是一种在计算机系统中用于连接不同硬件组件的总线架构,它可以帮助这些组件之间高效地传输数据和信息。这个总线架构通常用于处理速度较快且对性能要求较高的…...

k8s debug 浅谈

一 k8s debug 浅谈 说明&#xff1a; 本文只是基于对kubectl debug浅显认识总结的知识点,后续实际使用再补充案例 Kubernetes 官方出品调试工具上手指南(无需安装&#xff0c;开箱即用) debug-application 简化 Pod 故障诊断: kubectl-debug 介绍 1.18 版本之前需要自己…...

Day10 Liunx高级系统设计11-数据库2

DQL:数据查询语言 查询全表 select * from 表名; 查询指定列 select 列名 1, 列名 2,… from 表名 ; 条件查询 select * from 表名 where 条件 ; 注意&#xff1a; 条件查询就是在查询时给出 WHERE 子句&#xff0c;在 WHERE 子句中可以使用如下运算符及关键 字&#…...

车载导航系统UI界面,可视化大屏设计(PS源文件)

大屏组件可以让UI设计师的工作更加便捷&#xff0c;使其更高效快速的完成设计任务。现分享车载导航系统科技风蓝黑简约UI界面、车载系统UI主界面、车载系统科技风UI界面、首页车载系统科技感界面界面的大屏Photoshop源文件&#xff0c;开箱即用&#xff01; 若需 更多行业 相关…...

工作之踩坑记录

1.i386架构之atol函数使用导致的业务程序错误&#xff1a; 情景:将框架传递的链接地址采用整形保存传输,在i386架构上导致地址比较大&#xff0c;采用atol转型可能导致数据被截断出现异常。 方案:采用atoll更大的数据类型进行处理即可避免该问题。 2.Json库使用注意long int问…...

【深度学习目标检测】四、基于深度学习的抽烟识别(python,yolov8)

YOLOv8是一种物体检测算法&#xff0c;是YOLO系列算法的最新版本。 YOLO&#xff08;You Only Look Once&#xff09;是一种实时物体检测算法&#xff0c;其优势在于快速且准确的检测结果。YOLOv8在之前的版本基础上进行了一系列改进和优化&#xff0c;提高了检测速度和准确性。…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!

多连接 BLE 怎么设计服务不会乱&#xff1f;分层思维来救场&#xff01; 作者按&#xff1a; 你是不是也遇到过 BLE 多连接时&#xff0c;调试现场像网吧“掉线风暴”&#xff1f; 温度传感器连上了&#xff0c;心率带丢了&#xff1b;一边 OTA 更新&#xff0c;一边通知卡壳。…...

新版NANO下载烧录过程

一、序言 搭建 Jetson 系列产品烧录系统的环境需要在电脑主机上安装 Ubuntu 系统。此处使用 18.04 LTS。 二、环境搭建 1、安装库 $ sudo apt-get install qemu-user-static$ sudo apt-get install python 搭建环境的过程需要这个应用库来将某些 NVIDIA 软件组件安装到 Je…...

Excel 怎么让透视表以正常Excel表格形式显示

目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...

小白的进阶之路系列之十四----人工智能从初步到精通pytorch综合运用的讲解第七部分

通过示例学习PyTorch 本教程通过独立的示例介绍PyTorch的基本概念。 PyTorch的核心提供了两个主要特性: 一个n维张量,类似于numpy,但可以在gpu上运行 用于构建和训练神经网络的自动微分 我们将使用一个三阶多项式来拟合问题 y = s i n ( x ) y=sin(x) y=sin(x),作为我们的…...