涅槃を目指す in はてな

人生に迷う様を書きます

Kubernetes The Hard Way On VirtualBox 2日目

今回やること

前回はノードの作成をしました、今回は接続に必要な証明書の作成です。

Provisioning a CA and Generating TLS Certificates

Public Key Infrastructure (PKI)を準備し、以下のコンポーネントで使うTLS証明書を作成します。

  • etcd
  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler
  • kubelet
  • kube-proxy

PKIてなに?

日本語では「公開鍵暗号基盤」とか訳されて、電子証明書を発行するために用いられ、3つの要素で構成されています。

  1. サーバ証明書やクライアント証明書
  2. 証明書の発行元である認証局
  3. 証明書を管理するリポジトリ

詳しくは以下を参照して下さい

ja.wikipedia.org

どこで作業するか

openssl コマンドが使えて、作成した証明書をVMにコピーできる環境であればOK。

公式ではmaster-1ノードを管理用クライアントにする方式が紹介されていますが、私は手元のPCを管理用マシンとして使いたいので手元のPCで行います。

Certificate Authority(認証局)作成

ここではTLS証明書発行に必要な認証局を作成します。

ディレクトリ作成

$ mkdir pki
$ cd pki

CA用の秘密鍵作成

$ openssl genrsa -out ca.key 2048

権限問題を回避するために /etc/ssl/openssl.cnf ファイル内の RANDFILE という文字列で始まる行があったらコメントアウトします。

RANDFILEは乱数を生成するためのファイルで、デフォだと $ENV::HOME/.rnd が使われるハズです(多分)

sudo sed -i '0,/RANDFILE/{s/RANDFILE/\#&/}' /etc/ssl/openssl.cnf

秘密鍵を使ってCSRを作成します。

openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.csr

自分の秘密鍵を使って自己署名します

$ openssl x509 -req -in ca.csr -signkey ca.key -CAcreateserial  -out ca.crt -days 1000

Signature ok
subject=CN = KUBERNETES-CA
Getting Private key

直下に以下2つのファイルがあることを確認しましょう

ca.crt
ca.key

ca.crtKubernetes認証局の証明書で、ca.keyKubernetes認証局秘密鍵です。ca.crtは至る所で使われるので色んな所にコピーされます。

ca.key認証局が証明書の署名に使います。そしてそれは安全な場所に保管する必要があり、私の環境だと手元のPCが認証局サーバになります。これは他のノードにコピーする必要はありません。

クライアント証明書とサーバ証明書の作成

ここではkubernetesの各コンポーネント用のクライアント証明書とサーバ証明書、adminユーザ用のクライアント証明書を作成します。

admin 用のクライアント証明書作成

admin用の秘密鍵作成

$ openssl genrsa -out admin.key 2048

admin用のCSR作成。OUに注意。adminユーザはsystem:masters グループの一員であることに注意して下さい。

そうすることでkubectlを使ってあらゆる管理操作を行うことが出来ます。

$ openssl req -new -key admin.key -subj "/CN=admin/O=system:masters" -out admin.csr

作成した秘密鍵でadmin用の証明書に署名

$ openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out admin.crt -days 1000
Signature ok
subject=CN = admin, O = system:masters
Getting CA Private Key

以下のファイルが出来ていることを確認

admin.key
admin.crt

admin.keyadmin.crtがあれば管理者アクセスが可能です。これらをkubectlで使って管理操作を実行できるようにします。

Kubeletのクライアント証明書

ここではスキップします。Workerノードをセットアップする時に行います。

Controller Manager のクライアント証明書

ここではkube-controller-managerのクライアント所証明書と秘密鍵を作成します。

$ openssl genrsa -out kube-controller-manager.key 2048
$ openssl req -new -key kube-controller-manager.key -subj "/CN=system:kube-controller-manager" -out kube-controller-manager.csr
$ openssl x509 -req -in kube-controller-manager.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-controller-manager.crt -days 1000

以下のファイルが出来ていることを確認

kube-controller-manager.key
kube-controller-manager.crt

Kube Proxyのクライアント証明書

ここではkube-proxy のクライアント所証明書と秘密鍵を作成します。

$ openssl genrsa -out kube-proxy.key 2048
$ openssl req -new -key kube-proxy.key -subj "/CN=system:kube-proxy" -out kube-proxy.csr
$ openssl x509 -req -in kube-proxy.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out kube-proxy.crt -days 1000

以下のファイルが出来ていることを確認

kube-proxy.key
kube-proxy.crt

Schedulerのクライアント証明書

ここではkube-scheduler のクライアント所証明書と秘密鍵を作成します。

似たような作業が続くのでコピペミスに注意。コピペの乱れは心の乱れ。

$ openssl genrsa -out kube-scheduler.key 2048
$ openssl req -new -key kube-scheduler.key -subj "/CN=system:kube-scheduler" -out kube-scheduler.csr
openssl x509 -req -in kube-scheduler.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out kube-scheduler.crt -days 1000

以下のファイルが出来ていることを確認

kube-scheduler.key
kube-scheduler.crt

The Kubernetes API Serverの証明書

kube-apiserverの証明書は、アクセス可能なコンポーネント名それぞれに対応するための名前の一部を代替名として持っている必要があります。

maesterサーバ、ロードバランサー、kube-apiサービス等のIPアドレスDNS名が含まれます。

opensslのconfファイルに以下の設定をします。10.96.0.1はThe Kubernetes API ServerのIPアドレスです。

$ cat > openssl.cnf <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 10.96.0.1
IP.2 = 192.168.5.11
IP.3 = 192.168.5.12
IP.4 = 192.168.5.30
IP.5 = 127.0.0.1
EOF

kube-apiserverの証明書を作成します

$ openssl genrsa -out kube-apiserver.key 2048
$ openssl req -new -key kube-apiserver.key -subj "/CN=kube-apiserver" -out kube-apiserver.csr -config openssl.cnf
$ openssl x509 -req -in kube-apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out kube-apiserver.crt -extensions v3_req -extfile openssl.cnf -days 1000

以下のファイルが出来ていることを確認

kube-apiserver.crt
kube-apiserver.key

ETCDのサーバ証明書作成

kube-apiserverと同様に、etcdにはetcdクラスタを構成する全てのIPアドレスが必要です

$ cat > openssl-etcd.cnf <<EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.5.11
IP.2 = 192.168.5.12
IP.3 = 127.0.0.1
EOF

etcd用の証明書を作成します

$ openssl genrsa -out etcd-server.key 2048
$ openssl req -new -key etcd-server.key -subj "/CN=etcd-server" -out etcd-server.csr -config openssl-etcd.cnf
$ openssl x509 -req -in etcd-server.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out etcd-server.crt -extensions v3_req -extfile openssl-etcd.cnf -days 1000

以下のファイルが出来ていることを確認

etcd-server.key
etcd-server.crt

Service Accountキーペア

Service Accountキーペアを作成します。

Kubernetesには、User AccountとService Accountがあります。User AccountはEKSではIAMと紐付いたりして、Kubernetesの管理対象ではありません。

Service AccountはPodの実行のために割り当てられ、Namespaceに紐づくリソースです。詳しくはこちらをご覧ください。

Managing Service Accounts | Kubernetes

$ openssl genrsa -out service-account.key 2048
$ openssl req -new -key service-account.key -subj "/CN=service-accounts" -out service-account.csr
$ openssl x509 -req -in service-account.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out service-account.crt -days 1000

以下のファイルが出来ていることを確認

service-account.key
service-account.crt

証明書の配布

証明書と秘密鍵をコントローラインスタンスに配布します。masterノードからではなく手元のPCで作成した鍵を配布ているので公式とは手順が異なっています

