背景
kubeasz是一个利用ansible-playbook基于二进制方式自动化部署和运维k8s集群的开源项目,目前该项目最新发布版本为3.3.0,基于该版本我们可以快速实现部署最高版本为1.24.1的k8s集群。
K8s HA-architecture

基于kubeasz安装的k8s高可用架构方案如上,目前kubeasz的官方文档中Node节点还使用的是haproxy处理自身高可用,但实际上kubeasz-3.3.0目前是使用kube-lb代替了haproxy,这部分内容官方还没有来得及更新,使用上留意下就可以了。
使用kubeasz默认安装的kubernetes集群主要特性如下
•etcd集群独立于kubernetes集群
•kubernetes三大组件均二进制运行
•各节点服务器都经过基本的性能基线设置,能满足常规的使用场景
•使用证书有效期为100年
•集群通过kube-lb组件实现内部高可用
•集成安装了kubernetes-dashboard,开箱即用
高可用集群所需节点配置如下
角色 | 服务器 | 描述 |
部署节点 | 10.0.1.121 | 作为宿主机通过kubeasz容器运行ansible/ezctl命令 |
etcd节点 | 10.0.1.122 10.0.1.123 10.0.1.124 | 注意etcd集群需要1,3,5,...奇数个节点,本实战安装3个节点 |
master节点 | 10.0.1.122 10.0.1.123 10.0.1.124 | 高可用集群至少2个master节点,本实战安装3个节点 |
node节点 | 10.0.1.125 10.0.1.126 10.0.1.127 | 运行应用负载的节点,节点数任意,本实战安装3个节点 |
以上服务器均是在一台普通台式机开的虚拟机,配置均是1c4g40g,最小化安装centos7.9。本次部署将以10.0.1.121作为宿主机通过kubeasz容器在线安装k8s集群,其中kubeasz使用即时的最新版本3.3.0。部署的k8s集群版本信息如下:
•k8s: v1.24.1
•etcd: v3.5.4
•containerd: 1.6.4
•flanal: v0.15.1
•dashboard: v2.5.1
以下所有操作在部署节点10.0.1.121完成。
- # 下载工具脚本ezdown,使用kubeasz版本3.3.0
- export release=3.3.0
- wget https://github.com/easzlab/kubeasz/releases/download/${release}/ezdown
- chmod +x ./ezdown
- # 使用工具脚本下载
- ./ezdown -D
./ezdown -D命令多执行几遍,直至再执行的时候不再downloading为止。这样就在/etc/kubeasz目录下下载了在线安装所有需要的脚本、二进制文件和镜像文件。
另外,通过执行./ezdown -D我们会发现docker环境也在主控宿主机安装好了,这个效果即使在做非k8集群本地化交付场景的时候也特别有用。
- [root@server121 ~]# docker version
- Client:
- Version: 20.10.16
- API version: 1.41
- Go version: go1.17.10
- Git commit: aa7e414
- Built: Thu May 12 09:14:28 2022
- OS/Arch: linux/amd64
- Context: default
- Experimental: true
-
-
- Server: Docker Engine - Community
- Engine:
- Version: 20.10.16
- API version: 1.41 (minimum version 1.12)
- Go version: go1.17.10
- Git commit: f756502
- Built: Thu May 12 09:19:16 2022
- OS/Arch: linux/amd64
- Experimental: false
- containerd:
- Version: v1.6.4
- GitCommit: 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
- runc:
- Version: 1.1.1
- GitCommit: v1.1.1-0-g52de29d7
- docker-init:
- Version: 0.19.0
- GitCommit: de40ad0
如果目标服务器可以直接连外网,那么通过./ezdown -D下载的文件足够用了,但是如果目标服务器不能连外网,那么我们还需要通过另外一个命令./ezdown -P把离线文件也下载下来,这些文件也都在/etc/kubeasz。后面我们把/etc/kubeasz这个目录打个压缩包,并和ezdown文件归档在一起后续可以直接使用。
- # 主控机设置密钥
- ssh-keygen
-
-
- # 设置免密登陆
- ssh-copy-id 10.0.1.122
- ssh-copy-id 10.0.1.123
- ssh-copy-id 10.0.1.124
- ssh-copy-id 10.0.1.125
- ssh-copy-id 10.0.1.126
- ssh-copy-id 10.0.1.127
- ./ezdown -S
- 2022-07-01 19:56:27 INFO Action begin: start_kubeasz_docker
- 2022-07-01 19:56:27 INFO try to run kubeasz in a container
- 2022-07-01 19:56:27 DEBUG get host IP: 10.0.1.121
- b2d5eeeaba3a: Loading layer [==================================================>] 5.88MB/5.88MB
- ff362123de14: Loading layer [==================================================>] 2.852MB/2.852MB
- d90070ff2c3a: Loading layer [==================================================>] 30.32MB/30.32MB
- b1ed2c7094f4: Loading layer [==================================================>] 4.608kB/4.608kB
- 9f48806e63e9: Loading layer [==================================================>] 8.55MB/8.55MB
- ab2737de92cb: Loading layer [==================================================>] 128.6MB/128.6MB
- 7a12142df705: Loading layer [==================================================>] 2.838MB/2.838MB
- Loaded image: easzlab/kubeasz:3.3.0
- d037e087572e16c07c7f5d3469decbc4cedc4aaca79dffd2d73ab2a4fa69f3c7
- 2022-06-30 20:34:24 INFO Action successed: start_kubeasz_docker
- docker exec -it kubeasz bash
- bash-5.1# ezctl new k8s-01
- 2022-07-01 19:58:27 DEBUG generate custom cluster files in /etc/kubeasz/clusters/k8s-01
- 2022-07-01 19:58:27 DEBUG set version of common plugins
- 2022-07-01 19:58:27 DEBUG cluster k8s-01: files successfully created.
- 2021-01-19 10:48:23 INFO next steps 1: to config '/etc/kubeasz/clusters/k8s-01/hosts'
- 2021-01-19 10:48:23 INFO next steps 2: to config '/etc/kubeasz/clusters/k8s-01/config.yml'
根据提示修改hosts如下,config.yml保持不变。其中hosts文件中按规划调整了etcd、kube_master、kube_node和ex_lb四处位置的服务器IP,注意这里只能使用IP,不能使用hostname;另外CONTAINER_RUNTIME应该设置为containerd,CLUSTER_NETWORK设置为flannel,其它配置可保持不变。
注意:
•生成的hosts文件里的CONTAINER_RUNTIME一定不能是docker,这个不要调整错了。
•CLUSTER_NETWORK默认是calico,但我按这个设置安装会遇到问题,所以切换成flannel了。
- # 'etcd' cluster should have odd member(s) (1,3,5,...)
- [etcd]
- 10.0.1.122
- 10.0.1.123
- 10.0.1.124
-
-
- # master node(s)
- [kube_master]
- 10.0.1.122
- 10.0.1.123
- 10.0.1.124
-
-
- # work node(s)
- [kube_node]
- 10.0.1.125
- 10.0.1.126
- 10.0.1.127
-
-
- # [optional] harbor server, a private docker registry
- # 'NEW_INSTALL': 'true' to install a harbor server; 'false' to integrate with existed one
- [harbor]
- #192.168.1.8 NEW_INSTALL=false
-
-
- # [optional] loadbalance for accessing k8s from outside
- [ex_lb]
- 10.0.1.125 LB_ROLE=backup EX_APISERVER_VIP=10.0.1.200 EX_APISERVER_PORT=8443
- 10.0.1.126 LB_ROLE=master EX_APISERVER_VIP=10.0.1.200 EX_APISERVER_PORT=8443
-
-
- # [optional] ntp server for the cluster
- [chrony]
- #192.168.1.1
-
-
- [all:vars]
- # --------- Main Variables ---------------
- # Secure port for apiservers
- SECURE_PORT="6443"
-
-
- # Cluster container-runtime supported: docker, containerd
- # if k8s version >= 1.24, docker is not supported
- CONTAINER_RUNTIME="containerd"
-
-
- # Network plugins supported: calico, flannel, kube-router, cilium, kube-ovn
- CLUSTER_NETWORK="flannel"
-
-
- # Service proxy mode of kube-proxy: 'iptables' or 'ipvs'
- PROXY_MODE="ipvs"
-
-
- # K8S Service CIDR, not overlap with node(host) networking
- SERVICE_CIDR="10.68.0.0/16"
-
-
- # Cluster CIDR (Pod CIDR), not overlap with node(host) networking
- CLUSTER_CIDR="172.20.0.0/16"
-
-
- # NodePort Range
- NODE_PORT_RANGE="30000-32767"
-
-
- # Cluster DNS Domain
- CLUSTER_DNS_DOMAIN="cluster.local"
-
-
- # -------- Additional Variables (don't change the default value right now) ---
- # Binaries Directory
- bin_dir="/opt/kube/bin"
-
-
- # Deploy Directory (kubeasz workspace)
- base_dir="/etc/kubeasz"
-
-
- # Directory for a specific cluster
- cluster_dir="{{ base_dir }}/clusters/k8s-01"
-
-
- # CA and other components cert/key Directory
- ca_dir="/etc/kubernetes/ssl"
默认安装模式是在线安装,这里我们调整为离线安装模式
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/kubeasz/clusters/k8s-01/config.yml
- docker exec -it kubeasz bash
- # 一键安装,等价于执行docker exec -it kubeasz ezctl setup k8s-01 all
- bash-5.1# ezctl setup k8s-01 all
-
-
- # 分步安装 需要分别执行01-07的yml
- # 01-创建证书和环境准备
- bash-5.1# ezctl setup k8s-01 01
- # 02-安装etcd集群
- bash-5.1# ezctl setup k8s-01 02
- # 03-安装容器运行时(docker or containerd)
- bash-5.1# ezctl setup k8s-01 03
- # 04-安装kube_master节点
- bash-5.1# ezctl setup k8s-01 04
- # 05-安装kube_node节点
- bash-5.1# ezctl setup k8s-01 05
- # 06-安装网络组件
- bash-5.1# ezctl setup k8s-01 06
- # 07-安装集群主要插件
- bash-5.1# ezctl setup k8s-01 07
- 执行一键安装,静候安装完成,显示如下就是安装好了。也可以分步安装。按照kubeasz对安装kubernetes集群的步骤拆解,一共分为7步,每一步都对应相应的安装任务,读者可以自行体验。
- PLAY RECAP *******************************************************************************************************************************************************************************************************************
- 10.0.1.122 : ok=117 changed=85 unreachable=0 failed=0 skipped=187 rescued=0 ignored=0
- 10.0.1.123 : ok=112 changed=81 unreachable=0 failed=0 skipped=169 rescued=0 ignored=0
- 10.0.1.124 : ok=112 changed=81 unreachable=0 failed=0 skipped=169 rescued=0 ignored=0
- 10.0.1.125 : ok=107 changed=74 unreachable=0 failed=0 skipped=192 rescued=0 ignored=0
- 10.0.1.126 : ok=96 changed=68 unreachable=0 failed=0 skipped=177 rescued=0 ignored=0
- 10.0.1.127 : ok=96 changed=68 unreachable=0 failed=0 skipped=177 rescued=0 ignored=0
- localhost : ok=32 changed=22 unreachable=0 failed=0 skipped=15 rescued=0 ignored=0
- 验证安装
- 登陆任意一台Master,我们确认下是否安装成功。
- # 可以看到各节点就绪 (Ready) 状态、角色、运行时间以及版本号
- [root@server122 ~]# kubectl get nodes
- NAME STATUS ROLES AGE VERSION
- 10.0.1.122 Ready,SchedulingDisabled master 10h v1.24.1
- 10.0.1.123 Ready,SchedulingDisabled master 10h v1.24.1
- 10.0.1.124 Ready,SchedulingDisabled master 10h v1.24.1
- 10.0.1.125 Ready node 10h v1.24.1
- 10.0.1.126 Ready node 10h v1.24.1
- 10.0.1.127 Ready node 10h v1.24.1
- # 可以看到scheduler/controller-manager/etcd等组件 Healthy
- [root@server122 ~]# kubectl get cs
- Warning: v1 ComponentStatus is deprecated in v1.19+
- NAME STATUS MESSAGE ERROR
- scheduler Healthy ok
- etcd-1 Healthy {"health":"true","reason":""}
- etcd-2 Healthy {"health":"true","reason":""}
- etcd-0 Healthy {"health":"true","reason":""}
- controller-manager Healthy ok
- # 可以看到kubernetes master(apiserver)组件 running
- [root@server122 ~]# kubectl cluster-info
- Kubernetes control plane is running at https://127.0.0.1:6443
- CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
- KubeDNSUpstream is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns-upstream:dns/proxy
- kubernetes-dashboard is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
- # 可以查看所有集群pod状态,默认已安装网络插件flannel、coredns、metrics-server等
- [root@server122 ~]# kubectl get po --all-namespaces
- NAMESPACE NAME READY STATUS RESTARTS AGE
- kube-system coredns-ff4774677-xm6dq 1/1 Running 0 13h
- kube-system dashboard-metrics-scraper-8c47d4b5d-lpzcd 1/1 Running 0 13h
- kube-system kube-flannel-ds-gnwvt 1/1 Running 0 13h
- kube-system kube-flannel-ds-jh87x 1/1 Running 0 13h
- kube-system kube-flannel-ds-lrlcm 1/1 Running 0 13h
- kube-system kube-flannel-ds-m7xqp 1/1 Running 0 13h
- kube-system kube-flannel-ds-nj82h 1/1 Running 0 13h
- kube-system kube-flannel-ds-xm6jc 1/1 Running 0 13h
- kube-system kubernetes-dashboard-5d46f4c997-44d4r 1/1 Running 0 13h
- kube-system metrics-server-56646b5b79-k9sdr 1/1 Running 0 13h
- kube-system node-local-dns-6dh4c 1/1 Running 0 13h
- kube-system node-local-dns-dtktz 1/1 Running 0 13h
- kube-system node-local-dns-ln9kk 1/1 Running 0 13h
- kube-system node-local-dns-mvmvf 1/1 Running 0 13h
- kube-system node-local-dns-nl7bq 1/1 Running 0 13h
- kube-system node-local-dns-tnwpj 1/1 Running 0 13h
- # 可以查看所有集群svc状态
- [root@server122 ~]# kubectl get svc --all-namespaces
- kubectl get svc --all-namespaces
- NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- default kubernetes ClusterIP 10.68.0.1
443/TCP 14h - kube-system dashboard-metrics-scraper ClusterIP 10.68.44.158
8000/TCP 14h - kube-system kube-dns ClusterIP 10.68.0.2
53/UDP,53/TCP,9153/TCP 14h - kube-system kube-dns-upstream ClusterIP 10.68.126.39
53/UDP,53/TCP 14h - kube-system kubernetes-dashboard NodePort 10.68.227.190
443:32360/TCP 14h - kube-system metrics-server ClusterIP 10.68.25.222
443/TCP 14h - kube-system node-local-dns ClusterIP None
9253/TCP
至此,我们的k8s集群安装验证成功,一套6节点的集群,从开始安装到完成大概需要10分钟。这样的效率确实是让人很满意的(笔者运行这7台虚拟机的台式机网卡网速是1000M)。
在验证安装过程查看所有集群svc状态的操作中,我们看到了默认安装了kubernetes-dashboard,我们可以通过NodePort访问https://${IP}:32360/,其中${IP}可为任一节点IP。
这里我们使用chrome浏览器访问,显示如下

