NUCで始めるVMware Tanzu - TKCにアプリをデプロイ

今日は、せっかくTKCを建てたので、アプリをデプロイしてみましょう。

#MetalLBのデプロイ
[Day14](https://qiita.com/hirosat/items/a3b332281449d585609c#%E7%8F%BE%E5%9C%A8%E3%81%AE%E6%A7%8B%E6%88%90%E3%81%A7tkg%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E9%9A%9B%E3%81%AE%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85)でも少し触れましたが、TKCを利用する上で、一つ問題点があります。
こちらの、[Load Balancer for vSphere](https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.2/vmware-tanzu-kubernetes-grid-12/GUID-mgmt-clusters-vsphere.html#-load-balancers-for-vsphere-2)の注意事項をご覧下さい。
> NOTE: Kube-vip is an in-cluster load balancer that is solely used by the API server. It is not a general purpose Service type: load-balancer for vSphere. Tanzu Kubernetes Grid does not currently provide a Service type: load-balancer for vSphere. If you require load balancing, you can use a solution such as MetalLB.

TKG v1.2.x時点の制約として、TKGに統合されている [Kube-vip](https://kube-vip.io/) はAPI server用のLBなので、「Service type:LoadBalancer」 用のLBは、 [MetalLB](https://metallb.universe.tf/) などのソリューションを自前で用意する必要があるよ！ということですね。
それでは、VMware一推し(?)の、MetalLBをデプロイします！　[Installation](https://metallb.universe.tf/installation/) の通りにやってみます。

```shell:踏み台
$ kubectl edit configmap -n kube-system kube-proxy
# 以下、編集画面
apiVersion: v1
data:
  config.conf: |-
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
# (省略)
    ipvs:
      excludeCIDRs: null
      minSyncPeriod: 0s
      scheduler: ""
      strictARP: true  #←ここがfalseだったので修正
# (省略)
    kind: KubeProxyConfiguration
    metricsBindAddress: ""
    mode: "ipvs"  #←ここが""だったので修正

$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/namespace.yaml
# 成功時の出力例
namespace/metallb-system created

$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.5/manifests/metallb.yaml
# 成功時の出力例 (出力が長かったので、最後の行のみ)
deployment.apps/controller created

$ kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
# 成功時の出力例
secret/memberlist created

# 動作確認
$ kubectl get all -n metallb-system
NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-65db86ddc6-tf76b   1/1     Running   0          5m24s
pod/speaker-2hf7n                 1/1     Running   0          5m24s
pod/speaker-wlj7z                 1/1     Running   0          5m24s

NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker   2         2         2       2            2           kubernetes.io/os=linux   5m24s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           5m24s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-65db86ddc6   1         1         1       5m24s
```

お、Runningだ。問題なし。:smiley:

続いて、MetalLBの設定。実は、MetalLBには、2種類のモードが存在します。Layer2モードとBGPモードです。
Layer2モードは、クラスタ内の1台のマシンがサービスの所有権を取得してIPを外部公開し、標準的なアドレス検出プロトコル(IPv4はARP、IPv6はNDP)により、ローカルネットワーク上で到達可能にします。サービス権を取得したマシンは、ネットワーク上からは複数のIPを持っているように見えます。どれか1台のマシンのみで受け付けるため、実際にはロードバランシングしませんｗ　別マシンのPodには、クラスタ内を横断するコンテナネットワークによって到達します。
BGPモードは、クラスタ内の各マシンとBGP対応ルータがピアリングセッションを確立し、BGPポリシーに従って複数ノード間でちゃんとロードバランシングをしてくれます。ただし、我が家は普通の家庭用ルータなので、BGPをおしゃべりしてくれるルータを持っていないため、こちらのモードは諦めましたｗ

よって、Layer2モードで設定します。以下のように、アサインするIPプールを指定するだけです。

```shell
$ vi metallb-cm.yaml
# 以下、編集内容
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.5.61-192.168.5.70
# 編集ここまで

$ kubectl apply -f metallb-cm.yaml
configmap/config created
```

#APPのデプロイ
github上で"pod demo"と検索して人気があった、[hello-kubernetes](https://github.com/paulbouwer/hello-kubernetes)を使ってみます。

```shell:踏み台
$ vi hello-kubernetes.yaml
# 上記リンクの、Standard Configurationをコピペ

# デモアプリのデプロイ
$ kubectl apply -f hello-kubernetes.yaml
service/hello-kubernetes created
deployment.apps/hello-kubernetes created

# EXTERNAL-IPにIPアドレスが割り振られている！
$ kubectl get svc
NAME               TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
hello-kubernetes   LoadBalancer   100.65.85.225   192.168.5.61   80:30750/TCP   142m
kubernetes         ClusterIP      100.64.0.1      <none>         443/TCP        32h
```

上記でアサインされた、 http://192.168.5.61 にブラウザからアクセスしてみると・・・
<img width="776" alt="スクリーンショット 2020-12-15 19 30 28" src="https://user-images.githubusercontent.com/3906298/102203821-687b4a80-3f0c-11eb-93a8-7b8be2a767c1.png">
よし、成功！！

本日はこれまで！お疲れさまでした。