k8s學習筆記-證書詳解


在進行二進制搭建K8S集群前,我們需要梳理最磨人的一個點,就是各種各樣的證書。

官方文檔參考https://kubernetes.io/docs/setup/certificates/

一共有多少證書:

先從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證書

加起來共8套,但是這里的“套”的含義我們需要理解。

同一個套內的證書必須是用同一個CA簽署的,簽署不同套里的證書的CA可以相同,也可以不同。例如,所有etcd server證書需要是同一個CA簽署的,所有的etcd peer證書也需要是同一個CA簽署的,而一個etcd server證書和一個etcd peer證書,完全可以是兩個CA機構簽署的,彼此沒有任何關系。這算兩套證書。

為什么同一個“套”內的證書必須是同一個CA簽署的

原因在驗證這些證書的一端。因為在要驗證這些證書的一端,通常只能指定一個Root CA。這樣一來,被驗證的證書自然都需要是被這同一個Root CA對應的私鑰簽署,不然不能通過認證。

其實實際上,使用一套證書(都使用一套CA來簽署)一樣可以搭建出K8S,一樣可以上生產,但是理清這些證書的關系,在遇到因為證書錯誤,請求被拒絕的現象的時候,不至於無從下手,而且如果沒有搞清證書之間的關系,在維護或者解決問題的時候,貿然更換了證書,弄不好會把整個系統搞癱。

TLS bootstrapping 簡化kubelet證書制作

Kubernetes1.4版本引入了一組簽署證書用的API。這組API的引入,使我們可以不用提前准備kubelet用到的證書。

官網地址:https://kubernetes.io/docs/tasks/tls/certificate-rotation/

每個kubelet用到的證書都是獨一無二的,因為它要綁定各自的IP地址,於是需要給每個kubelet單獨制作證書,如果業務量很大的情況下,node節點會很多,這樣一來kubelet的數量也隨之增加,而且還會經常變動(增減Node)kubelet的證書制作就成為一件很麻煩的事情。使用TLS bootstrapping就可以省事兒很多。

工作原理:Kubelet第一次啟動的時候,先用同一個bootstrap token作為憑證。這個token已經被提前設置為隸屬於用戶組system:bootstrappers,並且這個用戶組的權限也被限定為只能用來申請證書。 用這個bootstrap token通過認證后,kubelet申請到屬於自己的兩套證書(kubelet server、kube-apiserver client for kubelet),申請成功后,再用屬於自己的證書做認證,從而擁有了kubelet應有的權限。這樣一來,就去掉了手動為每個kubelet准備證書的過程,並且kubelet的證書還可以自動輪替更新

參考文檔:

https://mritd.me/2018/01/07/kubernetes-tls-bootstrapping-note/

https://www.jianshu.com/p/bb973ab1029b

kubelet證書為何不同

這樣做是一個為了審計,另一個為了安全。 每個kubelet既是服務端(kube-apiserver需要訪問kubelet),也是客戶端(kubelet需要訪問kube-apiserver),所以要有服務端和客戶端兩組證書。

服務端證書需要與服務器地址綁定,每個kubelet的地址都不相同,即使綁定域名也是綁定不同的域名,故服務端地址不同

客戶端證書也不應相同,每個kubelet的認證證書與所在機器的IP綁定后,可以防止一個kubelet的認證證書泄露以后,使從另外的機器上偽造的請求通過驗證。

安全方面,如果每個node上保留了用於簽署證書的bootstrap token,那么bootstrap token泄漏以后,是不是可以隨意簽署證書了?安全隱患非常大。所以,kubelet啟動成功以后,本地的bootstrap token需要被刪除。

正式制作證書

雖然可以用多套證書,但是維護多套CA實在過於繁雜,這里還是用一個CA簽署所有證書。

需要准備的證書:

  • admin.pem
  • ca.-key.pem
  • ca.pem
  • admin-key.pem
  • admin.pem
  • kube-scheduler-key.pem
  • kube-scheduler.pem
  • kube-controller-manager-key.pem
  • kube-controller-manager.pem
  • kube-proxy-key.pem

  • kube-proxy.pem

  • kubernetes-key.pem

  • kubernetes.pem

使用證書的組件如下:

  • etcd:使用 ca.pem kubernetes-key.pem kubernetes.pem 

  • kube-apiserver:使用 ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem

  • kubelet:使用 ca.pem

  • kube-proxy:使用 ca.pem kube-proxy-key.pem kube-proxy.pem

  • kubectl:使用 ca.pem admin-key.pem、admin.pem

  • kube-controller-manager:使用 ca-key.pem ca.pem kube-controller-manager-key.pem kube-controller-manager.pem

  • kube-scheduler: 使用 kube-scheduler-key.pem kube-scheduler.pem

我們使用CFSSL來制作證書,它是cloudflare開發的一個開源的PKI工具,是一個完備的CA服務系統,可以簽署、撤銷證書等,覆蓋了一個證書的整個生命周期,后面只用到了它的命令行工具。

注:一般情況下,K8S中證書只需要創建一次,以后在向集群中添加新節點時只要將/etc/kubernetes/ssl目錄下的證書拷貝到新節點上即可。

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

創建CA證書

創建證書配置文件
vim ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}

字段說明:

ca-config.json:可以定義多個 profiles,分別指定不同的過期時間、使用場景等參數;后續在簽名證書時使用某個 profile;

