Zadara での Kubernetes: ブログシリーズ #3

Kubernetes の新しいブログシリーズの 3回目へようこそ!このシリーズでは、Zadara でのKubernetes デプロイの世界と、Zadara の AWS 互換クラウドでコンテナ化されたアプリケーションを管理するために Kubernetes をどのように使用できるかを探ります。このシリーズでは、Kubernetes が初めての方にも、経験豊富な方にも、Zadara クラウドでコンテナ化されたアプリケーションを管理するための貴重な洞察とベストプラクティスを提供します。さらなるエキサイティングなコンテンツにご期待ください!

 

このブログ記事では、Kubernetes クラスタ上で実際のワークロードを実行することに焦点を当てます。WordPress(有名なブログ・コンテンツ管理プラットフォーム)をデプロイすることで、Zadara クラウド上の Kubernetes のパワーを紹介し、ネイティブの Kubernetes 機能だけでなく、当社の EKS-D ビルトインアドオンによるシームレスなクラウド統合も紹介します。

 

WordPress のデプロイ

このデモでは、Wordpress 用の Bitnami Helm チャートを使用します。Bitnami のチャートは文書化され、エンタープライズ対応のプロダクショングレードのデプロイソリューションとして知られており、WordPress チャートはそのようなユースケースの完璧な例です。WordPress チャートには、WordPress 自体に加えて、データベース(MariaDB)、キャッシュストア(Memcached)、およびこのデモの一部として使用するロードバランシングやスケーリング指向オプションなどの Bitnami のその他の機能が含まれています。

 

以下の図は、チャートのデフォルトの内容を簡略化して表したもので、ServiceAccount や Secrets など、クラウド統合に関係のないリソースは省略してあります。

WordPress 自体は Kubernetes Deployment(memcached の PVC にリンク)であるのに対し、MariaDB は Kubernetes StatefulSet(データベースの PVC にリンク)であることに注意してください。どちらも通信に Kubernetes Services を使用していますが、MariaDB は内部の ClusterIP(WordPress によって消費される)を使用しているのに対し、WordPress 自体はLoadBalancer(外部ユーザーによって消費される)を使用しています。

 

まずは、作成されるすべてのリソースを確認するために、値を変更せずに Helm チャートをそのままデプロイします。kubectl が(KUBECONFIG 環境変数やその他の方法で)Kubernetes クラスタで動作するように設定されていると仮定します。Helm も呼び出す時に同じ設定を利用します。

helm install wp oci://registry-1.docker.io/bitnamicharts/wordpress --namespace wordpress --create-namespace
 これにより、WordPress のチャートがすべてのデフォルト値とともに、wordpress 名前空間内に “wp “という名前の Helm リソースとしてインストールされます(存在しない場合は作成されます)。
 

wordpress ネームスペース内で、チャートによっていくつかのリソースが作成されているのが分かります。以下に、前述のアーキテクチャ図で言及した Pod、PVC、Service を示します。

Pod は k8s-worker-1 で実行するようにスケジュールされていますが、まだ準備ができていなません。

 

Pod の準備ができると WordPress にアクセスできるはずです。通常であれば、先ほど作成された LoadBalancer Service を通してアクセスすることになりますが、一つ注意点があります。Helm charts のデフォルトでは特に指定がない限り、AWS Load Balancer Controller(Kubernetes のリソースをクラウド上の Load Balancer に変換する役割)は、パブリック向けの Load Balancer ではなく、インターナルの Load Balancer を作成します。これは設計上の AWS API の制限で、Zadara の互換 API はこれを再現しているためロードバランサーは内部 IP と DNS しか持たなくなります。

このロードバランサーは VPC の外では使えませんが、ターゲットグループを見ることができ、関連するポートリクエストを関連するワーカーノードのポート(例えばポート80)に転送しているのが確認できます。

同様な情報を Kubernetes 側からも見ることができます。Kubernetes は各ワーカーノードでこれらのポートを管理し、着信するトラフィックをリッスンし、関連する Pod の IP(エンドポイント)に転送します。

