k3s上にNginx Ingressを使ってWebアプリをデプロイ

＊すでにk3sのクラスタがある前提で話をすすめます．

# はじめに

Kubernetesの機能であるIngressを使います．IngressはTCP/IPのLayer 7(つまりHTTP)のレベルでアクセスを制御するKubenetesの機能です．具体的には，URLルーティングを行います．これは `http://example.com/hello` と `http://example.com/world` で別のサーバ（コンテナ）を参照させることです．IngressにはKubenetesクラスタの内部に構築するものと，外部に構築するものがあります．今回は内部に構築するものを使います．Ingressの動作は以下の図が分かりやすいです．IngressからNodePortへ振り分けられ，その後Podへ振り分けられています．

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/280a6325-01b4-cd38-3af7-e1f2d23fa82d.png)
出典:  [KubernetesのDiscovery＆LBリソース（その2） | Think IT（シンクイット）](https://thinkit.co.jp/article/13739)

# Nginx Ingressを動かす

Nginx Ingressを動かす．
https://kubernetes.github.io/ingress-nginx/deploy/

インストール

```bash
$ sudo k3s kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml
```

確認

```bash
$ alias k='sudo k3s kubectl'  # これ便利です
$ k get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --watch
NAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-patch-7hjpr        0/1     Completed   0          82s
ingress-nginx-admission-create-6gfst       0/1     Completed   0          82s
ingress-nginx-controller-f8d756996-bb6gz   1/1     Running     0          92s
```

# Ingressを使ったデプロイ

以下のファイルをデプロイする．

```bash
$ k apply -f ingress-app.yaml
$ k apply -f ingress-controller.yaml
```

```yaml:ingress-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: get-my-host
  labels:
    app: hostname
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hostname
  template:
    metadata:
      labels:
        app: hostname
    spec:
      containers:
      - name: host-app
        image: adongy/hostname-docker
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: get-my-host
spec:
  type: NodePort
  selector:
    app: hostname
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 4000
      targetPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: get-my-info
  labels:
    app: nginxdemo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginxdemo
  template:
    metadata:
      labels:
        app: nginxdemo
    spec:
      containers:
      - name: info-app
        image: nginxdemos/hello
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: get-my-info
spec:
  type: NodePort
  selector:
    app: nginxdemo
  ports:
    - name: "http-port"
      protocol: "TCP"
      port: 4000
      targetPort: 80
```

```yaml:ingress-controller.yaml
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
    ingress.kubernetes.io/rewrite-target: "/"
spec:
  rules:
  - http:
      paths:
      - path: /hello
        backend:
          serviceName: get-my-info
          servicePort: 4000
      - path: /world
        backend:
          serviceName: get-my-host
          servicePort: 4000
```

うまく動いていた時

```bash
$ k get all
NAME                               READY   STATUS    RESTARTS   AGE
pod/my-ingress-default             1/1     Running   0          11h
pod/get-my-info-6666748778-5gxnv   1/1     Running   0          5m1s
pod/get-my-host-7449f7cf55-6hjzg   1/1     Running   0          5m1s
pod/get-my-info-6666748778-nxlgs   1/1     Running   0          5m1s
pod/get-my-info-6666748778-vzmxx   1/1     Running   0          5m1s
pod/get-my-host-7449f7cf55-d8bm7   1/1     Running   0          5m1s
pod/get-my-host-7449f7cf55-ncrvz   1/1     Running   0          5m1s

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kubernetes    ClusterIP   10.43.0.1       <none>        443/TCP          13h
service/get-my-host   NodePort    10.43.140.123   <none>        4000:32265/TCP   5m1s
service/get-my-info   NodePort    10.43.73.32     <none>        4000:31270/TCP   5m1s

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/get-my-info   3/3     3            3           5m1s
deployment.apps/get-my-host   3/3     3            3           5m1s

NAME                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/get-my-info-6666748778   3         3         3       5m1s
replicaset.apps/get-my-host-7449f7cf55   3         3         3       5m1s

$ k get ingress
NAME            HOSTS   ADDRESS        PORTS   AGE
nginx-ingress   *       192.168.0.17   80      11h
```

ブラウザからアクセスしてみる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/5c5a33c9-ac1d-498a-4e62-13fef4985827.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/f7360bc7-ec80-8e96-ea7a-030a17a71f7b.png)

ユーザのリクエストがコンテナに到達するまでのながれ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/0bf6e1e9-9af2-ebf9-e22d-c4b373e43666.png)