6-1 ingress及ingress controller
Kubernetes v1.19 [stable] 管理对集群中服务的外部访问的API对象,通常是HTTP。 Ingress可以提供负载平衡、SSL终止和基于名称的虚拟主机 Ingress 是什么? Ingress将来自集群外部的HTTP和HTTPS路由暴露给集群内的服务。流量路由由Ingress资源上定义的规则控制。 可以将Ingress配置为提供服务外部可访问的 URL、负载均衡流量、SSL/TLS,以及提供基于名称的虚拟主机。Ingress 控制器 通常负责通过负载均衡器来实现 ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。 Ingress不会公开任意端口或协议。若将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。 ingress是k8s集群里工作在osi网络参考模型下,第7层的应用,对外暴露的接口; service只能进行L4流量调度器,表现形式是ip+port; ingress则可以调度不同业务域、不同URL访问路径的业务流量; 文档:https://kubernetes.io/docs/concepts/services-networking/ingress/ Ingress-Nginx官网地址:https://kubernetes.github.io/ingress-nginx/ GitHub地址:https://github.com/kubernetes/ingress-nginx/ ingress所需的yaml文件: namespace.yaml rabc.yaml configmap.yaml tcp-services-configmap.yaml udp-services-cnfigmap.yaml with-rabc.yaml # kubectl apply -f namespace.yaml # kubectl apply -f rabc.yaml .... # kubectl get pod -n ingress-nginx 这是一个简单的示例,其中Ingress将其所有流量发送到一个Service: Ingress可以配置为向服务提供外部可访问的 URL、负载平衡流量、终止SSL/TLS并提供基于名称的虚拟主机。一个入口控制器负责履行入口,通常有一个负载均衡器,虽然它也可以配置您的边缘路由器或额外的前端,以帮助处理流量。 Ingress不会公开任意端口或协议。向Internet公开HTTP和HTTPS以外的服务通常使用Service.Type=NodePort或Service.Type=LoadBalancer类型的服务 示例1: https://cloud.tencent.com/developer/article/1718482 https://www.cnblogs.com/zhanglianghhh/p/13721288.html 镜像下载与重命名:因quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0无法拉取下来镜像,所以: docker pull registry.cn-beijing.aliyuncs.com/google_registry/nginx-ingress-controller:0.30.0 docker tag 89ccad40ce8e quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 docker rmi registry.cn-beijing.aliyuncs.com/google_registry/nginx-ingress-controller:0.30.0 使用nginx:0.30 ingress-nginx的yaml文件修改后并启动: 下载包: wget https://github.com/kubernetes/ingress-nginx/archive/nginx-0.30.0.tar.gz tar -xf nginx-0.30.0.tar.gz 解压后:yaml文件在下载包中的位置:ingress-nginx-nginx-0.30.0/deploy/static/mandatory.yaml cp -a ingress-nginx-nginx-0.30.0/deploy/static/mandatory.yaml ./ yaml文件配置修改: # vim mandatory.yaml ……………… apiVersion: apps/v1 kind: DaemonSet # 从Deployment改为DaemonSet 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 # 注释掉 ……………… nodeSelector: kubernetes.io/hostname: vm1 # 修改处,需注意打的master的标签label值 # 如下几行为新加行 作用【允许在master节点运行】 tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule ……………… ports: - name: http containerPort: 80 hostPort: 80 # 添加处【可在宿主机通过该端口访问Pod】 protocol: TCP - name: https containerPort: 443 hostPort: 443 # 添加处【可在宿主机通过该端口访问Pod】 protocol: TCP ……………… # 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 daemonset.apps/nginx-ingress-controller created limitrange/ingress-nginx created # kubectl get ds -n ingress-nginx -owide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR nginx-ingress-controller 1 1 1 1 1 kubernetes.io/hostname=vm1 62s nginx-ingress-controller registry.cn-beijing.aliyuncs.com/google_registry/nginx-ingress-controller:0.30.0 app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx # kubectl get pod -n ingress-nginx -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ingress-controller-9hs4s 1/1 Running 0 66s 10.244.0.7 vm1 <none> <none> 创建deployment和service: deployment_service1的yaml: # cat deploy_service1.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy1 namespace: default spec: relicas: 3 selector: matchLabels: app: myapp release: v1 template: metadata: labels: app: myapp release: v1 spec: containers: - name: myapp image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: myapp-clusterip1 namespace: default spec: type: ClusterIP #默认类型 selector: app: myapp release: v1 ports: - name: http port: 80 targetPort: 80 启动Deployment和Service # kubectl apply -f deploy_service1.yaml # kubectl get deployment -owide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp-deploy1 3/3 3 3 5m19s myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 app=myapp,release=v1 # kubectl get rs -owide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy1-7dc65c445c 3 3 3 5m55s myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 app=myapp,pod-template-hash=7dc65c445c,release=v1 # kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-deploy1-7dc65c445c-7sckz 1/1 Running 0 67s 10.244.1.34 vm2 <none> <none> myapp-deploy1-7dc65c445c-mqnst 1/1 Running 0 6m15s 10.244.1.33 vm2 <none> <none> myapp-deploy1-7dc65c445c-wn5vb 1/1 Running 0 67s 10.244.1.35 vm2 <none> <none> # kubectl get svc -owide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 44d <none> myapp-clusterip1 ClusterIP 10.1.165.199 <none> 80/TCP 3m19s app=myapp,release=v1 curl访问pod: # curl 10.244.1.34 # curl 10.244.1.34/hostname.html # curl 10.244.1.33/hostname.html # curl 10.244.1.35/hostname.html curl访问svc: # curl 10.1.165.199 # curl 10.1.165.199/hostname.html #多次curl deployment_service2的yaml: # cat deploy_service2.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy2 namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: v2 template: metadata: labels: app: myapp release: v2 spec: containers: - name: myapp image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: myapp-clusterip2 namespace: default spec: type: ClusterIP #默认类型 selector: app: myapp release: v2 ports: - name: http port: 80 targetPort: 80 启动Deployment和Service # kubectl apply -f deploy_service2.yaml # kubectl get deployment -owide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp-deploy1 3/3 3 3 14m myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 app=myapp,release=v1 myapp-deploy2 3/3 3 3 110s myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2 app=myapp,release=v2 # kubectl get rs -owide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy1-7dc65c445c 3 3 3 14m myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 app=myapp,pod-template-hash=7dc65c445c,release=v1 myapp-deploy2-744ff669dc 3 3 3 118s myapp registry.cn-beijing.aliyuncs.com/google_registry/myapp:v2 app=myapp,pod-template-hash=744ff669dc,release=v2 # kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-deploy1-7dc65c445c-7sckz 1/1 Running 0 9m51s 10.244.1.34 vm2 <none> <none> myapp-deploy1-7dc65c445c-mqnst 1/1 Running 0 14m 10.244.1.33 vm2 <none> <none> myapp-deploy1-7dc65c445c-wn5vb 1/1 Running 0 9m51s 10.244.1.35 vm2 <none> <none> myapp-deploy2-744ff669dc-5rzrm 1/1 Running 0 2m3s 10.244.1.36 vm2 <none> <none> myapp-deploy2-744ff669dc-mbkxv 1/1 Running 0 2m3s 10.244.1.37 vm2 <none> <none> myapp-deploy2-744ff669dc-zwkkz 1/1 Running 0 2m3s 10.244.1.38 vm2 <none> <none> # kubectl get svc -owide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 44d <none> myapp-clusterip1 ClusterIP 10.1.165.199 <none> 80/TCP 16m app=myapp,release=v1 myapp-clusterip2 ClusterIP 10.1.125.102 <none> 80/TCP 2m9s app=myapp,release=v2 curl访问svc: # curl 10.1.125.102 # curl 10.1.125.102/hostname.html #多次curl Ingress HTTP代理访问 yaml文件(由于自建的service在默认default名称空间,因此这里也是default名称空间) # cat ingress-http.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx-http namespace: default spec: rules: - host: www.zytest01.com http: paths: - path: / backend: serviceName: myapp-clusterip1 servicePort: 80 - host : www.zytest02.com http: paths: - path: / backend: serviceName: myapp-clusterip2 servicePort: 80 启动ingress并查看状态: # kubectl apply -f ingress-http.yaml ingress.networking.k8s.io/nginx-http created # kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE nginx-http <none> www.zytest01.com,www.zytest02.com 80 5s 查看Nginx的配置: # kubectl get pod -n ingress-nginx NAME READY STATUS RESTARTS AGE nginx-ingress-controller-9hs4s 1/1 Running 0 47m # kubectl exec -it nginx-ingress-controller-9hs4s -n ingress-nginx bash $ cat /etc/nginx/nginx.conf ...... ## start server www.zytest01.com server { server_name www.zytest01.com ; listen 80 ; listen 443 ssl http2 ; set $proxy_upstream_name "-"; ssl_certificate_by_lua_block { certificate.call() } location / { set $namespace "default"; set $ingress_name "nginx-http"; set $service_name "myapp-clusterip1"; set $service_port "80"; set $location_path "/"; ...... ## start server www.zytest02.com server { server_name www.zytest02.com ; listen 80 ; listen 443 ssl http2 ; set $proxy_upstream_name "-"; ssl_certificate_by_lua_block { certificate.call() } location / { set $namespace "default"; set $ingress_name "nginx-http"; set $service_name "myapp-clusterip2"; set $service_port "80"; set $location_path "/"; ...... 浏览器访问: hosts文件修改,添加如下信息(192.168.1.84为master/ingress机器的ip) 文件位置:C:\WINDOWS\System32\drivers\etc\hosts 192.168.1.84 www.zytest01.com www.zytest02.com 浏览器里输入:http://www.zytest01.com http://www.zytest02.com Ingress HTTPS代理访问 SSL证书创建: # mkdir cert # openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BeiJing/O=BTC/OU=MOST/CN=zhang/emailAddress=ca@test.com" cert]# ls -l total 8 -rw-r--r-- 1 root root 1359 Oct 6 01:06 tls.crt -rw-r--r-- 1 root root 1708 Oct 6 01:06 tls.key # kubectl create secret tls tls-secret --key tls.key --cert tls.crt secret/tls-secret created 创建ingress https yaml文件(由于自建的service在默认default名称空间,因此这里也是default名称空间) # cat ingress-https.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx-https namespace: default spec: tls: - hosts: - www.zytest01.com - www.zytest02.com secretName: tls-secret rules: - host: www.zytest01.com http: paths: - path: / backend: serviceName: myapp-clusterip1 servicePort: 80 - host: www.zytest02.com http: paths: - path: / backend: serviceName: myapp-clusterip2 servicePort: 80 启动ingress https并查看状态 # kubectl apply -f ingress-https.yaml # kubectl get ingress -owide NAME CLASS HOSTS ADDRESS PORTS AGE nginx-http <none> www.zytest01.com,www.zytest02.com 80 26m nginx-https <none> www.zytest01.com,www.zytest02.com 80, 443 79s 浏览器访问 hosts文件修改后再在浏览器访问: 浏览器里输入:https://www.zytest01.com https://www.zytest02.com Ingress-Nginx实现BasicAuth认证 官网地址: https://kubernetes.github.io/ingress-nginx/examples/auth/basic/ 准备工作: # htpasswd -c auth foo New password: Re-type new password: Adding password for user foo # ls -l -rw-r--r-- 1 root root 42 Oct 6 11:03 auth # cat auth foo:$apr1$Z3CNOfQA$kgNyXwHUz9gwGLmqnFJ.p1 # kubectl create secret generic basic-auth --from-file=auth secret/basic-auth created # kubectl get secret NAME TYPE DATA AGE basic-auth Opaque 1 8s default-token-4fzfg kubernetes.io/service-account-token 3 44d tls-secret kubernetes.io/tls 2 9h # kubectl get secret basic-auth -oyaml apiVersion: v1 data: auth: Zm9vOiRhcHIxJFozQ05PZlFBJGtnTnlYd0hVejlnd0dMbXFuRkoucDEK kind: Secret metadata: creationTimestamp: "2021-10-06T03:03:28Z" name: basic-auth namespace: default resourceVersion: "785781" selfLink: /api/v1/namespaces/default/secrets/basic-auth uid: f2144306-cafe-41ac-a2d0-15ab8f438602 type: Opaque ingress yaml文件: cat ingress-basicauth.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-with-auth annotations: # type of authentication nginx.ingress.kubernetes.io/auth-type: basic # name of the secret that contains the user/password definitions nginx.ingress.kubernetes.io/auth-secret: basic-auth # message to display with an appropriate context why the authentication is required nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo' spec: rules: - host: www.auth.zytest01.com http: paths: - path: / backend: serviceName: myapp-clusterip1 servicePort: 80 启动ingress并且查看状态: # kubectl apply -f ingress-basicauth.yaml ingress.networking.k8s.io/ingress-with-auth created # kubectl get ingress -owide NAME CLASS HOSTS ADDRESS PORTS AGE ingress-with-auth <none> www.auth.zytest01.com 80 68s 浏览器访问:写hosts后访问,需要输入用户名和密码 http://www.auth.zytest01.com Ingress-Nginx实现Rewrite重写 官网地址: https://kubernetes.github.io/ingress-nginx/examples/rewrite/ 名称描述值nginx.ingress.kubernetes.io/rewrite-target必须重定向的目标URLStringnginx.ingress.kubernetes.io/ssl-redirect指示位置部分是否只能由SSL访问(当Ingress包含证书时,默认为True)Boolnginx.ingress.kubernetes.io/force-ssl-redirect即使Ingress没有启用TLS,也强制重定向到HTTPSBoolnginx.ingress.kubernetes.io/app-root定义应用程序根目录,Controller在“/”上下文中必须重定向该根目录Stringnginx.ingress.kubernetes.io/use-regex指示Ingress上定义的路径是否使用正则表达式Bool ingress yaml文件: # cat ingress-rewrite.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/rewrite-target: https://www.baidu.com name: rewrite namespace: default spec: rules: - host: www.rewrite.zytest01.com http: paths: - backend: serviceName: myapp-clusterip1 servicePort: 80 启动ingress并且查看状态: # kubectl apply -f ingress-rewrite.yaml ingress.networking.k8s.io/rewrite created # kubectl get ingress -owide NAME CLASS HOSTS ADDRESS PORTS AGE rewrite <none> www.rewrite.zytest.com 80 66s 浏览器访问:写hosts后访问,需要输入用户名和密码 http://www.rewrite.zytest01.com 之后,可见重定向到了https://www.baidu.com 百度页面 ---------------------------------- 其它示例: service.yaml apiVersion:v1 kind: Service metadata: name: myapp namespace: default spec: selector: app: myapp release: canary ports: - name: http targetPort: 80 port: 80 --- apiVersion:apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: mathLables: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernets/app: v2 ports: - http: containerPort: 80 services-nodeport.yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx namespace: ingress-nginx spec: type: Nodeport ports: - name: http port: 80 targetPort: 80 protocol: TCP nodePort: 30080 - name: https port: 443 targetPort: 443 protocol: TCP nodePort: 300443 selector: app: ingress-nginx 基于ingress的后端app应用: myapp-ingress.yaml apiVsersion:extensions/v1beta1 kind:Ingress metadata: name: myapp-ingress namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: rancher.domain.com http: path: - path: backend: serviceName:myapp servicePort: 80 # kubectl apply -f myapp-ingress.yaml # kubectl get ingress 在浏览器访问:rancher.domain.com:30080 tomcat应用: tomcat-deploy.yaml apiVersion: v1 kind: Service metadata: name: tomcat namespace: default spec: selector: app: tomcat release: canary ports: - name: http port: 8080 targetPort: 8080 - name: ajp port: 8009 targetPort: 8009 --- apiVersion: v1 kind: Deployment metadata: name: tomcat-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: tomcat release: canary template: metadata: labels: app: tomcat release: canary spec: containers: - name: tomcat image: tomcat:8.5.32-jre8-alpine ports: - name: http containerPort: 8080 - name: ajp containerPort: 8009 ingress-tomcat.yaml apiVsersion:extensions/v1beta1 kind:Ingress metadata: name: ingress-tomcat namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: tomcat.domain.com http: path: - path: backend: serviceName:tomcat servicePort: 8080 # kubectl apply -f tomcat-deploy.yaml # kubectl apply -f ingress-tomcat.yaml # kuebctl get pod # kubectl get svc # kubectl get ingress NAME HOSTS ADDRESS PORTS AGE ingtess-tomcat tomcat.domain.com 80 10m 浏览器访问:tomcat.domain.com:30080 基于https: # kubectl secret ingress-tomcat-tls.yaml apiVsersion:extensions/v1beta1 kind:Ingress metadata: name: ingress-tomcat-tls namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - tomcat.domain.com secretName: tomcat-ingress.secret rules: - host: tomcat.domain.com http: path: - path: backend: serviceName:tomcat servicePort: 8080 # kubectl apply -f ingress-tomcat-tls.yaml # kuebctl get ingress NAME HOSTS ADDRESS PORTS AGE ingtess-tomcat tomcat.domain.com 80,443 10m ingtess-tomcat-tls tomcat.domain.com 80,443 1m 浏览器访问: https:tomcat.domain.com:30443 # kubectl get pods -n ingress nginx-ingress-controller--d658896cd-t55dm # kubectl exec -it nginx-ingress-controller--d658896cd-t55dm -n ingress cat nginx.conf