基于 kubeadm 搭建 k8s 集群
一、环境规划
-
如果搭建多 master 节点,先搭建 keepalive 服务
-
pod 网段:10.244.0.0/16
-
service 网段:10.96.0.0/12
-
注意: pod 和 service 网段不可冲突,如果冲突会导致 K8S 集群安装失败
主机名 | IP 地址 | 操作系统 |
master-1 | 192.168.32.61 | Anolis OS 8.10 |
master-2 | 192.168.32.65 | Anolis OS 8.10 |
master-3 | 192.168.32.66 | Anolis OS 8.10 |
node-1 | 192.168.32.62 | Anolis OS 8.10 |
node-2 | 192.168.32.63 | Anolis OS 8.10 |
node-3 | 192.168.32.64 | Anolis OS 8.10 |
二、系统初始化准备
所有节点均需以下操作
-
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld --nowsystemctl stop iptables
systemctl disable iptable
-
禁用 Selinux
setenforce 0
sed -i -r 's/SELINUX=[ep].*/SELINUX=disabled/g' /etc/selinux/config
-
禁用 swap 交换分区
swapoff --all
sed -i -r '/swap/ s/^/#/' /etc/fstab # 禁止开机自启动swap交换分区
-
配置域名解析
# vim /etc/hosts
10.0.32.61 master-1
10.0.32.65 master-2
10.0.32.66 master-3
10.0.32.62 node-1
10.0.32.63 node-2
10.0.32.64 node-3# 在不同的主机修改对应的主机名
hostnamectl set-hostname master-1
hostnamectl set-hostname master-2
hostnamectl set-hostname master-3
hostnamectl set-hostname node-1
hostnamectl set-hostname node-2
hostnamectl set-hostname node-3
-
配置服务器时间保持一致
rpm -ivh http://mirrors.wlnmp.com/centos/wlnmp-release-centos.noarch.rpm
yum install wntp -y
ntpdate -u ntp1.aliyun.com # 同步阿里云标准时间
echo "0 1 * * * ntpdate ntp1.aliyun.com" >> /var/spool/cron/root # 每天凌晨1点自动同步时间
crontab -l
-
修改 Linux 内核参数,添加网桥过滤器和地址转发功能
sed -i -r 's/SELINUX=[ep].*/SELINUX=disabled/g' /etc/selinux/configcat >> /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOFsysctl -p /etc/sysctl.d/kubernetes.conf
-
加载网桥过滤器模块
modprobe br_netfilter
lsmod | grep br_netfilter # 验证是否生效
-
配置 IPVS 功能
在kubernetes中Service有两种代理模型,一种是基于iptables的,一种是基于ipvs,两者对比ipvs的性能要高,如果想要使用ipvs模型,需要手动载入ipvs模块
yum -y install ipset ipvsadmcat > /etc/sysconfig/modules/ipvs.modules <<EOF
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOFchmod +x /etc/sysconfig/modules/ipvs.modulesmodprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntracklsmod | grep -e ip_vs -e nf_conntrack # 验证 ipvs 模块
三、安装 Docker
-
下载阿里云的 yum 源
-
配置文件到 /etc/yum.repos.d/CentOS-Base.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
-
修改 yum 源配置文件
vim /etc/yum.repos.d/CentOS-Base.repo# 在命令模式下执行(按Esc键后,再按冒号键进入命令模式)
:%s/mirrors.cloud.aliyuncs.com/mirrors.aliyun.com/g# 替换完后,再次进入命令模式执行
:%s/$releasever/$releasever-stream/g# 最后保存修改后的内容(按Esc键后,再按冒号键,输入 wq ,按回车键即可)
-
更新 yum 源配置文件
# 清理一下
yum clean all# 生成缓存
yum makecache
-
卸载 docker 老的版本
(如果存在的话,没有可以忽略)
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
-
安装docker 基础包
yum install -y yum-utils \device-mapper-persistent-data \lvm2
-
设置稳定仓库
yum-config-manager \--add-repo \https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
安装 Docker Engine - Community
# 安装最新版本(latest)
yum install docker-ce docker-ce-cli -y # 安装指定版本
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> -y
-
Docker 配置加速源
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"],
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": ["10.0.31.201"], # 公司的 Harbor 仓库(可选)
"data-root": "/docker", # 自定义 docker 工作目录(建议挂载到磁盘)
"log-driver": "json-file", # docker 日志规则(最大日志文件10M,最多保留3个)
"log-opts": {"max-size": "10m","max-file": "3"}
}
-
启动、开机自启 docker
systemctl daemon-reload
systemctl start docker
systemctl enable docker
注意:此时如果 docker 无法启动,并且报错如下:
解决办法:
-
添加 docker 组
$ groupadd docker
groupadd:无法打开 /etc/group
-
这里涉及到一个知识点就是文件隐藏属性,使用 lsattr 查看文件隐藏属性
$ lsattr /etc/group
----i--------e-- /etc/group
$ lsattr lsattr /etc/gshadow
----i--------e-- /etc/gshadow
-
这里的 i 属性表示文件不能被删除、改名,也不能写入或添加数据,所以需要先去掉 i 属性
$ chattr -i /etc/gshadow
$ chattr -i /etc/group
-
然后添加 docker 组,并启动 docker 服务
$ groupadd docker
$ systemctl enable docker && systemctl start docker
四、安装 cri-docker 插件
-
下载 cri-docker 的 rpm 包
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.1/cri-dockerd-0.3.1-3.el7.x86_64.rpm
rpm -ivh cri-dockerd-0.3.1-3.el7.x86_64.rpm
-
备份并更新 cri-docker.service 文件
mv /usr/lib/systemd/system/cri-docker.service{,.default}vim /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
-
启动 cri-docker
systemctl daemon-reload
systemctl start cri-docker.service
systemctl enable cri-docker.service
五、安装 kubelet、kubeadm、kubectl
-
配置阿里云的 kubernetes 源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF
-
安装 1.28.0 版本的的 kubelet、kubeadm、kubectl
yum install -y kubelet-1.28.0 kubeadm-1.28.0 kubectl-1.28.0
-
设置开机自启 kubelet
kubeadm 将使用 kubelet 服务以容器方式部署 kubernetes的 主要服务,所以需要先启动 kubelet 服务
systemctl enable kubelet.service --now
六、搭建 keepalive 服务
-
在三台 master 节点上安装 keepalived
yum -y install keepalived
-
编辑配置文件
抢占模式
在抢占模式中,keepalived的某台机器挂了之后VIP漂移到了备节点,当主节点恢复后主会将VIP再次抢回,这就是keepalive的抢占模式。keepalived默认工作在抢占模式下。在抢占模式中,主节点的state设为MASTER,备节点的state设为BACKUP,主节点的优先级要比备节点的优先级要高。
抢占模式 取决于优先级,哪个优先级高,谁就是 master,和启动顺序无关。
master-1:
cat /etc/keepalived/keepalived.conf
global_defs {router_id master-1 # 一般是主机名称,通过hostname获取
}#定义脚本。固定间隔时间执行
vrrp_script chk_mysql {script "killall -0 mysqld" # 检测haproxy状态,若无对应进程,则权重降级,备用keepalived启用interval 2weight -30fall 5rise 5
}# 定义主机信息
vrrp_instance VI_1 {state MASTER # 主机填写MASTERinterface ens192 # 设置实例绑定的网卡garp_master_delay 1virtual_router_id 10 # 虚拟路由器id号。主从必须一致priority 100 # 定义优先级,数字越大,优先级越高advert_int 1 # 心跳频率unicast_src_ip 192.168.32.61 # 本机ip
unicast_peer {192.168.32.65 # 对端ip192.168.32.66 # 对端ip
}authentication {auth_type PASSauth_pass zuanlan1437xi
}
virtual_ipaddress {#192.168.112.210 dev ens33 label ens33:0
非抢占模式
两者的state都设为BUAKUP(官网说的),一个节点的优先级要比另一个节点的优先级要高,同时高优先级的节点设置nopreempt参数,该参数表示不抢占vip。这样,当高优先级的节点挂了之后,vip就会漂移到低优先级的节点上,但是当高优先级的节点再次恢复正常后再次起来后不会再抢回vip,因为它加了nopreempt参数。
非抢占模式 取决于启动顺序,哪个先启动,谁就是master,和优先级无关。
master-1:
global_defs {router_id master-1 #一般是主机名称,通过hostname获取
}#定义脚本。固定间隔时间执行
vrrp_script chk_mysql {script "killall -0 mysqld" #检测haproxy状态,若无对应进程,则权重降级,备用keepalived启用interval 2weight -30fall 5rise 5
}# 定义主机信息
vrrp_instance VI_1 {state MASTER #主机填写MASTERinterface ens192 #设置实例绑定的网卡garp_master_delay 1nopreemptvirtual_router_id 10 #虚拟路由器id号。主从必须一致priority 100 #定义优先级,数字越大,优先级越高advert_int 1 #心跳频率unicast_src_ip 192.168.32.61 #本机ip
unicast_peer {192.168.32.65 #对端ip192.168.32.66 #对端ip
}authentication {auth_type PASSauth_pass zuanlan1437xi
}
virtual_ipaddress {#192.168.112.210 dev ens33 label ens33:0
-
启动并设置开机自启
service keepalived start
systemctl enable keepalived
systemctl status keepalived
七、初始化集群
-
编辑 kubeadm 配置文件
master-1 节点执行
[root@master-1 ~]# vim kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authentication
kind: InitConfiguration
localAPIEndpoint:advertiseAddress: 10.0.32.61 # 本机(主节点)ipbindPort: 6443
nodeRegistration:criSocket: unix:///var/run/cri-dockerd.sockimagePullPolicy: IfNotPresentname: master-1taints: null
---
apiServer:timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:local:dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.28.0controlPlaneEndpoint: "192.168.32.100:6443" # 如果是多master,增加该行指定 apiserver 用 vip 通信
我们根据自己需求进行修改默认配置文件,我主要更改了一下配置如下:
advertiseAddress:10.0.32.61 更改为 master-1 的IP地址
criSocket:unix:///var/run/cri-dockerd.sock 指定容器运行时
imageRepository:registry.cn-hangzhou.aliyuncs.com/google_containers 配置国内加速源地址
podSubnet:10.244.0.0/16 pod 网段地址
serviceSubnet:10.96.0.0/12 services 网段地址
mode: ipvs 指定使用ipvs
cgroupDriver: systemd 开启systemd
-
进行初始化
kubeadm init --config=kubeadm-config.yaml --ignore-preflight-errors=SystemVerification
-
配置 kubectl 的配置文件 config
相当于对kubectl进行授权,这样kubectl命令可以使用这个证书对k8s集群进行管理
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config# 验证使用可以使用 kubectl 命令
kubectl get nodes
八、节点成员加入集群
1、控制节点加入到集群
-
在 master-1 节点执行以下命令,获取加入命令和证书秘钥
kubeadm token create --ttl 0 --print-join-commandkubeadm init phase upload-certs --upload-certs
-
把输出的加入集群命令和证书拼接好,在 master-2 和 master-3 节点执行,进行加入集群操作
kubeadm join 192.168.32.100:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:c55c03c47a7d0406381120cf5925e0004ceaa88d463e7a833e185a26d62927f3 --control-plane --certificate-key 9f0b485781eadbf594ecdee371674f7f36bbf8e7a5fd6449ce7939b475ec7b44 --cri-socket=unix:///var/run/cri-dockerd.sock
-
在 master-2 和 master-3 节点同样执行以下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
-
删除 master-2 和 master-3 控制节点不可调度 pod 的污点
[root@master-1 ~]# kubectl describe node master-2 | grep Taints
Taints: node-role.kubernetes.io/control-plane:NoSchedule
[root@master-1 ~]# kubectl describe node master-3 | grep Taints
Taints: node-role.kubernetes.io/control-plane:NoSchedule
[root@master-1 ~]# kubectl taint node master-2 node-role.kubernetes.io/control-plane:NoSchedule-
node/master-2 untainted
[root@master-1 ~]# kubectl taint node master-3 node-role.kubernetes.io/control-plane:NoSchedule-
node/master-3 untainted
[root@master-1 ~]# kubectl describe node master-2 | grep Taints
Taints: <none>
[root@master-1 ~]# kubectl describe node master-3 | grep Taints
Taints: <none>
2、工作节点加入到集群
-
在 master-1 使用以下命令创建并查看token
kubeadm token create --print-join-command
-
在三台 node 节点执行,注意添加 --cri-socket=unix:///var/run/cri-dockerd.sock
kubeadm join 192.168.32.100:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:c55c03c47a7d0406381120cf5925e0004ceaa88d463e7a833e185a26d62927f3 --cri-socket=unix:///var/run/cri-dockerd.sock
九、安装网络组件 calico
-
在所有节点解压
unzip calico-image-v3.25.0.zip
-
在所有节点导入镜像
docker load -i calico-image-v3.25.0.tar
-
部署 calico
-
在 master-1 上操作
kubectl apply -f calico.yaml
-
查看集群状态 & 查看 Pod 状态
kubectl get node -o wide
kubectl get pod -A -o wide
kubectl get pod -A -o wide | grep calico
十、安装 Kuboard
-
拉取镜像
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eipwork/kuboard:v3.5.2.7
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eipwork/kuboard:v3.5.2.7 docker.io/eipwork/kuboard:v3.5.2.7
-
创建目录
mkdir -p /root/kuboard-data/data
-
启动 Kuboard
docker run -d --restart=unless-stopped --name=kuboard -p 31000:80/tcp -p 10081:10081/tcp -e KUBOARD_ENDPOINT="http://192.168.32.61:80:80" -e KUBOARD_AGENT_SERVER_TCP_PORT="10081" -v /root/kuboard-data/data eipwork/kuboard:v3.5.2.7
-
登录 web 页面导入 k8s 集群
http://192.168.32.61:31000
admin
Kuboard123