目标
在一台阿里云服务器上部署 k8s + containerd + flannel + ingress-nginx + helm3
准备
一台阿里云服务器(笔者这里是 3m2g2 核)
服务器初始化
重装系统
进入阿里云控制台,找到云服务器 ECS,重装系统(笔者这里是 ubuntu24)
后续补充
笔者用阿里云ubuntu24系统实践遇到了额外问题:
- k8s初始化1700内存限制告警
- containerd容器无法删除
- k8s pod 内dns无法解析外网
这些问题有些能解决,有些用尽了所有力气和手段都无可奈何
后续笔者使用腾讯云ubuntu24同样的流程尝试复现,却发现这些问题都没出现
再接着又实用阿里云debian12.7同样的流程尝试复现,依旧没有问题因此笔者这里建议使用debian系统
安全组
放开所有端口
hostname 设置
通过 hostnamectl 设置 hostname
bash
hostnamectl set-hostname master
exec /bin/bash
hosts 设置
ip route
查看 ip (找 default)
配置 hosts vim /etc/hosts
网络参数调整
k8s 中为什么需要 br_netfilter 与 net.bridge.bridge-nf-call-iptables=1
bash
# 配置iptables参数,使得流经网桥的流量也经过iptables/netfilter防火墙
cat >> /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# 配置生效
sysctl -p /etc/sysctl.d/k8s.conf
# 加载br_netfilter模块
modprobe br_netfilter
containerd 安装
安装
bash
apt update
apt install containerd
生成默认配置文件
bash
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
配置 cgroup 驱动程序
编辑配置文件,将 SystemdCgroup 由 false 改为 true
配置 阿里云镜像加速
创建配置文件
bash
mkdir -p /etc/containerd/certs.d/docker.io
vim /etc/containerd/certs.d/docker.io/hosts.toml
toml
server = "https://registry-1.docker.io"
[host."https://[这里写你的阿里云镜像加速地址前缀].mirror.aliyuncs.com"]
capabilities = ["pull", "resolve", "push"]
# 其他第三方镜像加速地址
[host."https://dockerproxy.com"]
capabilities = ["pull", "resolve", "push"]
重启服务使生效 systemctl restart containerd
containerd 的相关安装配置便已搞定!🎉
k8s 初始化
安装 kubeadm kubelet kubectl
-
kubeadm:用来初始化集群的指令。
-
kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
-
kubectl:用来与集群通信的命令行工具。
- 更新 apt 包索引并安装使用 Kubernetes apt 仓库所需要的包:
bash
sudo apt-get update
# apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
- 下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略 URL 中的版本:
bash
# 如果 `/etc/apt/keyrings` 目录不存在,则应在 curl 命令之前创建它,请阅读下面的注释。
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
- 添加 Kubernetes apt 仓库
bash
# 此操作会覆盖 /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.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
- 更新 apt 包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:
bash
sudo apt-get update
# 列出apt可以安装哪些版本
apt-cache madison kubeadm kubectl kubelet
# 安装指定版本 可以根据需要进行修改
sudo apt-get install kubeadm=1.16.10-00 kubelet=1.16.10-00 kubectl=1.16.10-00
# 锁定版本
sudo apt-mark hold kubelet kubeadm kubectl
命令补全
编辑.bashrc vim ~/.bashrc
在结尾处加上
bashrc
source <(kubectl completion bash)
source <(kubeadm completion bash)
使生效 source ~/.bashrc
若出 现_get_comp_words_by_ref: command not found
错误:
bash
# 安装 bash-completion
apt install bash-completion
# 载入
source /usr/share/bash-completion/bash_completion
环境初始化
提前拉取镜像
bash
kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers
# 可查看
ctr -n k8s.io image ls
⚠️⚠️⚠️将containerd的pause版本与k8s初始化需要的版本设置成一样
查看k8s初始化需要的镜像 kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers
编辑containerd配置文件 vim /etc/containerd/config.toml
记得重启containerd使生效 systemctl restart containerd
集群初始化
bash
kubeadm init \
# 指定k8s版本
--kubernetes-version=1.31.0 \
# 指定master的ip,这里跟ip route查看的default上的ip相同
--apiserver-advertise-address=172.16.89.83 \
# 指定拉取的镜像地址为阿里云
--image-repository=registry.aliyuncs.com/google_containers \
# service的网段
--service-cidr=10.96.0.0/12 \
# pod的网段,这里与后续flannel网络插件中的配置要相同
--pod-network-cidr=10.244.0.0/16 \
# 这里忽略Mem报错,原因是笔者的阿里云服务器内存还不到1700mb
--ignore-preflight-errors=Mem
--ignore-preflight-errors=Mem
这里忽略 Mem 报错,原因是笔者的阿里云服务器内存还不到 1700mb
触发了 k8s 的最低限制(说好的 2g,实际居然只有 1677.1mb,debian12.7正好1700多一点)
向阿里云提交工单反馈,说是正常的
作为对比,笔者这里另一台 4m2g2 核的腾讯云服务器有 1963.7mb
这里必须吐槽一下阿里云,差的可不是一点半点:
初始化卡在了[api-check] The API server is not healthy after 4m0.000526881s

