Ingressについて
今回はオンプレミスの環境に対してIngressリソースを作成し、Ingressコントローラーを動作させます。GCP上のIngressとは概念や方法が異なりますのでご注意ください。
Ingressを使う上で2つのコンポーネントが存在します。
- Ingressリソース
- Ingressコントローラー
kuberneteの中身から紹介すると、マニュフェストに定義したリソースをkubernetesに登録することから始まります。登録しただけでは何もおきず、リソースを元に何か処理を行う「コントローラー」が存在しなければなりません。
例えばDeploymentをマニュフェストで定義したとしましょう。登録されたDeploymentをあるべき状態にするDeployment Controllerが存在しなければ何も設定されないのです。ということでIngressについてもリソースとコントローラーが必要になってきます。
少し他と違うのはIngressのコントローラーは自分で入れる必要があるということです。
オンプレミス環境におけるNginx Ingressについて
今回はNginx Ingress Controller
を使います。図示するとこのようなアーキテクチャーとなっています。(WebサーバはNginx Ingress Controllerには含まれていません)
名前 | 役割 |
---|---|
Ingressリソース | Ingressの定義を行う |
Ingressコントローラ | Ingressリソースを監視し変更をL7 LBに伝える |
Nginx Ingress(L7 LB) | Ingressリソースで指定されたルールに従ってリクエストを処理する |
Nginx(Web) | コンテンツを保有している(最終的にアクセスされる) ※WebサーバはNginx Ingress Controllerには含まれていません |
ここでややこしいのがNginx Ingress Controller podが「Contollerの機能」と「L7 LB機能」の両方を持っている点です。そのためControllerという名前ですがトラフィックを受け付けL7の負荷分散を実施します。
実際にpod内のプロセスをみてみるとinitプロセス(dumb-initは軽量のinit)の配下に/nginx-ingress-controller
とnginx
が起動していることがわかります。
bash-5.0$ ps -ef PID USER TIME COMMAND 1 www-data 0:00 /usr/bin/dumb-init -- /nginx-ingress-controller --configmap=ingress-nginx 6 www-data 0:41 /nginx-ingress-controller --configmap=ingress-nginx/nginx-configuration - 25 www-data 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.con 730 www-data 0:01 nginx: worker process 731 www-data 0:02 nginx: worker process 732 www-data 0:00 nginx: cache manager process
【ハンズオン】MetalLB+Ingressの実装
最終的に目指す姿はこちら。
今回つかったコードはGitHubに格納しています。
k8s-sample/ingress at master · lirlia/k8s-sample · GitHub
環境
名前 | バージョン |
---|---|
OS | CentOS Linux release 7.6.1810 (Core) |
kubelet | v1.18.1 |
kubeadm | v1.18.1 |
docker | v1.13.1 |
calico | v3.8.8-1 |
metallb | v0.9.3 |
Ingress-nginx-controller | v0.30.0 |
kubernetesの導入はこちらを参考にしてください
事前準備
- kubernetes(kubeadm/kubelet/kubectl/docker)がインストールされている
- calicoが導入されている
MetalLBの準備
MetalLBの準備はこちらをご覧ください。L2 mode
でやっていきます。
Ingress リソースの準備
ingress.yaml
という名前で作成します。
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: namespace: default name: test-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: test.com http: paths: - backend: serviceName: nginx-ingress-test servicePort: 80 path: /ingress
Ingress Controllerの準備
必要なファイルをダウンロードします。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
service-nodeport.yaml
を以下のように書き換えます。
apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: - type: NodePort + type: LoadBalancer + loadBalancerIP: 192.168.10.10 ports: - name: http port: 80 targetPort: 80 protocol: TCP - name: https port: 443 targetPort: 443 protocol: TCP selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx
ついで名前を変えておきます
mv service-nodeport.yaml service-lb.yaml
動作させるNginxサービス&podを準備
ややこしいですが先ほどのNginx Ingress Controllerではなく、最終的にアクセスするWebサーバとしてのNginxを用意します。名前はnginx.yaml
です。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx-ingress-test name: nginx-ingress-test spec: selector: matchLabels: app: nginx-ingress-test template: metadata: labels: app: nginx-ingress-test spec: containers: - image: nginx name: nginx-ingress-test ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-ingress-test spec: type: NodePort selector: app: nginx-ingress-test ports: - name: http port: 80 targetPort: 80
リソースの作成
ここまでできたら適用します
kubectl apply -f ingress.yaml kubectl apply -f mandatory.yaml kubectl apply -f service-lb.yaml kubectl apply -f nginx.yaml
正しく適用するとこのようになります。
[root@master ingress]# kubectl get svc nginx-ingress-test NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-test NodePort 10.103.112.35 <none> 80:30471/TCP 28m [root@master ingress]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE test-ingress <none> * 192.168.10.10 80 162m [root@master ingress]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.101.97.141 192.168.10.10 80:32398/TCP,443:30249/TCP 80m
実際にアクセスしてみる
[root@master ingress]# curl 192.168.10.10/ingress <!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 192.168.10.10
の場合はIngressにて指定されていないパスになるためアクセスできず404が返却されます。
[root@master ingress]# curl 192.168.10.10 <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.17.8</center> </body> </html>
お疲れ様でした、以上で終了です。