在實際kubernetes應用場景中,集羣內組件之間訪問都是經過TLS雙向認證安全訪問,即https訪問,因此在部署時,給kubernetes各個組件建立證書是必要的,這是由於沒有https安全訪問會致使集羣間節點通訊訪問不安全,非法用戶能夠經過客戶端操做,對集羣資源非法操做,引發集羣服務異常,甚至集羣宕機。例如:非法操做etcd存儲的數據,所以集羣開啓https訪問雙向認證是必要的。node
# 證書及密鑰存放路徑 SSL_BIN_PATH=/usr/local/cfssl CA_DIR=/etc/k8s/ssl # 外網和內網apiserver vip訪問地址 VIP_KUBEAPI_OUTSIDE=192.168.20.100 VIP_KUBEAPI_INSIDE=10.10.10.100 # master集羣各節點組件監聽地址 MASTER1_IP=10.10.10.22 MASTER2_IP=10.10.10.23 MASTER3_IP=10.10.10.24 # etcd集羣內各節點監聽地址 ETCD1_IP=10.10.10.22 ETCD2_IP=10.10.10.23 ETCD3_IP=10.10.10.24 # kubernetes默認service發地址 CLUSTER_KUBERNETES_SVC_IP=10.254.0.1 證書認證域名 DOMAIN=mo9.com
kube-apiserver組件: 使用 ca.pem、kubernetes.pem、kubernetes-key.pem、etcd公私鑰證書、 metric公私鑰等證書; kube-controller-manager組件 使用 ca-key.pem, ca.pem, kuber-controller-manager公私鑰等證書; kube-scheduler組件: 使用ca.pem、kube-scheduler.pem、kube-scheduler-key.pem等證書; kube-proxy組件: 使用 ca.pem、kube-proxy-key.pem、kube-proxy.pem等證書; kubelet組件: 使用 ca.pem等證書; kubectl組件: 使用 ca.pem、admin-key.pem、admin.pem等證書; etcd組件: 使用 ca.pem、etcd-key.pem、etcd.pem等證書; flannel組件: 使用ca.pem、flannel.pem、flannel-key.pem等證書;
本安裝文檔爲全部的組件生成證書文件,實際狀況下也能夠選擇部分組件共用某個證書或不選擇開啓https訪問。如:etcd、flannel共用apiserver組件證書或不啓用https訪問,controller-manager,scheduler也能夠基於http訪問;linux
mkdir -p $SSL_BIN_PATH mkdir -p $CA_DIR
大多數狀況下,kubernetes集羣都是創建在本身的私有網絡裏,好比公有云vpc區域,自建數據中心等等,因爲k8s全部相關組件都是須要TLS雙向認證,合法證書機構大多都是提供ssl單向認證證書,因此必須自建CA根證書,並生成相應的公鑰和私鑰根證書,能夠經過openssl或cfssl建立CA證書,這裏以cfssl爲例:shell
mkdir -p $SSL_BIN_PATH/bin > /dev/null 2>&1 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -P $SS_BINL_PATH/bin/ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -P $SSL_BIN__PATH/bin/ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -P $SSL_BIN_PATH/bin/ cd $SSL_BIN_PATH/bin/ mv cfssl_linux-amd64 cfssl && mv cfssljson_linux-amd64 cfssljson mv cfssl-certinfo_linux-amd64 cfssl-certinfo chmod +x * && ln -sf $SSL_BIN_PATH/bin/cfssl* /usr/local/bin/
CA 證書是集羣全部節點共享的,只須要建立一個 CA 證書,後續建立的全部證書都由它簽名。json
CA 配置文件用於配置根證書的使用場景 (profile) 和具體參數 (usage,過時時間、服務端認證、客戶端認證、加密等),後續在簽名其它證書時須要指定特定場景。api
cat >$CA_DIR/ca-config.json<<EOF { "signing": { "default": { "expiry": "175200h" }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "175200h" } } } } EOF
cat >$CA_DIR/ca-csr.json<<EOF { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "ShangHai", "O": "k8s", "OU": "System" } ] } EOF
cd $CA_DIR cfssl gencert --initca=true ca-csr.json | cfssljson --bare ca
cat >$CA_DIR/kubernetes-csr.json << EOF { "CN": "kubernetes", "hosts": [ "127.0.0.1", "${MASTER1_IP}", "${MASTER2_IP}", "${MASTER3_IP}", "${VIP_KUBEAPI_INSIDE}", "${VIP_KUBEAPI_OUTSIDE}", "${CLUSTER_KUBERNETES_SVC_IP}", "*.${DOMAIN}", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "SahgnHai", "O": "k8s", "OU": "System" } ] } EOF
$ kubectl get svc kubernetes NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.254.0.1 <none> 443/TCP 1d
cd $CA_DIR cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ kubernetes-csr.json | cfssljson -bare kubernetes
cat > $CA_DIR/kube-controller-manager-csr.json <<EOF { "CN": "system:kube-controller-manager", "key": { "algo": "rsa", "size": 2048 }, "hosts": [ "127.0.0.1", "${MASTER1_IP}", "${MASTER2_IP}", "${MASTER3_IP}" ], "names": [ { "C": "CN", "ST": "ShangHai", "L": "ShangHai", "O": "system:kube-controller-manager", "OU": "System" } ] } EOF
cd $CA_DIR cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
cat > $CA_DIR/kube-scheduler-csr.json <<EOF { "CN": "system:kube-scheduler", "hosts": [ "127.0.0.1", "${MASTER1_IP}", "${MASTER2_IP}", "${MASTER3_IP}" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "ShangHai", "O": "system:kube-scheduler", "OU": "System" } ] } EOF
cd $CA_DIR cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ kube-scheduler-csr.json | cfssljson -bare kube-scheduler
cat > $CA_DIR/kube-proxy-csr.json << EOF { "CN": "system:kube-proxy", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "SahgnHai", "O": "k8s", "OU": "System" } ] } EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ kube-proxy-csr.json | cfssljson -bare kube-proxy
cat > $CA_DIR/admin-csr.json << EOF { "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "SahgnHai", "O": "system:masters", "OU": "System" } ] } EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ admin-csr.json | cfssljson -bare admin
cat > $CA_DIR/etcd-csr.json << EOF { "CN": "etcd", "hosts": [ "127.0.0.1", "${ETCD1_IP}", "${ETCD2_IP}", "${ETCD3_IP}" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "SahgnHai", "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
cat > $CA_DIR/flannel-csr.json << EOF { "CN": "flanneld", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "ShangHai", "O": "k8s", "OU": "System" } ] } EOF
cd $CA_DIR cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ flannel-csr.json | cfssljson -bare flannel
cat > $CA_DIR/proxy-client-csr.json <<EOF { "CN": "aggregator", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "ShangHai", "L": "ShangHai", "O": "k8s", "OU": "System" } ] } EOF
cd $CA_DIR cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes \ proxy-client-csr.json | cfssljson -bare proxy-client
cd $CA_DIR rm -rf *csr* && rm -rf *json chmod 666 *
ansible master_k8s_vgs -m \ synchronize -a "src=${CA_DIR} dest=${CA_DIR}/ mode=push delete=yes rsync_opts=-avz'" -b ansible master_k8s_vgs -m shell -a "chmod 666 ${CA_DIR}/*" -b ansible master_k8s_vgs -m shell -a "cd ${CA_DIR} && rm -rf kube-proxy*" -b
ansible worker_k8s_vgs -m copy -a "src=${CA_DIR}/ca.pem dest=${CA_DIR}/" -b ansible worker_k8s_vgs -m copy -a "src=${CA_DIR}/flannel.pem dest=${CA_DIR}/" -b ansible worker_k8s_vgs -m copy -a "src=${CA_DIR}/flannel-key.pem dest=${CA_DIR}/" -b
備註:瀏覽器
證書建立內容基本完成,關於tls證書雙向認證請自行查閱文檔,建立完成證書後,還須要建立各組件認證文件,請參閱下一節:kubernetes集羣安裝指南:客戶端安裝及各組件認證文件建立安全