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 测试,可以看到跳转到了指定网页