※ 本記事は、Guido Ferreyraによる”Optimizing environment isolation in OKE with namespaces and ExternalDNS“を翻訳したものです。

2023年12月7日


Oracle Container Engine for Kubernetes (OKE)でKubernetesユーザーが直面する一般的なジレンマの1つは、異なる環境(開発者、テスト、本番または様々な顧客)に対して複数のクラスタを作成するか、それらを単一のOKEクラスタ内で統合するかです。万能の回答は存在しませんが、このブログ投稿では、単一のOKEクラスタ内でnamespace、ロールベースのアクセス制御(RBAC)およびネットワーク・ポリシーを使用して効率的な環境分離を実現するメリットについて考察します。また、アプリケーション間で共有されるロード・バランサに関する重要な考慮事項にも対応しています。

単一のOKEクラスタ内の複数の環境に関する考慮事項

開発(dev)、テスト(test)および本番(prod)環境のデプロイを目指し、パブリック・ドメイン内の個別のAレコード(myapp.orgなど)でそれらが公開されていることを確認するシナリオについて詳しく説明します。

OKE Diagram

Oracle Cloud Infrastructure (OCI)の観点から見たこのアーキテクチャの概要では、各環境に専用のロード・バランサがあります。dev、testおよびprodデプロイメントでは異なるKubernetesサービスが使用されるため、OKEは宣言されたサービスごとに1つのロード・バランサをデプロイします。

リソースとnamespaceのグループ化

次の課題は、リソースを環境別にグループ化する方法です。答えは、Kubernetesにおけるnamespaceです。namespaceは、pod、サービス、レプリケーション・コントローラなど、同じクラスタ内の様々なKubernetesオブジェクトを分類および分離する強力な方法を提供します。

gferreyr-mac:~ gferreyr$ kubectl create namespace dev 
namespace/dev created 
gferreyr-mac:~ gferreyr$ kubectl create namespace test 
namespace/test created 
gferreyr-mac:~ gferreyr$ kubectl create namespace prod 
namespace/prod created

アプリケーションのデプロイとサービスの公開を進める前に、DNSレコードの作成を自動化して、アプリケーションをDNSゾーンに公開する方法について説明します。

namespaceの保護

セキュリティに関しては、RBACとネットワーク・ポリシーの2つの側面に注目します。KubernetesのRBACポリシーを使用して、namespaceへの管理アクセスを保護できます。これらのロールをOCI Identity and Access Management (IAM)サービスのユーザーにバインドして、KubernetesがOCIサービスと直接対話できるようにすることもできます。デプロイメントの例に従うと、対応するExternalDNSを持つnamespaceを作成する「administrator」というロールと、個別のnamespaceへのアクセス権を付与する3つの異なるロール・バインディング構成を持つことができます。

デフォルトでは、namespace間のpod通信は許可されず、分離とセキュリティが向上します。namespace間をまたがった通信が必要な場合は、ネットワーク・ポリシーを構成して制御できます。

OCI DNSゾーン

DNSについては詳しく説明していませんが、OCIのDNSサービスでは、パブリック・ドメインを含む管理ゾーンを呼び出すことができます。この記事では、myapp.orgという名前のパブリック・ゾーンを作成しました。ドメインを真に所有するには、登録者にゾーンを委任するなど、より多くのステップが必要ですが、この投稿の範囲では、この設定を使用します。

ここで、異なるロード・バランサを指すAレコードをどのように追加できますか? 解答はExternalDNSです。OKEクラスタで設定するには、Oracle Cloud Infrastructure DNSを使用するためのExternalDNSの構成を参照してください。この設定を行うと、適切な注釈を使用してアプリケーションをデプロイし、DNSレコードを生成できます。この例では、namespaceおよびDNS注釈用に調整された次の構文を使用して、3つのサービスをデプロイしました:

apiVersion: v1
kind: Service
metadata:
 name: nginx
 annotations:
  external-dns.alpha.kubernetes.io/hostname: dev.myapp.org
 namespace: dev
spec:
 type: LoadBalancer
 ports:
 - port: 80
   name: http
   targetPort: 80
  selector:
   app: nginx
<<< truncated >>>

サービスのデプロイ後、Kubernetesクラスタは次のダイアグラムの形式を取ります:

A graphic depicting the workflow of the deployment for the example Kubernetes cluster.

gferreyr-mac:~ gferreyr$ k get svc -A | grep -e nginx -e NAMESPACE 
NAMESPACE     NAME         TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                  AGE 
dev           nginx        LoadBalancer   10.96.197.87    158.180.60.164    80:32195/TCP             10 m 
prod          nginx        LoadBalancer   10.96.6.15      89.168.122.8      80:31873/TCP             9 m 38 s 
test          nginx        LoadBalancer   10.96.174.231   130.162.254.126   80:32523/TCP             1 0m

DNSゾーンは次の例のようになります:

A screenshot of the Zones screen in the Oracle Cloud Console for the example zone.

これで、namespaceで区切られた3つの環境を含む完全にデプロイされたOKEクラスタがあり、その上、ExternalDNSによって自動的にDNSゾーンが更新されます。

まとめ

このブログ投稿では、環境の分離にKubernetesのnamespaceを使用し、ExternalDNSを利用してOracle Cloud Infrastructure内でDNSゾーンをシームレスに更新する方法について説明しました。このアプローチは、セキュリティを強化するだけでなく、単一のOKEクラスタ内の複数の環境の管理も合理化します。

詳細は、次のリソースを参照してください: