k8s容器编排技术实践------OpenEuler安装部署k8s
https://blog.csdn.net/xiaochenXIHUA/article/details/161323314
一、基础准备
1.1、高可用k8s集群架构
所谓的k8s高可用,实际是对k8s的master节点实现高可用(更具体的是实现对k8s的master节点中API Server的高可用)因为一旦API Server出故障,则整个k8s集群就无法使用了。而我们最终实现的其实是借助开源软件(如:haproxy)针对k8s的master节点API Server的高可用、负载均衡集群。
高可用 Kubernetes 集群能够确保应用程序在运行时不会出现服务中断,这也是生产的需求之一,并且在私有网络环境中,使用固定IP对外提供服务,并且基于Kubernetes service 4层负载均衡可以在保证高用的情况下,又可以获取到客户端的真实IP,这里我使用keepalived+haproxy 来实现。通过使用Proxy Protocol 代理协议透传客户端IP来实现。
典型的高可用k8s集群架构如下:

上图中,HAProxy 提供k8s中apiserver可靠、高性能的负载均衡,任何一个master节点异常,HAProxy 都会自动切换到其他正常的master节点,同时,为保障HAProxy的可靠性,这里使用Keepalived 提供的VRRP机制,预防了HAProxy的单点故障。如果其中一个HAProxy节点故障,VIP 地址(即浮动 IP 地址)将自动漂移到另一个节点,使HAProxy集群仍然可以正常运行,从而实现HAProxy的高可用。
1.2、安装规划
本文以6台服务器为例进行实战演示,每台主机的主机名、IP、操作系统版本、角色规划如下表所示:
| 主机名称 | IP地址 | 集群角色 | 系统版本 |
|---|---|---|---|
| k8s-master1 | 192.168.1.140 | master | OpenEuler2403-sp2 |
| k8s-master2 | 192.168.1.141 | master | OpenEuler2403-sp2 |
| k8s-node1 | 192.168.1.142 | node1 | OpenEuler2403-sp2 |
| k8s-node2 | 192.168.1.143 | node2 | OpenEuler2403-sp2 |
| keepalived1/haproxy1 | 192.168.1.51 | haproxy1 | OpenEuler2403-sp2 |
| keepalived2/haproxy2 | 192.168.1.152 | haproxy2 | OpenEuler2403-sp2 |
由于OpenEuler服务器默认的yum源较慢,因此推荐修改为华为云镜像源:
bash
#直接将原有源替换为华为云的源
#直接替换为华为云的源
cd /etc/yum.repos.d/
cp -p openEuler.repo openEuler.repo.old
sed -i 's|repo.openeuler.org|repo.huaweicloud.com/openeuler|g' /etc/yum.repos.d/openEuler.repo
sed -i 's|mirrors.openeuler.org|mirrors.huaweicloud.com|g' /etc/yum.repos.d/openEuler.repo
#清理并重新生成
yum clean all
yum makecache
1.3、修改主机名称并配置hosts
bash
#1-修改主机名称并让其生效(如:修改主机名称为【k8s-master】)
hostnamectl set-hostname k8s-master1
systemctl restart systemd-hostnamed
exec bash
hostname
#2-给这三台服务器都配置本地的域名解析
cat >>/etc/hosts <<EOF
192.168.1.140 k8s-master1
192.168.1.141 k8s-master2
192.168.1.142 k8s-node1
192.168.1.143 k8s-node2
EOF



1.4、开启流量转发
bash
#1-开启流量转发(每台k8s服务器都需要开启)
cat > /etc/sysctl.d/k8s.conf << EOF
#开启IPv4内核转发,Pod跨节点通信、Service转发必备
net.ipv4.ip_forward = 1
#网桥流量交给iptables处理(配合br_netfilter模块)
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
# 调高连接跟踪最大值,集群大量Pod防丢包
net.nf_conntrack_max = 131072
net.netfilter.nf_conntrack_max = 131072
# 优化TCP队列,高并发集群防拥塞
net.core.somaxconn = 32768
# 禁用内存交换
vm.swappiness=0
EOF
#2-加载br_netfilter模块,并让br_netfilter模块开机自动加载
modprobe br_netfilter
lsmod | grep br_netfilter
echo "br_netfilter" >> /etc/modules-load.d/k8s.conf
#3-加载nf_conntrack模块,并让nf_conntrack模块开机自动加载
modprobe nf_conntrack
lsmod | grep nf_conntrack
echo "nf_conntrack" >> /etc/modules-load.d/k8s.conf
#4-让k8s内核参数生效
sysctl -p /etc/sysctl.d/k8s.conf
#5-【/etc/rc.local】是 Linux 开机自动运行脚本,已经将modprobe br_netfilter、sysctl 等内核配置写进去,因此必须有执行权限(x),开机才会自动运行,默认权限是 644(无执行权限),开机不生效
chmod 755 /etc/rc.local
#6-注意:在openeuler系统中,由于/etc/sysctl.conf中也定义了net.ipv4.ip_forward参数,因此在/etc/sysctl.conf中,找到'net.ipv4.ip_forward=0'行与'vm.swappiness=10',然后注释,上面的配置才能生效。


1.5、关闭防火墙与selinux
bash
#关闭防火墙和selinux
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
systemctl disable --now firewalld
1.6、彻底关闭swap
关闭swap很关键【因为swap打开,会导致k8s无法正常运行】。但在openeuler下,不能仅是临时关闭swap,要永久关闭。
bash
#1-临时关闭系统的交换分区
swapoff -a
cp /etc/fstab /etc/fstab.bak
cat /etc/fstab.bak | grep -v swap > /etc/fstab
#2-确认systemctl系统服务中swap分区名的方法
systemctl list-unit-files |grep swap
#3-使用systemctl指令mask参数关闭对应swap分区服务(显示disabled才表示彻底关闭了)
systemctl mask swap.target
systemctl mask 'dev-disk-by\x2duuid-2617a1d1\x2d8202\x2d403b\x2db35d\x2d08313c1929c2.swap'
systemctl list-unit-files |grep swap
#4-重启服务器并查看swap数据是否显示0,显示0则表示彻底禁用了,否则还需要按照如上2、3方法再次执行【一般需要禁用2次就彻底禁用了】
reboot
top
二、haproxy+keepalived安装与配置
haproxy与keepalived只在规划的服务器主机(192.168.1.51、192.168.1.152)上配置安装。
2.1、haproxy的安装与配置
可以从HAProxy的官网下载对应的源码包进行安装【推荐】,或者也可以直接运行【yum install haproxy】命令安装,但是直接在线安装的版本比较老。

