kubeadm安装Kubernetes集群部署笔记

背景

最近在极客时间上跟Chrono大神学习Kubernetes基础,在实践过程中遇到一些运维、使用方面的问题,这里把整个过程以及遇到的问题进行记录。

kubeadm,原理和 minikube 类似,也是用容器和镜像来封装 Kubernetes 的各种组件,但它的目标不是单机部署,而是要能够轻松地在集群环境里部署 Kubernetes,并且让这个集群接近甚至达到生产级质量。

准备两台机器
Master:10.218.21.192
Worker:10.218.21.184
发行版本:CentOS7
内核版本:3.10.0-1127.el7.x86_64

步骤一 安装Docker Engine

虽然 Kubernetes 目前支持多种容器运行,但 Docker 还是最方便最易用的一种,所以继续使用 Docker 作为 Kubernetes 的底层支持。
使用Yum安装Docker
【如果已经安装Docker没问题可忽略~】

#更新
 yum update
 #添加仓库
 yum install -y yum-utils
 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
 #安装
 yum install docker-ce docker-ce-cli containerd.io
 #启动
sudo systemctl start docker
sudo systemctl enable docker
systemctl status docker

这里面遇到的问题是环境污染问题,我的系统以前使用安装包安装过dockerd,并且用dockerd &的方式启动,用这种方式启动的docker会遇到很多未知问题,所以使用Yum重新安装,但是没有对原环境进行彻底清理,只是kill掉了dockerd进程,在使用yum安装的docker之后,执行docker ps等操作都没有反应。所以考虑还是跟之前安装docker有关系,需要清理一下。
[问题]:在关闭systemctl stop docker警告。

Warning: Stopping docker.service, but it can still be activated by:
 docker.socket

是因为 docker在关闭状态下被访问会触发自动唤醒机制
可以通过执行

systemctl stop docker 
systemctl stop docker.socket

