k8s ingress以及ingress Cintroller
參考文檔:
https://segmentfault.com/a/1190000019908991
service的作用體現在兩個方面,對集群內部,它不斷跟蹤pod的變化,更新endpoint中對應pod的對象,提供了ip不斷變化的pod的服務發現機制,對集群外部,他類似負載均衡器,可以在集群內外部對pod進行訪問。但是,單獨用service暴露服務的方式,在實際生產環境中不太合適:
ClusterIP的方式只能在集群內部訪問。
NodePort方式的話,測試環境使用還行,當有幾十上百的服務在集群中運行時,NodePort的端口管理是災難。
LoadBalance方式受限於雲平台,且通常在雲平台部署ELB還需要額外的費用。
所幸k8s還提供了一種集群維度暴露服務的方式,也就是ingress。ingress可以簡單理解為service的service,他通過獨立的ingress對象來制定請求轉發的規則,把請求路由到一個或多個service中。這樣就把服務與請求規則解耦了,可以從業務維度統一考慮業務的暴露,而不用為每個service單獨考慮。
舉個例子,現在集群有api、文件存儲、前端3個service,可以通過一個ingress對象來實現圖中的請求轉發:
ingress的部署
ingress的部署,需要考慮兩個方面:
ingress-controller是作為pod來運行的,以什么方式部署比較好
ingress解決了把如何請求路由到集群內部,那它自己怎么暴露給外部比較好
下面列舉一些目前常見的部署和暴露方式,具體使用哪種方式還是得根據實際需求來考慮決定。
Deployment+LoadBalancer模式的Service
如果要把ingress部署在公有雲,那用這種方式比較合適。用Deployment部署ingress-controller,創建一個type為LoadBalancer的service關聯這組pod。大部分公有雲,都會為LoadBalancer的service自動創建一個負載均衡器,通常還綁定了公網地址。只要把域名解析指向該地址,就實現了集群服務的對外暴露。
Deployment+NodePort模式的Service
同樣用deployment模式部署ingress-controller,並創建對應的服務,但是type為NodePort。這樣,ingress就會暴露在集群節點ip的特定端口上。由於nodeport暴露的端口是隨機端口,一般會在前面再搭建一套負載均衡器來轉發請求。該方式一般用於宿主機是相對固定的環境ip地址不變的場景。
NodePort方式暴露ingress雖然簡單方便,但是NodePort多了一層NAT,在請求量級很大時可能對性能會有一定影響。
DaemonSet+HostNetwork+nodeSelector
用DaemonSet結合nodeselector來部署ingress-controller到特定的node上,然后使用HostNetwork直接把該pod與宿主機node的網絡打通,直接使用宿主機的80/433端口就能訪問服務。這時,ingress-controller所在的node機器就很類似傳統架構的邊緣節點,比如機房入口的nginx服務器。該方式整個請求鏈路最簡單,性能相對NodePort模式更好。缺點是由於直接利用宿主機節點的網絡和端口,一個node只能部署一個ingress-controller pod。比較適合大並發的生產環境使用。
注意事項:使用hostnetwork DNS配置策略項必須使用:dnsPolicy: ClusterFirstWithHostNet,此項配置如果不指定,可能會導致內部svc域名無法解析。
ingress與ingress-controller
要理解ingress,需要區分兩個概念,ingress和ingress-controller:
ingress對象:
指的是k8s中的一個api對象,一般用yaml配置。作用是定義請求如何轉發到service的規則,可以理解為配置模板。
ingress-controller:
具體實現反向代理及負載均衡的程序,對ingress定義的規則進行解析,根據配置的規則來實現請求轉發。
簡單來說,ingress-controller才是負責具體轉發的組件,通過各種方式將它暴露在集群入口,外部對集群的請求流量會先到ingress-controller,而ingress對象是用來告訴ingress-controller該如何轉發請求,比如哪些域名哪些path要轉發到哪些服務等等。
ingress Cintroller
重要:可以使用DaemonSet結合nodeselector來部署ingress-controller到特定的node(打上污點)上,然后使用HostNetwork直接把該pod與宿主機node的網絡打通,直接使用宿主機的80/433端口就能訪問服務。
一組獨立運行的一組pod資源,可以理解為應用程序,可以實現七層調度負載均衡。
若集群中存在N多個Node節點,可以通過DaemonSet 控制器運行一個為集群接入七層調度的負載均衡pod,用於轉發至后端pod。
此pod監聽nNodeIP+port,可以在前面搭建四層代理轉發至這幾台node節點,在通過這幾個pod實現七層負載均衡至后端pod。
如何對后端pod進行分組
還必須要借助service 的標簽選擇器來將后端代理的pod來分組,僅僅用來對后端pod資源功能分組,upstream 里面寫入service地址,ingress Cintroller pod還是直接訪問后端pod地址。
ingress 與 ingress Cintroller 並不是一回事
ingress資源
ingress 定義了期望 ingress Cintroller 如何建立一個前端,可能是一個虛機,也有可能是url映射。
如何實現對后端pod進行實時監控
同時定義了upstream service,可以通過service 來得到有幾個主機並識別出后端pod的ip地址,並反饋注入到配置文件中。
可以保存為配置文件,一旦ingress發現serrvice 關聯的pod資源發生改變(重建、修改等),會及時反應到ingress中並及時注入到 ingress Cintroller pod的配置文件中,pod中的主容器進程重新加載配置文件(因為upstream中配置的 service並不會實現負載均衡功能,僅僅用來實現分組分類,實際上還是ingress Cintroller pod還是直接訪問后端pod地址)。
ingress參考文檔:https://segmentfault.com/a/1190000019908991
在華為雲買一塊硬盤,掛載到服務器並初始化:https://support.huaweicloud.com/qs-ecs/zh-cn_topic_0085634797.html
搭建nfs:https://www.cnblogs.com/rtnb/p/15584847.html
先跑起來
部署一個ingress控制器,資源清單
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 --- 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: serviceAccountName: nginx-ingress-serviceaccount containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0 imagePullPolicy: IfNotPresent 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 -> 33 runAsUser: 33 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 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 ---
service
apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: type: NodePort ports: - name: http port: 80 targetPort: 80 protocol: TCP - name: https port: 443 targetPort: 443 protocol: TCP selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx
運行
]# kubectl apply -f mandatory.yaml namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.apps/nginx-ingress-controller created
修改測試網頁
cat index.html
www.magedu.com
www.rtnb.com
制作兩個不同業務的鏡像:搭建后端pod服務器:https://www.cnblogs.com/rtnb/p/15646506.html
后端服務資源清單
kind: Deployment apiVersion: apps/v1 metadata: labels: app: magedu-nginx-deployment-label name: magedu-nginx-deployment namespace: linux40 spec: replicas: 1 selector: matchLabels: app: magedu-nginx-selector template: metadata: labels: app: magedu-nginx-selector spec: containers: - name: magedu-nginx-container image: nginx-web1-magedu:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 protocol: TCP name: http - containerPort: 443 protocol: TCP name: https env: - name: "password" value: "123456" - name: "age" value: "20" resources: limits: cpu: 1 memory: 512Mi requests: cpu: 200m memory: 246Mi volumeMounts: - name: magedu-images mountPath: /usr/local/nginx/html/webapp/images readOnly: false - name: magedu-static mountPath: /usr/local/nginx/html/webapp/static readOnly: false volumes: - name: magedu-images nfs: server: 192.168.0.58 path: /root/data/nginx/nfs1 - name: magedu-static nfs: server: 192.168.0.104 path: /root/data/nginx/nfs2 --- kind: Service apiVersion: v1 metadata: labels: app: magedu-nginx-service-label name: magedu-nginx-service namespace: linux40 spec: type: ClusterIP ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: magedu-nginx-selector --- apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: namespace: linux40 name: linux40-nginx-web1-podautoscaler labels: app: magedu-nginx-selector version: v2beta1 spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: magedu-nginx-deployment minReplicas: 2 maxReplicas: 5 targetCPUUtilizationPercentage: 60
啟動服務
[root@master project]# kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE ingress-nginx nginx-ingress-controller-67cff8fb65-z4cn8 1/1 Running 1 17h linux40 magedu-nginx-deployment-8589cb6dc7-mvtv6 1/1 Running 0 9s linux40 magedu-nginx-deployment-8589cb6dc7-s2tlr 1/1 Running 0 24s linux40 rtnb-nginx-deployment-7c668f7c6-jq8tg 1/1 Running 0 19s linux40 rtnb-nginx-deployment-7c668f7c6-xz7fl 1/1 Running 0 4s
查看svc
[root@master nginx]# kubectl get svc -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE linux40 magedu-nginx-service ClusterIP 10.98.112.183 <none> 80/TCP 19m
測試
[root@master nginx]# curl 10.98.112.183 www.magedu.com test page
部署ingress,轉發規則
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-test namespace: linux40 //注意,非同一個namespace,無法轉發 annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/use-regex: "true" spec: rules: - host: www.magedu.com http: paths: - path: / backend: serviceName: magedu-nginx-service servicePort: 80 - path: /webapp backend: serviceName: linux39-tomcat-app1-service servicePort: 80
查看
]# kubectl get ingress -n linux39 NAME CLASS HOSTS ADDRESS PORTS AGE ingress-magedu-nginx-service <none> www.magedu.com,www.magedu.com 80, 443 112m
查看端口
[root@master nginx]# kubectl get svc -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx ingress-nginx NodePort 10.98.53.31 <none> 80:32280/TCP,443:30022/TCP 22h
測試訪問,用瀏覽器訪問
http://www.magedu.com:32280/webapp/ linux36 web1 v1 linux36 web1 v2 linux36 web1 v3
http://www.magedu.com:32280/ www.magedu.com test page
二、Ingress HTTPS 代理訪問
2.1 制作證書以及secret
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=magedu-nginx-service/O=magedu-nginx-service" kubectl create secret tls tls-secret --key tls.key --cert tls.crt
2.2 ssl域名類型的域名
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress_magedu-nginx-service spec: tls: - hosts: - www.magedu.com secretName: tls-secret rules: - host: www.magedu.com http: paths: - path: / backend: serviceName: magedu-nginx-service servicePort: 80
2.3 查看端口
]# kubectl get svc -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d18h ingress-nginx ingress-nginx NodePort 10.98.53.31 <none> 80:32280/TCP,443:30022/TCP 2d16h
2.4 查看ingress
]# kubectl get ingress -n linux39 Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-magedu-nginx-service <none> www.magedu.com,www.magedu.com 80, 443 112m
2.5 測試訪問
三、拓展
3.1 進入ingress-controller pod,在/etc/nginx/conf.d目錄下查看nginx.conf,可以查看到以下轉發策略
upstream upstream_balancer { server 0.0.0.1; # placeholder balancer_by_lua_block { balancer.balance() } keepalive 32; keepalive_timeout 60s; keepalive_requests 100; } server { server_name www.magedu.com ; listen 80; set $proxy_upstream_name "-"; set $pass_access_scheme $scheme; set $pass_server_port $server_port; set $best_http_host $http_host; set $pass_port $pass_server_port; listen 443 ssl http2; # PEM sha: 1d79db9b8d38290f05f4c11572e7a284c02c4a4f ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem; # 這個證書莫非是 ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem; # 私鑰 ssl_certificate_by_lua_block { certificate.call() } location /myapp { # uri set $namespace "linux39"; # namespace set $ingress_name "ingress-magedu-nginx-service"; set $service_name "linux39-tomcat-app1-service"; # 后端service名稱 set $service_port "80"; set $location_path "/myapp"; rewrite_by_lua_block { lua_ingress.rewrite({ force_ssl_redirect = true, use_port_in_redirects = false, }) balancer.rewrite() plugins.run() } header_filter_by_lua_block { plugins.run() } body_filter_by_lua_block { } log_by_lua_block { balancer.log() monitor.call() plugins.run() } if ($scheme = https) { more_set_headers "Strict-Transport-Security: max-age=15724800; includeSubDomains"; } port_in_redirect off; set $balancer_ewma_score -1; set $proxy_upstream_name "linux39-linux39-tomcat-app1-service-80"; set $proxy_host $proxy_upstream_name; set $proxy_alternative_upstream_name ""; client_max_body_size 1m; proxy_set_header Host $best_http_host; # Pass the extracted client certificate to the backend # Allow websocket connections proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Request-ID $req_id; proxy_set_header X-Real-IP $the_real_ip; proxy_set_header X-Forwarded-For $the_real_ip; proxy_set_header X-Forwarded-Host $best_http_host; proxy_set_header X-Forwarded-Port $pass_port; proxy_set_header X-Forwarded-Proto $pass_access_scheme; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Scheme $pass_access_scheme; # Pass the original X-Forwarded-For proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for; # mitigate HTTPoxy Vulnerability # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ proxy_set_header Proxy ""; # Custom headers to proxied server proxy_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; proxy_buffering off; proxy_buffer_size 4k; proxy_buffers 4 4k; proxy_request_buffering on; proxy_http_version 1.1; proxy_cookie_domain off; proxy_cookie_path off; # In case of errors try the next upstream server before returning an error proxy_next_upstream error timeout; proxy_next_upstream_timeout 0; proxy_next_upstream_tries 3; proxy_pass http://upstream_balancer; # 轉發 proxy_redirect off; } location / { set $namespace "linux39"; set $ingress_name "ingress-magedu-nginx-service"; set $service_name "magedu-nginx-service"; set $service_port "80"; set $location_path "/"; rewrite_by_lua_block { lua_ingress.rewrite({ force_ssl_redirect = true, use_port_in_redirects = false, }) balancer.rewrite() plugins.run() } header_filter_by_lua_block { plugins.run() } body_filter_by_lua_block { } log_by_lua_block { balancer.log() monitor.call() plugins.run() } if ($scheme = https) { more_set_headers "Strict-Transport-Security: max-age=15724800; includeSubDomains"; } port_in_redirect off; set $balancer_ewma_score -1; set $proxy_upstream_name "linux39-magedu-nginx-service-80"; set $proxy_host $proxy_upstream_name; set $proxy_alternative_upstream_name ""; client_max_body_size 1m; proxy_set_header Host $best_http_host; # Pass the extracted client certificate to the backend # Allow websocket connections proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header X-Request-ID $req_id; proxy_set_header X-Real-IP $the_real_ip; proxy_set_header X-Forwarded-For $the_real_ip; proxy_set_header X-Forwarded-Host $best_http_host; proxy_set_header X-Forwarded-Port $pass_port; proxy_set_header X-Forwarded-Proto $pass_access_scheme; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Scheme $pass_access_scheme; # Pass the original X-Forwarded-For proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for; # mitigate HTTPoxy Vulnerability # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ proxy_set_header Proxy ""; # Custom headers to proxied server proxy_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; proxy_buffering off; proxy_buffer_size 4k; proxy_buffers 4 4k; proxy_request_buffering on; proxy_http_version 1.1; proxy_cookie_domain off; proxy_cookie_path off; # In case of errors try the next upstream server before returning an error proxy_next_upstream error timeout; proxy_next_upstream_timeout 0; proxy_next_upstream_tries 3; proxy_pass http://upstream_balancer; proxy_redirect off; } }
cd /etc/ingress-controller/ssl/ $ ls default-fake-certificate.pem $ cat default-fake-certificate.pem -----BEGIN CERTIFICATE----- MIIDcDCCAligAwIBAgIRALJgcH7IPjDUE3BfuvHirsUwDQYJKoZIhvcNAQELBQAw SzEQMA4GA1UEChMHQWNtZSBDbzE3MDUGA1UEAxMuS3ViZXJuZXRlcyBJbmdyZXNz IENvbnRyb2xsZXIgRmFrZSBDZXJ0aWZpY2F0ZTAeFw0yMjA1MDcxMTAxMTVaFw0y MzA1MDcxMTAxMTVaMEsxEDAOBgNVBAoTB0FjbWUgQ28xNzA1BgNVBAMTLkt1YmVy bmV0ZXMgSW5ncmVzcyBDb250cm9sbGVyIEZha2UgQ2VydGlmaWNhdGUwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCa5LFSYG3MFML5oqEv6+QKIPXNJIJ2 nJWHtwWryBGgHXmdn3fy1pEC+yI3I6umiDUkyBqoVbrFD7XB/IKxwrilXnN2rUA7 9/OuB6suL0AltiEMgDQ96EoT8LPMuBJcyy7IJK3qa9xr0o1u1Ty7tU++WLC3VOXa 5ERHmxqMhapD/svTuYyqc2hT+8ekRAj9MJi9HRu1sqg3MU2HCdN/YhJ4nFtrY6+W c8GaqyL4Uq44BME7d/dcpCIF5Yb1GZTrPQYIv6FWW45j6kE4JzmRty2Mz16aj9rC cjmrQHlbA7Imf4UkG5qU3a+e2sHOn8ITLUzQKiqZx7aSBDA3VT3uKEotAgMBAAGj TzBNMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMB Af8EAjAAMBgGA1UdEQQRMA+CDWluZ3Jlc3MubG9jYWwwDQYJKoZIhvcNAQELBQAD ggEBAEZCJZ+0XaUifvYAM5nWuDmle9Do8o4F3mu0aVspvCberU2hzFaNGKy4t46y Lx2sMlrUcdpdl+z8Z6qoCCWcDnQaw85hhRzoSNNnHz4N73zrBS2bj30Qv8uPCngy xo3w3IMWkLu2D894p46d8ndiXwtc9wdnIt7h7DGZN5/L6WCjX0S/j5BgLfq7P85f 3iwCKPww0xocPym7swybkJLMG5IanTXzUCCraHs4h+x8weBhptuwOgQHBAy1CxM4 0CalNAYr9iPhzhCYA9hiNywNgUeu+DdTjyydHYXrc59EOCRbgMzBGxFMh0tihoLS H8uM4dx4HEDeJwwIfpbM8KLCVOw= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAmuSxUmBtzBTC+aKhL+vkCiD1zSSCdpyVh7cFq8gRoB15nZ93 8taRAvsiNyOrpog1JMgaqFW6xQ+1wfyCscK4pV5zdq1AO/fzrgerLi9AJbYhDIA0 PehKE/CzzLgSXMsuyCSt6mvca9KNbtU8u7VPvliwt1Tl2uRER5sajIWqQ/7L07mM qnNoU/vHpEQI/TCYvR0btbKoNzFNhwnTf2ISeJxba2OvlnPBmqsi+FKuOATBO3f3 XKQiBeWG9RmU6z0GCL+hVluOY+pBOCc5kbctjM9emo/awnI5q0B5WwOyJn+FJBua lN2vntrBzp/CEy1M0Coqmce2kgQwN1U97ihKLQIDAQABAoIBABoB5DQstMLbiZFY 2S+ur+9zcVIsmytHR2QuOumJAkycJlts9zrzBA44FJqlhqDDpgizAKbbHi0QYjhc KaWnSFGb9k8q7+ohy+ygpQFwNZkfZ5UtwZfTdPy8IbRyA8NI6mX4oqsFyVDhXZYK f9QUsXsIcUOXIbELOtu7E04c82XPE5MqvnDfYl65Gzhr2bsUMihJUjjZS2Nj7uo8 T8MBitJ/quZ1yyXwSKuYJ4P2CgC6HjeG2gP62KrleWF4CPYbhYgkxwuA/UxnLWEL wi10k4nT+wZaS/gN4XLkXVfs71ejqUxMs0PLjTISUDuHUjwfZMbrucGWT2//e/GI HlqV6YECgYEAyBL+izdzr5/YHVLiSbiL6WTouyfgLveSXxhTpp+93g0K/9eRxYU5 eabKl5zWdQFJY53CgDbgu14wu8xfTZFgrCLPFLpKqstdis1SHEeLS9fpBdLMMaY1 j4TxJSrB460lQ9VRBTh5vanfWAprvW3FdZtn7Uhv8igVAYxQTbBoBKkCgYEAxjCf y6vQd1Qd2b3QnwCS4d0CWN9xyCUdh0ZXxNoHFPdIFtoP2ljNQCOAzzF699LJKabl ikBbiMQ5lF+BXUM8lKAAA/7MeTMDaXQ0bERWeosg3B9ksDiTi4QRuDfVsPYqTxTF Mj5cSppDSuvy7iOlbGpw5FMcADIgCeMJx7LPh+UCgYBLoMpxS3vCZlSl+P+qyESy 678Bh/g5KMI+ig6MzJNTzXBb91uV418vefnYx6NVRTA9pJOyLYxTpy4avw1DX/G/ /8RxXF3/I7JvVl90ayLff3UJC36+Qcq7PpB88SWrb3bHpmni5E84f276c634Q/dB FoZ5bklKqxYNqMFuLIGVSQKBgAFXuv1qQJNOYpVjD9LD8jrNgIKRoPe2KKkN9PJE d9/QfRCKkajtCRbyJqFAuJCNQQejNdLl9LjMe4dhzkKPfg2Tt+xPAZugmNlSDDjf jaZu4t4a6Fe5SmabknMpDa2RPWAjx+I7QezPdr0/M/ohC7HcVr91QK9Pp5/phdtw fq9xAoGBAIrHWRaToUOfzJg9cwNCschuQBmiRgDmY3YBS2lMhNvT0QRmfR38ObVK iwnIR3rk1ChPJsZFEZcYM2H2KoKHFifl6Bb1ZIx7nGofFRSW28tgSVMz5g01vtYg Wtaq+H7L/aUCRqa/mopBQu4QR2shbBLzR8+qrPmhncyNvJzJGpTO -----END RSA PRIVATE KEY-----
四、配置多域名的TLS
4.1 ingress
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-magedu-nginx-service namespace: linux39 spec: tls: - hosts: - magedu.com secretName: mage-tomcat rules: - host: nginx.magedu.com http: paths: - path: / backend: serviceName: magedu-nginx-service servicePort: 80 - host: tomcat.magedu.com http: paths: - path: /myapp backend: serviceName: linux39-tomcat-app1-service servicePort: 80
4.2 openssl.cnf
[req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [ alt_names ] DNS.1 = nginx.magedu.com # 多個域名設置 DNS.2 = tomcat.magedu.com
4.3 創建secret
openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -days 5000 -out ca.crt -subj "/CN=magedu.com" openssl genrsa -out ingress.key 2048 openssl req -new -key ingress.key -out ingress.csr -subj "/CN=magedu.com" -config openssl.cnf # 保證TLS證書包含相應的host全限定域名在/CN openssl x509 -req -in ingress.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ingress.crt -days 5000 -extensions v3_req -extfile openssl.cnf kubectl create secret tls mage-tomcat --key ingress.key --cert ingress.crt
五、Nginx 進行 BasicAuth
5.1 下載tools工具包
[root@master ingress]# yum -y install httpd-tools htpasswd -c auth foo //創建foo用戶 kubectl create secret generic basic-auth --from-file=auth //創建secret
5.2 創建ingress
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-with-auth annotations: nginx.ingress.kubernetes.io/auth-type: basic //需要后端開始認證模塊 nginx.ingress.kubernetes.io/auth-secret: basic-auth //secret 名稱 nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo' //歡迎信息 spec: rules: - host: foo2.bar.com http: paths: - path: / backend: serviceName: nginx-svc servicePort: 80
六、Nginx 重寫
6.1 資源清單
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-nginx-rewrite annotations: nginx.ingress.kubernetes.io/rewrite-target: http://www.baidu.com spec: rules: - host: rewrite.magedu.com http: //下面這塊可以不用寫了 paths: - path: / backend: serviceName: rtnb-nginx-service servicePort: 80
6.2 測試,可以看到跳轉到了指定網頁