signing:表示該證書可以簽名其他證書;生成的ca.pem證書中 CA=TRUE;

server auth:表示client可以用該 CA 對server提供的證書進行驗證;

client auth:表示server可以用該CA對client提供的證書進行驗證

expiry:過期時間

創建CA證書簽名請求文件

vim ca-csr.json

 

{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ],
    "ca": {
       "expiry": "87600h"
    }
}

字段說明:

“CN”:Common Name,kube-apiserver 從證書中提取該字段作為請求的用戶名 (User Name);瀏覽器使用該字段驗證網站是否合法;

“O”:Organization,kube-apiserver 從證書中提取該字段作為請求用戶所屬的組 (Group)

生成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。

創建kubernetes證書

在創建這個證書之前,先規划一下架構

k8s-master1  10.211.55.11

k8s-master2  10.211.55.12

k8s-master3  10.211.55.13

etcd01          10.211.55.11

etcd02          10.211.55.12

etcd03          10.211.55.13

VIP               10.211.55.8  

創建kubernetes證書簽名請求文件 

 

vim kubernetes-csr.json
{
    "CN": "kubernetes",
    "hosts": [
      "127.0.0.1",
      "10.211.55.11",
      "10.211.55.12",
      "10.211.55.13",
      "10.211.55.8",
      "10.0.0.1",
      "k8s-master1",
      "k8s-master2",
      "k8s-master3",
      "etcd01",

      "etcd02",

      "etcd03",
      "kubernetes",
      "kube-api.wangdong.com",
      "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"
        }
    ]
}

字段說明:

如果 hosts 字段不為空則需要指定授權使用該證書的 IP 或域名列表。

由於該證書后續被 etcd 集群和 kubernetes master 集群使用,將etcd、master節點的IP都填上,同時還有service網絡的首IP。(一般是 kube-apiserver 指定的 service-cluster-ip-range 網段的第一個IP,如 10.0.0.1)

三個etcd,三個master,以上物理節點的IP也可以更換為主機名。

生成kubernetes證書和私鑰

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

創建admin證書

創建admin證書簽名請求文件

 vim admin-csr.json
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}

說明:

后續 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

相關權限認證可以參考下面文章

https://mp.weixin.qq.com/s/XIkQdh5gnr-KJhuFHboNag

生成admin證書和私鑰

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

創建kube-proxy證書

創建 kube-proxy 證書簽名請求文件 

vim kube-proxy-csr.json
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}

說明:

 

CN 指定該證書的 User 為 system:kube-proxy;

kube-apiserver 預定義的 RoleBinding system:node-proxier 將User system:kube-proxy 與 Role system:node-proxier 綁定,該 Role 授予了調用 kube-apiserver Proxy 相關 API 的權限;

該證書只會被 kubectl 當做 client 證書使用,所以 hosts 字段為空 
生成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
ls |grep kube-proxy
kube-proxy.csr
kube-proxy-csr.json
kube-proxy-key.pem
kube-proxy.pem

創建kube-controoler-manager證書

創建 kube-controoler-manager 證書簽名請求文件  

vim kube-controller-manager-csr.json

 

{
    "CN": "system:kube-controller-manager",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "hosts": [
      "127.0.0.1",
      "10.211.55.11",
      "10.211.55.12",
      "10.211.55.13",
  "k8s-master1",
  "k8s-master2",
  "k8s-master3"
    ],
    "names": [
      {
        "C": "CN",
        "ST": "BeiJing",
        "L": "BeiJing",
        "O": "system:kube-controller-manager",
        "OU": "system"
      }
    ]
} 

說明:

hosts 列表包含所有 kube-controller-manager 節點 IP;
CN 為 system:kube-controller-manager、O 為 system:kube-controller-manager,kubernetes 內置的 ClusterRoleBindings system:kube-controller-manager 賦予 kube-controller-manager 工作所需的權限

生成kube-controoller-manager證書和私鑰

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 

創建kube-scheduler證書 

 創建 kube-scheduler 證書簽名請求文件

vim kube-scheduler-csr.json 
{
    "CN": "system:kube-scheduler",
    "hosts": [
      "127.0.0.1",
      "10.211.55.11",
      "10.211.55.12",
      "10.211.55.13",
  "k8s-master1",
  "k8s-master2",
  "k8s-master3",
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
      {
        "C": "CN",
        "ST": "BeiJing",
        "L": "BeiJing",
        "O": "system:kube-scheduler",
        "OU": "4Paradigm"
      }
    ]
}

說明:

hosts 列表包含所有 kube-scheduler 節點 IP;

CN 為 system:kube-scheduler、O 為 system:kube-scheduler,kubernetes 內置的 ClusterRoleBindings system:kube-scheduler 將賦予 kube-scheduler 工作所需的權限。

經過上述操作,我們會用到如下文件

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json| cfssljson -bare kube-scheduler
ls | grep pem
admin-key.pem
admin.pem
ca-key.pem
ca.pem
kube-proxy-key.pem
kube-proxy.pem
kubernetes-key.pem
kubernetes.pem
kube-controller-manager-key.pem
kube-controller-manager.pem
kube-scheduler-key.pem
kube-scheduler.pem

查看證書信息: 

cfssl-certinfo -cert kubernetes.pem

在搭建k8s集群的時候,將這些文件分發到至此集群中其他節點機器中即可。至此,TLS證書創建完畢

證書這塊知道怎么生成、怎么用即可,建議暫時不必過多研究


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM