Kubeadm+Containerd+keepalived部署高可用k8s(v1.28.2)集群
一.环境准备,二.容器运行时Containerd安装请参照前文。Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)-CSDN博客
文章目录
- Kubeadm+Containerd+keepalived部署高可用k8s(v1.28.2)集群
- 一.环境准备,二.容器运行时Containerd安装请参照前文。[Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)-CSDN博客](https://blog.csdn.net/qq_43479188/article/details/144567672)
- 服务器准备
- 三.安装`Keepalived`+`Nginx`配置`k8s apiserver`高可用
- 1.安装`Keepalived`
- 2.安装`Nginx`
- 3.安装`msmtp`邮箱
- 4.修改`Nginx`配置
- 5.`keepalived`配置
- 6.测试`Keepalived`是否配置成功
- 四.K8S集群部署
- 1.集群软件的apt源准备
- 2.K8S集群软件的安装
- 3.进行`kubectl`命令补全
- 4.K8S集群初始化
- 5.K8S集群网络插件Calico部署
- 6.`Msater`节点设置Worker角色
- 五.部署应用测试集群是否安装成功
服务器准备
服务器信息(此处为同一内网上的服务器,各个运营商的云服务器Keepalived功能是收费的)如本地搭建的服务器则需要保证在同一内网中,且最好关闭防火墙。
systemctl disable ufw
角色 主机名称 IP Kubernetes版本 master k8s-master1 192.168.6.132 v1.28.2 master2 k8s-master2 192.168.6.131 v1.28.2 VIP 192.168.6.139
三.安装Keepalived
+Nginx
配置k8s apiserver
高可用
1.安装Keepalived
在两个master
节点分别执行
apt update
#安装keepalived
apt install -y keepalived
2.安装Nginx
因为默认的Ubuntu
源安装的Nginx,是简版,不包括--with-stream
等模块,所以这里选择安装Nginx
官方源的版本
#更新源
apt-get update
#下载必须组件
apt-get install -y gnupg2 curl lsb-release ca-certificates
#添加密钥
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo tee /etc/apt/trusted.gpg.d/nginx.asc
#添加镜像源地址
sh -c "echo 'deb http://nginx.org/packages/mainline/ubuntu/ $(lsb_release -cs) nginx' > /etc/apt/sources.list.d/nginx.list"
#再次更新镜像源
apt-get update
#下载安装Nginx
apt-get install nginx
检测Nginx
是否安装成功,可以看到有我们需要的模块。
nginx -V
3.安装msmtp
邮箱
#执行命令安装邮箱功能
apt install -y msmtp msmtp-mta ca-certificates bsd-mailx
#编辑配置文件
vi ~/.msmtprc
# QQ SMTP 服务器设置
account default
host smtp.qq.com
port 465
auth on
user your_email@qq.com
password your_password(授权码)
from your_email@qq.com
tls on
tls_starttls off
tls_certcheck off
logfile ~/.msmtp.log
#测试是否能够发送邮件
echo "Test email body" | msmtp -a default recipient@example.com
4.修改Nginx
配置
修改Nginx
配置,两个节点相同:
#这一步避免修改配置后重启包报错
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.back
#修改配置文件
cat > /etc/nginx/nginx.conf << -'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
include /etc/nginx/conf.d/*.conf;
events {
worker_connections 1024;
}
# 四层负载均衡,为两台Master apiserver组件提供负载均衡
stream {
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
access_log /var/log/nginx/k8s-access.log main;
upstream k8s-apiserver {
server 192.168.6.131:6443; # xianchaomaster2 APISERVER IP:PORT
server 192.168.6.132:6443; # xianchaomaster3 APISERVER IP:PORT
}
server {
listen 16443; # 由于nginx与master节点复用,这个监听端口不能是6443,否则会冲突
proxy_pass k8s-apiserver;
}
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80 default_server;
server_name _;
location / {
}
}
}
-EOF
5.keepalived
配置
- 主
keepalived
配置:
cat > /etc/keepalived/keepalived.conf << -'EOF'
global_defs {
notification_email { #指定keepalived在发生事件时(比如切换)发送通知邮件的邮箱,
2*****0@qq.com #设置报警邮件地址,可以设置多个,每行一个。 需开启本机的sendmail服务
}
notification_email_from 1*****05@qq.com #keepalived在发生诸如切换操作时需要发送email通知地址
smtp_server smtp.qq.com #指定发送email的smtp服务器
smtp_connect_timeout 30 #设置连接smtp server的超时时间
router_id NGINX_MASTER #运行keepalived的机器的一个标识,通常可设为hostname。故障发生时,发邮件时显示在邮件主题中的信息。
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2 #脚本执行间隔,每2s检测一次
timeout 2
weight -5 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
rise 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
fall 2 #检测2次成功就算成功。但不修改优先级
}
vrrp_instance VI_1 {
state MASTER
interface ens34 #换成自己服务器的网卡名ifconfig查看
virtual_router_id 51
priority 100 #MASTER的优先级必须大于BACKUP的优先级,slave设置的值不能超过weight设置倍数,非常重要
advert_int 1 #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication {
auth_type PASS
auth_pass 20210825
}
virtual_ipaddress {
192.168.6.139/32 dev ens34 label ens34:1
}
notify_master "/etc/keepalived/mail_notify.sh master" #当前节点成为主节点时触发的脚本
notify_backup "/etc/keepalived/mail_notify.sh backup" #当前节点转为备节点时触发的脚本
notify_fault "/etc/keepalived/mail_notify.sh fault" #当前节点转为失败状态时触发的脚本
track_script {
chk_nginx
}
}
-EOF
注意此处
#
后面的注释为解释用,修改的时候请删除#
和#
后面的内容。
- 配置脚本(两个节点都需要)
#新增Nginx检查脚本
cat > /etc/keepalived/check_nginx.sh << -'EOF'
#!/bin/bash
if [ "${nginx_pid}" = "0" ]; then
systemctl start nginx
sleep 2
nginx_pidd=$(ps -C nginx --no-heading|wc -l)
if [ "${nginx_pidd}" = "0" ]; then
systemctl stop keepalived
systemctl stop nginx
fi
fi
-EOF
#给脚本赋权
chmod +x /etc/keepalived/check_nginx.sh
#新增主节点keepalived漂移后告警脚mail_notify.sh
cat > /etc/keepalived/mail_notify.sh << -'EOF'
#!/bin/bash
IPADDR=$(/usr/sbin/ifconfig eth0 | grep "inet" | awk '{ print $2}')
contact='2*****80@qq.com'
function notify() {
mailsubject="nginx服务器${IPADDR},keepalived-master $1 状态被激活,查看nginx服务运行状态"
mailbody="$(date +'%F %T'): 服务器${IPADDR} keepalived vip发生漂移, 当前服务器keepalived状态为 $1,节点为msater"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename$0) {master|backup|fault}"
exit 100
;;
esac
-EOF
#给脚本赋权
chmod +x /etc/keepalived/mail_notify.sh
#新增备节点keepalived漂移后告警脚mail_notify.sh
cat > /etc/keepalived/mail_notify.sh << -'EOF'
#!/bin/bash
IPADDR=$(/usr/sbin/ifconfig eth0 | grep "inet" | awk '{ print $2}')
contact='2*****80@qq.com'
function notify() {
mailsubject="nginx服务器${IPADDR},keepalived-backup 状态被激活,查看nginx服务运行状态"
mailbody="$(date +'%F %T'): 服务器${IPADDR} keepalived vip发生漂移, 当前服务器keepalived状态为 $1,节点为Backup"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename$0) {master|backup|fault}"
exit 100
;;
esac
-EOF
#给脚本赋权
chmod +x /etc/keepalived/mail_notify.sh
- 备
Keepalived
配置
cat > /etc/keepalived/keepalived.conf << -'EOF'
global_defs {
notification_email {
2*****80@qq.com
}
notification_email_from 19*****05@qq.com
smtp_server smtp.qq.com
smtp_connect_timeout 30
router_id NGINX_SLAVE
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
timeout 2
weight -5
rise 2
fall 2
}
vrrp_instance VI_1 {
state BACKUP #此处需修改为BACKUP
interface ens34
virtual_router_id 51
priority 95 #注意此处设置的值不能比msater节点高
advert_int 1
authentication {
auth_type PASS
auth_pass 20210825
}
virtual_ipaddress {
192.168.6.139/32 dev ens34 label ens34:1
}
notify_master "/etc/keepalived/mail_notify.sh master"
notify_backup "/etc/keepalived/mail_notify.sh backup"
notify_fault "/etc/keepalived/mail_notify.sh fault"
track_script {
chk_nginx
}
}
-EOF
注意此处
#
后面的注释为解释用,修改的时候请删除#
和#
后面的内容。
- 启动服务(两个节点都执行)
systemctl daemon-reload
systemctl restart nginx
systemctl start keepalived
systemctl enable nginx keepalived
6.测试Keepalived
是否配置成功
- 主节点检查是否绑定
VIP
ip addr show | grep ens34
- 备节点检查是否绑定
VIP
可以看到此时的VIP已经绑定到主节点,现在测试主备节点和其他处于统一网络环境的内网服务器是否能够Ping
通这个VIP节点。
主节点:
备节点:
其他内网服务器:
如果都测试通过则代表VIP地址是可用的。
- 测试
VIP
是否能够漂移
#停止keepalived服务
systemctl stop keepalived.service
可以看到停止之后就收到了邮件,然后可以在backup
节点看到,VIP已经漂移过去了。
然后我们在master
节点启动keepalived
。
systemctl start keepalived.service
可以看到VIP已经漂移回msater
同时会收到三个邮件。
至此k8s apiserver
高可用就配置完成。
四.K8S集群部署
1.集群软件的apt源准备
此处使用使用阿里云镜像源:
#添加镜像源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
#添加密钥
curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
#更新源
apt-get update
2.K8S集群软件的安装
查看可以安装的软件列表
apt-cache madison kubeadm
可以看到最新的版本是1.28.2,此处选择安装的版本是1.28.2,可自行选择。
apt-get install -y kubelet=1.28.2-00 kubeadm=1.28.2-00 kubectl=1.28.2-00
node节点上可以不用安装kubectl
apt-get install -y kubelet=1.28.2-00 kubeadm=1.28.2-00
启动kueblet,并设置开机自启动。
systemctl enable --now kubelet
为求稳定,通过以下命令进行锁定定版本。
apt-mark hold kubelet kubeadm kubectl
3.进行kubectl
命令补全
#安装命令补全工具
apt install bash-completion
kubectl completion bash > /etc/bash_completion.d/kubectl
ls /etc/bash_completion.d/kubectl
source /etc/bash_completion.d/kubectl
source ~/.bashrc
4.K8S集群初始化
#创建文件夹
mkdir -p /home/k8s/init/
#生成默认配置文件
kubeadm config print init-defaults > /home/k8s/init/kubeadm-init.yaml
修改文件的一些参数:
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.6.139 #此处配置VIP地址
bindPort: 6443 #端口地址不变,因为Nginx配置的还是6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: k8s-master
taints: null
---
apiServer:
certSANs: #此处配置VIP地址和其他两个主节点的地址
- 192.168.6.131
- 192.168.6.132
- 192.168.6.139
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.28.2
controlPlaneEndpoint: 192.168.6.139:16443 #此处配置VIP地址加Nginx代理后的端口
networking:
dnsDomain: cluster.local
serviceSubnet: 10.244.0.0/12
podSubnet: 10.96.0.0/16
scheduler: {}
注意此处
#
后面的注释为解释用,修改的时候请删除#
和#
后面的内容。
通过以下命令列举出需要拉取的镜像:
kubeadm config images list --config /home/k8s/init/kubeadm-init.yaml
通过下面命令进行拉取:
kubeadm config images pull --config /home/k8s/init/kubeadm-init.yaml
然后通过以下命令进行初始化:
kubeadm init --config=/home/k8s/init/kubeadm-init.yaml --upload-certs --v=6
可以看到此处和非高可用版有点不一样:
--v=6
是日志级别参数,表示将日志详细度设置为 6(范围是 0 到 10,数字越高日志越详细)。
--upload-certs
参数用于将集群的控制平面节点所需的证书上传到 kubeadm 的配置存储(存储在 etcd 中),以便其他控制平面节点(通过kubeadm join
命令)可以拉取这些证书并加入集群。在配置高可用的 Kubernetes 集群(即包含多个控制平面节点)的时候,需要使用
--upload-certs
。没有这个参数,后续添加控制平面节点时需要手动提供证书。
出现如下信息则证明初始化成功:
然后按照上述的提示,进行如下的操作:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
执行完上述的命令,就可以通过kubectl进行查看k8s集群的状态信息。如下图:
因为一开始没有安装Calico等网络插件,所以节点状态是STATUS: NotReady
。
新节msater点加入到集群中,复制输出中的包含--control-plane
的命令:
kubeadm join 192.168.6.139:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:8f7971ee2f7a2baefbcde6ca28afb77107df09a96caa2a8e39fed876574a40a2 \
--control-plane --certificate-key a5607ce95a056f7a9510830860706c35174f46195f31009c98a67b28b833243a
在另一个msater
节点执行。子节点则是下面的:
kubeadm join 192.168.6.139:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:8f7971ee2f7a2baefbcde6ca28afb77107df09a96caa2a8e39fed876574a40a2
执行后如图:
然后按照上述的提示,进行如下的操作:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
再次查看节点:
同样是STATUS: NotReady
。
在安装途中可以通过如下命令来排查节点插件的安装进程:
kubectl get pod -n kube-system -o wide | grep k8s-master2
如果一直未启动成功可以用如下命令来排查:
kubectl describe pod -n kube-system <PodID>
#或者
kubectl logs -f -n kube-system <PodID>
在节点上还可以通过crictl ps -a
命令来排查是否有pod启动。同理,在初始化的时候也可以这样排查。
crictl
是Containerd
的命令行工具。
5.K8S集群网络插件Calico部署
此处选用科学部署方式,拉取的镜像到自己的阿里云仓库。镜像地址如下:
registry.cn-hangzhou.aliyuncs.com/docker_image-ljx/calico-cni:v3.27.5
registry.cn-hangzhou.aliyuncs.com/docker_image-ljx/calico-node:v3.27.5
registry.cn-hangzhou.aliyuncs.com/docker_image-ljx/calico-kube-controllers:v3.27.5
分别替换name: upgrade-ipam
,name: install-cni
,name: "mount-bpffs"
,name: calico-node
,name: calico-kube-controllers
这几处的镜像地址,然后执行以下命令安装:
kubectl create -f calico.yml
calico
文件地址如下calico/manifests/calico.yaml at release-v3.27 · projectcalico/calico
执行完上述的命令后,即可完成calico的部署。如下:
可以看到每个节点都有Calico
的插件,然后稍等一会,node
节点就会变成Ready
:
6.Msater
节点设置Worker角色
默认情况下
Kubernetes Control Plane Master Node
被设置为不能部署pod
,因为Control Plane
节点默认设置了以下NoSchedule
标签:
如图:
kubectl describe node k8s-master | grep Taint
所以去掉NoSchedule
标签,即可在Control Plane
调度Pod
#执行命令删除该节点的标签
kubectl taint node k8s-master2 node-role.kubernetes.io/control-plane:NoSchedule-
#再次查看
kubectl describe node k8s-master2 | grep Taint
可以发现标签已经删除。
五.部署应用测试集群是否安装成功
以部署一个Nginx应用为例,以下是一个简单的Nginx
部署的yaml
文件:
apiVersion: apps/v1 #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment #该配置的类型,我们使用的是 Deployment
metadata: #译名为元数据,即 Deployment 的一些基本属性和信息
name: nginx-deployment #Deployment 的名称
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
app: nginx #为该Deployment设置key为app,value为nginx的标签
spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
replicas: 1 #使用该Deployment创建一个应用程序实例
selector: #标签选择器,与上面的标签共同作用,目前不需要理解
matchLabels: #选择包含标签app:nginx的资源
app: nginx
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
app: nginx
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
- name: nginx #container的名称
image: registry.cn-hangzhou.aliyuncs.com/docker_image-ljx/nginx:1.26.0 #使用镜像nginx:1.26.0创建container,该container默认80端口可访问
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service #Service 的名称
labels: #Service 自己的标签
app: nginx #为该 Service 设置 key 为 app,value 为 nginx 的标签
spec: #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
selector: #标签选择器
app: nginx #选择包含标签 app:nginx 的 Pod
ports:
- name: nginx-port #端口的名字
protocol: TCP #协议类型 TCP/UDP
port: 80 #集群内的其他容器组可通过 80 端口访问 Service
nodePort: 32600 #通过任意节点的 32600 端口访问 Service
targetPort: 80 #将请求转发到匹配 Pod 的 80 端口
type: NodePort #Serive的类型,ClusterIP/NodePort/LoaderBalancer
上述的资源清单创建了两种类型一个Deployment
,一个Service
,然后执行命令部署:
kubectl apply -f nginx.yaml
执行成功后,如下图:
可以看到这个pod
是部署在那个删除标签的Control Plane
节点的。
然后通过node
节点IP+32600的方式进行访问: