k8s容器编排技术实践——OpenEuler的k8s高可用集群构建实战

k8s容器编排技术实践------OpenEuler安装部署k8shttps://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】即可访问,如下图所示:

相关推荐
java_cj2 小时前
从kubectl学Visitor模式:如何优雅处理多态数据结构的遍历
云原生·golang·k8s·访问者模式
就改了2 小时前
微服务异步场景链路断裂完整解决方案
微服务·云原生·架构
swordbob4 小时前
Nacos vs Eureka
spring cloud·云原生·eureka
万能的知了5 小时前
K8s到底需不需要GPU节点?集群资源分配的底层逻辑
云原生·容器·kubernetes
卧室小白7 小时前
K8S基础-控制器&deploy&pod回滚更新&service
docker·容器·kubernetes
OceanBase数据库官方博客7 小时前
OceanBase × Flink 数据集成系列——旁路导入连接器的批量写入能力
架构·kubernetes·oceanbase
Moshow郑锴7 小时前
Ubuntu26.04之Docker配置国内镜像加速器
云原生·eureka
Jooolin16 小时前
从 DeepSeek、Qwen 到 GPT:一次企业级 AI 知识库项目的模型选型复盘
人工智能·云原生·ai编程
皮皮蟹虾饺20 小时前
DNS协议指南:从报文格式到安全加密与 K8s 实战
安全·容器·kubernetes
阿里云云原生21 小时前
AI Agent 如何“驾驭”云监控?实测自然语言驱动的全链路可观测运维
云原生