从零搭建 k8s 集群
家里的台式机闲置了,建了几个虚拟机就打算搭建一个一主一从的集群,方便在家使用。
一,准备工作
// :转发 IPv4 并让 iptables 看到桥接流量
$ 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
// 应用 sysctl 参数而不重新启动
$ sudo sysctl --system
二,安装容器运行时 —— docker
k8s v1.24 之后就不用 docker 而使用 containerd 了,但是,安装 docker 时本身也需要安装 containerd ,而且 docker 还能用来构建镜像,所以还是决定安装 docker。
1,进入 docker 官网
https://docs.docker.com/engine/install/
docker 官网 ——> Docker Engine ——> Server ——> Centos(x86_64/amd64) 来到 Install Docker Engine on ContOS 页面。有三种安装方法,选择第一种 Install using the repository:
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
// 安装最新的版本,指定版本网页上也有详细说明
$ sudo systemctl start docker
$ sudo systemctl enable docker
// 设置开机自启
$ sudo docker run hello-world
// 检测是否安装成功
三,安装 kubeadm,kubelet,kubectl
https://kubernetes.io/zh-cn/docs/setup/production-environment/tools/kubeadm/install-kubeadm/,centOS 是基于 Red Hat 的发行版。
$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
// 将 SELinux 设置为 permissive 模式(相当于将其禁用)
$ sudo setenforce 0
$ sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
$ sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
$ sudo systemctl enable --now kubelet
四,创建集群
在执行 kubeadm init 之前还有些准备工作,不然会报错。如果 kubeadm init 没有成功执行,解决问题后都要先 kubeadm reset 再 kubeadm init,主从节点都是,如果从节点执行了 kubeadm join。
1,此时直接执行 $ kubeadm init,有两条报错信息:
报错一:[WARNING Firewalled]…
解决办法:需要关闭防火墙
$ systemctl disable firewalld
$ systemctl stop firewalld
报错二:[ERROR CRI]…
报错原因是当前的 containerd 是服务于 docker 的,它的配置文件也是由 docker 指定为 disable-plugins=[“cri”]。
// docker:“You don’t need to be yourself, obey me!”
解决办法:删除当前配置,并生成一个 containerd 单独运行用的默认配置。
$ rm -rf /etc/containerd/config.toml
$ containerd config default > /etc/containerd/config.toml
// 修改生成的默认配置中的其中一条:false 改为 true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
// 此时如果再执行 kubeadm reset; kubeadm init 那么是可以初始化成功的,但是,在安装网络插件时需要在 init 时添加子命令,那么又需要重新初始化集群,所以先看 calico 教程:
https://projectcalico.docs.tigera.io/getting-started/kubernetes/quickstart
$ sudo kubeadm init --pod-network-cidr=192.168.0.0/16
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml
$ kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/custom-resources.yaml
$ watch kubectl get pods -n calico-system
// 部署 calico 的时候要用 create ,如果用 apply 会报错说注解太长
3,加入 worker 节点
在上一步执行完 sudo kubeadm init –pod-network-cidr=192.168.0.0/16 后,会出现一条 kubeadm join 的命令,复制到 worker 节点执行就行。
// 以上几乎所有操作都是要在所有节点上运行的,只是 init 以及安装 calico 只在主节点上执行,join 只在从节点上执行。
五,注意事项
1,如果当前节点之前已经执行过 kubeadm init/join,再重建 k8s 集群时一定要先 kubeadm reset。
2,把网络插件从 calico 改成 flannel 后,kube-system 下面的 coredns 起不来,原因是 kubelet 会从默认目录读取配置文件,如果有多个配置文件,那么它会按字母顺序应用先出现的配置文件中的 CNI 插件。解决办法:到 coredns 所在的节点上删除 /etc/cni/net.d/ 目录下面关于 calico 的两个相关文件。
六,追加
1,后期使用时发现 master 节点跟 pod 不通,但是 worker 节点是通的。暂不清楚原因。改用 flannel 正常:
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
$ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
2,2023/07/26 在新的机器上搭建最新的 k8s1.27,三台机器的系统分别是 alma,opensuse,debian:
1)alma 正常;
2)opensuse 多次修正均报错:
The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
// opensuse 的软件包有些问题,安装的 kubelet 无法正常使用,后续换成 ubuntu 系统正常
3)debian 报错:CRI 没有正常运行,但查看 containerd 的状态又是 running 的,原因是通过 apt 安装的 containerd 版本太低不适配 k8s1.27 ,通过 docker 官网的提示安装最新的 containerd 就行(1.6.21 可以)。