はじめまして。VMware の伊藤です。Tanzu 製品のプラットフォームアーキテクトとして働いており、開発と運用双方の経験があります。この記事では vSphere with Tanzu 7.0u2 を利用して Kubernetes クラスタのライフサイクル管理の基本(作成/コンテキスト取得/スケール/バージョンアップ/削除)を実施します。
この記事の内容は vSphere with Tanzu の構成には左右されませんが、テスト環境は以下の図の構成(ワークロードとロードバランサが異なるネットワーク)となっています。
この構成の構築に関しては以下の記事をご参照ください。
- vSphere with Tanzu 7.0u2, NSX-ALB LoadBalancer の簡易構成の構築
- Tanzu with NSX ALB をロードバランサーとk8sワークロードが異なるネットワークの構成にデプロイする手法
vSphere with Tanzu の Kubernetes クラスタ管理の概要
OSS ベースの k8s であれば、 k8s 環境を利用するための構築/変更/削除作業では基盤(仮想マシンやネットワーク、ストレージなど)を用意して、ホスト OS のセットアップ(Linux のインストールと必要なパッケージを導入)し、最後に k8s を構成するための複雑な操作(kubeadm などの利用)が必要となります。慣れれば構築自体はさほど難しくなく、Ansible などを使って一部自動化を実施することも可能です。ただ、いわゆる Day2 操作(スケールやバージョンアップなど)といった構成の変更作業は定型的なものの、1台ずつ手を入れる必要があるので手間と時間がかかります。これを完全に手組みで自動化することは一般ユーザには難しいでしょう。
パブリッククラウドおよびオンプレミスクラウドの k8s 製品を利用することは、一般的には k8s の管理運用を簡素化し、コストを低減させてサイロ化と陳腐化を防ぐ効果があります。VMware が提供する vSphere with Tanzu(vSphere にインテグレートされた k8s 基盤) や TKGm(マルチクラウド用の k8s 基盤)も同様に k8s の運用コストを低減させるための製品です。 この記事は vSphere with Tanzu の k8s ライフサイクル操作の基礎を具体的に説明することで、製品を検討されているお客様に実際の使用感を感じてもらったり、導入を検討されるお客様の PoC の手助けとなることなどを目的として書かれています。
具体的な操作解説を開始するまえに、vSphere with Tanzu でどのように Kubernetes クラスタを管理するか概要説明をします。以下の図を見てください。
vSphere with Tanzu を使った Kubernetes の利用には大きく3つの作業があります。
- 管理者としてアクセス権限やリソース上限を定義(図の左の運用者の仕事)
- Kubernetes クラスタの利用者として、Kubernetes クラスタのライフサイクル管理
- Kubernetes クラスタの利用者として、Kubernetes クラスタをアプリに使う
1つめの管理者としての仕事は多人数で多数の Kubernetes クラスタを利用する際に必要となるルール作りです。想像していただくと分かるかと思いますが、100人の開発者が本番環境も含めた100個のクラスタに誰でも管理者権限でアクセスできるという状況は望ましくありません。「チームAのクラスタにはチームAの人員がアクセス可能」「本番環境には運用エンジニアのみがアクセス可能」などと適切なアクセス権限の設定が必要です。また、同じインフラ基盤(k8s より下のレイヤ)を共有しているのに、ある1つのグループが無尽蔵に資源を食い尽くすという状況も避けたいので、「使っているリソースの可視化」「リソース上限(クオータ)の設定」なども必要です。これらを vSphere with Tanzu のネームスペース(リソースプールに近い)を使うことでシンプルに実現できます。
図の中央にある2つめの作業は、Kubernetes クラスタのライフサイクル管理です。1つめの作業で決められたネームスペースに従って、アクセス権限を持つユーザが許された資源の範囲で Kubernetes クラスタを簡単に作成したり、変更したり、削除するといったことができます。このアプリケーション用のクラスタは「TKC(Tanzu Kubernetes Cluster)」と呼ばれています。さきほど説明したように OSS の k8s はこの管理がかなり大変ですが、vSphere with Tanzu は「スーパーバイザクラスタと呼ばれる管理専用の k8s クラスタにたいして、YAMLに定義された k8s の構成をkubectl apply/delete することでクラスタのライフサイクル操作を実施する」という管理方法なので、運用の負担が大幅に低減します。
最後の図の右側にある3つめの作業は一般的な k8s の利用です。特に vSphere with Tanzu としての独自機能はありませんので、ここで動くアプリは大きな変更無く他の Kubernetes 環境で動くことが期待されます。普通の k8s の話なので、この記事では扱いません。
ここまでをまとめると、Kubernetes のライフサイクル管理は vSphere with Tanzu 独自の手法により OSS 版よりも大幅に効率化されており、vSphere with Tanzu の Kubernetes 自体は独自性がほとんどないためバニラや他社製品も含めて Kubernetes アプリの可搬性は高いといえます。
ここからは具体的にこれらをどう実現するかを以下の順で紹介していきます。
- ネームスペースの作成と管理
- 作業端末へのプラグイン追加
- vSphere with Tanzu へのログインとコンテキスト取得
- Kubernetes クラスタ(TKC)の作成
- TKC へのログインとコンテキスト取得
- クラスタの水平スケールと垂直スケール
- クラスタの Kubernetes バージョンアップ
- クラスタの削除
ネームスペースの作成と管理
vSphere with Tanzu の構築後に実施する作業はネームスペースの管理です。このネームスペースは Kubernetes のネームスペースと似ていますが、vSphere を管理する運用者視点ではリソースプールの概念に似ています。
まず、vSphere の管理者として、vSphere Client でネームスペースを作成します。
クラスタを右クリックして「新規名前空間作成」を選び、ネームスペース名と利用するワークロードネットワーク(vSphere with Tanzu 構築時に定義)を1つ選びます。このネームスペース上に作成されるクラスタはここで指定したネットワーク上に構築されますので、必要であればネームスペースごとにネットワークを分離できます。
次に作成したネットワークにたいして閲覧ユーザおよび閲覧/編集ユーザーを割り当てます。割り当てるユーザは vSphere が管理する SSO ユーザなので、ローカルで管理している場合は「メニュー -> 管理 -> Single Sign On」でユーザ作成や変更ができます。
ネームスペースを選択し、「権限の管理」ボタンからネームスペースのユーザを指定します。上記の例では「ネームスペース team-a に user1 と user2 を編集可能ユーザとして登録」「ネームスペース team-b に user3 と user4 を編集可能ユーザとして登録。user1 を閲覧可能ユーザとして登録」としています。
この設定をすると、user2 はネームスペース team-a は利用できる(ログインに成功)ものの、ネームスペース team-b は利用できません(ログインに失敗)。一方、 user1 は team-B のリソース閲覧のみできます。
ネームスペースの設定では、ユーザー以外にもリソース系の設定や、どのデータストアを利用するかを設定できます。今回はデータストアとして「default (構築時の記事でタグベースで登録作業をしている)」を選択し、リソース制限は実施していません。以下の図を見るとわかるように、vSphere 上でネームスペース単位でリソース使用量が簡単に把握できます。
以上でネームスペースの設定は終了です。
以後はネームスペース「yuichi」と、それに登録したユーザ「[email protected]」使ってライフサイクル操作を実施します。検証以外ではアドミンユーザーは直接利用しないことをおすすめします。
この項目の詳細は以下のドキュメントをご参照ください。
CLIツールのインストールとスーパーバイザクラスタへのログイン
今までの図にあったように、Kubernetes のライフサイクル管理はスーパーバイザクラスタにたいして YAML を適用することで実施します。この操作は極めて k8s 的な利用法なので、k8s に慣れたユーザであればすぐに習得できるはずです。
先ほど定義したアクセス管理の設定ですが、vSphere with Tanzu は「ユーザが vSphere で定義したネームスペースにログインできるか」ということを kubectl コマンドをプラグインで拡張(これもk8sの一般的な機能追加手法)して実現しています。
以下の図にあるようにダウンロードページからプラグインを操作マシンに導入し、kubectl コマンドで vSphere(スーパーバイザクラスタ)にログインすると、一定時間利用できる kubernetes のコンテキストが得られます。そのコンテキストを使うと認証ユーザとしてクラスタ操作ができるようになります。一定時間が経過するとコンテキストは再ログインしないと使えなくなりますので、作業端末に操作権限が永続してしまう心配はありません。
図の左にあるツールのダウンロードページは1つ前のネームスペースのスクリーンショット画像にある「CLIツールへのリンク」から行けます。ちなみに、このリンクのURLがスーパーバイザクラスタのIPやホスト名となります。これは vSphere with Tanzu の設定画面にも記載されていますが、今回の環境では「192.168.52.50」となっています。スーパーバイザークラスタの IP は vCenter の IP とは異なりますのでご注意ください。
なお、ツールのインストール手順は上記ダウンロードページに書いてありますが、ダウンロードしたバイナリ(プラグイン)をパスが通ったディレクトリ(通常は kubectl がある場所)に配置するだけです。
ツールの準備が整ったら、スーパーバイザクラスタに「kubectl vsphere login」コマンドでログインします。
ログインに成功すると、ログインしたユーザに結び付けられたネームスペース名がコンテキストとして得られます。今回はコンテキスト「yuichi」が利用したいものとなります。ログインコマンドは長いのでスニペットに登録したり、1行のシェルスクリプトとして呼び出すなどするのがよいと思います。
そのコンテキストを「kubectl config use-context <コンテキスト名>」として選択すると、スーパーバイザクラスタの決められたネームスペース(今回はyuichi)を使えるようになります。ここには直接アプリを展開することはありませんが、次に説明する k8s クラスタ定義のYAMLをapply/deleteなどすることで、k8sクラスタ(TKC)のライフサイクル管理の操作を実施します。なお、「kubectl get nodes」などとすると、スーパーバイザクラスタのノード一覧が得られます。
以上で TKC のライフサイクル管理を実現する準備が整いました。
この項目の詳細は以下のドキュメントをご参照ください。
Kubernetes クラスタ(TKC)の作成
Kubernetes のライフサイクル管理の最初の作業として TKC(アプリ用のk8sクラスタ)の作成を実施します。この作業は「Kubernetes クラスタの定義が書かれた YAML ファイルを kubectl apply コマンドでスーパーバイザークラスタ(管理用の k8s クラスタ)に適用する」というだけです。
スーパーバイザクラスタの定義ファイルは Pod や Deployment リソースの定義とさほど変わらず、スペックで k8s のバージョンやノードのサイズや数といった必要最低限のパラメーターに加えて、メタデータで名前などを定義します。一般的な k8s でリソースをスクラッチから定義することは珍しいように、クラスタ定義のYAMLもコピペを改変して作成します。なお、上記 YAML ではネットワーク定義もしており、これはオプション扱いです。ただ、ここでは k8s の外部ネットワークと k8s 内部のアドレス空間が衝突することを防ぐために意図的に記載しています。
この YAML の詳細は以下の2つの記事を参照ください。
この作業を実施すると以下の図のように TKC が vSphere 上に仮想マシンとして展開されます。
TKCへのログインとコンテキスト取得
TKC の展開が完了するとコンテキストを得ることで操作ができるようになります。コンテキストを得る手法は2つあり、1つめは「kubectl vsphere login」コマンドでログインするというものです。
また長いコマンドで恐縮なのですが、スーパーバイザクラスタにログインするときと同様にクレデンシャルを指定し、それに加えてネームスペースと TKC のクラスタ名を指定しています。これもスニペットなどに登録しておくことをおすすめします。接続先のサーバーホスト名は TKC ではなく認証情報をチェックするスーパーバイザークラスタ(今回は 192.168.52.50)であることにご注意ください。
このログインにパスすると、作成した TKC のコンテキストが得られます。コンテキストの指定後にノード一覧を得ると作成時に指定したノード台数が確認できます。
せっかくですので、参考までにこのクラスタに nginx ポッドを作成し、サービスをタイプ:ロードバランサーで公開します。ロードバランサーのIPへの wget に成功していることからワークロード(Pod)もネットワーク(サービス)も問題なく動作していることがわかります。
この1つめのコンテキスト取得方法の詳細は以下のドキュメントをご参照ください。
2つめのコンテキスト取得方法はスーパーバイザークラスタから TKC のコンテキストファイルを取得するというものです。以下に新規クラスタを作成して、それを使うサンプルを記載します。
重要なのは「kubectl get secret」の操作で、シークレット名「<TKCクラスタ名>-kubeconfig」が持つ値を取得し、それを base64 デコードしてファイルにリダイレクトしています。
このファイルに書かれている内容は kubeconfig ですので、それをオプション「–kubeconfig」で指定したり、環境変数「KUBECONFIG」にセットするなりして、該当の TKC のコンテキストで操作をすることができます。
2つめのコンテキスト取得手法の詳細は以下のドキュメントをご参照ください。
Connect to the Tanzu Kubernetes Cluster Control Plane as the Administrator
Kubernetesクラスタの水平スケールと垂直スケール
次にライフサイクル管理の一環として、クラスタのパフォーマンス向上を実施します。このやりかたとしては大きく以下の2種類があります。
- 水平スケール: ノードの台数を増減させる
- 垂直スケール: ノード1台あたりのスペック(CPU/メモリ)を上下させる
k8s としては前者のほうが一般的ですが、vSphere with Tanzu では両者ともクラスタ構成のYAMLを更新して再適用することで簡単に実現できます。
まず最初に水平スケールでTKCのワーカーノードの数を3から5に増やす操作を実施します。
この操作は Deployment でポッド数を増やす操作と大差ありません。YAMLに定義されている workers の count を3から5に変更し、スーパーバイザクラスタのネームスペースコンテキスト(yuichi)で kubectl apply でリソースを更新するだけです。TKCのコンテキストで実施する操作ではないのでご注意ください(実施しても害のないエラー表示がされるだけです)。
この操作で図の右にあるようにスーパーバイザクラスタが管理するTKCのワーカーノード数が3から5に増加しています。この操作の裏側では vSphere が新たに仮想マシン2台をワーカーノードとして作成してTKCに追加していますが、その作業はユーザには隠蔽されています。ノード数を削減するのも「5 -> 3」などとするだけなので、ここでは割愛します。当然ながらノード削減時に削除されるノード上のコンテナは、他の残るノード上に退避(再起動)されます。
次に垂直スケールでTKCのワーカーノード1台あたりのメモリを2Gから4Gに増加させます。これもクラスタの定義ファイルにあるマシン定義を更新して適用するだけです。マシン定義の詳細は以下のドキュメントにあります。
Tanzu Kubernetes クラスタの仮想マシンのクラス タイプ
今回であればワーカーノードのマシン定義を「best-effort-xsmall」から「best-effort-small」に変更することで、ノードのメモリを2Gから4Gに増加させています。
この操作をすると、「新しくメモリが4Gのワーカーノードを作成してTKCに追加し、追加された1つぶんの既存のメモリが2Gのワーカーノードを削除。この操作をTKCの全ワーカーノードのメモリが4Gになるまで繰り返す」という動作でノードのメモリが4Gに変更されます。ローリング形式でマシンを徐々に変更していくため、クラスタのワークロードは停止しません。
なお、垂直スケールの操作は水平スケールに比べて時間がかかりますし、k8s 的にはあまり一般的ではありません。必要なリソースを持つノードを最初から作成して、水平スケールでパフォーマンス調整を実施することを基本としてください。
この項目の詳細は以下のドキュメントをご参照ください。
Kubernetesクラスタのバージョンアップ
次のライフサイクル管理は TKC の kubernetes バージョンアップです。これはスーパーバイザークラスタ(アップグレード可能だが別手順)ではなく、アプリを動かす TKC のバージョンです。バージョンダウンは一般的な k8s と同様にサポートされていません。
TKC のバージョンアップもクラスタ定義の YAML を更新して適用することで実現できます。ここでは「kubectl apply」ではなく、ドキュメントに記載のある「kubectl edit」による手法で更新してみます。
まず、アップグレード可能なバージョンを「kubectl get tanzukubernetesreleases」コマンドで確認しています。現在利用しているバージョン(kubectl get nodes で確認可能)は 1.18.15 なので、今回はアップグレード可能な 1.19.7 に変更します。一般的な k8s がそうであるように、マイナーバージョンは1つごとしかアップグレードできません。そのため、1.18.15から1.20.2にしたければ、1.19.7を挟む必要があります。
kubectl edit コマンドでリソース種類(tanzukubernetescluster)とリソース名(worker)を指定して編集しています。fullVersion を null にし、version に使いたいバージョン(v1.19.7)を与えています。厳密にバージョン指定したい場合は fullVersion 側に先ほど確認できたバージョンの正式名を書き、それに対応するバージョンを version に記載してください。
edit を終了するとリソースが更新されるので、自動でクラスタのアップグレードが開始されます。これも垂直スケール時と同様にローリング形式で実施されますが、一般的な k8s のアップグレードと同様にマスターを更新してからワーカーを更新という手順で内部的に動いています。
1ノードあたり5-10分ほど時間がかかります。
余談となりますが、kubernetes 上のアプリの可搬性を保証するのであれば「アプリが動いているクラスタのバージョンアップをする」のではなく「アプリを新規構築した新バージョンのクラスタに移す」という対応を習慣化してもよいかもしれません。アプリを別クラスタに移行できることが分かっているのであれば構いませんが、長く1つのクラスタを使い続けることで「このアプリはこの kubernetes クラスタでしか動かない」「アプリのデータ(PVCで利用)を動かせない」などとならないようにご注意ください。
この項目の詳細は以下のドキュメントをご参照ください。
Kubernetes バージョンのアップグレードによる Tanzu Kubernetes クラスタのアップデート
Kubernetes クラスタの削除
当記事で取り上げるライフサイクル管理の最後の作業はクラスタの削除です。これはポッドやデプロイメントと同様にクラスタリソースを「kubectl delete」で削除することで実施できます。
この操作をすることでクラスタが削除されるだけでなく、それを構成していた vSphere 上の仮想マシンやデータストアリソース、およびロードバランサー(NSX-ALB)のVIPの開放なども自動で実施されますのでゴミは残りません。
この項目の詳細は以下のドキュメントをご参照ください。