k3sでingressを使う

はじめに

Kubernetesの機能であるIngressを使います.IngressはTCP/IPのLayer 7(つまりHTTP)のレベルでアクセスを制御するKubenetesの機能です.具体的には,URLルーティングを行います.これは http://example.com/hellohttp://example.com/world で別のサーバ(コンテナ)を参照させることです.IngressにはKubenetesクラスタの内部に構築するものと,外部に構築するものがあります.今回は内部に構築するものを使います.

出典: KubernetesのDiscovery&LBリソース(その2) | Think IT(シンクイット)

Nginx Ingressを動かす

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

インストール

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

確認

$ 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を使ったデプロイ

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

$ k apply -f ingress-app.yaml
$ k apply -f ingress-controller.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

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

うまく動いていた時

$ 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

ブラウザからアクセスしてみる.

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

hnote over User: ブラウザからアクセス
User -> "ingress-endpoint \n[LoadBalancer Service]"

hnote over "ingress-endpoint \n[LoadBalancer Service]": L4(IP/ポート)\nロードバランサ\nDeploymentの選択
"ingress-endpoint \n[LoadBalancer Service]" -> "nginx-ingress-controller \n[Deployment]"

hnote over "nginx-ingress-controller \n[Deployment]": L7(HTTP)\nロードバランサ\nServiceの選択
"nginx-ingress-controller \n[Deployment]" -> "get-my-info \n[NodePort Service]"

hnote over "get-my-info \n[NodePort Service]": L4(IP/ポート)\nロードバランサ\nDeploymentの選択
"get-my-info \n[NodePort Service]" -> "get-my-info \n[Deployment]"

' "get-my-info \n[Deployment]" -> "get-my-info-xxx \n[ReplicaSet]"
' "get-my-info-xxx \n[ReplicaSet]" -> "get-my-info-yyy \n[Pod]"

Deploymentの内側

frame "deployment.apps/get-my-host" {
    frame replicaset.apps/get-my-host-7449f7cf55 {
        component "pod/get-my-host-7449f7cf55-6hjzg"
        component "pod/get-my-host-7449f7cf55-d8bm7"
        component "pod/get-my-host-7449f7cf55-ncrvz"
    }
}

frame "deployment.apps/get-my-info" {
    frame replicaset.apps/get-my-info-6666748778 {
        component "pod/get-my-info-6666748778-5gxnv"
        component "pod/get-my-info-6666748778-nxlgs"
        component "pod/get-my-info-6666748778-vzmxx"
    }
}

'deployment.apps/~get-my-host --> ~deployment.apps/get-my-info