第2章 インフラストラクチャーコンポーネント
2.1. Kubernetes インフラストラクチャー
2.1.1. 概要
OpenShift Container Platform 内で、Kubernetes はコンテナーのセット全体でコンテナー化されたアプリケーションを管理し、デプロイメント、メンテナーンス、およびアプリケーションののメカニズムを提供します。コンテナーのランタイムは、コンテナー化されたアプリケーションのパッケージを作成してインスタンス化し、実行します。Kubernetes クラスターは 1 つ以上のマスターおよびノードセットで設定されます。
オプションとして、高可用性 (HA) のマスターを設定し、クラスターから単一障害点がなくなるようにします。
OpenShift Container Platform は Kubernetes 1.11 および Docker 1.13.1 を使用します。
2.1.2. マスター
マスターは、API サーバー、コントローラーマネージャーサーバー、および etcd などのコントロールプレーンのコンポーネントが含まれるホストです。マスターはその Kubernetes クラスターでノードを管理し、Podがノードで実行されるようスケジュールします。
コンポーネント | 説明 |
---|---|
API サーバー | Kubernetes の API サーバーは、Pod、サービス、レプリケーションコントローラーのデータを検証し、設定します。さらに Pod をノードに割り当て、Pod の情報をサービス設定に同期します。 |
etcd | etcd は、コンポーネントが etcd で必要な状態に戻すための変更の有無を確認する間に永続マスター状態を保存します。etcd は、通常 2n+1 ピアサービスでデプロイされるなど、高可用性のためにオプションで設定できます。 |
コントローラーマネージャーサーバー | コントローラーマネージャーサーバーは、レプリケーションコントローラーのオブジェクトに変更がないか etcd を監視し、API を使用して希望とする状態を有効化します。このような複数のプロセスは、一度に 1 つのアクティブなリーダーを設定してクラスターを作成します。 |
HAProxy |
オプションで、高可用性のマスターを |
2.1.2.1. コントロールプレーンの静的 Pod
コントロールプレーンのコンポーネント、API サーバーおよびコントローラーマネージャーのコンポーネントは、kubelet で操作される 静的 Pod として実行されます。
etcd が同じホストに共存しているマスターでは、etcd も静的 Pod に移動されます。RPM ベースの etcd は依然として、マスターではない etcd ホスト上でサポートされます。
さらに、ノードコンポーネントの openshift-sdn と openvswitch が systemd サービスではなく、DaemonSet を使用して実行されます。
図2.1 コントロールプレーンホストのアーキテクチャーの変更
マスターおよびノードの設定 のトピックに記載されているように、静的 Pod として実行中のコントロールプレーンのコンポーネントの場合でさえも、マスターホストは /etc/origin/master/master-config.yaml ファイルからの設定をソースとして使用します。
起動シーケンスの概要
Hyperkube は、すべての Kubernetes (kube-apiserver、controller-manager、scheduler、proxy、および kubelet) を含むバイナリーです。起動時に、kubelet は kubepods.slice を作成します。次に、kubelet は kubepods.slice 内に QoS レベルのスライス burstable.slice と best-effort.slice を作成します。Pod が開始されると、kubelet は pod<UUID-of-pod>.slice
形式で Pod レベルのスライスを作成し、そのパスを Container Runtime Interface (CRI) の反対側のランタイムに渡します。次に、Docker または CRI-O は、Pod レベルのスライス内にコンテナーレベルのスライスを作成します。
Pod のミラーリング
マスターノード上の kubelet は自動的に、コントロールプレーンの静的 Pod ごとに、API サーバー上に ミラーの Pod を作成し、kube-system プロジェクトのクラスターで表示できるようにします。これらの静的 Pod のマニフェストは、デフォルトで、マスターホスト上の /etc/origin/node/pods ディレクトリーに配置されている openshift-ansible インストーラーによりインストールされます。
これらの Pod は、以下の hostPath
ボリュームを定義します。
/etc/origin/master | すべての証明書、設定ファイル、admin.kubeconfig ファイルが含まれます。 |
/var/lib/origin | バイナリーの潜在的なコアダンプとボリュームが含まれます。 |
/etc/origin/cloudprovider | クラウドプロバイダー固有の設定 (AWS、Azure など) が含まれます。 |
/usr/libexec/kubernetes/kubelet-plugins | 追加のサードパーティーのボリュームプラグインが含まれます。 |
/etc/origin/kubelet-plugins | システムコンテナーに向けた追加のサードパーティーのボリュームプラグインが含まれます。 |
静的 Pod で実行できる一連の操作は制限されています。以下に例を示します。
$ oc logs master-api-<hostname> -n kube-system
API サーバーからの標準出力を返します。ただし、
$ oc delete pod master-api-<hostname> -n kube-system
上記のコマンドでは実際には Pod は削除されません。
別の例として、クラスター管理者は、API サーバーの loglevel
を増やすなど、一般的な操作を実行して、問題が発生した場合により詳細なデータを参照できるようにする場合があります。コンテナー内で実行中のプロセスに渡せるように、/etc/origin/master/master.env ファイルを編集して、OPTIONS
変数の --loglevel
パラメーターを変更する必要があります。変更を適用するには、コンテナー内で実行中のプロセスを再起動する必要があります。
マスターサービスの再起動
コントロールプレーンの静的 Pod で実行中のコントロールプレーンサービスを再起動するには、マスターホストの master-restart
コマンドを使用します。
マスター API を再起動します。
# master-restart api
コントローラーを再起動します。
# master-restart controllers
etcd を再起動します。
# master-restart etcd
マスターサービスログの表示
コントロールプレーンの静的 Pod で実行中のコントロールプレーンサービスのログを表示するには、適切なコンポーネントの master-logs
コマンドを使用します。
# master-logs api api
# master-logs controllers controllers
# master-logs etcd etcd
2.1.2.2. 高可用性マスター
オプションとして、高可用性 (HA) のマスターを設定し、クラスターから単一障害点がなくなるようにします。
マスターの可用性についての懸念を少なくするために、2 つのアクティビティーを実行することが推奨されます。
- runbook エントリーは、マスターの再作成のために作成される必要があります。runbook エントリーは、いずれの高可用性サービスに対しても必要なバックアップです。追加ソリューションは、runbook が参照される頻度を制御するのみです。たとえば、マスターホストのコールドスタンドバイは新規アプリケーションの作成または失敗したアプリケーションコンポーネントの復元に 1 分未満のダウンタウンのみを要求する SLA を十分に満たせる可能性があります。
-
高可用性ソリューションを使用してマスターを設定し、クラスターに単一障害点がなくなるようにします。クラスターのインストールに関するドキュメントでは、
native
HA 方法を使用し、HAProxy を設定した具体的なサンプルについて説明します。さらに、これらの概念を採用し、HAProxy ではなくnative
方法を使用して既存の HA ソリューションに対して適用できます。
実稼働の OpenShift Container Platform クラスターでは、API サーバーのロードバランサーの高可用性を維持する必要があります。API サーバーのロードバランサーを利用できない場合、ノードはそれらのステータスを報告できず、それらの Pod すべてに dead (実行不可能) のマークが付けられます。 また、Pod のエンドポイントはサービスから削除されます。
HA (高可用性) を OpenShift Container Platform に設定するほかに、HA を API サーバーのロードバランサーに別途設定する必要があります。HA を設定するには、F5 Big-IP™ または Citrix Netscaler™ アプライアンスなどのエンタープライズロードバランサー (LB) を統合する方法が推奨されます。このようなソリューションが利用できない場合、複数の HAProxy ロードバランサーを実行し、Keepalived を使用して HA の浮動仮想 IP アドレスを指定することができます。ただし、このソリューションは実稼働インスタンスでは推奨されません。
native
HA 方式を HAProxy で使用する際に、マスターコンポーネントには以下の可用性があります。
ロール | スタイル | 注記 |
---|---|---|
etcd | アクティブ/アクティブ | ロードバランシング機能のある完全に冗長性のあるデプロイメントです。別個のホストにインストールすることも、マスターホストに共存させることもできます。 |
API サーバー | アクティブ/アクティブ | HAProxy で管理されます。 |
コントローラーマネージャーサーバー | アクティブ/パッシブ | 一度に 1 つのインスタンスがクラスターリーダーとして選択されます。 |
HAProxy | アクティブ/パッシブ | API マスターエンドポイント間に負荷を分散します。 |
クラスター化された etcd では定足数を維持するためにホストの数は奇数である必要がありますが、マスターサービスには定足数やホストの数が奇数でなければならないという要件はありません。ただし、HA 用に 2 つ以上のマスターサービスが必要になるため、マスターサービスと etcd を共存させる場合には、一律奇数のホストを維持することが一般的です。
2.1.3. ノード
ノードはコンテナーのランタイム環境を提供します。Kubernetes クラスターの各ノードには、マスターで管理される必須のサービスが含まれます。また、ノードには、コンテナーランタイム、kubelet、サービスプロキシーなど、Pod の実行に必要なサービスも含まれます。
OpenShift Container Platform は、ノードをクラウドプロバイダー、物理システムまたは仮想システムから作成します。Kubernetes は、それらのノードの表現である ノードオブジェクト と対話します。マスターはノードオブジェクトの情報を使ってヘルスチェックでノードを検証します。ノードはこれがヘルスチェックをパスするまで無視され、マスターはノードが有効になるまでチェックを継続します。Kubernetes ドキュメント にはノードのステータスと管理についての詳細が記載されています。
管理者は CLI を使用して OpenShift Container Platform インスタンスでノードを管理できます。ノードサーバーの起動時に完全な設定およびセキュリティーオプションを定義するには、専用のノード設定ファイル を使用します。
ノードの推奨される最大数については、cluster limits のセクションを参照してください。
2.1.3.1. Kubelet
各ノードには、Pod を記述する YAML ファイルであるコンテナーマニフェストで指定されるようにノードを更新する kubelet があります。kubelet は一連のマニフェストを使用して、そのコンテナーが起動しており、継続して実行することを確認します。
コンテナーマニフェストは以下によって kubelet に提供できます。
- 20 秒ごとにチェックされるコマンドのファイルパス。
- 20 秒ごとにチェックされるコマンドラインで渡される HTTP エンドポイント。
- /registry/hosts/$(hostname -f) などの etcd サーバーを監視し、変更に作用する kubelet。
- HTTP をリッスンし、単純な API に対応して新規マニフェストを提出する kubelet。
2.1.3.2. サービスプロキシー
各ノードは、ノード上で API で定義されるサービスを反映した単純なネットワークプロキシーも実行します。これにより、ノードは一連のバックエンドで単純な TCP および UDP ストリームの転送を実行できます。
2.1.3.3. ノードオブジェクト定義
以下は、Kubernetes のノードオブジェクト定義の例になります。
apiVersion: v1 1 kind: Node 2 metadata: creationTimestamp: null labels: 3 kubernetes.io/hostname: node1.example.com name: node1.example.com 4 spec: externalID: node1.example.com 5 status: nodeInfo: bootID: "" containerRuntimeVersion: "" kernelVersion: "" kubeProxyVersion: "" kubeletVersion: "" machineID: "" osImage: "" systemUUID: ""
2.1.3.4. ノードのブートストラップ
ノードの設定はマスターからブートストラップされます。つまり、ノードが事前定義済みの設定、クライアントとサーバーの証明書をマスターからプルします。これにより、ノード間の相違点を減らして、より多くの設定を集約し、クラスターを必要な状態で収束させることで、ノードの起動時間を短縮することができます。 証明書のローテーションや集約された証明書の管理はデフォルトで有効にされます。
図2.2 ノードブートストラップのワークフローに関する概要
ノードサービスの起動時に、ノードは /etc/origin/node/node.kubeconfig ファイルと他のノード設定ファイルが存在するかチェックしてから、クラスターに参加します。存在しない場合には、ノードはマスターから設定をプルしてから、クラスターに参加します。
ConfigMaps は、クラスターにノードの設定を保存するために使用され、ノードホスト上の /etc/origin/node/node-config.yaml で設定ファイルを生成します。デフォルトのノードグループやその ConfigMaps の定義については、クラスターのインストールガイドの ノードグループとホストマッピングの定義 を参照してください。
ノードブートストラップのワークフロー
自動ノードブートストラップのプロセスでは、以下のワークフローを使用します。
デフォルトでは、クラスターのインストール時に、
clusterrole
、clusterrolebinding
およびserviceaccount
オブジェクトのセットが、ノードブートストラップで使用するために作成されます。system:node-bootstrapper クラスターロールは、ノードのブートストラップ時に、証明書署名要求 (CSR) の作成に使用します。
$ oc describe clusterrole.authorization.openshift.io/system:node-bootstrapper
出力例
Name: system:node-bootstrapper Created: 17 hours ago Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: authorization.openshift.io/system-only=true openshift.io/reconcile-protect=false Verbs Non-Resource URLs Resource Names API Groups Resources [create get list watch] [] [] [certificates.k8s.io] [certificatesigningrequests]
以下の node-bootstrapper サービスアカウントを、openshift-infra プロジェクトに作成します。
$ oc describe sa node-bootstrapper -n openshift-infra
出力例
Name: node-bootstrapper Namespace: openshift-infra Labels: <none> Annotations: <none> Image pull secrets: node-bootstrapper-dockercfg-f2n8r Mountable secrets: node-bootstrapper-token-79htp node-bootstrapper-dockercfg-f2n8r Tokens: node-bootstrapper-token-79htp node-bootstrapper-token-mqn2q Events: <none>
以下の system:node-bootstrapper のクラスターロールのバインディングは、ノードブートストラップのクラスターロールとサービスアカウント向けです。
$ oc describe clusterrolebindings system:node-bootstrapper
出力例
Name: system:node-bootstrapper Created: 17 hours ago Labels: <none> Annotations: openshift.io/reconcile-protect=false Role: /system:node-bootstrapper Users: <none> Groups: <none> ServiceAccounts: openshift-infra/node-bootstrapper Subjects: <none> Verbs Non-Resource URLs Resource Names API Groups Resources [create get list watch] [] [] [certificates.k8s.io] [certificatesigningrequests]
また、デフォルトでは、クラスターのインストール時に、openshift-ansible のインストーラーにより、OpenShift Container Platform の認証局とその他のさまざまな証明書、鍵、kubeconfig ファイルが /etc/origin/master ディレクトリーに作成されます。注目すべき 2 つのファイルは以下のとおりです。
/etc/origin/master/admin.kubeconfig
system:admin ユーザーを使用します。
/etc/origin/master/bootstrap.kubeconfig
マスター以外のノードブートストラップノードに使用します。
/etc/origin/master/bootstrap.kubeconfig は、インストーラーが以下のように node-bootstrapper のサービスアカウントを使用するときに作成されます。
$ oc --config=/etc/origin/master/admin.kubeconfig \ serviceaccounts create-kubeconfig node-bootstrapper \ -n openshift-infra
- マスターノードでは、ブートストラップファイルとして /etc/origin/master/admin.kubeconfig を使用し、/etc/origin/node/boostrap.kubeconfig にコピーされます。他のマスター以外のノードでは、/etc/origin/master/bootstrap.kubeconfig ファイルは、他のノードすべてに対して、各ノードホストごとに /etc/origin/node/boostrap.kubeconfig にコピーされます。
次に、/etc/origin/master/bootstrap.kubeconfig は、以下のように、フラグ
--bootstrap-kubeconfig
を使用して kubelet に渡されます。--bootstrap-kubeconfig=/etc/origin/node/bootstrap.kubeconfig
- kubelet は、指定の /etc/origin/node/bootstrap.kubeconfig ファイルで先に起動します。内部での初期接続後に、kubelet は証明書署名要求 (CSR) を作成して、マスターに送信します。
CSR はコントローラーマネージャーを使用して検証、承認されます (特に、証明署名コントローラー)。承認された場合には、kubelet クライアントとサーバー証明書は /etc/origin/node/ceritificates ディレクトリーに作成されます。以下に例を示します。
# ls -al /etc/origin/node/certificates/
出力例
total 12 drwxr-xr-x. 2 root root 212 Jun 18 21:56 . drwx------. 4 root root 213 Jun 19 15:18 .. -rw-------. 1 root root 2826 Jun 18 21:53 kubelet-client-2018-06-18-21-53-15.pem -rw-------. 1 root root 1167 Jun 18 21:53 kubelet-client-2018-06-18-21-53-45.pem lrwxrwxrwx. 1 root root 68 Jun 18 21:53 kubelet-client-current.pem -> /etc/origin/node/certificates/kubelet-client-2018-06-18-21-53-45.pem -rw-------. 1 root root 1447 Jun 18 21:56 kubelet-server-2018-06-18-21-56-52.pem lrwxrwxrwx. 1 root root 68 Jun 18 21:56 kubelet-server-current.pem -> /etc/origin/node/certificates/kubelet-server-2018-06-18-21-56-52.pem
- CSR の承認後に、node.kubeconfig ファイルが /etc/origin/node/node.kubeconfig に作成されます。
- kubelet は、/etc/origin/node/certificates/ ディレクトリーにある /etc/origin/node/node.kubeconfig ファイルと証明書で再起動されます。 再起動後に、クラスターへの参加の準備ができます。
ノード設定のワークフロー
ノードの設定を取得するには、以下のワークフローを使用します。
- 最初に、ノードの kubelet は、/etc/origin/node/ ディレクトリーにあるブートストラップの設定ファイル bootstrap-node-config.yaml を使用して起動され、ノードのプロビジョニング時に作成されます。
- 各ノードで、ノードサービスファイルは、/usr/local/bin/ ディレクトリーにあるローカルスクリプト openshift-node を使用して、指定の bootstrap-node-config.yaml で kubelet を起動します。
- マスターごとに、/etc/origin/node/pods ディレクトリーには、マスターに静的 Pod として作成された apiserver、controller および etcd の Pod のマニフェストが含まれます。
クラスターのインストール時に、sync DaemonSet が作成され、ノードごとに同期 Pod を作成します。同期 Pod は、/etc/sysconfig/atomic-openshift-node ファイル内の変更をモニターリングします。特に、設定される
BOOTSTRAP_CONFIG_NAME
を監視します。BOOTSTRAP_CONFIG_NAME
は、openshift-ansible インストーラーにより設定され、対象のノードが所属するノード設定グループをもとにした ConfigMap の名前です。デフォルトでは、インストーラーは以下のノード設定グループを作成します。
- node-config-master
- node-config-infra
- node-config-compute
- node-config-all-in-one
- node-config-master-infra
各グループの ConfigMap は openshift-node プロジェクトに作成されます。
-
同期 Pod は、
BOOTSTRAP_CONFIG_NAME
の値セットを基に適切な ConfigMap を抽出します。 - 同期 Pod は kubelet 設定に ConfigMap データを変換し、対象のノードホスト用に /etc/origin/node/node-config.yaml を作成します。このファイルに変更が加えられると (またはファイルが初めて作成される場合には)、kubelet が再起動されます。
ノード設定の変更
ノードの設定は、openshift-node プロジェクトの適切な ConfigMap を編集して変更します。/etc/origin/node/node-config.yaml は直接変更しないでください。
たとえば、node-config-compute グループに含まれるノードの場合は、以下のコマンドを使用して ConfigMap を編集します。
$ oc edit cm node-config-compute -n openshift-node