【K8s 精选】CKA - 管理高可用性 Kubernetes 集群

创建 HA 集群的一般步骤:
● 设置负载均衡器。有许多开源选项可用于负载均衡:HAproxy、Envoy 或来自云提供商的类似负载均衡器效果很好。
● 在第一个控制平面节点上运行 kubeadm init,并进行以下修改:
① 创建 kubeadm 配置文件
② 在配置文件中,将 controlPlaneEndpoint 字段设置为可以访问负载均衡器的位置。
③ 运行 init,带有如下--upload-certs 标志:sudo kubeadm init --config=kubeadm-config.yaml --upload-certs
kubeadm join –control-plane在您想要扩展控制平面节点集时随时运行。控制平面和普通节点可以随时以任何顺序加入。

1 创建前检查

① 3 台机器作为控制面节点、3 台机器作为工作节点、3 台机器作为外部 etcd 集群(外部 etcd 拓扑方案)
② 在集群中,确保所有计算机之间存在全网络连接(公网或私网)
③ 在所有机器上具有 sudo 权限
④ 从某台设备通过 ssh 访问系统中所有节点的能力
⑤ 所有机器上已经安装 kubeadmkubeletkubectl 是可选的

2 为 kube-apiserver 创建负载均衡器

### 创建高可用的负载均衡器
# 例如 ip 和 port 为 LOAD_BALANCER_IP 和 LOAD_BALANCER_PORT
$kubeadm init --control-plane-endpoint=LOAD_BALANCER_IP:LOAD_BALANCER_PORT

### 逐个添加控制平面节点到负载均衡器并测试连接
nc -v LOAD_BALANCER_IP PORT

3 初始化和添加多个控制平面节点

### 初始化控制平面
$sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_IP:LOAD_BALANCER_PORT" --upload-certs
...
You can now join any number of control-plane node by running the following command on each as a root:
kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07

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 to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:
  kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866

### 逐个添加控制平面
# --control-plane 命令通知 kubeadm join 创建一个新的控制平面
$sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07

$sudo kubeadm join 192.168.0.300:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07

$sudo kubeadm join 192.168.0.400:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07

4 创建和配置 ectd 集群

堆叠(Stacked) etcd 拓扑方案

每个控制平面节点创建一个本地 etcd 成员(member)。该 etcd 成员只与该节点的 kube-apiserverkube-controller-managerkube-scheduler 实例通信。

堆叠 etcd 拓扑.png

堆叠(stacked) etcd 方案,在控制平面设置负载均衡后,自动管理 etcd 的 external 对象下带有 endpoints 的配置文件。

外部 etcd 拓扑方案

etcd 分布式数据存储集群在独立于控制平面节点的其他节点上运行。每个控制平面节点都运行 kube-apiserverkube-schedulerkube-controller-manager 实例。每个 etcd 主机与每个控制平面节点的 kube-apiserver 通信

外部 etcd 拓扑.png

① 设置 ectd 集群

● 利用 kubeadm 创建高可用 etcd 集群

● 配置 SSH。

● 将以下文件从集群中的任何 etcd 节点复制到第一个控制平面节点:

    $export CONTROL_PLANE="[email protected]"
    $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}":
    #说明:第一台控制平面机的 user@host 替换 CONTROL_PLANE

② 控制平面对接外部 ectd 集群

### 步骤 1:创建 kubeadm-config.yaml
$vi kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: stable
controlPlaneEndpoint: "LOAD_BALANCER_IP:LOAD_BALANCER_PORT"
etcd:
    external:
        endpoints:
        - https://ETCD_0_IP:2379
        - https://ETCD_1_IP:2379
        - https://ETCD_2_IP:2379
        caFile: /etc/kubernetes/pki/etcd/ca.crt
        certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
        keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
#说明:替换 LOAD_BALANCER_IP、LOAD_BALANCER_PORT、ETCD_0_IP、ETCD_1_IP、ETCD_2_IP

### 步骤 2:使得 kubeadm 命令生效
$sudo kubeadm init --config kubeadm-config.yaml --upload-certs
#说明:记下输出的 join 命令,然后根据 3 个控制平面的 ip 逐个对接 etcd 集群 

注意:外部 etcd 拓扑方案类似堆叠 etcd 拓扑方案,不同点是需要首先设置 etcd,并在 kubeadm 配置文件中传递 etcd 信息。如上所示,堆叠(stacked) etcd 和外部 etcd 之前的区别在于设置外部 etcd 需要一个 etcdexternal 对象下带有 etcd 端点的配置文件如果是堆叠 etcd,则自动管理的

5 利用 kubeadm 创建高可用 etcd 集群

