系统环境准备
安装系统
根据要求安装一台 4 核心CPU,4G内存,两块网卡(第一块为仅主机模式,第二块为 NAT 模式),磁盘空间为 100GB 的 Redhat 9.0以上系统。
初始化环境
配置本地仓库
            
            
              bash
              
              
            
          
          # 1. 配置本地仓库
[root@192 ~]# vi /etc/yum.repos.d/bendi.repo
[root@192 ~]# cat /etc/yum.repos.d/bendi.repo
[BaseOS]
name=BaseOS
baseurl=/mnt/BaseOS
gpgcheck=0
[AppStream]
name=AppStream
baseurl=/mnt/AppStream
gpgcheck=0
# 2. 配置自动挂载
[root@192 ~]# cat /etc/fstab
...
/dev/sr0	/mnt	iso9660		defaults	0 0
# 3. 验证挂载
[root@192 ~]# systemctl daemon-reload
[root@192 ~]# mount -a
[root@192 ~]# df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sr0         12G   12G     0 100% /mnt关闭防火墙和SELinux
            
            
              bash
              
              
            
          
          [root@192 ~]# systemctl disable --now firewalld
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
[root@192 ~]# sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
[root@192 ~]# setenforce 0关闭交换分区
交换空间 是硬盘上的一块区域,用于在物理内存 (RAM)不足时,将暂时不用的内存页面转移 到磁盘上,从而释放物理内存供其他进程使用。
            
            
              bash
              
              
            
          
          # 禁用指定的交换空间,-a 表示禁用全部
[root@192 ~]# swapoff -a
# 在匹配包含 swap 的任意行前添加 #
[root@192 ~]# sed -i 's/.*swap.*/#&/' /etc/fstab
[root@192 ~]# free -m
               total        used        free      shared  buff/cache   available
Mem:            1738         556         451           6         913        1182
Swap:              0           0           0安装基本软件
            
            
              bash
              
              
            
          
          # 安装完后重启生效代码补全
[root@192 ~]# dnf install net-tools nfs-utils vim wget curl bash-completion device-mapper-persistent-data psmisc -y
[root@192 ~]# init 6修改最大连接数
            
            
              bash
              
              
            
          
          [root@192 ~]# vim /etc/security/limits.conf
# End of file
*       soft    nofile  655350
*       hard    nofile  655350
*       soft    nproc   655350
*       hard    nproc   655350
*       soft    memlock unlimited
*       hard    memlock unlimited安装 ipvs 和路由转发
et.ipv4.ip_forward 是控制 IPv4 转发的内核参数:
- 值为 0时,关闭 IPv4 转发(默认值,系统仅作为终端节点,不转发数据包);
- 值为 1时,开启 IPv4 转发(系统可作为路由器或网关,转发不同网络接口之间的数据包)。
            
            
              bash
              
              
            
          
          [root@192 ~]# dnf install ipvsadm -y
# 开启 IPv4 转发功能
[root@192 ~]# echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
[root@192 ~]# sysctl -p
net.ipv4.ip_forward = 1做好以上配置后,我们为虚拟机做个快照 ,这台虚拟机就作为模板机用于克隆。
集群准备
克隆一台 k8s 虚拟机,用作 Kubernetes 集群的 Master 节点,三台主机配置差异不大,可以做完Master主机后直接克隆两台,在Master基础上修改IP地址即可。
主机规划
主机规划如下表所示:
| 主机名 | IP 地址 | 配置最低要求 | 角色 | 
|---|---|---|---|
| k8s-master01, m1 | 192.168.10.11 | CPU≥2,MEM≥2GB,DISK=100G | Master | 
| k8s-node01, n1 | 192.168.10.12 | CPU≥1,MEM≥1GB,DISK=100G | Worker | 
| k8s-node02, n2 | 192.168.10.13 | CPU≥1,MEM≥1GB,DISK=100G | Worker | 
配置 Master 主机
修改主机名
            
            
              bash
              
              
            
          
          [root@192 ~]# hostnamectl hostname k8s-master01
