Oracle Cloud Infrastructureドキュメント

クラスタ・ノード間のトラフィックを分散するロード・バランサの作成

サービスを作成するときに、オプションでロード・バラン・サーを作成して、サービスに割り当てられたノード間でサービス・トラフィックを分散させることができます。 ロード・バランサの構成における主要なフィールドは、作成されるサービスのtypeと、ロード・バランサが待機するportsです。

HTTPトラフィックを分散するロード・バランサの作成

次の構成ファイル(nginx_lb.yaml)を考えてみます。 nginxアプリのデプロイメント(kind: Deployment)と、nginxアプリが80ポートのhttpトラフィックを分散するLoadBalancer (type: LoadBalancer)タイプのサービス定義が続きます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx

構成ファイルの最初の部分はNginxデプロイメントを定義し、nginx:1.7.9イメージを実行する3つのポッドでホストされることをリクエストし、ポート80のコンテナへのトラフィックを受け入れます。

構成ファイルの2番目の部分は、Nginxサービスを定義します。このサービスは、LoadBalancerタイプを使用して、利用可能なポッドの間でポート80上のNginxトラフィックのバランスをとります。

nginx_lb.yamlで定義されているデプロイメントとサービスをKubernetesクラスタに接続して作成するには、次のコマンドを入力します:

$ kubectl apply -f nginx_lb.yaml

このコマンドは、デプロイメントとロード・バランサが正常に作成されたときに、次の情報を出力します:

deployment "my-nginx" created
service "my-nginx-svc" created

ロード・バランサは、保留中の状態から完全に動作するまでに数分かかることがあります。 kubectl get allと入力すると、クラスタの現在の状態を表示できます。出力は次のようになります:

$ kubectl get all
			
NAME                                  READY     STATUS    RESTARTS   AGE
po/my-nginx-431080787-0m4m8           1/1       Running   0          3m
po/my-nginx-431080787-hqqcr           1/1       Running   0          3m
po/my-nginx-431080787-n8125           1/1       Running   0          3m

NAME               CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
svc/kubernetes     203.0.113.1     <NONE>           443/TCP        3d
svc/my-nginx-svc   203.0.113.7     192.0.2.22       80:30269/TCP   3m

NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/my-nginx           3         3         3            3           3m

NAME                            DESIRED   CURRENT   READY     AGE
rs/my-nginx-431080787           3         3         3         3m

出力は、ロード・バランサが実行している(svc/my-nginx-svc)、クライアントが使用できる外部IP (192.0.2.22)を持つ3つのポッド(po/my-nginxエントリ)でmy-nginxデプロイメントが実行されていることを示していますポッドに展開されているアプリに接続します。

HTTPSトラフィックを配布するためのSSLサポートによるロード・バランサの作成

SSL終端を備えたロード・バランサを作成することで、アプリケーションへのhttpsトラフィックをクラスタ内のノード間で分散させることができます。 この例では、SSLサポートを備えたロード・バランサの構成と作成について説明します。

以下の構成ファイル、nginx-demo-svc-ssl.yamlを検討してください。これはNginxデプロイメントを定義し、HTTPをポート80で、httpsをポート443で使用するロード・バランサを介して公開します。 このサンプルでは、タイプのLoadBalancer (type: LoadBalancer)でサービスを定義することによって、Oracle Cloud Infrastructureロード・バランサを作成します。

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
  name: nginx-service
  annotations:
    service.beta.kubernetes.io/oci-load-balancer-ssl-ports: "443"
    service.beta.kubernetes.io/oci-load-balancer-tls-secret: ssl-certificate-secret
spec:
  selector:
    app: nginx
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    targetPort: 80
  - name: https
    port: 443
    targetPort: 80

ロード・バランサの注釈は特に重要です。 httpsトラフィックをサポートするポートは、oci-load-balancer-ssl-portsの値で定義されます。 注釈値のカンマ区切りリストを使用して、複数のSSLポートを宣言できます。 たとえば、ポート443と3000でSSLをサポートするには、注釈の値を443,3000に設定します。

必要なTLSシークレットssl-certificate-secretは、Kubernetesで作成する必要があります。 この例では、自己署名証明書を作成して使用します。 ただし、運用環境では、最も一般的なシナリオは、認証局によって署名されたパブリック証明書を使用することです。

