文章目录
- 前言
- 一、环境准备
-
- [1.1 节点信息](#1.1 节点信息)
- [1.2 系统要求](#1.2 系统要求)
- [1.3 将镜像导入harbor仓库](#1.3 将镜像导入harbor仓库)
- [1.4 登录harbor仓库查看镜像是否导入成功](#1.4 登录harbor仓库查看镜像是否导入成功)
- 二、基础环境配置(所有节点)
- [三、安装 kubeadm、kubelet、kubectl](#三、安装 kubeadm、kubelet、kubectl)
- 四、配置安装Master节点
- 五、加入worker节点
-
- [5.1 执行kubeadm join加入集群](#5.1 执行kubeadm join加入集群)
- [5.2 如果token过期,执行下述命令加入集群](#5.2 如果token过期,执行下述命令加入集群)
- 5.3查看节点状态
- 六、安装网络插件
-
- [6.1 安装flannel](#6.1 安装flannel)
- [6.2 创建flannel](#6.2 创建flannel)
- [6.3 验证](#6.3 验证)
- 七、常见问题排查
- 总结
前言
Kubernetes(简称 K8s)是当前最流行的容器编排平台。对于初学者或测试环境而言,部署一个单 Master 节点的集群是最常见的方式。本文将手把手教你如何使用 kubeadm 工具快速搭建一个单 Master 的 K8s 集群,并配置使用你自己的私有 Harbor 镜像仓库(已提前导入所需镜像)。
一、环境准备
1.1 节点信息
| 主机名 | IP 地址 | 角色 |
|---|---|---|
| k8s-master | 192.168.80.100 | master |
| k8s-worker1 | 192.168.80.101 | worker |
| k8s-worker2 | 192.168.80.102 | worker |
1.2 系统要求
- 操作系统:Ubuntu 22.04 / CentOS 7/8(本文以 CentOS 7 为例)
- 至少 2 核 CPU、2GB 内存
- 禁用 swap
- 安装好docker环境
- 网络互通,能访问 Harbor 仓库(192.168.80.102:88)
1.3 将镜像导入harbor仓库
bash
## 在有网的机器上拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.6
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6
## 保存镜像
docker save \
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.23.10 \
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.23.10 \
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.23.10 \
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.23.10 \
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0 \
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.6 \
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6 \
-o k8s-v1.23.10-images.tar
#将镜像导入内网harbor服务器192.168.80.102,harbor搭建可参考https://blog.csdn.net/m0_46879864/article/details/150523798?fromshare=blogdetail&sharetype=blogdetail&sharerId=150523798&sharerefer=PC&sharesource=m0_46879864&sharefrom=from_link
docker load -i k8s-v1.23.10-images.tar
[root@k8s-harbor k8s]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver v1.23.10 9ca5fafbe8dc 3 years ago 135MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy v1.23.10 71b9bf9750e1 3 years ago 112MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager v1.23.10 91a4a0d5de4e 3 years ago 125MB
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler v1.23.10 d5c0efb802d9 3 years ago 53.5MB
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd 3.5.1-0 25f8c7f3da61 4 years ago 293MB
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns v1.8.6 a4ca41631cc7 4 years ago 46.8MB
registry.cn-hangzhou.aliyuncs.com/google_containers/pause 3.6 6270bb605e12 4 years ago 683kB
### 在Harbor创建google_containers项目,并将刚才导入的镜像上传到harbor仓库
### 在Harbor上操作
for image in `docker image list|grep registry.cn-hangzhou.aliyuncs|awk '{print $1":"$2}'`;
do
image_new=`echo ${image}| sed 's#registry.cn-hangzhou.aliyuncs.com/#192.168.80.102:88/#'`;
docker image tag ${image} ${image_new};
docker image push ${image_new};
done
### harbor上创建flannel项目
### 导入镜像
wget https://github.com/flannel-io/flannel/releases/download/v0.18.1/flanneld-v0.18.1-amd64.docker
docker load -i flanneld-v0.18.1-amd64.docker
wget https://gitcode.com/open-source-toolkit/58695/blob/main/flannel-flannel-cni-plugin-v1.4.1-flannel1-amd64.tar.gz
docker load -i flannel-flannel-cni-plugin-v1.4.1-flannel1-amd64.tar.gz
[root@k8s-harbor k8s]# docker images | grep flannel
flannel/flannel-cni-plugin v1.4.1-flannel1 1e3c860c213d 19 months ago 10.3MB
flannelcni/flannel v0.18.1-amd64 e237e8506509 3 years ago 62.3MB
### 在Harbor创建flannel项目,并将刚才导入的镜像上传到harbor仓库
### 在Harbor上操作
docker image tag flannel/flannel-cni-plugin:v1.4.1-flannel1 192.168.80.102:88/flannel/flannel-cni-plugin:v1.4.1-flannel1
docker push 192.168.80.102:88/flannel/flannel-cni-plugin:v1.4.1-flannel1
docker image tag flannelcni/flannel:v0.18.1-amd64 192.168.80.102:88/flannel:v0.18.1-amd64
docker push 192.168.80.102:88/flannel:v0.18.1-amd64
1.4 登录harbor仓库查看镜像是否导入成功
浏览器访问:http://192.168.80:102/

二、基础环境配置(所有节点)
bash
### 根据规划设置主机名
hostnamectl set-hostname k8s-master
# 修改/etc/hosts,master节点需包含所有主机域名解析、worker节点需包含vip域名解析
192.168.80.100 k8s-master
192.168.80.101 k8s-worker1
192.168.80.102 k8s-worker2
### 关闭防火墙
systemctl disable --now firewalld
### 关闭selinux, 让容器可以读取主机文件系统
getenforce # 查看
setenforce 0 # 临时关闭
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # 永久关闭
### 关闭swap
swapoff -a && sed -i 's/.*swap.*/#&/' /etc/fstab
### 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# 将br_netfilter模块加载到内核
modprobe br_netfilter
# 文件生效
sysctl -p /etc/sysctl.d/kubernetes.conf
### 时间同步(重要)
yum install ntpdate -y
ntpdate time.windows.com
# 调高ulimit最大打开数
echo '* soft nofile 65535' >> /etc/security/limits.conf
echo '* hard nofile 65535' >> /etc/security/limits.conf
echo '* soft nproc 65535' >> /etc/security/limits.conf
echo '* hard nproc 65535' >> /etc/security/limits.conf
三、安装 kubeadm、kubelet、kubectl
安装kube 3件套
我们需要在所有节点上安装 kubelet、kubeadm 和 kubectl,它们作用分别如下:
- kubeadm:用来初始化集群(Cluster)的指令
- kubelet:运行在集群中的所有节点上,负责启动 pod 和 容器。
- kubectl:这个是 Kubernetes 命令行工具。通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。
bash
[root@k8s-master rpm_pack]# ll
总用量 65412
-rw-r--r--. 1 root root 191000 11月 18 13:38 conntrack-tools-1.4.4-7.el7.x86_64.rpm
-rw-r--r--. 1 root root 6007990 11月 18 13:38 cri-tools-1.19.0-0.x86_64.rpm
-rw-r--r--. 1 root root 9480074 11月 18 13:38 kubeadm-1.23.10-0.x86_64.rpm
-rw-r--r--. 1 root root 9925150 11月 18 13:38 kubectl-1.23.10-0.x86_64.rpm
-rw-r--r--. 1 root root 21515690 11月 18 13:38 kubelet-1.23.10-0.x86_64.rpm
-rw-r--r--. 1 root root 19487362 11月 18 13:38 kubernetes-cni-0.8.7-0.x86_64.rpm
-rw-r--r--. 1 root root 18400 11月 18 13:38 libnetfilter_cthelper-1.0.0-11.el7.x86_64.rpm
-rw-r--r--. 1 root root 18212 11月 18 13:38 libnetfilter_cttimeout-1.0.0-7.el7.x86_64.rpm
-rw-r--r--. 1 root root 23584 11月 18 13:38 libnetfilter_queue-1.0.2-2.el7_2.x86_64.rpm
-rw-r--r--. 1 root root 296632 11月 18 13:40 socat-1.7.3.2-2.el7.x86_64.rpm
## 安装
yum -y localinstall *.rpm
# 设置开机自启
systemctl enable kubelet
四、配置安装Master节点
使用命令引导
bash
kubeadm init \
--apiserver-advertise-address=192.168.80.100 \
--image-repository harbor.eastcom-sw.com/google_containers \
--kubernetes-version v1.23.10 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
结果如下:
bash
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join 192.168.80.100:6443 --token v2i6ju.cgybl0w1qog77pqw \
--discovery-token-ca-cert-hash sha256:2192788dd9520078d3261d0d7bc083a00176b1f9ba48d806329924f842a935f7
## 根据提示配置相关信息
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
五、加入worker节点
5.1 执行kubeadm join加入集群
bash
kubeadm join 192.168.80.100:6443 --token v2i6ju.cgybl0w1qog77pqw \
--discovery-token-ca-cert-hash sha256:2192788dd9520078d3261d0d7bc083a00176b1f9ba48d806329924f842a935f7
## 输出如下
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[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-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.
5.2 如果token过期,执行下述命令加入集群
bash
# master节点执行
[root@k8s-master ~]# kubeadm token create --print-join-command
kubeadm join 192.168.80.100:6443 --token b7wyrl.gvnkoipl0nj2b4aw --discovery-token-ca-cert-hash sha256:1d2da001c90bcaa22a37e58b7fa1f8f77b21d2245bcdef9b3791e91922eaa2d4
# node节点加入
kubeadm join 192.168.80.100:6443 --token b7wyrl.gvnkoipl0nj2b4aw --discovery-token-ca-cert-hash sha256:1d2da001c90bcaa22a37e58b7fa1f8f77b21d2245bcdef9b3791e91922eaa2d4
5.3查看节点状态
bash
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane,master 4h32m v1.23.10
k8s-worker1 NotReady <none> 8m50s v1.23.10
k8s-worker2 NotReady <none> 20s v1.23.10
六、安装网络插件
执行kubectl get node,发现各节点状态还是NotReady,原因是未配置网络插件。
6.1 安装flannel
bash
下载配置文件
wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 下载后的配置文件,需要修改一处
...
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.14.0
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=ens192 # 增加一行。如果不指定,默认找第一块网卡
...
同时修改镜像地址,找到image参数,把后面的地址改成harbor的地址
例如:
[root@k8s-master flannel]# cat kube-flannel.yml |grep image
image: 192.168.80.102:88/flannel/flannel-cni-plugin:v1.4.1-flannel1
image: 192.168.80.102:88/flannel/flannel:v0.18.1-amd64
image: 192.168.80.102:88/flannel/flannel:v0.18.1-amd64
6.2 创建flannel
bash
kubectl create -f kube-flannel.yml
6.3 验证
所有节点的状态变成Ready,表示flannel安装成功
bash
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 4h32m v1.23.10
k8s-worker1 Ready <none> 8m50s v1.23.10
k8s-worker2 Ready <none> 20s v1.23.10
七、常见问题排查
- Q1:kubeadm init 报错 "pulling image XXX failed"
检查192.168.1.39:88/google_containers/kube-apiserver:v1.23.10 镜像是否存在
手动执行 docker pull 192.168.80.100:88/google_containers/kube-apiserver:v1.23.10测试
确保 Docker 已配置信任 Harbor(证书或 insecure-registries) - Q2:节点 NotReady
检查 CNI 插件是否安装
查看 kubelet 日志:journalctl -u kubelet -f
总结
通过本文,你已经成功使用 kubeadm 部署了一个单 Master 的 Kubernetes 集群,并集成了私有的 Harbor 镜像仓库。整个过程的关键在于:
- 提前将 K8s 系统镜像推送到 Harbor
- 使用 --image-repository 指向私有仓库路径
- 正确配置 docker信任 Harbor
这种方式非常适合离线或内网环境下的 K8s 部署,也为后续生产环境的高可用集群打下基础。