基于ansible的自动化二进制模式部署高可用Kubernetes集群

【说明】

本文档详细描述了在openEuler 22.03 LTS上通过ansible以二进制模式自动化部署高可用Kubernetes集群(适用k8s v1.26版本)。

本文档参考了小陈运维的ansible剧本,并进行了适当改造,使之适用于openEuler 22.03 LTS,并改用nginx实现高可用;仅采用containerd作为容器运行时;采用calico网络插件;采用yaml配置文件自动部署dashboard。改造后的ansible剧本在华为私有云中的ECS测试通过,ECS系统统一采用openEuler 22.03 LTS SP1(根据小陈运维的说法,也可以支持CentOS 7、CentOS 8和Ubuntu,因此改造后的剧本理论上也可以支持)。

改造后的联网部署的ansible剧本已发布到gitee,联网部署仓库。

适用于内部离线部署的ansible剧本可参考仓库:内网部署仓库

手动部署可参见:手动部署k8s集群

1 部署环境说明

1.1 主机清单

本文档采用6台华为ECS进行部署,其中一台为ansible主控节点,另外5台为k8s节点,基本情况如下表所示。

主机名称 IP地址 说明 软件
ansible-controller 192.168.1.100 ansible主控节点 ansible 2.9.27、git、sshpass
k8s-master-1 192.168.1.31 master节点 kube-apiserver、kube-controller-manager、kube-scheduler、etcd、
kubelet、kube-proxy、nfs-client、nginx
k8s-master-2 192.168.1.32 master节点 kube-apiserver、kube-controller-manager、kube-scheduler、etcd、
kubelet、kube-proxy、nfs-client、nginx
k8s-master-3 192.168.1.33 master节点 kube-apiserver、kube-controller-manager、kube-scheduler、etcd、
kubelet、kube-proxy、nfs-client、nginx
k8s-node-1 192.168.1.34 node节点 kubelet、kube-proxy、nfs-client、nginx
k8s-node-2 192.168.1.35 node节点 kubelet、kube-proxy、nfs-client、nginx

1.2 主要软件清单

k8s节点涉及的主要软件及其版本如下表所示。

软件 版本
kernel 5.10.0
openEuler 22.03 LTS
etcd v3.5.6
containerd 1.6.15
cfssl v1.6.3
cni 1.1.1
crictl 1.24.1

1.3 网络规划

k8s主机:192.168.1.0/24

service:10.96.0.0/12

pod:172.16.0.0/12

注:在开始以下操作前,请确保k8s各节点及ansible主控节点能访问Internet。

2 部署前准备工作

本节操作在专用的ansible主控节点上操作完成。

2.1 安装ansible软件包

openEuler默认已配置好yum软件仓库,在确认ansible主控节点可连网的情况下,直接安装ansible软件包即可。

注:若是内网部署,请先为主控节点配置好yum软件仓库,再安装软件包。

[root@ansible-controller ~]# dnf -y install ansible

2.2 配置ansible主机清单

其中的IP地址可根据自身情况修改。

[root@ansible-controller ~]# vim /etc/ansible/hosts 

[kube_pki]
192.168.1.31

[etcd]
192.168.1.31 hostname=etcd-1
192.168.1.32 hostname=etcd-1
192.168.1.33 hostname=etcd-1

[kube_master]
192.168.1.31 hostname=k8s-master-1
192.168.1.32 hostname=k8s-master-2
192.168.1.33 hostname=k8s-master-3

[kube_node]
192.168.1.34 hostname=k8s-node-1
192.168.1.35 hostname=k8s-node-2

[chrony]
192.168.1.31

2.3 克隆仓库

ansible剧本文件已上传至gitee,点击该链接可查看。

可用git工具将其克隆至本地,操作如下:

# 安装git
[root@ansible-controller ~]# dnf -y install git

# 克隆下载文件
[root@ansible-controller ~]# git clone https://gitee.com/ptu706/k8s

