如何在阿里雲Kubernetes叢集中部署多個Ingress Controller
場景說明
在前面 ofollow,noindex" target="_blank">如何配置阿里雲容器服務K8S Ingress Controller使用私網SLB 一文中描述瞭如何調整阿里雲容器服務Kubernetes叢集中預設的Nginx Ingress Controller配置使用私網SLB例項,文中提到的兩種模式基本可以滿足大部分需求場景,但對於一些特殊場景,比如叢集內有部分公網服務需要通過公網Ingress方式來對外暴露提供訪問,但是又有部分內網服務僅僅只希望對同VPC內非Kubernetes叢集內的服務提供訪問,而又不允許能被公網訪問到,對此我們完全可以通過部署兩套獨立的Nginx Ingress Controller服務,其前端繫結不同網路型別的SLB例項來滿足這類需求場景。
下面我們以此場景來說明如何在阿里雲容器服務Kubernetes叢集中同時部署多套獨立的Nginx Ingress Controller來對外提供不同的服務訪問。
現有服務說明
我們知道,當我們通過阿里雲容器服務控制檯成功申請一個Kubernetes集群后,預設叢集內已經部署了一套帶有 公網SLB例項 的Nginx Ingress Controller服務,通過如下命令可以檢視到:
~ # 查詢叢集預設 Nginx Ingress Controller 服務相關資源 ~ kubectl -n kube-system get svc nginx-ingress-lb default-http-backend NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE nginx-ingress-lbLoadBalancer172.19.7.3047.95.97.11580:31429/TCP,443:32553/TCP2d default-http-backendClusterIP172.19.11.213<none>80/TCP2d ~ ~ kubectl -n kube-system get deploy nginx-ingress-controller default-http-backend NAMEDESIREDCURRENTUP-TO-DATEAVAILABLEAGE nginx-ingress-controller22222d default-http-backend11112d ~ ~ kubectl -n kube-system get configmap nginx-configuration tcp-services udp-services NAMEDATAAGE nginx-configuration42d tcp-services02d udp-services02d
從上可以看到叢集預設部署的Nginx Ingress Controller服務及相關資源部署在 kube-system
名稱空間下,並且其預設會監聽叢集內所有名稱空間下建立的且未明確配置註釋 kubernetes.io/ingress.class
的Ingress配置。
新部署NginxIngressController服務
這裡我們說明如何在現有的阿里雲容器服務Kubernetes叢集中再部署一套完全獨立的Nginx Ingress Controller服務,其前端繫結一個新的SLB例項(可依據實際需求配置私網SLB例項或公網SLB例項)。
1、通過阿里雲負載均衡控制檯在對應Region申請一個期望規格和網路型別的SLB例項。
2、準備Nginx Ingress Controller服務的yaml檔案:
wget https://acs-k8s-ingress.oss-cn-hangzhou.aliyuncs.com/ingress-controller-template.yml.j2
由於這裡需要用到jinja2命令列,安裝方式可參考 官方文件 。通過如下命令來生成我們需要新部署的Nginx Ingress Controller服務的yaml檔案:
jinja2 -D Namespace='NAMESPACE' -D LoadbalancerID='SLB_ID' -D IngressClass='INGRESS_CLASS' ingress-controller-template.yml.j2 > ingress-controller.yml 引數說明: NAMESPACE:期望部署到哪個命令空間下(確保該名稱空間已存在且不能再使用kube-system) SLB_ID:新申請的SLB例項ID INGRESS_CLASS:Ingress標識(不能使用nginx這個字串,已預留給叢集預設IngressController服務)
3、待yaml生成後通過如下命令部署新的Nginx Ingress Controller服務:
# 部署新 Nginx Ingress Controller 服務 kubectl apply -f ingress-controller.yml serviceaccount "admin" created clusterrolebinding.rbac.authorization.k8s.io "admin" created service "nginx-ingress-lb" created configmap "nginx-configuration" created configmap "tcp-services" created configmap "udp-services" created deployment.extensions "default-http-backend" created service "default-http-backend" created deployment.apps "nginx-ingress-controller" created # 確認新 Nginx Ingress Controller 服務正常執行起來 kubectl -n <YOUR_NAMESPACE> get svc nginx-ingress-lb NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE nginx-ingress-lbLoadBalancer172.19.6.22739.105.252.6280:30969/TCP,443:31325/TCP4m kubectl -n <YOUR_NAMESPACE> get pod | grep nginx-ingress-controller nginx-ingress-controller-78bc478f5b-blpgz1/1Running02m nginx-ingress-controller-78bc478f5b-k5jh71/1Running02m
4、預設情況下系統會自動配置SLB例項的埠監聽,請確認您的SLB例項埠監聽已正常配置,若無配置說明叢集CloudControllerManager服務版本過低,一種方式可參考 CloudProvider Release Notes 進行版本升級,另一種方式也可以進行手工配置,具體需要的埠對映關係可通過如下命令檢視到 PORT(S)
:
kubectl -n <YOUR_NAMESPACE> get svc nginx-ingress-lb NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE nginx-ingress-lbLoadBalancer172.19.6.22739.105.252.6280:30969/TCP,443:31325/TCP4m
至此在您指定的名稱空間下一套新的Nginx Ingress Controller已經成功部署完成。
訪問測試
這裡我們部署一個測試應用,並配置通過新部署的Nginx Ingress Controller來對外暴露提供服務訪問。
1、 部署一個nginx測試應用:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx spec: replicas: 1 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx imagePullPolicy: Always name: nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx sessionAffinity: None type: NodePort
2、通過Ingress來對外暴露提供服務訪問:
注意:這裡需要配置註釋 kubernetes.io/ingress.class
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx annotations: # 注意這裡要設定為您前面配置的 INGRESS_CLASS kubernetes.io/ingress.class: "<YOUR_INGRESS_CLASS>" spec: rules: - host: foo.bar.com http: paths: - path: / backend: serviceName: nginx servicePort: 80
待部署完成後我們可以看到該Ingress資源對應的端點IP地址與新部署的Nginx Ingress Controller服務的一致:
kubectl -n kube-system get svc nginx-ingress-lb NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE nginx-ingress-lbLoadBalancer172.19.7.3047.95.97.11580:31429/TCP,443:32553/TCP2d kubectl -n <YOUR_NAMESPACE> get svc nginx-ingress-lb NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE nginx-ingress-lbLoadBalancer172.19.6.22739.105.252.6280:30969/TCP,443:31325/TCP39m kubectl get ing NAMEHOSTSADDRESSPORTSAGE nginxfoo.bar.com39.105.252.62805m
3、此時我們嘗試分別通過叢集預設的Nginx Ingress Controller服務和新部署的Nginx Ingress Controller服務來訪問該應用:
# 通過叢集預設的 Nginx Ingress Controller 服務訪問該應用(預期返回404) curl -H "Host: foo.bar.com" http://47.95.97.115 default backend - 404 # 通過新部署的 Nginx Ingress Controller 服務訪問該應用(預期返回nginx頁面) curl -H "Host: foo.bar.com" http://39.105.252.62 <!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>
從上面測試訪問情況可以看到,通過不同的Nginx Ingress Controller暴露的服務彼此完全是獨立的,這特別適用於同一叢集內部分服務需要提供公網訪問能力,但又有部分服務僅僅只希望為同VPC內非Kubernetes叢集的其他服務提供訪問的場景。