ingress-nginx-controller部署

lldhsds發表於2024-06-28

Ingress Controller介紹及部署實踐

1. 概念

1.1 Ingress

Ingress 提供從叢集外部到叢集內服務的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 資源所定義的規則來控制。

下面是 Ingress 的一個簡單示例,可將所有流量都傳送到同一 Service:

ingress

透過配置,Ingress 可為 Service 提供外部可訪問的 URL、對其流量作負載均衡、 終止 SSL/TLS,以及基於名稱的虛擬託管等能力。 Ingress 控制器 負責完成 Ingress 的工作,具體實現上通常會使用某個負載均衡器, 不過也可以配置邊緣路由器或其他前端來幫助處理流量。

Ingress 不會隨意公開埠或協議。 將 HTTP 和 HTTPS 以外的服務開放到 Internet 時,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 型別的 Service。

1.2 Ingress controller

為了讓 Ingress 資源工作,叢集必須有一個正在執行的 Ingress 控制器。Kubernetes 作為一個專案,Kubernetes 作為一個專案,目前支援和維護 AWSGCENginx Ingress 控制器。此外還有一些由第三方維護的ingress contoller:

  • AKS 應用程式閘道器 Ingress 控制器 是一個配置 Azure 應用程式閘道器 的 Ingress 控制器。

  • 阿里雲 MSE Ingress 是一個 Ingress 控制器,它負責配置阿里雲原生閘道器, 也是 Higress 的商業版本。

  • Apache APISIX Ingress 控制器 是一個基於 Apache APISIX 閘道器 的 Ingress 控制器。

  • Avi Kubernetes Operator 使用 VMware NSX Advanced Load Balancer 提供第 4 到第 7 層的負載均衡。

  • Cilium Ingress 控制器是一個由 Cilium 出品支援的 Ingress 控制器。

  • Citrix Ingress 控制器 可以用來與 Citrix Application Delivery Controller 一起使用。

  • EnRoute 是一個基於 Envoy 的 API 閘道器,可以用作 Ingress 控制器。

  • F5 BIG-IP 的 用於 Kubernetes 的容器 Ingress 服務 讓你能夠使用 Ingress 來配置 F5 BIG-IP 虛擬伺服器。

  • 用於 Kubernetes 的 HAProxy Ingress 控制器 也是一個針對 HAProxy 的 Ingress 控制器。

  • Istio Ingress 是一個基於 Istio 的 Ingress 控制器。

  • 用於 Kubernetes 的 Kong Ingress 控制器 是一個用來驅動 Kong Gateway 的 Ingress 控制器。

  • 用於 Kubernetes 的 NGINX Ingress 控制器 能夠與 NGINX 網頁伺服器(作為代理)一起使用。

    備註:nginx和k8s官方各自維護了一套 nginx ingress controller

  • Traefik Kubernetes Ingress 提供程式 是一個用於 Traefik 代理的 Ingress 控制器。

  • Voyager 是一個針對 HAProxy 的 Ingress 控制器。

2. ingress nginx簡介

ingress nginx是一種使用nginx實現的ingress controller,作為K8S的反向代理和負載均衡器。Kubernetes 是容器化應用管理的事實標準。對許多企業而言,將生產工作負載遷移到 Kubernetes 會增加應用流量管理方面的挑戰和複雜性。Ingress controller 能夠將 Kubernetes 應用流量路由的複雜性抽象出來,並在 Kubernetes 服務和外部服務之間建立了一座橋樑。

Kubernetes Ingress Controller 的功能如下:

  • 接受來自 Kubernetes 平臺外部的流量,並將其負載均衡到 Kubernetes 平臺內部執行的 pod(容器)
  • 可管理叢集內需要與叢集外其他服務通訊的服務的出向流量
  • 使用 Kubernetes API 進行配置,以部署名為“Ingress 資源”的物件
  • 監控 Kubernetes 中執行的 pod,並在服務新增或刪除 pod 後自動更新負載均衡規則

版本相容性矩陣:

Ingress-NGINX version k8s supported version Alpine Version Nginx Version Helm Chart Version
v1.10.1 1.29, 1.28, 1.27, 1.26 3.19.1 1.25.3 4.10.1*
v1.10.0 1.29, 1.28, 1.27, 1.26 3.19.1 1.25.3 4.10.0*
v1.9.6 1.29, 1.28, 1.27, 1.26, 1.25 3.19.0 1.21.6 4.9.1*
v1.9.5 1.28, 1.27, 1.26, 1.25 3.18.4 1.21.6 4.9.0*
v1.9.4 1.28, 1.27, 1.26, 1.25 3.18.4 1.21.6 4.8.3
v1.9.3 1.28, 1.27, 1.26, 1.25 3.18.4 1.21.6 4.8.*
v1.9.1 1.28, 1.27, 1.26, 1.25 3.18.4 1.21.6 4.8.*
v1.9.0 1.28, 1.27, 1.26, 1.25 3.18.2 1.21.6 4.8.*
v1.8.4 1.27, 1.26, 1.25, 1.24 3.18.2 1.21.6 4.7.*
v1.7.1 1.27, 1.26, 1.25, 1.24 3.17.2 1.21.6 4.6.*
v1.6.4 1.26, 1.25, 1.24, 1.23 3.17.0 1.21.6 4.5.*
v1.5.1 1.25, 1.24, 1.23 3.16.2 1.21.6 4.4.*
v1.4.0 1.25, 1.24, 1.23, 1.22 3.16.2 1.19.10† 4.3.0
v1.3.1 1.24, 1.23, 1.22, 1.21, 1.20 3.16.2 1.19.10† 4.2.5

本文使用k8s 1.19版本,使用 ingress nginx 0.30.0版本。

3. 安裝部署nginx-ingress

環境資訊如下:

[root@k8s-master ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
[root@k8s-master ~]# uname -a
Linux k8s-master 3.10.0-1160.71.1.el7.x86_64 #1 SMP Tue Jun 28 15:37:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
[root@k8s-master ~]# kubectl get node
NAME         STATUS   ROLES    AGE   VERSION
k8s-master   Ready    master   16d   v1.19.0
k8s-node1    Ready    worker   16d   v1.19.0
k8s-node2    Ready    worker   16d   v1.19.0
[root@k8s-master ~]# helm version
version.BuildInfo{Version:"v3.6.1", GitCommit:"61d8e8c4a6f95540c15c6a65f36a6dd0a45e7a2f", GitTreeState:"clean", GoVersion:"go1.16.5"}

下載 Ingress-nginx yaml檔案:

[root@k8s-master ~]# mkdir ingress-nginx
[root@k8s-master ~]# cd ingress-nginx
[root@k8s-master ingress-nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
[root@k8s-master ingress-nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@k8s-master ingress-nginx]# ls
mandatory.yaml  service-nodeport.yaml

mandatory.yaml下載後需要新增hostNetwork: true,否則無法透過 K8s 節點 IP 地址繫結域名外部訪問。

ingress-controller 會直接使用 K8s 物理機的 DNS 來解析域名,而不再使用 K8s 內部的 DNS 來解析域名。

mandatory.yaml配置修改如下:

...
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
...
    spec:
      # wait up to five minutes for the drain of connections
      # 新增 hostNetwork: true
      hostNetwork: true
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount

安裝 Ingress-nginx:

[root@k8s-master ingress-nginx]# kubectl create -f mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Role
role.rbac.authorization.k8s.io/nginx-ingress-role created
Warning: rbac.authorization.k8s.io/v1beta1 RoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 RoleBinding
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
[root@k8s-master ingress-nginx]# kubectl create -f service-nodeport.yaml
service/ingress-nginx created

# 檢視部署的資源
[root@k8s-master ingress-nginx]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.100.114.169   <none>        80:31433/TCP,443:32351/TCP   16m
[root@k8s-master ingress-nginx]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-7d4544b644-lmnkp   1/1     Running   0          17m

4. 建立例項測試 Ingress

my-nginx.yaml配置檔案:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:latest
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    run: my-nginx
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: test.ingress.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 8080

建立 Deployment、service、ingress:

[root@k8s-master ingress-nginx]# kubectl create -f my-nginx.yaml
deployment.apps/my-nginx created
service/nginx-service created
ingress.networking.k8s.io/example-ingress created

nginx-ingress-controller所在的節點與域名做好hosts繫結,訪問後端pod服務:


# 本文環境中nginx-ingress-controller容器排程到了master節點
[root@k8s-master ingress-nginx]# kubectl get pod -n ingress-nginx -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP    NODE         NOMINATED NODE   READINESS GATES
nginx-ingress-controller-7d4544b644-lmnkp   1/1 Running   0  24m   192.168.0.51   k8s-master   <none>   <none>

# 在其他節點上新增域名解析,域名指向nginx-ingress-controller所在節點的ip
[root@k8s-node1 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.51 test.ingress.com

# curl測試
[root@k8s-node1 ~]# curl test.ingress.com
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>

5. 最佳化 Ingress-nginx部署

上述 Ingress部署為 Deployment 型別,可以最佳化改為 DaemonSet ,讓每個工作節點執行一個 ingress-controller,實現高可用部署,避免單點故障。

...
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  selector:
...

部署daemonset:

[root@k8s-master ingress-nginx]# kubectl get pod -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-9vckp   1/1     Running   0          2m48s
nginx-ingress-controller-j5dvr   1/1     Running   0          2m48s
nginx-ingress-controller-jndjr   1/1     Running   0          2m48s

備註:本文使用的k8s環境,master節點設定可排程業務容器。

改為高可用部署後,即可將域名test.ingress.com同時解析到各節點ip,達到高可用部署的目的。

6. 參考資料

  1. 倉庫地址:https://github.com/kubernetes/ingress-nginx

  2. 官網:https://kubernetes.github.io/ingress-nginx/

  3. nginx官網介紹:https://www.nginx-cn.net/resources/glossary/kubernetes-ingress-controller/

  4. 文件:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

  5. K8s Ingress-nginx 部署和例項演示 - 神奇二進位制 - 部落格園 (cnblogs.com)

相關文章