本文作者:念宗

kubernetes系列之证书的创建与部署

念宗 6年前 ( 2019-04-26 ) 4973 抢沙发
摘要: 8.1创建TLS证书和密钥为了保证线上集群的信任和数据安全,节点之间必须要使用TLS证书来相互通信。这里我们使用自签名的证书,所以要先生成自有的TLS证书。使用 Clou...

8.1创建TLS证书和密钥

为了保证线上集群的信任和数据安全,节点之间必须要使用TLS证书来相互通信。这里我们使用自签名的证书,所以要先生成自有的TLS证书。

使用 CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 和其它证书。

 

8.2生成的 CA 证书和秘钥文件如下:

o    ca-key.pem

o    ca.pem

o    kubernetes-key.pem

o    kubernetes.pem

o    kube-proxy.pem

o    kube-proxy-key.pem

o    admin.pem           --更正为kubectl.pem

o    admin-key.pem     --更正为kubectl-key.pem

o    etcd-key.pem

o    etcd.pem

使用证书的组件如下:

o    etcd:是否启用https根据需求,内部访问可以不使用https 使用ca.pemetcd-key.pemetcd.pem

o    master(kube-apiserver/kube-controller-manager/kube-scheduler):使用 ca.pemkubernetes-key.pemkubernetes.pem

o    kubelet:使用 ca.pem

o    kube-proxy:使用 ca.pemkube-proxy-key.pemkube-proxy.pem

o    kubectl:使用 ca.pemadmin-key.pemadmin.pem

o    flannel:使用flannel-key.pem,flannel.pem


注意:以下操作都在 master 节点上执行,证书只需要创建一次即可,以后在向集群中添加新节点时只要将 /etc/kubernetes/ssl 目录下的证书拷贝到新节点上即可。


8.3安装 CFSSL

直接使用二进制源码包安装:

 

$ wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64

$ chmod +x cfssl_linux-amd64

$ mv cfssl_linux-amd64 /usr/local/bin/cfssl

 

$ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

$ chmod +x cfssljson_linux-amd64

$ mv cfssljson_linux-amd64 /usr/local/bin/cfssljson

 

$ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

$ chmod +x cfssl-certinfo_linux-amd64

$ mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo

 

[root@master01 ~]# ls /usr/local/bin/
cfssl    cfssl-certinfo  cfssljson

因为涉及的证书比较多,为了便于区分,这里先进行分类说明: 

 

证书类型

文件名

用途说明

CA

ca*

证书机构,颁发证书和签名

master

kubernetes*.pem

master三个组件使用[一般都部署在同一台机器]

kubectl

admin*.pem

客户端管理工具kubectl使用[kubernetes-client]

kube-proxy

kube-proxy*.pem

kube-proxy部署在node




 

生成出来的证书都是两个pem文件,将这里两个文件拷贝到目标机器上。

另外其他需要证书的组件都可以按照步骤生成证书即可

 

8.4 创建 CA (Certificate Authority)

[root@master01 ssl]# pwd
/root/k8s/ssl
[root@master01 ssl]# cfssl print-defaults   config |sed /^$/d > config.json
# 注意默认输出最后有空行,所以这里用了sed处理了一下
cp config.json ca-config.json
[root@node01 ssl]# cat ca-config.json
{
    "signing": {
        "default": {
            "expiry": "87600h"
        },
        "profiles": {
            "kubernetes": {
                "expiry": "87600h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "87600h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            }
        }
    }
}



字段说明
 

o    ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile

o    signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE

o    server auth:表示client可以用该 CA server提供的证书进行验证;

o    client auth:表示server可以用该CAclient提供的证书进行验证;

 

 

8.4.1创建 CA 证书签名请求:

 

创建 ca-csr.json 文件:

[root@master01 ssl]# cfssl print-defaults csr | sed /^$/d > csr.json
cp csr.json   ca-csr.json
修改之后的内容如下:根据默认输出内容修改为实际环境值
[root@master01 ssl]# cat ca-csr.json
{
      "CN": "kubernetes",
      "key": {
          "algo": "rsa",
          "size": 2048
      },
      "names": [
          {
            "C": "CN",
            "L": "HangZhou",
            "ST": "ZJ",
            "O": "k8s",
            "OU": "System"
          }
      ]
}



o   
“CN”Common Namekube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法; 

o    “O”Organizationkube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)

 

 

 

8.4.2生成 CA 证书和私钥:

 

[root@master01 ssl]# cfssl gencert   -initca ca-csr.json | cfssljson -bare ca

