k8s 证书创建

一 证书分类
服务器证书:
server cert :用户客户端验证服务端的身份。
客户端证书:
client cert:用户服务端验证客户端的身份。
对等证书:
peer cert: 用户成员之间的身份验证,例如etcd,(该证书,它即是server cert,又是client cert)。
 
二 k8s集群证书的分类
ETCD:
需要server cert标识自己,也需要client cert与其它etcd集群通讯,因此需要一个peer cert(对等证书)。
master节点:
需要标识api-server的server cert,也需要client cert连接到etcd集群,还需要一个对等证书peer跟client交互。
kubelet:
需要标识服务kubelet的server cert,也需要client cert 去请求api-server,因此还需要一个对等证书peer cert。
kubelet,kube-proxy,calico:
需要client cert
 
三 生成的 CA 证书和秘钥文件
目录位置:/etc/kubernetes/ssl
分类
证书/秘钥
说明
备注
Ca
ca-key.pem
证书私钥
单独存放的pem格式证书的秘钥
 
ca.pem
证书
可以单独存放证书文件,也可以同时存放证书和秘钥
 
ca.csr
证书签名请求文件,包含证书持有人的信息,如:国家,邮件,域名等
 
Kubernetes
kubernetes-key.pem
   
 
kubernetes.pem
   
 
kubernetes.csr
   
Admin
admin-key.pem
admin用户
集群必须有一个用户来操作,所以默认我们会配置一个管理员用户
 
admin.pem
   
 
admin.csr
   
Kube-proxy
kube-proxy.crt
   
 
kube-proxy.key
   
 
使用证书的组件
分类
证书/秘钥
说明
ETCD
ca.pem
 
 
kubernetes-key.pem
 
 
kubernetes.pem
 
kube-apiserver
ca.pem
 
 
kubernetes-key.pem
 
 
kubernetes.pem
 
kube-controller-manager
ca-key.pem
 
 
ca.pem
 
kubelet
ca.pem
 
kube-proxy
ca.pem
 
 
kube-proxy-key.pem
 
 
kube-proxy.pem
 
kubectl
ca.pem
 
 
admin-key.pem
 
 
admin.pem
 
 
CA 证书说明讲解
可信任证书颁发机构
例如:我们的身份证,它为什么大家都认可它信任它,因为它是*局颁发的所有被信任,这里的CA机构就相当于*局。
 
CA证书结构:
ca-config.json (CA配置文件)
{
  "signing": {   #表示该证书可用于签名其它证书;生成的ca.pem证书中CA=TRUE。
    "default": {
      "expiry": "8760h"   #默认证书过期时间(小时,用户可自己调大过期时间)。
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",  #表示client可以用该CA对server提供的证书进行验证。
            "client auth"   #表示server可以用该CA对client提供的证书进行验证。
        ],
        "expiry": "8760h"  #默认证书过期时间(小时,用户可自己调大过期时间)。
      }
    }
  }
}
ca-csr.json(证书签名请求)
{
  "CN": "kubernetes",  #CN-Common Name:kube-apiserver从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法
  "key": {
    "algo": "rsa",   #加密算法
    "size": 2048     #加密的位数,您可以不改也可以加大
  },
  "names": [
    {
      "C": "CN",         #国家
      "ST": "BeiJing",  #城市
      "L": "BeiJing",   #组织
      "O": "k8s",       #O-Organization:kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group);
      "OU": "System"    #组织单元
    }
  ]
}

 

四 证书生成操作
4.1 证书颁发工具
安装cfssl
这里我们选择CloudFlare的PKI工具集cfssl ,它比OpenSSL要简单
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

export PATH=/usr/local/bin:$PATH
4.2 创建CA(Certificate Authority)
4.2.1 创建ca配置文件:(CA证书的说明可参考上面CA证书讲解部分)
mkdir /root/ssl
cd /root/ssl

cfssl print-defaults config > config.json
cfssl print-defaults csr > csr.json

# 根据config.json文件的格式创建如下的ca-config.json文件

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
4.2.2 创建CA证书签名请求文件
cat > ca-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ],
    "ca": {
       "expiry": "87600h"
    }
}
EOF
4.2.3 生成CA证书文和私钥
$cfssl gencert -initca ca-csr.json | cfssljson -bare ca

$ll
total 20
drwxr-xr-x 2 root root   93 Aug  3 10:24 ./
drwxr-xr-x 5 root root   60 Aug  3 09:11 ../
-rw-r--r-- 1 root root  292 Aug  3 10:23 ca-config.json
-rw-r--r-- 1 root root 1001 Aug  3 10:24 ca.csr      #证书签名请求文件
-rw-r--r-- 1 root root  253 Aug  3 10:23 ca-csr.json
-rw------- 1 root root 1679 Aug  3 10:24 ca-key.pem #证书私钥
-rw-r--r-- 1 root root 1359 Aug  3 10:24 ca.pem     #证书
4.3 创建kubernetes证书
4.3.1 创建kubernetes证书签名请求文件kubernetes-csr.json
 
