[[339892]] この記事はWeChat公式アカウント「Xintai Cloud Service」から転載し、Zhu Xiangが翻訳したものです。この記事を転載する場合は、Xintai Cloud Service公式アカウントまでご連絡ください。 マネージド Kubernetes やクラウドで実行される Kubernetes についてよく話しますが、VMware などの非クラウド環境やベアメタル サーバーでも Kubernetes を実行します。 クラウド ベンダー統合の典型的な例についても、よく耳にすることがあるでしょう。たとえば、ホストされたサービスにアクセスするためにパスワードなしの認証情報を取得できる、手動介入なしでクラウド ロード バランサーを構成できる、DNS エントリが自動的に作成される、などです。 ローカルで実行する場合、OpenStack などのサポートされているクラウド プラットフォームを使用していない限り、これらの統合機能は通常利用できません。では、ベアメタルまたは VM 上で実行しているときに、クラウド ネイティブ環境の自動化のメリットをどのように得るのでしょうか? それでは、何を達成したいのかを段階的に見ていきましょう。 この記事で使用されているすべてのマニフェストは、github プロジェクト (https://github.com/clusterfrak-dynamics/gitops-template) で入手できます。 ギットオプス いつものように、クラウド上かオンプレミスかに関係なく、リソースをクラスターにデプロイするには GitOps と FluxCD を使用します。詳細については、Flux に関する記事を参照してください。 開始するには、GitOps テンプレートを使用して、ニーズに合わせてカスタマイズできます。より適切な場合は、kubectl を使用してマニフェストを直接デプロイすることもできます。 コンポーネントを詳しく見てみましょう。 負荷分散 クラウド上で Kubernetes を実行する場合、通常はすぐに使用できるロードバランサーを使用できます。ベアメタルまたは VM 上で実行している場合、ロード バランサは保留状態のままになります。 したがって、まず第一に、サービス タイプ LoadBalancer が使用不可の保留状態にならないようにし、haproxy やその他の同様のサービスを手動で構成することなく、必要なときに動的なロード バランサーを提供できるようにする必要があります。 Metallb は、仮想ロード バランサ実装の 2 つのモードを提供できます。 後者は、追加の構成なしでほぼすべてのレイヤー 2 ネットワークで動作するため、よりシンプルです。 ARP モードでは、metallb の設定は非常に簡単です。使用する IP をいくつか指定するだけです。 構成マニフェストは、こちらまたは公式ドキュメントに記載されています。必要な IP アドレスを構成するには、ConfigMap を使用します。 metallb-config.yaml: - APIバージョン: v1
- 種類: ConfigMap
- メタデータ:
- 名前空間: metallb-system
- 名前: config
- データ:
- 設定: |
- アドレスプール:
- -名前:デフォルト
- プロトコル: レイヤー2
- 住所:
- - 10.10.39.200-10.10.39.220
Metallb コンポーネントの通信を暗号化するためのキーを生成する必要もあります。次のスクリプトを使用して Kubernetes シークレット yaml を生成できます。 - kubectl は、generic -n metallb-system メンバーリストを作成します
すべてがデプロイされると、metallb-system 名前空間内に対応するポッドが表示されます。 - 名前準備完了 ステータス 再起動 年齢
- controller-57f648cb96-tvr9q 1/1 実行中 0 2d1h
- speaker-7rd8p 1/1 実行中 0 2d1h
- speaker-7t7rg 1/1 実行中 0 2d1h
- speaker-8qm2t 1/1 実行中 0 2d1h
- speaker-bks4s 1/1 実行中 0 2d1h
- speaker-cz6bc 1/1 実行中 0 2d1h
- speaker-h8b54 1/1 実行中 0 2d1h
- speaker-j6bss 1/1 実行中 0 2d1h
- speaker-phvv7 1/1 実行中 0 2d1h
- speaker-wdwjc 1/1 実行中 0 2d1h
- スピーカー-xj25p 1/1 実行中 0 2d1h
これでロードバランサーをテストする準備が整いました。これについては、次のトピックに直接進みましょう。 イングレスコントローラ クラウド上で実行する場合、従来のレイヤー 4 ロード バランサに加えて、GCP および AWS でレイヤー 7 ロード バランサ (Application Load Balancer など) を利用できる場合もあります。しかし、機能は限られており、コスト効率が良くなく、Kubernetes クラスターからのトラフィックを管理するために Ingress コントローラーが必要になることがよくあります。 この Ingress コントローラは通常、LoadBalancer のサービス タイプを通じて外部に公開されます。これが、以前の metallb 展開が役立つ理由です。 最初に登場し、最も一般的に使用されるイングレス コントローラーの 1 つは nginx-ingress で、Helm を使用して簡単にデプロイできます。 Helm Operator で Flux を使用しているため、使用している Helm に応じて次の values.yaml 構成を参照できます。 Helm Operator で Flux を使用するため、values.yaml を取得できる Helm Release バージョンを使用します。以下に構成を示します。 - apiバージョン: helm.fluxcd.io/v1
- 種類: HelmRelease
- メタデータ:
- 名前: nginx-ingress
- 名前空間: nginx-ingress
- 仕様:
- リリース名: nginx-ingress
- チャート:
- リポジトリ: https://kubernetes-charts.storage.googleapis.com
- バージョン: 1.36.3
- 名前: nginx-ingress
- 値:
- コントローラ:
- 公開サービス:
- 有効: true
- 種類: "DaemonSet"
- サービス:
- 有効: true
- 外部トラフィックポリシー:ローカル
- デーモンセット:
- ホストポート:
- http: 80
- https: 443
- デフォルトバックエンド:
- レプリカ数: 2
- ポッドセキュリティポリシー:
- 有効: true
ここでは特別なことは何もありません。DaemonSet を使用しており、デフォルトで使用されるサービス タイプは LoadBalancer です。 新しくデプロイされたバージョンを確認すると: - $ kubectl -n nginx-ingress で helmreleases.helm.fluxcd.io を取得します
- 名前リリース フェーズ ステータス メッセージ 年齢
- nginx-ingress nginx-ingress Helmリリース'nginx-ingress'のデプロイに成功しました で 'nginx-ingress' 。 2日1時間
-
- または
-
- $ helm -n nginx-ingress ls
- 名前名前空間 リビジョン 更新 ステータス チャート アプリ バージョン
- nginx-ingress nginx-ingress 2 2020-05-12 15:06:25.832403094 +0000 UTC デプロイ済み nginx-ingress-1.36.3 0.30.0
-
- $ kubectl -n nginx-ingress svc を取得します
- 名前タイプ クラスター IP 外部 IP ポート 年齢
- nginx-ingress-controller ロードバランサー 10.108.113.212 10.10.39.200 80:31465/TCP、443:30976/TCP 2d1h
- nginx-ingress- default -backend ClusterIP 10.102.217.148 <なし> 80/TCP
サービスが LoadBalancer タイプであり、外部 IP が以前の metalb ConfigMap で定義したものであることがわかります。 デモ用の名前空間を作成し、イングレスを作成するときの動作を確認しましょう。 - $ kubectl名前空間デモを作成します
-
- APIバージョン: アプリ/v1
- 種類: デプロイメント
- メタデータ:
- ラベル:
- アプリ: nginx
- 名前: nginx
- 名前空間: デモ
- 仕様:
- セレクタ:
- 一致ラベル:
- アプリ: nginx
- テンプレート:
- メタデータ:
- ラベル:
- アプリ: nginx
- 仕様:
- コンテナ:
- - 画像: nginx
- 名前: nginx
-
- APIバージョン: v1
- 種類: サービス
- メタデータ:
- ラベル:
- アプリ: nginx
- 名前: nginx
- 名前空間: デモ
- 仕様:
- ポート:
- - ポート: 80
- プロトコル: TCP
- ターゲットポート: 80
- セレクタ:
- アプリ: nginx
-
- APIバージョン: networking.k8s.io/v1beta1
- 種類: イングレス
- メタデータ:
- 注釈:
- kubernetes.io/ingress.class: nginx
- 名前: nginx
- 名前空間: デモ
- 仕様:
- ルール:
- - ホスト: nginx.test.org
- http:
- パス:
- - バックエンド:
- サービス名: nginx
- サービスポート: 80
nginx-ingress はデフォルトでサービスを公開できるため、ロード バランサの IP アドレスを ingress オブジェクトに報告できます。 - $ kubectl -n デモ イングレスを取得
-
- 名前クラス ホスト アドレス ポート 年齢
- nginx <なし> nginx.test.org 10.10.39.200 80, 443 47h
LoadBalancer IP アドレスが Ingress に埋め込まれていることがわかります。これは、次のトピックで説明する外部 DNS を使用できるようにするための要件の 1 つです。 外部DNS クラスター内のレイヤー 7 ロード バランサー (nginx-ingress) にトラフィックを渡すことができるレイヤー 4 ロード バランサー (metallb) ができたので、DNS を動的に管理するにはどうすればよいでしょうか。 Kubernetes サービスと Ingress を DNS プラットフォームと同期させるためによく使用されるツールは、external-dns (https://github.com/kubernetes-sigs/external-dns) です。 広く使用されている DNS プラットフォーム (AWS Route53 または Google Cloud DNS) のいずれかを使用している場合、これは非常に簡単に使用できます。外部 DNS は他の DNS プロバイダーもサポートしていますが、直接サポートされている DNS プロバイダーを使用していない場合、問題が発生する可能性があります。 たとえば、ローカル DNS は Active Directory によって管理されます。外部 DNS は Active Directory DNS に直接書き込むことができないため、最終的には DNS 解決が利用できなくなります。 では、ダイナミック DNS 機能を利用するにはどうすればよいでしょうか?もちろん、ワイルドカード DNS レコードを使用して、それを nginx-ingress ロードバランサー IP にポイントすることもできます (これは一方向です)。クラスターへの入力として LoadBalancer を 1 つだけ使用している場合、HTTP 以外のプロトコルや他の種類の LoadBalancer サービスを使用する場合は、一部の DNS レコードを手動で更新する必要があります。 別の解決策としては、クラスターの DNS ゾーンを指定することです。 外部 DNS はバックエンドとして CoreDNS をサポートしているため、Kubernetes で実行されている CoreDNS サーバーに Active Directory の DNS ゾーンを割り当てることができます。 予防 十分シンプルに聞こえますが、external-dns/CoreDNS セクションを詳しく調べると、外部 DNS で使用される CoreDNS でサポートされている唯一のバックエンドは Etcd であることがわかりました。したがって、Etcd クラスターが必要になります。また、readme は etcd-operator に依存していることに気付くかもしれませんが、これは現在非推奨になっており、etcd との暗号化通信もサポートされていません。 最新のガイダンスを公開しました。まず、Cilium の etcd-operator を使用して 3 ノードの etcd クラスターを構成し、TLS を生成します。 Etcd 演算子 まず、etcd のカスタム リソース定義を適用します: (https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/): -
- apiバージョン: apiextensions.k8s.io/v1beta1
- 種類: カスタムリソース定義
- メタデータ:
- 名前: etcdclusters.etcd。データベース.coreos.com
- 仕様:
- 追加のプリンター列:
- - JSONPath: .metadata.creationTimestamp
- 説明: 「CreationTimestampはサーバー時間を表すタイムスタンプです いつ
- このオブジェクトが作成されました。それは 設定される保証はありません 先行順に
- 別々の操作にわたって。クライアントは この値を設定します。それは表される
- RFC3339形式で は UTCで。システムによって入力されます。読み取り専用。ヌル のために
- リスト。詳細情報: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata'
- 名前: 年齢
- タイプ:日付
- グループ: etcd.データベース.coreos.com
- 名前:
- 種類: EtcdCluster
- リストの種類: EtcdClusterList
- 複数形: etcdclusters
- 短縮名:
- - など
- 単数形: etcdcluster
- スコープ: 名前空間
- バージョン: v1beta2
- バージョン:
- -名前: v1beta2
- 提供:本当
- ストレージ: true
次に、Etcd オペレーターをデプロイできます。 すぐにetcdポッドとシークレットを取得できます。 - $ kubectl -n 外部DNS ポッドを取得する
-
- 名前準備完了 ステータス 再起動 年齢
- cilium-etcd-mnphzk2tjl 1/1 実行中 0 2d1h
- cilium-etcd-operator-55d89bbff7-cw8rc 1/1 実行中 0 2d1h
- cilium-etcd-tsxm5rsckj 1/1 実行中 0 2d1h
- cilium-etcd-wtnqt22ssg 1/1 実行中 0 2d1h
- etcd-operator-6c57fff6f5-g92pc 1/1 実行中 0 2d1h
-
- $ kubectl -n 外部DNS シークレットを取得する
- 名前タイプ データ 年齢
- cilium-etcd-client-tls 不透明 3 2d1h
- cilium-etcd-operator-token-zmjcl kubernetes.io/サービスアカウントトークン 3 2d1h
- cilium-etcd-peer-tls 不透明 3 2d1h
- cilium-etcd-sa-token-5dhtn kubernetes.io/サービスアカウントトークン 3 2d1h
- 繊毛-etcd-秘密 不透明 3 2d1h
- cilium-etcd-server-tls 不透明 3 2d1h
コアDNS その後、公式の Helm チャットを使用して CoreDNS をデプロイできます。 以前と同様に、リソースは *HelmRelease* (https://github.com/clusterfrak-dynamics/gitops-template/blob/master/flux/resources/external-dns/coredns.yaml) です。 values.yaml が必要な場合は、以下から取得できます。 - apiバージョン: helm.fluxcd.io/v1
- 種類: HelmRelease
- メタデータ:
- 名前: coredns
- 名前空間: 外部DNS
- 仕様:
- リリース名: coredns
- チャート:
- リポジトリ: https://kubernetes-charts.storage.googleapis.com
- バージョン: 1.10.1
- 名前: coredns
- 値:
- サービスタイプ: "NodePort"
- レプリカ数: 2
- サービスアカウント:
- 作成: true
- rbac:
- pspEnable:有効
- isClusterService:偽
- 追加秘密:
- -名前: cilium-etcd-client-tls
- マウントパス: /etc/coredns/tls/etcd
- サーバー:
- - ゾーン:
- - ゾーン: .
- ポート: 53
- プラグイン:
- -名前: エラー
- -名前: 健康
- 構成ブロック: |-
- レームダック5s
- -名前:準備完了
- -名前: プロメテウス
- パラメータ: 0.0.0.0:9153
- -名前:転送
- パラメータ: ./etc/resolv.conf
- -名前: キャッシュ
- パラメータ: 30
- -名前: ループ
- -名前: リロード
- -名前: ロードバランス
- -名前: etcd
- パラメータ: test.org
- 構成ブロック: |-
- スタブゾーン
- パス /skydns
- エンドポイント https://cilium-etcd-client.external-dns.svc:2379
- tls /etc/coredns/tls/etcd/etcd-client.crt /etc/coredns/tls/etcd/etcd-client.キー/etc/coredns/tls/etcd/etcd-client-ca.crt
重要な行は次のとおりです。 - 追加秘密:
- -名前: cilium-etcd-client-tls
- マウントパス: /etc/coredns/tls/etcd
-
- そして
-
- -名前: etcd
- パラメータ: test.org
- 構成ブロック: |-
- スタブゾーン
- パス /skydns
- エンドポイント https://cilium-etcd-client.external-dns.svc:2379
- tls /etc/coredns/tls/etcd/etcd-client.crt /etc/coredns/tls/etcd/etcd-client.キー/etc/coredns/tls/etcd/etcd-client-ca.crt
etcd との TLS 通信に etcd シークレットをインストールして使用しています。 外部DNS 最後に、外部 DNS をパッケージ化してインストールできます。いつものように、公式の Helm チャット (https://github.com/helm/charts/tree/master/stable/external-dns) と HelmRelease (https://github.com/clusterfrak-dynamics/gitops-template/blob/master/flux/resources/external-dns/external-dns.yaml) を使用します。 - apiバージョン: helm.fluxcd.io/v1
- 種類: HelmRelease
- メタデータ:
- 名前: 外部DNS
- 名前空間: 外部DNS
- 仕様:
- リリース名: 外部DNS
- チャート:
- リポジトリ: https://charts.bitnami.com/bitnami
- バージョン: 2.22.4
- 名前: 外部DNS
- 値:
- プロバイダー: coredns
- ポリシー: 同期
- コアデン:
- etcdエンドポイント: "https://cilium-etcd-client.external-dns.svc:2379"
- TLS:
- 有効: true
- シークレット名: "cilium-etcd-client-tls"
- caファイル名: "etcd-client-ca.crt"
- 証明書ファイル名: "etcd-client.crt"
- キーファイル名: "etcd-client.key"
ここでは、前と同様に、通信を保護するために etcd TLS シークレット名とパスを指定し、coredns を有効にします。 最終的な external-dns 名前空間は次のようになります。 - $ kubectl -n 外部DNSサービスを取得する
- 名前タイプ クラスター IP 外部 IP ポート 年齢
- cilium-etcd ClusterIP なし <なし> 2379/TCP、2380/TCP 2d2h
- cilium-etcd-client ClusterIP 10.105.37.25 <なし> 2379/TCP 2d2h
- coredns-coredns ノードポート 10.99.62.135 <なし> 53:31071/UDP、53:30396/TCP 2d1h
- 外部DNS ClusterIP 10.103.88.97 <なし> 7979/TCP 2d1h
-
- $ kubectl -n 外部DNS ポッドを取得する
- 名前準備完了 ステータス 再起動 年齢
- cilium-etcd-mnphzk2tjl 1/1 実行中 0 2d2h
- cilium-etcd-operator-55d89bbff7-cw8rc 1/1 実行中 0 2d2h
- cilium-etcd-tsxm5rsckj 1/1 実行中 0 2d2h
- cilium-etcd-wtnqt22ssg 1/1 実行中 0 2d2h
- coredns-coredns-5c86dd5979-866s2 1/1 実行中 0 2d
- coredns-coredns-5c86dd5979-vq86w 1/1 実行中 0 2d
- etcd-operator-6c57fff6f5-g92pc 1/1 実行中 0 2d2h
- external-dns-96d9fbc64-j22pf 1/1 実行中 0 2d1h
私たちの進入を振り返ってみると: -
- APIバージョン: networking.k8s.io/v1beta1
- 種類: イングレス
- メタデータ:
- 注釈:
- kubernetes.io/ingress.class: nginx
- 名前: nginx
- 名前空間: デモ
- 仕様:
- ルール:
- - ホスト: nginx.test.org
- http:
- パス:
- - バックエンド:
- サービス名: nginx
- サービスポート: 80
- $ kubectl -n デモ イングレスを取得
-
- 名前クラス ホスト アドレス ポート 年齢
- nginx <なし> nginx.test.org 10.10.39.200 80, 443 2d
このイングレスが外部 DNS によって受信され、etcd データベースに挿入されたかどうかを確認しましょう。 - $ kubectl -n 外部DNSログ -f 外部DNS-96d9fbc64-j22pf
- 時刻= "2020-05-12T15:23:52Z" レベル=info msg= "キー /skydns/org/test/nginx/4781436c を Host=10.10.39.200 に追加/設定します。テキスト =\"heritage=external-dns,external-dns/owner=default,external-dns/resource=ingress/demo/nginx\", TTL=0"
外部 DNS は動作しているようです。ここで、同じ etcd サーバーから読み取る必要があるため、CoreDNS から直接クエリを解決できるかどうかを確認しましょう。 CoreDNS は NodePort サービスをリッスンしているので、そのサービスの NodePort 上の任意のノードをクエリできます。 - $ kubectl -n 外部DNSサービスを取得する coredns-coredns
- 名前タイプ クラスター IP 外部 IP ポート 年齢
- coredns-coredns ノードポート 10.99.62.135 <なし> 53:31071/UDP、53:30396/TCP 2d1h
ポート 53/UDP はポート 31071/UDP にマッピングされます。ランダムなノードを選択しましょう: - 名前ステータス 役割 年齢 バージョン 内部 IP 外部 IP OS イメージ カーネル バージョン コンテナ ランタイム
- m1 準備完了マスター 15d v1.18.2 10.10.40.10 <なし> Ubuntu 18.04.3 LTS 4.15.0-99-generic containerd://1.3.4
- n1 準備完了 <なし> 15d v1.18.2 10.10.40.110 <なし> Ubuntu 18.04.3 LTS 4.15.0-99-generic containerd://1.3.4
- n2 準備完了 <なし> 15d v1.18.2 10.10.40.120 <なし> Ubuntu 18.04.3 LTS 4.15.0-74-generic containerd://1.3.4
dig を使用して DNS クエリを実行してみてください。 - root@inf-k8s-epi-m5:~# dig -p 31071 nginx.test.org @10.10.40.120
-
- ; <<>> DiG 9.11.3-1ubuntu1.11-Ubuntu <<>> -p 31071 nginx.test.org @10.10.40.120
- ;;グローバルオプション: +cmd
- ;;回答が得られました:
- ;; ->>HEADER<<- オペコード: QUERY、ステータス: NOERROR、ID: 61245
- ;;フラグ: qr aa rd;質問: 1、回答: 1、権限: 0、追加: 1
- ;;警告: 再帰が要求されましたが利用できません
-
- ;; OPT擬似セクション:
- ; EDNS: バージョン: 0、フラグ:;宛先アドレス: 4096
- ; COOKIE: ef8ff2732b2dc6fd (エコー)
- ;;質問セクション:
- ;nginx.test.org。で
-
- ;;回答セクション:
- nginx.test.org を参照してください。 30インチ10.10.39.200
-
- ;;クエリ時間: 2 ミリ秒
- ;;サーバー: 10.10.40.120#31071(10.10.40.120)
- ;;日時: 2020年5月14日(木) 16:26:07 UTC
- ;;受信したメッセージサイズ: 85
CoreDNS が MetalLB ロード バランサ IP で応答していることがわかります。 すぐに起動して実行 このガイドでは、クラウド アーキテクチャのような動的なエクスペリエンスを提供するために、CoreDNS、外部 DNS、Nginx Ingress、MetalLB を構成しました。すぐに開始したい場合は、このデモに使用されたすべてのリストなどが含まれている Flux github リポジトリを確認してください。 元記事: https://particule.io/en/blog/k8s-no-cloud/ |