K8S部署
1、环境准备
系统初始化
设置主机名
# 在 Master 节点执行
hostnamectl set-hostname k8s-master
# 在 Worker 节点执行
hostnamectl set-hostname k8s-worker1
配置 Hosts 文件
在所有节点的 /etc/hosts 文件中添加节点信息
cat <<EOF | tee -a /etc/hosts
192.168.1.2 k8s-master
192.168.1.3 k8s-worker1
192.168.1.4 k8s-worker2
EOF
关闭 Swap 分区
首先查看系统是否已启用 Swap,确认设备或文件路径:
# 查看活跃的 Swap 设备/文件
swapon --show
# 或查看内存与 Swap 占用情况
free -h
临时关闭 Swap(立即生效)
swapoff -a
永久关闭 Swap(重启生效)
vim /etc/fstab
#注释 Swap 行
#或者直接执行下面语句
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
2、部署安装
安装 依赖
apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
apt-get install -y apt-transport-https ca-certificates curl gpg
#kimi提供
apt-get install -y apt-transport-https ca-certificates curl gpg socat conntrack ipset
写入内核模块配置
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
加载内核模块
modprobe overlay
modprobe br_netfilter
确认模块是否加载
lsmod | grep -E 'overlay|br_netfilter'
将桥接的 IPv4 流量传递到 iptables 的链
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
修改生效
sysctl --system
3、安装容器运行时
下载containerd并安装
选择版本:https://github.com/containerd/containerd/releases
#直接安装
apt install containerd
#或者选择版本下载安装
wget https://github.com/containerd/containerd/releases/download/v2.2.0/containerd-2.2.0-linux-amd64.tar.gz
tar Cxzvf /usr/local containerd-2.2.0-linux-amd64.tar.gz
wget https://raw.githubusercontent.com/containerd/containerd/v2.2.0/containerd.service
mv containerd.service /usr/lib/systemd/system/
systemctl daemon-reload
systemctl enable --now containerd
手动安装 containerd 2.2.x(指定版本)
# 下载 containerd 2.2.3
wget https://github.com/containerd/containerd/releases/download/v2.2.3/containerd-2.2.3-linux-amd64.tar.gz
# 解压到 /usr/local
tar Cxzvf /usr/local containerd-2.2.3-linux-amd64.tar.gz
# 下载 systemd 服务文件
wget https://raw.githubusercontent.com/containerd/containerd/v2.2.3/containerd.service
mv containerd.service /usr/lib/systemd/system/
# 启用并启动
systemctl daemon-reload
systemctl enable --now containerd
containerd配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml && \
grep 'SystemdCgroup' -B 11 /etc/containerd/config.toml
# 使用 sed 替换镜像源
sed -i 's|registry.k8s.io/pause:3.8|registry.aliyuncs.com/google_containers/pause:3.8|g' /etc/containerd/config.toml
systemctl daemon-reload
systemctl restart containerd.service
查看版本
containerd --version
如果手动安装runc
选择版本地址:https://github.com/opencontainers/runc/releases
chmod +x runc.amd64
mv runc.amd64 /usr/bin/runc
#查看runc版本号
runc -v
4、安装 kubernetes 工具
所有节点机器都执行。
安装 kubeadm、kubelet、kubectl 工具
kubectl: 用以控制集群的客户端工具kubeadm: 用以构建一个 k8s 集群的官方工具kubelet: 工作在集群的每个节点,负责容器的一些行为如启动
# 添加 Kubernetes 签名密钥
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key |gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg
# 添加 Kubernetes 仓库
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
# 安装kubeadm、kubectl、kubelet
apt update
apt install kubelet=1.35.* kubeadm=1.35.* kubectl=1.35.*
apt-mark hold kubelet kubeadm kubectl
5、创建配置文件初始化集群
提前拉取了镜像
#查看所需镜像
kubeadm config images list --kubernetes-version=1.35.4
# 提前拉取镜像
kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
# 查看镜像
crictl images
kubeadm-config.yaml配置
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
# 修改为你的 Master 节点的 IP 地址
advertiseAddress: 192.168.1.10
bindPort: 6443
#nodeRegistration:
# 忽略前置检查中的 Swap 错误(如果你没关 Swap)
#ignorePreflightErrors:
#- Swap
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
# 修改为阿里云镜像源,解决 CoreDNS 等镜像拉取慢的问题
imageRepository: registry.aliyuncs.com/google_containers
kubernetesVersion: v1.34.6
networking:
# 【关键】Pod 网段,必须与 Calico 的默认配置匹配
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
dnsDomain: cluster.local
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
# 允许 Kubelet 访问 cgroupfs 驱动
cgroupDriver: systemd
初始化 master 节点
不要在非 master 节点上运行 kubeadm init
# 初始化 kubeadm
kubeadm init --config=kubeadm-config.yaml --upload-certs
#--config=kubeadm-config.yaml: 使用我们刚才创建的配置文件。
#--upload-certs: 允许证书自动分发,方便后续 Worker 节点加入。
# 初始化 kubeadm
kubeadm init \
--apiserver-advertise-address=192.168.0.210 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.35.4 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
# 初始化 kubeadm
kubeadm init --image-repository registry.aliyuncs.com/google_containers
# 报错查看日志
systemctl status kubelet
journalctl -xeu kubelet
# 成功后按照提示执行
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
# 查看已加入的节点,k8s-master 节点执行
kubectl get nodes
# 查看集群状态,k8s-master 节点执行
kubectl get cs
初始化后记住下面Then you can join any number of worker nodes by running the following on each as root:下面信息
#将信息复制下来
kubeadm 192.168.0.210:6443 --token e7qjhz.cjbevut83kc001c8 \
--discovery-token-ca-cert-hash sha256:50783ed23f76a59509a764b65b4e1f5adca9c850a3f87e0c64ca091279561052
如果错过初始化 Kubernetes 集群时输出的用于将其它节点加入集群的 kubeadm join 命令或者需要再次查看它。
可以在 master 节点通过以下方式来获取
添加 master 节点的命令获取方式
#24小时未过期的token查看获取
kubeadm token list
#获取前面拼接的sha256值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^/sha256:/'
# 获取新的 certificate-key
kubeadm init phase upload-certs --upload-certs
# 生成添加 master 节点的命令
kubeadm token create --print-join-command --certificate-key <your-new-certificate-key>
添加 worker 节点的命令获取方式
# 添加 worker 节点的命令获取方式
kubeadm token create --print-join-command
初始化 worker 节点
kubeadm join 192.168.0.210:6443 --token e7qjhz.cjbevut83kc001c8 --discovery-token-ca-cert-hash sha256:50783ed23f76a59509a764b65b4e1f5adca9c850a3f87e0c64ca091279561052
# 配置 kubectl 命令工具
# https://github.com/chaseSpace/k8s-tutorial-cn/blob/main/install_by_kubeadm/install.md#55-%E5%9C%A8%E6%99%AE%E9%80%9A%E8%8A%82%E7%82%B9%E6%89%A7%E8%A1%8Ckubectl
# 普通节点执行 kubectl get nodes 提示错误:memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
mkdir ~/.kube && cp /etc/kubernetes/kubelet.conf ~/.kube/config
# 执行完成后,可以尝试使用如下两条命令测试 kubectl 是否可用
# 查看已加入的节点,k8s-worker01 节点执行
kubectl get nodes
# 从主节点运行以下命令来检查节点状态,k8s-master 节点执行
kubectl get cs
现在有了 master 和 node 节点,但是所有节点状态都是 NotReady,这是因为没有 CNI 网络插件。
6、安装 CNI 网络插件
这里选择 Calico,注意版本需要匹配 k8s 版本,否则无法应用,查看支持的 k8s 版本。
#编辑calico.yaml,去掉#
# - name: CALICO_IPV4POOL_CIDR
# value: "10.244.0.0/16"
#Calico 只在 master 装一次,全集群自动生效
wget --no-check-certificate https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/calico.yaml
kubectl apply -f calico.yaml
#calico镜像拉不动,卡住了,换国内镜像源
#先删除清空脏 CNI 配置(必须!)
kubectl delete -f calico.yaml
rm -rf /etc/cni/net.d/*
systemctl restart containerd
systemctl restart kubelet
# 修改为阿里云 Calico 镜像
sed -i 's|docker.io/calico/|registry.aliyuncs.com/calico/|g' calico.yaml
#修改华为的 Calico 镜像
sed -i 's#docker.io/calico/#swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/#g' calico.yaml
kubectl apply -f calico.yaml
# 查看 pod 状态
kubectl get pods -n kube-system --watch
#查看 kube-system 命名空间下所有 Pod 的详细信息
kubectl get pods -n kube-system -o wide
# 报错看日志( Init:ImagePullBackOff )
kubectl describe pod calico-node-hv4ss -n kube-system
#检查镜像拉取情况
# 查看哪些镜像正在拉取或失败
kubectl get events -n kube-system --sort-by='.lastTimestamp' | tail -20
# 查看 pod 部署的所在 node
kubectl get pods -n kube-system -o wide
# 手动拉取镜像(在所有节点都执行)
export http_proxy=http://192.168.0.104:10809 && export https_proxy=http://192.168.0.104:10809 && export no_proxy="localhost, 127.0.0.1, ::1"
ctr -n k8s.io image pull docker.io/calico/cni:v3.28.1
ctr -n k8s.io image pull docker.io/calico/node:v3.28.1
ctr -n k8s.io image pull docker.io/calico/kube-controllers:v3.28.1
# 删除 Calico pod,让其重启
kubectl get pods -n kube-system | grep calico-node-hv4ss | awk '{print$1}'| xargs kubectl delete -n kube-system pods
kubectl describe po calico-node-hv4ss -n kube-system
# 防火墙中允许 Calico 端口,在所有节点上运行 ufw 命令
sudo ufw allow 179/tcp
sudo ufw allow 4789/udp
sudo ufw allow 51820/udp
sudo ufw allow 51821/udp
sudo ufw reload
# 验证 Calico pod 的状态,运行
kubectl get pods -n kube-system
# 查看 nodes 状态
kubectl get nodes
查看服务网段
kubectl get cm -n kube-system kubeadm-config -o yaml | grep serviceSubnet
查看 Pod 网段
kubectl get cm -n kube-system kubeadm-config -o yaml | grep podSubnet
一次性查看全部
kubectl get cm -n kube-system kubeadm-config -o yaml | grep -E 'podSubnet|serviceSubnet'
7、验证集群
节点导入离线镜像
ctr -n k8s.io images import nginx-alpine.tar
修改配置
#查看详细
kubectl get node -o wide
通过在集群中部署 nginx 服务来验证集群是否正常工作。
# 创建
kubectl create deployment nginx-test-deployment --image=nginx:alpine --replicas=2
# 通过 NodePort 类型的 Service 来暴露 Pod
kubectl expose deployment nginx-test-deployment --name=nginx-test-service --type NodePort --port 80 --target-port 80
# 查看 pod 及服务信息
kubectl get pod,svc
kubectl describe svc nginx-test-service
kubectl get pods -l app=nginx-test-deployment -o wide
kubectl get pod -o wide
kubectl get svc -o wide
# root@k8s-master:~/k8s/blog-in-kubernetes# kubectl get pod,svc
# NAME READY STATUS RESTARTS AGE
# pod/nginx-test-deployment-6876b4697f-68wnt 1/1 Running 0 13s
# pod/nginx-test-deployment-6876b4697f-dp66k 1/1 Running 0 13s
#
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/nginx-test-service NodePort 10.102.158.74 <none> 80:31493/TCP 6s
# 它将容器 80 端口映射到【所有节点】的一个随机端口(这里是 31493 )。 我们通过访问节点端口来测试在所有集群机器上的 pod 的连通性。
# 在 k8s-master(192.168.0.210)上执行
curl http://192.168.0.210:31493
curl http://192.168.0.211:31493
# k8s-master shell 打不开,局域网其它机器(192.168.0.104)浏览器可以打开
curl http://k8s-worker01:31493
# 删除部署
kubectl delete deployment nginx-test-deployment
kubectl delete svc nginx-test-service
kubectl delete namespace ingress-nginx
8、其他问题
1、版本不一致解决
解锁
apt-mark unhold kubelet kubeadm kubectl
直接安装指定正确版本
apt-get install -y \
kubelet=1.35.* \
kubeadm=1.35.* \
kubectl=1.35.*
验证是否正确
kubeadm version
kubelet --version
kubectl version --client
再锁定版本
apt-mark hold kubelet kubeadm kubectl
2、CNI 插件目录问题
# 创建目录
mkdir -p /usr/lib/cni /opt/cni/bin
# 下载官方 CNI 插件包
CNI_VERSION="v1.6.2"
curl -L -o cni-plugins.tgz "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz"
# 解压到标准路径
tar -C /opt/cni/bin -xzf cni-plugins.tgz
ln -sf /opt/cni/bin/* /usr/lib/cni/
# 确认插件存在
ls -la /opt/cni/bin/
ls -la /usr/lib/cni/
# 在所有节点执行
systemctl restart containerd
# 在 master 节点删除卡住的 Pod,让它们重新创建
kubectl delete pod -n kube-system -l k8s-app=kube-dns
kubectl delete pod -n kube-system -l k8s-app=calico-kube-controllers
后续关键操作提醒
令牌管理:初始化时生成的加入令牌默认 24 小时后过期。过期后,可在 Master 上 生成新命令。
kubeadm token create --print-join-command集群升级:不可直接使用
apt upgrade。必须使用kubeadm upgrade进行规划式升级,并依次升级控制平面和工作节点。生产加固:考虑配置高可用控制平面、启用 RBAC、设置网络策略等。
后面计划搭建一个 NFS Server 的虚机,通过 NFS 提供 PVC 功能,然后基于 PVC 建设私有镜像仓库 Habor