原因就是 registry.k8s.io/pause:3.8
这个镜像没有拉取好
而且奇怪的是kubeadm config images list
并未将其列出来(其依赖的是 3.10 版本)
也许是我使用的 k8s 版本太高了不是很稳定(1.31.0)
后续补充
为什么没列出来,因为这是containerd配置文件中sandbox字段指定的,所以解决方法就是将其更改为k8s初始化所依赖的pause容器地址便可,请参考上文(将containerd的pause版本与k8s初始化需要的版本设置成一样)
因此只需要将registry.k8s.io/pause:3.8
下载导入到 containerd 中即可解决
参考文章 docker.io 被封了后如何下载国外镜像与使用
注意,由于笔者这里用的是 containerd 而非 docker,并且要指定 k8s 使用的 namespace,故导入命令为ctr -n k8s.io image import xxx.tar
导入完后可能会发现 containerd 中突然有运行容器而导致再次初始化集群失败:
使用ctr -n k8s.io task kill [xxx] 删除即可
containerd 停止删除容器运行时 报错
unknown error after kill: runc did not terminate successfully: exit status 1: unable to signal init: permission denied
原因似乎是 ubuntu 中的 Apparmor 服务无法正常工作
https://github.com/containrrr/watchtower/discussions/1887#discussioncomment-7894961
重装 apparmor 即可解决
或运行 sudo aa-remove-unknown
运行sudo aa-remove-unknown
只可以临时解决,后续删除别的pod还是有问题
后续补充
似乎依旧解决不了,容器还是会出现删除不了的问题
同样的步骤,笔者用另一台腾讯云服务器 unbutu24,就没有出现这种问题
于是笔者再次同样的步骤,用阿里云服务器,但是镜像选择了debian12.7,也没有出现这种问题
于是不再深究了,改用debian12.7镜像即可
初始化成功
确保ctr -n k8s.io task ls
清空后,再次:
kubeadm init --kubernetes-version=1.31.0 --apiserver-advertise-address=172.16.89.83 --image-repository=registry.aliyuncs.com/google_containers --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Mem
静静等待几秒后,果然不出所料的成功了!🎉
设置环境变量
编辑 vim ~/.bashrc
在末尾添加export KUBECONFIG=/etc/kubernetes/admin.conf
使生效 source ~/.bashrc
查看 kubectl get node
发现 node 状态是 notReady(后续安装网络插件即可解决)
移除master的污点
kubectl taint node master node-role.kubernetes.io/control-plane:NoSchedule-
Helm3 安装
Helm 帮助您管理 Kubernetes 应用—— Helm Chart,即使是最复杂的 Kubernetes 应用程序,都可以帮助您定义,安装和升级。
简单理解就是 helm 是 k8s 的“包管理器”,类似 npm 与 node 的关系
这里依旧使用apt
进行安装:
bash
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
至此便安装完成,简直不要太简单!🎉
flannel 网络插件
添加 helm 仓库
这里用 helm 安装
bash
# 添加仓库
helm repo add flannel https://flannel-io.github.io/flannel/
# 确认
helm search repo flannel
# 拉取到本地
helm pull flannel/flannel
# 解压
tar -xvf flannel.tgz
# 进入
cd flannel
拉取镜像
筛出依赖的镜像地址cat values.yaml templates/* | grep image:
去查找 values.yaml 中的 repository 与 tag
因此得到这两个依赖的镜像地址:
docker.io/flannel/flannel:v0.25.6
docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel2
使用上文提到的镜像拉取脚本,将这两个镜像同步到服务器:
另外可以注意 values.yaml 中的 podCidr 配置
podCidr="10.244.0.0/16"
与 我们初始化集群时配置的 --pod-network-cidr=10.244.0.0/16
相同
安装
同步完成后输入helm install flannel . -n flannel --create-namespace
安装 flannel
安装完成后输入kubectl get nodes
,查看状态是否变成 ready
至此 flannel 网络插件安装便大功告成!🎉
ingress-nginx
添加 helm 仓库
依旧使用 helm 安装
bash
# 添加仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# 确认
helm search repo ingress-nginx
# 拉取到本地
helm pull ingress-nginx/ingress-nginx
# 解压
tar -xvf ingress-nginx.tgz
# 进入
cd ingress-nginx
拉取镜像
因为 helm 的松散的文件组织原因,筛选出镜像过于繁琐
可以拉取官方的 kubectl 部署方式的单 yaml 文件去检索依赖:
bash
// 将该文件下载下来
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml
// 过滤出镜像地址
cat deploy.yaml | grep image:
无视掉@shaxxxxxx,得到两个镜像地址:
registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3
registry.k8s.io/ingress-nginx/controller:v1.11.2
编辑values.yaml,注释掉镜像地址的digest(让其拉取镜像时不要带@shaxxx后缀)
随后再次使用拉取镜像的脚步做同步:
安装
同步完成后输入 helm install ingress-nginx . -n ingress-nginx --create-namespace
安装 ingress-nginx
笔者这里已经install过了,更新了values.yaml后用upgrade更新:
Comments | 0条评论