暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

k8s高可用集群部署利器kubeadm实现原理

CloudNativeX 2021-04-27
985

K8S作为一个强大的分布式项目,它复杂部署方式一直都是社区的诟病。特别是在 K8S 发布的前期,部署的方式如乱麻,这也导致了初期在社区推进k8s的难度很大,因为门槛较高。同时,K8S是一个用go语言进行编写的项目,天然就具备跨平台这样的功能,但除了将各个组件编译成二进制文件外,还需要负责为这些二进制文件对应的配置文件自启动脚本,以及为kube-apiserver 密钥证书文件等很多需要做的工作。

经过一段时间的演变,社区出现了各种对K8S部署的解决方案,有通过 saltstack这样的工具来部署的,也有使用ansible 等自动化工具来进行部署的。但是这些工具本身就存在一定的门槛,也就是还需要学习ansible等相关工具的使用,出了问题无法下手排查等,总之,学习成本又高了一层。

那k8s的部署方式就没有比较简单实用方法吗?答案是:有,那就是kubeadm,一款非常优秀的k8s部署工具,于2017年社区初现,是一个天才少年开发的工具,所谓:一朝红日出,依旧与天齐。

通过kubeadm,只需要两步,

1. Master节点执行:kubeadm init    初始化一个master节点

2. Node节点执行:    kubeadm join    就是将节点加入集群中

以上两个命令,即可部署一套k8s集群,是不是很爽?

但,如果你是一个严谨的技术人,你会发现,如果不了解它真正的工作原理,那就相当于这是一个不可控的黑盒,在生产环境中,这是一个不可预知的灾难。那接下来,我来给你聊一聊kubeadm的工作原理,知道它到底做了什么工作,心中有个数。

本篇文章内容是假如你具有一定k8s技术基础,大体知道它有哪些组件构成等

在集群部署时,每个组件都是一个单独可执行的二进制文件。其实,人们也想通过docker容器化来简化部署k8s,但容器化部署存在一个极大的问题,就是如何容器化kubelet。


kubelet是k8s用来操作Docker等容器运行时的核心组件,需要运行在每个节点上,它除了跟docker容器运行时交互以外,kubelet在进行网络、存储卷的管理时,这些都是需要直接和宿主机进行交互的。


所以,如果kubelet直接运行在一个docker容器中,那么直接操作宿主机就会有点舍本逐末,得不偿失。当然,对于网络层面来说倒是没多大问题,因为kubelet的容器在不开启--net host参数的情况下,也可以直接共享宿主机的网络栈。但是,要让kubelet的容器操作宿主机的文件系统等,就会很麻烦了,具体的过程感兴趣的小伙伴去了解下。但到目前为止,通过docker容器化部署kubelet,还是没有一个很好的解决方案。那kubeadm这个工具,已经是当前最优的方案了。


初步,我们把kubelet的二进制直接部署在宿主机上,然后通过容器部署其他的k8s的组件

所以,我们使用kubeadm部署集群的第一步,就是安装kubelet、kubectl和kubeadm这三个二进制文件。

yum install -y kubeadm

这样kubeadm、kubelet、kubectl就已经被安装好了。接下来,kubeadm实力演绎的开始。

第一、创建一个kubeadm初始化的配置文件,名字随便,我们暂且叫它kubeadm-config.yaml,具体的内容如下:

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.18.2
apiServer:
certSANs: #填写所有kube-apiserver节点的hostname、IP、VIP
- k8s-m-0001
- k8s-m-0002
- k8s-m-0003
  - 10.100.0.101
  - 10.100.0.102
  - 10.100.0.103
  - 10.100.0.100 #vip
controlPlaneEndpoint: "10.100.0.100:8443"
networking:
dnsDomain: cluster.local
serviceSubnet: "10.96.0.0/12"
podSubnet: "10.244.0.0/16"
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs


第二、kubeadm init --config kubeadm-config.yaml,初始化第一个主节点,这样,第一个主节点初始化完成,生成对应的证书密钥等文件。这里,需要了解的原理如下;

A. 预检查 

在执行kubeadm init命令后,kubeadm首先要做的是“预检查”的工作,确定这个服务器的环境资源是否可以符合部署K8S。预检查会检查以下项目:

  • Docker 和 kubelet 的驱动是否相同

  • 是否安装了k8s运行所需的二进制文件

  • Docker 是不是正常安装

  • 检查K8S组件的端口是否被占用,比如10250、10251等端口

  • 安装的kubeadm和 kubelet的版本是否匹配?

  • Linux Cgroups 模块是否可用?

  • 配置的hosts是否能正常解析到对应的IP

等这些预检查的项目。


B. 生成对应的证书和目录:

当A步骤这些条件预检查完成没问题之后,kubeadm将会生成K8S对应的各种证书和目录,这些证书和目录是保证K8S集群正常运行运行的必备条件。需要注意的是,当然你也可以选择使用自己的证书,不使用kubeadm为你生成的证书,那kubeadm就会跳过证书生成的步骤。可以把自己的证书放到证书的存放目录下。路径是:/etc/kubernetes/pki/


C. 生成配置文件

其他组件要访问api-serever,就得需要对应的访问api-server的配置文件,这些配置文件的路径是: 

/etc/kubernetes/admin.conf  /etc/kubernetes/controller-manager.conf  /etc/kubernetes/kubelet.conf  /etc/kubernetes/scheduler.conf


D. 为主节点的组件生成Pod对应的配置文件

kubeadm将会master 组件生成 Pod 配置文件。Kubernetes 有三个 Master 组件 kube-apiserver、kube-controller-manager、kube-scheduler,而它们都会被使用 Pod 的方式部署起来。

E.安装默认插件

K8S默认的kube-proxy代理和 DNS 这两个插件是必须安装的。它们分别用来提供整个集群的服务发现和 DNS 功能。其实,只需要通过k8s的客户端命令kubectl安装就ok了。

第三、kubeadm join,这个命令有两个不同的token,分别是master节点的token和worker节点的token。

这一步的原理是,在第一步的kubeadm init生成对应的token之后,我们就可以在别的服务器已经部署了kubelet和kubeadm的机器上,然后通过kubeadm join加入到集群。

通过对应的token(master和worker),别的服务器就可以在kube-apiserver上注册,节点也就可以加入到集群中了。

(1)高可用的主节点master加入集群的命令:

kubeadm join 10.100.0.100:8443 --token pqqcvk.t8apqpldoff49oqu \
--discovery-token-ca-cert-hash sha256:8daa9dc668df02424ab7fef21b5d568597c582b5368c5641cd16b743fd832f22 \
--control-plane

    --control-plane 参数表示的是控制平面,也就是集群的主节点。


(2)高可用的工作节点worker加入集群的命令:

kubeadm join 10.100.0.100:8443 --token pqqcvk.t8apqpldoff49oqu \
--discovery-token-ca-cert-hash sha256:8daa9dc668df02424ab7fef21b5d568597c582b5368c5641cd16b743fd832f22


总结:kubeadm通过init和join两个步骤,从而简单快捷实现了高可用集群的部署,在init通过预检查、生成对应的密钥和证书、配置文件以及安装插件的步骤,最后通过获取对应的token然后节点就可以join到集群中。

文章转载自CloudNativeX,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论