kubeadm init流程

1.引导前的检查

kubeadm init执行后,首先需要对集群master节点安装的各种约束条件进行逐一检查。
如果不符合kubeadm的要求,kubeadm将报错并停止init过程。
下面列举一些error级别的检查:
  kubeadm版本要与安装的kubernetes版本的比对检查。
  kubernetes安装的系统需求检查。
  其它检查:用户、主机、端口、swap、工具等。

 

2.生成私钥和数字证书

kubeadm会为整个集群生成多组私钥和公钥数字证书。
包括整个集群的root CA的私钥和CA的公钥数字证书,
API Server与其它组件之间的相互通信所用的多组私钥和数字证书,
用于service acount token签名的私钥和公钥文件等。
这样使得kubeadm搭建出来的集群是一个安全的集群。
所有kubernetes自身组件的通信以及pod到API Service的通信都是基于安全数据通道的。
且有生成验证和授权机制的。

关于数字证书、CA和CA证书:
数字证书:互联网通讯中标志通讯各方身份信息的一串数字,提供了一种在互联网上验证通信实体身份的方式。

CA:Certificate Authority,证书授权中心。它是负责管理和签发证书的第三方机构。
  它是负责管理和签发证书的第三方机构,作用是检查证书持有者身份的合法性,并签发证书,以访证书被伪造或篡改。
  数字证书就是CA发行。

CA证书:CA颁发的证书,也就是我们常说的数字证书,包含证书拥有者的身份信息,CA机构的签名,公钥和私钥。
   身份信息用于证明证书持有者的身份;CA签名用于保护身份的真实性。公钥和私钥用于通信过程中加解密,从而保证通信信息的安全性。


查看kubeadm的证书:

主要包括:

(1)自建CA、生成ca.key和ca.crt

如果不指定外部的证书授权机构,那么kubeadm会自建证书授权机构
生成私钥(ca.key)和自签署的数字证书(ca.crt),用于后续签发kubernetes集群所需要的其它公钥证书证书。
查看ca的数字证书:
ca.crt是一个标准的x509格式的数字证书文件。

ubuntu@VM-16-6-ubuntu:/etc/kubernetes/pki$ openssl x509 -in ca.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)  #版本号
        Serial Number: 0 (0x0)  #序列号,ca的第一个证书
    Signature Algorithm: sha256WithRSAEncryption  #加密方式
        Issuer: CN=kubernetes
        Validity
            Not Before: Jun 19 03:23:59 2019 GMT
            Not After : Jun 16 03:23:59 2029 GMT
        Subject: CN=kubernetes
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b4:e0:c3:3b:74:92:dc:57:87:dc:0e:cb:cb:1c:
                    92:e3:17:7d:74:eb:d5:06:14:7b:88:22:d2:77:34:
                    59:be:85:d2:65:7a:88:46:bc:9d:ec:3a:7e:d7:85:
                    08:e2:ce:46:cd:38:06:e1:6b:af:a8:46:b5:1e:3b:
                    74:60:a6:7a:45:6a:dd:fa:01:77:9f:61:66:5d:5c:
                    8e:06:82:9e:da:15:a3:80:95:e0:a2:f5:f7:3a:d5:
                    d1:1f:ce:f0:a7:47:df:75:a2:ad:62:95:a2:7b:f2:
                    15:8d:f2:b0:d0:82:f5:59:1f:75:c0:a8:fd:02:8e:
                    35:05:2b:96:ec:78:d7:c1:0c:9b:34:26:53:c8:df:
                    0a:c4:27:05:12:74:1d:26:4c:b0:15:74:74:b8:4d:
                    08:c4:d9:48:19:77:6f:49:e9:27:de:ed:f6:f5:d4:
                    8b:93:14:8e:cb:3d:0d:f8:20:bc:15:80:37:64:22:
                    cc:c2:bc:62:27:d4:cc:41:3b:81:59:26:77:10:fc:
                    8b:c6:7c:1f:9a:20:77:92:3c:51:f9:b8:15:8a:85:
                    d4:c5:02:aa:91:11:9c:ed:b7:fd:fd:2c:09:57:37:
                    f6:00:91:38:98:52:48:f6:b1:ed:d7:91:78:d0:a5:
                    d2:30:ff:d1:76:e3:ea:91:e2:d8:3f:26:82:ea:cd:
                    0f:53
                Exponent: 65537 (0x10001)
        X509v3 extensions:  #证书的用途
            X509v3 Key Usage: critical
                Digital Signature(数据签名), Key Encipherment(密钥加密), Certificate Sign(证书签发)
            X509v3 Basic Constraints: critical
                CA:TRUE  #这是一个ca的公钥证书
    Signature Algorithm: sha256WithRSAEncryption
         a6:f7:53:49:4f:1c:c4:1b:e9:84:08:4c:5a:49:03:c8:32:b1:
         24:15:b6:47:0b:78:db:9a:1d:c5:23:fb:7b:89:fa:96:2d:eb:
         df:e9:d8:ad:3a:90:02:e0:fd:12:f2:0c:b2:15:68:72:e4:08:
         83:57:ed:c9:78:5c:ae:10:4c:c5:92:50:14:32:c4:66:12:34:
         50:7f:e0:5d:b0:6e:5f:95:49:b7:e3:c8:83:b9:90:f0:94:29:
         19:0a:7c:9a:e6:59:68:11:1a:92:e8:9d:29:30:3c:3b:aa:06:
         7f:59:89:e0:37:8b:c2:2e:89:a0:68:d1:78:bc:6c:d1:d9:79:
         cd:0c:2e:7b:7c:c4:4c:59:2e:89:13:fc:c6:6c:f3:45:e7:6e:
         b1:15:41:ee:eb:4c:15:c1:59:e4:8e:84:d8:34:c6:dd:95:eb:
         36:26:4a:99:94:e4:11:6f:69:89:53:cb:8f:c0:6b:8f:bf:3f:
         91:3b:03:d0:db:67:96:a1:f1:16:40:af:e3:44:14:21:8c:f0:
         02:e9:a0:78:fc:30:5a:dd:d8:c1:b4:87:2c:2f:a3:64:71:e3:
         7d:88:a4:6f:c1:b6:f0:44:a3:8e:90:b2:10:e0:b8:02:00:af:
         40:bb:3b:6c:b9:b4:cf:9d:92:f9:83:1d:ba:d2:c8:f5:e3:04:
         0f:70:cf:9f

(2)apiserver的私钥与公钥证书

有了ca之后,就可以用来签发集群所使用的各种证书。
kubeadm会生成API Server的私钥文件,运用ca来签发API Server的公钥数据证书。
在pki目录下,apiserver.key是APIServer的私钥文件。apiserver.crt是用ca来签署的APIServer的公钥数据证书。
查看apiserver.crt证书内容:

ubuntu@VM-16-6-ubuntu:/etc/kubernetes/pki$ openssl x509 -in apiserver.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 5825362278220765184 (0x50d7d820c14f1800)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=kubernetes
        Validity
            Not Before: Jun 19 03:23:59 2019 GMT
            Not After : Jun 18 03:23:59 2020 GMT
        Subject: CN=kube-apiserver  #与ca中不一样
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:de:f4:70:62:6b:75:a2:d7:55:e6:b7:3e:54:4e:
                    75:f7:1a:d8:68:dd:b5:b8:3d:80:7b:06:b1:00:5b:
                    b3:71:32:d3:19:42:74:23:e6:32:9c:4a:a8:ef:28:
                    a5:63:28:d4:e7:e7:e9:77:6a:b3:36:15:b4:0e:c8:
                    46:c6:94:c1:a6:79:c7:fd:38:62:b0:9c:8c:83:f9:
                    7e:2f:11:f3:38:6a:81:50:f0:f3:54:66:28:95:04:
                    77:23:01:9d:7b:16:c9:45:7a:3f:4a:14:4a:f1:7a:
                    07:f3:85:f1:ab:cc:bf:e2:15:4e:3e:da:11:f0:8f:
                    2b:e0:81:1f:19:d2:27:17:97:e4:24:b9:e4:4d:20:
                    c7:91:ab:24:f1:25:ea:a5:de:0e:37:9d:d0:30:57:
                    95:82:7a:6d:ff:1e:7d:7e:3f:82:69:6b:c3:0d:e0:
                    cc:53:be:91:2f:f8:ec:6a:13:21:9f:d9:db:8a:f2:
                    a1:d1:b7:8e:5c:0e:16:41:d0:a9:e1:70:85:c2:86:
                    4a:dd:d9:0e:01:97:4e:ab:32:0c:ee:ec:7a:4f:64:
                    aa:0d:33:1d:d1:44:54:2b:97:b3:b5:88:7e:b4:1a:
                    d5:4e:31:a6:4c:3f:59:a0:60:4b:43:3c:4f:54:75:
                    64:83:cd:8a:37:a8:6b:61:51:cb:b5:07:7e:d3:45:
                    9e:55
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature(数据签名), Key Encipherment(密钥加密)#并没有签署证书的用途
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:   #可用于多种域名和IP地址。
                DNS:vm-16-6-ubuntu, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP Address:10.96.0.1, IP Address:148.70.251.10
    Signature Algorithm: sha256WithRSAEncryption
         ac:77:88:a4:c7:10:78:1a:25:f9:9d:d8:a7:0f:89:a7:62:d4:
         3c:27:86:b8:95:13:14:20:70:b9:00:88:a6:04:7b:01:a1:ba:
         3f:79:a6:12:7f:98:c1:2c:b5:5f:05:43:d6:38:55:3c:96:02:
         82:94:8b:b6:d5:99:48:e1:69:ac:cf:e9:44:b3:a4:73:6f:e5:
         83:91:f5:f9:1c:f6:43:f1:42:a8:a5:ca:bc:53:53:93:db:ed:
         7f:cb:fd:8c:9b:35:07:0c:cc:ea:f2:5e:be:20:d8:f7:58:f8:
         60:b0:ab:4a:82:a9:ec:5b:4d:da:7d:9a:5c:95:f4:37:e5:89:
         3a:1d:0a:ef:bd:fe:95:cd:b0:f8:07:d4:ba:17:36:da:33:cf:
         fc:f0:5e:98:0b:f9:db:b2:8f:a3:8c:1e:99:86:49:82:9f:29:
         5d:ef:13:83:94:6d:e4:3a:a6:81:b6:a3:9c:32:a9:8e:76:a6:
         e8:62:52:15:27:82:36:cc:c6:3d:89:12:9c:c8:9d:3a:cd:61:
         91:a7:f6:22:44:71:db:f4:ea:6f:65:37:9c:5a:5e:91:18:cb:
         35:3e:b6:00:46:8e:a9:64:76:b0:b7:90:c8:f1:06:4d:b4:e4:
         6b:65:b5:7c:f7:cd:36:ba:d8:4d:84:f5:e9:20:08:53:8f:3e:
         b0:55:72:5a

