Kubernetes 提供了兩種內建的雲端負載均衡機制( cloud load balancing )用於發佈公共應用, 工做於傳輸層的 Service 資源,它實現的是 TCP 負載均衡器」,另種是Ingress 資源,它 現的是「 HTTP(S )負載均衡器」html
Ingress和Ingress Controllernode
Ingress是Kubernetes API的標準資源類型之一,它其實就是基於DNS名稱(host)或URL路徑把請求轉發至指定的Service資源的規則,用於將集羣外部的請求流量轉發至集羣內部完成服務發佈。然而,Ingess資源自身並不能運行「流量穿透」,它僅僅是一組路由規則的集合,這些規則要想真正發揮做用還需其它功能的輔助,如監聽某個套接字上,根據這些規則匹配機制路由請求流量:這種可以爲Ingress資源監聽套接字並轉發流量的組件稱之爲Ingress控制器linux
注意:
不一樣於 Deployment 控制器等 Ingress 控制器並不直接運行爲 kube-controller-rnanager的一部 ,它是Kubemetes集羣的重要附件相似於 CoreDNS 須要在集羣單獨部署nginx
官方地址git
此處部署3.0版本github
在你須要部署的node節點上拉去Ingerss-Controller鏡像web
[root@k8s-master01 daem]# docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
docker
進入到GitHub上將mandatory.yaml複製到node節點上後端
[root@k8s-master01 ingressdeploy]# cat mandatory.yaml apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx #data: # whitelist-source-range: 192.168.29.102 #白名單,容許某個IP或IP段的訪問 # block-cidrs: 192.168.29.101 #黑名單拒絕訪問 --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: name: nginx-ingress-serviceaccount namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: nginx-ingress-role namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - pods - secrets - namespaces verbs: - get - apiGroups: - "" resources: - configmaps resourceNames: # Defaults to "<election-id>-<ingress-class>" # Here: "<ingress-controller-leader>-<nginx>" # This has to be adapted if you change either parameter # when launching the nginx-ingress-controller. - "ingress-controller-leader-nginx" verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: nginx-ingress-role-nisa-binding namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-role subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: nginx-ingress-clusterrole-nisa-binding labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: hostNetwork: true ###修改爲hostNetwork模式直接共享服務器的網絡名稱空間 # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux kubernetes.io/hostname: k8s-master02 dnsPolicy: ClusterFirstWithHostNet containers: - name: nginx-ingress-controller imagePullPolicy: IfNotPresent image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 protocol: TCP #hostPort: 80 - name: https containerPort: 443 protocol: TCP #hostPort: 443 livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop: exec: command: - /wait-shutdown --- apiVersion: v1 kind: LimitRange metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: limits: - min: memory: 90Mi cpu: 100m type: Container
需修改:
hostNetwork: true ###修改爲hostNetwork模式直接共享服務器的網絡名稱空間
執行create建立Ingress-Controller
[root@k8s-master01 ingressdeploy]# kubectl get deploy -n ingress-nginx NAME READY UP-TO-DATE AVAILABLE AGE nginx-ingress-controller 1/1 1 1 76m
Ingress-Controller已部署完成
建立測試的web應用
[root@k8s-master01 daem]# cat deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: namespace: default name: nginxapp labels: app: nginx-deploy spec: replicas: 2 selector: matchLabels: app: mynginx template: metadata: labels: app: mynginx spec: containers: - name: nginxweb image: nginx:1.15-alpine [root@k8s-master01 daem]# cat svc.yaml apiVersion: v1 kind: Service metadata: name: nginx-svc labels: app: nginx-svc spec: ports: - name: http port: 80 protocol: TCP nodePort: 30001 #node節點的映射端口 能夠經過外部訪問 targetPort: 80 selector: app: mynginx sessionAffinity: None type: NodePort
建立Ingress規則
[root@k8s-master01 daem]# cat ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-daem annotations: kubernetes.io/ingress.class: "nginx" #nginx.ingress.kubernetes.io/limit-connections: 10 #nginx.ingress.kubernetes.io/limit-rate: 100K #nginx.ingress.kubernetes.io/limit-rps: 1 #nginx.ingress.kubernetes.io/limit-rpm: 30 spec: rules: - host: test.nginxsvc.com http: paths: - backend: serviceName: nginx-svc servicePort: 80 path: /
瀏覽器訪問
添加hosts解析
192.168.29.102 test.nginxsvc.com test-tls.test.com
[root@k8s-master01 daem]# curl -I http://test.nginxsvc.com/ HTTP/1.1 200 OK Server: nginx/1.17.8 Date: Thu, 03 Dec 2020 06:56:49 GMT Content-Type: text/html Content-Length: 612 Connection: keep-alive Vary: Accept-Encoding Last-Modified: Sat, 11 May 2019 00:35:53 GMT ETag: "5cd618e9-264" Accept-Ranges: bytes
流量重定向到目標URL
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-daem annotations: #kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com #當訪問 test.nginxsvc.com會被重寫到百度上 spec: rules: - host: test.nginxsvc.com http: paths: - backend: serviceName: nginx-svc servicePort: 80 path: /
先後端分離
[root@k8s-master01 daem]# cat ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-daem annotations: #kubernetes.io/ingress.class: "nginx" #nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com nginx.ingress.kubernetes.io/rewrite-target: / #當訪問test.nginxsvc.com/foo 會把請求打到 nginx-svc此service上 spec: rules: - host: test.nginxsvc.com http: paths: - backend: serviceName: nginx-svc servicePort: 80 path: /foo [root@k8s-master01 daem]# cat ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-daem annotations: #kubernetes.io/ingress.class: "nginx" #nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - host: test.nginxsvc.com http: paths: - backend: serviceName: nginx-svc servicePort: 80 path: /nginxservice(/|$)(.*) paths: - backend: serviceName: tomcat-svc servicePort: 80 path: /tomcatservice(/|$)(.*) #當訪問test.nginxsvc.com:PORT/tomcatservice -> 就會被重定向到tomcat-svc / 資源下
[root@k8s-master01 ~]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.cert -subj "/CN=test-tls.test.com/O=test-tls.test.com" Generating a 2048 bit RSA private key ..............................................+++ .........................................................................................+++ writing new private key to 'tls.key' ----- [root@k8s-master01 ~]# kubectl create secret tls ca-cert --key tls.key --cert tls.cert secret/ca-cert created [root@k8s-master01 ~]# cat tlsingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" name: test-tls spec: rules: - host: test-tls.test.com http: paths: - backend: serviceName: nginx-svc servicePort: 80 path: / tls: - hosts: - test-tls.test.com secretName: ca-cert
黑白名單 [root@k8s-master01 ingressdeploy]# cat mandatory.yaml apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx data: #############添加以下信息################# whitelist-source-range: 192.168.29.102 #白名單,容許某個IP或IP段的訪問 block-cidrs: 192.168.29.101 #黑名單拒絕訪問
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/server-snippet: | set $agentflag 0; if ($http_user_agent ~* "(Mobile)" ){ set $agentflag 1; } if ( $agentflag = 1 ) { return 301 https://m.example.com; }
解釋:
若是你的http_user_agent == Mobile。那麼就把agentflag set成1 ,而後當agentflag == 1時,就會return 到這個域名 https://m.example.com
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-nginx annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/limit-rate: 100K nginx.ingress.kubernetes.io/limit-rps: 1 nginx.ingress.kubernetes.io/limit-rpm: 30 spec: ......
nginx.ingress.kubernetes.io/limit-connections
單個IP地址容許的併發鏈接數。超過此限制時返回503錯誤
nginx.ingress.kubernetes.io/limit-rps:
每秒從給定IP接受的請求數。突發限制設置爲該限制乘以突發乘數,默認乘數爲5。當客戶機超過此限制時,將返回limit req status code default:503
nginx.ingress.kubernetes.io/limit-rpm:
每分鐘從給定IP接受的請求數。突發限制設置爲該限制乘以突發乘數,默認乘數爲5。當客戶機超過此限制時,將返回limit req status code default:503
nginx.ingress.kubernetes.io/limit-burst-multiplier:
突發大小限制速率的乘數。默認的突發乘數爲5,此批註覆蓋默認乘數。當客戶機超過此限制時,將返回limit req status code default:503。
nginx.ingress.kubernetes.io/limit-rate-after
初始千字節數,此後對給定鏈接的響應的進一步傳輸將受到速率限制。此功能必須在啓用代理緩衝的狀況下使用
nginx.ingress.kubernetes.io/limit-rate
每秒容許發送到給定鏈接的KB數。零值禁用速率限制。此功能必須在啓用代理緩衝的狀況下使用
nginx.ingress.kubernetes.io/limit-whitelist
要從速率限制中排除的客戶端IP源範圍。該值是一個逗號分隔的cidr列表
以上就是Ingress經常使用的相關配置,全部配置均來自官方文檔:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/