次のコマンドは、自己署名証明書tls.crtを対応するキーtls.keyとともに作成します:

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

証明書を作成したので、証明書と秘密キーの両方を秘密としてKubernetesに保存する必要があります。 シークレットの名前は、ロード・バランサ定義のoci-load-balancer-tls-secret注釈の名前と一致する必要があります。 次のコマンドを使用して、キーと証明書の値がそれぞれ--key--certで設定されたKubernetesにTLSシークレットを作成します。

$ kubectl create secret tls ssl-certificate-secret --key tls.key --cert tls.crt

サービスが定義内のシークレットを参照するため、サービスを作成する前にKubernetesシークレットを作成する必要があります。 次のコマンドを使用してサービスを作成します:

$ kubectl create -f manifests/demo/nginx-demo-svc-ssl.yaml

サービスを見て、パブリックIPアドレス(EXTERNAL-IP)がNginxサービス(nginx-service)に割り当てられるのを待ちます。 これは、サービスに接続するために使用するロード・バランサIPです。

$ kubectl get svc --watch
			
NAME            CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
nginx-service   192.0.2.1      198.51.100.1     80:30274/TCP   5m

ロード・バランサが実行されているため、次のコマンドで示すように、httpまたはhttpsを使用してサービスにアクセスできるようになりました:

$ curl http://198.51.100.1
			
$ curl --insecure https://198.51.100.1

この例では、--insecureフラグは、自己署名証明書を使用しているため、httpsを使用してサービスにアクセスするために使用されます。 パブリック証明書が認証局によって署名された運用環境では、このフラグを使用しないでください。

ノート: クラスタが削除されると、サービスの作成時に動的に作成されるロード・バランサは削除されません。 クラスタを削除する前に、サービスを削除します。その結果、クラウド・プロバイダはロード・バランサを削除します。 このコマンドの構文は次のとおりです。

$ kubectl delete svc SERVICE_NAME

たとえば、前の例からサービスを削除するには、次のように入力します:

$ kubectl delete svc nginx-service

パブリック・サブネットおよびプライベート・サブネット内での内部ロード・バランサの作成

クラスタ上で実行されているサービスへのアクセスを制御するOracle Cloud Infrastructureロード・バランサを作成できます:

  • カスタムのクラスタを作成する際に、新しいクラスタで使用されるネットワーク・リソースが含まれる既存のVCNを選択します。 ロード・バランサを使用してVCNへのトラフィックを制御するには、そのVCNにある既存のパブリックまたはプライベートのサブネットを選択してロード・バランサをホストします。
  • クイック・クラスタを作成する場合、自動的に作成されるVCNには、ロード・バランサをホストするパブリック・リージョン・サブネットが含まれます。 プライベート・サブネット内でロード・バランサをホストする場合、後でVCNにプライベート・サブネットを追加できます。

あるいは、クラスタ内に内部ロード・バランサ・サービスを作成して、クラスタと同じVCNで稼働している他のプログラムがクラスタ内のサービスにアクセスできるようにすることもできます。 パブリック・サブネットおよびプライベート・サブネットに内部ロード・バランサをホストできます。

パブリック・サブネットでホストされる内部ロード・バランサを作成するには、マニフェスト・ファイルのメタデータ・セクションに次の注釈を追加します:

service.beta.kubernetes.io/oci-load-balancer-internal: "true"

プライベート・サブネットでホストされる内部ロード・バランサを作成するには、次の両方の注釈をマニフェスト・ファイルのメタデータ・セクションに追加します:

service.beta.kubernetes.io/oci-load-balancer-internal: "true"

service.beta.kubernetes.io/oci-load-balancer-subnet1: "ocid1.subnet.oc1..aaaaaa....vdfw"

ocid1.subnet.oc1..aaaaaa....vdfwは、プライベート・サブネットのOCIDです。

例えば:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
  annotations:
    service.beta.kubernetes.io/oci-load-balancer-internal: "true"
    service.beta.kubernetes.io/oci-load-balancer-subnet1: "ocid1.subnet.oc1..aaaaaa....vdfw"
