multipass上のmicrok8s(kubernetes)にIngressを導入してブラウザで表示するまで

# はじめに
ローカルで動作させるのkubernetes環境をできる限りクラウド上にあるクラスターと同一にするため、microk8sにIngressを導入してみる。

ローカル環境で動作するkubernetesとしては[minikube](https://minikube.sigs.k8s.io/) が有名だと思いますが、自分は [microk8s](https://microk8s.io/) を使っています。
また、Mac/Linuxの両方で同じように使いたいので、[multipass](https://multipass.run/) を間にはさんでいます。

multipassを使ったmicrok8s環境構築に興味がある方は [こちらの記事](https://qiita.com/cashewnuts/items/b4120ba9e0171328251f) をどうぞ

# 注意点・前提条件

microk8sをインストールしたmultipassのインスタンスとして `microk8s-vm` を作成しています。
また、このインスタンスは [こちらの記事](https://qiita.com/cashewnuts/items/b4120ba9e0171328251f) で作成したもので、以下のようにして `microk8s.kubectl` のaliasとして `kubectl` が設定されています。

```
$ snap alias microk8s.kubectl kubectl
```

以下、特に断りがなければ例示しているコマンドはmultipassのゲスト環境（VMインスタンス内）で実行されたものになります。
ホスト側でゲストのコマンドを実行するには以下のようにする必要があります。
場合によって適宜置き換えて確認してください。

```
multipass exec <インスタンス名(microk8s-vm)> -- <ゲスト側のコマンド>
```

# やってみる

## multipassインスタンスにログイン
まずはホストからmicrok8sのあるゲスト環境に入ります。

```
$ multipass shell microk8s-vm
```
## Ingressの `mandatory` リソースを作成
このリソース作成はどの環境、どのクラウドプロバイダーでIngressを使う場合でも共通です。

```
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.28.0/deploy/static/mandatory.yaml
```
## `nginx-ingress-controller` をデプロイする
この設定はクラウドプロバイダーごとに異なりますが、microk8sではIngressアドオンを有効化するだけでよい。

```
$ microk8s.enable ingress
```

`nginx-ingress-controller` が存在するかチェック

```
$ kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE                                    
nginx-ingress-controller-5556bd798f-9gvqv   1/1     Running   0          55s
```

## echoサーバーのServiceを作成
Ingressのルーティングを確認するため、appleサービスとbananaサービスを作成します。

```
# apple.yaml
kind: Pod
apiVersion: v1
metadata:
  name: apple-app
  labels:
    app: apple
spec:
  containers:
    - name: apple-app
      image: hashicorp/http-echo
      args:
        - "-text=apple"

---

kind: Service
apiVersion: v1
metadata:
  name: apple-service
spec:
  selector:
    app: apple
  ports:
    - port: 5678 # Default port for image
```

```
# banana.yaml
kind: Pod
apiVersion: v1
metadata:
  name: banana-app
  labels:
    app: banana
spec:
  containers:
    - name: banana-app
      image: hashicorp/http-echo
      args:
        - "-text=banana"

---

kind: Service
apiVersion: v1
metadata:
  name: banana-service
spec:
  selector:
    app: banana
  ports:
    - port: 5678 # Default port for image
```

以下のコマンドで、上記のリソースを作成します。

```
$ kubectl apply -f apple.yaml
$ kubectl apply -f banana.yaml
```

## Ingressを作成する
いよいよIngressを作成します。

```
# ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: echo-server
    http:
      paths:
        - path: /apple
          backend:
            serviceName: apple-service
            servicePort: 5678
        - path: /banana
          backend:
            serviceName: banana-service
            servicePort: 5678
```

以下のコマンドで http://echo-server/apple をappサービスへ、 http://echo-server/banana をbananaサービスへルーティングするIngressが作成されます。

```
$ kubectl create -f ingress.yaml
```

## 動作確認

appleサービスへアクセス

```
$ curl --header 'Host: echo-server' http://localhost/apple
apple
```

bananaサービスへアクセス

```
$ curl --header 'Host: echo-server' http://localhost/banana
banana
```

# ブラウザで表示する

ホスト環境のブラウザでIngressにアクセスするためには少し工夫が必要ですが、そこまで複雑ではありません。
以下のコマンドやファイルはすべてホスト側のものです。

## multipassインスタンスのIPを取得
multipassのインスタンスに割り当てられたIPアドレスを確認します。
以下のコマンドで `microk8s-vm` のIPアドレスが 10.205.54.200 であることがわかります。

```
$ multipass info microk8s-vm
Name:           microk8s-vm
State:          Running
IPv4:           10.205.54.200
Release:        Ubuntu 18.04.3 LTS
Image hash:     ae2c9391b71a (Ubuntu 18.04 LTS)
Load:           0.15 0.11 0.10
Disk usage:     2.7G out of 38.6G
Memory usage:   720.8M out of 3.9G
```

## `/etc/hosts` にecho-serverを設定
簡易DNSとして `/etc/hosts` に以下の1行を設定してください。

```
# /etc/hosts
...
echo-server    10.205.54.200
```

## ブラウザで表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308122/57204937-6147-852e-9745-db2e119f50d4.png)

# 資料

今回使ったファイルは以下にまとめています。

https://github.com/cashewnuts/qiita-sample/tree/ingress-on-microk8s/ingress-on-microk8s

# 参考文献

https://matthewpalmer.net/kubernetes-app-developer/articles/kubernetes-ingress-guide-nginx-example.html
https://kubernetes.io/docs/concepts/services-networking/ingress/