这篇文章上次修改于 318 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
k8s 集群安装笔记
要做的事
- 配置每个节点的 host & hostname
- 关闭 swap, 开启必须的内核支持
- 下载集群所需的软件, 指定要使用的 container
- 初始化主节点
- 安装第三方网络插件
- 登录从节点, 重复前三步并加入集群
硬件要求
- 两台以上 Linux, 虚拟机也算.
- 2H2G 以上配置
- 网络能够互相访问
其中网络这里如果是云服务器应该会遇到各种防火墙问题, 但我是内网环境部署.
配置主节点
配置 host & hostname
host 文件配置也很简单, 和 Windows 下是一样的, 大概写成这样:
# /etc/hosts
10.0.0.1 k8s-master1
10.0.10.1 k8s-node1
10.0.10.2 k8s-node2
设备名将作为节点名出现在 kubectl get ndoes
中, 一般命名方式就是 k8s-master node1 这样.
sudo hostnamectl set-hostname "xxx"
关闭 swap
# 临时关闭
sudo swapoff -a
# 效果是在 /etc/fstab 文件注释掉带有 swap 的配置行
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
但是我发现重启设备后仍然开启了 swap, 用 systemctl --type swap --all
命令也能看到有输出.
解决方案也很简单, 直接删了 swap 分区 (或者这样
$ systemctl --type swap
UNIT LOAD ACTIVE SUB DESCRIPTION
dev-disk-by\x2ddiskseq-1\x2dpart2.swap loaded active active Swap Partition
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
1 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
# 因为包含转义字符所以一定要引号
$ sudo systemctl mask "dev-disk-by\x2ddiskseq-1\x2dpart2.swap"
Created symlink /etc/systemd/system/dev-disk-by\x2ddiskseq-1\x2dpart2.swap → /dev/null.
开启内核
这里可以暂时先跳过, 如果有问题后续报错会给出具体缺少哪些支持.
另外 modules-load.d 文件夹是安装 containerd 时自动创建的.
可以先用 lsmod | grep -e br_netfilter -e overlay
验证, 已经开启就不需要管了.
我配置的时候发现 Ubuntu 没开 br_netfilter.
# vim /etc/modules-load.d/k8s.conf
overlay
br_netfilter
sysctl 在 kubeadm init 时会自动配置, 从节点存疑. 根据系统不同可能有 /etc/sysctl.d 文件夹并且有其他配置.
其中 bridge 参数依赖上面的 br_netfilter 模块, 临时开启用 sudo modprobe br_netfilter
.
# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-iptables=1
应用改变
sudo sysctl --system
安装必要软件
Arch 系安装非常简单, 其他发行版参考官方文档.
安装时可能会提示 iptables 和 iptables-nft 冲突, 查了一下可以直接平替不影响系统.
按照官方文档来看, 比较推荐使用 containerd 作为 runtime, 它使用 crictl 进行管理.
这意味着现在将不再依赖 docker.
# 只需要安装这些, 其他的将作为软件依赖或者由 kubeadm 自动安装到 containerd.
yay -S kubeadm kubectl kubelet containerd
配置服务自启
sudo systemctl enable --now kubelet.service containerd.service
指定 runtime 为 containerd, 否则每次使用都会遍历 sock 并报错.
sudo crictl config runtime-endpoint unix:///run/containerd/containerd.sock
这些软件之间的关系:
- kubeadm 是一个方便的 kubernetes cluster 安装工具, 可以快速部署每个节点, 其中主节点用 kubeadm init 初始化, 从节点用初始化输出内容中的 kubeadm join 加入集群.
- kubectl 负责与集群的通信, 默认情况下只有主节点可以用, 在从节点上执行会请求本机的 8080 端口, 这没有用.
- kubelet 最重要的东西, 也是唯一一个 service. 用来启动本机的 pod 和 container.
- containerd 官方现在推荐的容器运行时, 旧版本则使用 docker.
说到这里, 可以发现它们和集群的主从节点之间并没有什么关联, 也就是说不管什么节点都需要安装这些软件!
主从节点只是代表了分工的不同, 但它们仍然都是节点, 并且在高可用集群中身份也是可以互换的.
不同于其他三个, kubeadm 是非必须软件. 它做的只是帮你自动配置集群.但是 kubernetes 的配置过程极其复杂, 就算不用 kubeadm 也会选择其他的平替软件.
用 crictl image ls
命令查看已配置完成的主从节点的镜像, 发现有很大的区别.
从节点的镜像
IMAGE TAG IMAGE ID SIZE
docker.io/flannel/flannel-cni-plugin v1.2.0 a55d1bad692b7 3.88MB
docker.io/flannel/flannel v0.23.0 01cdfa8dd262f 28.1MB
registry.k8s.io/kube-proxy v1.28.4 83f6cc407eed8 24.6MB
registry.k8s.io/pause 3.9 e6f1816883972 322kB
主节点的镜像
IMAGE TAG IMAGE ID SIZE
docker.io/flannel/flannel-cni-plugin v1.2.0 a55d1bad692b7 3.88MB
docker.io/flannel/flannel v0.23.0 01cdfa8dd262f 28.1MB
registry.k8s.io/coredns/coredns v1.10.1 ead0a4a53df89 16.2MB
registry.k8s.io/etcd 3.5.9-0 73deb9a3f7025 103MB
registry.k8s.io/kube-apiserver v1.28.4 7fe0e6f37db33 34.7MB
registry.k8s.io/kube-controller-manager v1.28.4 d058aa5ab969c 33.4MB
registry.k8s.io/kube-proxy v1.28.4 83f6cc407eed8 24.6MB
registry.k8s.io/kube-scheduler v1.28.4 e3db313c6dbc0 18.8MB
registry.k8s.io/pause 3.9 e6f1816883972 322kB
初始化 kubeadm
首先可以提前拉取镜像 (可选, 如果对自己的网络环境自信可以直接跳到下一步), 或者在执行 kubeadm init
时将自动拉取, 我整个初始化时间是两分半, 但网络环境不好就无法保证了.
如果是国内服务器应该用第二条, 因为默认镜像源是 k8s.io
, 仓库地址是 prod-registry-k8s-io-ap-southeast-1.s3.dualstack.ap-southeast-1.amazonaws.com
, 不管是哪个裸连体验都要比 docker 和 github 还要差.
sudo kubeadm config images pull
sudo kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
然后再执行初始化操作, 因为包含了一些重要信息最好记录一下这里的输出内容.
如果后续有问题可以执行 sudo kubeadm reset -f
来重新开始 init.
# 这里需要加上 --image-repository registry.aliyuncs.com/google_containers 才会使用刚才拉取到的阿里云镜像
$ sudo kubeadm init --pod-network-cidr 10.244.0.0/16 --service-cidr 10.96.0.0/12 --apiserver-advertise-address 10.0.0.1 --control-plane-endpoint k8s.kazusa.cc
[init] Using Kubernetes version: v1.28.4
......
[certs] apiserver serving cert is signed for DNS names [coda kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.0.0.1]
......
[certs] etcd/server serving cert is signed for DNS names [coda localhost] and IPs [10.0.0.1 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [coda localhost] and IPs [10.0.0.1 127.0.0.1 ::1]
......
[mark-control-plane] Marking the node coda 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 coda as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: blkkkw.f0a5598qnshl5w7z
......
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
......
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 10.0.0.1:6443 --token blkkkw.f0a5598qnshl5w7z \
--discovery-token-ca-cert-hash sha256:26654980f017cafd0ccec0476c862c724c35c0ee7e072d45cd96670e47ebb779
根据输出选择其中一种配置文件的存储方式, 这种服务还是上 root 权限比较稳, 有几种方式都可以实现自动加载环境变量, 这里我选择 environment.
export KUBECONFIG=/etc/kubernetes/admin.conf
echo 'KUBECONFIG=/etc/kubernetes/admin.conf' | sudo tee -a /etc/environment
# source /etc/environment
查看一下刚才拉取的镜像, 感觉和 docker 差不多.
$ sudo crictl image ls
IMAGE TAG IMAGE ID SIZE
registry.k8s.io/coredns/coredns v1.10.1 ead0a4a53df89 16.2MB
registry.k8s.io/etcd 3.5.9-0 73deb9a3f7025 103MB
registry.k8s.io/kube-apiserver v1.28.4 7fe0e6f37db33 34.7MB
registry.k8s.io/kube-controller-manager v1.28.4 d058aa5ab969c 33.4MB
registry.k8s.io/kube-proxy v1.28.4 83f6cc407eed8 24.6MB
registry.k8s.io/kube-scheduler v1.28.4 e3db313c6dbc0 18.8MB
registry.k8s.io/pause 3.8 4873874c08efc 311kB
registry.k8s.io/pause 3.9 e6f1816883972 322kB
注意到这里有两个相邻版本的 pause, 这是因为 containerd 默认的更旧, 同时 init 也输出了 detected that the sandbox image "registry.k8s.io/pause:3.8" of the container runtime is inconsistent with that used by kubeadm. It is recommended that using "registry.k8s.io/pause:3.9" as the CRI sandbox image.
, 既然如此我们手动替换一下.
不知道为什么我这里都没有 containerd 文件夹, 之前在 kali WSL 中测试是有的. 但是没关系, 直接把默认的配置导出到对应位置就好了.
通过查看帮助找到默认配置文件是 /etc/containerd/config.toml
sudo mkdir /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo vim /etc/containerd/config.toml
配置文件也不算很长, 就不说怎么找了. 将 sandbox_image = "registry.k8s.io/pause:3.8"
替换为 3.9 即可. 如果使用镜像源这一行会带有例如 aliyuncs.com
的字样
然后重启软件再重置 kubeadm.
sudo systemctl restart containerd
sudo kubeadm reset
sudo crictl rmi 4873874c08efc
sudo kubeadm init --pod-network-cidr 10.244.0.0/16 --service-cidr 10.96.0.0/12 --apiserver-advertise-address 10.0.0.1
发现这一次没有下载 pause:3.8 了.
安装第三方网络插件
这一步很重要, 后期想换插件比较麻烦, 而且方式一点都不优雅. 所以最好一开始就选定要使用的网络插件.
这里我选择 Flannel, 因为它好像更简单.
cd /srv/k8s/config
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
sudo kubectl apply -f kube-flannel.yml
根据 项目文档 的描述, 如果使用那个默认网段什么都不用修改.
If you use custom podCIDR (not 10.244.0.0/16) you first need to download the above manifest and modify the network to match your one.
* 类似于 docker compose, k8s 的默认文件名为 kustomization.yaml
配置从节点
有了之前的经验配置起来就很快了, 大概是这样:
- 重复之前的前三步
- 命令由
kubeadm init
改为kubeadm join
作为从节点加入集群 - 网络插件 (存疑)
先写到这, 下次开三个虚拟机测试一下.
todo: Hyper-V 装 iso
补充 Debian 配置软件源并 hold 版本
配置 dashboard
完善超链接
参考文章
https://www.drxcloud.club/662.html
https://github.com/chaseSpace/k8s-tutorial-cn/blob/main/install_by_kubeadm/install.md
https://www.linuxtechi.com/install-kubernetes-cluster-on-debian/
https://kubernetes.io/zh-cn/docs
https://zhuanlan.zhihu.com/p/613288409
https://www.qikqiak.com/post/manual-install-high-available-kubernetes-cluster/
https://alanhou.org/kubernetes-recipes/
已有 2 条评论
感谢,原来 containerd 是指定了旧版本的 pause,难怪会同时有好几个版本的 pause。然后网络那块,flannel 的服务是 DaemonSet 的,意味着每个节点都会部署一个,不用手动操作。A DaemonSet for every architecture to deploy the flannel pod on each Node.
@Emmett 同样感谢, 感觉这方面的相关资料太少了也可能是我不会找.