前言:
什么是Ingress?
官网的解释是:
Ingress 是对集群中服务的内部拜访进行治理的 API 对象,典型的拜访形式是 HTTP。
Ingress 能够提供负载平衡、SSL 终结和基于名称的虚构托管。
Ingress简介
Ingress对象,其实就是对“反向代理”的一种形象,简略的说就是一个全局的负载均衡器,能够通过拜访URL定位到后端的Service
有了Ingress这个形象,K8S就不须要关怀Ingress的细节了,理论应用时,只须要抉择一个具体的Ingress Controller部署就行了,业界罕用的反向代理我的项目有:Nginx、HAProxy、Envoy、Traefik 都曾经成为了K8S专门保护的Ingress Controller
一个Ingress对象的次要内容,就相似Nginx的配置文件形容,对应的转发规定就是ingressRule,
有了Ingress这个对象,用户就能够依据本人的需要抉择Ingress Controller,例如,如果利用对代理服务的中断十分敏感,能够应用Treafik这样的Ingress Controller
Ingress工作在七层,Service工作在四层,当想要在Kubernetes里为利用进行TLS配置等HTTPS相干操作时,都必须通过Ingress来进行
- ingress-nginx 简略的了解就是你原来须要改 Nginx 配置,而后配置各种域名对应哪个 Service,当初把这个动作形象进去,变成一个 Ingress 对象,你能够用 yaml 创立,每次不要去改 Nginx 了,间接改 yaml 而后创立/更新就行了;那么问题来了:”Nginx 该怎么解决?”
- Ingress Controller 这货色就是解决 “Nginx 的解决形式” 的;Ingress Controoler 通过与 Kubernetes API 交互,动静的去感知集群中 Ingress 规定变动,而后读取他,依照他本人模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最初 reload 一下,工作流程如下图:
- 实际上Ingress也是Kubernetes API的规范资源类型之一,它其实就是一组基于DNS名称(host)或URL门路把申请转发到指定的Service资源的规定。用于将集群内部的申请流量转发到集群外部实现的服务公布。咱们须要明确的是,Ingress资源本身不能进行“流量穿透”,仅仅是一组规定的汇合,这些汇合规定还须要其余性能的辅助,比方监听某套接字,而后依据这些规定的匹配进行路由转发,这些可能为Ingress资源监听套接字并将流量转发的组件就是Ingress Controller
- Ingress 两种路由形式
1.虚拟主机
2.URL 门路
Ingree-nginx部署
ingress-nginx 很多全局配置或批改默认配置都是通过annotations 正文来加载配置文件具体参数具体解释可
参考官网文档:https://kubernetes.github.io/...
抉择NodePort部署形式
https://kubernetes.github.io/...
- extensions/v1beta1 Ingress资源标准 1.22+版本后会被彻底弃用
apiVersion: extensions/v1betal #资源所属的API群组和版本Kind: Ingress#资源类型标识符metadata: #元数据 name <string> #资源名称 annotationsl #资源注解,v1betal应用上面的注解来指定要解析该资源的控制器类型 kubernetes.io/ingress.class: <string> #适配的Ingress控制器类别 namespace <string> #名称空间spec: rules <[]Object> #Ingress规定列表; - host <string> #虚拟主机的FQDN,反对“*"前缀通配,不反对IP,不反对指定端口 http <object> paths<[]0bject>#虚拟主机PATH定义的列表,由path和backend组成 - path <string> #流量匹配的HTTP PATH,必须以/结尾 pathType <string> #匹配机制,反对Exact、_Prefix和ImplementationSpecific backend <object> #匹配到的流量转发到的指标后端 resource <Object> #援用的同一名称空间下的资源,与上面两个字段互斥 serviceName <string>#援用的Service资源的名称 servicePort <string># Service用于提供服务的端口 tls <[]object> #TLS配置,用于指定上rules中定义的哪些host须要工作HTTPS模式 - hosts <[]string> #应用同一组证书的主机名称列表 secretName <string> #保留于数字证书和私钥信息的secret资源名称 backend <object> #默认backend的定义,可嵌套字段及应用格局跟rules字段中的雷同 ingressClassName <string> #ingress类名称,用于指定适配的控制器
- v1 Ingress资源标准
apiVersion: networking.k8s.io/v1 #资源所属的API群组和版本kind: Ingress #资源类型标识符metadata: #元数据 name <string> #资源名称 annotations: #资源注解,vlbetal应用上面的注解来指定要解析该资源的控制器类型 kubernetes.io/ingress.class:<string> #适配的Ingress控制器类别 namespace <string> #名称空间spec: rules <[]object> #Ingress规定列表 - host <string> #虚拟主机的FQDN,反对“*"前缀通配,不反对IP,不反对指定端口 http <object> paths <[]object>#虚拟主机PATH定义的列表,由path和backend组成 - path <string> #流量匹配的HTTP PATH,必须以/结尾 pathType <string> #反对Exact、Prefix和ImplementationSpecific,必选 backend <Object>#匹配到的流量转发到的指标后端 resource <object> #援用的同一名称空间下的资源,与上面两个字段互斥 service <object> #关联的后端Service对象 name <string> #后端Service的名称 port bject> #后端Service上的端口对象 name <string> #端口名称 number <integer> #端口号 tls <[]object> #TLS配置,用于指定上rules中定义的哪些host须要工作HTTPS模式 - hosts <[]string> #应用同一组证书的主机名称列表 secretName <string> #保留于数字证书和私钥信息的secret资源名称 backend <object> #默认backend的定义,可嵌套字段及应用格局跟rules字段中的雷同 ingressClassName <string> #ingress类名称,用于指定适配的控制器
- 增加externalIPs:节点3 IP非必须步骤,不便记忆应用 而不是记忆NodePort端口 NodePort与externalIPs可同时拜访
[root@k8s-master Ingress]# vim deploy.yaml...---# Source: ingress-nginx/templates/controller-service.yamlapiVersion: v1kind: Servicemetadata: annotations: labels: helm.sh/chart: ingress-nginx-4.0.1 app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/version: 1.0.0 app.kubernetes.io/managed-by: Helm app.kubernetes.io/component: controller name: ingress-nginx-controller namespace: ingress-nginxspec: type: NodePort externalIPs: [192.168.54.173] #增加externalIPs字段 固定拜访IP ports: - name: http port: 80 protocol: TCP targetPort: http appProtocol: http - name: https port: 443 protocol: TCP targetPort: https appProtocol: https selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/component: controller...
- 部署Ingress-nginx
[root@k8s-master Ingress]# kubectl apply -f deploy.yaml namespace/ingress-nginx unchangedserviceaccount/ingress-nginx unchangedconfigmap/ingress-nginx-controller configuredclusterrole.rbac.authorization.k8s.io/ingress-nginx unchangedclusterrolebinding.rbac.authorization.k8s.io/ingress-nginx unchangedrole.rbac.authorization.k8s.io/ingress-nginx unchangedrolebinding.rbac.authorization.k8s.io/ingress-nginx unchangedservice/ingress-nginx-controller-admission unchangedservice/ingress-nginx-controller configureddeployment.apps/ingress-nginx-controller configuredingressclass.networking.k8s.io/nginx unchangedvalidatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission configuredserviceaccount/ingress-nginx-admission unchangedclusterrole.rbac.authorization.k8s.io/ingress-nginx-admission unchangedclusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchangedrole.rbac.authorization.k8s.io/ingress-nginx-admission unchangedrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchangedjob.batch/ingress-nginx-admission-create unchangedjob.batch/ingress-nginx-admission-patch unchanged[root@k8s-master Ingress]# kubectl get podNAME READY STATUS RESTARTS AGEetcd-operator-646cbffdb6-brbn6 1/1 Running 0 19hexample-etcd-cluster-5fb5d9d6n8 1/1 Running 0 49mexample-etcd-cluster-nc8pdgjrjr 1/1 Running 0 19hexample-etcd-cluster-svgdngq28k 1/1 Running 0 48m[root@k8s-master Ingress]# kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx-controller NodePort 10.109.24.78 192.168.54.173 80:32493/TCP,443:30239/TCP 120mingress-nginx-controller-admission ClusterIP 10.110.72.52 <none> 443/TCP 120m
示例1:创立 Ingress-nginx虚拟主机
- 创立 Deployment 和与之对应的SVC
[root@k8s-master Ingress]# cat deployment-demo.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: deployment-demo namespace: defaultspec: replicas: 4 selector: matchLabels: app: demoapp release: stable template: metadata: labels : app: demoapp release: stable spec: containers: - name: demoapp image: ikubernetes/demoapp:v1.1 ports: - containerPort: 80 name: http---apiVersion: v1kind: Servicemetadata: name: demoapp-deploy namespace: defaultspec: selector: app: demoapp release: stable ports: - name: http port: 80 targetPort: 80
- 创立 ingress-nginx
[root@k8s-master Ingress]# cat demoapp-ingress.yaml apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-demo annotations: kubernetes.io/ingress.class: "nginx" namespace: defaultspec: rules: - host: www.ik8s.io #虚拟主机 http: paths: - path: / pathType: Prefix #前缀匹配 backend: service: name: demoapp-deploy port: number: 80[root@k8s-master Ingress]# kubectl apply -f deployment-demo.yaml[root@k8s-master Ingress]# kubectl apply -f demoapp-ingress.yaml[root@k8s-master Ingress]# kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx-controller NodePort 10.109.24.78 192.168.54.173 80:32493/TCP,443:30239/TCP 5h50mingress-nginx-controller-admission ClusterIP 10.110.72.52 <none> 443/TCP 5h50m[root@k8s-master Ingress]# kubectl get ingressWarning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 IngressNAME CLASS HOSTS ADDRESS PORTS AGEingress-demo <none> www.ik8s.io 192.168.4.171 80 3h11m
- 拜访测试
[root@bigyong ~]# cat /etc/hosts # ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4...192.168.54.173 www.ik8s.io #写hosts[root@bigyong ~]# curl 192.168.54.173 #间接拜访只能到ingress-nginx 没到转发到后端<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center><hr><center>nginx</center></body></html>[root@bigyong ~]# curl -H "Host:www.ik8s.io" 192.168.54.173 #拜访胜利iKubernetes demoapp v1.1 !! ClientIP: 192.168.113.37, ServerName: deployment-demo-867c7d9d55-gw6qp, ServerIP: 192.168.113.39[root@bigyong ~]# curl -H "Host:www.ik8s.io" 192.168.54.173iKubernetes demoapp v1.1 !! ClientIP: 192.168.113.37, ServerName: deployment-demo-867c7d9d55-9lnpq, ServerIP: 192.168.12.39![root@bigyong ~]# curl -H "Host:www.ik8s.io" 192.168.54.173iKubernetes demoapp v1.1 !! ClientIP: 192.168.113.37, ServerName: deployment-demo-867c7d9d55-2zcr5, ServerIP: 192.168.51.61![root@bigyong ~]# curl -H "Host:www.ik8s.io" 192.168.54.173iKubernetes demoapp v1.1 !! ClientIP: 192.168.113.37, ServerName: deployment-demo-867c7d9d55-9lnpq, ServerIP: 192.168.12.39!
示例2:创立TLS Ingress HTTPS
[root@k8s-master Ingress]# cat demoapp-ingress.yaml apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ingress-demo annotations: kubernetes.io/ingress.class: "nginx" namespace: defaultspec: rules: - host: www.ik8s.io http: paths: - path: / pathType: Prefix #前缀匹配 backend: service: name: demoapp-deploy port: number: 80 tls: #增加tls - hosts: - www.ik8s.io secretName: ik8s-tls [root@k8s-master Ingress]# kubectl apply -f demoapp-ingress.yaml ingress.networking.k8s.io/ingress-demo configured[root@k8s-master Ingress]# kubectl describe ingress ingress-demoWarning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 IngressName: ingress-demoNamespace: defaultAddress: 192.168.4.171Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)TLS: ik8s-tls terminates www.ik8s.ioRules: Host Path Backends ---- ---- -------- www.ik8s.io / demoapp-deploy:80 (192.168.113.39:80,192.168.12.39:80)Annotations: kubernetes.io/ingress.class: nginxEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 113s (x3 over 6h36m) nginx-ingress-controller Scheduled for sync
- 创立tls自签证书
[root@k8s-master Ingress]# (umask 077); openssl genrsa -out tls.key 2048Generating RSA private key, 2048 bit long modulus............................+++.......................+++e is 65537 (0x10001)[root@k8s-master Ingress]# openssl req -new -x509 -key tls.key -out tls.crt -subj "/CN=www.ik8s.io" -days 365[root@k8s-master Ingress]# lsdemoapp-ingress.yaml deployment-demo.yaml tls.crtdeploy-externalIP.yaml deploy.yaml tls.key
- 创立Secret
[root@k8s-master Ingress]# kubectl create secret tls ik8s-tls --cert=./tls.crt --key=./tls.keysecret/ik8s-tls created
- 拜访测试
[root@k8s-master Ingress]# curl -H "Host:www.ik8s.io" 192.168.54.173 #308曾经被重定向<html><head><title>308 Permanent Redirect</title></head><body><center><h1>308 Permanent Redirect</h1></center><hr><center>nginx</center></body></html>#通过https拜访 提醒证书有效不被信赖[root@k8s-master Ingress]# curl -H "Host:www.ik8s.io" https://192.168.54.173 curl: (60) Issuer certificate is invalid.More details here: http://curl.haxx.se/docs/sslcerts.htmlcurl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option.If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL).If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
- 疏忽危险 拜访胜利
[root@k8s-master Ingress]# curl -k -H "Host:www.ik8s.io" https://192.168.54.173 iKubernetes demoapp v1.1 !! ClientIP: 192.168.113.37, ServerName: deployment-demo-867c7d9d55-9lnpq, ServerIP: 192.168.12.39!
示例3:为dashboard 增加ingress
https://kubernetes.github.io/...
[root@k8s-master Ingress]# cat ingress-kubernetes-dashboard.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: dashboard annotations: kubernetes.io/ingress.class: "nginx" #指定控制器 ingress.kubernetes.io/ssl-passthrough: "true" #tcp代理 因为后端dashboard必须通过https拜访 这里通过4层转发间接转发到后端Pod nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" #后端间接通过https协定拜访 nginx.ingress.kubernetes.io/rewrite-target: /$2 #重写标记 path:/dashboard(/|$)(.*) 这里的第2局部 namespace: kubernetes-dashboardspec: #这里没有配置host 相当于*号通配所有主机 rules: - http: paths: - path: /dashboard(/|$)(.*) backend: serviceName: kubernetes-dashboard servicePort: 443[root@k8s-master Ingress]# kubectl apply -f ingress-kubernetes-dashboard.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingressingress.extensions/dashboard created[root@k8s-master Ingress]# kubectl describe ingress dashboard -n kubernetes-dashboardWarning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 IngressName: dashboardNamespace: kubernetes-dashboardAddress: 192.168.4.171Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)Rules: Host Path Backends ---- ---- -------- * /dashboard(/|$)(.*) kubernetes-dashboard:443 (192.168.51.64:8443) #后端podAnnotations: ingress.kubernetes.io/ssl-passthrough: true kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/backend-protocol: HTTPS nginx.ingress.kubernetes.io/rewrite-target: /$2Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 103s (x2 over 2m41s) nginx-ingress-controller Scheduled for sync
- 拜访测试
留神:https://192.168.54.173/dashbo... 肯定要带上最初的/ $2为/前面局部 不然无法访问
示例4:longhorn增加ingress-nginx basic认证
参考官网文档
https://longhorn.io/docs/1.2....
- 默认longhorn没有登录认证裸露到公网会存在危险 首先增加basic认证
[root@k8s-master Ingress]# kubectl get pod -n longhorn-system NAME READY STATUS RESTARTS AGE....longhorn-manager-cc8sp 1/1 Running 0 149mlonghorn-manager-fs5tx 1/1 Running 2 149mlonghorn-manager-vwbzn 1/1 Running 1 149mlonghorn-ui-79f8976fbf-c44ct 1/1 Running 1 149m[root@k8s-master Ingress]# kubectl get svc -n longhorn-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEcsi-attacher ClusterIP 10.108.190.205 <none> 12345/TCP 142mcsi-provisioner ClusterIP 10.99.216.181 <none> 12345/TCP 142mcsi-resizer ClusterIP 10.96.161.192 <none> 12345/TCP 141mcsi-snapshotter ClusterIP 10.101.216.72 <none> 12345/TCP 141mlonghorn-backend ClusterIP 10.108.67.31 <none> 9500/TCP 149mlonghorn-frontend ClusterIP 10.107.71.176 <none> 80/TCP 149m[root@k8s-master Ingress]# USER=user.com; PASSWORD=passwd.com; echo "${USER}:$(openssl passwd -stdin -apr1 <<< ${PASSWORD})" >> auth[root@k8s-master Ingress]# lsauth deploy-externalIP.yaml deploy.yaml tls.crtdemoapp-ingress.yaml deployment-demo.yaml ingress-kubernetes-dashboard.yaml tls.key[root@k8s-master Ingress]# kubectl -n longhorn-system create secret generic basic-auth --from-file=authsecret/basic-auth created[root@k8s-master Ingress]# cat longhorn-ui-ingress.yaml apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: longhorn-ingress namespace: longhorn-system annotations: kubernetes.io/ingress.class: "nginx" #指定控制器 # type of authentication nginx.ingress.kubernetes.io/auth-type: basic #认证类型 # prevent the controller from redirecting (308) to HTTPS nginx.ingress.kubernetes.io/ssl-redirect: 'false' #http通信 # name of the secret that contains the user/password definitions nginx.ingress.kubernetes.io/auth-secret: basic-auth #secret名称 # message to display with an appropriate context why the authentication is required nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required ' #输出提醒 # custom max body size for file uploading like backing image uploading nginx.ingress.kubernetes.io/proxy-body-size: 10000m nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: paths: - pathType: Prefix path: /longhorn(/|$)(.*) backend: service: name: longhorn-frontend port: number: 80[root@k8s-master Ingress]# kubectl apply -f longhorn-ui-ingress.yaml ingress.networking.k8s.io/longhorn-ingress configured
- 拜访 http://IP/longhorn/ #最初的 "/" 肯定要加
- 以下图片IP 重新部署后的服务IP