清空环境,将docker-ce docker-ce-cli containerd.io全部yum remove,将cp docker/* /usr/bin/的操作移入的文件全部删除,之后重新安装。
清理完之后,在使用yum重新安装启动,但还是失败,查找原因。
[问题] 使用 journalctl -xe 查看systemd日志的命令

containerd: failed to get listener for main endpoint: is a directory
Failed to start containerd container runtime.
Unit containerd.service entered failed state.
containerd.service failed.


这里就是我之前说的环境污染,不知道之前解决什么问题,创建了一个/run/containerd/containerd.sock目录,但其本该是一个设备文件,导致containerd起不来,所以删除之后,执行systemctl restart containerd就可以进行解决。

步骤二:安装前配置

  1. 修改主机名,由于 Kubernetes 使用主机名来区分集群里的节点,所以每个节点的 hostname 必须不能重名,这里我感觉是可选的,只要自己可以管理即可,影响不大。
sudo vi /etc/hostname
  1. 对 Docker 的配置, 在“/etc/docker/daemon.json”里把 cgroup 的驱动程序改成 systemd ,然后重启 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

sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
  1. 修改 iptables 的配置,启用“br_netfilter”模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1 # better than modify /etc/sysctl.conf
EOF

sudo sysctl --system
  1. 修改“/etc/fstab”,关闭 Linux 的 swap 分区,提升 Kubernetes 的性能
sudo swapoff -a
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab

步骤三:安装kubeadm

设置镜像库

vi /etc/yum.repos.d/kubernetes.repo

文件内容

[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl

安装

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# 查看安装结果
kubeadm version
kubectl version --client

步骤四:安装kubernetes的Master节点

kubeadm 把 apiserver、etcd、scheduler 等组件都打包成了镜像,以容器的方式启动 Kubernetes,但这些镜像不是放在 Docker Hub 上,而是放在 Google 自己的镜像仓库网站 gcr.io,而它在国内的访问很困难,直接拉取镜像几乎是不可能的。

镜像准备

可以先查看要安装的镜像

kubeadm config images list --kubernetes-version v1.28.6
# --kubernetes-version 指定安装版本,默认最新


接下来要做的就是准备这些镜像。
从国内的阿里云镜像网站下载然后再用 docker tag 改名,相关脚本

repo=registry.aliyuncs.com/google_containers

for name in `kubeadm config images list --kubernetes-version v1.28.6`; do

    src_name=${name#registry.k8s.io/}
    src_name=${src_name#coredns/}

    docker pull $repo/$src_name

    docker tag $repo/$src_name $name
    docker rmi $repo/$src_name
done

[问题] 这里可能会遇到报错

Error response from daemon: pull access denied for registry.aliyuncs.com/google_containers/registry.kube-apiserver, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

后面一值在像着docker login方向研究,但是怎么试也不行。其实当这个地址不对时。相关镜像错误的时候也会报这个错误,后来验证确实是地址错误的原因,正确的路径是registry.aliyuncs.com/google_containers/kube-apiserver,这就是对镜像这块知识储备不足导致的问题,耽误了很多时间,其实不是什么大的问题。

开始安装

kubeadm init --pod-network-cidr=10.10.0.0/16 --apiserver-advertise-address=10.218.21.184  --kubernetes-version=v1.28.2 --image-repository registry.aliyuncs.com/google_containers

# --pod-network-cidr,设置集群里 Pod 的 IP 地址段。
# -apiserver-advertise-address,设置 apiserver 的 IP 地址,对于多网卡服务器来说很重要,可以指定 apiserver 在哪个网卡上对外提供服务。
# --kubernetes-version,指定 Kubernetes 的版本号。

[问题]
不出意外的话应该还是会出意外,出现报错

This error is likely caused by:
- The kubelet is not running
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

表面看不出那里问题,使用 journalctl -xeu kubelet 和 journalctl -xeu containerd 查看日志排查报错两种错误

error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR CRI]: container runtime is not running: output: time="2023-02-20T08:33:48Z" level=fatal msg="validate service connection: CRI v1 runtime API is not implemented for endpoint "unix:///var/run/containerd/containerd.sock": rpc error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
, error: exit status 1

相关的讨论:https://github.com/containerd/containerd/issues/8139
应该是跟 /etc/containerd/config.toml文件中的 disabled_plugins = ["cri"] 配置有关。
可以直接删掉,然后重启

rm /etc/containerd/config.toml
systemctl restart containerd

在国内光删除这个应该还是不行,会报docker pull registry.k8s.io/pause:3.6 超时的问题。即使我们手动的将镜像下载到本地也不行。需要我们配置刚才删除的config.toml的文件
相关配置可参考:https://www.cnblogs.com/-ori/p/16971368.html
主要是 sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9 这条配置
后面在执行kubeadm init就不会有什么问题了

#重新加载配置文件与重启containerd
systemctl daemon-reload && systemctl restart containerd
在使用kubeadm init命令

#执行完init命令会告诉我们后续的执行内容,逐条执行即可
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

#其他节点直接这条join操作就会拉取相应的镜像与网络插件
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.218.21.192:6443 --token 78sqrd.zme05kf8bwxajzwg --discovery-token-ca-cert-hash sha256:c1fdd9e5fe3e22273fe863744186116d509426c7481ce7394657dbc1fe442741

#检查
kubectl version
kubectl get node

但是查看node的信息是NotReady状态,这是因为没有网络插件,所以还不能组成集群。

安装Flannel 网络插件

下载yml文件 https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
修改配置文件的网段

  net-conf.json: |
    {
      "Network": "10.10.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

执行

kubectl apply -f kube-flannel.yml
#再次查看状态就变成Ready状态

步骤五:安装kubernetes的Worker节点

Worker节点需要把上述1,2,3步骤全部安装完成后,执行命令

kubeadm join 10.218.21.192:6443 --token 78sqrd.zme05kf8bwxajzwg --discovery-token-ca-cert-hash sha256:c1fdd9e5fe3e22273fe863744186116d509426c7481ce7394657dbc1fe442741

不出意外的还是会出意外

这里提示两种错,一种是上面已经遇到的问题,通过删除rm /etc/containerd/config.toml解决,其实也存在docker pull registry.k8s.io/pause:3.6 的问题,只是暂时不在这里解决。
删除config.toml文件之后可以正常启动。
另外还有一种报错是

unexpected kernel config: CONFIG_CGROUP_PIDS 和
missing required cgroups: pids

这是与内核有关,可以对比内核信息和执行命令 cat /boot/config-uname -r | grep CGROUP查看相关设置,这块要么升级内核,要么只能更换机器了。
在kubeadm join成功之后,在控制面板(Master节点)执行kubectl get nodes 发现worker节点还是NotReady状态

kubectl get pod -n kube-system 发现有一个proxy启动不成功。

kubectl describe pod kube-proxy-vm4cj -n kube-system 查看详情。

遇到熟悉的报错了,还是需要解决registry.k8s.io/pause:3.6镜像问题,所以上一步光删除config.toml不行,需要用新的配置文件替换,然后重启containerd,方法同上。
重启之后再次查看日志。

执行成功,在使用kubectl get nodes会发现两个节点全部启动

总结思考

正如那句老话,难者不会,会者不难,所有的事情回头来看都感觉不过如此,但当时是头疼,真的头疼。头疼的原因有很多,运维能力不足,相关的知识体系没有掌握,可能还有一点原因是个人习惯安装的方式和使用的版本与课程、教程不一致,这会导致很多莫名其妙的问题,虽然会给自己带来一些麻烦,但解决问题的过程,学习的知识可能比安装本身更有意义。

posted @ 2024-01-29 19:57  zscbest  阅读(201)  评论(0编辑  收藏  举报