[root@192 ~]# hostnamectl hostname k8s-node01
[root@192 ~]# hostnamectl hostname k8s-node02修改仅主机网卡
这里我的仅主机IP段为 60。
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# ls /etc/NetworkManager/system-connections/
ens160.nmconnection ens192.nmconnection
[root@k8s-master01 ~]# ip a show ens160 && ip a show ens192 
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:5f:bf:b2 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 192.168.10.134/24 brd 192.168.60.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe5f:bfb2/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:5f:bf:bc brd ff:ff:ff:ff:ff:ff
    altname enp11s0
    inet 192.168.23.137/24 brd 192.168.23.255 scope global dynamic noprefixroute ens192
       valid_lft 1739sec preferred_lft 1739sec
    inet6 fe80::20c:29ff:fe5f:bfbc/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever其中 ens160 为仅主机网络模式 的网络设备,而 ens192 为 NAT 网络模式的网络设置。我们修改 ens160 的 IP 地址、网关指向 ikuai,以及DNS。
            
            
              bash
              
              
            
          
          # 这里网关要跟ikuai的网关相同为200
[root@k8s-master01 ~]# nmcli c m ens160 ipv4.method manual ipv4.addresses 192.168.60.11/24 ipv4.dns "223.5.5.5 8.8.8.8" ipv4.gateway 192.168.60.200 connection.autoconnect yes
[root@k8s-master01 ~]# nmcli c up ens160
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)同时,暂时关闭 NAT模式网卡,以防止安装集群时出现绑定网卡错误的问题。
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# nmcli c modify ens192 connection.autoconnect no
[root@k8s-master01 ~]# nmcli c up ens192
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)配置主机映射
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# cat > /etc/hosts <<EOF
192.168.10.11   k8s-master01 m1
192.168.10.12   k8s-node01 n1
192.168.10.13   k8s-node02 n2
192.168.10.14   minio
192.168.10.20   harbor.registry.com harbor
EOF配置好后做好快照。
配置节点主机
可以直接在master主机基础上克隆两台主机,只用修改IP地址即可。
修改仅主机网卡
            
            
              bash
              
              
            
          
          # 修改主机名
[root@192 ~]# hostnamectl hostname k8s-node01
[root@192 ~]# hostnamectl hostname k8s-node02
# 克隆的master主机只用修改IP即可
[root@k8s-node01 ~]# nmcli c m ens160 ipv4.addresses 192.168.10.12/24 
[root@k8s-node01 ~]# nmcli c up ens160
[root@k8s-node02 ~]# nmcli c m ens160 ipv4.addresses 192.168.10.13/24 
[root@k8s-node02 ~]# nmcli c up ens160
# 两台都暂时关闭NAT模式网卡,以防止安装集群时出现绑定网卡错误的问题
[root@k8s-node01 ~]# nmcli c modify ens192 connection.autoconnect no
[root@k8s-node01 ~]# nmcli c up ens192主机映射跟master主机相同,配置好后做好快照。
搭建 Kubernetes 集群
!note
注意:以下操作都需要在 k8s-master01、k8s-node01 和 k8s-node02 这三台主机上执行。
安装 docker
添加源并安装
            
            
              bash
              
              
            
          
          # 安装工具包
[root@k8s-master01 ~]# dnf install yum-utils -y
# 安装 docker 仓库,这里使用阿里云
[root@k8s-master01 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/rhel/docker-ce.repo
# 安装docker
[root@k8s-master01 ~]# dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y配置镜像源
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# cat /etc/docker/daemon.json 
{
    "default-ipc-mode": "shareable",
    "data-root": "/data/docker",
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m",
        "max-file": "50"
    },
    "insecure-registries": ["https://harbor.registry.com"],
    "registry-mirrors":[
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run",
        "https://func.ink",
        "https://docker.hlmirror.com",
        "https://docker.imgdb.de",
        "https://docker-0.unsee.tech",
        "https://docker.rainbond.cc",
        "https://lispy.org",
        "https://docker.xiaogenban1993.com",
        "https://mirror.ccs.tencentyun.com"
    ]
}启动并验证
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# systemctl enable --now docker
# 查看版本
[root@k8s-master01 ~]# docker version
Client: Docker Engine - Community
 Version:           28.3.1
 API version:       1.51
 Go version:        go1.24.4
 Git commit:        38b7060
 Built:             Wed Jul  2 20:58:10 2025
 OS/Arch:           linux/amd64
 Context:           default
