Kubernetes The Hard Way On VirtualBox 6日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの6日目。
今回はKubernetes のControl Planeを作成します。
いよいよそれっぽくなってきました。
Bootstrapping the Kubernetes Control Plane
今回は高可用性のために2つのインスタンスにControl Planeを設定します。また、Kubernetes API Serverをリモートクライアントに公開するためのロードバランサも作成します。
以下のコンポーネントが2つのノードにインストールされます
- Kubernetes API Server
- Scheduler
- Controller Manager
Prerequisites
今回の作業は maste-1
master-2
両方に行います
Provision the Kubernetes Control Plane
設定用のディレクトリ作成
sudo mkdir -p /etc/kubernetes/config
Download and Install the Kubernetes Controller Binaries
公式のバイナリをダウンロードします。公式手順だと v1.13.0
なんですけど流石に古いので、執筆時点で最新の v1.22.0
に変えてます。
リリース情報は https://kubernetes.io/docs/setup/release/#server-binaries から確認できます。
wget -q --show-progress --https-only --timestamping \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-apiserver" \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-controller-manager" \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-scheduler" \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kubectl"
バイナリをインストールします。
{ chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/ }
Configure the Kubernetes API Server
証明書と暗号化に関するファイルを配置します。
{ sudo mkdir -p /var/lib/kubernetes/ sudo cp ca.crt ca.key kube-apiserver.crt kube-apiserver.key \ service-account.key service-account.crt \ etcd-server.key etcd-server.crt \ encryption-config.yaml /var/lib/kubernetes/ }
インスタンスの内部IPアドレスはAPIサーバをクラスターメンバにする際のアドバタイズに使われます。
現在の内部IPアドレスを取得しておきます。
INTERNAL_IP=$(ip addr show enp0s8 | grep "inet " | awk '{print $2}' | cut -d / -f 1)
確認します。
echo $INTERNAL_IP
kube-apiserver.service
という、systemdのunitファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-apiserver \\ --advertise-address=${INTERNAL_IP} \\ --allow-privileged=true \\ --apiserver-count=2 \\ --audit-log-maxage=30 \\ --audit-log-maxbackup=3 \\ --audit-log-maxsize=100 \\ --audit-log-path=/var/log/audit.log \\ --authorization-mode=Node,RBAC \\ --bind-address=0.0.0.0 \\ --client-ca-file=/var/lib/kubernetes/ca.crt \\ --enable-admission-plugins=NodeRestriction,ServiceAccount \\ --enable-swagger-ui=true \\ --enable-bootstrap-token-auth=true \\ --etcd-cafile=/var/lib/kubernetes/ca.crt \\ --etcd-certfile=/var/lib/kubernetes/etcd-server.crt \\ --etcd-keyfile=/var/lib/kubernetes/etcd-server.key \\ --etcd-servers=https://192.168.5.11:2379,https://192.168.5.12:2379 \\ --event-ttl=1h \\ --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\ --kubelet-certificate-authority=/var/lib/kubernetes/ca.crt \\ --kubelet-client-certificate=/var/lib/kubernetes/kube-apiserver.crt \\ --kubelet-client-key=/var/lib/kubernetes/kube-apiserver.key \\ --kubelet-https=true \\ --runtime-config=api/all=true \\ --service-account-key-file=/var/lib/kubernetes/service-account.crt \\ --service-cluster-ip-range=10.96.0.0/24 \\ --service-node-port-range=30000-32767 \\ --tls-cert-file=/var/lib/kubernetes/kube-apiserver.crt \\ --tls-private-key-file=/var/lib/kubernetes/kube-apiserver.key \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Configure the Kubernetes Controller Manager
kube-controller-manager のkubeconfigを配置します
sudo cp kube-controller-manager.kubeconfig /var/lib/kubernetes/
kube-controller-manager.service
という、systemdのunitファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-controller-manager \\ --address=0.0.0.0 \\ --cluster-cidr=192.168.5.0/24 \\ --cluster-name=kubernetes \\ --cluster-signing-cert-file=/var/lib/kubernetes/ca.crt \\ --cluster-signing-key-file=/var/lib/kubernetes/ca.key \\ --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ --leader-elect=true \\ --root-ca-file=/var/lib/kubernetes/ca.crt \\ --service-account-private-key-file=/var/lib/kubernetes/service-account.key \\ --service-cluster-ip-range=10.96.0.0/24 \\ --use-service-account-credentials=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Configure the Kubernetes Scheduler
kube-scheduler のkubeconfigを配置します
sudo cp kube-scheduler.kubeconfig /var/lib/kubernetes/
kube-scheduler.service
という、systemdのunitファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-scheduler \\ --kubeconfig=/var/lib/kubernetes/kube-scheduler.kubeconfig \\ --address=127.0.0.1 \\ --leader-elect=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Start the Controller Services
作成したサービスの自動起動設定と、起動をします
{ sudo systemctl daemon-reload sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler }
確認しましょう
kubectl get componentstatuses --kubeconfig admin.kubeconfig
ここでトラブル!
vagrant@master-1:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port?
ほうほう。なんで?
vagrant@master-1:~$ systemctl status kube-apiserver ● kube-apiserver.service - Kubernetes API Server Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled Active: activating (auto-restart) (Result: exit-code) since Wed 2021-10-06 22:30:20 UTC; 3s Docs: https://github.com/kubernetes/kubernetes Process: 7337 ExecStart=/usr/local/bin/kube-apiserver --advertise-address=192.168.5.11 --all Main PID: 7337 (code=exited, status=1/FAILURE)
どうもkube-apiserver が動いてない。sudo 付けてもう一度起動させてみる。
vagrant@master-1:~$ sudo systemctl start kube-apiserver vagrant@master-1:~$ sudo systemctl status kube-apiserver ● kube-apiserver.service - Kubernetes API Server Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled Active: activating (auto-restart) (Result: exit-code) since Sat 2021-10-09 04:35:15 UTC; 2s Docs: https://github.com/kubernetes/kubernetes Process: 30902 ExecStart=/usr/local/bin/kube-apiserver --advertise-address=192.168.5.11 --al Main PID: 30902 (code=exited, status=1/FAILURE) Oct 09 04:35:15 master-1 systemd[1]: kube-apiserver.service: Main process exited, code=exited, Oct 09 04:35:15 master-1 systemd[1]: kube-apiserver.service: Failed with result 'exit-code'.
やっぱダメ
syslog見ると
Oct 9 04:35:57 master-1 systemd[1]: Started Kubernetes API Server. Oct 9 04:35:57 master-1 kube-apiserver[31144]: Error: unknown flag: --kubelet-https Oct 9 04:35:57 master-1 systemd[1]: kube-apiserver.service: Main process exited, code=exited, status=1/FAILURE Oct 9 04:35:57 master-1 systemd[1]: kube-apiserver.service: Failed with result 'exit-code'.
https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/ みてもそんな--kubelet-https
というフラグはないなあ。廃止になったのかな?
--kubelet-https
を消して起動させると、今度はこんなログが
Oct 9 04:53:32 master-1 kube-apiserver[4894]: Error: [service-account-issuer is a required flag, --service-account-signing-key-file and --service-account-issuer are required flags] Oct 9 04:53:32 master-1 systemd[1]: kube-apiserver.service: Main process exited, code=exited, status=1/FAILURE Oct 9 04:53:32 master-1 systemd[1]: kube-apiserver.service: Failed with result 'exit-code'.
やれやれだぜ。一難去ってまた一難
service-account-issuer
と service-account-signing-key-file
が必須と来たか。k8s 1.18以降では、ServiceAccountIssuerDiscoveryというOIDC DiscoveryやJWKsのエンドポイントを提供する機能が追加されて、認証用トークン作成のために鍵が必要らしい。
ここでissueが上がってるな
https://github.com/kelseyhightower/kubernetes-the-hard-way/issues/626
秘密鍵を作成
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
/etc/systemd/system/kube-apiserver.service
に以下を追記
--service-account-key-file=/var/lib/kubernetes/service-account-key.pem \ --service-account-signing-key-file=/var/lib/kubernetes/service-account-key.pem \ --service-account-issuer=api \
もう1回起動
sudo systemctl daemon-reload sudo systemctl start kube-apiserver
vagrant@master-1:~$ sudo systemctl status kube-apiserver ● kube-apiserver.service - Kubernetes API Server Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled Active: active (running) since Sun 2021-10-10 21:34:46 UTC; 1min 36s ago Docs: https://github.com/kubernetes/kubernetes Main PID: 30706 (kube-apiserver) Tasks: 9 (limit: 2360) CGroup: /system.slice/kube-apiserver.service └─30706 /usr/local/bin/kube-apiserver --advertise-address=192.168.5.11 --allow-priv
よしよし。kubectlでも確認
kubectl get componentstatuses --kubeconfig admin.kubeconfig
vagrant@master-1:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR scheduler Healthy ok etcd-1 Healthy {"health":"true","reason":""} controller-manager Healthy ok etcd-0 Healthy {"health":"true","reason":""}
master-2
に鍵を転送して確認
vagrant@master-2:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR etcd-1 Healthy {"health":"true","reason":""} etcd-0 Healthy {"health":"true","reason":""} controller-manager Healthy ok scheduler Healthy ok
OKOK!
The Kubernetes Frontend Load Balancer
ここではKubernetes API Server用の外部向けロードバランサを作成します。
vagrant ssh loadbalancer
haproxyをインストールします。
sudo apt-get update && sudo apt-get install -y haproxy
/etc/haproxy/haproxy.cfg
に設定をします。
cat <<EOF | sudo tee /etc/haproxy/haproxy.cfg frontend kubernetes bind 192.168.5.30:6443 option tcplog mode tcp default_backend kubernetes-master-nodes backend kubernetes-master-nodes mode tcp balance roundrobin option tcp-check server master-1 192.168.5.11:6443 check fall 3 rise 2 server master-2 192.168.5.12:6443 check fall 3 rise 2 EOF
sudo service haproxy restart
HTTTPリクエストをして動作確認
curl https://192.168.5.30:6443/version -k
以下のように返ってくればOK
{ "major": "1", "minor": "22", "gitVersion": "v1.22.0", "gitCommit": "c2b5237ccd9c0f1d600d3072634ca66cefdf272f", "gitTreeState": "clean", "buildDate": "2021-08-04T17:57:25Z", "goVersion": "go1.16.6", "compiler": "gc", "platform": "linux/amd64" }
今回はここまで。エラー出たときはびっくりした。
お読みいただきありがとうございました。