随便点击页面的空白处,然后输入:thisisunsafe
页面正常打开如下

从master节点查看token并使用token登陆(这里为了方便,我们可以直接使用admin-user的token)
- # 查看内容含有token的secret
- [root@server122 ~]# kubectl get secret -n kube-system
- NAME TYPE DATA AGE
- admin-user kubernetes.io/service-account-token 3 15h
- dashboard-read-user kubernetes.io/service-account-token 3 15h
- kubernetes-dashboard-certs Opaque 0 15h
- kubernetes-dashboard-csrf Opaque 1 15h
- kubernetes-dashboard-key-holder Opaque 2 15h
- # 查看admin-user对应的token
- [root@server122 ~]# kubectl describe secret -n kube-system admin-user
- Name: admin-user
- Namespace: kube-system
- Labels:
- Annotations: kubernetes.io/service-account.name: admin-user
- kubernetes.io/service-account.uid: 1d698eb4-e299-44d7-9c04-84b8981a64df
-
-
- Type: kubernetes.io/service-account-token
-
-
- Data
- ====
- ca.crt: 1302 bytes
- namespace: 11 bytes
- token: eyJhbGciOiJSUzI1NiIsImtpZCI6IlFLdmIxYUNmclEzenhfczFWdkJySU04VF9XYm9tZzExVTlFbHBNRDJRUTgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxZDY5OGViNC1lMjk5LTQ0ZDctOWMwNC04NGI4OTgxYTY0ZGYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.a6qxey5eRrRPi7T5RSFy-mZMaAu1YsMIrBVZdbj8g0-kNC06fYLOtFIezPtp3drHSUzOz31TTSZ_0PoU4PYAS9-c_IabiMaf4qhN0BJ05JpX17SDZ5PlbD-7jh2bqpkd96tr3BDZQpb_NYk_vwiCYCItMEoHNvihjopp4lNG0cxxZEvyZ1X8wKDIQq401lO2xrfP13Y3eE3FkZYq9eQEw0RY9YOyDemMikvVWKTdTRjy9RMOG4rxRYROZMJHU_KtmOjBZp21NDVyCYnxeQfw9hLxj0roJAWEsDe_NCE4_WFm5JcAeH5tC1YaRuDhotXaeqN46lDPzB-KDBW8dB1EEQ
使用admin-user的token登陆kubernetes-dashboard,进入后显示如下

