LoginSignup
27
23

More than 5 years have passed since last update.

K8s on Vagrant, NGINX Ingress Controller の利用

Last updated at Posted at 2018-04-27

k8sクラスタ外部のトラフィックを受け入れて、負荷分散など実行しながら、ポッドへアクセスを分散させる方法です。

vagrantの仮想サーバーで、k8s v1.10のクラスタを動作させて検証した5回目の記事で、これまでの記事を列挙しておきます。

  1. Kubenetes v1.10 クラスタをVagrantで構築したメモ
  2. K8s on Vagrant, Node障害時の振る舞いについての検証記録
  3. K8s on Vagrant, ダッシュボードのセットアップ
  4. K8s on Vagrant, NFS 永続ボリュームの利用メモ

Ingressとは?

ノード横断のポッド・ネットワーク上のサービスやアプリケーションは、プライベートIPアドレスがアサインされますから、ルーティングする事が出来ないために、インターネットのクライアントと通信することができません。 このため、Ingressは、クラスタ内のサービス(通常はHTTP)に、クラスタ外部からのアクセスを橋渡しするもので、ロードバランシング、SSL/TLS暗号の終端処理、名前ベースの仮想ホスティングを提供するものです。 図にすると次の様になります。

スクリーンショット 2018-04-26 11.48.13.png

Ingressコントローラーの果たす役割範囲

外観的にIngressの役割が解ったので、Ingressの実装について、話を進めて行きたいと思います。IngressとIngressコントローラーと二つの言葉が出てきて混乱するのですが、この二つの言葉の違いを整理することから進めます。

次のIngressファイルは、kubectl apply -f ingress.yaml コマンドを使って適用します。 解説しやすくするために、行番号を付与してあります。 このIngressのYAMLを適用する事で、hello-world-svcを外部へ公開出来る様になります。

ingress.yaml
     1  apiVersion: extensions/v1beta1
     2  kind: Ingress
     3  metadata:
     4    name: hello-world-ingress
     5    namespace: ingress-nginx   
     6    annotations:
     7      kubernetes.io/ingress.class: 'nginx'
     8      nginx.org/ssl-services: 'hello-world-svc'
     9      ingress.kubernetes.io/ssl-redirect: 'false'
    10  
    11  spec:
    12    tls:
    13    - hosts:
    14      - abc.sample.com
    15      secretName: tls-certificate
    16    rules:
    17    - host: abc.sample.com
    18      http:
    19        paths:
    20        - path: /
    21          backend:
    22            serviceName: hello-world-svc
    23            servicePort: 8080

2行目 kind: Ingress として、この定義によって、APIオブジェクトのIngressを操作する事が解ります。
6行目 annotationsは、NGINX Ingressコントローラーへ送るパラメータで、Ingressコントローラーの動作を変更する事ができます。このアノテーションの詳細は、GitHubのNGINX Ingressコントローラ Annotaions に記載されています。

12行目 HTTPSに関する設定で、ドメイン名、そして、SSL/TLS暗号の証明書のシークレットを指定します。

17行目 ドメイン名 abc.sample.com でアクセスするのみが、アプリケーションのサービスに転送されます。 もし、IPアドレス直打ちでアクセスした場合は、後述のデフォルト・バックエンドサービスから応答を返します。

21行目 アプリケーションのサービス hello-world-svc を外部提供するものです。

このYAMLファイルとNGINX Ingress コントローラの関係を表したのが、次の図になります。

スクリーンショット 2018-04-26 13.39.20.png

水色のボックスで、「Ingress APIオブジェクト」が前述のingress.yaml を適用して作られるオブジェクトです。 Ingressのオブジェクトは、NGINX Ingressコントローラに指令を送り、外部からのトラフィックを、プライベートのポッド・ネットワークにアクセス用のIPアドレスを確保している水色ボックスのユーザーアプリのサービスに転送します。 そして、IngressのYAMLファイルのルールに該当し無い場合は、図中紫色のボックス 「default-backend」サービスにルーティングして、エラーメッセージ等をクライアントへ返します。

このingress.yaml を適用して作成したオブジェクトによって、NGINX Ingressコントローラに指令が送られ、アプリケーションへ要求のトラフィックが流れ込む様になります。 この内容は、kubectl get ingkubectl describe ingとして、内容を確認できます。

