51、K8S-流量调度-Ingress、Ingress-nginx、Dashboard
1、Ingress基础
1.1、简介
在实际的应用中,kubenetes接受的不仅仅有内部的流量,还有外部流量,我们可以通过两种方式实现将集群外部的流量引入到集群的内部中来,从而实现外部客户的正常访问。
service方式:
nodePort、externalIP 等service对象方式,借助于 namespace、iptables、ipvs 等代理模式实现流量的转发。
Host方式:
通过node节点的 hostNetwork 与 hostPort 及配套的port映射,以间接的方式实现service的效果
1.2、k8s网络流程图
1.3、关于网络流向的问题
1、在实际的应用中,虽然我们可以基于service或host等多种方式实现集群内外的网络通信,但是这些 内容都是基于四层协议来进行调度的,而且服务级别的健康检查功能很难实现。
2、而对于外部流量的接入,一般都是http(s)协议的数据,四层协议是无法实现的。尤其是涉及到各种 ssl会话的管理,由于其位于osi七层模型的会话层,要高于传输层的四层,service和host是无法正常实现的。
3、虽然service能够实现将外部流量引入到集群内部,但是其本质上,是通过网络规则方式来进行转发 的,形象的说法就是在墙上打洞,将集群内部的服务暴露到外部。甚至这些洞和洞之间根本没有关联关系。
1.4、解决方案
为了解决上述的问题,就引入了一种新的解决方法ingress,简单来说,它可以解决上面提出的三个问题: 1、可以基于https的方式,将集群外部的流量统一的引入到集群内部 2、通过一个统一的流量入口,避免将集群内部大量的"洞"暴露给外部。 Ingress这种利用应用层协议来进行流量的负载均衡效果,它可以实现让用户通过域名来访问相应的service就可以了,无需关心Node IP及Port是什么,避免了信息的泄露。
1.5、什么是Ingress
Ingress 是k8s上的一种标准化资源格式,它为了剥离与特定负载均衡功能实现软件的相关性,而抽象 出来的一种公共的统一的声明式配置格式。然后借助于特定的ingress controller功能负责将其加载并转换成k8s集群内部的配置信息。
Ingress的特点符合我们之前对于CRD的学习 - ingress + controller,所以,其具备了动态更新 并加载新配置的特性。而且ingress本身是不具备实现集群内外流量通信的功能的,这个功能是通过controller来实现的。
1.6、为什么需要Ingress
Service是基于四层TCP和UDP协议转发的,而Ingress可以基于七层的HTTP和HTTPS协议转发,可以通过域名和路径做到更细粒度的划分
1.7、ingress框架图
2、Ingress原理解析
2.1、Ingress组成
Ingress由任何具有反向代理功能的程序实现,如Nginx、Traefik、Envoy、HAProxy、Vulcand等,Ingress本身是运行于集群中的Pod资源对象。
ingress 主要包含两个组件Ingress Controller和Ingress。
2.2、Ingress组件
2.2.1、Ingress
将Nginx的配置抽象成一个Ingress对象,每个服务对应一个ingress的yaml配置文件
2.2.2、Ingress Controller
将新加入的Ingress转化成Nginx的配置文件并使之生效
2.3、问题梳理
如果我们将ingress以pod的方式部署到k8s集群内部,那么就会遇到多个问题: 1、ingress的pod如何引入外部流量 - 通过一个专用的service就可以实现了
2、ingress的pod如何把流量负载均衡到其他pod - 关于pod负载均衡的流量,直接通过controller转发给后端pod即可。
3、后端应用的pod很多,如何知道谁是我们要转发的目标? - 通过k8s的server对所有的pod进行分组管理,借助于controller内部的负载均衡配置,找到对应的目标。
2.4、Ingress原理解析
2.4.1、Ingress流程说明
Ingress是授权入站连接到达集群服务的规则集合。 从外部流量调度到nodeport上的service 从service调度到ingress-controller ingress-controller根据ingress[Pod]中的定义(虚拟主机或者后端的url) 根据虚拟主机名直接调度到后端的一组应用pod中
2.4.2、Ingress流程图
外部请求首先到达Ingress Controller,Ingress Controller根据Ingress的路由规则,查找到对应的Service,
进而通过Endpoint查询到Pod的IP地址,然后将请求转发给Pod。
2.5、Ingress-常见的解决方案
对于ingress controller的软件实现,其实没有特殊的要求,只要能够实现七层的负载均衡功能效果即可,各种组织对于ingress的controller虽然实现方式不同, 但是功能基本上一样,常见的实现方式有: Ingress-Nginx: Kong HAProxy:性能相对于nginx来说,较稳定。 Envoy: 基于C++语言开发,本身就为动态环境设计的,支持配置动态加载的XDS API不能像ingress-nginx一样,直接加载配置文件并动态加载转换成对应的应用配置,所以需要借助于其他控制平面工具来实现。 常见解决方案:Contour, Gloo、Traefik 注意:ingress 自从 1.6版本引入后,在1.19 正式进入了一个稳定版本状态。
3、Ingress-Nginx
3.1、Ingress-属性解析
apiVersion: networking.k8s.io/v1 # 资源所属的API群组和版本 kind: Ingress # 资源类型标识符 metadata: # 元数据 name <string> # 资源名称 annotations: # 资源注解,v1beta1使用下面的注解来指定要解析该资源的控制器类型 kubernetes.io/ingress.class: <string> # 适配的Ingress控制器类别,便于多ingress组件场景下,挑选针对的类型 namespace <string> # 名称空间 spec: rules <[]Object> # Ingress规则列表,也就是http转发时候用到的url关键字 - 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 <object> # 后端Service上的端口对象 name <string> # 端口名称 number <integer> # 端口号 tls <[]Object> # TLS配置,用于指定上rules中定义的哪些host需要工作HTTPS模式 - hosts <[]string> # 使用同一组证书的主机名称列表 secretName <string> # 保存于数字证书和私钥信息的secret资源名称,用于主机认证 backend <Object> # 默认backend的定义,可嵌套字段及使用格式跟rules字段中的相同 ingressClassName <string> # ingress类名称,用于指定适配的控制器,类似于注解的功能
3.2、Ingress-nginx布署
3.2.1、官方参考文档
参考资料:https://github.com/kubernetes/ingress-nginx 安装文档:https://kubernetes.github.io/ingress-nginx/deploy/
3.2.2、下载软件
当前版本:ingress-nginx-controller-v1.7.0.tar.gz 地址:https://github.com/kubernetes/ingress-nginx/releases/tag/controller-v1.7.0
3.2.3、获取安装的yaml
# 获取安装的yaml文件 压缩文件位置:ingress-nginx-controller-v1.7.0.tar.gz\ingress-nginx-controller-v1.7.0\deploy\static\provider\baremetal\deploy.yaml
3.2.4、提前准备镜像
# 准备离线镜像,加快安装速度 master1 ingress-nginx]# grep 'image' deploy.yaml | grep -iv 'pull' | uniq image: registry.k8s.io/ingress-nginx/controller:v1.7.0@sha256:7612338342a1e7b8090bef78f2a04fffcadd548ccaabe8a47bf7758ff549a5f7 image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f # 如果有外网代理的话,可以使用docker代理下载 参考文章:https://www.cnblogs.com/ygbh/p/17295746.html # 下载好的镜像上传至私有仓库 docker tag 0d4c0564c465 192.168.10.33:80/k8s/ingress-nginx/controller:v1.7.0 docker push 192.168.10.33:80/k8s/ingress-nginx/controller:v1.7.0 docker tag 5a86b03a88d2 192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0 docker push 192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0
3.2.5、修改deploy.yaml【修改下载镜像的地址】
sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f#192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0#'g deploy.yaml sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f#192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0#'g deploy.yaml master1 ~]# grep 'image' ingress-nginx/deploy.yaml | grep -iv 'pull' | uniq image: 192.168.10.33:80/k8s/ingress-nginx/controller:v1.7.0 image: 192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0
3.2.6、修改deploy.yaml【增加一个外网访问的入口ip】
apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.7.0 name: ingress-nginx-controller namespace: ingress-nginx spec: ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - appProtocol: http name: http port: 80 protocol: TCP targetPort: http - appProtocol: https name: https port: 443 protocol: TCP targetPort: https selector: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx type: NodePort externalIPs: ['192.168.10.222'] # 增加此行,这个IP地址不是一个物理IP地址,虚拟IP来的
注意:如果需要被宿主机访问到的话,就要在主机上增加多一个虚拟网口,并且IP地址与externalIPs保持一致。创建方法如下:
ifconfig ens33:1 192.168.10.222 netmask 255.255.255.0
3.2.7、应用资源配置清单
master1 ~]# kubectl apply -f ingress-nginx/deploy.yaml namespace/ingress-nginx created serviceaccount/ingress-nginx created serviceaccount/ingress-nginx-admission created role.rbac.authorization.k8s.io/ingress-nginx created role.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrole.rbac.authorization.k8s.io/ingress-nginx created clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created rolebinding.rbac.authorization.k8s.io/ingress-nginx created rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created configmap/ingress-nginx-controller created service/ingress-nginx-controller created service/ingress-nginx-controller-admission created deployment.apps/ingress-nginx-controller created job.batch/ingress-nginx-admission-create created job.batch/ingress-nginx-admission-patch created ingressclass.networking.k8s.io/nginx created validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
3.2.8、查看运行状态
# Pod master1 ~]# kubectl -n ingress-nginx get pods NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-zcm9b 0/1 Completed 0 7m39s ingress-nginx-admission-patch-jtlj5 0/1 Completed 1 7m39s ingress-nginx-controller-89c678f9f-j59ll 1/1 Running 0 7m39s # SVC master1 ~]# kubectl -n ingress-nginx get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.111.40.152 192.168.10.222 80:30565/TCP,443:30073/TCP 8m47s ingress-nginx-controller-admission ClusterIP 10.97.213.211 <none> 443/TCP 8m47s # Job master1 ~]# kubectl -n ingress-nginx get job NAME COMPLETIONS DURATION AGE ingress-nginx-admission-create 1/1 4s 8m51s ingress-nginx-admission-patch 1/1 6s 8m51s
3.2.9、测试访问svc
master1 ~]# curl 192.168.10.222 <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html> master1 ~]# curl -I -o /dev/null -s -w %{http_code}"\n" 192.168.10.222 404
3.2.10、安装成功
目前为止已经安装成功
4、Ingress-nginx-入门实践
4.1、创建deployment、svc资源
4.1.1、定义资源配置清单且应用
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: deployment-test spec: replicas: 4 selector: matchLabels: app: pod-test template: metadata: labels: app: pod-test spec: containers: - name: pod-test image: 192.168.10.33:80/k8s/pod_test:v0.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: http --- apiVersion: v1 kind: Service metadata: name: deployment-service spec: selector: app: pod-test ports: - name: http port: 80 targetPort: 80 EOF
4.1.2、查询资源运行状态
master1 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE deployment-test-d6756dd79-7njmq 1/1 Running 0 61s deployment-test-d6756dd79-ds84h 1/1 Running 0 61s deployment-test-d6756dd79-f5k6j 1/1 Running 0 61s deployment-test-d6756dd79-kmqv8 1/1 Running 0 61s master1 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE deployment-service ClusterIP 10.99.121.115 <none> 80/TCP 63s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d14h master1 ~]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE deployment-test 4/4 4 4 114s
4.2、创建ingress-nginx资源
4.2.1、定义资源配置清单且应用
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: cyc.example.com http: paths: - path: / pathType: Prefix backend: service: name: deployment-service port: number: 80 EOF 属性解析: 1、annotations注释,ingress实现类为nginx 2、对于ingress来说,最终要的就是rules了,hosts是一个自定义的域名,backend指向svc name
4.2.2、查询资源运行状态
master1 ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test <none> cyc.example.com 192.168.10.29 80 63s master1 ~]# kubectl describe ingress ingress-test Name: ingress-test Labels: <none> Namespace: default Address: 192.168.10.29 Ingress Class: <none> Default backend: <default> Rules: Host Path Backends ---- ---- -------- cyc.example.com / deployment-service:80 (10.244.3.81:80,10.244.3.82:80,10.244.4.114:80 + 1 more...) Annotations: kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 54s (x2 over 95s) nginx-ingress-controller Scheduled for sync ingress将后端的deployment-service:80 的样式自动与 ingress 的 url(/) 关联在一起了
4.3、访问测试
4.3.1、配置hosts
echo '192.168.10.222 cyc.example.com' >> /etc/hosts
4.3.2、访问配置的域名
master1 ~]# curl cyc.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-f5k6j, ServerIP: 10.244.3.82! master1 ~]# curl cyc.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-7njmq, ServerIP: 10.244.3.81! master1 ~]# curl cyc.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-ds84h, ServerIP: 10.244.4.115! master1 ~]# curl cyc.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-kmqv8, ServerIP: 10.244.4.114!
# 通过自定义携带域名的方式可以正常访问。
4.4.、原理解析
master1 ~]# kubectl -n ingress-nginx exec -it ingress-nginx-controller-89c678f9f-xlstd -- /bin/bash -c 'grep cyc nginx.conf' ## start server cyc.example.com server_name cyc.example.com ; ## end server cyc.example.com nginx配置文件,定义好域名信息作为信息的入口。
5、Ingress-nginx-多域名、多URL访问-实践
5.1、需求
nginx controller的功能远不止我们所说的主机域名的管理,在实际的工作需求中,肯定会遇到,不同的功能服务以子路径的方式来进行访问,以及与https相关的访问。
5.2、准备pod和svc资源
5.2.1、创建nginx pod和svc资源
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: deployment-nginx spec: replicas: 4 selector: matchLabels: app: nginx-test template: metadata: labels: app: nginx-test spec: containers: - name: nginx-test image: 192.168.10.33:80/k8s/my_nginx:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: nginx --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx-test ports: - name: nginx port: 80 targetPort: 80 EOF 注意:这里面有两个主机访问的地址是同一个后端端口,如果还用number的话,就无法正常的识别导致同一个地址访问不同的后端效果。
5.2.2、创建flask pod和svc资源
上一小节已经创建过的,可以忽略。 如果没有创建请看小节:4.1.1、定义资源配置清单且应用
5.2.3、查询资源创建情况
master1 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE deployment-nginx-5c4b6689f6-6dfkn 1/1 Running 0 105s deployment-nginx-5c4b6689f6-74k2w 1/1 Running 0 105s deployment-nginx-5c4b6689f6-jmzjw 1/1 Running 0 105s deployment-nginx-5c4b6689f6-rprfp 1/1 Running 0 105s deployment-test-d6756dd79-7njmq 1/1 Running 0 40m deployment-test-d6756dd79-ds84h 1/1 Running 0 40m deployment-test-d6756dd79-f5k6j 1/1 Running 0 40m deployment-test-d6756dd79-kmqv8 1/1 Running 0 40m
5.2、不同主机域名访问-实践
5.2.1、需求
访问 flask.example.com/的时候,返回flask的结果
访问 nginx.example.com/的时候,返回nginx的结果
5.2.2、创建ingress-nginx资源
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-mul-url annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: flask.example.com http: paths: - path: / pathType: Prefix backend: service: name: deployment-service port: name: http #number: 80 - host: nginx.example.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-service port: name: nginx EOF 配置解析: 这里面有两个主机访问的地址是同一个后端端口,如果还用number的话,就无法正常的识别导致同一个 地址访问不同的后端效果
5.2.3、查询资源运行状态
master1 ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-mul-url <none> flask.example.com,nginx.example.com 80 4s ingress-test <none> cyc.example.com 192.168.10.29 80 35m master1 ~]# kubectl describe ingress ingress-mul-url Name: ingress-mul-url Labels: <none> Namespace: default Address: 192.168.10.29 Ingress Class: <none> Default backend: <default> Rules: Host Path Backends ---- ---- -------- flask.example.com / deployment-service:http (10.244.3.81:80,10.244.3.82:80,10.244.4.114:80 + 1 more...) nginx.example.com / nginx-service:nginx (10.244.3.83:80,10.244.3.84:80,10.244.4.116:80 + 1 more...) Annotations: kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 117s (x2 over 2m37s) nginx-ingress-controller Scheduled for sync
5.2.4、配置hosts
echo '192.168.10.222 flask.example.com nginx.example.com' >> /etc/hosts
5.2.5、访问测试
master1 ~]# curl nginx.example.com nginx v1版本
master1 ~]# curl flask.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-f5k6j, ServerIP: 10.244.3.82!
5.3、单域名多URL访问-实践
5.3.1、需求
访问 www.example.com/flask的时候,返回flask的结果 访问 www.example.com/nginx的时候,返回nginx的结果 注意事项: 由于这里涉及到了域名的url转发,而后端服务有可能不存在,我们需要在后端url转发的时候,取消转发关键字。 解决方法:在annotation中添加一个重写的规则nginx.ingress.kubernetes.io/rewrite-target: /(即所有的请求,把ingress匹配到的url关键字清除掉)
5.3.2、创建ingress-nginx资源
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-mul-url annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.example.com http: paths: - path: /flask pathType: Prefix backend: service: name: deployment-service port: name: http #number: 80 - path: /nginx pathType: Prefix backend: service: name: nginx-service port: name: nginx #number: 80 EOF
5.3.3、查询资源运行状态
master1 ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-mul-url <none> www.example.com 192.168.10.29 80 9m27s ingress-test <none> cyc.example.com 192.168.10.29 80 44m master1 ~]# kubectl describe ingress ingress-mul-url Name: ingress-mul-url Labels: <none> Namespace: default Address: 192.168.10.29 Ingress Class: <none> Default backend: <default> Rules: Host Path Backends ---- ---- -------- www.example.com /flask deployment-service:http (10.244.3.81:80,10.244.3.82:80,10.244.4.114:80 + 1 more...) /nginx nginx-service:nginx (10.244.3.83:80,10.244.3.84:80,10.244.4.116:80 + 1 more...) Annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: / Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 20s (x3 over 9m44s) nginx-ingress-controller Scheduled for sync
5.3.4、配置hosts
echo "192.168.10.222 www.example.com" >>/etc/hosts
5.3.5、访问测试
master1 ~]# curl www.example.com/nginx nginx v1版本
master1 ~]# curl www.example.com/flask kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-f5k6j, ServerIP: 10.244.3.82!
6、Ingress-nginx-https-实践
6.1、需求
我们准备对基础的flask应用进行https方式来进行访问。
方法:Ingress的tls规则就可以帮助我们实现对http应用进行https升级
6.2、准备CA证书
6.2.1、创建CA证书
mkdir tls && cd tls (umask 077;openssl genrsa -out tls.key 2048) openssl req -new -x509 -key tls.key -out tls.crt -subj '/CN=www.example.com' -days 10000
6.2.2、将证书导入secret配置资源
kubectl create secret tls ingress-tls --cert=./tls.crt --key=./tls.key [root@master1 tls]# kubectl get secrets NAME TYPE DATA AGE ingress-tls kubernetes.io/tls 2 11s
6.3、创建ingress-nginx资源
6.3.1、定义资源配置清单并且应用
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-test annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: www.example.com http: paths: - path: / pathType: Prefix backend: service: name: deployment-service port: number: 80 tls: - hosts: - www.example.com secretName: ingress-tls EOF
6.3.2、查询资源运行状态
master1 ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-test <none> www.example.com 192.168.10.29 80, 443 60m
6.3.3、配置hosts
echo "192.168.10.222 www.example.com" >>/etc/hosts # 如果配置过,就忽略
6.3.4、访问测试
master1 ~]# curl -k https://www.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-kmqv8, ServerIP: 10.244.4.114! master1 ~]# curl www.example.com <html> <head><title>308 Permanent Redirect</title></head> <body> <center><h1>308 Permanent Redirect</h1></center> <hr><center>nginx</center> </body> </html>
7、Dashboard、Ingress-nginx-实践
7.1、需求
7.1.1、问题点
我们知道,对于k8s的dashboard来说,它所实现的功能还是比较多的,而且原则上要求必须是https方式来 进行访问。我们之前是通过service的方式实现正常的请求访问。有了ingress,我们也可以自由的访问 dashboard了。比如我们访问k8s的dashboard的首页地址是 https://10.0.0.12:30443/#/login
7.1.2、解决dashboard的方法
除了我们之前所说的动态url的方式之外,就需要tls认证了。关于对集群内部的ingress的tls访问方式,可以借助于ingress controller的annotation的方式向nginx中传递一些属性,从而上nginx支持相应的功能。 这与我们上一节的方式有所不同通过两个annotation中的规则 ingress.kubernetes.io/ssl-passthrough: "true" - 以为后面的dashboard本身就做了tls功能,所以这里进行tls代理即可 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" - 对后端直接启动https协议访问即可。 参考资料:https://kubernetes.github.io/ingress-nginx/user-guide/nginxconfiguration/annotations/
7.2、创建Ingress资源
7.2.1、定义资源配置清单且应用
echo ' apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-dashboard namespace: kubernetes-dashboard annotations: ingress.kubernetes.io/ssl-passthrough: "true" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx rules: - host: dashboard.example.com http: paths: - path: /dashboard(/|$)(.*) pathType: Prefix backend: service: name: kubernetes-dashboard port: number: 443 ' | kubectl apply -f -
7.2.2、查询资源运行状态
master1 ~]# kubectl get ingress -n kubernetes-dashboard NAME CLASS HOSTS ADDRESS PORTS AGE ingress-dashboard nginx dashboard.example.com 192.168.10.29 80 41m master1 ~]# kubectl get ingress -n kubernetes-dashboard [root@master1 ~]# kubectl describe ingress -n kubernetes-dashboard ingress-dashboard Name: ingress-dashboard Labels: <none> Namespace: kubernetes-dashboard Address: 192.168.10.29 Ingress Class: nginx Default backend: <default> Rules: Host Path Backends ---- ---- -------- dashboard.example.com /dashboard(/|$)(.*) kubernetes-dashboard:443 (10.244.4.118:8443) Annotations: ingress.kubernetes.io/ssl-passthrough: true nginx.ingress.kubernetes.io/backend-protocol: HTTPS nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/use-regex: true Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 43s (x17 over 41m) nginx-ingress-controller Scheduled for sync
7.2.3、配置hosts
192.168.10.222 dashboard.example.com
# 这里的IP地址,是我们配置externalIP地址
7.2.4、访问测试
https://dashboard.example.com/dashboard/#/login
8、Ingress-nginx之hostNetwork-实践
8.1、什么时候用到?【不建议生产使用这种模式】
hostNetwork <boolean> Host networking requested for this pod. Use the host's network namespace. # 大概的意思:使用主机的网络访问Pod 1、只有一个node节点的时候,就可以使用这种模式。【不建议生产使用这种模式】 2、如果生产需要使用这种模式,需要单独部署nginx做反向代理至每台主的pod开放的端口, 但是如果pod挂掉,单独部署nginx就无法自动踢除故障服务了。
8.2、配置hostNetwork
8.2.1、配置hostNetwork: true
~]# vi ingress-nginx/deploy.yaml spec: minReadySeconds: 0 revisionHistoryLimit: 10 selector: matchLabels: ... template: metadata: ... spec: hostNetwork: true containers: - args: - /nginx-ingress-controller - --election-id=ingress-nginx-leader - --controller-class=k8s.io/ingress-nginx - --ingress-class=nginx - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller - --validating-webhook=:8443 - --validating-webhook-certificate=/usr/local/certificates/cert - --validating-webhook-key=/usr/local/certificates/key
8.2.2、配置svc【主要修改为NodePort和externalIPS】
~]# vi ingress-nginx/deploy.yaml apiVersion: v1 kind: Service metadata: labels: ... name: ingress-nginx-controller namespace: ingress-nginx spec: ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - appProtocol: http name: http port: 80 protocol: TCP targetPort: http - appProtocol: https name: https port: 443 protocol: TCP targetPort: https selector: ... type: NodePort externalIPs: ['192.168.10.222']
8.3、应用资源配置清单
~]# kubectl apply -f ingress-nginx/deploy.yaml
8.4、查询相关的运行状态
8.4.1、查询svc
~]# kubectl -n ingress-nginx get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.101.51.125 192.168.10.222 80:32690/TCP,443:32170/TCP 18m ingress-nginx-controller-admission ClusterIP 10.103.241.48 <none> 443/TCP 18m
8.4.2、查询node节点信息
~]# kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME master1 Ready control-plane 19h v1.25.7 192.168.10.26 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 containerd://1.6.18 node1 Ready <none> 19h v1.25.7 192.168.10.29 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 containerd://1.6.18 node2 Ready <none> 19h v1.25.7 192.168.10.30 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 containerd://1.6.18
8.4.3、查询pod运行状态
~]# kubectl get pods -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ingress-nginx-admission-create-75txr 0/1 Completed 0 23m 10.244.1.22 node1 <none> <none> ingress-nginx-admission-patch-4v47j 0/1 Completed 1 23m 10.244.1.23 node1 <none> <none> ingress-nginx-controller-67958f98cd-58dk4 1/1 Running 0 23m 192.168.10.30 node2 <none> <none>
8.4、测试访问
8.4.1、增加externalIP
# 主要作用是nginx-controller布署在哪个节点,哪个节点才会开放出NodePort端口出来,所以增加多一个外部IP方便访问
ifconfig ens33:1 192.168.10.222/24
8.4.2、访问externalIP地址
~]# curl -I -o /dev/null -s -w %{http_code}"\n" 192.168.10.222 404
8.4.3、访问node1节点
~]# curl -I -o /dev/null -s -w %{http_code}"\n" 192.168.10.30 404
8.4.4、小结
说明已经部署成功了