Skip to content

K8s安装

确保各节点时间同步、关闭防火墙

sudo ufw disable

禁用交换空间

Kubernetes 要求禁用交换分区。

临时禁用

sudo swapoff -a

永久禁用

编辑 /etc/fstab 文件,注释掉与 Swap 相关的行:
sudo vim /etc/fstab
找到类似以下内容:
/swap.img none swap sw 0 0
在行首添加 # 注释:
#/swap.img none swap sw 0 0

配置内核对 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

容器运行时

下面的表格包括被支持的操作系统的已知端点。

运行时 Unix 域套接字
containerd unix:///var/run/containerd/containerd.sock
CRI-O unix:///var/run/crio/crio.sock
Docker Engine(使用 cri-dockerd) unix:///var/run/cri-dockerd.sock

说明: Docker Engine 没有实现 CRI, 而这是容器运行时在 Kubernetes 中工作所需要的。 为此,必须安装一个额外的服务 cri-dockerd。 cri-dockerd 是一个基于传统的内置 Docker 引擎支持的项目, 它在 1.24 版本从 kubelet 中移除。

安装 kubeadm, kubelet 和 kubectl(使用阿里云镜像)

你需要在每台机器上安装以下的软件包: - kubeadm:用来初始化集群的指令。 - kubelet:在集群中的每个节点上用来启动 Pod 和容器等。 - kubectl:用来与集群通信的命令行工具。

安装 cri-dockerd(版本>=1.28)

由于 Kubernetes 1.28 不再内置 Dockershim,我们需要安装 cri-dockerd:

# 下载 cri-dockerd
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.4/cri-dockerd-0.3.4.amd64.tgz

# 解压
tar xvf cri-dockerd-0.3.4.amd64.tgz

# 安装
sudo mv cri-dockerd/cri-dockerd /usr/bin/
sudo chmod +x /usr/bin/cri-dockerd

# 创建 systemd 服务文件
sudo wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service
sudo wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket

sudo mv cri-docker.service /etc/systemd/system/
sudo mv cri-docker.socket /etc/systemd/system/

# 启动 cri-dockerd
sudo systemctl daemon-reload
sudo systemctl enable cri-docker.service
sudo systemctl enable --now cri-docker.socket
sudo systemctl start cri-docker.service

# 验证 cri-dockerd
sudo systemctl status cri-docker.service

添加库

使用官方库:

1.更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包:

sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

2.下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本:

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

说明: 在低于 Debian 12 和 Ubuntu 22.04 的发行版本中,/etc/apt/keyrings 默认不存在。 应在 curl 命令之前创建它。

3.添加 Kubernetes apt 仓库。 请注意,此仓库仅包含适用于 Kubernetes 1.34 的软件包; 对于其他 Kubernetes 次要版本,则需要更改 URL 中的 Kubernetes 次要版本以匹配你所需的次要版本 (你还应该检查正在阅读的安装文档是否为你计划安装的 Kubernetes 版本的文档)。

# 此操作会覆盖 /etc/apt/sources.list.d/kubernetes.list 中现存的所有配置。
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

使用阿里云库:

添加 Kubernetes 的阿里云 GPG 密钥:

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -

添加 Kubernetes 的 apt仓库(阿里云镜像):

cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF```

>>4.更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:
```text
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

阻止自动更新

sudo apt-mark hold kubelet kubeadm kubectl

5.(可选)先启用 kubelet 服务,再运行 kubeadm:

sudo systemctl enable --now kubelet

初始化控制平面节点

拉取镜像(使用国内镜像):

由于 kubeadm默认从 k8s.gcr.io拉取镜像,在国内无法访问。我们可以使用阿里云镜像仓库。 首先查看需要哪些镜像:

kubeadm config images list

registry.k8s.io/kube-apiserver:v1.28.2
registry.k8s.io/kube-controller-manager:v1.28.2
registry.k8s.io/kube-scheduler:v1.28.2
registry.k8s.io/kube-proxy:v1.28.2
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.9-0
registry.k8s.io/coredns/coredns:v1.10.1
# 拉取 1.28.2 版本镜像
images=(
    kube-apiserver:v1.28.2
    kube-controller-manager:v1.28.2
    kube-scheduler:v1.28.2
    kube-proxy:v1.28.2
    pause:3.9
    etcd:3.5.9-0
    coredns:v1.10.1
)

