2023.01.12
RKE2によるKubernetesクラスタ構築の検討
はじめに
こんにちは。次世代システム研究室のT.Tです。
現在開発運用に携わっているサービスはKubernetes/Docker環境で運用しています。Kubernetesのライフサイクルに伴いKubernetesをバージョンアップしており、次回はv1.24以降のバージョンへの更新を予定していますが、そのバージョンではコンテナランタイムでのDocker利用が非推奨となっているためDockerのリプレイスも検討しています。
現在の運用環境ではIaaS上にRKEでKubernetes/Docker環境を構築しています。RKEはKubernetes/Dockerのクラスタを簡単な構成定義ファイルに基づいて自動で構築するツールです。次回のバージョンアップ時もIaaS上での環境構築を計画していて、RKEの後継となるRKE2ではコンテナランタイムにcontainerdをサポートしているため、RKE2でのKubernetes/containerd環境構築を検討しています。
本記事ではRKE2でのKubernetes/containerd環境の構築の概要をご紹介したいと思います。
1.RKE2とは
1.1.RKE2の概要
冒頭でも触れましたがRKE2は、Kubernetes/Dockerのクラスタを簡単な構成定義ファイルに基づいて自動で構築するRKEの後継となるツールです。特徴としては以下の点が挙げられます。
- IaaS上でKubernetesクラスタを構築管理するための機能が充実している
- コンテナランタイムにcontainerdをサポートしている
加えてRKE2にはセキュリティ対策の仕組みも取り入れられていて、この点もプロダクトとして重要な要素となっているようです。詳細は公式サイトに書かれています。こちらの記事では環境構築についても分かりやすく解説されています。
1.2.RKE2のアーキテクチャ
RKE2のアーキテクチャは以下の図のようになっています。KubernetesのコントロールプレーンをRKE2サーバーノードで管理し、ワーカーノードをRKE2エージェントノードで管理する仕組みとなっています。
https://docs.rke2.io/assets/images/overview-783b5a0a7e319dc96a2db8473dc83f3d.png
2.RKE2での環境構築
現状のローカル環境はVirtual BoxとVagrantで構築していて、ホストOSにはCentOSを利用しています。KubernetesのコントロールプレーンとワーカーノードにそれぞれVMを1台ずつ割り当てる構成で、RKEでKubernetesクラスタを構築しています。検証環境はこの構成に合わせて、RKE2のサーバーノードとエージェントノードにそれぞれVMを1台ずつ割り当てる構成で環境を構築します。
公式サイトのQuick Startに従って環境を構築してみます。まず、前提条件があるのでそれに合うように以下の環境を用意して、rootでRKE2をインストールして設定します。サーバーノードとエージェントノードのホスト名はそれぞれci2とconsumer2にしています。
- ホストOSはCentOS 7.8
- ホスト名を同じものにしない
- AppArmorが利用できる
- firewalldを無効にする
- NetworkManagerでcalico/flannelのネットワーク関連のインターフェースを無視する
サーバーノードへのrke2-serverのインストール。
# curl -sfL https://get.rke2.io | sh - # systemctl enable rke2-server.service # systemctl start rke2-server.service
# journalctl -u rke2-server -f Jan 11 12:06:31 ci2 systemd[1]: Starting Rancher Kubernetes Engine v2 (server)... Jan 11 12:06:31 ci2 sh[9133]: + /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service Jan 11 12:06:31 ci2 sh[9133]: Failed to get unit file state for nm-cloud-setup.service: No such file or directory Jan 11 12:06:31 ci2 rke2[9140]: time="2023-01-11T12:06:31Z" level=warning msg="not running in CIS mode" Jan 11 12:06:31 ci2 rke2[9140]: time="2023-01-11T12:06:31Z" level=info msg="Starting rke2 v1.24.8+rke2r1 (b061438ce1f04518d980aac842b62f92095d793d)" Jan 11 12:06:31 ci2 rke2[9140]: time="2023-01-11T12:06:31Z" level=info msg="Managed etcd cluster initializing" ...
エージェントノードへのrke2-agentのインストール。
# curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sh - # systemctl enable rke2-agent.service # mkdir -p /etc/rancher/rke2/ # vi /etc/rancher/rke2/config.yaml server: https://ci2:9345 token: K10...fdc::server:2e8...f5a # systemctl start rke2-agent.service
# journalctl -u rke2-agent -f Jan 11 12:47:11 consumer2 systemd[1]: Starting Rancher Kubernetes Engine v2 (agent)... Jan 11 12:47:11 consumer2 sh[3651]: + /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service Jan 11 12:47:11 consumer2 sh[3651]: Failed to get unit file state for nm-cloud-setup.service: No such file or directory Jan 11 12:47:11 consumer2 rke2[3657]: time="2023-01-11T12:47:11Z" level=warning msg="not running in CIS mode" Jan 11 12:47:11 consumer2 rke2[3657]: time="2023-01-11T12:47:11Z" level=info msg="Starting rke2 agent v1.24.8+rke2r1 (b061438ce1f04518d980aac842b62f92095d793d)" Jan 11 12:47:11 consumer2 rke2[3657]: time="2023-01-11T12:47:11Z" level=info msg="Running load balancer rke2-agent-load-balancer 127.0.0.1:6444 -> [10.0.2.15:9345 ci2:9345]" Jan 11 12:47:11 consumer2 rke2[3657]: time="2023-01-11T12:47:11Z" level=info msg="Running load balancer rke2-api-server-agent-load-balancer 127.0.0.1:6443 -> [10.0.2.15:6443 ci2:6443]" ...
3.Kubernetesクラスタの確認
rke2-serverとrke2-agentの起動コマンドの完了が確認できたので、ノードとPodのステータスを確認してみます。
ci2 # /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes NAME STATUS ROLES AGE VERSION ci2 NotReady control-plane,etcd,master 70m v1.24.8+rke2r1 consumer2 NotReady <none> 33m v1.24.8+rke2r1
ci2 # /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get po -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system cloud-controller-manager-ci2 1/1 Running 30 (54m ago) 71m kube-system etcd-ci2 1/1 Running 7 71m kube-system kube-apiserver-ci2 1/1 Running 11 (58m ago) 71m kube-system kube-controller-manager-ci2 0/1 Pending 0 59m kube-system kube-proxy-ci2 0/1 Pending 0 59m kube-system kube-proxy-consumer2 1/1 Running 2 (34m ago) 34m kube-system kube-scheduler-ci2 1/1 Running 8 (58m ago) 71m
ノードのステータスがNotReadyで正常に稼働していないようなので、詳細なステータスを確認してみます。
ci2 # /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml describe nodes ci2 ... Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- MemoryPressure False Wed, 11 Jan 2023 13:23:13 +0000 Wed, 11 Jan 2023 12:09:32 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Wed, 11 Jan 2023 13:23:13 +0000 Wed, 11 Jan 2023 12:09:32 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Wed, 11 Jan 2023 13:23:13 +0000 Wed, 11 Jan 2023 12:09:32 +0000 KubeletHasSufficientPID kubelet has sufficient PID available Ready False Wed, 11 Jan 2023 13:23:13 +0000 Wed, 11 Jan 2023 12:09:32 +0000 KubeletNotReady container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized ...
kubeletが稼働していないようなので、kubeletのログを確認してみます。CNIプラグインが稼働していないようです。
# tail -f /var/lib/rancher/rke2/agent/logs/kubelet.log E0111 13:49:41.106233 14842 kubelet.go:2349] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized" ...
CNIの内容を確認してみるとデフォルトのcanalが定義されているので設定的には問題なさそうです。
# cat /var/lib/rancher/rke2/server/manifests/rke2-canal.yaml apiVersion: helm.cattle.io/v1 kind: HelmChart metadata: annotations: helm.cattle.io/chart-url: https://rke2-charts.rancher.io/assets/rke2-canal/rke2-canal-v3.24.1-build2022101103.tgz creationTimestamp: null name: rke2-canal namespace: kube-system spec: bootstrap: true chartContent: ... set: global.cattle.systemDefaultRegistry: "" global.clusterCIDR: 10.42.0.0/16 global.clusterCIDRv4: 10.42.0.0/16 global.clusterCIDRv6: "" global.clusterDNS: 10.43.0.10 global.clusterDomain: cluster.local global.rke2DataDir: /var/lib/rancher/rke2 global.serviceCIDR: 10.43.0.0/16 global.systemDefaultRegistry: "" status: {}
いくつか関連するログを調べてみましたが今のところ原因が特定できておらず、ネットワーク周りの設定もいくつか変更して確認してみましたがエラーが改善できていません。Kubernetesクラスタ上でアプリケーションを稼働させるところまで検証を進める予定でしたが、CNIが利用できないとKubernetesクラスタが未完成の状態で検証が継続できないので、検証はここまでで断念しました。
4.RKEとの運用上の相違点
RKEとの相違点は公式サイトの冒頭に記載されていますが、実際にRKE2での構築を進めてみた上での所感を書いておきます。
RKE2ではKubernetesクラスタの構成を変更する際に各エージェントノードでrke2-agentからサーバーノードにHTTPリクエストを投げる形で変更します。システム全体としてはサーバーノードにrke2-server、エージェントノードにrke2-agentをインストールして各ノードに構成定義ファイルを配置してサーバーノードとエージェントノードが連携してKubernetesクラスタを構成する仕組みとなっています。一方RKEはコンテナランタイムにDockerを使い、サーバーノードとワーカーノードにDocker(dockerd)がインストールされている前提で、サーバーノードでrkeコマンドを実行してssh経由で構成定義ファイルの内容に基づいてKubernetesクラスタを構築する仕組みでした。
中央集権的な管理から分散的な管理の仕組みに移行しているのでRKEからRKE2への移行により構成管理も大きな変更が必要になりそうです。現行システムの構成管理にはAnsibleも利用しているので、Ansibleと組み合わせることで手軽に管理できる仕組みを目指したいと思います。
5.まとめ
RKE2でKuberntes/containerd環境を構築してみたことで構成管理の方針を検討する材料は集められました。Kubernetesクラスタ構築、アプリケーションのデプロイ、containerdによる運用等、既存の環境とは大分異なるものとなりそうです。今回はネットワーク周りのエラーにより検証ができませんでしたが、今後も本番環境への導入に向けて引き続き様々な検証を進める予定です。
次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。
皆さんのご応募をお待ちしています。
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD