Helmを使ってMetalLBをデプロイしてLoadBalancerを使う

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

前回の記事でkubetnetesクラスタ上にHelmをデプロイしました。今回はHelmを使ってMetalLBをデプロイしてLoadBalancerを使えるようにしていきたいと思います。
前回の記事は以下となります。

https://qiita.com/ohtsuka-shota/items/f94cb16deba812285758

なお、Helmを使わないMetalLBのデプロイは以下で実施しております。※やっていたことを忘れていたとは口が裂けても言えない。

https://qiita.com/ohtsuka-shota/items/2bcf2cd0d0b0c159cb8d


# MetalLBとは
以下の私の記事上で分かりやすい引用元を掲載しておりますので、確認したい方はリンク先に飛んで頂けますと幸いです。

https://qiita.com/ohtsuka-shota/items/ad62014ee93bfbc57c9f

# 構築イメージ
今回構築するイメージは以下となります。
k8sクラスタ上にmetal-lb namespaceとwp namespaceを作成し、metal-lb namespace上にmetallb関連のpod,serviceをデプロイします。次にwp namespace上にwordpress環境に必要になるものをデプロイしていきます。

![k8s_3-ページ11.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/e8e0a02c-c702-4995-4064-81e8b0a0b6cd.png)

# 参考サイト

https://metallb.universe.tf/installation/#installation-with-helm

https://zenn.dev/vampire_yuta/articles/ccbc57be8e092a

# 環境構築
## namespaceの作成
以下のコマンドを使ってnamespaceを作ります。
```
root@k8s-master:~/yaml/configmap# kubectl create ns metal-lb
namespace/metal-lb created
root@k8s-master:~/yaml/configmap# kubectl create ns wp
namespace/wp created
root@k8s-master:~/yaml/configmap# kubectl get ns
NAME              STATUS   AGE
default           Active   21d
kube-node-lease   Active   21d
kube-public       Active   21d
kube-system       Active   21d
metal-lb          Active   14s
observability     Active   7d5h
wp                Active   6s
```

## MetalLBのデプロイ
Helmを使ってMetalLBをデプロイしていきます。
MetalLBのリポジトリを追加した後、デプロイします。--namespaceオプションを使うことで、そこで指定したnamespaceにデプロイしてくれます。
```
root@k8s-master:~/yaml/metal-lb# helm ls
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION

root@k8s-master:~/yaml/metal-lb# helm repo add metallb https://metallb.github.io/metallb
root@k8s-master:~/yaml/metal-lb# helm install metallb metallb/metallb --namespace metal-lb
NAME: metallb
LAST DEPLOYED: Sat Jul  1 14:01:52 2023
NAMESPACE: metal-lb
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
MetalLB is now running in the cluster.

Now you can configure it via its CRs. Please refer to the metallb official docs
on how to use the CRs.
```

podとserviceを確認してみます。
speakerとcontrollerの役割は以下の様です。私のk8s環境は7台構成の為、speaker podが7つある形となります。
speaker：全てのnodeで動作するpod。MetalLBサービスの到達性を確保する
controller：IPアドレスの管理や払い出しを行うもの
```
root@k8s-master:~/yaml/metal-lb# kubectl get pod,svc -n metal-lb 
NAME                                      READY   STATUS    RESTARTS   AGE
pod/metallb-controller-5cd9b4944b-hdbkj   1/1     Running   0          34s
pod/metallb-speaker-k84gr                 4/4     Running   0          34s
pod/metallb-speaker-pvc82                 4/4     Running   0          34s
pod/metallb-speaker-pzqdg                 4/4     Running   0          34s
pod/metallb-speaker-s7vk2                 4/4     Running   0          34s
pod/metallb-speaker-t86kq                 4/4     Running   0          34s
pod/metallb-speaker-xsgsf                 4/4     Running   0          34s
pod/metallb-speaker-zfptn                 4/4     Running   0          34s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/metallb-webhook-service   ClusterIP   10.109.95.209   <none>        443/TCP   35s
```