for image in "${images[@]}"; do
    if [[ $image == coredns/* ]]; then
        docker pull registry.aliyuncs.com/google_containers/${image}
        docker tag registry.aliyuncs.com/google_containers/${image} registry.k8s.io/${image}
    else
        docker pull registry.aliyuncs.com/google_containers/${image}
        docker tag registry.aliyuncs.com/google_containers/${image} registry.k8s.io/${image}
    fi
    echo "Pulled: ${image}"
done

# 验证镜像
docker images | grep registry.k8s.io

初始化控制平面节点:

选择一个 Pod 网络插件。这里我们使用 Flannel。Flannel 需要一个 pod-network-cidr为 10.244.0.0/16。

两种初始化方式,二选一:

方式1.使用命令行参数进行初始化:

sudo kubeadm init \
  --kubernetes-version v1.28.2 \
  --pod-network-cidr=10.244.0.0/16 \
  --image-repository registry.aliyuncs.com/google_containers \
  --apiserver-advertise-address=192.168.3.15 \
  --cri-socket=unix:///var/run/containerd/containerd.sock
  --upload-certs \
  --v=5

方式2.使用配置文件进行初始化:

#配置写入到文件
cat <<EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.3.15
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/cri-dockerd.sock
  imagePullPolicy: IfNotPresent
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.2
imageRepository: registry.aliyuncs.com/google_containers
networking:
  podSubnet: 10.244.0.0/16
controlPlaneEndpoint: "192.168.3.15:6443"
EOF

创建文件后再执行:
sudo kubeadm init --config kubeadm-config.yaml --upload-certs --v=5

以上配置中关键参数说明:

--kubernetes-version:指定确切的版本,避免歧义。
--pod-network-cidr:指定 Pod 网络段,必须与后续安装的 CNI 插件匹配。
--image-repository:指定从阿里云镜像仓库拉取镜像,这是最关键的一步,避免了手动拉取镜像的麻烦。
--cri-socket参数,需要设置为容器引擎的unix通信地址。
基于containerd --cri-socket=unix:///var/run/containerd/containerd.sock
基于docker --cri-socket=unix:///var/run/cri-dockerd.sock

如果安装成功日志如下,会在末尾后会打印一些命令:

[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". This can take up to 4m0s
[apiclient] All control plane components are healthy after 4.501359 seconds
[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 ubuntu 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 ubuntu as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: 0abvqi.0mk71lh6zttuz8pq
[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-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You 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.3.15:6443 --token 0abvqi.0mk71lh6zttuz8pq \
        --discovery-token-ca-cert-hash sha256:f3b689782778f70198a63c47ae6cfd9ee2d032cf83c3e6b136217ce2a52a124d 

1.普通用户

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

2.root用户可直接查看kubeconfig位置:

/etc/kubernetes/admin.conf

3.如果需要集群,在其他节点节点机器上再执行此join命令:

kubeadm join 192.168.3.15:6443 --token 0abvqi.0mk71lh6zttuz8pq \
        --discovery-token-ca-cert-hash sha256:f3b689782778f70198a63c47ae6cfd9ee2d032cf83c3e6b136217ce2a52a124d 

安装 Pod 网络插件(Flannel):

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

如果 RawGit 访问不畅,可以尝试:

kubectl apply -f https://cdn.jsdelivr.net/gh/coreos/flannel/master/Documentation/kube-flannel.yml

检查集群状态:

kubectl get nodes
# 输出应显示一个控制平面节点,状态为 NotReady,等待片刻后变为 Ready。
kubectl get pods --all-namespaces
# 检查所有系统 Pod 是否都在运行。

添加集群

1.在工作节点上,重复步骤 1 和 步骤 2,安装 Docker、kubeadm、kubelet。
2.在控制平面节点上,运行 kubeadm token create --print-join-command来获取加入集群的命令。
3.在工作节点上,使用 sudo运行上一步输出的命令。命令格式如下:

sudo kubeadm join <control-plane-host>:<port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

4.在控制平面节点上验证新节点:

kubectl get nodes

如果安装失败,重置并重新初始化:

# 1. 重置集群
sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock -f
sudo rm -rf /etc/kubernetes/ /var/lib/etcd /var/lib/kubelet ~/.kube

# 2. 清理网络接口和iptables规则
sudo ip link delete cni0 2>/dev/null || true
sudo ip link delete flannel.1 2>/dev/null || true
sudo rm -rf /var/lib/cni/
sudo rm -rf /etc/cni/
sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X

# 3. 重启 Docker 
sudo systemctl restart docker

# 重启 kubelet
sudo systemctl restart kubelet

# 4. 重新初始化(使用更详细的输出),重新执行kubeadm init 命令

其他

查看 kubeadm init是否完成:

sudo kubeadm init phase upload-config all --v=5

检查 kubelet的完整日志,寻找初始化过程中的错误:

sudo journalctl -u kubelet -n 100 --no-pager

查看 kubeadm的配置:

sudo kubeadm config print init-defaults

重置集群

# docker
sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock -f
sudo rm -rf /etc/kubernetes/ /var/lib/etcd /var/lib/kubelet ~/.kube
# containerd
sudo kubeadm reset --cri-socket unix:///var/run/containerd/containerd.sock -f
sudo rm -rf /etc/kubernetes/ /var/lib/etcd /var/lib/kubelet ~/.kube

配置文件位置

/var/lib/kubelet/config.yaml