$ kubectl get ing
NAME                  HOSTS            ADDRESS         PORTS     AGE
hello-world-ingress   abc.sample.com   192.168.1.100   80, 443   1d

$ kubectl describe ing
Name:             hello-world-ingress
Namespace:        ingress-nginx
Address:          192.168.1.100
Default backend:  default-http-backend:80 (<none>)
TLS:
  tls-certificate terminates abc.sample.com
Rules:
  Host            Path  Backends
  ----            ----  --------
  abc.sample.com  
                  /   hello-world-svc:8080 (<none>)
Annotations:
  nginx.org/ssl-services:                            hello-world-svc
  ingress.kubernetes.io/ssl-redirect:                false
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"ingress.kubernetes.io/ssl-redirect":"false","kubernetes.io/ingress.class":"nginx","nginx.org/ssl-services":"hello-world-svc"},"name":"hello-world-ingress","namespace":"ingress-nginx"},"spec":{"rules":[{"host":"abc.sample.com","http":{"paths":[{"backend":{"serviceName":"hello-world-svc","servicePort":8080},"path":"/"}]}}],"tls":[{"hosts":["abc.sample.com"],"secretName":"tls-certificate"}]}}

  kubernetes.io/ingress.class:  nginx
Events:                         <none>

NGINX Ingressコントローラーのセットアップ

IBM Cloud Container Service などパブリック・クラウドでは、k8sクラスタを起動する段階で、Ingressコントローラは、自動的にセットアップされるので、前述のIngressのYAMLファイルだけを提供すれば良いのですが、今回の例の様に、自前で構築するケースでは、Ingressコントローラをセットアップする必要があります。 また、HELMには、https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress が提供されているので、HELMを利用したセットアップも可能になっています。

今回は、k8s on Vagrant のシリーズとして、自前でセットアップして、基礎を学ぶという目的がありますので、kubernetes/ingress-nginx Installation Guide を参考にして進めていきます。 設定作業は、全く同じではなく、内容に応じて、多少変更していますので、ご了承ください。

それから、実際の設定はで、kubectl apply -f https://github.com/kubernetes/ingress-nginx...の形で、GitHubから直接最新のYAMLを適用するという方法も取れます。 ここでは、内容を理解する事をフォーカスするので、YAMLのリストを提示して進めます。

NGINX Ingressコントローラーの範囲

外部へ公開するIPアドレス(VIP)の取得、ノードへのVIPアサイン、ノード停止時のVIPの他ノードへの付け替えは、NGINX Ingressコントローラの役割の範囲外となります。 このため、今回は、vagrant の仮想サーバーに、コマンドラインからifconfigでVIPをアサインして、動作を確認したいと思います。

NGINX Ingressコントローラ インストール

ネームスペースの作成

今回の検証用に、専用のネームスペースを作成して進めます。 次のYAMLファイルを kubectl apply -f namespace.yaml として適用することで、ネームスペースが作られます。 確認するには、kubectl get ns とすることで、作成済みのネームスペースをリストすることができます。

namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx

ネームスペースの変更

ネームスペースに対する操作は、kubectl get all -n ingress-nginxの様にオプションで指定できますが、毎回、オプションをセットすると、間違いの原因になりますから、 Qiita k8s便利コマンド Namespaceを恒久的に変更する方法に書いた方法を利用します。

(1) ネームスペース ingress-nginx の設定を作るには

$ kubectl config set-context ingress-nginx --namespace=ingress-nginx --cluster=kubernetes --user=kubernetes-adminContext 

(2) 作った設定に切り替えるには

$ kubectl config use-context ingress-nginx

(3) 元のネームスペース defaultにするには

$ kubectl config use-context kubernetes-admin@kubernetes

上記の(1)と(2)の方法で、ネームスペースを切り替えて、以下の作業を進めていきます。

ConfigMapのインストール

ConfigMapに、パラメータを設定することで、NGINX Ingress Controller のふるまいを変更することができます。 パラメータの種類は、https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md にあります。また、同ページのExampleに、設定例がありますので、迷わず設定できると思います。 適用は同様に kubectl apply -f configmap.yaml で実行します。

configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx

デフォルト・バックエンドのインストール

後述のIngressのルール設定で、ルールに該当しないケースに応答を返すためのデプロイとサービスです。 https://github.com/kubernetes/ingress-nginx/blob/master/deploy/default-backend.yaml 適用は、kubectl apply -f default-backend.yamlとします。

