出力を入力へ

プログラミングに関する自分が考えた事を中心にまとめます

Kubernetes The Hard Wayをやった

Kubernetsを学ぶ上での鉄板教材であるKubernetes The Hard Wayをやった。 Kubernetes関連の書籍は数冊読んでいるが、運用経験は無く、もう少し内部コンポーネントについて理解を深めたかった。 以前(5年以上前)はいつかやりたいなで終わってしまったので、今回時間を取って取り組んでみた。

やったこと

基本はチュートリアルの通り(写経)。 ただし、条件として以下を変更している。

  • VMとして自宅ラボを利用
  • jumpboxマシーンとして常用の開発サーバを利用
  • サーバホスト名にprefix khw-を付与

VMはQEMU on Ubuntu 22.04(x86_64)を利用して構築した。 このUbuntu上に64-bit Arm System emulatorを利用してDebian (arm64)のVMを構築した。 これ自体は特に後続手順に影響は無く、qemu-system-arm パッケージをインストールすること、インスタンス作成時に aarch64 を選択することくらいしか違いが無かった。 しかしarm64エミュレーションのせいか処理が若干重く感じた。 今まであえて arm64エミュレーションでVMを実行してこなかったのでよい経験になった。
VM構築にisoから手動でインストールセットアップしたので、実はこのVM構築がおそらくチュートリアル中で一番時間が掛かった(単に待つ時間が長いだけだが)。

jumpboxサーバはDebian / arm64 でなくても良いとのことだったので、普段利用しているUbuntu 22.04 (x86_64)を流用する形にした。 当然この影響でトラブルに遭遇したのだが(後述)、良いトラブルシューティング程度で済んだ。特に影響なし。

サーバホスト名として、チュートリアル中では server node-0 node-1を推奨していたが、自宅検証環境の関係からprefixに khw-を付与し、khw-server khw-node-0 khw-node-1とした。 こちらも良い感じのトラブルを引き起こすことになったが(後述)、あまりKubernets関連の理解向上に寄与したわけではないので何ともいえないところ。

遭遇したトラブル

openssl1.1.1によるTLS証明書の作成失敗

ステップ4の ca.confによるTLS証明書の作成ステップにはいくつかのトラブルに遭遇した。 1つはopensslのバージョン影響による複数オプションが動作しないこと。自分の開発環境では、Ruby 2.7利用のためopenssl 1.1.1を利用していた。openssl 3.0からは -noenc-section -copy_extensionsなどのオプションが追加されている。 これはopenssl 1.1.1では利用できないのでTLS証明書の作成に失敗した。

Ruby2.7環境は今後不要になること、仮にruby2.7がまた必要になってもrbenvが対処してくれて自前でopenssl1.1.1のセットアップは不要になることから、openssl1.1.1は無効化してopenssl 3.0を利用することで解決した。 openssl1.1.1をまだ利用していたことを認識しておらず、このあたりのセットアップ手順はansible化していなかったので1つ自分の開発環境の負債を解消することができた。

blog.noellabo.jp

www.hsbt.org

とはいえ、opensslのオプション詳細やcnfファイルについては詳しくない。何となくやりたい事はわかる、くらいの感覚なのでもう少し理解を深める必要がある。 必要な情報は openssl-reqのman (web版はこちら)にあるので、これを読み解いていく必要がある。

ホスト名変更をca.confに反映する

TLS証明書を作成する上では接続先のホスト名変更についても考慮する必要がある。 単にssh先を変更するだけであればほぼ影響ないが、TLS証明書を作成する上でホスト名が間違っていると正しく接続できないので ca.confファイルを修正する必要がある。 とはいえ単にセクション名の変更やDNS設定の変更だけなのであまり迷わずに修正できた(これで正しいのかはあまり自信は無い)。

$ git diff ca.conf
diff --git a/ca.conf b/ca.conf
index eb17657..4f90131 100644
--- a/ca.conf
+++ b/ca.conf
@@ -46,7 +46,7 @@ CN = service-accounts
 # that identifies them as being in the `system:nodes` group, with a username
 # of `system:node:<nodeName>`.
 
-[node-0]
+[khw-node-0]
 distinguished_name = node-0_distinguished_name
 prompt             = no
 req_extensions     = node-0_req_extensions
@@ -57,17 +57,17 @@ extendedKeyUsage     = clientAuth, serverAuth
 keyUsage             = critical, digitalSignature, keyEncipherment
 nsCertType           = client
 nsComment            = "Node-0 Certificate"
-subjectAltName       = DNS:node-0, IP:127.0.0.1
+subjectAltName       = DNS:khw-node-0, IP:127.0.0.1
 subjectKeyIdentifier = hash
 
 [node-0_distinguished_name]
-CN = system:node:node-0
+CN = system:node:khw-node-0
 O  = system:nodes
 C  = US
 ST = Washington
 L  = Seattle
 
-[node-1]
+[khw-node-1]
 distinguished_name = node-1_distinguished_name
 prompt             = no
 req_extensions     = node-1_req_extensions
@@ -78,11 +78,11 @@ extendedKeyUsage     = clientAuth, serverAuth
 keyUsage             = critical, digitalSignature, keyEncipherment
 nsCertType           = client
 nsComment            = "Node-1 Certificate"
-subjectAltName       = DNS:node-1, IP:127.0.0.1
+subjectAltName       = DNS:khw-node-1, IP:127.0.0.1
 subjectKeyIdentifier = hash
 
 [node-1_distinguished_name]
-CN = system:node:node-1
+CN = system:node:khw-node-1
 O  = system:nodes
 C  = US
 ST = Washington
@@ -187,7 +187,7 @@ DNS.1 = kubernetes.default
 DNS.2 = kubernetes.default.svc
 DNS.3 = kubernetes.default.svc.cluster
 DNS.4 = kubernetes.svc.cluster.local
-DNS.5 = server.kubernetes.local
+DNS.5 = khw-server.kubernetes.local
 DNS.6 = api-server.kubernetes.local
 
 [kube-api-server_distinguished_name]

encryption-config.yamlファイルが存在しない

secretsをetcdに保存するときにrest側で暗号化して保存するための設定としてEncryptionConfigurationがある。 チュートリアル中ではこの設定を有効にするためにリポジトリ中のencryption-config.yamlファイルを参照しているが、実際にはこのファイルは存在しない。 これについては既にIssueとして報告されている。
Issueに記載の通りの設定をコピーして利用したところ問題なく動作した。

github.com

EncryptionConfigrationについては知らなかったので以下を参考にした。

kubernetes.io

sotoiwa.hatenablog.com

全体を通して

Kubernetes The Hard Wayはもっと何十時間も掛かる壮大な内容かと思っていたのでちょっと肩透かしをくらった感じ。 正直これならもっと早く取り組んでおけばよかったとも思った。これが最近のKubernetesの進化により構築が簡単になったおかげなのかはよくわからない。

また前述の通り、基本的にはkubernetes関連ではトラブルは発生せず、その下回りのLinux関連でのみトラブルが発生した。 内部で動作させるコンポーネント(kubeletやkube-apiserverなど)についてはイメージが具体化できたが、Kubernetesの理解が深まったかは怪しく感じたのでもう少しいろいろ取り組んでいる。 こういった検証を気軽に行える環境を得たことは1つのメリットだが、もっと手軽にKubernetesのクラスタ検証環境を構築できる手順が欲しいところ。 RancherKubespray? (Kubernetes The Easy Wayもあった)。 このあたりも試してみたい。