前提条件
① 3 个可以通过 2379 和 2380 端口相互通信的主机
② 已经安装 kubernetes 集群,即每台主机有可以运行 Pod、执行命令 kubeadm、kubelet
③ 每台主机有复制文件的工具。例如 sshscp

5.1 将 kubelet 配置为 etcd 的服务管理器

$cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf
[Service]
ExecStart=
# 将下面的 "systemd" 替换为你的容器运行时所使用的 cgroup 驱动。
# kubelet 的默认值为 "cgroupfs"。
ExecStart=/usr/bin/kubelet --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests --cgroup-driver=systemd
Restart=always
EOF

$systemctl daemon-reload
$systemctl restart kubelet

# 检查 kubelet 的状态以确保其处于运行状态
$systemctl status kubelet

5.2 创建 kubeadm 配置文件

# 使用 IP 或可解析的主机名替换 HOST0、HOST1 和 HOST2
export HOST0=10.0.0.6
export HOST1=10.0.0.7
export HOST2=10.0.0.8

# 创建临时目录来存储将被分发到其它主机上的文件
mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/

ETCDHOSTS=(${HOST0} ${HOST1} ${HOST2})
NAMES=("infra0" "infra1" "infra2")

for i in "${!ETCDHOSTS[@]}"; do
HOST=${ETCDHOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: ClusterConfiguration
etcd:
    local:
        serverCertSANs:
        - "${HOST}"
        peerCertSANs:
        - "${HOST}"
        extraArgs:
            initial-cluster: infra0=https://${ETCDHOSTS[0]}:2380,infra1=https://${ETCDHOSTS[1]}:2380,infra2=https://${ETCDHOSTS[2]}:2380
            initial-cluster-state: new
            name: ${NAME}
            listen-peer-urls: https://${HOST}:2380
            listen-client-urls: https://${HOST}:2379
            advertise-client-urls: https://${HOST}:2379
            initial-advertise-peer-urls: https://${HOST}:2380
EOF
done

5.3 证书配置

参考 kubeadm init 命令

### 创建/复制证书到目录 /etc/kubernetes/pki/etcd/ca.crt   /etc/kubernetes/pki/etcd/ca.key
$cd  /etc/kubernetes/pki/etcd
$kubeadm init phase certs etcd-ca


### 为成员创建证书
$kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml
$kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml
$kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
$kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
$cp -R /etc/kubernetes/pki /tmp/${HOST2}/
# 清理不可重复使用的证书
$find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

$kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml
$kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml
$kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
$kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
$cp -R /etc/kubernetes/pki /tmp/${HOST1}/
$find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

$kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
$kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
$kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
$kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
# 不需要移动 certs 因为它们是给 HOST0 使用的

# 清理不应从此主机复制的证书
$find /tmp/${HOST2} -name ca.key -type f -delete
$find /tmp/${HOST1} -name ca.key -type f -delete

5.4 复制证书和 kubeadm 配置到 3 个 etcd 节点

USER=ubuntu
HOST=${HOST1}
scp -r /tmp/${HOST}/* ${USER}@${HOST}:
ssh ${USER}@${HOST}
USER@HOST $ sudo -Es
root@HOST $ chown -R root:root pki
root@HOST $ mv pki /etc/kubernetes/

### 查看预期文件都存在
# 节点 $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、$HOST2

5.5 指定配置创建 etcd pod

# 在对应的节点上,使用从配置文件 kubeadmcfg.yaml 读取的选项为 etcd 生成静态 Pod 清单文件
root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml

root@HOST1 $ kubeadm init phase etcd local --config=/tmp/${HOST1}/kubeadmcfg.yaml

root@HOST2 $ kubeadm init phase etcd local --config=/tmp/${HOST2}/kubeadmcfg.yaml

5.6 检查 etcd 集群状态

### 查询 etcd 镜像版本 ETCD_TAG
$kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.20.0
k8s.gcr.io/kube-controller-manager:v1.20.0
k8s.gcr.io/kube-scheduler:v1.20.0
k8s.gcr.io/kube-proxy:v1.20.0
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns:1.7.0

### 运行 etcd 容器
$docker run --rm -it \
--net host \
-v /etc/kubernetes:/etc/kubernetes k8s.gcr.io/etcd:${ETCD_TAG} etcdctl \
--cert /etc/kubernetes/pki/etcd/peer.crt \
--key /etc/kubernetes/pki/etcd/peer.key \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://${HOST0}:2379 endpoint health --cluster
...
https://[HOST0 IP]:2379 is healthy: successfully committed proposal: took = 16.283339ms
https://[HOST1 IP]:2379 is healthy: successfully committed proposal: took = 19.44402ms
https://[HOST2 IP]:2379 is healthy: successfully committed proposal: took = 35.926451ms

你可能感兴趣的:(【K8s 精选】CKA - 管理高可用性 Kubernetes 集群)