spec:
  type: LoadBalancer
  ports:
  - port: 8100
  selector:
    app: nginx

代替ロード・バランサ・シェイプの指定

Oracle Cloud Infrastructureロード・バランサのシェイプは、最大合計帯域幅(つまり、イングレスとエグレス)を指定します。 デフォルトでは、ロード・バランサは100Mbpsのシェイプで作成されます。 400Mbpsと8000Mbpsを含む他のシェイプも利用可能です。

ロード・バランサの代替のシェイプを指定するには、マニフェスト・ファイルのメタデータ・セクションに次の注釈を追加します:

service.beta.kubernetes.io/oci-load-balancer-shape: <value>

valueはシェイプの帯域幅です(たとえば、100 Mbps、400 Mbps、8000Mbps)。

例えば:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
  annotations:
    service.beta.kubernetes.io/oci-load-balancer-shape: 400Mbps
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx

ノート: 指定したシェイプのリージョンでは、十分なロードバランサクォータが使用可能でなければなりません。 次のkubectlコマンドを入力して、クォータが不足してロード・バランサの作成が失敗しなかったことを確認します:

$ kubectl describe service <service-name>

Load Balancer接続タイムアウトの指定

クライアントとバックエンド・サーバー間で、連続する2つの受信操作または2つの送信操作の間で許容される最大アイドル時間(秒)を指定できます。

最大アイドル時間を明示的に指定するには、マニフェスト・ファイルのメタデータ・セクションに次の注釈を追加します:

oci-load-balancer-connection-idle-timeout: <value>

ここで、valueは秒です。

例えば:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
  annotations:
    oci-load-balancer-connection-idle-timeout: 100
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx

最大アイドル時間を明示的に指定しない場合、デフォルト値が使用されます。 デフォルト値は、リスナーのタイプによって異なります:

  • TCPリスナーの場合、デフォルトの最大アイドル時間は300秒です。
  • HTTPリスナーの場合、デフォルトの最大アイドル時間は60秒です。

Load Balancerセキュリティ・リスト管理オプションの指定

セキュリティ・リストの管理方法を指定できます。

セキュリティ・リスト管理モードを明示的に指定するには、マニフェスト・ファイルのメタデータ・セクションに次の注釈を追加します:

oci-load-balancer-security-list-management-mode: <value>

ここで、<value>は次のいずれかです:

  • "All": ロード・バランサ・サービスに必要なすべてのセキュリティ・リスト・ルールが管理されます。
  • "Frontend": ロード・バランサ・サービスに対するイングレスのセキュリティ・リスト・ルールのみが管理されます。 ノード・ポート範囲、kube-proxyポートおよびヘルス・チェック・ポート範囲の適切なポートへのインバウンド・トラフィックを許可するルールを設定する必要があります。
  • "None": セキュリティ・リスト管理は有効になっていません。 ノード・ポート範囲、kube-proxyポートおよびヘルス・チェック・ポート範囲の適切なポートへのインバウンド・トラフィックを許可するルールを設定する必要があります。 さらに、インバウンド・トラフィックがロード・バランサをロードできるようにルールを設定する必要があります。

例えば:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
  annotations:
    oci-load-balancer-security-list-management-mode: "Frontend"
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx

oci-load-balancer-security-list-management-modeに対して無効な値を指定した場合は、かわりに値"All"が使用されます。

Load Balancerリスナー・プロトコルの指定

リスナーが接続リクエストを受け入れるプロトコルを指定することによって、ロード・バランサ・リスナーが受信するトラフィックのタイプを定義できます。

ロード・バランサ・リスナー・プロトコルを明示的に指定するには、マニフェスト・ファイルのメタデータ・セクションに次の注釈を追加します:

oci-load-balancer-backend-protocol: <value>

ここで、<value>はリスナーが受け入れたトラフィックのタイプを定義するプロトコルです。 たとえば、"HTTP"です。 有効なプロトコルのリストを取得するには、ListProtocols操作を使用します。

例えば:

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
  annotations:
    oci-load-balancer-backend-protocol: "HTTP"
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx

明示的にプロトコルを指定しない場合、デフォルト値として"TCP"が使用されます。