# 查看
[root@ansible-controller ~]# ll

# 切换至目标目录
[root@ansible-controller ~]# cd k8s

2.4 配置免密SSH连接

2.4.1 生成ssh密钥

# 安装sshpass软件包
[root@ansible-controller k8s]# dnf -y install sshpass

# 生成密钥
[root@ansible-controller k8s]# ssh-keygen -f /root/.ssh/id_rsa -P ''

2.4.2 编辑和创建Shell脚本 

脚本中的IP地址可根据自身情况修改。

# 创建或编辑文件
[root@ansible-controller k8s]# vim ssh.sh 

export IP="192.168.1.31 192.168.1.32 192.168.1.33 192.168.1.34 192.168.1.35"
export SSHPASS=Mima12346789#
for HOST in $IP
do
    sshpass -e ssh-copy-id -o StrictHostKeyChecking=no $HOST
done

2.4.3 执行脚本

[root@ansible-controller k8s]# bash ssh.sh

2.5 下载软件包

在files目录下的download.sh文件中,列出了需要下载的文件及其版本,若有需要修改,可在该文件中修改,然后执行该shell文件下载软件包。

[root@ansible-controller k8s]# cd files/
[root@ansible-controller files]# bash download.sh 


# 下载完成后返回至父目录
[root@ansible-controller files]# cd .. 

注:建议多执行一两次下载的Shell脚本,确保文件全部成功下载。 

2.6 编辑证书环境变量

在pki/files/pki.sh文件中包括了主节点的IP地址,可根据自身情况修改。

[root@ansible-controller k8s]# vim pki/files/pki.sh 

#!/bin/bash

export k8s_master01="192.168.1.31"
export k8s_master02="192.168.1.32"
export k8s_master03="192.168.1.33"
……此处省略后续内容……

2.7 修改kube-nginx环境变量

在nginx/files/kube-nginx.conf配置文件中包括了k8s主节点的IP地址,可根据自身情况修改。

[root@ansible-controller k8s]# vim nginx/files/kube-nginx.conf
……此处省略部分内容……
    server 192.168.1.31:6443        max_fails=3 fail_timeout=30s;
    server 192.168.1.32:6443        max_fails=3 fail_timeout=30s;
    server 192.168.1.33:6443        max_fails=3 fail_timeout=30s;
……此处省略后续内容……

2.8 修改ansible变量

main.yaml文件中包含了k8s各节点的IP地址,以及SSH登录这些节点的账号root及其密码(均统一指定为相同的密码)。

[root@ansible-controller k8s]# vim main.yaml 

……此处省略部分输出……
#     all 写所有IP地址
#     passed 是所有的系统密码,此密码需要所有主机相同
- hosts:
  - etcd
  - kube_master
  - kube_node
  remote_user: root
  vars:
    - all: 192.168.1.31 192.168.1.32 192.168.1.33 192.168.1.34 192.168.1.35
    - passwd: Mima12346789#

……此处省略后继内容……

2.9 设置主机映射

修改local_init/files/hosts.sh文件中k8s主机对应的IP地址。

[root@ansible-controller k8s]# vim local_init/files/hosts.sh 

cat >> /etc/hosts << EOF
192.168.1.31   k8s-master-1
192.168.1.32   k8s-master-2
192.168.1.33   k8s-master-3
192.168.1.34   k8s-node-1
192.168.1.35   k8s-node-2
EOF

3 自动化部署

注:强烈建议在执行以下操作前,为k8s各节点做好系统快照,以便在需要时可随时回滚,特别是因为网络或其它原因导致安装失败时需要恢复系统后再次重新部署。

在ansible主控节点上执行剧本文件,开始自动化部署。

[root@ansible-controller k8s]# ansible-playbook main.yaml

稍候十余分钟后,最后显示的消息应如下所示。