現段階では、WordPress は Kubernetes クラスタ内で実行されているので、ロードバランサーを使用する唯一の方法は、bastion VM のような VPC 内の別の VM を経由することになります。ローカルブラウザから WordPress を利用するために(bastion VM を経由するか、Kubernetes Pod 上で直接)ポートフォワードを行うこともできますがそれはアプリケーションを利用する本当の方法ではありません。インターナルロードバランサーではなく、パブリック向けのロードバランサーが必要です。

 

ロードバランサー (再考)

Kubernetes Service がどのようにクラウドの NLB(Network Load Balancer)に変換されるかを見てきましたが、Kubernetes も AWS/Zadara も既存の Service/NLB を変更することはできません。別の方法として、既存の Service を削除し(NLB も削除されます)、Helm リリースを関連する設定で更新して(専用の設定ファイルを使用して)、パブリック向けのロードバランサーを作成します。

kubectl delete service wp-wordpress --namespace wordpress
cat > ./values-wordpress.yaml << "EOF"
service:
annotations:
  service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
EOF
helm upgrade wp oci://registry-1.docker.io/bitnamicharts/wordpress --namespace wordpress -f values-wordpress.yaml

ここでは、Helm charts のドキュメントに記載されているように、chart の元プロパティに基づいて設定ファイルを作成し、新しい NLB がパブリックからアクセスできるように、ロードバランサーコントローラーのサービスドキュメントに従って、アノテーションにインターネットに面した値を使用しました。

 

数分以内に、新しいロードバランサは使えるようになるはずです。Service アノテーションはその動作を制御するために使われるので、今回はより広いインターネットからアクセスするために使われるパブリック IP アドレスを持つことになります。

 

AWS とは異なり、Zadara クラウドはパブリック DNS サービスを提供していないため、外部DNS 名を使用できないことに注意してください。しかし、独自の DNS プロバイダーにこのパブリック IP の A レコードを作成するか、インターネットからアプリケーションにアクセスするために直接使用することができます。 

 

 

この例で、ブラウジングにセキュアな接続を使用していないことにお気づきかもしれません。IP を直接使用しており、Zadara の NLB は現在ドメイン証明書をサポートしていないからです。しかし、これはサービスではなく Ingress リソースを通して Kubernetes とやり取りする ALB(レイヤー 7 ロードバランサー)を導入する絶好の口実となるでしょう。レイヤー 7 のようなロードバランサーはドメイン証明書をサポートしているので、証明書をクラウドにインポートし、後で Ingress リソースを定義するときにそれを使うことができます。

 

現在のロードバランササービスを削除し、チャートのドキュメントとロードバランサコントローラの Ingress ドキュメントに基づいて Helm の設定ファイルを再度設定して、この証明書IDを使用するインターネットに面した Ingress リソースを作成します。

