一 Kubernetes證書
1.1 TLS
Kubernetes系統的各個組件需要使用TLS證書對其通信加密以及授權認證,建議在部署之前先生成相關的TLS證書。
1.2 CA證書創建方式
kubernetes 系統各個組件需要使用TLS證書對通信進行加密,通常可通過以下工具生產自建證書:
- openssl
- cfssl
- easyrsa
1.3 Kubernetes組件證書
部署kubernetes組件建議使用TLS雙向認證的,相關組件涉及的主要證書有:
- etcd證書:etcd集群之間通信加密使用的TLS證書。
- kube-apiserver證書:配置kube-apiserver組件的證書。
- kube-controller-manager證書:用於和kube-apiserver通信認證的證書。
- kube-scheduler證書:用於和kube-apiserver通信認證的證書。
- kubelet證書【可選,非必需】:用於和kube-apiserver通信認證的證書,如果使用TLS Bootstarp認證方式,將沒有必要配置。
- kube-proxy證書【可選,非必需】:用於和kube-apiserver通信認證的證書,如果使用TLS Bootstarp認證方式,將沒有必要配置。
二 openssl生成證書
2.1 openssl創建證書
1 [root@master ~]# MASTER_IP=172.24.8.71 #定義MASTER_IP 2 [root@master ~]# mkdir cert #建議創建獨立存儲證書的目錄 3 [root@master ~]# cd cert 4 [root@master cert]# openssl genrsa -out ca.key 2048 #生成一個 2048 bit的ca.key 5 [root@master cert]# openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt #根據 ca.key 生成一個 ca.crt(使用 -days 設置證書的有效時間) 6 [root@master cert]# openssl genrsa -out server.key 2048 #生成一個 2048 bit 的 server.key 7 [root@master cert]# openssl req -new -key server.key -subj "/CN=${MASTER_IP}" -out server.csr #根據 server.key 生成一個 server.csr 8 [root@master cert]# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000 #根據 ca.key、ca.crt 和 server.csr 生成 server.crt 9 [root@master cert]# openssl x509 -noout -text -in ./server.crt
三 cfssl生成證書
3.1 cfssl創建證書
1 [root@master ~]# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl #下載cfssl軟件 2 [root@master ~]# chmod u+x /usr/local/bin/cfssl 3 [root@master ~]# curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson #下載json模板 4 [root@master ~]# chmod u+x /usr/local/bin/cfssljson 5 [root@master ~]# curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo 6 [root@master ~]# chmod u+x /usr/local/bin/cfssl-certinfo 7 [root@master ~]# mkdir cert 8 [root@master ~]# cd cert/ 9 [root@master cert]# cfssl print-defaults config > config.json 10 [root@master cert]# cfssl print-defaults csr > csr.json #創建模版配置json文件 11 [root@master cert]# cp config.json ca-config.json #復制一份作為CA的配置文件 12 [root@master cert]# vi ca-config.json 13 { 14 "signing": { 15 "default": { 16 "expiry": "168h" 17 }, 18 "profiles": { 19 "kubernetes": { 20 "expiry": "8760h", 21 "usages": [ 22 "signing", 23 "key encipherment", 24 "server auth" 25 "client auth" 26 ] 27 } 28 } 29 } 30 }
字段解釋:
config.json:可以定義多個profiles,分別指定不同的過期時間、使用場景等參數;后續在簽名證書時使用某個profile;
- signing: 表示該證書可用於簽名其它證書;生成的ca.pem 證書中CA=TRUE;
- server auth: 表示client 可以用該CA 對server 提供的證書進行校驗;
- client auth: 表示server 可以用該CA 對client 提供的證書進行驗證。
1 [root@master cert]# cp csr.json ca-csr.json #復制一份作為CA的配置文件 2 [root@master cert]# vi ca-csr.json 3 { 4 "CN": "kubernetes", 5 "key": { 6 "algo": "rsa", 7 "size": 2048 8 }, 9 "names": [ 10 { 11 "C": "CN", 12 "ST": "Shanghai", 13 "L": "Shanghai", 14 "O": "k8s", 15 "OU": "System" 16 } 17 ] 18 }
字段解釋:
- CN: Common Name,kube-apiserver 從證書中提取該字段作為請求的用戶名(User Name);瀏覽器使用該字段驗證網站是否合法;
- C:country;
- ST:state;
- L:city;
- O: Organization,kube-apiserver 從證書中提取該字段作為請求用戶所屬的組(Group);
- OU:organization unit。
1 [root@master cert]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca #生成CA密鑰(ca-key.pem)和證書(ca.pem)
提示:生成證書后,Kubernetes集群需要雙向TLS認證,則可將ca-key.pem和ca.pem拷貝到所有要部署的機器的/etc/kubernetes/ssl目錄下。
四 easyrsa生成證書
4.1 easyrsa創建證書
1 [root@master ~]# mkdir cert 2 [root@master ~]# curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz #下載easyrsa軟件 3 [root@master ~]# tar xzf easy-rsa.tar.gz 4 [root@master ~]# cd easy-rsa-master/easyrsa3 5 [root@master easyrsa3]# ./easyrsa init-pki 6 [root@master easyrsa3]# MASTER_IP=172.24.8.71 #定義MASTER_IP 7 [root@master easyrsa3]# ./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass #生成 CA
解釋:
--batch:設置為自動模式;
--req-cn:設置默認的 CN
1 [root@master easyrsa3]# ./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full server nopass #生成服務器證書和密鑰
解釋:
build-server-full [文件名]:生成一個鍵值對,在本地為客戶端和服務器簽名。
1 [root@master easyrsa3]# cp pki/ca.crt pki/issued/server.crt pki/private/server.key /root/cert/ #復制相關證書
提示:生成證書后,Kubernetes集群可通過如下配置使用證書:
-
--client-ca-file=/root/cert/ca.crt
- --tls-cert-file=/root/cert/server.crt
- --tls-private-key-file=/root/cert/server.key
五 相關證書及配置項
5.1 API Server 證書
API Server 證書配置為如下兩個選項:
- --tls-cert-file string
File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert). If HTTPS serving is enabled, and --tls-cert-file and --tls-private-key-file are not provided, a self-signed certificate and key are generated for the public address and saved to the directory specified by --cert-dir.
- --tls-private-key-file string
File containing the default x509 private key matching --tls-cert-file.
5.2 Client CA 證書
- --client-ca-file string
If set, any request presenting a client certificate signed by one of the authorities in the client-ca-file is authenticated with an identity corresponding to the CommonName of the client certificate.
該配置明確了 Clent 連接 API Server 時,API Server 應當確保其證書源自哪個 CA 簽發;如果其證書不是由該 CA 簽發,則拒絕請求;事實上,這個 CA 不必與 HTTPS 端點所使用的證書 CA 相同;同時這里的 Client 是一個泛指的,可以是 kubectl,也可能是你自己開發的應用
5.3 請求頭證書
API Server 支持多種認證方式的,其中一種就是使用 HTTP 頭中的指定字段來進行認證,相關配置如下:
- --requestheader-allowed-names stringSlice
List of client certificate common names to allow to provide usernames in headers specified by --requestheader-username-headers. If empty, any client certificate validated by the authorities in --requestheader-client-ca-file is allowed.
- --requestheader-client-ca-file string
Root certificate bundle to use to verify client certificates on incoming requests before trusting usernames in headers specified by --requestheader-username-headers. WARNING: generally do not depend on authorization being already done for incoming requests.
5.4 kubelet證書
對於 Kubelet 組件,API Server 單獨提供了證書配置選項,從而指定 API Server 與 Kubelet 通訊所使用的證書以及其簽署的 CA。同時這個 CA 可以完全獨立與上述其他CA。同時 Kubelet 組件也提供了反向設置的相關選項:
# API Server
- --kubelet-certificate-authority string
Path to a cert file for the certificate authority.
- --kubelet-client-certificate string
Path to a client cert file for TLS.
- --kubelet-client-key string
Path to a client key file for TLS.
# Kubelet
- --client-ca-file string
If set, any request presenting a client certificate signed by one of the authorities in the client-ca-file is authenticated with an identity corresponding to the CommonName of the client certificate.
- --tls-cert-file string
File containing x509 Certificate used for serving HTTPS (with intermediate certs, if any, concatenated after server cert). If --tls-cert-file and --tls-private-key-file are not provided, a self-signed certificate and key are generated for the public address and saved to the directory passed to --cert-dir.
- --tls-private-key-file string
File containing x509 private key matching --tls-cert-file.
5.5 Service Account 證書
在 API Server 配置中,對於 Service Account 同樣有兩個證書配置:
- --service-account-key-file stringArray
File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify ServiceAccount tokens. The specified file can contain multiple keys, and the flag can be specified multiple times with different files. If unspecified, --tls-private-key-file is used. Must be specified when --service-account-signing-key is provided
- --service-account-signing-key-file string
Path to the file that contains the current private key of the service account token issuer. The issuer will sign issued ID tokens with this private key. (Requires the 'TokenRequest' feature gate.)
這兩個配置描述了對 Service Account 進行簽名驗證時所使用的證書;不過需要注意的是這里並沒有明確要求證書 CA,所以這兩個證書的 CA 理論上也是可以完全獨立的。
Kubernetes相關證書及配置項參考:
https://mritd.me/2018/08/26/kubernetes-certificate-configuration/
提示:以上證書創建示例參考:https://notes.doublemine.me/2018-03-26-Kubernetes%E9%9B%86%E7%BE%A4%E4%B9%8B%E8%B7%AF%E4%B9%8BTLS%E8%AF%81%E4%B9%A6%E9%85%8D%E7%BD%AE.html