kubeasz除了用来运维x86架构kubernetes集群外,还可以在不限于如下场景发挥积极作用。
kubeasz的分步安装中,第一步是创建证书和环境准备,其中环境准备是对所有目标服务器进行一些基础设置,能够调整操作系统的性能基线,这个也是适用于非容器化环境的服务器的;第三步是安装容器运行时,可以选择docker或者containerd,只需要调整如/etc/kubeasz/clusters/${CLUSTER_NAME}/hosts文件中的CONTAINER_RUNTIME为docker就可以后,再执行第三步,我们就可以在所有的目标服务器统一安装docker。
当下的kubeasz其实是只支持x86服务器架构的,并不能直接支持arm架构服务器。但笔者相信通过一定的改造,其安装包也是可以适配arm架构服务器的。笔者已经做过如下的简单尝试,有真实需求的读者可以继续深入。
笔者在kubeasz的在线安装包上了做了一些改动,比如置换cfssl、cfssl-certinfo和cfssljson为适配arm架构的二进制;比如下载了kubectl的arm版本二进制命名kubectl-arm64后放在/etc/kubeadz/bin目录下,同时修改了/etc/kubeadz/roles若干的roles定义等等后使用自行构建的适配arm架构的镜像pi4k8s/easzlab-kubasz:3.3.0在树莓派PI4B(raspios-arm64)上成功远程部署了一套x86架构的k8s集群。
本次实战表明,我们使用kubeasz可以在很短的时间内部署一套二进制部署的次新高版本x86架构多master高可用k8s集群,在这个基础上,我们只需要集成helm、ingress、prometheus、storage等组件后,这套集群就可以迅速交付使用。
众所周知,在k8s集群应用和实践过程中,一般业务开发工程师除了会使用一些简单容器化命令外,对于k8s集群本身或者关联的问题,往往会觉得很棘手,需要协调k8s运维工程师深度协作才能分析、定位和解决,究其原因,就是k8s集群的搭建和运维涉及组件众多,关系复杂,业务开发工程师在遇到问题的时候,总难免畏手畏脚,非常担心操作失当,导致更复杂问题的出现,典型的就是把k8s集群弄得不正常,又非常不好协调k8s运维工程师处理,项目进展因此雪上加霜。因为在大多数公司,业务开发工程师和运维工程师分属不同的团队或者部门,协调起来并不容易;另外其实还有些公司可能连做k8s运维的工程师都没有,更谈不上协调了,这时候就只能靠业务开发工程师自行探索解决了。kubeasz这样的神器,除了能提高k8s集群交付效率外,也正因为大幅度降低了k8s集群构建成本,从而也相应减少了业务开发工程师面对k8s集群的畏难情绪,提升了学习和使用热情,对其培养k8s环境的熟悉和敏感程度非常有价值,而这一点其实非常重要。
另外,kubeasz除了用来运维x86架构kubernetes集群外,也可以扩展到其他场景,比如做docker的离线交付,比如做ARM架构适配改造等。
作者介绍:
崔莹峰,一名70后程序员,拥有10多年工作经验,长期从事 Java 开发,架构设计,容器化等相关工作。精通Java,熟练使用Maven、Jenkins等Devops相关工具链,擅长容器化方案规划、设计和落地。
往期推荐:

长按二维码关注
以分布式设计、架构、体系思想为基础,兼论研发相关的点点滴滴,不限于代码、质量体系和研发管理。