Kubernetes Ingressを利用したクラスタ外部公開

Ingressとは、Podをクラスタ内外に公開するL7、つまりHTTPに基づいて振り分け可能なロードバランサーを指す。クラスタ外部からURLのホストやパスによってサービスを振り分けることができる。外部アクセスは公開DNSを使用して行われる。

Ingressアドオンを有効化する

では、使い方を見ていこう。次のコマンドを使用して、minikubeでIngressアドオンを有効化する。

minikube addons enable ingress

実行結果:

% minikube addons enable ingress
💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
💡  After the addon is enabled, please run "minikube tunnel" and your ingress resources would be available at "127.0.0.1"
    ▪ Using image k8s.gcr.io/ingress-nginx/controller:v1.2.1
    ▪ Using image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
    ▪ Using image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1
🔎  Verifying ingress addon...
🌟  'ingress' アドオンが有効化されました

次に、以下のコマンドを実行してminikubeのアドオン一覧を表示し、ingressが有効化されているか確認する。

minikube addons list

実行結果:

% minikube addons list
|-----------------------------|----------|--------------|--------------------------------|
|         ADDON NAME          | PROFILE  |    STATUS    |           MAINTAINER           |
|-----------------------------|----------|--------------|--------------------------------|
| ambassador                  | minikube | disabled     | 3rd party (Ambassador)         |

... 中略 ...

| inaccel                     | minikube | disabled     | 3rd party (InAccel             |
|                             |          |              | [info@inaccel.com])            |
| ingress                     | minikube | enabled ✅   | Kubernetes                     | <<< 有効化
| ingress-dns                 | minikube | disabled     | Google                         |

... 中略 ...

| volumesnapshots             | minikube | disabled     | Kubernetes                     |
|-----------------------------|----------|--------------|--------------------------------|

次に、以下のコマンドを実行してIngress controller Podが作成されたか確認する。

kubectl get pods -n ingress-nginx
% kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-sqvcp        0/1     Completed   0          8m9s
ingress-nginx-admission-patch-t6cj5         0/1     Completed   1          8m9s
ingress-nginx-controller-755dfbfc65-cf8ww   1/1     Running     0          8m9

minikubeの場合はこのようにアドオンを有効化してIngress controllerを作成できるが、クラウド環境ではIngress controllerをインストールする必要がある。

YAMLファイルを利用したIngressの実行

次に、接続を許可するパスをYAMLで定義する。今回はhello-world Podをすべてのパス/で公開する。そのために、次のようなYAMLファイルを作成する。

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: helloworld
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: helloworld-nodeport
                port:
                  number: 8080

このYAMLファイルでは、Ingressの名前をhelloworldとし、http配下にパスに関するルールを記載している。また、pathとして/に来た場合にどのServiceへ接続するかをbackendの場所に記入している。ここではhelloworld-nodeportにポート8080で接続されるように定義している。

このファイルを使用してマニフェストを作成する。マニフェストについては後で説明するが、ここでは設定を反映させる程度に理解しておく。次のコマンドを使用して実行する。

kubectl apply -f ingress.yaml

実行結果:

% kubectl apply -f ingress.yaml
ingress.networking.k8s.io/helloworld created

Ingress一覧を表示し、上で作成したhelloworldのIngressが作成されたか確認するには、次のコマンドを実行する。

kubectl get ingress

実行結果:

% kubectl get ingress
NAME         CLASS   HOSTS   ADDRESS        PORTS   AGE
helloworld   nginx   *       192.168.49.2   80      69s

また、Ingress resourceの詳細を見るには、次のコマンドを実行する。

kubectl describe ingress [Ingress名]

helloworldの場合は、以下のように実行する。

% kubectl describe ingress helloworld
Name:             helloworld
Labels:           <none>
Namespace:        default
Address:          192.168.49.2
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /   helloworld-nodeport:8080 (172.17.0.3:8080)
Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /$1
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    40s (x2 over 80s)  nginx-ingress-controller  Scheduled for sync

さらに、次のコマンドでIngress controllerのIPを取得できる。このIPを使用して、Ingress経由でhelloworld-nodeport Serviceへアクセスする。

% kubectl get ingress | awk '{ print $4 }'|tail -1
192.168.49.2

Ingressを経由してアクセスしてみる。

% kubectl run --image curlimages/curl:7.68.0 -it --restart Never --rm curl sh
If you don't see a command prompt, try pressing enter.
/ $ curl 192.168.49.2
Hello, world!
Version: 1.0.0
Hostname: helloworld
/ $

これでIngress経由で安全にhelloworld-nodeportのServiceへアクセスし、helloworld Podに接続できたことを確認できる。