阿里云轻量服务器单机部署 K8s(Docker 作为容器运行时)
免费领取服务器
完成阿里云学生认证后,成功领取到300 元券包权益。使用其中的 178 元额度兑换了一台半年有效期的轻量应用服务器(公网流量无限)。服务器核心配置如下:2 vCPU + 2 GiB 内存,40 GiB ESSD 云盘。获取到服务器公网地址后,使用 Xshell8 通过 SSH 协议连接,端口为 22。
使用 lsb_release -a
查看服务器系统版本
当前系统为 Ubuntu 20.04(Debian 系操作步骤相同)。
系统初始化更新
执行 sudo apt update && sudo apt upgrade -y
命令:
阿里云轻量服务器已经把基础软件源切为阿里源,因此这里会使用阿里源。
sudo apt update
:刷新软件源索引,获取最新软件版本信息。sudo apt upgrade -y
:升级所有可更新软件包,-y
参数自动确认操作。
关闭防火墙并禁用内存交换
# 临时关闭内存交换空间(实际上阿里服务器默认关闭)
sudo swapoff -a
# 永久禁用,通过注释 fstab 文件中所有包含 swap 的行
sudo sed -i '/swap/s/^/#/' /etc/fstab
# 查看ufw状态,若显示“active”则关闭(阿里云镜像默认关闭的)
sudo ufw status
# 关闭防火墙并禁止开机自启
sudo ufw disable
sudo systemctl disable ufw
配置内核参数并开启网络转发
# 加载必要内核模块
sudo modprobe overlay
sudo modprobe br_netfilter
# 配置内核模块开机自动加载
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 配置内核网络参数
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
安装 Docker 容器运行时
需要先安装docker依赖包,不要直接安装 docker-ce ,因为Ubuntu系统自带仓库的docker版本很老旧。
更新软件包索引并安装docker的依赖,这里阿里云轻量服务器的 Ubuntu 系统默认已预置阿里基础软件源:
sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release
ca-certificates
:用于验证软件证书签名curl
:文件下载工具gnupg
:密钥验证工具lsb-release
:获取系统发行版信息
配置 Docker 镜像源(用于下载docker引擎)
由于网络访问限制,建议使用阿里云镜像源来获取docker:
不要使用这个docker官方源来下载docker(国内访问不了):
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
需要使用阿里云镜像源来下载docker:
此时仅仅是设置了docker“从哪下载”,实际上并未真正开始下载和安装。
# 下载并安装阿里云 Docker 源的 GPG 密钥,gpgcheck=1默认开启检查,因此需要这一步。
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/aliyun-docker-archive-keyring.gpg
# 添加阿里云 Docker 源(适配 Ubuntu 20.04 focal)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/aliyun-docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/aliyun-docker.list > /dev/null
安装 Docker 引擎
修改了阿里云镜像源后,使用apt install
会优先使用阿里云获取软件进行安装。
sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io
编辑 Docker 配置以适配 Kubernetes
sudo mkdir -p /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
关键配置是将 cgroup 驱动改为systemd,与后续 Kubernetes 的 cgroup 配置保持一致。
重启并启用 Docker 服务
用于应用以上的驱动更改。
sudo systemctl daemon-reload && sudo systemctl restart docker && sudo systemctl enable docker
# 验证 Docker 配置
docker info | grep -i "cgroup driver"
确认 swap 警告且 cgroup 驱动为 systemd。
重启服务器后检查服务状态:
sudo systemctl status docker # 按 `q` 退出
查看一下剩余内存
free -h
配置 Docker 镜像加速器
阿里云私人加速器网址为 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
,访问获取你自己的私人加速地址。
我之前不是换了一次阿里镜像源吗?
- 之前是阿里云 Docker 软件源(安装 Docker 用)
- 安装 Docker 软件(如
docker-ce
、containerd.io
)时,从阿里云获取docker,解决官方源下载 docker 连不上的问题。
- 安装 Docker 软件(如
- 这一次是 Docker 镜像加速器(拉取镜像用)
- 用途:Docker 安装完成后,拉取镜像(如
hello-world
、nginx
,后续 K8s 等等所需镜像)时,从阿里云镜像仓库获取,避免直接连 Docker Hub 被墙。
- 用途:Docker 安装完成后,拉取镜像(如
# 配置阿里云镜像加速器,用于docker镜像仓库用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
测试 Docker 运行状态:
sudo docker run hello-world
以上输出表明 Docker 运行正常,且镜像加速器配置成功。
部署 Kubernetes
安装 Kubernetes 核心组件
# 下载并导入阿里云 Kubernetes 镜像源的 GPG 密钥(用于软件包验证)
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/kubernetes-archive-keyring.gpg
# 添加 Kubernetes 软件源配置
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null
# 更新软件包索引
sudo apt update
# 安装指定版本的 Kubernetes 组件(确保版本兼容性)
# 安装 1.24.0 版本(兼容 Docker + cri-dockerd 方案)
sudo apt install -y kubelet=1.24.0-00 kubeadm=1.24.0-00 kubectl=1.24.0-00
# 锁定组件版本,防止意外升级导致兼容性问题
sudo apt-mark hold kubelet kubeadm kubectl
核心组件说明
-
kubelet
- 运行在 Kubernetes 集群所有节点(控制节点和工作节点)上的核心服务,每个节点一个。
- 负责监听节点上的 Pod 配置,确保容器按照定义规则运行。
- 管理容器的启动、停止、重启等生命周期操作。
- 作为节点与 Kubernetes 集群通信的桥梁。
-
kubeadm
- Kubernetes 集群部署工具,简化集群管理操作
- 支持集群初始化(
kubeadm init
)、节点加入(kubeadm join
)、集群升级等功能 - 提供快速搭建生产就绪集群的能力
-
kubectl
- Kubernetes 命令行管理工具,用于与 API Server 交互
- 支持集群状态查看(
kubectl get nodes
)、应用部署(kubectl apply -f
)、日志查看(kubectl logs
)等操作 - 是管理和维护 Kubernetes 集群的主要入口
手动处理 pause
镜像
提前拉取 K8s 必需的 pause 镜像(pause镜像需要特殊处理)
# 1. 从阿里云同步仓库拉取 pause 镜像(国内可访问)
sudo docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10
# 2. 给镜像打标签,让 K8s 识别为官方路径(关键:K8s 只认 registry.k8s.io/pause)
sudo docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10 registry.k8s.io/pause:3.10
# 3. 验证标签是否生效(确保输出中有两个名称指向同一镜像)
sudo docker images | grep pause
初始化 Kubernetes 集群
查看服务器网络配置
执行 sudo ip addr
命令,查看服务器网络接口信息,找到 eth0 网卡的 IPv4 地址(示例中为 172.25.54.102)。
版本兼容性说明
重要提示:从 Kubernetes 1.24 版本开始,官方已移除对 dockershim
的支持。如需继续使用 Docker 作为容器运行时,需要安装 cri-dockerd
插件让 K8s 与 Docker 进行桥接。
配置 cri-dockerd
完成 Kubernetes 组件安装后,继续配置 cri-dockerd 以支持 Docker 运行时:
-
下载 cri-dockerd 安装包
# 下载 Debian Bullseye 版本的 .deb(适配 Ubuntu 20.04,10.1MB)。 # 这里是 Github 的地址,可能会有点慢。如果慢可以FQ下载或者用阿里云效。 wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.20/cri-dockerd_0.3.20.3-0.debian-bullseye_amd64.deb
-
下载完成后检查一下文件
# 查看文件大小,输出约 11M左右 即正确 ls -lh cri-dockerd_0.3.20.3-0.debian-bullseye_amd64.deb
-
安装并启动 cri-docker 服务
sudo dpkg -i cri-dockerd_0.3.20.3-0.debian-bullseye_amd64.deb sudo apt -f install -y sudo systemctl daemon-reload sudo systemctl start cri-docker.socket sudo systemctl enable cri-docker.socket sudo systemctl start cri-docker.service # 启动服务 sudo systemctl enable cri-docker.service # 开机启动
-
验证 cri-dockerd 服务状态
# 检查 cri-docker.socket 是否正常运行 sudo systemctl status cri-docker.socket
输出中必须包含 active (running)
-
执行
kubeadm init
kubeadm init
的核心就是 “初始化 K8s 集群配置 + 启动控制平面组件”,这一步需要一点时间,4分钟左右。sudo kubeadm init \ --image-repository registry.aliyuncs.com/google_containers \ --pod-network-cidr=10.244.0.0/16 \ --kubernetes-version=v1.24.0 \ --apiserver-advertise-address=172.25.54.102 \ --cri-socket unix:///var/run/cri-dockerd.sock
配置 kubectl
权限
kubeadm init
完成后,默认只有 root
用户能操作 kubectl
,需给实际使用的普通用户配置权限(替换下面的 ubuntu
为你的用户名):
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes
移除单机节点污点
允许普通 Pod 调度到控制平面节点,单机部署时必须执行(K8s 1.24 版本可能同时存在两种污点)
移除 control-plane
污点(执行后无输出即成功)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
移除 master
污点(部分版本默认存在,需补充执行,避免调度限制)
kubectl taint nodes --all node-role.kubernetes.io/master-
验证污点是否移除(输出中无 "Taints" 字段或 Taints 为空)
kubectl describe node | grep Taints
安装 flannel 网络插件
安装网络插件是 K8s 集群部署的核心,用于实现 Pod 之间的跨节点通信。Flannel 插件包含 2 个容器(核心flannel
,CNI 配置容器kube-flannel-cni
),需全部修改为本地镜像避免远程拉取超时。
步骤 1:提前拉取 Flannel 所需镜像
# 1. Flannel核心服务镜像(主容器)
docker pull m.daocloud.io/docker.io/flannel/flannel:v0.25.5
# 2. Flannel CNI插件镜像(初始化容器,用于安装CNI二进制文件)
docker pull m.daocloud.io/docker.io/flannel/flannel-cni-plugin:v1.2.0
# 3. 清理旧CNI配置的辅助镜像(隐藏的初始化容器,默认用busybox)
docker pull m.daocloud.io/docker.io/busybox:1.35.0 # 必须拉取,否则会远程拉取超时
步骤 2:下载 Flannel 官方配置文件(与镜像版本严格匹配)
# 下载v0.25.5版本对应的配置文件(国内可访问,与镜像版本一致)
wget https://raw.githubusercontent.com/flannel-io/flannel/v0.25.5/Documentation/kube-flannel.yml
# 查看文件是否下载成功(确保文件大小不为0)
ls -lh kube-flannel.yml
步骤 3:修改 yml 文件(3 处修改,全部设置为本地镜像 + 禁止远程拉取)
用vim kube-flannel.yml
打开文件,按/image:
搜索镜像配置,找到以下 3 处并修改:
第 1 处:安装 CNI 插件的初始化容器(install-cni-plugin)
initContainers:
- name: install-cni-plugin
image: m.daocloud.io/docker.io/flannel/flannel-cni-plugin:v1.2.0 # 改为本地拉取的CNI插件镜像
imagePullPolicy: Never # 新增:禁止远程拉取,只用本地镜像
command: ["cp", "-f", "/flannel", "/opt/cni/bin/flannel"]
volumeMounts:
- name: cni-bin-dir
mountPath: /opt/cni/bin
第 2 处:复制 CNI 配置文件的初始化容器(install-cni)
负责将 Flannel 网络配置文件(10-flannel.conflist
)复制到节点,缺少会导致 CNI 无法识别网络规则。
initContainers:
- name: install-cni
image: m.daocloud.io/docker.io/flannel/flannel:v0.25.5 # 改为本地拉取的Flannel核心镜像(与第3处镜像一致)
imagePullPolicy: Never # 新增:禁止远程拉取,强制使用本地镜像
command: ["cp", "-f", "/etc/kube-flannel/cni-conf.json", "/etc/cni/net.d/10-flannel.conflist"] # 复制配置文件到CNI目录
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d # 节点存放CNI配置的目录
- name: flannel-cfg
mountPath: /etc/kube-flannel/ # 挂载Flannel的配置文件目录
第 3 处:Flannel 核心服务容器(kube-flannel)
containers:
- name: kube-flannel
image: m.daocloud.io/docker.io/flannel/flannel:v0.25.5 # 改为本地拉取的核心镜像
imagePullPolicy: Never # 新增:禁止远程拉取,只用本地镜像
command: ["/opt/bin/flanneld"]
args: # 关键参数:必须包含--kube-subnet-mgr,否则无法从apiserver获取子网配置
- --ip-masq # 启用IP伪装,避免Pod访问外部网络时IP暴露
- --kube-subnet-mgr # 从K8s apiserver获取子网信息(核心参数,不可删除)
- --iface=eth0 # 可选:指定服务器的主网卡(如eth0,避免Flannel选错网卡)
步骤 4:部署 Flannel 并验证(确保 3 个容器都正常启动)
# 部署Flannel,-f 是 --filename 的缩写
kubectl apply -f kube-flannel.yml
# 等待30秒,查看Flannel Pod状态(必须全部显示Running,3个容器都就绪)
kubectl get pods -n kube-flannel -o wide
# 验证关键输出(示例,确保STATUS为Running,READY为3/3)
# NAME READY STATUS RESTARTS AGE
# kube-flannel-ds-xxxx 3/3 Running 0 25s
至此,单节点K8s的部署已全部完成,你可以通过kubectl get namespaces
或简写的kubectl get ns
查看所有命名空间,用kubectl get node
查看节点状态(状态为Ready
即表示工作正常),通过kubectl get pod -A
(或--all-namespaces
)查看集群中所有命名空间的Pod,也可以用kubectl get pod -n kube-system
单独查看kube-system
命名空间下的Pod(即K8s核心组件的Pod)。
其他解释
为什么要先单独拉取 pause 镜像?
pause 镜像是 Kubernetes(K8s)的底层基础镜像,在执行 kubeadm init
初始化集群时,K8s 会自动尝试从官方仓库拉取该镜像。但官方仓库地址为 registry.k8s.io/pause
(非 docker.io.pause
),国内网络因访问限制(“墙”)无法直接拉取,会导致拉取失败。
其他 K8s 镜像(如 kube-proxy
、etcd
)可通过 --image-repository
命令 “全局替换仓库”(例如指定从阿里云拉取),但 pause 镜像特殊:K8s 代码中硬编码了其路径为 registry.k8s.io/pause
,仅识别该 “官方名字”。因此,即使从阿里云拉取了 pause 镜像(地址如 registry.cn-hangzhou.aliyuncs.com/google_containers/pause
),也需通过 docker tag
命令手动为其添加 “官方标签”(即重命名为 registry.k8s.io/pause
),K8s 才会认可并使用。
imagePullPolicy
有哪几种?
imagePullPolicy
用于控制 K8s 拉取镜像的策略,共 3 种:
Always
:每次创建 Pod 时,无论本地是否已有镜像,都从仓库拉取最新版本。IfNotPresent
:仅当本地节点不存在该镜像时,才从仓库拉取;本地已有时直接使用。Never
:完全不从仓库拉取,仅依赖本地已有的镜像;若本地没有,Pod 启动失败。
Node 与 Pod 的关系是什么?
-
Node(节点):指集群中的物理服务器或虚拟机,是 K8s 集群的 “工作机器”。节点分为两种:
-
控制节点(control-plane):负责集群管理(如调度、API 服务、集群状态存储等);
-
工作节点(worker node):负责运行实际的应用负载。
所有节点协同工作,构成 K8s 集群的基础。
-
-
Pod:是 K8s 的最小部署单元,每个 Pod 运行在某个 Node 上,包含一个或多个紧密关联的容器(这些容器共享网络、存储等资源)。一个 Node 可运行多个 Pod,K8s 会根据资源情况自动调度 Pod 到合适的 Node 上。
什么是命名空间(Namespace)?
命名空间是 K8s 中的逻辑隔离概念,用于在集群层面分隔不同的资源(如 Pod、服务、配置等)。通过命名空间,可将集群划分为多个 “虚拟子集群”,适用于区分不同环境(如开发、测试、生产)或不同团队的应用,避免资源命名冲突,简化管理。
K8s如何拉取镜像并部署?
# 生成名为“my-app”的Deployment模板,临时指定一个镜像(后续会修改)
kubectl create deployment my-app --image=临时镜像名(如nginx) --dry-run=client -o yaml > 我的名字-deploy.yaml
- 参数说明
--image=临时镜像名
:必填参数(K8s 要求创建 Deployment 时必须指定镜像),可先用nginx
、busybox
等占位,后续在 YAML 中修改为你的实际镜像。--dry-run=client
:仅创建模板,不实际部署到集群。-o yaml > 文件名
:将模板输出为 YAML 文件,方便后续编辑。
打开生成的我的名字-deploy.yaml
文件,重点修改以下内容(其他默认配置可保留):
然后运行 kubectl apply -f 我的名字-deploy.yaml
即可执行部署命令,K8s 会按 YAML 配置拉取镜像并启动应用。