kubernetes的master是需要配置高可用集群的,当一台master出问题了之后另外一台master仍然是可以继续工作的。比如下图
file
不管是worker还是client,只要把请求发送到LB负载均衡器,然后LB会把请求在master1和master2之间进行转发。这里只要有一个master能够正常工作,整个kubernetes集群就会正常工作。
master1和master2需要实时同步数据,利用的是etcd集群的数据同步,在kubernetes官网提供了两种etcd同步的方案,一个是使用内部etcd集群,一个是使用的外部etcd集群。下面分别来演示这两种实验步骤。

方法1:使用内部etcd集群

官网提供的实验拓扑图如下
file
官网提供的拓扑图里有三台master,每台master上的etcd都是以pod的方式运行的,当建立好三台master之后,三台master上的etcd会自动建立成etcd集群。
本实验用两台master,拓扑图如下。
file

1-1安装haproxy

步骤1:在vms80上安装haproxy

yum install haproxy -y

修改/etc/haproxy/haproxy.cfg,在最后面添加如下内容

listen k8s-lb *:6443
        mode tcp
        balance roundrobin
        server s1 192.168.26.81:6443 weight 1 
        server s2 192.168.26.82:6443 weight 1

启动haproxy并设置开机自动启动

systemctl enable haproxy --now

这样当把请求转发给192.168.26.80:6443的时候,vms80会把请求转发到vms81和vms82的6443端口。

1-2安装k8s集群

步骤2:安装containerd安装k8s
这里安装和配置containerd、安装kubernetes相关软件、修改内核参数、加载模块等操作这些步骤不是重点,这里忽略,大家自行操作。

步骤3:编写配置文件
在vms81上,通过命令kubeadm config print init-defaults > config.yaml 获取初始化集群的配置文件,并修改成如下这个样子

apiServer:
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
controlPlaneEndpoint: "192.168.26.80:6443"
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.26.1
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/12
scheduler: {}

注意这里添加了controlPlaneEndpoint: “192.168.26.80:6443” 用于指定haproxy的地址和端口,同时注意这里的etcd的配置都是本地的。

步骤4:在vms81上初始化集群
执行下面命令初始化集群

kubeadm init --config=./config.yaml

之后按提示拷贝kubeconfig文件

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

这样第一台master就安装完毕了。
步骤5:把所需要的证书拷贝到vms82
先把需要的证书名及路径写入到aa.txt

[root@vms81 ~]# cat aa.txt 
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
/etc/kubernetes/pki/sa.key
/etc/kubernetes/pki/sa.pub
/etc/kubernetes/pki/front-proxy-ca.crt
/etc/kubernetes/pki/front-proxy-ca.key
/etc/kubernetes/pki/etcd/ca.key
/etc/kubernetes/pki/etcd/ca.crt
[root@vms81 ~]#

然后用tar命令把aa.txt里指定的文件压缩到cert.tar.gz里。

 tar czf cert.tar.gz -T aa.txt

cert.tar.gz的内容如下

[root@vms81 ~]# tar tf cert.tar.gz 
etc/kubernetes/pki/ca.crt
etc/kubernetes/pki/ca.key
etc/kubernetes/pki/sa.key
etc/kubernetes/pki/sa.pub
etc/kubernetes/pki/front-proxy-ca.crt
etc/kubernetes/pki/front-proxy-ca.key
etc/kubernetes/pki/etcd/ca.key
etc/kubernetes/pki/etcd/ca.crt
[root@vms81 ~]# 

把压缩的证书拷贝到vms82上。

scp cert.tar.gz 192.168.26.82:~

切换到vms82上,解压cert.tar.gz

tar zxf cert.tar.gz -C /

查看证书

[root@vms82 ~]# ls /etc/kubernetes/pki/
ca.crt  ca.key  etcd  front-proxy-ca.crt  front-proxy-ca.key  sa.key  sa.pub
[root@vms82 ~]# ls /etc/kubernetes/pki/etcd/
ca.crt  ca.key
[root@vms82 ~]#

