详解K8s集群搭建:从环境准备到成功运行
系统环境准备
安装系统
根据要求安装一台 4 核心CPU
,4G
内存,两块网卡(第一块为仅主机
模式,第二块为 NAT
模式),磁盘空间为 100GB
的 Redhat 9.0以上系统。
初始化环境
配置本地仓库
# 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
[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)不足时,将暂时不用的内存页面转移到磁盘上,从而释放物理内存供其他进程使用。
# 禁用指定的交换空间,-a 表示禁用全部
[root@192 ~]# swapoff -a
# 在匹配包含 swap 的任意行前添加 #
[root@192 ~]# sed -i 's/.*swap.*/#&/' /etc/fstab
[root@192 ~]# free -mtotal used free shared buff/cache available
Mem: 1738 556 451 6 913 1182
Swap: 0 0 0
安装基本软件
# 安装完后重启生效代码补全
[root@192 ~]# dnf install net-tools nfs-utils vim wget curl bash-completion device-mapper-persistent-data psmisc -y
[root@192 ~]# init 6
修改最大连接数
[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 转发(系统可作为路由器或网关,转发不同网络接口之间的数据包)。
[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 主机
修改主机名
[root@192 ~]# hostnamectl hostname k8s-master01
[root@192 ~]# hostnamectl hostname k8s-node01
[root@192 ~]# hostnamectl hostname k8s-node02
修改仅主机网卡
这里我的仅主机IP段为 60。
[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 1000link/ether 00:0c:29:5f:bf:b2 brd ff:ff:ff:ff:ff:ffaltname enp3s0inet 192.168.10.134/24 brd 192.168.60.255 scope global noprefixroute ens160valid_lft forever preferred_lft foreverinet6 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 1000link/ether 00:0c:29:5f:bf:bc brd ff:ff:ff:ff:ff:ffaltname enp11s0inet 192.168.23.137/24 brd 192.168.23.255 scope global dynamic noprefixroute ens192valid_lft 1739sec preferred_lft 1739secinet6 fe80::20c:29ff:fe5f:bfbc/64 scope link noprefixroute valid_lft forever preferred_lft forever
其中 ens160
为仅主机网络模式的网络设备,而 ens192
为 NAT
网络模式的网络设置。我们修改 ens160
的 IP 地址、网关指向 ikuai
,以及DNS
。
# 这里网关要跟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模式网卡,以防止安装集群时出现绑定网卡错误的问题。
[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)
配置主机映射
[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地址即可
。
修改仅主机网卡
# 修改主机名
[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
添加源并安装
# 安装工具包
[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
配置镜像源
[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"]
}
启动并验证
[root@k8s-master01 ~]# systemctl enable --now docker
# 查看版本
[root@k8s-master01 ~]# docker version
Client: Docker Engine - CommunityVersion: 28.3.1API version: 1.51Go version: go1.24.4Git commit: 38b7060Built: Wed Jul 2 20:58:10 2025OS/Arch: linux/amd64Context: defaultServer: Docker Engine - CommunityEngine:Version: 28.3.1API version: 1.51 (minimum version 1.24)Go version: go1.24.4Git commit: 5beb93dBuilt: Wed Jul 2 20:56:24 2025OS/Arch: linux/amd64Experimental: falsecontainerd:Version: 1.7.27GitCommit: 05044ec0a9a75232cad458027ca83437aae3f4darunc:Version: 1.2.5GitCommit: v1.2.5-0-g59923efdocker-init:Version: 0.19.0GitCommit: de40ad0
安装 CRI
安装 cri-docker
# 网址下载容易失败,建议本地上传解压
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-dockerd
1.配置 cri-docker 服务
[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 套接字
[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
EOF
3.启动服务
# 重载配置
[root@k8s-master01 ~]# systemctl daemon-reload
# 配置开机自启
[root@k8s-master01 ~]# systemctl enable --now cri-docker
# 查看是否运行
[root@k8s-master01 ~]# systemctl is-active cri-docker
1.生成配置文件
# 创建目录
[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.设置开机启动
# 设置开机启动
[root@k8s-master01 ~]# systemctl enable --now containerd# 查看版本
[root@k8s-master01 ~]# containerd --version# 查看镜像
[root@k8s-master01 ~]# crictl images
IMAGE TAG IMAGE ID SIZE
3.安装 libseccomp
# 下载软件
[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.so
4.安装 runc
# 下载软件
[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 源
# 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.repo
2.安装和启动服务
[!note]
注意:安装时
ikuai
虚拟机一定要保持开启状态,因为网关设置的是ikuai
。
[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"}
查看所需镜像
[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
# 此操作只需要在 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
。
输出信息
[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-proxyYour Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou 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
文件复制到该目录下。
# 根据输出信息执行以下三条命令
[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:6443name: kubernetes
contexts:
- context:cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-adminuser: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.2
kubeconfig
是 kubectl
等客户端工具连接 Kubernetes
集群的配置文件,包含:
- 集群的
API Server
地址 - 认证方式(证书、令牌等)
- 上下文(
Context
)配置(默认连接的集群和用户)
最后可以看到,当前 Kubernetes
集群已经出现了一个节点了。
增加工作节点
我们在 k8s-node01
和 k8s-node02
两个节点上分别执行如下命令来将其加入到 Kubernetes 集群中。
# 复制前面主节点输出注意最后的命令
# 注意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 BootstrapThis 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
主节点上执行如下命令来查看集群信息。
[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
安装说明文档。
说明文档:https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managedonprem/onpremises#install-calico
然后点击 Manifest
下面的 Install Calico with Kubernetes API datastore, more than 50 nodes
链接。
然后复制命令将配置文件下载到本地。
# 下载配置文件
[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.yamlimage: docker.io/calico/cni:v3.30.2imagePullPolicy: IfNotPresentimage: docker.io/calico/cni:v3.30.2imagePullPolicy: IfNotPresentimage: docker.io/calico/node:v3.30.2imagePullPolicy: IfNotPresentimage: docker.io/calico/node:v3.30.2imagePullPolicy: IfNotPresentimage: docker.io/calico/kube-controllers:v3.30.2imagePullPolicy: IfNotPresent
- image: docker.io/calico/typha:v3.30.2imagePullPolicy: IfNotPresent
修改配置文件
将 calico.yaml
配置文件中 CALICO_IPV4POOL_CIDR
修改为初始集群时指定的 Pod
地址,即 --pod network-cidr=10.244.0.0/16
参数所指定的地址。然后将 CALICO_IPV4POOL_IPIP
和 CALICO_IPV4POOL_VXLAN
都关闭,即使用 BGP
模式。
[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_VXLANvalue: "Never"# Enable or Disable VXLAN on the default IPv6 IP pool.- name: CALICO_IPV6POOL_VXLANvalue: "Never"
........# no effect. This should fall within `--cluster-cidr`.# - name: CALICO_IPV4POOL_CIDR# value: "192.168.0.0/16"- name: CALICO_IPV4POOL_CIDRvalue: "10.244.0.0/16"# Disable file logging so `kubectl logs` works.
修改完成后保存退出。
上传镜像文件
# 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
压缩包进行解压。
# 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
中。
# 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
节点上执行如下命令:
[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
可以发现:集群中各个节点都已经处于就绪状态了。
# 查看集群节点详细信息
[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 3h33m
k8s集群搭建完毕,由于有的镜像文件获取不便展示,如有需要欢迎私信交流学习或打包给你,共同进步。