## MetalLBのAddress Poolを定義する
MetalLBがLoadBalancerに対して割り当てるためのAddress Poolを定義します。
以下のyamlを用意します。今回は192.168.2.45～49のアドレスを持たせています。
```metallb-config.yaml 
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metal-lb
spec:
  addresses:
  - 192.168.2.45-192.168.2.49
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default
  namespace: metal-lb
spec:
  ipAddressPools:
  - default
```

これをデプロイします。
```
root@k8s-master:~/yaml/configmap# kubectl apply -f metallb-config.yaml
ipaddresspool.metallb.io/default created
l2advertisement.metallb.io/default created
```

## wordpress関連をデプロイする
4つのyamlを用意します。
```wordpress-pod.yaml
apiVersion: v1 
kind: Pod 
metadata: 
  name: wordpress-pod 
  namespace: wp
  labels: 
    app: wordpress  
spec: 
  containers: 
    - name:  wordpress-con 
      image: wordpress:php8.1-apache 
      ports: 
      - containerPort: 80 
      env: 
      - name: WORDPRESS_DB_HOST 
        value: mysql-clusterip 
      - name: WORDPRESS_DB_USER 
        value: devuser 
      - name: WORDPRESS_DB_PASSWORD 
        value: password 
      - name: WORDPRESS_DB_NAME 
        value: gke-wordpress-database
```
```mysql-pod.yaml
apiVersion: v1 
kind: Pod 
metadata: 
  name: mysql-pod  
  namespace: wp
  labels: 
    app: mysql  
spec: 
  containers: 
    - name:  mysql-con  
      image: mysql:8.0-debian 
      ports:  
      - containerPort: 3306  
      env: 
      - name: MYSQL_USER 
        value: devuser 
      - name: MYSQL_PASSWORD  
        value: password  
      - name: MYSQL_ROOT_PASSWORD  
        value: password  
      - name: MYSQL_DATABASE 
        value: gke-wordpress-database
```
```mysql-clusterip.yaml
apiVersion: v1  
kind: Service  
metadata:  
  name: mysql-clusterip 
  namespace: wp
spec:  
  selector:  
    app: mysql  
  type: ClusterIP  
  ports:  
  - name: mysql  
    port: 3306  
    protocol: TCP  
    targetPort: 3306
```
```wordpress-loadbalancer.yaml
apiVersion: v1 
kind: Service 
metadata: 
  name: wordpress-loadbalancer 
  namespace: wp 
spec: 
  type: LoadBalancer 
  selector: 
    app: wordpress
  ports: 
  - protocol: TCP 
    port: 60000 
    targetPort: 80
```

デプロイしていきます。
```
root@k8s-master:~/yaml/wp# kubectl apply -f mysql-clusterip.yaml
service/mysql-clusterip created
root@k8s-master:~/yaml/wp# kubectl apply -f mysql-pod.yaml
pod/mysql-pod created
root@k8s-master:~/yaml/wp# kubectl apply -f wordpress-loadbalancer.yaml
service/wordpress-loadbalancer created
root@k8s-master:~/yaml/wp# kubectl apply -f wordpress-pod.yaml
pod/wordpress-pod createdz
```

デプロイされていることを確認します。
podがrunningになっていること、及びLoadBalancerのEXTERNAL-IPにMetalLBで定義したIPアドレスが付与されていることを確認します。
```
root@k8s-master:~/yaml/wp# kubectl get pod,svc -n wp
NAME                READY   STATUS    RESTARTS   AGE
pod/mysql-pod       1/1     Running   0          52s
pod/wordpress-pod   1/1     Running   0          39s

NAME                             TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)           AGE
service/mysql-clusterip          ClusterIP      10.96.152.58    <none>         3306/TCP          58s
service/wordpress-loadbalancer   LoadBalancer   10.105.94.140   192.168.2.45   60000:31847/TCP   45s
```

Webブラウザでも確認します。
出来ていますね。
![fegfeihudhwj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/9d3ef4d1-7f8f-aad1-533d-2336b19ccf62.png)