WSの小屋

目标

在一台阿里云服务器上部署 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 驱动程序

配置 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"]

配置镜像加速器_容器镜像服务(ACR)-阿里云帮助中心

重启服务使生效 systemctl restart containerd

containerd 的相关安装配置便已搞定!🎉

k8s 初始化

安装 kubeadm kubelet kubectl

安装 kubeadm kubelet kubectl

  • kubeadm:用来初始化集群的指令。

  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。

  • kubectl:用来与集群通信的命令行工具。

  1. 更新 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
  1. 下载用于 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
  1. 添加 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
  1. 更新 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 的关系

Helm Install

这里依旧使用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 网络插件

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条评论