注意:
. 如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表,由于该证书后续被 etcd 集群和 kubernetes master 集群使用,所以上面分别指定了 etcd 集群kubernetes master 集群的主机 IP 和 kubernetes 服务的服务 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1)。
 
. 以下物理节点的IP也可以更换为主机名
cat > kubernetes-csr.json <<EOF
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "172.20.0.112",
      "172.20.0.113",
      "172.20.0.114",
      "172.20.0.115",
      "10.254.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",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF
4.3.2 生成kubernetes证书和秘钥
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes

$ ll kubernetes*
-rw-r--r-- 1 root root 1269 Aug  3 10:36 kubernetes.csr     #证书签名请求文件
-rw-r--r-- 1 root root  578 Aug  3 10:36 kubernetes-csr.json
-rw------- 1 root root 1679 Aug  3 10:36 kubernetes-key.pem #证书私钥
-rw-r--r-- 1 root root 1635 Aug  3 10:36 kubernetes.pem     #证书 
4.4 创建Admin证书
4.4.1 创建admin证书签名请求文件admin-csr.json
注意:
. kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
. kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该 Role 授予了调用kube-apiserver 的所有 API的权限;
. O 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;
 
注意证书权限的关系:
. 这个admin 证书,是将来生成管理员用的kube config 配置文件用的,现在我们一般建议使用RBAC 来对kubernetes 进行角色权限控制, kubernetes 将证书中的CN 字段 作为User, O 字段作为 Group
. 安装完集群后您可以查看该admin用户的集群权限,以下命令可查看,查看到 clusterrolebinding cluster-admin 的 subjects 的 kind 是 Group,name 是 system:masters。 roleRef 对象是 ClusterRole cluster-admin。 意思是凡是 system:masters Group的 user 或者 serviceAccount 都拥有 cluster-admin 的角色。 因此我们在使用 kubectl 命令时候,才拥有整个集群的管理权限
$ kubectl get clusterrolebinding cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: 2017-04-11T11:20:42Z
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "52"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin
  uid: e61b97b2-1ea8-11e7-8cd7-f4e9d49f8ed0
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters
4.4.1 创建admin证书签名请求文件admin-csr.json
cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF
4.4.2 生成admin证书和私钥:
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

$ ll admin*
-rw-r--r-- 1 root root 1009 Aug  3 10:48 admin.csr
-rw-r--r-- 1 root root  229 Aug  3 10:45 admin-csr.json
-rw------- 1 root root 1675 Aug  3 10:48 admin-key.pem
-rw-r--r-- 1 root root 1399 Aug  3 10:48 admin.pem
4.5 创建kube-proxy证书
4.5.1 创建kube-proxy证书签名请求文件kube-proxy-csr.json
注意:
. CN 指定该证书的 User 为 system:kube-proxy
. kube-apiserver 预定义的 RoleBinding system:node-proxier 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;
cat > kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
4.5.2 生成kube-proxy证书和秘钥
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy

$ ll kube-proxy*
-rw-r--r-- 1 root root 1009 Aug  3 10:55 kube-proxy.csr
-rw-r--r-- 1 root root  230 Aug  3 10:54 kube-proxy-csr.json
-rw------- 1 root root 1679 Aug  3 10:55 kube-proxy-key.pem
-rw-r--r-- 1 root root 1403 Aug  3 10:55 kube-proxy.pem

 

 
五 校验证书
如 kubernets证书
5.1 使用OpenSSL命令校验:
openssl x509 -noout -text -in kubernetes.pem
检查字段:
. 确认 Issuer 字段的内容和 ca-csr.json 一致;
. 确认 Subject 字段的内容和 kubernetes-csr.json 一致;
. 确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;
. 确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.json 中 kubernetes profile 一致;
$ openssl x509  -noout -text -in  kubernetes.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            65:d7:41:64:d0:f7:62:78:3a:da:e3:1c:72:25:16:84:b7:bb:9f:8b
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = CN, ST = BeiJing, L = BeiJing, O = k8s, OU = System, CN = kubernetes
        Validity
            Not Before: Aug  3 02:31:00 2021 GMT
            Not After : Aug  1 02:31:00 2031 GMT
        Subject: C = CN, ST = BeiJing, L = BeiJing, O = k8s, OU = System, CN = kubernetes
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:d2:d8:2c:15:96:6d:97:03:1c:26:1a:17:06:38:
                    d5:7f:e1:4f:12:3a:f6:52:bd:4e:ae:0a:12:7a:ac:
                    c9:8a:23:38:2b:5c:3f:46:47:9f:95:15:7a:4d:69:
                    f3:0a:87:74:5c:28:2e:e5:6c:fe:55:79:51:d1:5a:
                    9e:ef:fd:a3:65:67:cf:66:f3:fb:d6:4a:29:98:11:
                    a8:8a:e7:9a:8f:05:bd:4c:23:e9:52:93:43:5a:09:
                    fc:39:48:ac:f9:04:15:a1:92:1e:af:4d:26:99:7b:
                    d7:ee:3c:b0:71:bc:a2:95:da:d4:78:dc:44:52:ad:
                    f3:47:a2:d2:4d:57:25:e5:56:59:ed:c5:dd:2c:5b:
                    d6:66:f1:7e:0b:4d:61:03:6a:8b:a0:df:54:71:f3:
                    48:c8:51:02:fc:4b:a2:4d:71:8c:41:af:0b:b7:f3:
                    61:09:a9:c4:49:7c:e0:68:d6:a6:ea:e3:bd:27:95:
                    2f:f7:a6:59:56:28:ea:b0:e2:b8:3e:31:74:97:ee:
                    04:08:70:ae:00:4f:21:a9:37:77:dc:fb:76:c6:78:
                    c5:fa:a3:46:20:b4:f6:5f:79:d1:16:fc:5f:64:c7:
                    57:68:34:49:3b:99:40:91:ce:2c:2d:de:fe:fc:fa:
                    83:5e:5e:73:6c:f1:46:6a:8f:64:f1:b8:6f:92:1b:
                    66:89
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                6F:FE:15:72:91:75:2F:F5:E5:50:A9:26:8F:76:C7:8F:26:BD:55:F0
            X509v3 Authority Key Identifier: 
                keyid:3F:8C:95:EE:E9:3A:B1:84:FC:0D:BA:1B:F1:A8:AA:FD:B1:C4:C0:E2

            X509v3 Subject Alternative Name: 
                DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.default.svc.cluster.local, IP Address:127.0.0.1, IP Address:172.20.0.112, IP Address:172.20.0.113, IP Address:172.20.0.114, IP Address:172.20.0.115, IP Address:10.254.0.1
    Signature Algorithm: sha256WithRSAEncryption
         40:6e:12:57:13:87:17:47:6c:5a:6a:bb:9f:8c:06:04:2c:7e:
         71:5c:37:f7:6b:87:9c:23:ab:bf:54:df:53:be:f7:a1:3b:46:
         b2:87:77:0a:fd:99:ef:7d:44:33:75:b1:bf:fc:ca:1a:20:8a:
         c2:d7:e8:bc:e1:ea:7e:fe:7f:bb:58:68:03:a1:5d:9b:62:7e:
         9a:48:27:36:42:be:14:41:9f:1a:41:53:31:0f:cf:a7:a8:70:
         08:45:99:b9:09:82:fd:00:02:32:52:f5:62:c2:92:96:35:51:
         25:ca:cc:08:d5:c4:e8:d2:97:50:93:9a:48:5e:6b:f9:d8:91:
         58:4c:fb:24:56:aa:37:1b:78:94:ca:5f:a0:7c:84:91:99:a7:
         8e:e5:37:83:50:b8:31:23:2d:bb:74:48:57:aa:5c:b3:5f:37:
         15:b4:7d:5d:45:44:63:f5:c0:4b:83:a1:de:4b:a2:12:fe:2b:
         e1:5c:58:6a:a6:74:b9:72:b7:3e:ff:89:4d:7c:18:d1:b5:6d:
         ea:92:f3:67:53:ad:93:78:72:ab:9f:d8:89:e1:62:ce:d7:56:
         57:cc:0b:f6:12:11:ab:17:ff:2e:76:19:c4:fe:36:e0:fe:74:
         cc:f8:9f:ee:cd:27:00:21:fc:61:79:48:e5:27:74:bb:bd:e4:
         26:8c:8d:50
