はじめに
Kubernetesではpodへの負荷分散を行うためにAWSのEKSなどのCloudサービス上で、ServiceとしてLoadBalancerを定義することが可能です。
AWSのALB等のサービスを利用して、podへの負荷分散を行える便利なServiceリソースなのですが、オンプレミスでは利用出来ません。 これをオンプレミスで利用出来るようにするのがMetalLBです。
今回は以下のリファレンスを参照して、MetalLBをインストールしていきます。
構成
MetalLB導入前の構成
Ingress ControllerをNodePortで公開する必要があり、外部からはNodePortを経由してアクセスします。
MetalLB導入後の構成
MetalLBを導入することで、Ingress ControllerをLoadBalancerタイプに変更でき、NodePortを使わずに外部からアクセス可能になります。
インストール
MetalLBにはBGP用と、BGPを利用していない小規模NW用のインストール方法が存在します。
今回は後者を利用します。
インストール実行
本記事執筆時点ではMetalLBのバージョンは「v0.15.2」です。
以下のコマンドを実行します。
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yamlKustomizeを利用している場合は以下の定義を利用します。
namespace: metallb-system
# URLをhttp経由で取得するために、公式ドキュメントのgit経由からURLを変更しています。resources: - https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yamlHelmでのインストールの場合は以下の定義を利用します。
helm repo add metallb https://metallb.github.io/metallbhelm install metallb metallb/metallborhelm install metallb metallb/metallb -f values.yamlMetalLB用のOperatorもあるようです。
今回はKustomizeを利用するため、以下のコマンドでデプロイします。
kubectl apply -k .デプロイすると以下のようになります。
[root@k8s-bastion ~]# kubectl get all -n metallb-systemNAME READY STATUS RESTARTS AGEpod/controller-58fdf44d87-4j2zp 1/1 Running 1 (117s ago) 2m37spod/speaker-4vjbx 1/1 Running 0 2m37spod/speaker-js6p6 1/1 Running 0 2m37spod/speaker-khxhd 1/1 Running 0 2m37spod/speaker-lkdk6 1/1 Running 0 2m37spod/speaker-xq59w 1/1 Running 0 2m37s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/metallb-webhook-service ClusterIP 10.108.202.241 <none> 443/TCP 2m38s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGEdaemonset.apps/speaker 5 5 5 5 5 kubernetes.io/os=linux 2m37s
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/controller 1/1 1 1 2m37s
NAME DESIRED CURRENT READY AGEreplicaset.apps/controller-58fdf44d87 1 1 1 2m37s現状、利用するIPアドレスを設定していないため、
このままではLoadBalancerを定義してもIPアドレスが割り振られないため、IPアドレスを設定していきます。
利用するIPアドレスの設定
MetalLBで利用するIPアドレスの範囲を設定するために、IPAddressPoolとL2Advertisementの2つのリソースを定義します。
IPAddressPool の作成
IPAddressPoolリソースでは、LoadBalancerに割り当てるIPアドレスの範囲を定義します。
単一のIP,CIDR指定等可能ですが、今回は単一のIP指定にします。
apiVersion: metallb.io/v1beta1kind: IPAddressPoolmetadata: name: default-pool namespace: metallb-systemspec: addresses: - 192.168.0.50/32L2Advertisement の作成
L2Advertisementリソースでは、L2モード(ARP)でIPアドレスをアドバタイズする設定を行います。
apiVersion: metallb.io/v1beta1kind: L2Advertisementmetadata: name: default-l2 namespace: metallb-systemspec: ipAddressPools: - default-pool # 上記で定義したIPAddressPoolの名前を指定デプロイ
上記の2つのリソースをデプロイします。
せっかくKustomizeを利用しているので、resourcesに追加しちゃいましょう。
namespace: metallb-system
resources: - https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml - ipaddresspool.yaml - l2advertisement.yamlIngress ControllerをLoadBalancerタイプに変更
Ingress Controllerを事前に設定しているため、Ingress ControllerのServiceをLoadBalancerタイプに変更します。
これにより、外部からMetalLBが割り当てたIPアドレス経由でIngress Controllerにアクセス可能となり、portを意識する必要が無くなります。
なお、Ingress Controllerのセットアップについては以下の記事を参照してください。
Ingress ControllerをLoadBalancerに変更
Ingress ControllerはデフォルトでNodePortで公開されていますが、これをLoadBalancerに変更します。
Kustomizeを利用している場合は、以下のようにpatchで変更できます。
利用していない場合は、kubectl edit service/ingress-nginx-controller -n ingress-nginxでも修修正可能です。
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.13.3/deploy/static/provider/baremetal/deploy.yaml
patches: - target: kind: Service name: ingress-nginx-controller namespace: ingress-nginx patch: |- - op: replace path: /spec/type value: LoadBalancerkubectl apply -k .デプロイ後、Ingress ControllerのTypeがLoadBalancerに変わり、EXTERNAL-IPが割り振られます。
[root@k8s-bastion ]# kubectl get service -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx-controller LoadBalancer 10.111.186.246 192.168.0.50 80:30080/TCP,443:30443/TCP 46hこれで外部からhttp://192.168.0.50でIngress Controllerにアクセスできるようになります。
各アプリケーション(Redmine等)はClusterIPのServiceのままで、Ingressリソースで定義したホスト名(例:redmine.home.tessy.dev)でアクセス可能になります。
まとめ
オンプレミス環境では、通常LoadBalancerタイプのServiceを利用できず、NodePortを使う必要がありました。
MetalLBを導入することで、Cloud環境と同様にLoadBalancerタイプのServiceを利用できるようになり、IPアドレスのみでアクセス可能となりました。
これにより、外部サービスからportを意識する必要がなくなるため、より汎用的な設定が可能となりました。