Kubernetes で、お使いのアプリケーションの安定および確実な実行を保証するため、このトピックでは推奨される Kubernetes クラスターの設定を紹介します。
ディスクタイプとディスクサイズの設定
ディスクタイプの選択
- SSD ディスクタイプの選択を推奨します。
- ワーカーノードでは、クラスター作成時に [データディスクの接続] チェックボックスをオンにすることを推奨します。 このディスクは、ローカルイメージの保存のために /var/lib/docker に排他的に提供されます。 ルートディスクに莫大な数のイメージを保存することができるように設計されています。 お使いのクラスターをひと通り実行した後は、必要のない多くのイメージが保存されたままになります。 この状態を素早く解決するために、マシンをオフラインにし、このディスクを再構築してから、マシンをオンラインに戻すことを推奨します。
ディスクサイズの設定
Kubernetes ノードは大きなディスクスペースを必要とします。これは、Docker イメージ、システムログおよびアプリケーションログがディスクに保存されるためです。 Kubernetes クラスター作成時、それぞれのノードのポッド数、それぞれのポッドのログサイズ、イメージサイズ、一時データサイズ、およびシステムが確保済みの値に必要なスペースを考慮する必要があります。
ECS インスタンスオペレーションシステムには 8 GiB のスペースを確保することを推奨します。これは、オペレーションシステムが少なくとも 3 GiB のディスクスペースを必要とするためです。 Kubernetes リソースオブジェクトは残りのディスクスペースを使用します。
クラスター作成時のワーカーノード構築オプション
- 従量課金 は、クラスター作成時にワーカーノードの構築が可能であることを示しています。
- サブスクリプション は、クラスター作成後に、必要に応じて ECS インスタンスを購入し、お使いのクラスターに ECS インスタンスを追加することができます。
お使いのクラスターネットワーク設定の構成
- お使いのクラスターを、たとえば RDS (Relational Database Service) などの Kubernetes 外部のサービスと接続する場合、新しく VPC を作成するよりも、既存の VPC を使用することを推奨します。 これは、VPC が論理的に分離されているからです。 VSwitch の作成および、Kubernetesを実行する ECS インスタンスを VSwitch に追加することができます。
- Kubernetes クラスター作成時に、Terway ネットワークプラグインまたは Flannel ネットワークプラグインを選択できます。 詳しくは、「Kubernetes クラスターネットワークには、Terway または Flannel プラグインのどちらを選択するべきですか ?」をご参照ください。
- 最小数のノードのみをサポートするポッドネットワークの小さな CIDR ブロックを設定することは推奨しません。 ポッドネットワークの CIDR ブロック設定は、[高度な設定] の [ノードへのポッド数] と関連付けられています。 たとえば、ポッドネットワークの CIDR ブロックを "X.X.X.X/16" と設定した場合、これは、お使いのクラスターに割り当てられた IP アドレス数が 256*256 となることを意味しています。 加えて、それぞれのノードに対してポッド数を 128 に設定した場合、お使いのクラスターによりサポートされる最大ノード数は 512 となることを意味しています。
複数のゾーンの利用
Alibaba Cloud では、複数のリージョンをサポートし、それぞれのリージョンが複数のゾーンをサポートしています。 ゾーンは、リージョン内に独立したパワーグリッドおよびネットワークを持った物理エリアです。 複数のゾーンを利用することで、エリア間のディザスタリカバリが有効になりますが、ネットワーク遅延は増加します。 Kubernetes クラスター作成時、マルチゾーンクラスターの作成を選択できます。 詳しくは、「マルチゾーン Kubernetes クラスターの作成」をご参照ください。
それぞれのポッドへのリソース要求
Kubernetes クラスター作成時、1 つのノードに対し多すぎるポッドがスケジューリングされてしまうことが共通の問題点として挙げられます。 このようなポッドのスケジューリングはノードのオーバーロードの原因になり、サービスの提供を不可能にします。
Kubernetes でのポッドの設定時に、リソースリクエストパラメーターおよびリソース制限パラメーターの設定を推奨します。 この推奨される設定により、ポッドのデプロイ時にポッドリソース要件に応じた十分なリソースを持ったノードを Kubernetes が選択できるようになります。 以下の例では、Nginx ポッドが 1 コア CPU および 1024 MiB メモリーを使用し、2 コア CPU または 4096 MiB メモリより大きなリソースを使用できないように要求します。
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
Resources: # リソース要求
requests:
memory: "1024Mi"
cpu: "1000m"
limits:
memory: "4096Mi"
cpu: "2000m"
Kubernetes は静的リソーススケジューリングメソッドを使用します。これは、それぞれのノードに残っているリソースにより算出された量のリソースを使う代わりに、Kubernetes
に対し割り当てられたリソースを使うことを意味します。 算出方法は、残りのリソース = 全体のリソース - 割り当てられたリソース
となります。 手動でリソース使用プログラムを実行する場合、Kubernetes はプログラムで使用されているリソースに対応しません。
そのため、すべてのポッドに関する要求が必要です。 リソース要求を持たないポッドには、ノードにスケジューリングされた後、Kubernetes は、対応するノード上のリソース要求を持たないポッドにより使用されるリソースが、まだ使用可能であるとみなします。 そのため、このノードに対して多すぎるポッドがスケジューリングされることになります。
クラスター操作および管理設定の構成
- Log Service の有効化
クラスター作成時、[Log Service の利用] チェックボックスをオンにします。
- クラスターモニタリングの設定
Alibaba Cloud Container Service は CloudMonitor と統合されています。 ノードのモニタリングを設定することにより、リアルタイムモニタリングが実装できます。 モニタリングアラームルールを追加することにより、異常なリソース使用率を引き起こしている問題を素早く特定できます。
Container Service を通じて Kubernetes クラスターを作成する際、2 つのアプリケーショングループが自動的に CloudMonitor に作成されます。1 つはマスターノード、もう 1 つはワーカーノードです。 これらの 2 つのグループでアラームルールを追加でき、追加したルールをグループ内のすべてのマシンに適用できます。 対応するグループに後続のノードが追加された場合、そのグループのアラームルールが自動的に適用されます。これは、ECS リソースに関してのみアラームルールを設定する必要があることを意味しています。注- ECS インスタンスのモニターのために、CPU、メモリーおよびディスク のようなリソースに対してアラームルールを設定する必要あります。 排他的なディスク上に /var/lib/docker を設定することを推奨します。
起動後に依存関係のあるアプリケーションに対してアプリケーションを待機させる設定
アプリケーションの中には、いくつかの外部依存関係を持つことものがあります。 たとえば、アプリケーションによっては、データベース (DB) からのデータの読み込みや、他のサービスのインターフェイスへのアクセスなどが必要になります。 しかし、アプリケーション起動時に DB またはインターフェイスが利用できないことがあります。 従来の手動 O&M において、アプリケーション起動時に外部依存関係が利用できない場合、アプリケーションがすぐに終了してしまいます。これは "failfast" として知られています。 この戦略は Kubernetes には応用できません。Kubernetes での O&M は自動化されており、手動介入が要求されないためです。 たとえば、アプリケーションをデプロイした場合、手動でノードを選択し、ノードのアプリケーションを起動する必要はありません。 アプリケーションエラーの場合、Kubernetes は自動的にアプリケーションを再起動します。 加えて、大きな負荷が発生した際には HPA による自動的な容量増加がサポートされます。
たとえば、アプリケーション A がアプリケーション B に依存し、これら 2 つのアプリケーションが同一ノードで実行されると仮定します。 ノードの再起動後、アプリケーション A が起動し、アプリケーション B が起動済みではありません。 このケースでは、アプリケーション A の依存関係は利用できません。 "failfast" の戦略によれば、アプリケーション A が存在し、かつ、アプリケーション B の起動後でもアプリケーション A は起動しません。 このようなケースでは、アプリケーション A を手動で起動する必要があります。
Kubernetes では、システムに対し、起動中にアプリケーションの依存関係を確認するように設定することができ、依存関係が有効になるまで待機するようポーリングを実装することができます。 これは、『Init Container』 を通じて実装されます。
ポッドの再起動ポリシーの設定
コード上のバグや過剰なメモリー消費によりアプリケーション処理にエラーが起こった場合、処理があるポッドも同様にエラーになります。 エラー後に自動的にポッドが再起動するように、ポッドに対して再起動ポリシーを設定することを推奨します。
apiVersion: v1
kind: Pod
metadata:
name: tomcat
spec:
containers:
- name: tomcat
image: tomcat
restartPolicy: OnFailure #
再起動ポリシーパラメーターでの利用可能な値は以下のようになります。
- Always: 常にポッドを自動的に再起動します。
- OnFailure: ポッドがエラーの場合 (処理の終了ステータスが 0 でない場合) に自動的にポッドが再起動されます。
- Never: ポッドを再起動させません。
Liveness プローブと Readiness プローブの設定
ボッド上の処理がロックされることがあるため、実行中のポッドはサービスを提供できないことがあります。 しかし、ポッドが実行中であるため、Kubernetes により自動的にポッドが再起動されることはありません。 そのため、それぞれのポッドに Liveness プローブを設定し、ポッドが起動中であるか、またポッドがサービスを提供できる状態かを判断します。 Liveness プローブが例外を検出したとき、Kubernetes によりポッドが再起動されます。
Readiness プローブは、ポッドがサービスを提供できる状態かを検出すために使用されます。 起動時にアプリケーションの初期化のために時間がかかります。 初期化中、アプリケーションはサービスを提供できません。 Readiness プローブは、ポッドが Ingress またはサービスからトラフィックの受信準備ができている状態を検出できます。 ポッドに問題がある場合、Readiness プローブはポッドに転送される新しいトラフィックを停止させます。
apiVersion: v1
kind: Pod
metadata:
name: tomcat
spec:
containers:
- name: tomcat
image: tomcat
livenessProbe:
httpGet:
path: /index.jsp
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
httpGet:
path: /index.jsp
port: 8080
それぞれのコンテナー上で実行する 1 つの処理の設定
- 全体としてのポッドのリソース使用率の決定を複雑にし、効果的なリソース制限の設定を難しくします。
- コンテナーで 1 つの処理のみが実行されている場合、コンテナーエンジンは処理エラーを検出でき、それぞれの処理エラーに対してコンテナーを再起動させます。 しかし、コンテナーに複数の処理がある場合、コンテナーエンジンはどのようなプロセスのエラーも検出できません。 そのため、1 つだけの処理がエラーとなり、コンテナーが正常に稼働していないとしても、エンジンはコンテナーを再起動させません。
同時に複数の処理を実行したい場合、Kubernetes により簡単に同時複数処理を実装させることができます。 たとえば、Nginx と php-fpm がお互いに Unix ドメインソケットで通信しています。 2 つのコンテナーを含むポッドを使用し、2 つのコンテナーの共有ボリュームに対し Unix ソケットを配置することができます。
SPOF (Single Point of Failure) の回避
アプリケーションが 1 つの ECS インスタンスのみ使用する場合、インスタンスエラーによる Kubernetes の再起動中は、アプリケーションを利用できません。 この問題は、更新されたアプリケーションのリリース時にも発生します。 そのため、Kubernetes 上でポッドを直接使用しないことを推奨します。 代わりに、デプロイアプリケーションや StatefulSet アプリケーションをデプロイし、それぞれのアプリケーションに対して 3 つ以上のポッドを設定します。