default-backend.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend
  namespace: ingress-nginx
  labels:
    app: default-http-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: default-http-backend
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        # Any image is permissible as long as:
        # 1. It serves a 404 page at /
        # 2. It serves 200 on a /healthz endpoint
        image: gcr.io/google_containers/defaultbackend:1.4
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  namespace: ingress-nginx
  labels:
    app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: default-http-backend

動作確認

サービスとポッドのアドレスを確認します。

$ kubectl get svc
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
default-http-backend   ClusterIP      10.244.28.14     <none>          80/TCP                       2d
省略

$ kubectl get pods -o wide
NAME                                        READY     STATUS    RESTARTS   AGE       IP             NODE
default-http-backend-5c6d95c48-nr8sd        1/1       Running   0          2d        10.244.2.110   k8s3
省略

先ほど起動したUbuntuのポッドから、サービス名のDNS名、ポッドのIPアドレスから、それぞれ、アクセスして得られる応答を見ます。それから、このコンテナには、livenessProbeも実装されているはずですから、それも確認します。

vagrant@k8s1:/vagrant/yaml/ingress-nginx$ kubectl exec -it ubuntu-fcdb8ff7-657bj bash

root@ubuntu-fcdb8ff7-657bj:/# curl  http://default-http-backend/;echo 
default backend - 404

root@ubuntu-fcdb8ff7-657bj:/# curl http://10.244.2.110:8080/;echo
default backend - 404

root@ubuntu-fcdb8ff7-657bj:/# curl http://10.244.2.110:8080/healthz;echo
ok

root@ubuntu-fcdb8ff7-657bj:/# curl http://default-http-backend/healthz;echo 
ok

RBAC ロールベースアクセスコントロールの設定

この一連の k8s on vagrant の k8s v1.10 では、デフォルトで RBAC (Role Based Access Control) が有効になっているので、適用します。

このRBACの設定は以下の4層で構成されています。

  • ClusterRole - パーミッションはロールに設定され、これはクラスタ全体に適用されます。
  • ClusterRoleBinding - ClusterRoleを特定のアカウントに結び付け(バインド)します。
  • Role - パーミッションをロールに設定し、これは特定のネームスペースに適用されます。
  • RoleBinding - ロールを特定のアカウントに結び付けます。

RBAC を nginx-ingress-controller に適用するには、コントローラーは ServiceAccountに割り当てられる必要があり、サービスアカウントは、Roles と ClusterRoles に結び付けられなければなりません。

詳しい説明は、GitHub Role Based Access Control (RBAC) を参照ください。

rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
        - events
    verbs:
        - create
        - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

NGINX Ingressコントローラーのインストール

これは、https://github.com/kubernetes/ingress-nginx/blob/master/deploy/with-rbac.yaml を元に修正したものです。

修正箇所は、以下2点です。 外部向けIPアドレスを NGINX Ingress コントローラへ導くための修正です。

  • 30行目 - --publish-service=$(POD_NAMESPACE)/nginx-ingress-svc の引数はロードバランサー nginx-ingress-svc の EXTERNAL IP アドレスを受け入れ事を指定します。
  • 64行目以降 k8sのサービスのロードバランサーで、外部向けのIPアドレスのアクセスを、NGINX Ingressコントローラーへ転送します。