kubectl delete service wp-wordpress --namespace wordpress
cat > ./values-wordpress.yaml << "EOF"
service:
type: NodePort
ingress:
enabled: true
annotations:
alb.ingress.kubernetes.io/certificate-arn: 68b5f357-b25f-4a07-aa8b-2797305a57db
alb.ingress.kubernetes.io/scheme: internet-facing
hostname: wordpress
path: /*
EOF
helm upgrade wp oci://registry-1.docker.io/bitnamicharts/wordpress --namespace wordpress -f values-wordpress.yaml

LoadBalancer サービスをそのままにしておくこともできますが、その代わりに NodePort サービス(クラウドのロードバランサーではなく、ノードレベルのポート設定)に切り替えても、クラウドのリソースを消費することなく同じことができます。

今回のロードバランサーはインターネットに面した ALB で、HTTPS プロトコルでリッスンします。

 

ALB は、証明書とチャートで定義された他のコンフィギュレーション(例えば、アプリケーションに到達するためにはホスト名が “wordpress “でなければなりません。)に対応するリスナールールであらかじめ定義されています。

 

証明書は正しいドメイン名で使用された場合のみ有効で、ALB は「wordpress」以外のホスト名を許可しません。セキュアなソリューションを完成させるためには、DNS プロバイダーにこのパブリック IP の A レコードを作成する必要があります。一度設定すれば、https://wordpress.zadara-qa.com への接続がセキュアになったことを確認できます。

 

Kubernetes のスケーリング

Kubernetes は、ニーズの変化に対応するために環境を動的にスケールするさまざまな方法を提供します(たとえば、ピークロード時にアプリケーションが応答するようにするなど)。ここでは、クラウド統合を利用する方法、つまり、ニーズに合わせてデータプレーン(ワーカー ASG )ノードをスケールアウト/スケールインする方法のデモにのみ焦点を当てます。その他の方法論(水平/垂直ポッドスケーリングやポッドアンチアフィニティルールなど)は Kubernetes クラスタ内部のものなのでこのデモでは取り上げません。

 

クラスタを強制的にスケールさせる1つの方法は、現在のワーカーノードが新しいポッドを受け入れないように凍結(cordon)し、新しい Pod を作成することです。たとえば、レプリカカウントを 2 に設定することで、MariaDB StatefulSet をシングル Pod セットアップからマルチ Pod にスケールアップするように要求します。

kubectl cordon k8s-worker-1
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
kubectl scale --replicas=2 statefulset/wp-mariadb --namespace wordpress
kubectl get pods,pvcs --namespace wordpress

ワーカーノードが NoSchedule のテイントを持つことがわかります(マスターノードも同様に持っていますが理由は異なります)。

新しい Pod は実行可能なノードを待っているためペンディング状態にあり、同様に新しい PVC もポッドをペンディングしていることがわかります(EBS CSI が関連インスタンスへのボリュームのアタッチを保留するため)。

 

EKS-D にはあらかじめクラスタオートスケーラアドオンが搭載されているため、利用可能なノードでスケジュールされていない保留中の Pod をリッスンし、それに応じてワーカーの ASG の希望容量を設定済の最小値と最大値の間で変更します。

 

ASG はこの信号を受信し、ASG が希望するキャパシティを更新することで、新しいワーカーインスタンスを作成します。

 

数分以内に、新しいワーカーノードが Kubernetes クラスタに加わり準備が整います。そして、Pod は最終的に利用可能なノードにスケジューリングされるため、新しい PVC はこのノードにアタッチされた新しいボリュームにバインドされます。

 

スケールインについて心配な場合は、いつでも最初のワーカーの凍結を解除して 10 分間待つことができます(スケールイン前のデフォルトのクラスタオートスケーラの非アクティブウィンドウ)。追加のノードは(削除候補であるため)PreferNoSchedule のテイントを取得し、スケールインウィンドウの期限になる時に 2つ目の MariaDB Pod は自動的に最初のワーカーノード(その PVC とアンダーラインボリュームを含む)に移動されるため、ノードを安全に削除することができます。

 

永続性について 

このデモ全体を通じて、このアプリケーションにはストレージが必要であるという事実を当然としてきしました。その理由は、特に明記されていない限り、すべての永続性要件に対して暗黙的に StorageClass がすぐに使えるデフォルトの EBS CSI 構成となっているからです。

実際、Helmチャートの一部として作成されたPVCはすべて、対応するボリューム(アプリケーションポッドも保持する同じワーカーノードにアタッチされている)にバインドされている:実際、Helm charts の一部として作成された PVC はすべて、対応するボリューム(アプリケーション Pod も保持する同じワーカーノードにアタッチされている)にバインドされています。

 

デフォルトで有効になっている EBS CSI のもう一つの機能は、既存の PVC に要求された容量サイズを拡張する機能です。Helm リリースを更新するか、既存の PVC に直接手動でパッチを当てることでサイズを変更できます。どちらの方法でも、リクエストの後に既存の PV が拡張され PVC サイズに新しいサイズが反映されます。

 

このように、wordpress のボリュームが 10GB から 12GB に拡張されました。仕様上、拡張できるのは既存の PVC のみであることに注意してください(サイズを小さくすることはできません)。しかし、これもシームレスなクラウド統合なので心配する必要はありません。EKS-D が処理してくれます.

まとめ

このブログポストでは、標準的なツールと手法を使用して、典型的な Kubernetes ワークロードとして WordPress をデプロイしました。Helm はデプロイ自体を処理し、組み込みの EKS-D アドオンは、Volumes、Load Balancers、Auto-Scaling Groups などのクラウドリソースを処理するためのシームレスな統合を提供しました。ワークロードが稼働し始めたので、次回のブログポストではバックアップとリストアのユースケースについて説明したいと思います!

 

Share This Post

More To Explore