AKSのNGINX Ingress Controllerのデプロイで悩んだら

Posted on Feb 10, 2018

楽したいならhelmで入れましょう

AKSに限った話ではありませんが、Kubernetesにぶら下げるアプリの数が多くなってくると、URLマッピングやTLS終端がしたくなります。方法は色々あるのですが、シンプルな選択肢はNGINX Ingress Controllerでしょう。

さて、そのNGINX Ingress ControllerのデプロイはGitHubのドキュメント通りに淡々とやればいいのですが、helmを使えばコマンド一発です。そのようにドキュメントにも書いてあるのですが、最後の方で出てくるので「それ早く言ってよ」な感じです。

せっかくなので、Azure(AKS)での使い方をまとめておきます。開発ペースやエコシステムの変化が速いので要注意。この記事は2018/2/10に書いています。

使い方

AKSクラスターと、Azure DNS上に利用可能なゾーンがあることを前提にします。ない場合、それぞれ公式ドキュメントを参考にしてください。

ではhelmでNGINX Ingress Controllerを導入します。helmを使っていなければ、入れておいてください。デプロイはこれだけ。Chartはここ

$ helm install stable/nginx-ingress --name my-nginx

バックエンドへのつなぎが機能するか、Webアプリを作ってテストします。NGINXとApacheを選びました。

$ kubectl run nginx --image nginx --port 80
$ kubectl run apache --image httpd --port 80

サービスとしてexposeします。

$ kubectl expose deployment nginx --type NodePort
$ kubectl expose deployment apache --type NodePort

現時点のサービスたちを確認します。

$ kubectl get svc
NAME                                     TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                  AGE
apache                                   NodePort       10.0.244.167   <none>          80:30928/TCP                 14h
kubernetes                               ClusterIP      10.0.0.1       <none>          443/TCP                  79d
my-nginx-nginx-ingress-controller        LoadBalancer   10.0.91.78     13.72.108.187   80:32448/TCP,443:31991/TCP   14h
my-nginx-nginx-ingress-default-backend   ClusterIP      10.0.74.104    <none>          80/TCP                  14h
nginx                                    NodePort       10.0.191.16    <none>          80:30752/TCP                 14h

AKSの場合はパブリックIPがNGINX Ingress Controllerに割り当てられます。EXTERNAL-IPがpendingの場合は割り当て中なので、しばし待ちます。

割り当てられたら、EXTERNAL-IPをAzure DNSで名前解決できるようにしましょう。Azure CLIを使います。dev.example.comの例です。

$ az network dns record-set a add-record -z example.com -g your-dnszone-rg -n dev -a 13.72.108.187

TLSが終端できるかも検証したいので、Secretを作ります。証明書とキーはLet’s Encryptで作っておきました。

$ kubectl create secret tls example-tls --key privkey.pem --cert fullchain.pem

ではIngressを構成しましょう。以下をファイル名ingress-nginx-sample.yamlとして保存します。IngressでTLSを終端し、/へのアクセスは先ほどexposeしたNGINXのサービスへ、/apacheへのアクセスはApacheへ流します。rewrite-targetをannotaionsで指定するのを、忘れずに。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: ingress-nginx-sample
spec:
  rules:
    - host: dev.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: nginx
              servicePort: 80
          - path: /apache
            backend:
              serviceName: apache
              servicePort: 80
  tls:
    - hosts:
      - dev.example.com
      secretName: example-tls

あとは反映するだけ。

$ kubectl apply -f ingress-nginx-sample.yaml

curlで確認します。

$ curl https://dev.example.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[snip]

/apacheへのパスも確認します。

$ curl https://dev.example.com/apache
<html><body><h1>It works!</h1></body></html>

簡単ですね。