配置 CA 并创建 TLS 证书

我们将使用 CloudFlare’s PKI 工具 cfssl 来配置 PKI Infrastructure,然后使用它去创建 Certificate Authority(CA), 并为 etcd、kube-apiserver、kubelet 以及 kube-proxy 创建 TLS 证书。

Certificate Authority

本节创建用于生成其他 TLS 证书的 Certificate Authority。

新建 CA 配置文件

  1. cat > ca-config.json <<EOF
  2. {
  3. "signing": {
  4. "default": {
  5. "expiry": "8760h"
  6. },
  7. "profiles": {
  8. "kubernetes": {
  9. "usages": ["signing", "key encipherment", "server auth", "client auth"],
  10. "expiry": "8760h"
  11. }
  12. }
  13. }
  14. }
  15. EOF

新建 CA 凭证签发请求文件:

  1. cat > ca-csr.json <<EOF
  2. {
  3. "CN": "Kubernetes",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "Kubernetes",
  13. "OU": "CA",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF

生成 CA 凭证和私钥:

  1. cfssl gencert -initca ca-csr.json | cfssljson -bare ca

结果将生成以下两个文件:

  1. ca-key.pem
  2. ca.pem

client 与 server 凭证

本节将创建用于 Kubernetes 组件的 client 与 server 凭证,以及一个用于 Kubernetes admin 用户的 client 凭证。

Admin 客户端凭证

创建 admin client 凭证签发请求文件:

  1. cat > admin-csr.json <<EOF
  2. {
  3. "CN": "admin",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "system:masters",
  13. "OU": "Kubernetes The Hard Way",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF

创建 admin client 凭证和私钥:

  1. cfssl gencert \
  2. -ca=ca.pem \
  3. -ca-key=ca-key.pem \
  4. -config=ca-config.json \
  5. -profile=kubernetes \
  6. admin-csr.json | cfssljson -bare admin

结果将生成以下两个文件

  1. admin-key.pem
  2. admin.pem

Kubelet 客户端凭证

Kubernetes 使用 special-purpose authorization mode(被称作 Node Authorizer)授权来自 Kubelet 的 API 请求。为了通过 Node Authorizer 的授权, Kubelet 必须使用一个署名为 system:node:<nodeName> 的凭证来证明它属于 system:nodes 用户组。本节将会给每台 worker 节点创建符合 Node Authorizer 要求的凭证。

给每台 worker 节点创建凭证和私钥:

  1. for instance in worker-0 worker-1 worker-2; do
  2. cat > ${instance}-csr.json <<EOF
  3. {
  4. "CN": "system:node:${instance}",
  5. "key": {
  6. "algo": "rsa",
  7. "size": 2048
  8. },
  9. "names": [
  10. {
  11. "C": "US",
  12. "L": "Portland",
  13. "O": "system:nodes",
  14. "OU": "Kubernetes The Hard Way",
  15. "ST": "Oregon"
  16. }
  17. ]
  18. }
  19. EOF
  20. EXTERNAL_IP=$(gcloud compute instances describe ${instance} \
  21. --format 'value(networkInterfaces[0].accessConfigs[0].natIP)')
  22. INTERNAL_IP=$(gcloud compute instances describe ${instance} \
  23. --format 'value(networkInterfaces[0].networkIP)')
  24. cfssl gencert \
  25. -ca=ca.pem \
  26. -ca-key=ca-key.pem \
  27. -config=ca-config.json \
  28. -hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \
  29. -profile=kubernetes \
  30. ${instance}-csr.json | cfssljson -bare ${instance}
  31. done

结果将产生以下几个文件:

  1. worker-0-key.pem
  2. worker-0.pem
  3. worker-1-key.pem
  4. worker-1.pem
  5. worker-2-key.pem
  6. worker-2.pem

Kube-controller-manager 客户端凭证

  1. cat > kube-controller-manager-csr.json <<EOF
  2. {
  3. "CN": "system:kube-controller-manager",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "system:kube-controller-manager",
  13. "OU": "Kubernetes The Hard Way",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF
  19. cfssl gencert \
  20. -ca=ca.pem \
  21. -ca-key=ca-key.pem \
  22. -config=ca-config.json \
  23. -profile=kubernetes \
  24. kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

结果将产生以下几个文件:

  1. kube-controller-manager-key.pem
  2. kube-controller-manager.pem

Kube-proxy 客户端凭证

  1. cat > kube-proxy-csr.json <<EOF
  2. {
  3. "CN": "system:kube-proxy",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "system:node-proxier",
  13. "OU": "Kubernetes The Hard Way",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF
  19. cfssl gencert \
  20. -ca=ca.pem \
  21. -ca-key=ca-key.pem \
  22. -config=ca-config.json \
  23. -profile=kubernetes \
  24. kube-proxy-csr.json | cfssljson -bare kube-proxy

结果将产生以下两个文件:

  1. kube-proxy-key.pem
  2. kube-proxy.pem

kube-scheduler 证书

  1. cat > kube-scheduler-csr.json <<EOF
  2. {
  3. "CN": "system:kube-scheduler",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "system:kube-scheduler",
  13. "OU": "Kubernetes The Hard Way",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF
  19. cfssl gencert \
  20. -ca=ca.pem \
  21. -ca-key=ca-key.pem \
  22. -config=ca-config.json \
  23. -profile=kubernetes \
  24. kube-scheduler-csr.json | cfssljson -bare kube-scheduler

结果将产生以下两个文件:

  1. kube-scheduler-key.pem
  2. kube-scheduler.pem

Kubernetes API Server 证书

为了保证客户端与 Kubernetes API 的认证,Kubernetes API Server 凭证 中必需包含 kubernetes-the-hard-way 的静态 IP 地址。

首先查询 kubernetes-the-hard-way 的静态 IP 地址:

  1. KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \
  2. --region $(gcloud config get-value compute/region) \
  3. --format 'value(address)')

创建 Kubernetes API Server 凭证签发请求文件:

  1. cat > kubernetes-csr.json <<EOF
  2. {
  3. "CN": "kubernetes",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "Kubernetes",
  13. "OU": "Kubernetes The Hard Way",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF

创建 Kubernetes API Server 凭证与私钥:

  1. cfssl gencert \
  2. -ca=ca.pem \
  3. -ca-key=ca-key.pem \
  4. -config=ca-config.json \
  5. -hostname=10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,kubernetes.default \
  6. -profile=kubernetes \
  7. kubernetes-csr.json | cfssljson -bare kubernetes

结果产生以下两个文件:

  1. kubernetes-key.pem
  2. kubernetes.pem

Service Account 证书

  1. cat > service-account-csr.json <<EOF
  2. {
  3. "CN": "service-accounts",
  4. "key": {
  5. "algo": "rsa",
  6. "size": 2048
  7. },
  8. "names": [
  9. {
  10. "C": "US",
  11. "L": "Portland",
  12. "O": "Kubernetes",
  13. "OU": "Kubernetes The Hard Way",
  14. "ST": "Oregon"
  15. }
  16. ]
  17. }
  18. EOF
  19. cfssl gencert \
  20. -ca=ca.pem \
  21. -ca-key=ca-key.pem \
  22. -config=ca-config.json \
  23. -profile=kubernetes \
  24. service-account-csr.json | cfssljson -bare service-account

结果将生成以下两个文件

  1. service-account-key.pem
  2. service-account.pem

分发客户端和服务器证书

将客户端凭证以及私钥复制到每个工作节点上:

  1. for instance in worker-0 worker-1 worker-2; do
  2. gcloud compute scp ca.pem ${instance}-key.pem ${instance}.pem ${instance}:~/
  3. done

将服务器凭证以及私钥复制到每个控制节点上:

  1. for instance in controller-0 controller-1 controller-2; do
  2. gcloud compute scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
  3. service-account-key.pem service-account.pem ${instance}:~/
  4. done

kube-proxykube-controller-managerkube-schedulerkubelet 客户端凭证将会在下一节中用来创建客户端签发请求文件。

下一步:配置和生成 Kubernetes 配置文件