2019/03/04 23:43:49 [INFO] generating a   new CA key and certificate from CSR

2019/03/04 23:43:49 [INFO] generate   received request

2019/03/04 23:43:49 [INFO] received CSR

2019/03/04 23:43:49 [INFO] generating   key: rsa-2048

2019/03/04 23:43:49 [INFO] encoded CSR

2019/03/04 23:43:49 [INFO] signed   certificate with serial number 711935179240700127888697823340475658255165125725

[root@master01 ssl]# ls

ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem  config.json    csr.json

# 加亮三个文件为新生成

 

 

8.4.3创建 kubernetes 证书[master使用]

 

创建 kubernetes 证书签名请求文件 kubernetes-csr.json:

[root@master01 ssl]# cp ca-csr.json kubernetes-csr.json

修改内容为如下:

{

      "CN": "kubernetes",

      "hosts": [

        "127.0.0.1",

        "192.168.10.100",

        "192.168.10.101",

        "192.168.10.102",

        "10.1.0.1",

        "kubernetes",

        "kubernetes.default",

        "kubernetes.default.svc",

        "kubernetes.default.svc.cluster",

        "kubernetes.default.svc.cluster.local"

      ],

      "key": {

          "algo": "rsa",

          "size": 2048

      },

      "names": [

          {

            "C": "CN",

            "L": "HangZhou",

            "ST": "ZJ",

            "O": "k8s",

            "OU": "System "

          }

      ]

}


 

 host字段里的私有ip 换成你要部署的节点ip .

127.0.0.1master三个组件一般都部署在同一台机器,会有监听本地端口,组件内部通信采用了127.0.0.1地址

实际上只要将你的所有master节点ip写上就行了.

 

o    如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 kubernetes master集群使用,所以上面分别指定了kubernetes master集群的主机 IP **kubernetes 服务的服务 IP**(一般是kube-apiserver指定的service-cluster-ip-range网段的第一个IP,如我这里选择的是10.1.0.1。同时这个地址也将会是后续容器内部DNS服务器的地址

o    按照上面的配置,向集群中增加新节点后不需要重新生成证书。

 

下面生成 kubernetes 证书和私钥:

[root@master01 ssl]# cfssl gencert   -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes   kubernetes-csr.json | cfssljson -bare kubernetes

[root@master01 ssl]# ls -lrt   kubernetes*

-rw-r--r--. 1 root root  518 Mar    4 23:54 kubernetes-csr.json

-rw-r--r--. 1 root root 1594 Mar  4 23:56 kubernetes.pem

-rw-------. 1 root root 1675 Mar  4 23:56 kubernetes-key.pem

-rw-r--r--. 1 root root 1245 Mar  4 23:56 kubernetes.csr

 

8.4.4创建 admin 证书[kubernetes-client:kubectl管理工具使用]

创建 admin 证书签名请求文件 admin-csr.json,

[root@master01 ssl]# cp kubernetes-csr.json admin-csr.json

修改后内容如下

 

{

      "CN": "admin",

      "hosts": [],

      "key": {

          "algo": "rsa",

          "size": 2048

      },

      "names": [

          {

            "C": "CN",

            "L":   "Hangzhou",

            "ST": "ZJ",

            "O": "system:masters",

            "OU": "System"

          }

      ]

}

 

o    后续 kube-apiserver 使用 RBAC 对客户端( kubeletkube-proxyPod)请求进行授权;

o    kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin  Group system:masters  Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 所有 API的权限;

o    OU 指定该证书的 Group  system:masterskubelet 使用该证书访问 kube-apiserver  ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;

 

[root@master01 ssl]# cfssl gencert   -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes   admin-csr.json | cfssljson -bare admin

[root@master01 ssl]# ls admin*

admin.csr    admin-csr.json    admin-key.pem  admin.pem

 

8.4.5 创建kube-proxy证书

[root@master01 ssl]# cp admin-csr.json kube-proxy-csr.json

{

      "CN": "system:kube-proxy",

      "hosts": [],

      "key": {

          "algo": "rsa",

          "size": 2048

      },

      "names": [

          {

            "C": "CN",

            "L":   "HangZhou",

            "ST": "ZJ",

            "O": "k8s",

            "OU":   "System"

          }

      ]

}

 

o    CN 指定该证书的 User  system:kube-proxy

o    kube-apiserver 预定义的 RoleBinding cluster-admin User system:kube-proxy  Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

生成 kube-proxy 客户端证书和私钥:

[root@master01 ssl]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem   -config=ca-config.json -profile=kubernetes    kube-proxy-csr.json | cfssljson -bare kube-proxy

[root@master01 ssl]# ls kube-proxy*

kube-proxy.csr  kube-proxy-csr.json  kube-proxy-key.pem  kube-proxy.pem

 

 

 

 

 

8.4.6 创建etcd证书

本来etcd不用开启https也可以,但是如果是生产环境或者etcd的访问权限需要严格控制起来,则建议开启x509双向认证。

因为我发现如果不开启https,那么任意在一台机器上部署etcdctl都能对etcd数据库进行访问(默认没有开启用户认证模式,k8s环境中一旦开启是否会影响到集群之间的访问是个未知])。

