Amazon Elastic Container Service for Kubernetes(EKS)でClassic Load Balancer(CLB)とNetwork Load Balancer(NLB)を使ってみる

はじめに

EKSでCLBとNLBってどうつかうの?って疑問があったので調べながら構築してみました。

Classic Load Balancer(CLB)

こんなYAMLを書きます。

---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset-clb
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-clb
  template:
    metadata:
      labels:
        app: nginx-clb
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
          ports:
            - containerPort: 30081
---
apiVersion: v1
kind: Service
metadata:
  name: aws-clb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
    service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "environment=eks-mokumoku,owner=kato.ryo,lb_type=CLB" #Tags
    # https://kubernetes.io/docs/concepts/services-networking/service/#other-elb-annotations
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 80
      targetPort: 80
      nodePort: 30081
  selector:
    app: nginx-clb

ReplicaSetはシンプルにnginxのコンテナを3個建てるだけなので読み飛ばしてOKです。
metadataannotationsに注目してください。ここでCLBの各設定を行う事ができます。今回はプロトコルにHTTPを指定と任意のタグを付けてみました。
他の設定項目はこちらのKubernetesの公式ドキュメントからご確認ください。
https://kubernetes.io/docs/concepts/services-networking/service/#other-elb-annotations
AWS Certificate Managerに登録されている証明書を関連付ける方法なども紹介されています。

実際にデプロイしてみます。正しくロードバランスされているか確認する為に、各コンテナのindex.htmlを上書きしています。

$ kubectl apply -f aws-clb.yaml
$ kubectl get services
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP                                                              PORT(S)        AGE
aws-clb      LoadBalancer   10.100.106.180   ****-********.us-west-2.elb.amazonaws.com   80:30082/TCP   39m
kubernetes   ClusterIP      10.100.0.1       <none>                                                                   443/TCP        22d
$ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
nginx-replicaset-clb-7w9vq   1/1     Running   0          6m
nginx-replicaset-clb-d4lgs   1/1     Running   0          6m
nginx-replicaset-clb-q5q2l   1/1     Running   0          6m
$ kubectl exec -it nginx-replicaset-clb-7w9vq -- bash -c "echo nginx-replicaset-clb-7w9vq >> /usr/share/nginx/html/index.html"
$ kubectl exec -it nginx-replicaset-clb-d4lgs -- bash -c "echo nginx-replicaset-clb-d4lgs >> /usr/share/nginx/html/index.html"
$ kubectl exec -it nginx-replicaset-clb-q5q2l -- bash -c "echo nginx-replicaset-clb-q5q2l >> /usr/share/nginx/html/index.html"

Amazon EC2(ロードバランサ)のコンソールからロードバランサの状態を確認してみましょう。
リンクはオレゴンリージョンでは、EKSをしているということは東京以外のリージョンですよね、間違ったリージョンの画面を開いてないかお気をつけください。

無事にデプロイされており、DNS名でアクセスできました。

更新やシークレットブラウザで開くと最終行が違った内容に変化しロードバランサが動作していることも確認できました。

ReplicaSetは3ですが、ELBからのロードバランス先は2個となります、これはELBがロードバランスしてくれるのはKubernetesのノードまでだからです。

NLBと重複しない設計になっていますが、忘れない内に作った環境を削除しておきましょう。

$ kubectl delete -f aws-clb.yaml

Network Load Balancer(NLB)

続いてNLBです、まずYAMLを御覧ください、CLBの場合とほぼ変更はありません。
またnameやportは重複しないように変更しておきました。

---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset-nlb
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-nlb
  template:
    metadata:
      labels:
        app: nginx-nlb
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
          ports:
            - containerPort: 30082
---
apiVersion: v1
kind: Service
metadata:
  name: aws-nlb
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "environment=eks-mokumoku,owner=kato.ryo,lb_type=NLB" #Tags
    # https://kubernetes.io/docs/concepts/services-networking/service/#other-elb-annotations
spec:
  type: LoadBalancer
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 80
      targetPort: 80
      nodePort: 30082
  selector:
    app: nginx-nlb

annotationsservice.beta.kubernetes.io/aws-load-balancer-type: "nlb"を指定すればNLBが利用可能です。
デプロイから動作確認までやってみましょう。

$ kubectl apply -f aws-nlb.yaml
$ kubectl get services
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP                                                                     PORT(S)    AGE
aws-nlb      LoadBalancer   10.100.98.92   ****-********..elb.us-west-2.amazonaws.com   80:30082/TCP   4m
kubernetes   ClusterIP      10.100.0.1     <none>                                                                          443/TCP    22d
$ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
nginx-replicaset-nlb-gvh7p   1/1     Running   0          4m
nginx-replicaset-nlb-q8lfc   1/1     Running   0          4m
nginx-replicaset-nlb-xfwnj   1/1     Running   0          4m
$ kubectl exec -it nginx-replicaset-nlb-gvh7p -- bash -c "echo nginx-replicaset-nlb-gvh7p >> /usr/share/nginx/html/index.html"
$ kubectl exec -it nginx-replicaset-nlb-q8lfc -- bash -c "echo nginx-replicaset-nlb-q8lfc >> /usr/share/nginx/html/index.html"
$ kubectl exec -it nginx-replicaset-nlb-xfwnj -- bash -c "echo nginx-replicaset-nlb-xfwnj >> /usr/share/nginx/html/index.html"

Amazon EC2(ロードバランサ)のコンソールからロードバランサの状態を確認します。

NLBの場合はターゲットグループもあります、 Amazon EC2(ターゲットグループ) のコンソールから確認しましょう。

CLBの時はスクショを忘れてしまいましたが、ちゃんとタグも付けられています。

DNS名でアクセスしてみます。

無事にロードバランスされていました。

今回の構成

最後にですが、今回の構成図はこんな感じです!

あとがき

文字列でロードバランスされていることは確認しましたが、きれいに切り替わる感じでなく何回か更新を繰り返すと変わるという感じでした、ちゃんとロードバランスできているか不安があります...
そこらへんは実際に触っていく中で知識を深めていこうかなと思って今回は切り上げました。
勉強するときは素直に公式ドキュメントを読むのが良さそうです。