Kubernetes 安装
- 2026-02-14
- Kubernetes Linux
- k8s kubernetes
Linux 安装k8s 保姆级教程
在安装 k8s 之前我们先了解一下什么是 k8s
什么是k8s?
k8s 的概念
K8s 是 Kubernetes 的简称。这个缩写取自首字母 “K” 和尾字母 “s”,中间正好有 8 个字母(ubernete),因此得名。
K8s 是一个开源的容器编排(Container Orchestration)平台。它最初由 Google 开发(基于其内部系统 Borg),并于 2014 年开源,目前由云原生计算基金会(CNCF)维护。
如果把容器(如 Docker)比作装满货物的“集装箱”,那么 K8s 就是调度和管理这些集装箱的“大型货轮”或“港口调度员”
k8s 是做什么的
- 自动化部署和回滚:K8s 会自动帮你部署。如果更新版本出错了,它也能自动回滚。
- 服务发现与负载均衡:K8s 可以为一组容器提供统一的访问入口(IP 或域名),并自动平衡流量,确保不会因为某个容器压力过大而崩溃。
- 自我修复(Self-healing):如果某个容器挂了,K8s 会立即发现并重启一个新的;如果某个服务器(节点)挂了,它会把上面的容器迁移到健康的服务器上。
- 弹性伸缩(Scaling):当流量高峰来临时,K8s 可以在几秒钟内自动增加容器数量;流量减少时再自动缩减,节省成本。
- 存储编排:无论你的数据存在本地、云端还是分布式系统中,K8s 都能自动挂载这些存储系统。
核心架构(它是如何工作的?)
- 控制平面(Control Plane / Master 节点):集群的大脑,负责做决策(比如调度哪些容器到哪个机器运行)。
- API Server:整个系统的入口,所有指令都通过它下发。
- etcd:保存集群所有配置和状态的数据库。
- Scheduler(调度器):决定把容器放到哪台机器上。
- Controller Manager:负责执行任务,比如确保副本数量始终正确。
- 工作节点(Worker Nodes / Node 节点):真正干活的机器,运行容器化的应用。
- kubelet:节点上的管家,负责与 Master 通信并执行任务。
- kube-proxy:负责网络通信。
几个基本概念
- Pod:K8s 的最小调度单位。一个 Pod 里面可以包含一个或多个容器(通常是一个)。你可以把它理解为装着容器的吊篮。
- Deployment:定义应用该如何运行的策略(比如运行几个副本、用哪个镜像)。
- Service:定义如何访问一组 Pod(解决 Pod 频繁变动导致 IP 改变的问题)。
- Namespace:用于虚拟隔离。比如把“开发环境”和“生产环境”在逻辑上分开。
准备工作
服务器准备
准备至少三台服务器,或者虚拟机。如果没有,则可以看 MiniKube 的教程 把 master 和 worker 都部署到一起。
我这里准备了3台ubuntu 24的虚拟机。使用的 windows 的 Hyper-V 安装的。
| ip | 作用 |
|---|---|
| 192.168.50.180 | Master |
| 192.168.50.181 | Worker |
| 192.168.50.183 | Worker |
- 每台服务器至少2核CPU和2G内存(内存是k8s 强制要求),且互相之间网络互通,也需要能连外网,因为需要下载k8s的安装文件以及相关的程序的包(比如Docker等),且拥有sudu权限。
- 本地测试,我这边是关闭防火墙的,如果是生产环境,需要放行特定的端口,视具体环境而定。
- 关闭防火墙的命令是:
sudo ufw disable。
- 关闭防火墙的命令是:
- 需要关闭Swap交换内存。
- 关闭交换分区的命令是:
# 临时关闭,重启失效 sudo swapoff -a # 永久关闭(注释配置文件:/etc/fatab 中 /swap/开头的那一行配置即可) sudo sed -i '/swap/ s/^\(.*\)$/#\1/g' /etc/fstab
- 关闭swap分区的原因是:Kubernetes的调度器(也就是Scheduler) 在分配Pod到节点时,是根据 内存绝对值(也就是具体的内存,如 2G,4G 等,不是内存使用占比) 计算的。因此,当内存不足的时候:
- 如果没有关闭swap分区。系统就会使用交换分区的内存,导致性能下降,甚至进程卡住,但是程序不会崩溃。
- k8s希望当内存不足的时候是肢解杀掉Pod,并重新调度Pod,而不是让整个节点(worker)变慢或卡住。
- 配置内核模块和网络参数
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 # 应用参数 sudo sysctl --system
- 原因: 默认情况下,Linux 仅仅作为一台主机,不会转发不属于自己的流量。但在 K8s 中,每个 Node 实际上是一个路由器,它需要把发往 Pod IP 的流量转发到对应的容器网络接口(veth pair)。如果不开启,Pod 只能访问本机,无法访问外网或其他节点。 做完了这些之后,就可以准备开始安装k8s以及相关的组件了。
- 关闭交换分区的命令是:
安装容器运行时
所有节点都需要安装(可选Docker或者Containerd)。
Kubernetes 从 1.24版本开始,移除了 dockershim 。如果使用 docker 作为容器运行时,可往下翻。
使用Containerd作为容器运行时
安装Containerd (有可能在国内拉不下来镜像)
# 安装 Docker 官方 GPG Key 和 Repo (为了获取最新版 containerd)
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y containerd.io
配置Containerd
必须配置 SystemdCgroup,否则 kubelet 会启动失败。
# 生成默认配置
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
# 修改配置以启用 SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 重启 containerd
sudo systemctl restart containerd
使用Docker作为容器运行时
安装Docker
# 1. 更新并安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
# 2. 添加 Docker 官方 GPG Key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# 3. 添加 Docker 仓库 (Ubuntu 24.04 代号为 noble)
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 4. 安装 Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 5. 配置 Docker 使用 systemd 作为 cgroup 驱动,同时添加docker国内镜像源
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://doublezonline.cloud",
"https://dislabaiot.xyz",
"https://docker.fxxk.dedyn.io",
"https://dockerpull.org",
"https://docker.unsee.tech",
"https://hub.rat.dev",
"https://docker.1panel.live",
"https://docker.nastool.de",
"https://docker.zhai.cm",
"https://docker.5z5f.com",
"https://a.ussh.net",
"https://docker.udayun.com",
"https://hub.geekery.cn",
"https://registry.aliyuncs.com"
],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
# 6. 重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# 7. 查看docker配置, 如果出现在daemon.json中配置的内容,即为成功.
sudo docker info
Q:为什么要配置使用 systemd 作为 cgroup 驱动?
A:
- Cgroup 是 Linux 用于限制进程资源(CPU、内存)的机制。
- Ubuntu 系统默认使用 systemd 来管理所有进程的 Cgroup。
- Docker 默认使用 cgroupfs 来管理容器 Cgroup。
- 如果两者不一致,系统会有两套资源管理器在打架,导致 K8s 节点不稳定甚至 kubelet 崩溃。必须统一为 systemd。
安装cri-dockerd
- 为什么需要安装cri-dockerd
- 简单来说就是用于docker和k8s 之间做交互的。
- 在k8s 1.24版本之前,k8s 官方维护了一个叫
dockershim的组件,但是在1.24版本之后,官方移除了这个组件。 - 所以如果安装1.24之后的k8s 就需要安装 cri-dockerd 用于 k8s 跟 docker之间的交互。
- 它的执行流程是:kubelet (发送指令)->cri-dockerd (解释为docker认识的指令)->docker engine (执行指令)
- 安装
可以在 cri-dockerd 发布日志 上查看 cri-dockerd 的版本,进行下载
# 获取当前最新的版本号变量(或者手动指定)
VER=$(curl -s https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//g')
# 下载适配 Ubuntu jammy/noble 的 amd64 包
wget https://github.com/Mirantis/cri-dockerd/releases/download/v${VER}/cri-dockerd_${VER}.3-0.ubuntu-jammy_amd64.deb
# 安装
sudo dpkg -i cri-dockerd_${VER}.3-0.ubuntu-jammy_amd64.deb
# 修复潜在的依赖问题(如果有)
sudo apt-get install -f
也可以自己在cri-dockerd的仓库地址中自己下载对应的安装包下来,然后 scp 传到服务器中,执行后面两条指令即可安装。
配置cri-dockerd
- 修改 Pause 镜像地址
- 找到
cri-docker.service的 systemd文件 - 在
ExecStart这一行的尾部添加--network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.10.1
- 找到
vim /lib/systemd/system/cri-docker.service

- 配置原因:
- 每个 Pod 启动时,都会先启动一个极其微小的容器叫 pause。它的唯一作用是占住网络命名空间(Network Namespace),让同一个 Pod 内的其他容器共享同一个 IP。
- 默认的 pause 镜像在 Google 的服务器上 (k8s.gcr.io),国内网络通常拉取失败,导致 Pod 一直处于 Pending 或 ContainerCreating 状态。改成阿里云镜像可以解决网络问题。
安装k8s组件
安装好容器运行时就可以安祖行k8s 组件了: kubelet,kubeadm,kubectl.
安装
# 1. 准备 Key 和源
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 2. 安装
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
# 3. 锁定版本。防止因 apt-get upgrade 自动更新了
sudo apt-mark hold kubelet kubeadm kubectl
# 4. 验证安装结果,如果显示版本则代表按钻过成功
sudo kubectl version
初始化 Master
可以使用命令行初始化,也可以使用配置文件进行初始化。
- 使用命令行初始化
sudo kubeadm init \
--node-name=master-node \
--image-repository=registry.aliyuncs.com/google_containers \
--cri-socket=unix:///var/run/cri-dockerd.sock \
--pod-network-cidr=192.168.0.0/16 \
--kubernetes-version=v1.30.0
- image-repository:使用镜像源,这里配置阿里云的,可加速镜像拉取。
- cri-socket:设置 socket 接口文件路径
- 默认情况下,kubelet 会自动探测节点上有什么运行时。如果它发现了 Containerd,它就会直接连接 Containerd(因为 Containerd 原生支持 CRI)。此参数让kubelet使用cri-dockerd。
- pod-network-cidr:K8s 的 Pod 网络与主机网络是隔离的。我们需要预先划分一个私有网段(例如 192.168.0.0/16)给 Pod 使用。后续安装的网络插件(Calico)会根据这个范围分配 IP。
这个命令执行成功后会给两个提示:
- 一个提示拷贝配置文件。
- 另一个给出了worker节点加入集群的命令。
- 使用配置文件进行初始化
-
生成默认配置文件模板
# 生成包含 InitConfiguration, ClusterConfiguration 和 KubeletConfiguration 的完整模板 kubeadm config print init-defaults --component-configs KubeletConfiguration > kubeadm-config.yaml -
修改配置文件
apiVersion: kubeadm.k8s.io/v1beta4 # v1.35 通常使用 v1beta4 或 v1beta3 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.50.180 # 修改为你 Master 节点的实际 IP bindPort: 6443 nodeRegistration: criSocket: unix:///var/run/cri-dockerd.sock # 必须指向 cri-dockerd 的套接字 name: master-node # 你的主机名,或者保持默认 taints: null # 可选:如果你想让 Master 也能跑业务 Pod,设为 null --- apiVersion: kubeadm.k8s.io/v1beta4 kind: ClusterConfiguration kubernetesVersion: v1.35.0 # 指定版本 imageRepository: registry.aliyuncs.com/google_containers # 国内使用阿里云镜像 networking: dnsDomain: cluster.local podSubnet: 192.168.0.0/16 # Calico 默认网段,必须配置 serviceSubnet: 10.96.0.0/12 scheduler: {} --- apiVersion: kubelet.config.k8s.io/v1beta1 # 和上面的两个配置的值不一样。如果修改不正确,在初始化 master 的时候会报错。 kind: KubeletConfiguration cgroupDriver: systemd # 设置cgroup,Ubuntu 24 + Docker 必须显式指定 systemd failSwapOn: true # 默认 true,如果没关 swap 这里设为 false 但是不推荐不关闭swap -
验证配置文件
# 预拉取镜像, sudo kubeadm config images pull --config kubeadm-config.yaml如果你看到类似
[config/images] Pulled registry.aliyuncs.com/...的输出且没有报错,说明:- 配置文件格式正确。
- cri-dockerd 连接正常。
- 阿里云镜像源访问正常。
-
使用配置文件开始初始化
sudo kubeadm init --config kubeadm-config.yaml
-
将执行结果中提示执行的指令执行一下。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl 本身只是个 HTTP 客户端。它需要知道 API Server 的地址,以及最重要的——管理员证书(密钥)。这个文件里包含了连接集群所需的所有认证信息。
安装网络插件
如果下载不下来配置文件可以在可访问到github的机器上下载文件之后,scp到服务器即可。
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/custom-resources.yaml
K8s 定义了网络接口标准(CNI),但自己不实现具体的网络功能(比如怎么在这个节点给 Pod 分配 IP,怎么把包路由到另一个节点的 Pod)。
如果不安装 CNI 插件,CoreDNS 等系统组件启动不了,节点状态会一直是 NotReady。Calico 负责打通节点间的隧道(IPIP/BGP),让不同机器上的 Pod 能互相 Ping 通。
在worker节点加入集群
# 执行 初始化master 章节给出的指令,如果是使用 cri-dockerd 作为容器运行时,则需要在命令最后加上 --cri-socket=unix:///var/run/cri-dockerd.sock
kubeadm join 192.168.50.180:6443 --token fhun78.rf36l41t6h5druup --discovery-token-ca-cert-hash sha256:5137533109b8160818de26e605d3a141cec853b4c56fab46ea85df99a7501192 --cri-socket=unix:///var/run/cri-dockerd.sock
- Worker 节点通过 Token 认证加入集群。
- Worker 节点也需要运行 Pod,所以它也必须知道使用哪个运行时。必须在 join 命令中同样指定 cri-socket,否则 Worker 可能会错误地连接到 containerd 或者报错。
验证安装
kubectl get nodes -o wide
如果得到类似下面的输出。则为成功

如果你发现 k8s 的访问协议是 https ,不必惊慌(哪怕你是通过ip访问),因为 k8s 默认使用https安全协议,但它的证书是自签名的,而且是发给集群内部域名的,并不是发给你的本地ip或者域名。当你访问出现不安全的连接时,点击继续访问即可。