什么是Ingress
有了Service之后,我們可以訪問這個Service的IP(clusterIP)來請求對應的Pod,但是這只能是在集群內部訪問。 要想讓外部用戶訪問此資源,可以使用NodePort,即在node節點上暴漏一個端口出來,但是這個非常不靈活。為了解決此問題,K8s引入了一個新的API資源對象Ingress,它是一個七層的負載均衡器,類似于Nginx。
三個核心概念:Ingress、Ingress Controller、IngressClass
Ingress用來定義具體的路由規則,要實現什么樣的訪問效果;
Ingress Controller是實現Ingress定義具體規則的工具或者叫做服務,在K8s里就是具體的Pod;
IngressClass是介于Ingress和Ingress Controller之間的一個協調者,它存在的意義在于,當有多個Ingress Controller時,可以讓Ingress和Ingress Controller彼此獨立,不直接關聯,而是通過IngressClass實現關聯。
Ingress實戰
1)編輯ingress YAML文件
vimying.yaml#內容如下 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: mying ##ingress名字 spec: ingressClassName: myingc ##定義關聯的IngressClass rules: ##定義具體的規則 - host: aminglinux.com ##訪問的目標域名 http: paths: - path: / pathType: Exact backend: ##定義后端的service對象 service: name: ngx-svc port: number: 80查看ingress
kubectl get ing kubectl describe ing mying2)編輯IngressClass YAML文件
vimyingc.yaml#內容如下 apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name:myingc spec: controller: nginx.org/ingress-controller ##定義要使用哪個controller查看ingressClass
kubectl get ingressclass
3)安裝ingress-controller
首先做一下前置工作
curl -O 'https://gitee.com/aminglinux/linux_study/raw/master/k8s/ingress.tar.gz' tar zxf ingress.tar.gz cd ingress ./setup.sh ##說明,執行這個腳本會部署幾個ingress相關資源,包括namespace、configmap、secrect等編輯controller YAML文件
vi ingress-controller.yaml #內容如下 apiVersion: apps/v1 kind: Deployment metadata: name: ngx-ing namespace:nginx-ingress spec: replicas: 1 selector: matchLabels: app:ngx-ing template: metadata: labels: app: ngx-ing #annotations: #prometheus.io/scrape: "true" #prometheus.io/port: "9113" #prometheus.io/scheme: http spec: serviceAccountName: nginx-ingress containers: - image: nginx/nginx-ingress:2.2-alpine imagePullPolicy: IfNotPresent name: ngx-ing ports: - name: http containerPort: 80 - name: https containerPort: 443 - name: readiness-port containerPort: 8081 - name: prometheus containerPort: 9113 readinessProbe: httpGet: path: /nginx-ready port: readiness-port periodSeconds: 1 securityContext: allowPrivilegeEscalation: true runAsUser: 101 #nginx capabilities: drop: - ALL add: - NET_BIND_SERVICE env: - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name args: - -ingress-class=myingc - -health-status - -ready-status --nginx-status - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret應用YAML
kubectl apply -f ingress-controller.yaml查看pod、deployment:
kubectl get po -n nginx-ingress kubectl get deploy -n nginx-ingress將ingress對應的pod端口映射到master上臨時測試:
kubectl port-forward -n nginx-ingress ngx-ing-547d6575c7-fhdtt 8888:80 &注意,測試前可以修改ng-deploy對應的兩個pod里的/usr/share/nginx/html/index.html文件內容,用于區分兩個pod。 使用curl測試:
curl -x127.0.0.1:8888 aminglinux.com 或者: curl -H 'Host:aminglinux.com' http://127.0.0.1:8888Igress對外訪問的三種方案
上面對ingress做端口映射,然后通過其中一個節點的IP來訪問ingress只是一種臨時方案。那么正常如何做呢?有三種常用的方案:
1)Deployment+LoadBalancer
如果要把ingress部署在公有云,那用這種方式比較合適。用Deployment部署ingress-controller,創建一個type為LoadBalancer的service關聯這組pod。 大部分公有云,都會為LoadBalancer的service自動創建一個負載均衡器,通常還綁定了公網地址。 只要把域名解析指向該地址,就實現了集群服務的對外暴露。
2)Deployment+NodePort
同樣用deployment模式部署ingress-controller,并創建對應的服務,但是type為NodePort。這樣,ingress就會暴露在集群節點ip的特定端口上。 由于nodeport暴露的端口是隨機端口,一般會在前面再搭建一套負載均衡器來轉發請求。該方式一般用于宿主機是相對固定的環境ip地址不變的場景。 NodePort方式暴露ingress雖然簡單方便,但是NodePort多了一層NAT,在請求量級很大時可能對性能會有一定影響。
3)DaemonSet+nodeSelector
用DaemonSet結合nodeselector來部署ingress-controller到特定的node上,然后使用HostNetwork直接把該pod與宿主機node的網絡打通(如,上面的臨時方案kubectl port-forward),直接使用宿主機的80/433端口就能訪問服務。 這時,ingress-controller所在的node機器就很類似傳統架構的邊緣節點,比如機房入口的nginx服務器。該方式整個請求鏈路最簡單,性能相對NodePort模式更好。 缺點是由于直接利用宿主機節點的網絡和端口,一個node只能部署一個ingress-controller pod。比較適合大并發的生產環境使用。
審核編輯:劉清
-
nginx
+關注
關注
0文章
149瀏覽量
12171 -
YAML
+關注
關注
0文章
21瀏覽量
2322 -
負載均衡器
+關注
關注
0文章
18瀏覽量
2583
原文標題:一篇文章助你搞懂Ingress
文章出處:【微信號:aming_linux,微信公眾號:阿銘linux】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論