[root@master01 ssl]# cat create-etcd.sh

 

#!/bin/bash

cd /root/k8s/ssl

cat > etcd-csr.json << EOF

{

      "CN": "etcd",

      "hosts": [

        "127.0.0.1",

        "192.168.10.100",

        "192.168.10.105",

        "192.168.10.106",

        "192.168.10.107"

      ],

    "key": {

          "algo": "rsa",

          "size": 2048

      },

      "names": [

          {

            "C": "CN",

            "L":   "Hangzhou",

            "ST": "ZJ",

            "O": "k8s",

            "OU":   "System"

          }

      ]

}

EOF

 

# 生成证书和私钥

cfssl gencert -ca=ca.pem   -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json |   cfssljson -bare etcd

 

# check pem

echo "=====确认证书内容属性!!!====="

openssl x509  -noout -text -in etcd.pem|egrep   "Issuer:|Subject:|DNS|IP"

·         hosts 字段指定授权使用该证书的 etcd 节点 IP 或域名列表,这里将 etcd 集群的三个节点 IP 都列在其中;127.0.0.1可用于本地测试,192.168.10.100VIP地址

·         除了CN名称,其他信息保持跟kubectl/master等相同

分发证书和私钥到各个etcd节点:[不要忘了ca证书]

 

[root@master01 ssl]# for host in etcd01 etcd02 etcd03;do scp ca.pem etcd-key.pem etcd.pem $host:/etc/kubernetes/ssl/;done

 

8.4.7 创建flannel证书

[root@master01 ssl]# cat create-flanneld.sh

 

#!/bin/bash

cd /root/k8s/ssl

cat > flanneld-csr.json << EOF

{

      "CN": "flanneld",

      "hosts": [],

      "key": {

          "algo": "rsa",

          "size": 2048

    },

      "names": [

          {

            "C": "CN",

            "L":   "Hangzhou",

            "ST": "ZJ",

            "O": "k8s",

            "OU":   "System"

          }

      ]

}

EOF

 

# 生成证书和私钥

cfssl gencert -ca=ca.pem   -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes   flanneld-csr.json | cfssljson -bare flanneld

 

# check pem

echo "=====确认证书内容属性!!!====="

openssl x509  -noout -text -in flanneld.pem|egrep   "Issuer:|Subject:|DNS|IP"

 

  • 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;

 

将生成的证书和私钥分发到所有节点master worker):

 

 

 

 

 

 

8.4.8校验证书

kubernetes 证书为例:

# openssl x509  -noout -text -in  kubernetes.pem


o    确认 Issuer 字段的内容和 ca-csr.json 一致;

o    确认 Subject 字段的内容和 kubernetes-csr.json 一致;

o    确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;

o    确认 X509v3 Key UsageExtended Key Usage 字段的内容和 ca-config.json  kubernetesprofile 一致;

 

8.5 分发证书

 

生成证书的过程可以到任何一台机器上进行,生成之后作为原始文件可以留作备份,然后将这些证书分别拷贝到集群的目标机器。比如master机器就把master相关证书拷贝过去,需要安装管理工具kubectl的机器,就把admin相关证书拷贝过去。

为了统一,集群中机器存放证书的路径规定为:/etc/kubernetes/ssl

将生成的证书和秘钥文件(两个后缀名为.pem的文件)拷贝到 /etc/kubernetes/ssl 目录下:


文章版权及转载声明:

作者:念宗本文地址:http://pyops.net/?id=51发布于 6年前 ( 2019-04-26 )
文章转载或复制请以超链接形式并注明出处运维之道

分享到: 网站分享代码

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

发表评论

快捷回复:

验证码

评论列表 (暂无评论,4973人围观)参与讨论

还没有评论,来说两句吧...