K8S 部署

前置环境准备

安装 kubeadm

  • 每台机器 2 GB 或更多的 RAM(如果少于这个数字将会影响你应用的运行内存)。
  • CPU 2 核心及以上。
  • 集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)。
  • 节点之中不可以有重复的主机名、MAC 地址或 product_uuid。请参见这里了解更多详细信息。
  • 开启机器上的某些端口。请参见这里了解更多详细信息。
  • 交换分区的配置。kubelet 的默认行为是在节点上检测到交换内存时无法启动。

确保每个节点上的 MAC 地址和 Product_uuid 的唯一性

  1. 使用命令 ip linkifconfig -a 来获取网络接口的 MAC 地址
  2. 可以使用 sudo cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验

确保每个节点 hostname 的唯一性

如果不唯一可以使用如下方式修改 hostname:

  1. 设置 hostname
sudo hostname ctl set-hostname <hostname>
  1. 修改 /etc/hosts 文件,修改原 hostname 映射,并且添加每个节点的 hostname 到 ip 地址的映射
sudo vi /etc/hosts

安装依赖

apt install -y conntrack socat

检查所需端口是否开放

端口和协议

转发 IPv4 并让 iptables 看到桥接流量

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
 
sudo modprobe overlay
sudo modprobe br_netfilter
 
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo 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 参数而不重新启动sudo sysctl --system
sudo sysctl --system

部署控制平面

kubeadm 搭建单master多node的k8s集群 - 休耕 - 博客园 保姆级 Kubernetes 1.24 高可用集群部署中文指南-kubeadm部署高可用集群

安装容器运行时 containerd

容器运行时 containerd getting-started

安装 containerd

  1. 下载 containerd
  2. 将 containerd 解压到 /usr/local
sudo tar Cxzvf /usr/local containerd-1.7.8-linux-amd64.tar.gz
  1. 如果打算从 systemd 启动 containerd 这需要下载 containerd.service,并执行
sudo mkdir -p /usr/local/lib/systemd/system
sudo cp containerd.service /usr/local/lib/systemd/system/
 
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
  1. 生成 containerd 默认配置文件
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml

安装 runc

  1. 下载 runc,然后执行如下命令安装
sudo install -m 755 runc.amd64 /usr/local/sbin/runc

安装 CNI 插件

  1. 下载 cni,并将其解压到 /opt/cni/bin
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.3.0.tgz

设置 cgroup 驱动

cgroup 驱动

  1. 检查当前使用的 cgroup 版本
# 对于 cgroup v2,输出为 cgroup2fs。
# 对于 cgroup v1,输出为 tmpfs。
stat -fc %T /sys/fs/cgroup/
  1. 容器运行时默认使用 cgorup v1,如果 linux 使用的是 systemd 初始化系统或者 cgroup v2,则需要做如下修改:
# 修改 systemdCgroup 为 true
#
# [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
#   ...
#   [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
#     SystemdCgroup = true
sudo sed -i "s:SystemdCgroup = false:SystemdCgroup = true:g" /etc/containerd/config.toml
 
# 重启 containerd
sudo systemctl restart containerd

导入需要的镜像

  1. 列出需要的镜像
kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers
  1. 拉取这些镜像到本地 k8s.io 命名空间下
ctr -n k8s.io image pull <image-name>
  1. 或者下载这些镜像后导入
ctr -n k8s.io image import <image-tar>
 
# 导入某个文件夹的所有镜像
find <folder-path> -type f -name "*.tar" -exec ctr -n k8s.io image import {} \;

安装 kubeadm,kubelet 和 kubectl

  1. 安装 crictl
sudo tar -xzf crictl-v1.28.0-linux-amd64.tar.gz -C /usr/local/bin
  1. 安装 kubelet,配置 kubelet.service
sudo cp kubelet /usr/local/bin/
sudo chmod +x /usr/local/bin/kubelet
sudo sed "s:/usr/bin:/usr/local/bin:g" kubelet.service | sudo tee /etc/systemd/system/kubelet.service
  1. 安装 kubeadm,配置 kubeadm.conf
sudo mkdir -p /etc/systemd/system/kubelet.service.d
sudo cp kubeadm /usr/local/bin/
sudo chmod +x /usr/local/bin/kubeadm
sudo sed "s:/usr/bin:/usr/local/bin:g" kubeadm.conf | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
  1. 安装 kubectl
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client
  1. 激活 kubelet
sudo systemctl enable --now kubelet

安装 k8s 命令自动补全

yum install bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
source ~/.bashrc

使用 kubeadm 初始化集群

  1. 初始化 kubeadm

如果初始化失败则使用如下命令清理

sudo kubeadm reset
sudo rm -rf ~/.kube/  /etc/kubernetes/* var/lib/etcd/* /etc/cni/net.d
  • --ignore-preflight-errors=Swap 忽略交互分区的错误,如果不想忽略这个错误可以使用 sudo swapoff -a暂时禁用交互分区
sudo kubeadm init \
  --apiserver-advertise-address=192.168.70.131 \
  --kubernetes-version=v1.28.3 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --service-cidr=10.1.0.0/16 \
  --pod-network-cidr=10.244.0.0/16 \
  --ignore-preflight-errors=Swap \
  --v=5
  1. 创建一个用户

默认只有控制节点才有 /etc/kubernetes/admin.conf 文件,如果想让工作节点也可以执行 kubectl 命令,可以将控制节点的 /etc/kubernetes/admin.conf 文件复制到工作节点,然后执行如下命令

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
 
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source  ~/.bash_profile
  1. 安装 CNI 网络插件
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

k8s join 工作节点

每个工作节点都需要安装:容器运行时,kubeadm,,kubelet。kubectl 是可选的。并且需要进行前置环境准备

如果需要允许 pod 调度到控制平面所在节点,则执行:

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

在其他节点上执行 join 命令,在 kubeadm ini 结束或会输出此命令

如果 token 过期了,可以使用如下命令重新生成 join 命令 kubeadm token create --print-join-command

kubeadm join 192.168.70.131:6443 --token i0ti9f.ab2s1zb449c7aqt3 \
        --discovery-token-ca-cert-hash sha256:e13bb57668ba7a28db1dc721ea8a504ae001341b674c3d9f79fc731a545f25bf

kubectl 连接到远程 k8s 集群

安装 kubectl

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

将 k8s 控制节点上的 ~/.kube/config 文件复制到本机中

mkdir ~/.kube
scp romate-user@romate-hostname:~/.kube/config ~/.kube/

验证

kubectl get nodes

k8s 驱离节点

安全地清空一个节点 | Kubernetes

kubectl get nodes
kubectl drain --ignore-daemonsets <node name>

问题记录

  1. kubeadm init 失败,报 conntrack not found in system path
[sudo] password for guosongxin:
Sorry, try again.
[sudo] password for guosongxin:
[init] Using Kubernetes version: v1.28.3
[preflight] Running pre-flight checks
        [WARNING FileExisting-socat]: socat not found in system path
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR FileExisting-conntrack]: conntrack not found in system path
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

缺少 conntrack 软件包,安装即可

sudo apt install conntrack
  1. coredns pod 一直处于 pending 状态,journalctl -fu kubelet显示 Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized

Container runtime network not ready: cni config uninitialized AppArmor 是一个 Linux 内核安全模块,允许系统管理员使用每个程序配置文件来限制程序的功能。配置文件可以允许网络访问、原始套接字访问以及在匹配路径上读取、写入或执行文件的权限等功能,如果要允许 k8s 服务,则需要配置 AppArmor

sudo systemctl stop apparmor
sudo systemctl disable apparmor
sudo systemctl restart containerd.service