PLAY RECAP **************************************************************************************************************************************************
192.168.1.31               : ok=90   changed=80   unreachable=0    failed=0    skipped=27   rescued=0    ignored=0   
192.168.1.32               : ok=61   changed=54   unreachable=0    failed=0    skipped=25   rescued=0    ignored=0   
192.168.1.33               : ok=61   changed=54   unreachable=0    failed=0    skipped=25   rescued=0    ignored=0   
192.168.1.34               : ok=45   changed=41   unreachable=0    failed=0    skipped=23   rescued=0    ignored=0   
192.168.1.35               : ok=45   changed=41   unreachable=0    failed=0    skipped=23   rescued=0    ignored=0  

4 集群验证

完成自动化部署后,等候大约10-15分钟,甚至更久一些(内网部署非常快,1-2分钟即可),Pod才可能成功拉取并启动,这时才能看到k8s集群资源和服务的正常状况。

以下操作在任一个k8s主节点上操作完成,请注意Shell命令提示符。

4.1 查看集群

4.1.1 查看集群节点

要求能显示集群所有节点,且其状态均为Ready。

[root@k8s-master-1 ~]# kubectl get nodes
NAME           STATUS   ROLES    AGE   VERSION
k8s-master-1   Ready       11m   v1.26.0
k8s-master-2   Ready       11m   v1.26.0
k8s-master-3   Ready       11m   v1.26.0
k8s-node-1     Ready       11m   v1.26.0
k8s-node-2     Ready       11m   v1.26.0

4.1.2 查看集群Pod

除ingress-nginx-admission-开头的1~2个Pod外,要求所有其它Pod的状态为Running,READY为1/1。

[root@k8s-master-1 ~]# kubectl get pod -A -owide
NAMESPACE       NAME                                        READY   STATUS      RESTARTS   AGE   IP             NODE           NOMINATED NODE   READINESS GATES
ingress-nginx   ingress-nginx-admission-patch-vk8t6         0/1     Completed   0          12m   10.88.0.7      k8s-node-1                
ingress-nginx   ingress-nginx-controller-64668d8c7b-44w98   1/1     Running     0          12m   172.17.201.1   k8s-node-1                
kube-system     calico-kube-controllers-75679fbd89-4bjnd    1/1     Running     0          12m   10.88.0.5      k8s-node-1                
kube-system     calico-node-6x7nz                           1/1     Running     0          12m   192.168.1.31   k8s-master-1              
kube-system     calico-node-dc8t4                           1/1     Running     0          12m   192.168.1.35   k8s-node-2                
kube-system     calico-node-hrx5s                           1/1     Running     0          12m   192.168.1.32   k8s-master-2              
kube-system     calico-node-twpqp                           1/1     Running     0          12m   192.168.1.34   k8s-node-1                
kube-system     calico-node-whvxx                           1/1     Running     0          12m   192.168.1.33   k8s-master-3              
kube-system     calico-typha-75ffcf7dcc-jdd94               1/1     Running     0          12m   192.168.1.34   k8s-node-1                
kube-system     coredns-58c7668f8d-9wq9j                    1/1     Running     0          12m   10.88.0.2      k8s-node-1                
kube-system     default-http-backend-6f89b4654f-z7wgw       1/1     Running     0          12m   10.88.0.3      k8s-node-1                
kube-system     kubernetes-dashboard-549694665c-4xw6k       1/1     Running     0          12m   10.88.0.6      k8s-node-1                
kube-system     metrics-server-7888bbf49b-cjqhs             1/1     Running     0          12m   192.168.1.32   k8s-master-2              

4.1.3 查看集群服务