for instance in vagrant@192.168.5.11 vagrant@192.168.5.12 ; do
  scp ca.crt ca.key kube-apiserver.key kube-apiserver.crt \
    service-account.key service-account.crt \
    etcd-server.key etcd-server.crt \
    ${instance}:~/
done

master-1に配布されているか確認

vagrant@master-1:~$ ll
total 116
drwxr-xr-x 5 vagrant vagrant  4096 Sep 23 01:56 ./
drwxr-xr-x 4 root    root     4096 Sep 20 05:46 ../
-rw------- 1 vagrant vagrant   680 Sep 22 16:42 .bash_history
-rw-r--r-- 1 vagrant vagrant   220 Aug 27  2020 .bash_logout
-rw-r--r-- 1 vagrant vagrant  3771 Aug 27  2020 .bashrc
drwx------ 2 vagrant vagrant  4096 Sep 20 05:46 .cache/
drwx------ 3 vagrant vagrant  4096 Sep 20 05:46 .gnupg/
-rw-r--r-- 1 vagrant vagrant   807 Aug 27  2020 .profile
drwx------ 2 vagrant vagrant  4096 Sep 20 05:46 .ssh/
-rw-rw-r-- 1 vagrant vagrant  1001 Sep 23 01:56 ca.crt
-rw------- 1 vagrant vagrant  1679 Sep 23 01:56 ca.key
-rwxrwxr-x 1 vagrant vagrant 46007 Sep 20 05:47 cert_verify.sh*
-rw-rw-r-- 1 vagrant vagrant  1082 Sep 23 01:56 etcd-server.crt
-rw------- 1 vagrant vagrant  1679 Sep 23 01:56 etcd-server.key
-rw-rw-r-- 1 vagrant vagrant  1237 Sep 23 01:56 kube-apiserver.crt
-rw------- 1 vagrant vagrant  1675 Sep 23 01:56 kube-apiserver.key
-rw-rw-r-- 1 vagrant vagrant  1005 Sep 23 01:56 service-account.crt
-rw------- 1 vagrant vagrant  1675 Sep 23 01:56 service-account.key

master-2に配布されているか確認

vagrant@master-2:~$ ll
total 116
drwxr-xr-x 5 vagrant vagrant  4096 Sep 23 01:56 ./
drwxr-xr-x 4 root    root     4096 Sep 20 05:47 ../
-rw------- 1 vagrant vagrant   645 Sep 20 06:23 .bash_history
-rw-r--r-- 1 vagrant vagrant   220 Aug 27  2020 .bash_logout
-rw-r--r-- 1 vagrant vagrant  3771 Aug 27  2020 .bashrc
drwx------ 2 vagrant vagrant  4096 Sep 20 05:47 .cache/
drwx------ 3 vagrant vagrant  4096 Sep 20 05:47 .gnupg/
-rw-r--r-- 1 vagrant vagrant   807 Aug 27  2020 .profile
drwx------ 2 vagrant vagrant  4096 Sep 20 05:47 .ssh/
-rw-rw-r-- 1 vagrant vagrant  1001 Sep 23 01:56 ca.crt
-rw------- 1 vagrant vagrant  1679 Sep 23 01:56 ca.key
-rwxrwxr-x 1 vagrant vagrant 46007 Sep 20 05:48 cert_verify.sh*
-rw-rw-r-- 1 vagrant vagrant  1082 Sep 23 01:56 etcd-server.crt
-rw------- 1 vagrant vagrant  1679 Sep 23 01:56 etcd-server.key
-rw-rw-r-- 1 vagrant vagrant  1237 Sep 23 01:56 kube-apiserver.crt
-rw------- 1 vagrant vagrant  1675 Sep 23 01:56 kube-apiserver.key
-rw-rw-r-- 1 vagrant vagrant  1005 Sep 23 01:56 service-account.crt
-rw------- 1 vagrant vagrant  1675 Sep 23 01:56 service-account.key

今回はここまで!

お読みいただきありがとうございました!

面倒くさかったー