在vms82上该有的证书都有了。

1-3添加第二台master

步骤6:把vms82以控制平面节点的方式加入集群
敲如下命令把vms82加入集群(vms81集群初始化完成之后会提示如下命令)

kubeadm join 192.168.26.80:6443 --token ynacxs.5whmmtkpjc87d7f5 --discovery-token-ca-cert-hash sha256:abaad7129786ebd8d5e5dea1f99e7311ebdd0875455ead58163dda425c353b81 --control-plane

上述命令最后有一个–control-plane,意思就是以控制平面节点的方式加入集群。
之后按提示复制kubeconfig文件(在vms82上做)

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

步骤7:通过kubectl get nodes查看
不管在vms81上还是vms82上执行kubectl get nodes查看
file

步骤8:把worker加入节点
在vms83上以worker的方式加入集群

kubeadm join 192.168.26.80:6443 --token ynacxs.5whmmtkpjc87d7f5 --discovery-token-ca-cert-hash sha256:abaad7129786ebd8d5e5dea1f99e7311ebdd0875455ead58163dda425c353b81

切换到vms81或者vms82上通过kubectl get nodes查看
file

查看kube-system里的etcd,会发现两台master上的etcd自动建立了集群。
file
然后安装calico之后集群即可正常工作,这里忽略。

步骤9:为了方法2的练习做准备,下面清空集群

[root@vms81 ~]# kubectl delete node vms83.rhce.cc
[root@vms81 ~]# kubectl delete node vms82.rhce.cc
[root@vms81 ~]# kubectl delete node vms81.rhce.cc

在所有节点执行kubeadm reset,准备第二种方法。

方法2:使用外部etcd集群

官网提供的拓扑图如下
file
这里每个etcd是以外部集群的方式存在的,而不是以pod的方式运行。我们练习的拓扑图如下
file
为了节约机器,这里etcd1放在vms81上运行,etcd2放在vms82上运行。
因为要实现etcd集群和master之间的mTLS通信,这里需要在两台etcd上配置证书。

2-1准备证书

步骤1:准备cfssl工具
下载cfssl工具放在/usr/local/bin/里
下载地址
https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
之后把下载下来的文件的后缀_linux-amd64去除并加上x权限

for i in * ; do n=${i%_*} ; mv $i $n; done ; chmod +x *

步骤2:创建证书
创建etcd证书所能用到的目录,并进入到此目录里。

mkdir -p /etc/kubernetes/pki/etcd  ; cd /etc/kubernetes/pki/etcd

创建ca的配置文件ca-config.json,内容如下。

{
    "signing": {
        "default": {
            "expiry": "43800h"
        },
        "profiles": {
            "server": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            },
            "client": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

创建ca证书的请求文件ca-csr.json,内容如下。

{
    "CN": "etcd",
    "key": {
        "algo": "rsa",
        "size": 2048
    }
}

创建etcd客户端(apiserver就是etcd的客户端)用的证书请求文件client.json,内容如下。

{
    "CN": "client",
    "key": {
        "algo": "ecdsa",
        "size": 256
    }
}

已经创建的文件如下。

[root@vms81 etcd]# ls
ca-config.json  ca-csr.json  client.json
[root@vms81 etcd]#

生成CA证书和私钥。

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

生成etcd客户端能用到的证书和私钥(apiserver就是etcd的客户端)

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client

现在目录里的内容如下

[root@vms81 etcd]# ls
ca-config.json  ca-csr.json  ca.pem      
client.json     client.pem  ca.csr          
ca-key.pem      client.csr  client-key.pem
[root@vms81 etcd]#

把这些证书拷贝到其他所有master上(这里是要拷贝到vms82上)

scp -r /etc/kubernetes/pki/ 192.168.26.82:/etc/kubernetes/

步骤3:生成etcd服务器端的证书,以及etcd节点之间建立peer的证书
在所有master节点上进入到/etc/kubernetes/pki/etcd目录里,执行如下命令。

cd /etc/kubernetes/pki/etcd
export PEER_NAME=$(hostname)
export PRIVATE_IP=$(ip addr show ens32 | grep -Po 'inet \K[\d.]+')

cfssl print-defaults csr > config.json
sed -i 's/www\.example\.net/'"$PRIVATE_IP"'/' config.json
sed -i 's/example\.net/'"$PEER_NAME"'/' config.json
sed -i '0,/CN/{s/example\.net/'"$PEER_NAME"'/}' config.json

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server config.json | cfssljson -bare server
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer config.json | cfssljson -bare peer

这里涉及到的证书比较多,总结如下图。
file
客户端(apiserver)和etcd通信的时候,利用到client的密钥和etcd的server两个密钥进行验证。两台etcd服务器之间用peer的证书 进行验证。

2-2安装配置etcd

步骤4:在所有节点建立etcd的变量文件
在所有节点上执行

export PEER_NAME=$(hostname)
export PRIVATE_IP=$(ip addr show ens32 | grep -Po 'inet \K[\d.]+')

touch /etc/etcd.env
echo "PEER_NAME=$PEER_NAME" >> /etc/etcd.env
echo "PRIVATE_IP=$PRIVATE_IP" >> /etc/etcd.env

查看vms81上的变量文件

[root@vms81 ~]# cat /etc/etcd.env
PEER_NAME=vms81.rhce.cc
PRIVATE_IP=192.168.26.81
[root@vms81 ~]#

查看vms82上的变量文件

[root@vms82 etcd]# cat /etc/etcd.env
PEER_NAME=vms82.rhce.cc
PRIVATE_IP=192.168.26.82
[root@vms82 etcd]#

步骤5:所有节点安装配置etcd
在所有节点上安装etcd

yum install etcd -y

所有节点编写etcd的启动脚本,vms81上的内容如下。

[root@vms81 ~]# cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service
Conflicts=etcd2.service

[Service]
EnvironmentFile=/etc/etcd.env
Type=notify
Restart=always
RestartSec=5s
LimitNOFILE=40000
TimeoutStartSec=0

ExecStart=/bin/etcd --name vms81 \
	--data-dir /var/lib/etcd \
	--listen-client-urls https://${PRIVATE_IP}:2379,https://127.0.0.1:2379 \
	--advertise-client-urls https://${PRIVATE_IP}:2379 \
	--listen-peer-urls https://${PRIVATE_IP}:2380 \
	--initial-advertise-peer-urls https://${PRIVATE_IP}:2380 \
	--cert-file=/etc/kubernetes/pki/etcd/server.pem \
	--key-file=/etc/kubernetes/pki/etcd/server-key.pem \
	--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
	--peer-cert-file=/etc/kubernetes/pki/etcd/peer.pem \
	--peer-key-file=/etc/kubernetes/pki/etcd/peer-key.pem \
	--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
	--initial-cluster vms81=https://192.168.26.81:2380,vms82=https://192.168.26.82:2380 \
	--initial-cluster-token my-etcd-token \
	--initial-cluster-state new \
	--client-cert-auth=false \
	--peer-client-cert-auth=false

[Install]
WantedBy=multi-user.target
[root@vms81 ~]#

vms82上的内容如下。

[root@vms82 ~]# cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service
Conflicts=etcd2.service

[Service]
EnvironmentFile=/etc/etcd.env
Type=notify
Restart=always
RestartSec=5s
LimitNOFILE=40000
TimeoutStartSec=0

ExecStart=/bin/etcd --name vms82 \
	--data-dir /var/lib/etcd \
	--listen-client-urls https://${PRIVATE_IP}:2379,https://127.0.0.1:2379 \
	--advertise-client-urls https://${PRIVATE_IP}:2379 \
	--listen-peer-urls https://${PRIVATE_IP}:2380 \
	--initial-advertise-peer-urls https://${PRIVATE_IP}:2380 \
	--cert-file=/etc/kubernetes/pki/etcd/server.pem \
	--key-file=/etc/kubernetes/pki/etcd/server-key.pem \
	--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
	--peer-cert-file=/etc/kubernetes/pki/etcd/peer.pem \
	--peer-key-file=/etc/kubernetes/pki/etcd/peer-key.pem \
	--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \
	--initial-cluster vms81=https://192.168.26.81:2380,vms82=https://192.168.26.82:2380 \
	--initial-cluster-token my-etcd-token \
	--initial-cluster-state new \
	--client-cert-auth=false \
	--peer-client-cert-auth=false

[Install]
WantedBy=multi-user.target
[root@vms82 ~]# 

在所有节点上启动etcd

systemctl daemon-reload ; systemctl start etcd

查看etcd集群健康状态。
file

2-3安装k8s集群

步骤6:建立初始化集群的初始化文件
修改config.yaml内容如下。

[root@vms81 ~]# cat config.yaml 
apiServer:
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
controlPlaneEndpoint: "192.168.26.80:6443"
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  external:
    endpoints:
    - "https://192.168.26.81:2379"
    - "https://192.168.26.82:2379"
    caFile: /etc/kubernetes/pki/etcd/ca.pem
    certFile: /etc/kubernetes/pki/etcd/client.pem
    keyFile: /etc/kubernetes/pki/etcd/client-key.pem
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.26.1
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/12
scheduler: {}
[root@vms81 ~]# 

注意这里etcd部分,指定了etcd集群每台主机的地址,以及指定了apiserver所能用的证书。

步骤7:初始化集群

kubeadm init --config=config.yaml

初始化完毕之后按提示复制kubeconfig文件,因为本机器之前用过,所以在cp的时候提示是否覆盖,输入y。

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

2-4添加第二台master

步骤8:把vms81上所需要的证书拷贝到vms82上
把所需要的证书放在aa.txt,注意这里aa.txt的内容跟方法1里的aa.txt的内容有变化。

[root@vms81 ~]# vim aa.txt 
[root@vms81 ~]# cat aa.txt 
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
/etc/kubernetes/pki/sa.key
/etc/kubernetes/pki/sa.pub
/etc/kubernetes/pki/front-proxy-ca.crt
/etc/kubernetes/pki/front-proxy-ca.key
[root@vms81 ~]# 

把aa.txt里列出的证书打包到cert.tar.gz里

tar czf cert.tar.gz -T aa.txt

查看cert.tar.gz里的内容。

[root@vms81 ~]# tar tf cert.tar.gz 
etc/kubernetes/pki/ca.crt
etc/kubernetes/pki/ca.key
etc/kubernetes/pki/sa.key
etc/kubernetes/pki/sa.pub
etc/kubernetes/pki/front-proxy-ca.crt
etc/kubernetes/pki/front-proxy-ca.key
[root@vms81 ~]# 

把cert.tar.gz拷贝到vms82是哪个。

scp cert.tar.gz 192.168.26.82:~

到vms82上,解压

tar zxf cert.tar.gz -C /

步骤8:vms82以控制节点的方式加入到集群

kubeadm join 192.168.26.80:6443 --token z1jl6r.sh3g9ebulj3b97vz --discovery-token-ca-cert-hash sha256:3c9282325e761196a06583ac1308da85c5596ed025d7bb87a0b26217ba64db52 --control-plane

之后按提示复制kubeconfig文件。

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

步骤9:验证
在vms81或者vms82上执行kubectl get nodes命令
file
把vms83加入集群,在vms83上执行如下命令

kubeadm join 192.168.26.80:6443 --token z1jl6r.sh3g9ebulj3b97vz --discovery-token-ca-cert-hash sha256:3c9282325e761196a06583ac1308da85c5596ed025d7bb87a0b26217ba64db52

再次在vms81或者vms82上验证
file
之后自行安装calico即可。

Logo

开源、云原生的融合云平台

更多推荐