[root@k8s-master-1 ~]# kubectl get svc -A
NAMESPACE       NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
default         kubernetes                           ClusterIP   10.96.0.1                443/TCP                      16m
ingress-nginx   ingress-nginx-controller             NodePort    10.101.232.208           80:30359/TCP,443:31826/TCP   15m
ingress-nginx   ingress-nginx-controller-admission   ClusterIP   10.97.22.157             443/TCP                      15m
kube-system     calico-typha                         ClusterIP   10.108.92.67             5473/TCP                     15m
kube-system     default-http-backend                 ClusterIP   10.110.142.210           80/TCP                       15m
kube-system     kube-dns                             ClusterIP   10.96.0.10               53/UDP,53/TCP,9153/TCP       15m
kube-system     kubernetes-dashboard                 NodePort    10.97.12.241             443:31080/TCP                15m
kube-system     metrics-server                       ClusterIP   10.100.91.208            443/TCP                      15m

4.1.4 查看集群命名空间

[root@k8s-master-1 ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   17m
ingress-nginx     Active   15m
kube-node-lease   Active   17m
kube-public       Active   17m
kube-system       Active   17m

4.2 部署pod

4.2.1 部署busybox

利用busybox.yaml文件创建一个pod。

[root@k8s-master-1 ~]# kubectl apply -f busybox.yaml 
pod/busybox created

4.2.2 查看pod运行状态

1-2分钟后,查看pod运行的运行状况如下所示。

[root@k8s-master-1 ~]# kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          2m15s

若提示错误,可执行【kubectl describe pod busybox】命令或者【kubectl logs -f pod busybox】查看失败原因。有时候可执行【kubectl delete -f busybox.yaml】删除busybox,然后重新创建,或者将busybox.yaml文件中的busybox的版本修改为1.28,或者1.28.4,然后重新部署即可。

4.3 域名解析测试

4.3.1 命名空间内部的域名解析测试

默认情况下,在default命名空间会有一个kubernetes服务,如下所示。

[root@k8s-master-1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1            443/TCP   25m

该服务与前面的busybox在同一命名空间,利用busybox测试能否解析kubernetes服务。

[root@k8s-master-1 ~]# kubectl exec busybox -n default -- nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

若出现以下的nslookup: can't resolve 'kubernetes的错误提示。

[root@k8s-master-1 ~]# kubectl exec busybox -n default -- nslookup kubernetes
nslookup: can't resolve 'kubernetes'
Server:    10.96.0.10
Address 1: 10.96.0.10

command terminated with exit code 1

可执行【kubectl delete pod coredns容器名 -n kube-system】删除coredns开头的Pod,系统会自动再新建一个该类Pod,执行【kubectl get pod -A】命令查看Pod状态,待到该Pod状态为running后再测试即可(具体原因不详)。

4.3.2 跨名称空间的域名解析

执行【kubectl get svc -A】可查看所有名称空间下的服务,如下所示。

[root@k8s-master-1 ~]# kubectl get svc -A
NAMESPACE       NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
default         kubernetes                           ClusterIP   10.96.0.1                443/TCP                      38m
ingress-nginx   ingress-nginx-controller             NodePort    10.97.14.31              80:31574/TCP,443:32510/TCP   36m
ingress-nginx   ingress-nginx-controller-admission   ClusterIP   10.105.123.151           443/TCP                      36m
kube-system     calico-typha                         ClusterIP   10.97.17.197             5473/TCP                     37m
kube-system     default-http-backend                 ClusterIP   10.103.117.233           80/TCP                       36m
kube-system     kube-dns                             ClusterIP   10.96.0.10               53/UDP,53/TCP,9153/TCP       37m
kube-system     kubernetes-dashboard                 NodePort    10.107.195.56            443:31080/TCP                36m
kube-system     metrics-server                       ClusterIP   10.100.157.45            443/TCP                      36m

可见kube-system名称空间下有一个名为kube-dns的服务,可利用busybox解析该服务,如下所示。

[root@k8s-master-1 ~]# kubectl exec busybox -n default -- nslookup kube-dns.kube-system
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kube-dns.kube-system
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

4.4 测试服务访问

4.4.1 测试访问服务端口

从前面可以看到kubernetes服务的集群IP地址为10.96.0.1,服务端口为443/TCP,可在任意一个k8s节点上测试访问该服务端口,如下所示。

[root@k8s-master-1 ~]# telnet 10.96.0.1 443
Trying 10.96.0.1...
Connected to 10.96.0.1.
Escape character is '^]'.

4.4.2 测试访问DNS服务端口

从前面查看服务可看到kube-dns服务的集群IP地址为10.96.0.10,服务端口为53,可在任意一个k8s节点上测试访问该服务问口,如下所示。

[root@k8s-node-2 ~]# telnet 10.96.0.10 53
Trying 10.96.0.10...
Connected to 10.96.0.10.
Escape character is '^]'.
Connection closed by foreign host.


[root@k8s-node-2 ~]# curl 10.96.0.10:53
curl: (52) Empty reply from server

4.5 测试Pod与K8s节点间的连通性

正常情况下,Pod与k8s节点之间要相通,执行【kubectl get pod -owide】可查看当前命名空间下的Pod详情,包括其所在k8s节点和IP地址,如下所示。

[root@k8s-master-1 ~]# kubectl get pod -owide
NAME      READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
busybox   1/1     Running   0          24m   172.17.251.193   k8s-master-1              

执行【kubectl get pod -owide -n kube-system】可查看kube-system命名空间下的Pod详情,包括其所在k8s节点和IP地址,如下所示。

[root@k8s-master-1 ~]# kubectl get pod -owide -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-75679fbd89-85t5w   1/1     Running   0          52m   10.88.0.5        k8s-node-1                
calico-node-845n8                          1/1     Running   0          52m   192.168.1.31     k8s-master-1              
calico-node-g44rx                          1/1     Running   0          52m   192.168.1.33     k8s-master-3              
calico-node-nx54k                          1/1     Running   0          52m   192.168.1.34     k8s-node-1                
calico-node-srns9                          1/1     Running   0          52m   192.168.1.32     k8s-master-2              
calico-node-v559h                          1/1     Running   0          52m   192.168.1.35     k8s-node-2                
calico-typha-75ffcf7dcc-d5sc5              1/1     Running   0          52m   192.168.1.34     k8s-node-1                
coredns-58c7668f8d-sm2sc                   1/1     Running   0          20m   172.19.196.193   k8s-master-3              
default-http-backend-6f89b4654f-7gppl      1/1     Running   0          52m   10.88.0.4        k8s-node-1                
kubernetes-dashboard-549694665c-n4zgh      1/1     Running   0          52m   10.88.0.6        k8s-node-1                
metrics-server-7888bbf49b-gqz6j            1/1     Running   0          52m   192.168.1.31     k8s-master-1              

执行【kubectl exec -ti busybox -- /bin/sh】命令可进入busybox容器内部,然后测试ping其它Pod的IP地址,比如busybox在k8s-master-1,而kubernetes-dashboard容器在k8s-node-1,可测试busybox与节点k8s-node-1之间的连通性,如下所示。

[root@k8s-master-1 ~]# kubectl exec -it busybox -- /bin/sh
/ # ping -c3 192.168.1.34
PING 192.168.1.34 (192.168.1.34): 56 data bytes
64 bytes from 192.168.1.34: seq=0 ttl=63 time=0.449 ms
64 bytes from 192.168.1.34: seq=1 ttl=63 time=0.223 ms
64 bytes from 192.168.1.34: seq=2 ttl=63 time=0.207 ms

--- 192.168.1.34 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.207/0.293/0.449 ms

注意:Pod与Pod之间有可能是不通的,比如busybox容器与kubernetes-dashboard容器的IP地址就不通,如下所示。

/ # ping 10.88.0.6
PING 10.88.0.6 (10.88.0.6): 56 data bytes
^C
--- 10.88.0.6 ping statistics ---
85 packets transmitted, 0 packets received, 100% packet loss

4.6 测试部署ingress-demo-app

4.6.1 部署ingress-demo-app

[root@k8s-master-1 ~]# kubectl  apply -f ingress-demo-app.yaml
deployment.apps/hello-server created

4.6.2 查看

1、查看Pod

稍候片刻后,执行【kubectl get pod -owide】命令可查看到4个Pod,并分布部署在不同的节点上,如下所示:

[root@k8s-master-1 ~]# kubectl get pod -owide
NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
hello-server-6d9d5d86c9-kdc9h   1/1     Running   0          11m   172.17.251.194   k8s-master-1              
hello-server-6d9d5d86c9-p8bht   1/1     Running   0          11m   172.19.196.194   k8s-master-3              
nginx-demo-655bc4c9db-kd6ql     1/1     Running   0          11m   172.17.201.1     k8s-node-1                
nginx-demo-655bc4c9db-ztg2s     1/1     Running   0          11m   172.23.152.129   k8s-master-2              

2、查看应用

执行【kubectl get ingress】命令ingress-demo-app的状况,如下所示。 

[root@k8s-master-1 ~]# kubectl get ingress
NAME               CLASS   HOSTS                            ADDRESS        PORTS   AGE
ingress-host-bar   nginx   hello.ptuxgk.cn,demo.ptuxgk.cn   192.168.2.33   80      12m

3、查看服务端口

执行【kubectl get svc -A | grep ingress】可过滤查看ingress端口,如下所示。

[root@k8s-master-1 ~]# kubectl get svc -A | grep ingress
ingress-nginx   ingress-nginx-controller             NodePort    10.99.182.49             80:30709/TCP,443:31642/TCP   42m
ingress-nginx   ingress-nginx-controller-admission   ClusterIP   10.111.187.62            443/TCP                      42m

5 测试dashboard

5.1 获取账号token

在自动化部署时默认在kube-system命名空间创建一个管理账号admin-user,并将其与集群管理角色进行了绑定,现只需要获得该账号的token就可以访问。

[root@k8s-master-1 ~]# kubectl -n kube-system create token admin-user
eyJhbGciOiJSUzI1NiIsImtpZCI6IkYzREpjUUlDdkVCYS1Tc1Z1emFKMUdQQmJUa2ZIM25sQndrWUxjQTYwNGcifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlCm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjgwNjk1MTEyLCJpYXQiOjE2ODA2OTE1MTIsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJhZG1pbi11c2VyIiwidWlkIjoiNjYyYjNjYmYtZWRmOC00YjE0LTk1OTQtYWQ5MGNkODIxZDVhIn19LCJuYmYiOjE2ODA2OTE1MTIsInN1YiI6Inn5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbi11c2VyIn0.S63invWZYZ1hnxnQ0SeyBT7EKEcx2NhEc7bLlkRufLVmcKN64OGKI3PxO_23nVnc9vlhhddpQPXYfJT0EudT4RNaJt9LSiML-w0kwQEWAS3yuQCv4_1a2hfPo9B0YIR3kkOaOu7Az1woqCquNt_VnGFGZexpSn8L-cZo7nyzPqr8WsNq5y3jU1Qtt8MkT78E-gzjsUIeCax6SX8wjeUSq4Rsyi_URnx_YLj0M6UrTWkTCEmjr2GA1DIOV8Kvwec9a1f2Matq3KUZEcMjHwH6JbGwBeCxQ1i5Wc0YI0GSZsMNkOG6Hh_q_Ot7Sl25_Tmx6P0PojfSyRvXqHCGMsU5QQ

5.2 测试访问

复制上面的token,访问URL地址:https://dashboard容器所在节点IP地址:31080,如下所示。

基于ansible的自动化二进制模式部署高可用Kubernetes集群_第1张图片

粘贴前面生成的token,登录成功后的效果如下图所示。

基于ansible的自动化二进制模式部署高可用Kubernetes集群_第2张图片

在k8s上部署应用可参见: 分布式部署gpmall Web应用系统

你可能感兴趣的:(Kubernetes,kubernetes,ansible,自动化)