Closed1

Kubernetes内の自前DNSサーバにAWS NLBとEIPを使ってアクセス出来るようにする

harrythecodeharrythecode

解決したい課題

Kubernetes内の自前DNSサーバにAWS NLBとEIPを使ってアクセス出来るようにする方法を以下のように実装しました。説明のため細かな設定は省略しています。

実装例

  • 同一VPC内にPublic, Privateのサブネット
  • サブネット間の通信はルーティングテーブルで設定され、Firewallもオープンにし互いに疎通可能
  • PublicにはEC2上にDockerアプリが動作し、Network Load BalancerがElastic IP (固定IP) 付きで稼働
  • PrivateにはEKS上にDNSアプリが稼働。( e.g., label: app=dns, namespace: infra )

工夫したこと

AWS EKS上では「AWS Load Balancer Controller」がデフォルト?で稼働しており、K8sのService (Type: LoadBalancer)を作成すると自動的にLBが生成されるような仕組みがあります。

その際にドキュメント[1]と比較しながらmetadata.annotationsを以下の通り設定しました。

apiVersion: v1
kind: Service
metadata:
  # https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/service/annotations/
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-xxx
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
    service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-yyy
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
  name: infra-dns
  namespace: infra
spec:
  ports:
  - name: udp
    port: 53
    protocol: UDP
    targetPort: 53
  selector:
    app: dns
  type: LoadBalancer

💡 serviceとselectorで指定するpodは必ず同じnamespaceに配置しましょう。

ポイントは以下の2つです。

  • nlb-target-typeをipに指定
  • subnetsとeip-allocationsは同数でないとダメ

nlb-target-typeをipに指定

以下2つのモードが存在するのですが、配信効率を考えipモードを選択

instance: 全てのEC2インスタンスにselectorで指定したpodの所在を確認し、アクセスする
ip: serviceの後ろにあるpodへ直接アクセスする

subnetsとeip-allocationsは同数でないとダメ

Docker DNSでは複数のIPを指定可能ですが今回は冗長化を考えないので1つで済ませます。

Docker側の設定

docker composeを使用する場合はdnsパラメータを使い、EIPで生成されたIPを指定します。DNSサーバの指定は上から順番に読み込まれ、正常に動作するものが利用されます。公式ドキュメントも併せてご確認ください。

services:
  helloworld:
    image: hello-world
    container_name: helloworld
    dns:
      - x.x.x.x
脚注
  1. https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/service/annotations/ ↩︎

このスクラップは2023/03/17にクローズされました