信頼性が高く可用性の高い分散システムを確立することは、大きな課題です。このセクションでは、Kubernetesベースのシステムが確実に機能し、さまざまなタイプの障害に対処できるようにするいくつかのベストプラクティスの使用例を紹介します。
4.2.1高可用性クラスターの作成
高可用性Kubernetesクラスターを作成するには、主要コンポーネントを冗長化する必要があります。つまり、etcdはクラスター(通常は3または5ノードにまたがるクラスター)の形でデプロイする必要があり、Kubernetes APIサーバーは冗長である必要があります。必要に応じて、Heapsterストレージなどの補助クラスター管理サービスも冗長的に展開できます。図4.1は、いくつかの負荷分散マスターノードを含み、各マスターノードに完全なメインコンポーネントとetcdコンポーネントが含まれている、典型的な信頼性の高い高可用性Kubernetesクラスターを示しています。
これは、高可用性クラスターを構成する唯一の方法ではありません。たとえば、シングルトンetcdクラスターをデプロイしてマシンのワークロードを最適化するか、etcdクラスターを他のマスターノードよりも冗長性の高い構成にします。
図4.1信頼性が高く高可用性のKubernetesクラスター
4.2.2ノードの信頼性を確保する
ノードまたは特定のコンポーネントに障害が発生する可能性がありますが、多くの障害は一時的なものです。いくつかの基本的な保証により、障害が発生した場合にDockerバックグラウンドサポートサービスとKubeletが自動的に再起動します。
CoreOS、最新のDebianベースのOS(Ubuntu≥16.04バージョン)、または初期化メカニズムとしてSystemdを使用するその他のオペレーティングシステムを実行している場合、DockerとKubeletを自己起動のバックグラウンドサポートサービスとして簡単にデプロイできます。コードを以下に示します。
systemctl enable docker
systemctl enable kublet
他のオペレーティングシステムの場合、Kubernetesプロジェクトはその高可用性ユースケースにMonitを提供し、読者はニーズに応じて任意のプロセスモニターを選択できます。
4.2.3クラスタステータスの保護
Kubernetesクラスターの状態はetcdクラスターに保存されます。etcdクラスターは非常に信頼性が高く、複数のノードに分散されるように設計されています。これらの機能を信頼性が高く可用性の高いKubernetesクラスターに適用することは非常に重要です。
1。etcdクラスター
etcdクラスターには少なくとも3つのノードが必要です。リーダーがより高い信頼性と冗長性を必要とする場合、5、7、またはその他の奇数のノードを使用できます。ネットワーク分割の場合を考えると、ノードの数は奇数でなければなりません。
クラスターを作成するには、etcdノードがお互いを検出できる必要があります。これを行うにはいくつかの方法があります。
2。静的な発見
静的検出により、各etcdのIPアドレス/ホスト名を直接管理できます。これは、etcdクラスターをKubernetesクラスターの外部で管理できる、またはetcdクラスターの正常な動作を担当できるという意味ではありません。etcdノードはポッドとして実行され、必要に応じて自動的に再起動します。
etcdクラスターに3つのノードが含まれていると想定すると、コードは次のようになります。
etcd-1 10.0.0.1
etcd-2 10.0.0.2
etcd-2 10.0.0.3
各ノードは、この初期クラスター情報をコマンドライン情報として受け取ります。コードを以下に示します。
--initial-cluster etcd-1=http://10.0.0.1:2380,etcd-
2=http://10.0.0.2:2380,etcd-3=http://10.0.0.3:2380
--initial-cluster-state new
または、環境変数として受け取ると、コードは次のようになります。
ETCD_INITIAL_CLUSTER="etcd-1=http://10.0.0.1:2380,etcd-
2=http://10.0.0.2:2380,etcd-3=http://10.0.0.3:2380"
ETCD_INITIAL_CLUSTER_STATE=new
3。etcdが見つかりました
etcd検出では、既存のクラスターを使用して、新しいクラスターのノードがお互いを検出できるようにすることができます。もちろん、これには新しいクラスターノードが既存のクラスターにアクセスできる必要があります。依存関係やセキュリティリスクについて心配していない場合は、https://discovery.etcd.ioでパブリックetcd検出サービスを使用することもできます。
リーダーは検出トークンを作成する必要があります。必要に応じて、クラスターサイズを指定できます。デフォルト値は3です。次のコードは、入力する必要があるコマンドです。
$ curl https://discovery.etcd.io/new?size=3
https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
検出サービスを使用する場合は、トークンをコマンドラインパラメータとして渡す必要があります。コードは次のとおりです。
--discovery https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
これを環境変数として渡すこともできます。コードを以下に示します。
ETCD_DISCOVERY=https://discovery.etcd.io/3e86b59982e49066c5d813af1c2e2579cbf573de
検出サービスは初期クラスターの初期ブートにのみ関連していることに注意してください。クラスターが開始され、初期ノードで実行されると、別のプロトコルを使用して実行中のクラスターにノードを追加および削除し、サービスがパブリックなどに検出されないようにします。永続的な依存関係を維持します。
4。DNS発見
DNSを使用し、SRVレコードを介して検出を確立することもできます。SRVレコードにはTLSを含めることも含めないこともできます。コンテンツのこの部分については、本書では扱いません。読者は、etcd DNS検出を検索することで解決策を見つけることができます。
5。etcd.yamlファイル
見つかったアイデアによると、各ノードでetcdインスタンスを開始するコマンドは、etcd.yamlポッドリストの構成とは少し異なります。リストをコピーして、各etcdノードの/ etc / kubernetes / manifestsに貼り付けます。
次のコードは、etcd.yamlマニフェストファイルのさまざまな部分を示しています。
apiVersion: v1
kind: Pod
metadata:
name: etcd-server
spec:
hostNetwork: true
containers:
- image: gcr.io/google_containers/etcd:2.0.9
name: etcd-container
最初の部分には、ポッドの名前が含まれ、ポッドが使用するホストネットワークを指定し、etcd-containerという名前のコンテナーを定義します。次に、最も重要な部分は使用されるDockerイメージです。次のコードに示されているケースでは、etcd:2.0.9で、etcd V2に似ています。
command:
- /usr/local/bin/etcd
- --name
- <name>
- --initial-advertise-peer-urls
- http://<node ip>:2380
- --listen-peer-urls
- http://<node ip>:2380
- --advertise-client-urls
- http://<node ip>:4001
- --listen-client-urls
- http://127.0.0.1:4001
- --data-dir
- /var/etcd/data
- --discovery
- <discovery token>
コマンドセクションには、etcdが正しく動作するために必要なコマンドラインパラメータがリストされています。上記のコードに示されているケースでは、etcd検出メカニズムが使用されているため、検出フラグを指定する必要があります。<name>、<node IP>、および<discovery token>は、一意の名前(ホスト名が適切です)、ノードのIPアドレス、および以前に受信した検出トークン(すべてのノードで同じトークン)に置き換える必要があります。`
ports:
- containerPort: 2380
hostPort: 2380
name: serverport
- containerPort: 4001
hostPort: 4001
name: clientport
上記のコードに示されているケースでは、ポートセクションにサーバー(2380)とクライアント(4001)のポートがリストされており、これらのポートはホスト上の同じポートにマップされています。
volumeMounts:
- mountPath: /var/etcd
name: varetcd
- mountPath: /etc/ssl
name: etcssl
readOnly: true
- mountPath: /usr/share/ssl
name: usrsharessl
readOnly: true
- mountPath: /var/ssl
name: varssl
readOnly: true
- mountPath: /usr/ssl
name: usrssl
readOnly: true
- mountPath: /usr/lib/ssl
name: usrlibssl
readOnly: true
- mountPath: /usr/local/openssl
name: usrlocalopenssl
readOnly: true
- mountPath: /etc/openssl
name: etcopenssl
readOnly: true
- mountPath: /etc/pki/tls
name: etcpkitls
readOnly: true
マウントセクションには、etcdがデータを書き込む/ var / etcdのvaretcdマウントと、etcdによって変更されない一部のSSLおよびTLS読み取り専用マウントがリストされています。コードを以下に示します。
volumes:
- hostPath:
path: /var/etcd/data
name: varetcd
- hostPath:
path: /etc/ssl
name: etcssl
- hostPath:
path: /usr/share/ssl
name: usrsharessl
- hostPath:
path: /var/ssl
name: varssl
- hostPath:
path: /usr/ssl
name: usrssl
- hostPath:
path: /usr/lib/ssl
name: usrlibssl
- hostPath:
path: /usr/local/openssl
name: usrlocalopenssl
- hostPath:
path: /etc/openssl
name: etcopenssl
- hostPath:
path: /etc/pki/tls
name: etcpkitls
ボリュームセクションは、対応するホストパスにマップされた各マウントのストレージボリュームを提供します。読み取り専用のマウントは可能ですが、ユーザーは、etcdノードの冗長性のみに依存するのではなく、varetcdボリュームをより堅牢なネットワークストレージにマップすることができます。
6。etcdクラスターを確認する
etcdクラスターが起動して実行されると、etcdctlツールにアクセスしてクラスターのステータスとヘルスを確認できます。Kubernetesでは、execコマンド(docker execと同様)を使用して、ポッドまたはコンテナーで直接コマンドを実行できます。
以下に推奨コマンドコードを示します。
- etcdctlメンバーリスト
- etcdctlクラスターの正常性
- etcdctl set test( "ええ、それは動作します!")
- etcdctl get test(「ええ、それはうまくいく!」を返すはずです)
7.etcd v2与etcd v3
この本を執筆している時点では、Kubernetes 1.4はetcd v2のみをサポートしていますが、etcd v3では大幅な改善が行われ、以下の機能など多くの称賛に値する新機能が追加されました。
- JSON RESTからprotobufs gRPCに切り替えると、ローカルクライアントのパフォーマンスが2倍になりました。
- リースと長いキーTTLをサポートし、パフォーマンスを向上させます。
- ウォッチごとに開いた接続を維持する代わりに、gRPCを使用して1つの接続で複数のウォッチを多重化します。
etcd v3はKubernetesで実行できることが証明されていますが、正式にはサポートされていません。これは大きな前進であり、この作業は進行中です。読者がこの本を読んだときに、v3がKubernetesによって正式にサポートされることを願っています。そうでない場合は、etcd v2をetcd v3に移行することも可能です。
4.2.4データを保護する
クラスターの状態と構成を保護することは重要ですが、独自のデータを保護することはさらに重要です。クラスターの状態が破壊された場合、通常、クラスターを最初から再構築できます(ただし、再構築中はクラスターを使用できません)。しかし、データが破損したり失われたりすると、問題が発生します。同じルールが冗長性に適用されますが、Kubernetesクラスターの状態が動的である場合、ほとんどのデータは同期されない可能性があります(動的ではありません)。たとえば、多くの履歴データは重要であり、バックアップおよび復元できます。リアルタイムデータは失われる可能性がありますが、システム全体が以前のバージョンに復元され、一時的に損傷するだけの可能性があります。
4.2.5冗長APIサーバーを実行する
APIサーバーはステートレスであり、etcdクラスターからすべての必要なデータを取得できます。つまり、複数のAPIサーバーは、サーバー間で調整する必要なく、簡単に実行できます。複数のAPIサーバーが実行されている場合は、それらの前にロードバランサーを配置して、ユーザーに対して透過的にすることができます。
4.2.6 Kubernetesでリーダーシップ選挙を実施する
一部の主要コンポーネント(スケジューラーやコントローラーマネージャーなど)は、同時に複数のインスタンスを持つことはできません。複数のスケジューラが同じポッドを複数のノードにスケジュールしようとしたり、同じノードに複数回入ったりすると混乱が生じます。非常にスケーラブルなKubernetesクラスターにより、これらのコンポーネントをリーダー選出モードで実行できます。つまり、複数のインスタンスが実行されていますが、一度にアクティブになるインスタンスは1つだけです。失敗した場合、別のインスタンスがリーダーとして選択され、それを置き換えます。
Kubernetesは--leader-electフラグを通じてこのモードをサポートしています。スケジューラーとコントローラーマネージャーは、それぞれのマニフェストを/ etc / kubernetes / manifestsにコピーすることで、ポッドとしてデプロイできます。
次のコードは、フラグの使用法を示すスケジューラリストの一部です。
command:
- /bin/sh
- -c
- /usr/local/bin/kube-scheduler --master=127.0.0.1:8080 --v=2
--leader-elect=true 1>>/var/log/kube-scheduler.log
2>&1
次のコードは、フラグの使用法を示すコントローラーマネージャーリストの一部です。
- command:
- /bin/sh
- -c
- /usr/local/bin/kube-controller-manager --master=127.0.0.1:8080
--cluster-name=e2e-test-bburns
--cluster-cidr=10.245.0.0/16 --allocate-node-cidrs=true --cloud-
provider=gce --service-account-private-key-file=/srv/kubernetes/server.
key
--v=2 --leader-elect=true 1>>/var/log/kube-controller-manager.log
2>&1
image: gcr.io/google_containers/kube-controller-manager:fda24638d51a4
8baa13c35337fcd4793
これらのコンポーネントは、障害が発生したポッドのKubernetesコンポーネントを再起動する責任があるため、他のポッドと同様にKubernetesによって自動的に再起動できないことに注意してください。ここには、いつでも交換できる既製のコンポーネントが必要です。
アプリケーションのリーダー選挙
リーダー選挙もアプリケーションにとって非常に役立ちますが、実装するのは困難です。幸い、Kubernetesには巧妙な方法があり、ユーザーがGoogleのLeader-electorコンテナーを介して申請するリーダー選挙をサポートするための文書化されたプログラムがあります。基本的なコンセプトは、Kubernetesエンドポイントを使用してリソースの変換とアノテーションを組み合わせるというものです。このコンテナーが補助ツールとしてアプリケーションポッドに結合されている場合、ユーザーは非常にスムーズな方法でリーダー選出機能を利用できます。
次のコードは、3つのポッドと、elector-electorを実行するelectionと呼ばれる選択プログラムの使用を示しています。
> kubectl run leader-elector --image=gcr.io/google_containers/leader-
elector:0.4 --replicas=3 -- --election=election –http=0.0.0.0:4040
その後、クラスターに3つの新しいポッド(leader-elector-xxx)が表示されます。コードは以下のとおりです。
> kubectl get pods
NAME READY STATUS RESTARTS AGE
echo-3580479493-n66n4 1/1 Running 12 22d
leader-elector-916043122-10wjj 1/1 Running 0 8m
leader-elector-916043122-6tmn4 1/1 Running 0 8m
leader-elector-916043122-vui6f 1/1 Running 0 8m
しかし、マスターノードはどれですか?次のコードは、選挙のエンドポイントをクエリする方法を示しています。
> kubectl get endpoints election -o json
{
"kind": "Endpoints",
"apiVersion": "v1",
"metadata": {
"name": "election",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/endpoints/election",
"uid": "48ffc442-b451-11e6-9db1-c2777b74ca9d",
"resourceVersion": "892261",
"creationTimestamp": "2016-11-27T03:26:29Z",
"annotations": {
"control-plane.alpha.kubernetes.io/leader":
"{\"holderIdentity\":\"leader-elector-916043122-10wjj\",\"leaseDura
tionSeconds\":10,\"acquireTime\":\"2016-11-27T03:26:29Z\",\"renewTi
me\":\"2016-11-27T03:38:02Z\",\"leaderTransitions\":0}"
}
},
"subsets": []
}
上記のプロセスが比較的難しい場合は、metadata.annotationsで詳細を読むことができます。検出を容易にするために、jqプログラムを使用してJSONをスライスおよびカットすることをお勧めします。これは、Kubernetes APIまたはkubectlの出力を解析するのに非常に役立ちます。以下にコードを示します。
kubectl get endpoints election -o json | jq -r .metadata.annotations[]
| jq .holderIdentity
"leader-elector-916043122-10wjj"
次のコードは、選挙の有効性を証明するためにリーダーを削除する方法を示しています。
kubectl delete pod leader-elector-916043122-10wjj
pod "leader-elector-916043122-10wjj" deleted
このようにして、新しいリーダーがいます。コードを以下に示します。
kubectl get endpoints election -o json | jq -r .metadata.annotations[]
| jq .holderIdentity
"leader-elector-916043122-6tmn4"
各リーダーエレクターコンテナーは、ポート4 040で実行されているローカルWebサーバーを介してリーダーを公開するため、HTTPを介してリーダーを見つけることもできます。
Kubectl proxy
http http://localhost:8001/api/v1/proxy/namespaces/default/pods/
leader-elector-916043122-vui6f:4040/ | jq .name
"leader-elector-916043122-6tmn4"
ローカルウェブサーバーにより、リーダーエレクターコンテナーを同じポッド内のメインアプリケーションコンテナーのサイドカーコンテナーとして機能させることができます。アプリケーションコンテナーは、リーダーエレクターコンテナーと同じローカルネットワークを共有するため、http:// localhost:4040にアクセスして、現在のリーダーの名前を取得できます。選択したリーダーとポッドを共有するアプリケーションコンテナーのみがアプリケーションを実行し、他のポッドの他のアプリケーションコンテナーは休止状態になります。リクエストを受信すると、リーダーに転送します。一部の負荷分散手法では、すべてのリクエストを現在のリーダーに自動的に送信できます。
4.2.7リハーサル環境を高可用性にする
高可用性は非常に重要です。高可用性の設定に関する問題が発生した場合、それは高可用性システムのビジネスケースを意味します。したがって、クラスターを実稼働環境にデプロイする前に(実稼働環境でのNetflixテストでない限り)、信頼性が高く可用性の高いクラスターをテストする必要があります。さらに、理論的には、クラスターに変更を加えると、他のクラスター機能を中断せずに高可用性を中断する可能性があります。
デフォルトでは、ユーザーは信頼性と高可用性をテストする必要があります。最善の方法は、本番環境をできる限り再現できるリハーサル環境を作成することです。これは非常にコストがかかる可能性があります。次に、コストを制御するいくつかのソリューションを示します。
- アドホックHA プレビュー環境: HAテスト中にのみ大規模なHAクラスターを作成します。
- 時間の圧縮:意味のあるイベントストリームとシナリオを事前に作成し、入力を提供し、シナリオを迅速かつ継続的にシミュレートします。
- HAテストとパフォーマンスおよびストレステストを組み合わせる:パフォーマンスおよびストレステストの最後に、システムに過負荷をかけ、信頼性と高可用性の構成がどのように負荷を処理するかを確認します。
4.2.8高可用性のテスト
高可用性のテストには、システムの計画と深い理解が必要です。各テストの目的は、システムの設計や実装の欠陥を明らかにし、適切なカバレッジを提供することです。テストに合格すると、システムが期待どおりに動作することを確認できます。
信頼性と高可用性の分野では、これはシステムを破壊する方法を見つけ、それらを再結合して影響を観察することを意味します。
これには以下のメソッドが必要です。
- 起こりうる障害の包括的なリスト(妥当な組み合わせを含む)。
- 考えられるすべての障害について、システムがどのように応答する必要があるかを知る必要があります。
- 障害を引き起こす方法。
- システムの反応を観察する方法。
上記の各方法は重要です。過去の経験に基づくと、最善の方法は、それを段階的に実行し、常に変化する低レベルの障害のリストではなく、比較的少数の一般的な障害のカテゴリと一般的な応答を考え出すことです。
たとえば、一般的な障害カテゴリは、ノードが応答しないことです。一般的な応答は、ノードの再起動であり、障害を引き起こす方法は、ノードのVM(VMの場合)を停止することであり、ノードがダウンしている場合でも、システムは標準の受け入れテストに基づいています。最終的に上昇し、システムは通常に戻ります。開発者は、問題が記録されているかどうか、関連するアラートが適切な担当者に送信されているかどうか、さまざまな統計やレポートが更新されているかどうかなど、他の多くのコンテンツをテストすることもできます。
単一の応答では失敗を解決できない場合があることに注意してください。たとえば、応答しないノードの場合、それがハードウェア障害の場合、再起動しても役に立ちません。この場合、2番目の応答の実行が開始されます。おそらく、新しいVMが開始され、構成され、ノードに接続されます。この場合、あまりに広く定義することはできず、ノードで特定のタイプのポッド/ロール(etcd、マスター、ワーカー、データベース、モニタリング)のテストを作成する必要がある場合があります。
より高い要件がある場合、適切なテスト環境とテストをセットアップするには、実稼働環境よりも時間がかかります。
最も重要な点は、できるだけ非侵襲的であることです。つまり、理想的な状況では、本番システムには、一部の機能をオフにしたり、テスト容量を減らして実行するように構成したりできるテスト機能がありません。その理由は、システムの攻撃面が増加し、構成エラーが原因で誤ってトリガーされる可能性があるためです。理想的には、開発者は本番環境にデプロイされるコードや構成を変更する必要なしにテスト環境を制御できます。Kubernetesを使用すると、通常、ポッドやコンテナにカスタムテスト関数を簡単に挿入できます。これらの関数は、本番環境のシステムコンポーネントとやり取りできますが、本番環境にデプロイすることはできません。
このセクションでは、信頼性が高く高可用性のクラスター(etcd、APIサーバー、スケジューラー、コントローラーマネージャーを含む)に必要なものを紹介し、クラスター自体とデータを保護するためのベストプラクティスについて説明し、起動環境とテストに特別な注意を払います問題。
この記事は、「Kubernetesをマスターする」の第4章のセクション4.2からの抜粋です。
- K8s初心者向けガイド、K8s1.10用、豊富な実用例
- 読者がさまざまなクラウドプラットフォームで大規模なクラスターを設計および展開するためのスキルを習得するのに役立ちます
この本は、理論と実践を組み合わせて、コンテナーオーケストレーションの理想的なツールであるKubernetesを包括的に紹介しています。この本には14の章があり、Kubernetesアーキテクチャの理解、Kubernetesクラスタの作成、モニタリング、ロギングとトラブルシューティング、高可用性と信頼性、Kubernetesのセキュリティ、制限とアカウントの構成、主要なKubernetesリソースの使用、Kubernetesストレージの管理、使用Kubernetesは、ステートフルアプリケーション、ローリングアップデート、スケーラビリティと割り当て、高度なKubernetesネットワーク、クラウドプラットフォームとクラスタフェデレーションでのKubernetesの実行、Kubernetes APIとプラグインのカスタマイズ、Kubernetesパッケージマネージャーの操作、およびKubernetesの将来を実行します。この本では、さまざまな環境とユースケースを包括的に検討しているため、読者が大規模なシステムを作成してKubernetesにデプロイする方法を理解できます。各章のテーマでは、読者は魅力的で魅力的な豊富な実用的なケース分析を提供します。
この本は、Kubernetesクラスタの設計と管理に焦点を当てたKubernetesの実用的なリファレンスマニュアルとして使用でき、Kubernetesが開発者と運用保守エンジニアに提供する機能とサービスを詳細に紹介しています。