2021年2月28日日曜日

kubernetes に Ingress をデプロイして外部からアクセスできるようにしてみる

概要

k8s で Service に対して外部からアクセスできるようにする場合は基本的には Ingress が必要になります
過去に minikube を使った Ingress の設定方法は紹介しました
今回は kubeadm で構築した環境に Ingress をデプロイしてみたいと思います

環境

  • Ubuntu18.04
  • kubernetes v1.20.4

Nginx Ingress Controller のデプロイ

今回は Nginx Ingress Controller を使います

Nginx Ingress Controller の取得

  • git clone https://github.com/nginxinc/kubernetes-ingress/
  • cd kubernetes-ingress/deployments
  • git checkout v1.10.0

RBAC のデプロイ

  • kubectl apply -f common/ns-and-sa.yaml
  • kubectl apply -f rbac/rbac.yaml
  • kubectl apply -f rbac/ap-rbac.yaml
namespace/nginx-ingress created
serviceaccount/nginx-ingress created

clusterrole.rbac.authorization.k8s.io/nginx-ingress created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress created

clusterrole.rbac.authorization.k8s.io/nginx-ingress-app-protect created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-app-protect created

nginx の共通設定のデプロイ

  • kubectl apply -f common/default-server-secret.yaml
  • kubectl apply -f common/nginx-config.yaml
  • kubectl apply -f common/ingress-class.yaml
secret/default-server-secret created

configmap/nginx-config created

ingressclass.networking.k8s.io/nginx created

カスタムリソースのデプロイ

  • kubectl apply -f common/crds/k8s.nginx.org_virtualservers.yaml
  • kubectl apply -f common/crds/k8s.nginx.org_virtualserverroutes.yaml
  • kubectl apply -f common/crds/k8s.nginx.org_transportservers.yaml
  • kubectl apply -f common/crds/k8s.nginx.org_policies.yaml
  • kubectl apply -f common/crds/k8s.nginx.org_globalconfigurations.yaml
  • kubectl apply -f common/global-configuration.yaml
customresourcedefinition.apiextensions.k8s.io/virtualservers.k8s.nginx.org created

customresourcedefinition.apiextensions.k8s.io/virtualserverroutes.k8s.nginx.org created

customresourcedefinition.apiextensions.k8s.io/transportservers.k8s.nginx.org created

customresourcedefinition.apiextensions.k8s.io/policies.k8s.nginx.org created

customresourcedefinition.apiextensions.k8s.io/globalconfigurations.k8s.nginx.org created

globalconfiguration.k8s.nginx.org/nginx-configuration created

Ingress Controller のデプロイ

  • kubectl apply -f deployment/nginx-ingress.yaml
  • kubectl apply -f daemon-set/nginx-ingress.yaml
deployment.apps/nginx-ingress created

daemonset.apps/nginx-ingress created

service のデプロイ

  • kubectl create -f service/nodeport.yaml
service/nginx-ingress created

これでホストのどこかのポートで待ち受けることできます
今回は 31451 と 30023 で LISTEN しています

  • kubectl get svc -n nginx-ingress
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
nginx-ingress   NodePort   10.107.240.71   <none>        80:31451/TCP,443:30023/TCP   4m38s

Ingress Controller が動作しているか確認

  • kubectl get pods --namespace=nginx-ingress
AME                            READY   STATUS    RESTARTS   AGE
nginx-ingress-f69f79478-5gl72   1/1     Running   0          55m
nginx-ingress-k29kh             1/1     Running   0          42m

今回は daemonSets もデプロイしているので 2 つあります

使ってみる

Pod と Service をデプロイします
そして Service に対して Ingress 経由でアクセスできるようにしてみます

  • vim apple.yml
kind: Pod
apiVersion: v1
metadata:
  name: apple-app
  labels:
    app: apple
spec:
  containers:
    - name: apple-app
      image: hashicorp/http-echo
      args:
        - "-text=apple"
---

kind: Service
apiVersion: v1
metadata:
  name: apple-service
spec:
  selector:
    app: apple
  ports:
    - port: 5678
  • vim ingress.yml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: test.app.com
    http:
      paths:
        - path: /apple
          backend:
            serviceName: apple-service
            servicePort: 5678
  • kubectl apply -f apple.yml
  • kubectl create -f ingress.yml

最小構成の場合ワーカー側のノードの IP で LISTEN しています
なのでノードの IP にアクセスすればどの IP でもアクセスできます
アクセスする際は host ベースの振り分けをしていので Host を指定するようにしましょう

  • curl -H "Host: test.app.com" node1:31451/apple

もちろんノードの IP に DNS を設定して FQDN でアクセスすれば Host ヘッダなしでアクセスできるようになります

トラブルシューティング: うまく pods が起動しない

自分が遭遇したエラーは error retrieving k8s version: Get "https://10.96.0.1:443/version?timeout=32s": dial tcp 10.96.0.1:443: i/o timeout というエラーで nginx-ingress-controller の pods から ClusterIP を経由して k8s の API をコールするところでエラーになりました
原因は k8s を構築する際の flannel の設定で --pod-network-cidr=10.244.0.0/16 を忘れていたのと指定したネットワークがホストのネットワークと被っていたせいでうまく通信できなかったのが原因でした

最後に

Nginx Ingress Controller をデプロイして外部から k8s 環境にデプロイしたアプリにアクセスできるようにしてみました
結構複雑なので使いこなすとなるとかなり大変かなと思います
今回のように master/node の 2 台最小構成なのであれば NodePort を使って外部からアクセスするようになります

参考サイト

0 件のコメント:

コメントを投稿