kubernetes(五)揭开 kubeadm 的神秘面纱

Kubernetes(一)认识 kubernetes

Kubernets(二)部署非高可用Kubernetes集群的环境准备

Kubernets(三)部署非高可用Kubernetes集群-通过阿里云源安装 kubeadm、kubelet 和 kubectl

Kubernets(四)创建集群

Kubernetes(五)揭开 kubeadm 的神秘面纱

Kubernetes(六)第一个kubernetes 对象

文章目录

  • 前言
  • 一、部署 kubernets 工具的演进
  • 二、kubeadm 的原理
    • 1. kubernetes 部署工具的本质
    • 2. 为什么不能完全使用容器部署 kubernetes
    • 3. kubeadm 的解决方案
  • 三、kubeadm init 的工作流程
    • 1. 首先做如下一系列的检查
    • 2. 生成 Kubernetes 对外提供服务所需的各种证书和对应的目录
    • 2.1 集群证书
    • 2.2 发送命令的请求证书
    • 2.3 使用自己的证书
    • 3 生成集群组件使用的配置文件
    • 4 为Master 用到的组件生成 Pod 配置文件
    • 4. 生成 Token
    • 5. 安装插件

前言

一、部署 kubernets 工具的演进

其实,Kubernetes 作为一个 Golang 项目,已经免去了很多类似于 Python 项目要安装语言级别依赖的麻烦。但是,除了将各个组件编译成二进制文件外,用户还要负责为这些二进制文件编写对应的配置文件、配置自启动脚本,以及为 kube-apiserver 配置授权文件等等诸多运维工作。

在 Kubernetes 项目发布初期,它的部署完全要依靠一堆由社区维护的脚本。

后来,各大云厂商一般使用 SaltStack、Ansible 等运维工具自动化地执行这些步骤。

2017 年,在志愿者的推动下,社区才终于发起了一个独立的部署工具,名叫:kubeadm。

这个项目的目的,就是要让用户能够通过这样两条指令完成一个 Kubernetes 集群的部署:


# 创建一个Master节点
$ kubeadm init

# 将一个Node节点加入到当前集群中
$ kubeadm join <Master节点的IP和端口>

二、kubeadm 的原理

1. kubernetes 部署工具的本质

之前我们说过 Kubernetes 的架构和它的组件。在部署时,它的每一个组件都是一个需要被执行的、单独的二进制文件。

所以不难想象,SaltStack 这样的运维工具或者由社区维护的脚本的功能,就是要把这些二进制文件传输到指定的机器当中,然后编写控制脚本来启停这些组件。

2. 为什么不能完全使用容器部署 kubernetes

不过,现在你知道了容器这个技术,是不是有这样的想法:
这些 kubernetes 的组件为能不能用容器部?

这样,我只要给每个 Kubernetes 组件做一个容器镜像,然后在每台宿主机上用 docker run 指令启动这些组件容器,部署不就完成了吗?

这样做会带来一个很麻烦的问题,即:如何容器化 kubelet?

kubelet 是 Kubernetes 项目用来操作 Docker 等容器运行时的核心组件。可是,除了跟容器运行时打交道外,kubelet 在配置容器网络、管理容器数据卷时,都需要直接操作宿主机。

网络的问题还好解决,不过数据卷怎么办?

要让 kubelet 隔着容器的 Mount Namespace 和文件系统,操作宿主机的文件系统,就有点儿困难了。

比如,如果用户想要使用 NFS 做容器的持久化数据卷,那么 kubelet 就需要在容器进行绑定挂载前,在宿主机的指定目录上,先挂载 NFS 的远程目录。

由于现在 kubelet 是运行在容器里的,这就意味着它要做的这个“mount -F nfs”命令,被隔离在了一个单独的 Mount Namespace 中。即,kubelet 做的挂载操作,不能被“传播”到宿主机上。

3. kubeadm 的解决方案

把 kubelet 直接运行在宿主机上,然后使用容器部署其他的 Kubernetes 组件。

所以,你使用 kubeadm 的第一步,是在机器上手动安装 kubeadm、kubelet 和 kubectl 这三个二进制文件。当然,kubeadm 的作者已经为各个发行版的 Linux 准备好了安装包,所以你只需要执行:

  1. 使用当前系统版本对应的仓库文件
  2. 使用 系统对应的软件包安装命令安装即可
yum install kubeadm kubelet kubectl

接下来,你就可以使用“kubeadm init”部署 Master 节点了。

三、kubeadm init 的工作流程

1. 首先做如下一系列的检查

  • Linux 内核的版本必须是否是 3.10 以上?
  • Linux Cgroups 模块是否可用?
  • 机器的 hostname 是否标准?在 Kubernetes 项目里,机器的名字以及一切存储在 Etcd 中的 API 对象,都必须使用标准的 DNS 命名(RFC 1123)。
  • 用户安装的 kubeadm 和 kubelet 的版本是否匹配?
  • 机器上是不是已经安装了 Kubernetes 的二进制文件?
  • Kubernetes 的工作端口 10250/10251/10252 端口是不是已经被占用?
  • ip、mount 等 Linux 指令是否存在?
  • Docker 是否已经安装?
  • ……

