生k8sでIngressを使用する

# はじめに
特定の名前によるアクセスによる制御をKuberentesでやりたいという需要があります
これらの制御は、Ingressリソースを使用して制御します。

KuberentesでIngressリソースを利用するためにはIngressコントローラを導入しないと動作しません。
本記事では、[Nginx Ingress](https://kubernetes.github.io/ingress-nginx/)を導入する方法を解説しますが、Ingressコントローラはほかにもありますので、調べてみてください。

実際に、Nginx Ingressコントローラを導入した場合の動作図を以下に示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425374/5866eb0a-0379-d71f-df66-ad1287b848df.png)

図 Nginx-Ingressの動作イメージ


# Nginx-Ingressのインストール

以下のコマンドを実行してインストールを行います。

```bash
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/baremetal/deploy.yaml
kubectl apply -f deploy.yaml
```
実行すると以下の通り動作します。

```bash
$ kubectl get all -n ingress-nginx
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-fzccw        0/1     Completed   0          17m
pod/ingress-nginx-admission-patch-x8qvv         0/1     Completed   0          17m
pod/ingress-nginx-controller-55bc4f5576-7dqxz   1/1     Running     0          17m

NAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.106.114.222   <none>        80:31823/TCP,443:31739/TCP   17m
service/ingress-nginx-controller-admission   ClusterIP   10.108.135.62    <none>        443/TCP                      17m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           17m

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-55bc4f5576   1         1         1       17m

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           2s         17m
job.batch/ingress-nginx-admission-patch    1/1           2s         17m
```

## External IPの有効

もし、External IPを設定する場合は、上記のダウンロードした`deploy.yaml`を以下の通り編集する

```yaml:deploy.yaml
# --略---
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-3.30.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.46.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
  externalIPs:
    - 192.168.223.150
# ---略---
```

## ingress controllerのアクセス確認

まず、サービス状態を確認します。

```bash
$ kubectl get service -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.99.97.169    192.168.223.150   80:30958/TCP,443:30576/TCP   3s
ingress-nginx-controller-admission   ClusterIP   10.108.135.62   <none>            443/TCP                      22m
```
サービスリソースの状態から、ingress-nginx-controllerのPodにアクセスすると以下の通りになる

* nodeportアクセス

```bash
$ curl localhost:30958
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
$ curl https://localhost:30576 -k
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
```

* External IPアクセス

```bash
$ curl 192.168.223.150
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
```

# Nginxの動作テスト
nginxコンテナを動かすのdeploymentリソースとそれと紐づくServiceリソースのYAMLは以下の通りになります。

```yaml:pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP
```
ingressリソースの設定ファイルを以下の通りなります。

```yaml:ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-host-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: first.bar.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80
```

両方を適応するして、host名前でアクセスすると以下の通り動作になります。

* nodeportアクセス

```bash
$ curl 192.168.223.220:30958 --header "HOST: first.bar.com"<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

$ curl https://192.168.223.220:30576  --header "HOST: first.bar.com" -k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

* External IPアクセス

```bash
$ curl 192.168.223.150 --header "HOST: first.bar.com"
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

$ curl https://192.168.223.150 --header "HOST: first.bar.com" -k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

# 終わりに
以上で、名前でアクセスすると、対象のPodに割り振ることができるようになりました。
完全に名前でアクセス解決したい場合は、hostsファイルを編集するか
プロキシーサーバやDNSサーバーを立てる必要があります。

これで、やることができることが増えるようになります。