一、 写作背景
近来工作需要,预将公司现有应用服务 Docker
化,并使用 Kubernetes
进行统一资源编排,现将部署过程记录一下。
本次构建环境为内网 UAT 环境,尽量按生产可用进行搭建,本集群采用三主六从服务架构(从服务器可以根据实际使用情况进行增减,主服务器最好是三台),为达到快速部署,基础软件环境(系统初始化)采用 Ansible
的 playbook
方式进行部署。
二、 系列文章
- 快速搭建Kubernetes高可用集群一 基础环境初始化
- 快速搭建Kubernetes高可用集群二 Kubeadm 初始化集群
- 快速搭建Kubernetes高可用集群三 Ingress、Dashboard、Metrics-server
- 快速搭建Kubernetes高可用集群四 Rook-Ceph
- 快速搭建Kubernetes高可用集群五 Harbor
- 快速搭建Kubernetes高可用集群六 Prometheus
- 快速搭建Kubernetes高可用集群七 ELK-stack
三、 环境准备
3.1 整体架构规划
服务器名称 | 服务器 IP | 安装软件 | 服务器功能 |
---|---|---|---|
kube-m1 | 172.17.0.151 | kubeadm、kubelet、docker、kubectl、etcd、haproxy、keepalived、cfssl | k8s主节点之一、etcd节点之一、主管理平台 |
kube-m2 | 172.17.0.152 | kubeadm、kubelet、docker、kubectl、etcd、haproxy、keepalived | k8s主节点之一、etcd节点之一 |
kube-m3 | 172.17.0.153 | kubeadm、kubelet、docker、kubectl、etcd、haproxy、keepalived | k8s主节点之一、etcd节点之一 |
kube-n1 | 172.17.0.154 | kubelet、docker、 | k8s 普通节点,服务应用主要部署服务器,要求配置尽可能高 |
kube-n2 | 172.17.0.155 | kubelet、docker、 | k8s 普通节点,服务应用主要部署服务器,要求配置尽可能高 |
kube-n3 | 172.17.0.156 | kubelet、docker、 | k8s 普通节点,服务应用主要部署服务器,要求配置尽可能高 |
kube-n4 | 172.17.0.157 | kubelet、docker、 | k8s 普通节点,服务应用主要部署服务器,要求配置尽可能高 |
kube-n5 | 172.17.0.158 | kubelet、docker、 | k8s 普通节点,服务应用主要部署服务器,要求配置尽可能高 |
kube-n6 | 172.17.0.159 | kubelet、docker、 | k8s 普通节点,服务应用主要部署服务器,要求配置尽可能高 |
VIP | 172.17.0.150 | 虚拟 IP | 通过 haproxy、keepalived 在三台 Master 节点进行负载,所有kubernetes 的API 访问均基于此IP |
3.2 系统要求
- 本文使用
Linux
的分发版Centos7.8
最小化安装,请参考{% post_link CentOS7系统安装 CentOS7系统安装 %}
,也可以使用其它更快捷的方式安装,比如我是在内网搭建了一套{% post_link 搭建Cobbler服务安装Linux系统 Cobbler 系统 %}
用于安装 Linux系统。 - 升级系统内核到最新(系统初始化过程中会自动执行)。
四、 软件安装
4.1 操作流程
- 找一台服务器安装
Ansible
做为管理机,并对服务器做{% post_link Linux下SSH免密登录 免密登录 %}
操作 - 下载git项目 kubeadm-install
- 进行目录执行
ansible-playbook
命令,完成系统初始化 - 执行
kubeadm init
命令,初始化 Kubernetes 集群系统 - 执行
kubeadm join
命令,连接其它主节点或普通节点到 kubernetes 集群系统 - 执行
kubectl
系列命令,操作 kubernetes 集群
4.2 项目修改内容
4.2.1、下载项目并进入目录修改
# 下载 git 项目
git clone https://gitee.com/fcu3dx/kubeadm-install.git
cd kubeadm-install
4.2.2、 修改 hosts 文件内容为自己的服务器相关信息
vim hosts
# [ka] 所有服务器均需进行操作
# IP 地址 hostname 为每台服务器设置计算机名,最好是自建内网 DNS 的域名,后面各种项目中会使用
[ka]
172.17.0.151 hostname=kube-m1.gxsk.uat
172.17.0.152 hostname=kube-m2.gxsk.uat
172.17.0.153 hostname=kube-m3.gxsk.uat
172.17.0.154 hostname=kube-n1.gxsk.uat
172.17.0.155 hostname=kube-n2.gxsk.uat
172.17.0.156 hostname=kube-n3.gxsk.uat
172.17.0.157 hostname=kube-n4.gxsk.uat
172.17.0.158 hostname=kube-n5.gxsk.uat
172.17.0.159 hostname=kube-n6.gxsk.uat
# [etcd] 这里为 k8s 的 Master 主机,需要三台
# etcd_name 区分 etcd 服务名
# haproxy_keepalived k8s 的 Master 主机,一主两从
# 和上面的 ETCD 在同一台服务器上,主要是为三台主机做负载及反向代理
# node_state 节点属性,MASTER 为主,BACKUP 为从
# node_priority 节点优先级,数字越大优先级越高。
[etcd]
172.17.0.151 etcd_name=GxEtcdProc01 node_state=MASTER node_priority=100
172.17.0.152 etcd_name=GxEtcdProc02 node_state=BACKUP node_priority=90
172.17.0.153 etcd_name=GxEtcdProc03 node_state=BACKUP node_priority=80
4.2.3、主目录中 kernelup.yml 说明
对所有服务器执行此脚本,升级所有相关服务器的内核到最新版本,该 playbook 对应项目 roles/cfssl
,其执行结果为:
- 备份yum源
- 添加 kernel-ml 内核 YUM 源
- 卸载相关软件以便下一步安装
- 升级到 Linux 最新内核并安装相关软件
- 设置内核启动顺序为
0
即最后安装的内核 - 使内核启动顺序的修改生效
- 如果服务器在国内,为了访问速度,添加新的 YUM 源,如果在国外,请注释此步骤并手动恢复第一步备份的源。
- 重启服务器使内核生效。
4.2.4、 主目录中main.yml文件中 playbook 说明
4.2.4.1、安装 cfssl 工具项目
目标服务器: Master 集群中的第一台服务器
vars: 对etcd 的 ssl 证书生效的服务器 IP 或域名,可以使用 *.xxx.xxx泛域名
执行内容:
- 创建文件存储目录
- 复制相关文件到目标服务器,包括
cfssl_linux-amd64
,cfssljson_linux-amd64
,helm
三个可执行文件,ca-config.json
,etcd-ca-csr.json
,两个 CA 证书配置文件,可以进入目录修改这两个文件为自己的内容,需要注意不要破坏原有格式。 - 生成
CA 证书
和Cert 证书
及相关key 文件
- 生成 ssh 证书
- 复制证书文件到 Ansible 服务器的指定目录中,便于后续使用。包括
etcd-ca-key.pem
,etcd-ca.pem
,etcd-key.pem
,etcd.pem
四个 Kubernetes(etcd) 相关的 CA 证书,id_rsa
,id_rsa.pub
两个服务器间互访的公私钥证书 - 删除目标服务器的多余的临时文件
- 生效 helm 命令的自动补全
4.2.4.2、配置基础环境
目标服务器: 针对所有服务器,部分仅需要安装在 Master 服务器上的内容,在 rolse 中使用 when: “‘kube-m’ in ansible_hostname” 判断
vars: 详细内容见文件内注释说明
- podSubnet: 10.244.0.0/16 ,如非必要,请不要修改这个地址,否则会造成后续安装不好 Coredns 及 flannel 插件
- kubernetesVersion: v1.18.6 目前版本是 v1.18.6 建议不要修改这个版本,最好是系统整体搭建完成后,使用
kubeadm upgrade
命令升级,否则需要修改的地方太多了。 - etcd_endpoints: 三个 ETCD 的访问地址中间注意需要加
/n
和四个空格
执行内容:
1、sethost
- 重命名服务器
- 复制文件,包括id_rsa、id_rsa.pub两个主机免密互认文件,hosts文件(如果没有内网 DNS服务器,一定要使用此文件并要和主目录中的文件设置成一样),k8s.conf、ipvs.modules等内核服务开启配置文件,chrony.conf时间同步文件(这里使用的是阿里云授时服务器,可以自行更改第一行地址)
- 设置服务器间互访
- 关闭防火墙(firewalld)
- 关闭 selinux
- 关闭磁盘缓存
- 使用 modprobe 载入相关模块,这里是
br_netfilter
- 执行 sysctl 命令操作内核配置
- 执行网络相关配置 ipvs.modules
- 安装 chrony 服务并启动
2、docker-yum-soft
- 新增 docker-ce 的 YUM 源(这里是清华源,可以更改为其它源)
- 更新 yum 缓存
- 安装基础软件,包括 epel-release、device-mapper-persistent-data、lvm2、wget、ipvsadm、docker-ce
- 创建 docker 相关目录
- 根据模板生成 daemon.json 文件
- 启动 docker
3、k8s-yum-soft
- 新增 kubernetes 的 YUM 源
- 更新 yum 缓存
- 安装基础软件,包括kubelet、kubeadm、kubectl、kubernetes-cni
- 创建 k8s 相关的目录
- 根据模板生成kubeadm-config.yaml 文件,用于后面的
kubeadm init
的部署,仅复制到 Master 服务器节点 - 因部分 Docker image 访问比较慢,所以提前下载到本地,在所有节点下载 kube-proxy pause flannel 这几个镜像
- 在 Master节点下载 kube-apiserver、kube-controller-manager、kube-scheduler、etcd、coredns 这几个镜像
- 复制 kube-flannel.yml 10-flannel.conflist 这两个 flannel 网络插件配置文件
- 启动 kubelet 服务
- 生效 kubelet、kubeadm 命令的自动补全
4.2.4.3 安装 ETCD
目标服务器: 三台 Master 节点,在三台 Master 节点安装 ETCD 并启动、使用 haproxy 和 keepalived 虚拟出 VIP 和服务。
vars:
- etct_init_cluster_list: etcd 集群节点,配置于 ETCD 的配置文件,用于组建 ETCD 集群
- apiserver_ip: 提供服务的虚拟 IP
- haproxy_list: haproxy 监控的节点及端口
执行内容:
1、etcd
- 安装 ETCD
- 创建 ETCD 相关目录
- 复制 ETCD 相关的证书文件到指定目录(3.2.4.1步骤中生成的)
- 根据模板生成 etcd.conf 文件
- 启动 ETCD 服务
2、haproxy
- 安装 harpoxy 和 keepalived
- 根据模板配置 keepalived.conf 和 haproxy.cfg 文件,配置两个服务
- 复制 haproxy 检测脚本到指定目录
- 启动 haproxy 和 keepalied 服务
4.3 执行 ansible-playbook 命令
1、升级内核
ansible-playbook -i hosts kernelup.yml -vv
命令执行完毕后,系统会自动重启,待重启完成后可以看到,内核版本已经升级到最新了。
2、初始化系统
ansible-playbook -i hosts main.yml -vv
五、问题
系统安装完成后,docker haproxy keepalived etcd 等服务可以正常启动,而 kubelet 未正常启动,通过 journalctl -xefu kubelet 命令或者 tail -f /var/log/message 命令查看日志得出
Aug 12 09:54:01 kube-n6.gxsk.uat systemd[1]: Started kubelet: The Kubernetes Node Agent.
-- Subject: Unit kubelet.service has finished start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit kubelet.service has finished starting up.
--
-- The start-up result is done.
Aug 12 09:54:01 kube-n6.gxsk.uat kubelet[6342]: F0812 09:54:01.577417 6342 server.go:199] failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file "/var/lib/kubelet/config.yaml", error: open /var/lib/kubelet/config.yaml: no such file or directory
Aug 12 09:54:01 kube-n6.gxsk.uat systemd[1]: kubelet.service: main process exited, code=exited, status=255/n/a
Aug 12 09:54:01 kube-n6.gxsk.uat systemd[1]: Unit kubelet.service entered failed state.
Aug 12 09:54:01 kube-n6.gxsk.uat systemd[1]: kubelet.service failed.
Aug 12 09:54:11 kube-n6.gxsk.uat systemd[1]: kubelet.service holdoff time over, scheduling restart.
Aug 12 09:54:11 kube-n6.gxsk.uat systemd[1]: Stopped kubelet: The Kubernetes Node Agent.
-- Subject: Unit kubelet.service has finished shutting down
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file “/var/lib/kubelet/config.yaml”, error: open /var/lib/kubelet/config.yaml: no such file or directory 是其中错误,该错误在下一步操作执行后即可恢复正常,脚本里让其启动,主要是为设置以后的自动启动。
六、 文章引用
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 long@longger.xin