2. 生成 Kubernetes 对外提供服务所需的各种证书和对应的目录

Kubernetes 对外提供服务时,除非专门开启“不安全模式”,否则都要通过 HTTPS 才能访问 kube-apiserver。

这就需要为 Kubernetes 集群配置好证书文件。

2.1 集群证书

kubeadm 为 Kubernetes 项目生成的证书文件都放在 Master 节点的 /etc/kubernetes/pki 目录下。
在这个目录下,最主要的证书文件是 ca.crt 和对应的私钥 ca.key

kubernetes(五)揭开 kubeadm 的神秘面纱_第1张图片

2.2 发送命令的请求证书

用户使用 kubectl 获取容器日志等 streaming 操作时,需要通过 kube-apiserver 向 kubelet 发起请求,这个连接也必须是安全的。

kubeadm 为这一步生成的是:

  • apiserver-kubelet-client.crt 证书
  • apiserver-kubelet-client.key 私钥

2.3 使用自己的证书

可以选择不让 kubeadm 为你生成这些证书,而是在初始化集群之前,拷贝现有的证书到如下证书的目录里:
/etc/kubernetes/pki/

最终它们的样子应该像下面一样:

/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key

这时,kubeadm 就会跳过证书生成的步骤,把它完全交给用户处理。

3 生成集群组件使用的配置文件

证书生成后,kubeadm 接下来会为其他组件生成访问 kube-apiserver 所需的配置文件。这些文件的路径是:
/etc/kubernetes/xxx.conf

[root@k8s-master ~]# ls /etc/kubernetes/*.conf
/etc/kubernetes/admin.conf
/etc/kubernetes/controller-manager.conf
/etc/kubernetes/kubelet.conf
/etc/kubernetes/scheduler.conf

这些文件里面记录的是,当前这个 Master 节点的服务器地址、监听端口、证书目录等信息。这样,对应的客户端(比如 scheduler,kubelet 等),可以直接加载相应的文件,使用里面的信息与 kube-apiserver 建立安全连接。

4 为Master 用到的组件生成 Pod 配置文件

之前说过 Kubernetes 有三个 Master 组件:

  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler

而它们都会被使用 Pod 的方式部署起来。

当然,目前 Kubernetes 集群尚不存在,kubeadm 不会直接执行 docker run 来启动这些容器。

在 Kubernetes 中,有一种特殊的容器启动方法叫做 “Static Pod”。

它允许你把要部署的 Pod 的 YAML 文件放在一个指定的目录里。

这样,当这台机器上的 kubelet 启动时,它会自动检查这个目录,加载所有的 Pod YAML 文件,然后在这台机器上启动它们。

在 Master 节点的服务器上,存放 Master 组件的 YAML 文件目录是:
/etc/kubernetes/manifests/

kubernetes(五)揭开 kubeadm 的神秘面纱_第2张图片

etcd.yaml 是最后生成的

关于一个 Pod 的 YAML 文件怎么写、里面的字段如何解读。后面后有专门的章节讲解。这里我们只需要注意以下几点信息即可。

  1. 这个 Pod 里只定义了一个容器,它使用的镜像是什么 。这些镜像都是 Kubernetes 官方维护的一个组件镜像。
  2. 这个容器的启动命令(commands)是什么。
  3. 如果你要修改一个已有集群的 kube-apiserver 的配置,需要修改这个 YAML 文件。
  4. 这些组件的参数也可以在部署时指定。

在这一步完成后,kubeadm 还会再生成一个 Etcd 的 Pod YAML 文件,用来通过同样的 Static Pod 的方式启动 Etcd。

目录 /etc/kubernetes/manifests

是被kubelet 监视的,kubelet 会自动创建这些 YAML 文件中定义的 Pod。

Master 容器启动后,kubeadm 会通过检查 localhost:6443/healthz 这个 Master 组件的健康检查 URL,等待 Master 组件完全运行起来。

4. 生成 Token

以上步骤完成后,kubeadm 就会为集群生成一个 bootstrap token。

在后面,只要持有这个 token,任何一个安装了 kubelet 和 kubadm 的节点,都可以通过 kubeadm join 加入到这个集群当中。

这个 token 的值和使用方法,会在 kubeadm init 结束后被打印出来。

在 token 生成之后,kubeadm 会将 ca.crt 等 Master 节点的重要信息,通过 ConfigMap 的方式保存在 Etcd 当中,供后续部署 Node 节点使用。

这个 ConfigMap 的名字是 cluster-info。

5. 安装插件

kubeadm init 的最后一步,就是安装默认插件。

kube-proxy 和 dns 这两个插件是必须安装的。它们分别用来提供整个集群的服务发现和 DNS 功能。其实,这两个插件也只是两个容器镜像而已,所以 kubeadm 只要用 Kubernetes 客户端创建两个 Pod 就可以了。

你可能感兴趣的:(kubernetes)