2. 前置条件

2.1. 基础环境

  • MateBook D16 Win 11 Build.22621 HyperV

  • Ubuntu Server 22.04.3

  • 安装完毕Ubuntu Server后设置SSH,安装源,时间同步,编码

IP Role HostName

192.168.1.121

k8s-master

hostnamectl set-hostname k8s-master

192.168.1.122

k8s-worker

hostnamectl set-hostname k8s-worker

2.2. hosts

vim /etc/hosts

192.168.1.121	k8s-master
192.168.1.122	k8s-worker

2.3. 更新环境

apt update

2.4. Disable Swap

swapoff -a && sed -i -e '/swap/d' /etc/fstab

# vim /etc/fstab
# 注释swap.img行
# /swap.img     none    swap    sw      0       0

# 重新加载/etc/fstab
# mount -a

swapon --show && free -mh

2.5. 关闭防火墙

# 生产慎用
ufw disable && ufw status

2.6. Network Traffic

cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay && modprobe br_netfilter

lsmod | grep br_netfilter && lsmod | grep overlay

2.7. IP Forward

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

2.8. 安装Docker

3. K8S前置

3.1. 依赖组件

apt update && apt install -y apt-transport-https ca-certificates curl

3.2. 密钥与源

#curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
#	gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg

#echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] \
#	https://apt.kubernetes.io/ kubernetes-xenial main" \
#	| tee /etc/apt/sources.list.d/kubernetes.list

# curl -fsSL https://mirrors.tencent.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# apt-add-repository "deb https://mirrors.tencent.com/kubernetes/apt/ kubernetes-xenial main"

curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | \
	gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] \
	https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" \
	| tee /etc/apt/sources.list.d/kubernetes.list

3.3. 安装kube工具

# apt install -y kubelet=1.27.4-00 kubeadm=1.27.4-00 kubectl=1.27.4-00
apt update && apt install -y kubelet kubeadm kubectl

# 阻止自动更新
apt-mark hold kubelet kubeadm kubectl

3.4. 查看版本

# 指定格式yaml或json

kubectl version --output=json --client && \
	kubeadm version --output=json && kubelet --version

3.5. 开机启动

systemctl enable kubelet

4. 容器运行时

4.1. 生成配置文件

containerd config default |tee /etc/containerd/config.toml

4.2. 启用systemd

  • vim /etc/containerd/config.toml

  • [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = falseSystemdCgroup = true

  • SystemdCgroup = false:大约125行

  • 第61行:sandbox_image = "registry.k8s.io/pause:3.6" 修改为:
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"

  • 我们通过命令:kubeadm config images list 查看组件pause的版本为3.9

  • kubeadm config images list
    kubeadm --image-repository registry.aliyuncs.com/google_containers config images list

4.3. 开机自启动

systemctl daemon-reload && \
	systemctl restart containerd && \
	systemctl enable containerd

5. Master Node

5.1. 生成初始化配置

kubeadm config print init-defaults > kubeadm.conf

5.2. 修改kubeadm.conf

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  #advertiseAddress: 1.2.3.4	(2)
  advertiseAddress: 192.168.1.121
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  # name: node	(1)
  name: k8s-master
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
# imageRepository: registry.k8s.io	(3)
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.27.0	(5)
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16 (4)
  serviceSubnet: 10.96.0.0/12
scheduler: {}
1 第17行:nodeRegistration.name:修改为master主机名
nodeRegistration.name:node 修改为
nodeRegistration.name:k8s-master
2 第12行:localAPIEndpoint.advertiseAddress,
修改为master的IP地址
localAPIEndpoint.advertiseAddress: 1.2.3.4 修改为
localAPIEndpoint.advertiseAddress: 192.168.1.121
3 第30行,修改镜像仓库地址:
imageRepository: registry.k8s.io 修改为:
imageRepository: registry.aliyuncs.com/google_containers
4 networking节点下第34和35行之间添加podSubnet节点:
podSubnet: 10.244.0.0/16
5 kubernetesVersion: 1.27.0 修改为
kubernetesVersion: v1.27.4

5.3. Master初始化

kubeadm init --config=kubeadm.conf --v=6

# 若初始化失败,则重置
kubeadm reset
# 无需操作此步骤,仅供参考
kubeadm init \
	--apiserver-advertise-address=192.168.1.121 \
	--image-repository registry.aliyuncs.com/google_containers \
	--kubernetes-version v1.27.4 \
	--service-cidr=10.96.0.0/12 \
	--pod-network-cidr=10.244.0.0/16 \
  	--control-plane-endpoint=k8s-master

5.4. 配置kubectl

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

5.5. CNI Plugin

6. Worker Node

6.1. Worker Join

  • 在master节点执行打印join命令

kubeadm token create --print-join-command
  • 在相应的worker节点执行join命令

kubeadm join 192.168.1.121:6443 --token 40q6kz.b05lx4s099nku2r9 \
	--discovery-token-ca-cert-hash \
	sha256:4fa9ffe9c07b42edc5f286359b6661d1e2798c73a3d63fe33ade9cb808c8154a

6.2. 配置kubectl

  • 将master节点中的"/etc/kubernetes/admin.conf"文件拷贝到
    worker节点相同目录,再在worker节点执行如下命令(非root):

scp -r root@192.168.1.121:/etc/kubernetes/admin.conf /etc/kubernetes/

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

6.3. 集群节点

  • master或worker都行,worker的role为空,
    通过命令添加,label-value随意添加

# kubectl get nodes
NAME         STATUS   ROLES           AGE   VERSION
k8s-master   Ready    control-plane   31m   v1.27.4
k8s-worker   Ready    <none>          12m   v1.27.4

# kubectl get nodes --show-labels

# kubectl label nodes k8s-worker node-role.kubernetes.io/worker=worker

# kubectl get nodes
NAME         STATUS   ROLES           AGE   VERSION
k8s-master   Ready    control-plane   42m   v1.27.4
k8s-worker   Ready    worker          23m   v1.27.4

kubectl cluster-info
  • 列出命名空间列表:kubectl get namespace

  • 列出命名空间下pod:kubectl get po --all-namespaces

kubectl label nodes <node-name> <label-key>=<label-value>
kubectl label nodes k8s-worker node-role.kubernetes.io/control-plane=control-plane
kubectl label nodes k8s-worker node-role.kubernetes.io/worker=worker
kubectl label nodes k8s-worker node-role.kubernetes.io/worker1=worker1
kubectl label nodes k8s-worker node-role.kubernetes.io/worker2=worker2

7. 排错

7.1. kubelet日志

tail -f /var/log/syslog
  • 注:若在/var/log/syslog的日志中看到如下kubelet服务启动失败信息,
    可先不用担心,在k8s master节点初始化之前,出现如下信息是正常的,
    kubelet会定时尝试连接k8s api server,直到成功。

# tail -f /var/log/syslog
Started kubelet: The Kubernetes Node Agent.
"command failed" err="failed to load kubelet config file, error:
	failed to load Kubelet config file /var/lib/kubelet/config.yaml,
	error failed to read kubelet config file \"/var/lib/kubelet/config.yaml\",
	error: open /var/lib/kubelet/config.yaml: no such file or directory,
	path: /var/lib/kubelet/config.yaml"
kubelet.service: Main process exited, code=exited, status=1/FAILURE
kubelet.service: Failed with result 'exit-code'.