(3)apiserver访问kubelet使用的客户端私钥与证书

APIServer会向各个node的kubelet主动发起链接,并从kubelet获取日志。
或touch到正在运行的pod中,或提供kubelet的端口转发功能。
kubelet会通过client端的SSL证书,来校验APIServer建立的链接。
apiserver-etcd-client.crt和apiserver-etcd-client.key用来证明APIServer的合法身份的。

(4)sa.key和sa.pub

sa是service acount的缩写。
sa.key用于对service acount token的数据签名。sa.pub是sa.key对应的公钥文件。

(5)Etcd相关私钥和数字证书

etcd是kubernetes整个集群的控制中心,而集群中唯一可以访问的组件是APIServer,
其它组件都是通过API Server的API存储数据的。
为建立etcd和API Server之间的安全数据通道,kubeadm init会生成APIServer访问etcd的相关私钥和证书。
apiserver-etcd-client.crt和apiserver-etcd-client.key是kubeadm init生成的APIServer用于访问etcd的私钥文件和公钥数字证书。用于etcd对于APIServer的身份验证所用。
在pki目录下面,还有一个etcd目录,专门用来保存与etcd相关的证书文件。

我们可以看到,etcd下面也有一个ca,那apiserver-etcd-client.crt这个数字证书是由谁来签发的了?测试一下

root@VM-16-6-ubuntu:/etc/kubernetes/pki# openssl verify -CAfile ca.crt ./apiserver-etcd-client.crt 
./apiserver-etcd-client.crt: O = system:masters, CN = kube-apiserver-etcd-client
error 7 at 0 depth lookup:certificate signature failure  #报错了,证明并非是由pki目录下的ca签发
139720460449432:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:rsa_pk1.c:103:
139720460449432:error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed:rsa_eay.c:705:
139720460449432:error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:a_verify.c:218:

root@VM-16-6-ubuntu:/etc/kubernetes/pki# openssl verify -CAfile etcd/ca.crt ./apiserver-etcd-client.crt 
./apiserver-etcd-client.crt: OK

 

3.生成控制平面组件kubeconfig文件,这些文件将用于组件之间通信鉴权使用

通过kubeadm init将master节点启动成功后,告知了kubeconfig的配置方法。
配置之后,kubectl就可以直接使用这些信息,访问kubernetes集群。

这些文件都是kubeconfig文件,由kubeadm init生成。
kubelet.conf被kubelet组件使用,用于访问APIServer。
scheduler.conf被scheduler组件所使用,用于访问APIServer。
controller-manager.conf被controller-manager组件所使用,用于访问APIServer。
admin.conf包含了整个集群的最高权限配置数据。

一旦配置了KUBECONFIG变量,kubectl就会使用KUBECONFIG变量所配置的信息。
Kubeconfig包含cluster、user和context信息。

Kubeconfig包含cluster、user和context信息。
root@VM-16-6-ubuntu:/etc/kubernetes# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED  #ca信息
    server: https://148.70.251.10:6443  #服务地址
  name: kubernetes
contexts:  #用来绑定user和cluster。
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes  #定义用哪个user访问哪个cluster。
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

允许kubectl快速切换context,这样可以使用不同身份管理不同集群。

 

4.生成控制平面组件manifest文件

这些文件将会被master节点上的kubelet所读取,并启动master控制平面组件,以及维护这些控制平面组件的状态。
虽然kubeadm init将集群引导起来,但是有些问题你需要知道。
比如控制平面的组件是怎么启动起来的?如果重启了master节点,这些组件是否还会自动重启。
这些控制组件的参数如何调整,又如何生效了?

kubeadm init在启动过程中,会生成各个组件的manifests文件。

对应master上所有组件。控制平面组件以Static Pod形式运行。

root@VM-16-6-ubuntu:/etc/kubernetes/manifests# cat kube-scheduler.yaml 
apiVersion: v1
kind: Pod
metadata:
  annotations:
    scheduler.alpha.kubernetes.io/critical-pod: ""
  creationTimestamp: null
  labels:
    component: kube-scheduler
    tier: control-plane
  name: kube-scheduler
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-scheduler
    - --address=127.0.0.1
    - --leader-elect=true
    - --kubeconfig=/etc/kubernetes/scheduler.conf
    image: k8s.gcr.io/kube-scheduler-amd64:v1.10.2
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: 127.0.0.1
        path: /healthz
        port: 10251
        scheme: HTTP
      initialDelaySeconds: 15
      timeoutSeconds: 15
    name: kube-scheduler
    resources:
      requests:
        cpu: 100m
    volumeMounts:
    - mountPath: /etc/kubernetes/scheduler.conf
      name: kubeconfig
      readOnly: true
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/scheduler.conf
      type: FileOrCreate
    name: kubeconfig
status: {}

这些manifests文件都是控制平面组件的yaml文件。
master节点上的pod将读取这些文件,并启动控制平面组件。
与普通pod不同的是,这些pod是以静态pod的形式运行。

静态pod是由节点上的kubelet进程来管理的,不通过APIServer来管理,也不关联任何replication的控制器。
由kubelet进程自己来监控。当静态pod崩溃时,kubelet会重启这些pod。
静态pod始终绑定在一个kubelet上,并且始终运行在同一个节点上。
kubelet会自动为每一个静态pod在APIServer上创建一个镜像的pod。
我们可以通过APIserver查询这些pod,但是不能通过APIServer对这些镜像进行控制。
如果要刪除静态pod,可以直接将其对应的manifests下的yaml文件移除即可。
所有控制平面的静态pod都运行在kubesystem的名称空间下,并且使用主机网络。
kubelet读取manifests目录并管理各控制平台组件pod启停。
如果修改调整组件的yaml文件,kubelet也会监视到这些变化,并重启对应的pod,使其配置生效。

 

5.下载镜像,等待控制平面启动

默认情况下Kubeadm依赖kubelet下载镜像并启动static pod.默认从k8s.gcr.io上下载组件镜像。
kubeadm会一直探测并等待localhost:6443/healthz服务返回成功。
localhost:6443/healthz服务是APIServer的存活探针服务。
存活探针配置在manifests的配置文件中的。

vim kube-apiserver.yaml
    ...
    livenessProbe:
      failureThreshold: 8  #失败门槛次数
      httpGet:
        host: 148.70.251.10
        path: /healthz
        port: 6443
        scheme: HTTPS
      initialDelaySeconds: 15
      timeoutSeconds: 15  #超时时间
    ...

 

6.保存MasterConfig配置信息,也就是集群创建的初始信息。

 

7.设置Master标值

将当前节点设置为master节点,这样工作负载就不会调度到master节点上。

 

8.进行基于TLS的安全引导相关配置

为后续的worker节点的加入,进行基于TLS的安全引导相关配置。

 

9.安装DNS和kube-proxy插件

DNS插件安装后会处于pending状态,需要等到网络插件安装后才能恢复到running状态。
以DaemonSet方式部署Kube-proxy。

部署Kube-dns插件,作为内部DNS服务,可以使用CoreDNS来替代。

 

posted @ 2020-03-31 16:47  明王不动心  阅读(11761)  评论(1编辑  收藏  举报