0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Metal LBを試してみる

Last updated at Posted at 2025-05-06

はじめに

以下の記事の続き。「はじめてのデプロイ」ではあくまでデプロイすることに主眼を置いていたため、外部からのアクセスは NodePort を利用し、特定Worker ノードの持つアドレスへ Port 番号を使ってアクセスする、かなり強引なやり方だった。前段にMetal LBを置いて80/TCPとして通信を終端してそこから各Workerノードに通信を振り分ける仕組みを作ってみる。

Metal LB 3つの実装

2025年5月現在、これまでの実装のほか、Metal LBは BGP部分にFRRを利用する FRR-Modeと、FRR-K8s Modeが存在する。このうち、FRR-K8s Modeはまだ experimental とのこと。まずは標準実装での検証を行う。

Metal LB のインストール

当然ながら公式サイトの記述に沿って構築する。作業はすべて Master ノードで実施する。

インストールは Helm Chartを利用する方法と Manifest を利用する方法あるが、まずは Manifest でのインストールを試みる。

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-native.yaml

IPVSモード利用時の注意点
kube-proxyのIPVS (IP Virtual Server)モードとして利用している場合、Strict ARPをtrueにする必要があるとのこと。
今回試した環境ではデフォルトのiptables モード。iptables/IPVSどちらも、kube-proxyのTraffic 分散方式で、IPVS のほうがよりスケーラブル。今回の検証では、まずはデフォルトの iptables モードで進める。

正常性確認

Metal LBは名前空間 metallb-system にインストールされ、controllerとspeaker podがそれぞれ存在する。

ubuntu@k8s-master:~$ kubectl -n metallb-system get pod
NAME                         READY   STATUS    RESTARTS   AGE
controller-bb5f47665-jxcj2   1/1     Running   0          2m22s
speaker-g6mmh                1/1     Running   0          2m22s
speaker-kzhd6                1/1     Running   0          2m22s
speaker-qppgk                1/1     Running   0          2m22s
ubuntu@k8s-master:~$ kubectl -n metallb-system get service
NAME                      TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
metallb-webhook-service   ClusterIP   172.16.25.63   <none>        443/TCP   2m26s

Controller ...IPアドレスのアサインを行うコントローラ
Speaker ... デーモンセット。ユーザが選択した Protocol を使用して外部と接続する。

L2モードでの MetalLB

  1. Metal LB でのIPアドレス Pool を指定(metallb-l2-IPAddressPool.yaml
  2. Metal LB での広告設定(metallb-l2-Advertisement.yaml
  3. Metal LB を利用する Deployment 例(nginx-metallb-l2-deployment.yaml
  4. Metal LB を利用する Service設定例( nginx-metallb-l2-service.yaml

Metal LB でのIPアドレス Pool を指定

Pool アドレスレンジを指定する。Worker ノードが所属するセグメント(192.168.11.0/24)末尾で11アドレスを確保し、これをPoolアドレスとした。MetalLBを利用する場合、namespaceは基本的にmetallb-system上に作る模様。Pool アドレスに名前(first-Pool)を付け、これをL2Advertisement 側から呼び出す。

metallb-l2-IPAddressPool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.11.240-192.168.11.250

2022年7月にリリースされた 0.13.2から Config方法が変更された(ConfigMap ⇒ CRD)。少し古めのサイトだと Config Map での実装例となっているため注意(ハマった)。

https://metallb.universe.tf/release-notes/#version-0-13-2

Metal LB での広告設定

metallb-l2-IPAddressPool.yamlで定義したIPアドレスPoolをここのSpec で呼び出す。

metallb-l2-Advertisement.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
    - first-pool

Metal LB を利用する Deployment 例

nginx-metallb-l2-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-metallb-l2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-metallb-l2
  template:
    metadata:
      labels:
        app: nginx-metallb-l2
    spec:
      containers:
      - name: nginx
        image: nginx:stable
        command: ["/bin/sh", "-c", "/mnt/start.sh"]
        ports:
          - containerPort: 80
        volumeMounts:
        - mountPath: /mnt
          name: nfs-volume
      volumes:
      - name: nfs-volume
        persistentVolumeClaim:
          claimName: nfs-dynamic-pvc

Metal LB を利用する Service設定例

nginx-metallb-l2-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-metallb-l2-service
spec:
  selector:
    app: nginx-metallb-l2
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

設定投入

kubectl apply -f metallb-l2-IPAddressPool.yaml
kubectl apply -f metallb-l2-Advertisement.yaml
kubectl apply -f nginx-metallb-l2-deployment.yaml
kubectl apply -f nginx-metallb-l2-service.yaml

正常性確認

ubuntu@k8s-master:~$ kubectl get IPAddressPool -n metallb-system
NAME         AUTO ASSIGN   AVOID BUGGY IPS   ADDRESSES
first-pool   true          false             ["192.168.11.240-192.168.11.250"]
ubuntu@k8s-master:~$
ubuntu@k8s-master:~$ kubectl get L2Advertisement -n metallb-system
NAME      IPADDRESSPOOLS   IPADDRESSPOOL SELECTORS   INTERFACES
example   ["first-pool"]
ubuntu@k8s-master:~$ kubectl get pod -l app=nginx-metallb-l2
NAME                               READY   STATUS    RESTARTS   AGE
nginx-metallb-l2-d8b48657c-rqqp5   1/1     Running   0          3h16m
nginx-metallb-l2-d8b48657c-tlnq6   1/1     Running   0          3h16m

External-IPの確認

nginx-metallb-l2-serviceEXTERNAL-IPとして、IPアドレスPoolに含まれる192.168.11.240が払いだされていることが確認できる。

ubuntu@k8s-master:~$ kubectl get svc
NAME                       TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
(snip)
nginx-metallb-l2-service   LoadBalancer   172.16.102.250   192.168.11.240   80:32529/TCP   65m

アクセス確認

curlからExternal IPに指定された192.168.11.240へアクセスすると、それぞれのPodから応答してくれることが確認できる。NodePort だとかなり限定的だが、ようやっと外部からまともに見えるようになる。

ubuntu@k8s-master:~$ curl http://192.168.11.240
<html><body><h1>Hello from nginx-metallb-l2-d8b48657c-tlnq6</h1></body></html>
ubuntu@k8s-master:~$ curl http://192.168.11.240
<html><body><h1>Hello from nginx-metallb-l2-d8b48657c-rqqp5</h1></body></html>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?