5.2 使用cfssl-certinfo命令
$ cfssl-certinfo -cert kubernetes.pem
{
  "subject": {
    "common_name": "kubernetes",
    "country": "CN",
    "organization": "k8s",
    "organizational_unit": "System",
    "locality": "BeiJing",
    "province": "BeiJing",
    "names": [
      "CN",
      "BeiJing",
      "BeiJing",
      "k8s",
      "System",
      "kubernetes"
    ]
  },
  "issuer": {
    "common_name": "kubernetes",
    "country": "CN",
    "organization": "k8s",
    "organizational_unit": "System",
    "locality": "BeiJing",
    "province": "BeiJing",
    "names": [
      "CN",
      "BeiJing",
      "BeiJing",
      "k8s",
      "System",
      "kubernetes"
    ]
  },
  "serial_number": "581408424675478050081912100441044253482994605963",
  "sans": [
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local",
    "127.0.0.1",
    "172.20.0.112",
    "172.20.0.113",
    "172.20.0.114",
    "172.20.0.115",
    "10.254.0.1"
  ],
  "not_before": "2021-08-03T02:31:00Z",
  "not_after": "2031-08-01T02:31:00Z",
  "sigalg": "SHA256WithRSA",
  "authority_key_id": "3F:8C:95:EE:E9:3A:B1:84:FC:D:BA:1B:F1:A8:AA:FD:B1:C4:C0:E2",
  "subject_key_id": "6F:FE:15:72:91:75:2F:F5:E5:50:A9:26:8F:76:C7:8F:26:BD:55:F0",
  "pem": "-----BEGIN CERTIFICATE-----\nMIIEizCCA3OgAwIBAgIUZddBZND3Yng62uMcciUWhLe7n4swDQYJKoZIhvcNAQEL\nBQAwZTELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDAOBgNVBAcTB0Jl\naUppbmcxDDAKBgNVBAoTA2s4czEPMA0GA1UECxMGU3lzdGVtMRMwEQYDVQQDEwpr\ndWJlcm5ldGVzMB4XDTIxMDgwMzAyMzEwMFoXDTMxMDgwMTAyMzEwMFowZTELMAkG\nA1UEBhMCQ04xEDAOBgNVBAgTB0JlaUppbmcxEDAOBgNVBAcTB0JlaUppbmcxDDAK\nBgNVBAoTA2s4czEPMA0GA1UECxMGU3lzdGVtMRMwEQYDVQQDEwprdWJlcm5ldGVz\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0tgsFZZtlwMcJhoXBjjV\nf+FPEjr2Ur1OrgoSeqzJiiM4K1w/RkeflRV6TWnzCod0XCgu5Wz+VXlR0Vqe7/2j\nZWfPZvP71kopmBGoiueajwW9TCPpUpNDWgn8OUis+QQVoZIer00mmXvX7jywcbyi\nldrUeNxEUq3zR6LSTVcl5VZZ7cXdLFvWZvF+C01hA2qLoN9UcfNIyFEC/EuiTXGM\nQa8Lt/NhCanESXzgaNam6uO9J5Uv96ZZVijqsOK4PjF0l+4ECHCuAE8hqTd33Pt2\nxnjF+qNGILT2X3nRFvxfZMdXaDRJO5lAkc4sLd7+/PqDXl5zbPFGao9k8bhvkhtm\niQIDAQABo4IBMTCCAS0wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF\nBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRv/hVykXUv9eVQ\nqSaPdsePJr1V8DAfBgNVHSMEGDAWgBQ/jJXu6TqxhPwNuhvxqKr9scTA4jCBrQYD\nVR0RBIGlMIGiggprdWJlcm5ldGVzghJrdWJlcm5ldGVzLmRlZmF1bHSCFmt1YmVy\nbmV0ZXMuZGVmYXVsdC5zdmOCHmt1YmVybmV0ZXMuZGVmYXVsdC5zdmMuY2x1c3Rl\ncoIka3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FshwR/AAABhwSs\nFABwhwSsFABxhwSsFAByhwSsFABzhwQK/gABMA0GCSqGSIb3DQEBCwUAA4IBAQBA\nbhJXE4cXR2xaarufjAYELH5xXDf3a4ecI6u/VN9TvvehO0ayh3cK/ZnvfUQzdbG/\n/MoaIIrC1+i84ep+/n+7WGgDoV2bYn6aSCc2Qr4UQZ8aQVMxD8+nqHAIRZm5CYL9\nAAIyUvViwpKWNVElyswI1cTo0pdQk5pIXmv52JFYTPskVqo3G3iUyl+gfISRmaeO\n5TeDULgxIy27dEhXqlyzXzcVtH1dRURj9cBLg6HeS6IS/ivhXFhqpnS5crc+/4lN\nfBjRtW3qkvNnU62TeHKrn9iJ4WLO11ZXzAv2EhGrF/8udhnE/jbg/nTM+J/uzScA\nIfxheUjlJ3S7veQmjI1Q\n-----END CERTIFICATE-----\n"
}

 

六 分发证书
将生成的证书和秘钥文件(后缀名为.pem)拷贝到所有机器的 /etc/kubernetes/ssl 目录下
for n in {cat host.txt}; do ssh root@$n ; mkdir -p /etc/kubernetes/ssl;exit;done 
for n in {cat hosts.txt}; do scp -r *.pem root@/etc/kubernetes/ssl/;done

 

 
本文有参考云原生社区文章
个人理解,如有错误麻烦指正^_^

k8s 证书创建

上一篇:FastDFS集群搭建


下一篇:《Java疯狂讲义》(第3版)学习笔记 2 - Java语言的运行机制