これも、同じ様に `kubectl apply -f ingress-controller-with-rbac.yaml' によって適用します。 問題があった時は、apply を delete に変更する事で、取り消すことができます。

ingress-controller-with-rbac.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx 
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ingress-nginx
  template:
    metadata:
      labels:
        app: ingress-nginx
      annotations:
        prometheus.io/port: '10254'
        prometheus.io/scrape: 'true'
    spec:
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.13.0
          args:
            - /nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --annotations-prefix=nginx.ingress.kubernetes.io
            - --publish-service=$(POD_NAMESPACE)/nginx-ingress-svc
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
          - name: http
            containerPort: 80
          - name: https
            containerPort: 443
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-svc
  namespace: ingress-nginx 
spec:
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    targetPort: http
  - name: https
    port: 443
    targetPort: https
  selector:
    app: ingress-nginx
  externalIPs:
    - 192.168.1.100

サービス用にIPアドレスの設定

vagrantの仮想サーバーで稼働する k8s ノード k8s2, k8s3のどちらかで、公開用IPが設定されている必要があります。 今回検証なので、コマンドを手打ちして、仮想サーバーに2つ目のIPアドレスを設定します。

次の様にワーカーノードにログインして、192.168.1.0/24 のIPアドレスが設定されたインタフェースに、前述のロードバランサーのexternalIPと同じアドレスをセカンドIPとして設定します。 この設定は、リブートすると消えてしまうので、再起動した場合は、再設定が必要です。

$ vagrant ssh k8s2
$ sudo -s
root@k8s2:~# ifconfig enp0s8:1 192.168.1.100

これで、NGINX Ingressコントローラーの基盤の設定が完了しました。 前述の図の左半分の紫色のボックスが全部できたことになります。

模擬ユーザー・アプリケーションの設定

ここから、前述の図の左半分の水色のボックスの設定を進めます。単純にHello-Worldとポッド名を表示するもので、適用は、以下のリストからコピペでファイルを作って、kubectl apply -f hello-world.yaml で実行します。

hello-world.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: hello-world-deployment
  namespace: ingress-nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
        - image: "strm/helloworld-http"
          imagePullPolicy: Always
          name: hello-world-container
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world-svc
  namespace: ingress-nginx
spec:
  type: NodePort
  ports:
     -  port: 8080
        protocol: TCP
        targetPort: 80
        nodePort: 31445
  selector:
    app: hello-world

動作確認

ここで、このアプリの動作確認をしておきます。 次の様にして、サービス、デプロイメント、ポッドの3点セットを確認します。

$ kubectl get svc hello-world-svc
NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
hello-world-svc   NodePort   10.244.245.180   <none>        8080:31445/TCP   1d

$ kubectl get deploy hello-world-deployment
NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-world-deployment   1         1         1            1           1d

$ kubectl get pods -o wide
NAME                                        READY     STATUS    RESTARTS   AGE       IP             NODE
hello-world-deployment-b58876bbd-r6z86      1/1       Running   0          1d        10.244.2.112   k8s3

ubuntuのポッドを起動して、対話型でシェルを立ち上げて、curlコマンドでサービスとポッドをアクセスして、模擬アプリの動作を確認します。

$ kubectl run ubuntu -n ingress-nginx --image=ubuntu:latest -- tail -f /dev/null
$ kubectl get pods |grep ubuntu
ubuntu-fcdb8ff7-657bj                       1/1       Running   0          35s

$ kubectl exec -it ubuntu-fcdb8ff7-657bj bash
root@ubuntu-fcdb8ff7-657bj:/# apt-get update
root@ubuntu-fcdb8ff7-657bj:/# apt-get install curl

サービスへのアクセス

root@ubuntu-fcdb8ff7-657bj:/# curl http://hello-world-svc:8080/
<html><head><title>HTTP Hello World</title></head><body><h1>Hello from hello-world-deployment-b58876bbd-r6z86</h1></body></html

ポッドへのアクセス

root@ubuntu-fcdb8ff7-657bj:/# curl http://10.244.2.112/
<html><head><title>HTTP Hello World</title></head><body><h1>Hello from hello-world-deployment-b58876bbd-r6z86</h1></body></html

ポッドをアプリの応答が、サービスでアクセスできれば、模擬アプリのデプロイは完了です。

暗号化なしのIngress設定

SSL/TLS暗号の無いIngressの設定から試します。 以下のファイルを kubectl apply -f ingress.yaml で適用します。

ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  namespace: ingress-nginx   
  annotations:
    kubernetes.io/ingress.class: 'nginx'

spec:
  rules:
  - host: abc.sample.com
    http:
      paths:
      - path: /
        backend:
          serviceName: hello-world-svc
          servicePort: 8080

動作確認

$ kubectl get ing -o wide
NAME                  HOSTS            ADDRESS         PORTS     AGE
hello-world-ingress   abc.sample.com   192.168.1.100   80        2d

3の方法で、アクセスのテストを試みます。 Ingressは仮想ホスト機能があるため、必ずDNSホスト名を意識したアクセスが必要になることが解ると思います。

192.168.1.100へアクセスした場合

imac:~ maho$ curl http://192.168.1.100/;echo
default backend - 404

ヘッダーにabc.sample.comを設定した場合

imac:~ maho$ curl http://192.168.1.100/ -H 'Host: abc.sample.com'
<html><head><title>HTTP Hello World</title></head><body><h1>Hello from hello-world-deployment-b58876bbd-r6z86</h1></body></html

リゾルバーでアドレス解決した場合

imac:~ maho$ curl http://abc.sample.com/
<html><head><title>HTTP Hello World</title></head><body><h1>Hello from hello-world-deployment-b58876bbd-r6z86</h1></body></html

暗号化有りのIngress設定

自己署名の証明書を作って、HTTPSでアクセスを確認します。
次のコマンドで、秘密鍵(暗号化しない)と 証明書を一度に生成します。

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx-selfsigned.key -out nginx-selfsigned.crt
Generating a 2048 bit RSA private key
............................................................+++
........................................................+++
writing new private key to 'nginx-selfsigned.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:TOKYO
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:TAKARA Ltd
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:abc.sample.com
Email Address []:

以下の様に、証明書(.crt) と 鍵(.key)が生成されます。

$ ls -la
total 8
drwxr-xr-x 1 vagrant vagrant  136 Apr 25  2018 .
drwxr-xr-x 1 vagrant vagrant  510 Apr 25 12:42 ..
-rw-r--r-- 1 vagrant vagrant 1245 Apr 25  2018 nginx-selfsigned.crt
-rw-r--r-- 1 vagrant vagrant 1708 Apr 25  2018 nginx-selfsigned.key

k8sクラスタの同ネームスペースに、TLS用のシークレットを作成します。

$ kubectl create secret tls tls-certificate --key nginx-selfsigned.key --cert nginx-selfsigned.crt 
secret "tls-certificate" created

TLS用シークレットで作成されている事を TYPE フィールドで確認します。

$ kubectl get secret
NAME                                       TYPE                                  DATA      AGE
省略
tls-certificate                            kubernetes.io/tls                     2         2m

前回からの変更点は以下です。

  • 8と9行目 サービスにSSLを適用を指示
  • 12〜15行目 TLS証明書と鍵のシークレットを追加
ingress-tls.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  namespace: ingress-nginx   
  annotations:
    kubernetes.io/ingress.class: 'nginx'
    nginx.org/ssl-services: 'hello-world-svc'
    ingress.kubernetes.io/ssl-redirect: 'false'

spec:
  tls:
  - hosts:
    - abc.sample.com
    secretName: tls-certificate
  rules:
  - host: abc.sample.com
    http:
      paths:
      - path: /
        backend:
          serviceName: hello-world-svc
          servicePort: 8080

アクセス確認

前回同様に、3パターンでアクセスを確認して見ました。

imac:~ maho$ curl -k https://192.168.1.100/;echo
default backend - 404

imac:~ maho$ curl -k https://192.168.1.100/ -H 'Host: abc.sample.com'
<html><head><title>HTTP Hello World</title></head><body><h1>Hello from hello-world-deployment-b58876bbd-r6z86</h1></body></html

imac:~ maho$ curl -k https://abc.sample.com/ 
<html><head><title>HTTP Hello World</title></head><body><h1>Hello from hello-world-deployment-b58876bbd-r6z86</h1></body></html

以下はブラウザからのアクセスです。

スクリーンショット 2018-04-27 13.27.45.png

感想

IngressとIngressコントローラの違いが、整理できたと思います。 それから、パブリッククラウドでは、公開用IPアドレスの付与とルーティング、そして、クラウドのロードバランサーとの連携など自動的に実行されているですが、自前で作ってみると、その仕組みや役割分担が良く理解できるように思います。

IBM Cloud Container Service(ICCS) では、Ingressコントローラはクラスタ構成時に自動的に設定されているので、DNS名や暗号鍵を設定しなくても即に利用できます。 しかし、IBM Cloud Private(ICP)では、ロードバランサーはアプライアンスを利用するか、それとも、NGINX Ingressコントローラーを立てる必要があるので、ここで確認した方法は役に立つと思います。

参考資料

  1. 「Kubernetes Concepts Ingress」, < https://kubernetes.io/docs/concepts/services-networking/ingress/ >, 2018/4/24
  2. 「NGINX Ingress Controller」, < https://github.com/kubernetes/ingress-nginx#conventions >, 2018/4/24
  3. 「kubernetesにNginx Ingress Controllerをセットアップ」, < https://qiita.com/sheepland/items/37ece5800eb6972ffd91 >, 2018/4/24
27
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
23