bash
#从HAProxy官网下载对应源码包安装【推荐】
#1-下载haproxy源码
wget https://www.haproxy.org/download/3.2/src/haproxy-3.2.19.tar.gz -c -P /data
cd /data
tar -zxvf haproxy-3.2.19.tar.gz
cd haproxy-3.2.19/
#2-安装必要的编译环境并编译安装
#2.1-安装编译haproxy源码所需的库
dnf install -y gcc make openssl-devel pcre2-devel systemd-devel tar wget
#2.2-编译haproxy源码【USE_OPENSSL=1:开启 HTTPS/SSL 支持】【USE_PCRE2=1:开启正则表达式支持】【USE_SYSTEMD=1:支持 Systemd 服务管理】【PREFIX=/usr/local/haproxy:安装路径(推荐默认)】
make \
TARGET=linux-glibc \
USE_OPENSSL=1 \
USE_PCRE2=1 \
USE_SYSTEMD=1 \
PREFIX=/usr/local/haproxy
#2.3-安装haproxy并指定安装路径
make install PREFIX=/usr/local/haproxy
#2.4-配置环境变量
# 创建软链接,让系统识别 haproxy 命令
ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin/haproxy
#2.5-验证安装是否成功(查看版本)
haproxy -v
#3-创建HAProxy专用系统用户/组【用于权限隔离,提升安全性】
groupadd -r haproxy
useradd -r -g haproxy -s /sbin/nologin -M haproxy
#4-haproxy默认不创建配置文件目录和日志目录,因此需要手动创建haproxy配置文件目录及其配置与日志文件目录
mkdir -p /usr/local/haproxy/conf
mkdir -p /usr/local/haproxy/logs
#4.2-【/usr/local/haproxy/conf/haproxy.cfg】配置文件内容
cat > /usr/local/haproxy/conf/haproxy.cfg<<EOF
# 全局配置:安全 + 性能 + 系统兼容
global
log 127.0.0.1 local0 info # 日志配置
maxconn 40960 # 放大最大连接数(K8s高并发)
user haproxy # 最小权限运行
group haproxy
nbthread 4 # 线程数(和CPU核心一致)
ulimit-n 102400 # 最大文件描述符(40960×2 + 37 = 81957)【所需FD = maxconn × 2(前端连接 + 后端连接) + 监听端口(6443/19088) + 日志 + 内部socket】
ssl-default-bind-ciphers PROFILE=SYSTEM # TLS兼容(透传K8s证书用)
ssl-default-server-ciphers PROFILE=SYSTEM
# 默认配置:TCP四层代理 + 长连接 + 高可用
defaults
mode tcp # 四层代理(K8s必须用TCP,不终止TLS)
log global # 继承全局日志
option tcplog # TCP日志格式
option dontlognull # 不记录空连接,减少日志冗余
option redispatch # 节点断线后,自动重定向到其他节点
retries 3 # 重试次数
timeout connect 12s # 连接超时(内网快速失败)
timeout client 8h # 客户端长连接(K8s必需)
timeout server 8h # 服务端长连接(K8s必需)
timeout check 2s # 健康检查超时
timeout tunnel 8h # TCP隧道超时(长连接核心)
# 监控页面:生产环境【安全加固】核心
listen admin_stats
bind 0.0.0.0:19088
mode http
log 127.0.0.1 local0 err
# 基础监控配置
stats refresh 10s
stats uri /haproxy-status
stats realm "Haproxy Stats Login"
# 生产必须修改!强密码账号(字母数字特殊字符混合,长度≥8)
stats auth admin:Strong@Passw0rd_2025
# 安全加固
stats hide-version # 隐藏版本
stats admin if TRUE # 允许在线管理
# 访问限制:只允许内网IP访问(生产必需!)
acl stats_allow src 127.0.0.1 192.168.1.0/24
http-request deny if !stats_allow
# K8s APIServer 前端入口
frontend kubernetes-frontend
bind 0.0.0.0:6443
mode tcp
option tcplog
option tcpka # 开启TCP keepalive,保活长连接
option nolinger # 快速释放断开的连接
maxconn 20480 # 前端最大连接限制
default_backend kubernetes-backend
# K8s APIServer 后端节点:性能 + 高可用 + 健康检查优化
backend kubernetes-backend
mode tcp
balance roundrobin # 轮询负载均衡
option tcpka # 后端TCP保活
option nolinger
# 健康检查:适配K8s APIServer(更精准)
option tcp-check
# 后端服务器配置:权重、最大连接、健康检查、高可用
server app1 192.168.1.140:6443 weight 6 maxconn 10240 check inter 2000 rise 2 fall 5
server app2 192.168.1.141:6443 weight 6 maxconn 10240 check inter 2000 rise 2 fall 5
EOF
#检查haproxy.conf配置文件的语法是否正确
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg -c
#4.3-编写haproxy服务脚本【/etc/systemd/system/haproxy.service】,启动haproxy服务,并指定日志输出到默认的journalctl和/var/log/messages
cat > /etc/systemd/system/haproxy.service <<EOF
[Unit]
Description=HAProxy Load Balancer
After=network.target
[Service]
Type=notify
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg -c -q
ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /usr/local/haproxy/conf/haproxy.cfg
ExecReload=/bin/kill -USR2 $MAINPID
# 高并发文件描述符(匹配你的 ulimit-n 102400)
LimitNOFILE=102400
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
#4.4-授权haproxy用户读写权限(否则无法写入PID文件)
chown -R haproxy:haproxy /usr/local/haproxy
#5-haproxy服务操作
#5.1-刷新systemd配置
systemctl daemon-reload
#5.2-启动HAProxy
systemctl start haproxy
#5.3-设置开机自启
systemctl enable haproxy
#5.4-查看运行状态
systemctl status haproxy
#5.5-查看端口监听(6443+19088)
netstat -tulpn | grep haproxy
注意:默认k8s初始化是在一个节点执行,此时可以先注释掉第二个节点,等两个master节点都正常后,去掉注释即可。
| haproxy.conf配置文件 |
|---|
| K8s 底层有一个核心机制:Watch 长连接 (所有控制器、kubelet、组件都靠它监听资源变化),这个连接是空闲阻塞型(无数据传输时保持静默),若设置的空闲超时太短(如:30s 超时会触发三大致命问题): 1. Watch 连接频繁断开 :K8s 组件每秒重连 apiserver,引发重连风暴 2. apiserver/etcd 负载飙升:大量重连导致控制平面卡死,集群失控 3. 业务异常:kubectl 操作中断、Pod 调度失败、节点状态异常、日志采集断连 30s 是 HTTP 短连接的配置,完全违背 K8s 长连接的设计理念,生产环境直接禁用。 |
8 小时超时是云原生社区、K8s 官方推荐的内网长连接标准值,合理性: 1. 完全匹配 K8s Watch 机制:空闲数小时的长连接不会被断开,避免重连风暴 2. 内网无资源浪费:空闲连接仅占用极小内存,8 小时超时不会导致连接泄漏 3. 高可用兼容 :配合 redispatch 断线重定向,既保证长连接稳定,又不影响故障切换 4. 运维友好:远低于操作系统 TCP keepalive 超时(默认 2 小时),无底层冲突 |
2.2、keepalived的安装与配置
keepalived是为了保证haproxy的高可用性,本文将keepalived也安装到了haproxy机器上,两台haproxy都需要安装keepalived。有两种安装方法【在线安装】【源码安装】。
Keepalived的详细实操安装流程及其配置文件选项的详解
https://blog.csdn.net/xiaochenxihua/article/details/151679187
从零到一使用开源Keepalived配置实现高可用的集群教程
https://blog.csdn.net/xiaochenxihua/article/details/151720348
解决keepalived的主备服务器都持有VIP------出现脑裂现象
https://blog.csdn.net/xiaochenxihua/article/details/152234950
keepalived的使用说明
https://keepalived-doc.readthedocs.io/zh-cn/latest/%E4%BB%8B%E7%BB%8D.html
2.2.1、直接在线安装keepalived
bash
#在线安装keepalived
yum install keepalived -y
yum install ipvsadm
2.2.2、使用源码安装
bash
#使用源码安装keepalived
#下载安装keepalived
yum install -y gcc gcc-c++ wget popt-devel openssl openssl-devel
yum install -y libnl3 libnl3-devel
wget https://keepalived.org/software/keepalived-2.3.4.tar.gz -c -P /data
cd /data
tar -zxvf keepalived-2.3.4.tar.gz
cd keepalived-2.3.4/
./configure --sysconf=/etc
make && make install
#2-配置keepalived的配置文件
cd /etc/keepalived/
cp keepalived.conf.sample keepalived.conf
#2.1-【keepalived.conf】文件的完整内容【如下是主节点的配置,备节点的配置也是如下内容,只是[priority 100]调整为[priority 80]】
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id haproxy_DEVEL
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2
}
vrrp_instance HAproxy_1 {
state BACKUP
interface ens33
virtual_router_id 118
priority 100
advert_int 2
nopreempt
authentication {
auth_type PASS
auth_pass qwer1234
}
notify_master "/usr/bin/python /etc/keepalived/mail_notify.py master"
notify_backup "/usr/bin/python /etc/keepalived/mail_notify.py backup"
notify_fault "/usr/bin/python /etc/keepalived/mail_notify.py fault"
track_script {
check_haproxy
}
virtual_ipaddress {
192.168.1.200/24 dev ens33
}
}
#3-keepalived 邮件通知脚本【mail_notify.py】文件内容
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# ===================== 配置项 =====================
# 发件邮箱
sender = "xxx@163.com"
# 邮箱授权码
mail_pass = "xxxxxxxxx"
# SMTP服务器
smtp_server = "smtp.163.com"
smtp_port = 465
# 接收告警邮箱列表
receivers = ["alert@xxx.com"]
# 主机备注名
host_name = "Keepalived集群节点"
# ==================================================
# 获取keepalived传入状态参数
state = sys.argv[1]
# 状态映射中文
state_map = {
"master": "切换为主节点",
"backup": "切换为备节点",
"fault": "节点出现故障"
}
state_text = state_map.get(state, "未知状态")
# 邮件内容
mail_content = f"""
【Keepalived集群告警通知】
主机名称:{host_name}
当前状态:{state_text}
系统时间:{sys.argv[0]}
请运维人员及时核查集群状态!
"""
# 构造邮件
msg = MIMEText(mail_content, "plain", "utf-8")
msg["From"] = Header(sender, "utf-8")
msg["To"] = Header(",".join(receivers), "utf-8")
msg["Subject"] = Header(f"{host_name}-{state_text}告警", "utf-8")
# 发送邮件
try:
smtp = smtplib.SMTP_SSL(smtp_server, smtp_port)
smtp.login(sender, mail_pass)
smtp.sendmail(sender, receivers, msg.as_string())
smtp.quit()
print("邮件发送成功")
except Exception as e:
print(f"邮件发送失败:{str(e)}")
#keepalived服务操作
systemctl daemon-reload
systemctl start keepalived
systemctl enable keepalived
三、k8s高可用集群的安装部署
3.1、安装必要的k8s软件包
openeuler系统在EPOL源中默认提供了稳定的k8s版本,不建议使用k8s官方的版本,官方较新版本可能会出现不兼容问题,因此,直接使用EPOL源安装openeuler版本的k8s即可。
bash
#安装k8s所需的软件包【规划的k8s每台主机都执行一遍】
yum install -y containerd
yum install -y kubernetes*
yum install -y cri-tools
注意:若系统中已经安装了Docker,请确保在安装containerd之前卸载Docker,否则可能会引发冲突。 containerd要求使用1.6.22-15或更高版本,如果下载的版本过低请运行以下命令升级成1.6.22-15版本,或自行升级。
bash
#1-卸载已有docker命令
#1.1-先停止 Docker 服务
systemctl stop docker
systemctl disable docker
#1.2-卸载 Docker 所有安装包
dnf remove -y docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
#1.3-删除残留数据(镜像、容器、卷、配置)
#注意:这一步会清空所有 Docker 数据,不可逆,确认要删再执行
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
rm -rf /etc/docker
#1.4-清理缓存
dnf clean all
#1.5-验证是否卸载完成【执行下面命令,提示找不到命令就说明卸载成功】
docker --version
#2-OpenEuler中升级containerd为1.6.22-15及其更高版本命令
#2.1-下载containerd-1.6.22-27.oe2403sp2.x86_64.rpm包
wget --no-check-certificate https://repo.openeuler.org/openEuler-24.03-LTS-SP2/update/x86_64/Packages/containerd-1.6.22-27.oe2403sp2.x86_64.rpm
#2.2-安装下载好的containerd-1.6.22-27.oe2403sp2.x86_64.rpm包
rpm -Uvh containerd-1.6.22-27.oe2403sp2.x86_64.rpm
3.2、下载cni组件
bash
#下载cni组件【规划的k8s每台主机都执行一遍】
mkdir -p /opt/cni/bin
cd /opt/cni/bin
wget --no-check-certificate https://github.com/containernetworking/plugins/releases/download/v1.9.1/cni-plugins-linux-amd64-v1.9.1.tgz -c
tar -zxvf cni-plugins-linux-amd64-v1.9.1.tgz
3.3、配置containerd及其加速器
bash
#配置containerd【规划的k8s每台主机都执行一遍】
#1-生成containerd的配置文件【config.toml】
mkdir -p /etc/containerd && cd /etc/containerd/
containerd config default > config.toml
#2-编辑生成的containerd配置文件【config.toml】
vi config.toml
#【config.toml】文件修改的内容如下表所示:
| /etc/containerd/config.toml修改内容 | 修改前 | 修改后 |
|---|---|---|
| 配置pause_image | sandbox_image = "registry.k8s.io/pause:3.6" |
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6" |
| 将cgroup驱动指定为systemd | SystemdCgroup = false |
SystemdCgroup = true |
| 关闭"registry.k8s.io"镜像源证书验证 | [plugins."io.containerd.grpc.v1.cri".registry.configs] |
plugins."io.containerd.grpc.v1.cri".registry.configs plugins."io.containerd.grpc.v1.cri".registry.configs."registry.k8s.io".tls insecure_skip_verify = true |
| 配置containerd镜像加速器 | [plugins."io.containerd.grpc.v1.cri".registry.mirrors] |
plugins."io.containerd.grpc.v1.cri".registry.mirrors plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io" endpoint = "[https://docker.1ms.run](https://docker.1ms.run "https://docker.1ms.run")","[https://docker.m.daocloud.io](https://docker.m.daocloud.io "https://docker.m.daocloud.io")","[https://docker.xuanyuan.me](https://docker.xuanyuan.me "https://docker.xuanyuan.me")" |
bash
#【config.toml】文件修改的内容命令如下:
#1-配置pause_image,找到sandbox镜像地址修改为国内的阿里云镜像
sed -i 's#sandbox_image = "registry.k8s.io/pause:3.6"#sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"#' /etc/containerd/config.toml
#2-将cgroup驱动指定为systemd
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
#3-关闭"registry.k8s.io"镜像源证书验证
sed -i '/plugins."io.containerd.grpc.v1.cri".registry.configs/a\
[plugins."io.containerd.grpc.v1.cri".registry.configs."registry.k8s.io".tls]\
insecure_skip_verify = true
' /etc/containerd/config.toml
#4-配置containerd镜像加速器
sed -i '/\[plugins."io.containerd.grpc.v1.cri".registry.mirrors\]/a \
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]\
endpoint = ["https://docker.1ms.run","https://docker.m.daocloud.io","https://docker.xuanyuan.me"]
' /etc/containerd/config.toml
bash
#containerd配置文件修改完成后,重启containerd服务
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
systemctl status containerd.service
3.4、配置crictl使用containerd作为容器运行时
bash
#配置crictl使用containerd作为容器运行时【规划的k8s每台主机都执行一遍】
#执行如下命令后【会生成配置文件/etc/crictl.yaml】
crictl config runtime-endpoint unix:///run/containerd/containerd.sock
crictl config image-endpoint unix:///run/containerd/containerd.sock
cat /etc/crictl.yaml
3.5、配置kubelet使用systemd作为cgroup驱动
bash
#配置kubelet使用systemd作为cgroup驱动
systemctl enable kubelet.service
echo 'KUBELET_EXTRA_ARGS="--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice"' >> /etc/sysconfig/kubelet
3.6、使用Kubeadm创建集群
3.6.1、使用kubeadm初始化master1服务器
bash
#使用Kubeadm创建集群
#1-生成集群配置文件【只需要在两个master节点操作即可】
#1.1-在master节点生成集群配置文件
cd
kubeadm config print init-defaults --component-configs KubeletConfiguration >> kubeletConfig.yaml
#1.2-编辑master节点生成的集群配置文件(编辑内容请看下表)
#2-初始化部署k8s集群【只需要在master节点操作即可】
#2.0-在正式初始化k8s集群前需要检查【192.168.1.51、192.168.1.152】两台服务器上的haproxy、keepalived是否启动
#这是因为:由于在初始化k8s集群时,会读取apiserver地址,所以需要先启动keepalived+haproxy集群服务,保证VIP地址正常可访问,启动完成后,确认VIP地址可访问即可
systemctl start haproxy
systemctl status haproxy
ps -ef | grep haproxy
systemctl start keepalived.service
systemctl status keepalived.service
tail -f /var/log/messages
#注意【keepalived设置的VIP地址(如:192.168.1.200)只能绑定在一台服务器的网卡(如:ens33)上,若绑定在两台上则是脑裂,需要解决】
ip a
#2.1-初始化k8s集群
#注意:若初始化失败,可执行【kubeadm reset --force】命令重置,继续执行初始化:
kubeadm init --config kubeletConfig.yaml
#2.2-初始化成功后,指定kubectl使用的配置文件
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
#2.3-获取k8s集群下的所有节点【注意:查看k8s集群中的节点都是NotReady 状态,这是因为还没有安装网络插件,接下来会配置安装】
kubectl get nodes
| kubeadm.yaml文件修改属性 | 说明 |
|---|---|
| advertiseAddress | 值配置k8s中的master节点所在服务器IP,可通过【ip a】命令获取 |
| criSocket | 值配置containerd.sock所在路径(默认是:unix:///var/run/containerd/containerd.sock); 可通过执行【find / -name containerd.sock】命令查找 |
| name | 值配置文件所在主机的名称,可通过【hostname】命令获取 |
| imageRepository | 值是镜像仓库地址(默认是【registry.k8s.io】; 国内可修改为【registry.aliyuncs.com/google_containers】) |
| kubernetesVersion | 值是版本信息,必须与我们安装的k8s组件版本一致,可通过【kubelet --version】或【kubeadm version】或【kubectl version】命令获取。 |
| serviceSubnet | 指定service网络地址段。持默认(10.96.0.0/12)即可 |
| podSubnet | 指定pod网络地址段。保持默认即可。 |
| scheduler: {} | 配置k8s高可用集群的VIP地址:找到【scheduler: {}】并在该行下面新增【controlPlaneEndpoint: "192.168.1.200:6443"】 |



3.6.2、将master2服务器加入到k8s集群中
k8s-master1节点初始化完成后,还需要将k8s-master2节点也加入集群:
bash
#将k8s-master2节点加入集群【以下操作都是在k8s-master2服务器上操作】
#1-创建k8s所需的证书目录
mkdir -p /etc/kubernetes/pki/
mkdir -p /etc/kubernetes/pki/etcd
#2-从k8s-master1节点拉取通用的证书到k8s-master2服务器上
scp -r 192.168.1.140:/etc/kubernetes/pki/ca.* /etc/kubernetes/pki/
scp -r 192.168.1.140:/etc/kubernetes/pki/sa.* /etc/kubernetes/pki/
scp -r 192.168.1.140:/etc/kubernetes/pki/front-proxy-ca.* /etc/kubernetes/pki/
#3-从k8s-master1节点拉取认证文件admin.conf与etcd的通用证书到k8s-master2服务器上
scp -r 192.168.1.140:/etc/kubernetes/admin.conf /etc/kubernetes/
scp -r 192.168.1.140:/etc/kubernetes/pki/etcd/ca* /etc/kubernetes/pki/etcd
#4-将k8s-master2服务器加入到k8s的control-plane中(从k8s-master初始化完成后结尾获取【kubeadm join】开头结尾是【--control-plane】的命令在k8s-master2服务器执行)
#注意:在这里的--token来自前面kubeadm init输出提示,如果当时没有记录下来可以通过【kubeadm token create --ttl 0 --print-join-command】命令找回, token是有24小时有效期的:
kubeadm join 192.168.1.200:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:656afd301a0ace54d963c4b52a02d9daf803c414a6c23911c30974c4c9265839 \
--control-plane
#4.1-在k8s-master2服务器也成功加入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 get nodes




3.6.3、将其他节点加入到k8s集群中
bash
#将其他节点(192.168.1.142、192.168.1.143)加入到k8s集群中
#1-在其他节点中执行刚才在master1节点下初始化成功后末尾显示的【kubeadm join】开头,且没有【--control-plane】结尾的内容就是加入命令
##注意:在这里的--token来自前面kubeadm init输出提示,如果当时没有记录下来可以通过【kubeadm token create --ttl 0 --print-join-command】命令找回, token是有24小时有效期的:
kubeadm join 192.168.1.200:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:656afd301a0ace54d963c4b52a02d9daf803c414a6c23911c30974c4c9265839
#2.5-再次查看k8s集群节点情况,是否其余的两个节点已经添加到集群中,如果节点状态显示为not ready,是因为网络插件未成功部署。所以,接下来还需要安装网络插件。
kubectl get nodes



注意:
1、上面的加入控制平面和work节点的命令,在master1节点初始化成功后,会输出token信息,记得保存备份,因为token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,可以直接在master1节点上,使用命令快捷生成:
bash
#在master1节点重新生成token命令
kubeadm token create --print-join-command
2、如果节点状态显示为【Not Ready】,是因为网络插件未成功部署。因此,接下来还需要安装网络插件。
3.7、安装部署网络插件
bash
#部署网络插件
#1-下载calico资源文件
wget https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml -c
#2-使用kubectl apply部署网络插件calico.yaml
kubectl apply -f calico.yaml
#2.1-Calico网络插件的安装过程,需要下载三个镜像文件【docker.io/calico/cni】【docker.io/calico/node】【docker.io/calico/kube-controllers】(可通过【cat calico.yaml | grep image】命令查看到是这几个镜像),下载完成,网络插件即可正常工作。等网络插件镜像下载完成以后,看到node的状态会变成ready,执行如下命令查看:
crictl images
kubectl get nodes
#2.2-【可选】如果发现某个节点还是处于NotReady状态,可以重启此节点的kubelet服务,然后此节点就会重新下载需要的镜像。
systemctl restart kubelet
systemctl status kubelet
#2.3-查看pod状态
kubectl get pods -n kube-system

3.8、k8s集群验证
bash
#创建一个标准的 Kubernetes Deployment 资源定义文件用来验证k8s集群是否安装成功
#1-创建一个名为 http-deployment 的 Deployment
#2-启动 3 个副本的 Nginx Pod
#3-使用标签 app: http_server 进行 Pod 管理
#4-容器镜像为官方仓库中的 nginx:1.28.3
mkdir -p /data/k8s/verify && cd /data/k8s/verify
vi httptest.yml
#【httptest.yml】文件完整内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-deployment
spec:
replicas: 3
selector:
matchLabels:
app: http_server
template:
metadata:
labels:
app: http_server
spec:
containers:
- name: http-web
image: library/nginx:1.28.3
ports:
- containerPort: 80
#在k8s的master节点上直接部署该服务
kubectl apply -f httptest.yml
#查看运行状态
kubectl get pods
#让外部网络可以访问到k8s集群内部的服务
vi service.yml
#【service.yml】文件的完整内容:
apiVersion: v1
kind: Service
metadata:
name: service-httpd
spec:
type: NodePort
selector:
app: http_server
ports:
- protocol: TCP
port: 8080
targetPort: 80
#创建service
kubectl apply -f service.yml
#查看service信息
kubectl get svc service-httpd
#最后在浏览器输入k8s集群的任意节点IP:端口即可访问到部署好的nginx服务,则表示k8s部署成功


3.9、HAProxy的监控k8s集群界面
直接在浏览器输入keepalived的VIP(192.168.1.200:19088/haproxy-status)后输入haproxy中配置的账号【admin】密码【Strong@Passw0rd_2025】即可访问,如下图所示:
