Ingress Controller介紹及部署實踐
1. 概念
1.1 Ingress
Ingress 提供從叢集外部到叢集內服務的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 資源所定義的規則來控制。
下面是 Ingress 的一個簡單示例,可將所有流量都傳送到同一 Service:
透過配置,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 作為一個專案,目前支援和維護 AWS、 GCE 和 Nginx 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. 參考資料
-
倉庫地址:https://github.com/kubernetes/ingress-nginx
-
官網:https://kubernetes.github.io/ingress-nginx/
-
nginx官網介紹:https://www.nginx-cn.net/resources/glossary/kubernetes-ingress-controller/
-
文件:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
-
K8s Ingress-nginx 部署和例項演示 - 神奇二進位制 - 部落格園 (cnblogs.com)