建K8S集群kubeadm會生成很多證書
[root@master /etc/kubernetes/pki]# tree . ├── apiserver.crt #apiserver 證書 ├── apiserver-etcd-client.crt #apiserver訪問etcd的證書 ├── apiserver-etcd-client.key #apiserver訪問etcd的證書 ├── apiserver.key #apiserver 證書 ├── apiserver-kubelet-client.crt #kubelet證書 ├── apiserver-kubelet-client.key #kubelet證書 ├── ca.crt #根證書 ├── ca.key #根證書 ├── etcd │ ├── ca.crt #etcd根證書 │ ├── ca.key #etcd根證書 │ ├── healthcheck-client.crt #pod中liveness探針客戶端證書 │ ├── healthcheck-client.key #pod中liveness探針客戶端證書 │ ├── peer.crt #etcd節點互通證書,由根證書簽發 │ ├── peer.key #etcd節點互通證書,由根證書簽發 │ ├── server.crt │ └── server.key ├── front-proxy-ca.crt #代理根證書 ├── front-proxy-ca.key #代理根證書
├── front-proxy-client.crt #由代理根證書簽發的客戶端證書
├── front-proxy-client.key #由代理根證書簽發的客戶端證書
├── sa.key
└── sa.pub
1 directory, 22 files
k8s集群一共有多少證書: 先從Etcd算起: 1、Etcd對外提供服務,要有一套etcd server證書 2、Etcd各節點之間進行通信,要有一套etcd peer證書 3、Kube-APIserver訪問Etcd,要有一套etcd client證書 再算kubernetes: 4、Kube-APIserver對外提供服務,要有一套kube-apiserver server證書 5、kube-scheduler、kube-controller-manager、kube-proxy、kubelet和其他可能用到的組件, 需要訪問kube-APIserver,要有一套kube-APIserver client證書 6、kube-controller-manager要生成服務的service account,要有一對用來簽署service account的證書(CA證書) 7、kubelet對外提供服務,要有一套kubelet server證書 8、kube-APIserver需要訪問kubelet,要有一套kubelet client
kubelet要主動訪問kube-apiserver, kube-apiserver也需要主動向kubelet發起請求, 所以雙方都需要有自己的根證書以及使用該根證書簽發的服務
端證書和客戶端證書. 在kube-apiserver中, 一般明確指定用於https訪問的服務端證書和帶有CN用戶名信息的客戶端證書. 而在kubelet的啟動配置中,
一般只指定了ca根證書, 而沒有明確指定用於https訪問的服務端證書,在生成服務端證書時, 一般會指定服務端地址或主機名, kube-apiserver相對變
化不是很頻繁, 所以在創建集群之初就可以預先分配好用作 kube-apiserver的IP 或主機名/域名, 但是由於部署在node節點上的kubelet會因為集群規
模的變化而頻繁變化, 而無法預知node的所有IP信息, 所以kubelet上一般不會明確指定服務端證書, 而是只指定ca根證書, 讓kubelet根據本地主機信
息自動生成服務端證書並保存到配置的cert-dir文件夾中
深入了解證書先了解一下 公鑰,私鑰和數字簽名
總結:公鑰和私鑰是成對的,它們互相解密。
公鑰加密,私鑰解密。
私鑰數字簽名,公鑰驗證。
一、公鑰加密 假設一下,我找了兩個數字,一個是1,一個是2 我喜歡2這個數字,就保留起來, 不告訴你們(私鑰),然后我告訴大家,1是我的公鑰。 我有一個文件,不能讓別人看,我就用1加密了。別人找到了這個文件,但是他不知道2就是解密的私鑰啊, 所以他解不開,只有我可以用 數字2,就是我的私鑰,來解密。這樣我就可以保護數據了。 我的好朋友x用我的公鑰1加密了字符a,加密后成了b,放在網上。別人偷到了這個文件,但是別人解不開, 因為別人不知道2就是我的私鑰, 只有我才能解密,解密后就得到a。這樣,我們就可以傳送加密的數據了。 二、私鑰簽名 如果我用私鑰加密一段數據(當然只有我可以用私鑰加密,因為只有我知道2是我的私鑰), 結果所有的人都看到我的內容了,因為他們都知 道我的公鑰是1,那么這種加密有什么用處呢? 假如我的好朋友x說有人冒充我給他發信。怎么辦呢?我把我要發的信,內容是c,用我的私鑰2,加密, 加密后的內容是d,發給x,再告訴他 解密看是不是c。他用我的公鑰1解密,發現果然是c。 這個時候, 他會想到,能夠用我的公鑰解密的數據,必然是用我的私鑰加的密。只有我知道我的私鑰, 因此他就可以確認確實是我發的東西。 這樣我們就能確認發送方身份了。這個過程叫做數字簽名。 用私鑰來加密數據,用途就是數字簽名。

RSA算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。
根證書與證書
通常我們配置https服務時需要到"權威機構"(CA)申請證書。過程是這樣的: 1.網站創建一個密鑰對,提供公鑰和組織以及個人信息給權威機構 2.權威機構頒發證書 3.瀏覽網頁的朋友利用權威機構的根證書公鑰解密簽名,對比摘要,確定合法性 4.客戶端驗證域名信息有效時間等(瀏覽器基本都內置各大權威機構的CA公鑰) 這個證書包含如下內容: 1.申請者公鑰 2.申請者組織和個人信息 3.簽發機構CA信息,有效時間,序列號等 4.以上信息的簽名 根證書又名自簽名證書,也就是自己給自己頒發的證書。CA(Certificate Authority)被稱為證書授權中心, k8s中的ca證書就是根證書。 密鑰對:sa.key sa.pub 根證書:ca.crt etcd/ca.crt 私鑰:ca.key 等 其它證書 生成CA證書和私鑰 cfssl gencert -initca ca-csr.json | cfssljson -bare ca ls | grep ca ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem 其中ca-key.pem是ca的私鑰,ca.csr是一個簽署請求,ca.pem是CA證書,是后面kubernetes組件會用到的RootCA。 #Pod中的容器訪問API Server(如dashboard容器 訪問API Server) 因為Pod的創建、銷毀是動態的,所以要為它 手動生成證書就不可行了。K8s使用了Service Account解決Pod 訪問API Server的認證問題 默認情況下,每個 namespace 都會有一個 ServiceAccount,如果 Pod 在創建時沒有指定 ServiceAccount 就會使用 Pod 所屬的 namespace 的 ServiceAccount,默認值/run/secrets/kubernates.io/serviceaccount/ #test 隨便查看kube-system命名空間下的pod kubectl get pod -n kube-system kubectl exec kube-proxy-cmzp6 -n=kube-system -it -- /bin/sh #進入容器 cd /run/secrets/kubernates.io/serviceaccount/ ls #里面有ca.crt(根的證書) namespace token 3個文件 #token是使用 API Server 私鑰簽名的 JWT(json web token)。用於訪問API Server時,Server端認證 #ca.crt,根證書(是k8s中私有的)。用於Client端驗證API Server發送的證書 #namespace, 標識這個service-account-token的作用域名空間 service Account密鑰對 sa.key sa.pub 提供給 kube-controller-manager使用,kube-controller-manager通過 sa.key 對 token 進行簽名, master 節點通過公鑰 sa.pub 進行簽名的驗證 如 kube-proxy 是以 pod 形式運行的, 在 pod 中, 直接使用 service account 與 kube-apiserver 進行認證, 此時就不需要再單獨為 kube-proxy 創建證書了, 會直接使用token校驗。