dombri-dev.diary

ぺーぺークラウドインフラエンジニアの奮闘記。

Kubernetes the Hard Way on Azure : 4.CA, TLS

こんにちは。

引き続き、Kubernetes the Hard Way on Azure を進めていきます。

4. Provisioning a CA and Generating TLS Certificates

このラボではCloudFlare のPKIツールキットであるcfssl を使用して、PKIインフラストラクチャをプロビジョニングします。それを使用して認証局をブートストラップし、etcd  kube-apiserver kubelet kube-proxy のコンポーネントTLS証明書を生成します。

主にこの辺り。今までなかった概念なので急遽書き足しました。
f:id:dombri:20200209105537j:plain

Certificate Authority

追加のTLS証明書を生成するために使用する認証局をプロビジョニングします。

CA構成ファイルを作成します。

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": ["signing", "key encipherment", "server auth", "client auth"],
        "expiry": "8760h"
      }
    }
  }
}
EOF

CA証明書署名要求を作成します。

cat > ca-csr.json <<EOF
{
  "CN": "Kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "Kubernetes",
      "OU": "DON",
      "ST": "JAPAN"
    }
  ]
}
EOF

CA証明書と秘密鍵を作成します。

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

# 以下が出来上がります
ca-key.pem
ca.pem


Client and Server Certificates

Kubernetes コンポーネントのクライアント証明書とサーバ証明書、およびKubernetes管理ユーザのクライアント証明書を生成します。

The Admin Client Certificate

管理クライアント証明書署名要求を作成します。

cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "system:masters",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

管理クライアント証明書と秘密鍵を作成します。

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

# 以下が生成されます
admin-key.pem
admin.pem


The Kubelet Client Certificates

Kubernetesは Node Authorizer と呼ばれる特別な許可モードを使用します。これはKubelet によって行われたAPIリクエストを特別に許可します。 Node Authorizer によって承認されるには、Kubelet はユーザ名 system:node: でsystem:nodes グループに属している、と識別する資格情報を使用する必要があります。
Node Authorizer の要件を満たす Kubernetes ワーカーノードごとに証明書を作成します。

ワーカーノードごとに証明書と秘密鍵を生成します。

for instance in worker-0 worker-1; do
cat > ${instance}-csr.json <<EOF
{
  "CN": "system:node:${instance}",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "system:nodes",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

EXTERNAL_IP=$(az network public-ip show -g kubernetes \
  -n kubernetes-pip --query ipAddress -otsv)

INTERNAL_IP=$(az vm show -d -n ${instance} -g kubernetes --query privateIps -otsv)

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \
  -profile=kubernetes \
  ${instance}-csr.json | cfssljson -bare ${instance}
done

# 以下が生成されます
worker-0-key.pem
worker-0.pem
worker-1-key.pem
worker-1.pem

The Controller Manager Client Certificate

[kubernetes-controller-manager]のクライアント証明書と秘密鍵を生成します。

{

cat > kube-controller-manager-csr.json <<EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

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-controller-manager-key.pem
kube-controller-manager.pem


The Kube Proxy Client Certificate

[kube-proxy]用クライアント証明書署名要求を作成します。

cat > kube-proxy-csr.json <<EOF
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "system:node-proxier",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

[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

# 以下が生成されます
kube-proxy-key.pem
kube-proxy.pem


The Scheduler Client Certificate

[kube-scheduler] 用クライアント証明書と秘密鍵を生成します。

{

cat > kube-scheduler-csr.json <<EOF
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  kube-scheduler-csr.json | cfssljson -bare kube-scheduler

}

# 以下が生成されます
kube-scheduler-key.pem
kube-scheduler.pem


The Kubernetes API Server Certificate

[Kubernetes-the-hard-way] 静的IPアドレスは、Kubernetes APIサーバ証明書サブジェクト代替名リストに含まれます。
これにより、リモートクライアントが証明書を検証できるようになります。

[Kubernetes-the-hard-way] 静的IPアドレスを取得します。

KUBERNETES_PUBLIC_ADDRESS=$(az network public-ip show -g kubernetes \
  -n kubernetes-pip --query "ipAddress" -otsv)

API サーバ証明書署名リクエストを作成します。

cat > kubernetes-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

APIサーバ証明書秘密鍵を生成します。★ip多いかも

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -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 \
  -profile=kubernetes \
  kubernetes-csr.json | cfssljson -bare kubernetes

# 以下が生成されます
kubernetes-key.pem
kubernetes.pem


The Service Account Key Pair

Kubernetes Controller Manager は、キーペアを利用してサービスアカウントトークンを生成・署名します。

[service-account] 証明書と秘密鍵を生成します。

{

cat > service-account-csr.json <<EOF
{
  "CN": "service-accounts",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "IT",
      "L": "TOKYO",
      "O": "Kubernetes",
      "OU": "Kubernetes The Hard Way",
      "ST": "JAPAN"
    }
  ]
}
EOF

cfssl gencert \
  -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes \
  service-account-csr.json | cfssljson -bare service-account

}

# 以下が生成されます
service-account-key.pem
service-account.pem


Distribute the Client and Server Certificates

クライアント証明書とサーバ証明書を配布します。
※前の手順に従っている場合、Linux VM の作成に使用されるユーザ名は[kuberoot] になります

VM毎の証明書・秘密鍵をワーカー インスタンスにコピーします。

for instance in worker-0 worker-1; do
  PUBLIC_IP_ADDRESS=$(az network public-ip show -g kubernetes \
    -n ${instance}-pip --query "ipAddress" -otsv)

  scp -o StrictHostKeyChecking=no ca.pem ${instance}-key.pem ${instance}.pem kuberoot@${PUBLIC_IP_ADDRESS}:~/
done

VM毎の証明書・秘密鍵をコントローラ インスタンスにコピーします。

for instance in controller-0 controller-1; do
  PUBLIC_IP_ADDRESS=$(az network public-ip show -g kubernetes \
    -n ${instance}-pip --query "ipAddress" -otsv)

  scp -o StrictHostKeyChecking=no ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \
    service-account-key.pem service-account.pem kuberoot@${PUBLIC_IP_ADDRESS}:~/
done

Kube-proxy、kube-controller-manager、kube-scheduler、kubeletクライアント証明書は、次のラボでクライアント認証構成ファイルを生成するために使用されます。

この章で行ったことは以下。

  • サーバ証明書を作成
  • クライアント証明書を作成
    • kube-proxy
    • kube-controller-manager
    • kube-scheduler
    • kubelet

5.に続きます。