Server: Docker Engine - Community
 Engine:
  Version:          28.3.1
  API version:      1.51 (minimum version 1.24)
  Go version:       go1.24.4
  Git commit:       5beb93d
  Built:            Wed Jul  2 20:56:24 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.27
  GitCommit:        05044ec0a9a75232cad458027ca83437aae3f4da
 runc:
  Version:          1.2.5
  GitCommit:        v1.2.5-0-g59923ef
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0安装 CRI
安装 cri-docker
            
            
              bash
              
              
            
          
          # 网址下载容易失败,建议本地上传解压
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.17/cri-dockerd-0.3.17.amd64.tgz
# 解压文件并复制到对应目录
tar -zxf cri-dockerd-0.3.17.amd64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
# 或者直接解压至指定目录
tar -zxf cri-dockerd-0.3.17.amd64.tgz -C /usr/bin/
# 设置文件可执行权限
chmod +x /usr/bin/cri-dockerd1.配置 cri-docker 服务
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# cat > /usr/lib/systemd/system/cri-docker.service <<EOF
[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.10
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=registry.k8s.io/pause:3.10
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
EOF!note
注意:
- 此文件也可以从 wget https://github.com/Mirantis/cri-dockerd/archive/refs/tags/v0.3.17.tar.gz 包中
packaging/systemd/目录下获取。- 然后修改
/etc/systemd/system/cri-docker.service文件,为Service.ExecStart字段增加--network-plugin与--pod-infra-container-image选项。
--pod-infra-container-image镜像tag需要根据具体k8s安装版本指定。也就是要修改网络和根容器镜像。
2.配置 cri-docker 套接字
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# cat > /usr/lib/systemd/system/cri-docker.socket <<EOF
[Unit]
Description=CRI Docker socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF3.启动服务
            
            
              bash
              
              
            
          
          # 重载配置
[root@k8s-master01 ~]# systemctl daemon-reload
# 配置开机自启
[root@k8s-master01 ~]# systemctl enable --now cri-docker
# 查看是否运行
[root@k8s-master01 ~]# systemctl is-active cri-docker1.生成配置文件
            
            
              bash
              
              
            
          
          # 创建目录
[root@k8s-master01 ~]# mkdir /etc/containerd
# 生成默认配置文件
[root@k8s-master01 ~]# containerd config default > /etc/containerd/config.toml
# 编辑配置文件
[root@k8s-master01 ~]# vim /etc/containerd/config.toml
# 修改为3.10,对于 kubernetes1.32.3 而言为 3.10
sandbox_image = "registry.k8s.io/pause:3.10" 2.设置开机启动
            
            
              bash
              
              
            
          
          # 设置开机启动
[root@k8s-master01 ~]# systemctl enable --now containerd
# 查看版本
[root@k8s-master01 ~]# containerd --version
# 查看镜像
[root@k8s-master01 ~]# crictl images
IMAGE TAG IMAGE ID SIZE3.安装 libseccomp
            
            
              bash
              
              
            
          
          # 下载软件
[root@k8s-master01 ~]# wget https://github.com/opencontainers/runc/releases/download/v1.2.6/libseccomp-2.5.5.tar.gz
# 解压软件
[root@k8s-master01 ~]# tar -zxf libseccomp-2.5.5.tar.gz
# 进入解压目录
[root@k8s-master01 ~]# cd libseccomp-2.5.5
# 安装gperf文件,用于编辑安装时用
[root@k8s-master01 ~]# dnf install gperf -y
# 编译配置
[root@k8s-master01 ~]# ./configure
# 编译并安装
[root@k8s-master01 ~]# make && make install
# 验证安装
[root@k8s-master01 ~]# find / -name "libseccomp.so"
/root/libseccomp-2.5.4/src/.libs/libseccomp.so
/usr/local/lib/libseccomp.so4.安装 runc
            
            
              bash
              
              
            
          
          # 下载软件
[root@k8s-master01 ~]# wget https://github.com/opencontainers/runc/releases/download/v1.2.6/runc.amd64
# 修改权限
[root@k8s-master01 ~]# chmod +x runc.amd64
# 查找containerd安装时已安装的runc所在位置,然后替换
[root@k8s-master01 ~]# which runc
/usr/local/sbin/runc
# 删除原来的runc文件
[root@k8s-master01 ~]# rm -rf `which runc`
# 替换containerd安装已安装的runc
[root@k8s-master01 ~]# mv runc.amd64 /usr/local/sbin/runc
# 执行runc命令,如果有命令帮助则为正常
[root@k8s-master01 ~]# runc --version
runc version 1.1.9
commit: v1.1.9-0-gccaecfcb
spec: 1.0.2-dev
go: go1.20.3
libseccomp: 2.5.5至此,容器运行时的准备就完成了。
安装 Kubernetes
配置仓库
1.添加 Kubernetes 源
            
            
              bash
              
              
            
          
          # tee用于将标准输入(stdin)同时输出到标准输出(stdout,即屏幕)
[root@k8s-master01 ~]# cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.33/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.33/rpm/repodata/repomd.xml.key
EOF
[root@k8s-master01 ~]# ls /etc/yum.repos.d/
bendi.repo       docker-ce.repo   kubernetes.repo  redhat.repo2.安装和启动服务
!note
注意 :安装时
ikuai虚拟机一定要保持开启状态 ,因为网关设置的是ikuai。
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# dnf install -y kubelet kubeadm kubectl
[root@k8s-master01 ~]# systemctl enable --now kubelet
[root@k8s-master01 ~]# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"33", EmulationMajor:"", EmulationMinor:"", MinCompatibilityMajor:"", MinCompatibilityMinor:"", GitVersion:"v1.33.2", GitCommit:"a57b6f7709f6c2722b92f07b8b4c48210a51fc40", GitTreeState:"clean", BuildDate:"2025-06-17T18:39:42Z", GoVersion:"go1.24.4", Compiler:"gc", Platform:"linux/amd64"}查看所需镜像
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# kubeadm config images list
registry.k8s.io/kube-apiserver:v1.33.2
registry.k8s.io/kube-controller-manager:v1.33.2
registry.k8s.io/kube-scheduler:v1.33.2
registry.k8s.io/kube-proxy:v1.33.2
registry.k8s.io/coredns/coredns:v1.12.0
registry.k8s.io/pause:3.10
registry.k8s.io/etcd:3.5.21-0
# 在主节点上传k8s镜像,分界点上传分节点镜像并加载
[root@k8s-master01 ~]# docker load -i k8s-images-v1.33.2.tar
[root@k8s-node01 ~]# docker load -i k8s-node-images-v1.33.2.tar
[root@k8s-node02 ~]# docker load -i k8s-node-images-v1.33.2.tar
# 查看镜像
[root@k8s-master01 ~]# docker images 
REPOSITORY                                TAG        IMAGE ID       CREATED         SIZE
registry.k8s.io/kube-apiserver            v1.33.2    ee794efa53d8   3 weeks ago     102MB
registry.k8s.io/kube-scheduler            v1.33.2    cfed1ff74892   3 weeks ago     73.4MB
registry.k8s.io/kube-proxy                v1.33.2    661d404f36f0   3 weeks ago     97.9MB
registry.k8s.io/kube-controller-manager   v1.33.2    ff4f56c76b82   3 weeks ago     94.6MB
registry.k8s.io/etcd                      3.5.21-0   499038711c08   3 months ago    153MB
registry.k8s.io/coredns/coredns           v1.12.0    1cf5f116067c   7 months ago    70.1MB
registry.k8s.io/pause                     3.10       873ed7510279   13 months ago   736kB初始化主节点
主节点 需要导入全部镜像 ,从节点 只需导入 kube-proxy、coredns、pause 这三个镜像。
官方文档:https://kubernetes.io/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-init/#custom-images
            
            
              bash
              
              
            
          
          # 此操作只需要在 k8s-master01 节点上执行,注意IP改为自己的
[root@k8s-master01 ~]# kubeadm init --apiserver-advertise-address=192.168.60.11 \
--kubernetes-version=1.33.2 \
--service-cidr=10.10.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all \
--cri-socket unix:///var/run/cri-dockerd.sock
# 以下用于阿里云下载
--image-repository=registry.aliyuncs.com/google_containers \!note
命令解析如下:
--apiserver-advertise-address=192.168.60.11:指定主服务器的IP地址 是多少,也就是 master主机的地址。
--image-repository:指定控制平面镜像 的仓库地址(默认registry.k8s.io),当前为阿里镜像仓库地址 ,也可指向自己的私有镜像仓库地址 如my-registry.com/k8s。
--kubernetes-version=1.33.0:指定 Kubernetes 版本 (默认最新稳定版),固定集群版本,避免自动升级导致兼容性问题。
--service-cidr=10.10.0.0/12:指定service资源的网络范围。
--pod-network-cidr=10.244.0.0/16:指定pos的网络范围。
--ignore-preflight-errors=all:跳过所有前置的错误检测。
--cri-socket unix:///var/run/cri-dockerd.sock:指定 CRI (容器运行时)的socket路径,如果是containerd则为unix:///run/containerd/containerd.sock。
输出信息
            
            
              bash
              
              
            
          
          [init] Using Kubernetes version: v1.33.2
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master01 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.0.0.1 192.168.60.11]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-master01 localhost] and IPs [192.168.60.11 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master01 localhost] and IPs [192.168.60.11 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "super-admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests"
[kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 501.831592ms
[control-plane-check] Waiting for healthy control plane components. This can take up to 4m0s
[control-plane-check] Checking kube-apiserver at https://192.168.60.11:6443/livez
[control-plane-check] Checking kube-controller-manager at https://127.0.0.1:10257/healthz
[control-plane-check] Checking kube-scheduler at https://127.0.0.1:10259/livez
[control-plane-check] kube-controller-manager is healthy after 1.611841054s
[control-plane-check] kube-scheduler is healthy after 1.781298802s
[control-plane-check] kube-apiserver is healthy after 3.501062562s
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master01 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node k8s-master01 as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: 72ebuv.j19f4p3kada9vd67
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
  export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.60.11:6443 --token 72ebuv.j19f4p3kada9vd67 \
	--discovery-token-ca-cert-hash sha256:b301c41f62363157a624391d9334692e79aa003c2fa345762d7f3ff0cf23b212创建 .kube 目录
根据提示,我们需要在 k8s-master01 主节点的家目录下创建.kube目录,并将 /etc/kubernetes/admin.conf 文件复制到该目录下。
            
            
              bash
              
              
            
          
          # 根据输出信息执行以下三条命令
[root@k8s-master01 ~]# mkdir -p $HOME/.kube
[root@k8s-master01 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master01 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 查看当前用户的 Kubernetes 集群配置文件(kubeconfig)
[root@k8s-master01 ~]# cat .kube/config
apiVersion: v1
clusters:
- cluster:
		certificate-authority-data: ...密文
		server: https://192.168.60.11:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
		client-certificate-data: ...密文
		client-key-data:...密文
		
# 查看节点
[root@k8s-master01 ~]# kubectl get node
NAME           STATUS     ROLES           AGE    VERSION
k8s-master01   NotReady   control-plane   8m5s   v1.33.2kubeconfig 是 kubectl 等客户端工具连接 Kubernetes 集群的配置文件,包含:
- 集群的 API Server地址
- 认证方式(证书、令牌等)
- 上下文(Context)配置(默认连接的集群和用户)
最后可以看到,当前 Kubernetes 集群已经出现了一个节点了。
增加工作节点
我们在 k8s-node01 和 k8s-node02 两个节点上分别执行如下命令来将其加入到 Kubernetes 集群中。
            
            
              bash
              
              
            
          
          # 复制前面主节点输出注意最后的命令
# 注意tokenIP段改为自己的,并指定CRI容器运行时
[root@k8s-node01 ~]# kubeadm join 192.168.60.11:6443 --token 72ebuv.j19f4p3kada9vd67 \
	--discovery-token-ca-cert-hash sha256:b301c41f62363157a624391d9334692e79aa003c2fa345762d7f3ff0cf23b212 \
	--cri-socket unix:///var/run/cri-dockerd.sock
[preflight] Running pre-flight checks
[preflight] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[preflight] Use 'kubeadm init phase upload-config --config your-config-file' to re-upload it.
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 501.778606ms
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
# node2同样操作
[root@k8s-node02 ~]# kubeadm join 192.168.60.11:6443 --token 72ebuv.j19f4p3kada9vd67 \
	--discovery-token-ca-cert-hash sha256:b301c41f62363157a624391d9334692e79aa003c2fa345762d7f3ff0cf23b212 \
		--cri-socket unix:///var/run/cri-dockerd.sock
...!note
命令解析:
kubeadm join 192.168.10.11:6443:指定主节点IP和端口。
--token ge53zg.14u86m07fuz4ywa7:指定token,如果过期 ,需要执行kubeadm token。
create --print-join-command: 命令重新申请。
--discovery-token-ca-cert-hash:指定证书。
--cri-socket unix:///var/run/cri-dockerd.sock:指定CRI(容器运行时 )的socket路径。
查看集群
在 k8s-master01 主节点上执行如下命令来查看集群信息。
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# kubectl get node
NAME           STATUS     ROLES           AGE    VERSION
k8s-master01   NotReady   control-plane   15m    v1.33.2
k8s-node01     NotReady   <none>          2m9s   v1.33.2
k8s-node02     NotReady   <none>          57s    v1.33.2可以看到,集群三个节点都已经创建完成 ,但这三个节点都处于未就绪状态 NotReady。
部署网络插件
Kubernetes 集群如果要能够正常工作,所有容器 都必须工作在一个扁平的网络空间 中。接下来我们就需要部署网络插件来实现这个扁平化网络空间,让 Kubernetes 集群可以正常工作。
下载配置文件
首先在浏览器中输入如下地址,来打开 Calico 安装说明文档。
然后点击 Manifest 下面的 Install Calico with Kubernetes API datastore, more than 50 nodes 链接。
然后复制命令将配置文件下载到本地。
            
            
              bash
              
              
            
          
          # 下载配置文件
[root@k8s-master01 ~]# curl https://raw.githubusercontent.com/projectcalico/calico/v3.30.2/manifests/calico-typha.yaml -o calico.yaml
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 322k 100 322k 0 0 244k 0 0:00:01 0:00:01 --:--:-- 244k
# 查看是否下载成功
[root@k8s-master01 ~]# ls
calico.yaml
# 查看所需要的镜像文件
[root@k8s-master01 ~]# grep image* calico.yaml
		image: docker.io/calico/cni:v3.30.2
		imagePullPolicy: IfNotPresent
		image: docker.io/calico/cni:v3.30.2
		imagePullPolicy: IfNotPresent
		image: docker.io/calico/node:v3.30.2
		imagePullPolicy: IfNotPresent
		image: docker.io/calico/node:v3.30.2
		imagePullPolicy: IfNotPresent
		image: docker.io/calico/kube-controllers:v3.30.2
		imagePullPolicy: IfNotPresent
- image: docker.io/calico/typha:v3.30.2
		imagePullPolicy: IfNotPresent修改配置文件
将 calico.yaml 配置文件中 CALICO_IPV4POOL_CIDR 修改为初始集群 时指定的 Pod 地址,即 --pod network-cidr=10.244.0.0/16 参数所指定的地址。然后将 CALICO_IPV4POOL_IPIP 和 CALICO_IPV4POOL_VXLAN 都关闭 ,即使用 BGP 模式。
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# vim calico.yaml
.........
				# Enable IPIP
				- name: CALICO_IPV4POOL_IPIP
					# value: "Always"
					value: "Off"
				# Enable or Disable VXLAN on the default IP pool.
				- name: CALICO_IPV4POOL_VXLAN
					value: "Never"
				# Enable or Disable VXLAN on the default IPv6 IP pool.
				- name: CALICO_IPV6POOL_VXLAN
					value: "Never"
........
				# no effect. This should fall within `--cluster-cidr`.
				# - name: CALICO_IPV4POOL_CIDR
				# value: "192.168.0.0/16"
				- name: CALICO_IPV4POOL_CIDR
					value: "10.244.0.0/16"
				# Disable file logging so `kubectl logs` works.修改完成后保存退出。
上传镜像文件
            
            
              bash
              
              
            
          
          # master01 节点
[root@k8s-master01 ~]# ls
calico-v3.30.2.tar calico.yaml
# node01 节点
[root@k8s-node01 ~]# ls
calico-v3.30.2.tar
# node02 节点
[root@k8s-node02 ~]# ls
calico-v3.30.2.tar然后将三个节点上的 calico 压缩包进行解压。
            
            
              bash
              
              
            
          
          # master01 节点
[root@k8s-master01 ~]# tar -xvf calico-v3.30.2.tar
cni:v3.30.2.tar.gz
kube-controllers:v3.30.2.tar.gz
node:v3.30.2.tar.gz
typha:v3.30.2.tar.gz
[root@k8s-master01 ~]# ls
anaconda-ks.cfg calico.yaml kube-controllers:v3.30.2.tar.gz typha:v3.30.2.tar.gz calico-v3.30.2.tar cni:v3.30.2.tar.gz node:v3.30.2.tar.gz
# node01 节点
[root@k8s-node01 ~]# tar -xvf calico-v3.30.2.tar
cni:v3.30.2.tar.gz 
kube-controllers:v3.30.2.tar.gz 
node:v3.30.2.tar.gz 
typha:v3.30.2.tar.gz
[root@k8s-node01 ~]# ls
cni:v3.30.2.tar.gz node:v3.30.2.tar.gz calico-v3.30.2.tar kube-controllers:v3.30.2.tar.gz typha:v3.30.2.tar.gz
# node02 节点
[root@k8s-node02 ~]# tar -xvf calico-v3.30.2.tar
cni:v3.30.2.tar.gz
kube-controllers:v3.30.2.tar.gz
node:v3.30.2.tar.gz
typha:v3.30.2.tar.gz
[root@k8s-node02 ~]# ls
cni:v3.30.2.tar.gz node:v3.30.2.tar.gz calico-v3.30.2.tar kube-controllers:v3.30.2.tar.gz typha:v3.30.2.tar.gz导入镜像文件
将三个节点上相关的镜像分别通过 docker load 命令导入到 docker 中。
            
            
              bash
              
              
            
          
          # master01 节点
[root@k8s-master01 ~]# docker load -i kube-controllers:v3.30.2.tar.gz
# node01 节点
[root@k8s-node01 ~]# docker load -i kube-controllers:v3.30.2.tar.gz
# node02 节点
[root@k8s-node02 ~]# docker load -i kube-controllers:v3.30.2.tar.gz安装网络插件
完成上面几步操作后,我们就可以安装 Calico 网络插件了。在 master01 节点上执行如下命令:
            
            
              bash
              
              
            
          
          [root@k8s-master01 ~]# kubectl apply -f calico.yaml
poddisruptionbudget.policy/calico-kube-controllers created
poddisruptionbudget.policy/calico-typha created
serviceaccount/calico-kube-controllers created
...
service/calico-typha created
daemonset.apps/calico-node created
deployment.apps/calico-kube-controllers created
deployment.apps/calico-typha created
# 查看当前的集群状态
[root@k8s-master01 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane 3h27m v1.33.0
k8s-node01 Ready <none> 3h14m v1.33.0
k8s-node02 Ready <none> 3h14m v1.33.0可以发现:集群中各个节点都已经处于就绪状态了。
            
            
              bash
              
              
            
          
          # 查看集群节点详细信息
[root@k8s-master01 ~]# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-master01 Ready control-plane 3h28m v1.33.0 192.168.10.11 <none> Red Hat Enterprise Linux 9.5 (Plow) 5.14.0-503.11.1.el9_5.x86_64 docker://28.1.1
k8s-node01 Ready <none> 3h15m v1.33.0 192.168.10.12 <none> Red Hat Enterprise Linux 9.5 (Plow) 5.14.0-503.11.1.el9_5.x86_64 docker://28.1.1
k8s-node02 Ready <none> 3h15m v1.33.0 192.168.10.13 <none> Red Hat Enterprise Linux 9.5 (Plow) 5.14.0-503.11.1.el9_5.x86_64 docker://28.1.1
# 查看所有的 pod 信息
[root@k8s-master01 ~]# kubectl get pod -A
NAMESPACE NAME READY STATUS
RESTARTS AGE
kube-system calico-kube-controllers-79949b87d-vmm7p 1/1 Running 0 7m9s
kube-system calico-node-5b7c6 1/1 Running 0 7m10s
kube-system calico-node-bdbsm 1/1 Running 0 7m10s
kube-system calico-node-tdxl5 1/1 Running 0 7m10s
kube-system calico-typha-87cb5c68d-766bs 1/1 Running 0 7m9s
kube-system coredns-6766b7b6bb-7b4jk 1/1 Running 0 3h33m
kube-system coredns-6766b7b6bb-tktzb 1/1 Running 0 3h33m
kube-system etcd-k8s-master01 1/1 Running 0 3h33m
kube-system kube-apiserver-k8s-master01 1/1 Running 0 3h33m
kube-system kube-controller-manager-k8s-master01 1/1 Running 0 3h33m
kube-system kube-proxy-7phhl 1/1 Running 0 3h33m
kube-system kube-proxy-clxqj 1/1 Running 0 3h21m
kube-system kube-proxy-kxvw4 1/1 Running 0 3h21m
kube-system kube-scheduler-k8s-master01 1/1 Running 0 3h33mk8s集群搭建完毕,由于有的镜像文件获取不便展示,如有需要欢迎私信交流学习或打包给你,共同进步。