01Ingress介绍
Kubernetes暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress;本节主要介绍ingress。
ingress简单的说就是一个代理过程,可以根据配置转发请求到指定的服务上。

通俗来讲,ingress和之前提到的Service、Deployment,也是一个k8s的资源类型,ingress用于实现用域名的方式访问k8s内部应用。
Ingress为Kubernetes集群中的服务提供了入口,可以提供负载均衡、SSL终止和基于名称的虚拟主机,在生产环境中常用的Ingress有Treafik、Nginx、HAProxy、Istio等。
在Kubernetesv 1.1版中添加的Ingress用于从集群外部到集群内部Service的HTTP和HTTPS路由,流量从Internet到Ingress再到Services最后到Pod上,通常情况下,Ingress部署在所有的Node节点上。
Ingress可以配置提供服务外部访问的URL、负载均衡、终止SSL,并提供基于域名的虚拟主机。但Ingress不会暴露任意端口或协议。
由于K8S集群拥有强大的副本控制能力,Pod随时可能从一个节点上被驱逐到另一个节点上,或者直接销毁再来一个新的。
然而伴随着Pod的销毁和重生,Pod的IP等信息不断地在改变,此时使用K8S提供的Service机制可以解决这一问题,Service通过标签选定指定的Pod作为后端服务,并监听这些Pod的变化。
在对外暴露服务时,使用Service的NodePort是一个方法
问题1-如何管理端口
当需要对外暴露的服务量比较多的时候,端口管理的问题变会暴露出来。
此时的一个处理方案是使用一个代理服务(例如nginx)根据请求信息将请求转发到不同的服务器上。
问题2-如何管理转发配置
每当有新服务加入,都需要对该服务的配置进行修改、升级,在服务数量逐渐变多后,该配置项目会变得越来越大,手工修改的风险也会逐渐增高。
那么需要一个工具来简化这一过程,希望可以通过简单的配置动态生成代理中复杂的配置,最好还可以顺手重新加载配置文件。
K8S刚好也提供了此类型资源。

Ingress 工作原理
(1)ingress-controller通过和 kubernetes APIServer 交互,动态的去感知集群中ingress规则变化,
(2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置。
(3)再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中。
(4)然后reload一下使配置生效。以此达到域名区分配置和动态更新的作用。
在使用普通的Service时,集群中每个节点的kube-proxy在监听到Service和Endpoints的变化时,会动态的修改相关的iptables的转发规则。客户端在访问时通过iptables设置的规则进行路由转发达到访问服务的目的。
而Ingress则跳过了kube-proxy这一层,通过Ingress Controller中的代理配置进行路由转发达到访问目标服务的目的。实际上可以把IngressController看做一个拥有默认处理后端的代理,根据Ingress资源的配置动态修改代理的配置文件,以实现按照规则转发请求的功能。
02Ingress环境准备
下面ingress-nginx为类来部署ingress-controller,具体的部署步骤如下:
#创建一个目录,目录名可以随便起,这里命令为ingress-controller[root@master ~]# mkdir ingress-controller#下载mandatory.yaml和service-nodeport.yaml两个文件#这里下载了现成的,所以就直接拷贝进去即可#拷贝进去后,需要注意的是修改mandatory.yaml文件的镜像路径,具体如下:#将原来的内容修改为以下内容,这个是国内的镜像地址image: shichao01/nginx-ingress-controller:0.30.0#再运行以下命令进行部署[root@master ingress-controller]# kubectl apply -f ./#部署完成后可以查看部署的结果[root@master ingress-controller]# kubectl get pod -n ingress-nginxNAME READY STATUS RESTARTS AGEnginx-ingress-controller-75bd94bd9d-lhn2g 1/1 Running 0 131m#再使用以下命令来查看ingress-nginx暴露的端口[root@master ingress-controller]# kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)AGEingress-nginx NodePort 10.96.163.204 <none>80:30223/TCP,443:32552/TCP 132m
下面构建一个deployment和一个service的清单,内容如下:
apiVersion: apps/v1kind: Deploymentmetadata:name: ingress-nginxnamespace: test-ingressspec:strategy:type: Recreatereplicas: 3selector:matchLabels:app: ingress-nginxtemplate:metadata:labels:app: ingress-nginxspec:containers:- name: ingress-nginximage: nginxports:- containerPort: 80---apiVersion: v1kind: Servicemetadata:name: web-nginxnamespace: test-ingressspec:selector:app: ingress-nginxports:- protocol: TCPport: 80targetPort: 80type: NodePort
再执行下面的命令进行部署
[root@master ~]# kubectl apply -f ingress-nginx-test.yaml
03HTTP代理
实现请求暴露到http端口下,先需要配置ingress的规则,配置文件内容如下:
# ingress规则中,要指定需要绑定暴露的svc名称apiVersion: extensions/v1beta1kind: Ingressmetadata:name: ingress-httpnamespace: test-ingressspec:rules: #定义路由规则- host: nginx.chuansinfo.com # 主机名,只能是域名,修改为项目域名,但如果主机无法解析到这个HOST,就会跳转到nginx主页,这样就会报404的错误,如果当报404错误时,就可以将这个选项设置为空http:paths:- path: /backend:serviceName: web-nginx # 后台部署的 Service NameservicePort: 80 # 后台部署的 Service Port
使用以下命令来部署ingress-http.yaml文件
[root@master ~]# kubectl apply -f ingress-http.yaml
使用以下命令来查看刚创建的ingress-http
[root@master ~]# kubectl get ing ingress-http -n test-ingressWarning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable inv1.22+; use networking.k8s.io/v1 IngressNAME CLASS HOSTS ADDRESS PORTS AGEingress-http <none> nginx.chuansinfo.com 10.96.149.201 80 3m15s
使用下面命令可以看到详细情况
[root@master ~]# kubectl describe ing ingress-http -n test-ingressWarning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable inv1.22+; use networking.k8s.io/v1 IngressName: ingress-httpNamespace: ingress-nginxAddress: 10.96.149.201Default backend: default-http-backend:80 (<error: endpoints "default-httpbackend"not found>)Rules:Host Path Backends---- ---- --------nginx.chuansinfo.com/ web-nginx:8010.244.104.12:80,10.244.166.142:80,10.244.166.143:80)Annotations: <none>Events:Type Reason Age From Message---- ------ ---- ---- -------Normal CREATE 5m4s nginx-ingress-controller Ingress ingress-nginx/ingresshttpNormal UPDATE 4m42s nginx-ingress-controller Ingress ingress-nginx/ingresshttp
再输入http://192.168.158.100:32451进行访问即可,192.168.158.100是master节点的IP地址.
04HTTPS代理
1.生成自签名证书
[root@master ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj"/CN=tomcat.test.com/ST=Chuansinfo/L=Chuansinfo/O=devops/OU=unicorn"-req是证书请求的子命令-newkey rsa:2048 -keyout tls.key -newkey是与-key互斥的-newkey是指在生成证书请求或者自签名证书的时候自动生成密钥,-nodes 表示私钥不加密-out 指定生成的证书请求或者自签名证书名称-days 365 证书有效期若执行自动输入,可使用-subj选项:-subj------证书相关的用户信息(subject的缩写)[root@master ~]# lsalways.yaml ingress-http.yaml never.yamlquota-mem-cpu-pod.yamlanaconda-ks.cfg ingress-nginx-test.yaml nginx-tomcat.yamlquota-mem-cpu.yamlcalico.yaml ingress-tomcat-test.yaml onfailure.yamlquota-pod.yamlcpu-defaults-pod2.yaml memory-constraints-pod-2.yaml pod-hook-exec.yamlservice-clusterip.yamlcpu-defaults-pod3.yaml memory-constraints-pod-3.yaml pod-nodeaffinitypreferred.yaml service-nodeport.yamlcpu-defaults-pod.yaml memory-constraints-pod-4.yaml pod-nodeaffinityrequired.yaml service.yamlcpu-default.yaml memory-constraints-pod.yaml pod-nodename.yamltest-deployment.yamldashboard.yaml memory-constraints.yaml pod-nodeselector.yamltest.txtdeployment-rolling.yaml memory-defaults-pod-2.yaml pod-podaffinityrequired.yaml tls.crtdeployment.yaml memory-defaults-pod-3.yaml pod-podaffinitytarget.yaml tls.key
2.将证书导入k8s的secret中,这里要指定namespace,否则ingress controller找不到证书
[root@master ~]# kubectl create secret tls tls-secret --key=tls.key --certtls.crt -n devsecret/tls-secret created
创建成功后可以使用下面的命令查看secret的相关信息
[root@master ~]# kubectl describe secret tls-secret
3、再创建个ingress资源文件指定使用https,文件名为tomcat-ingress.yaml
主要就是添加了tls相关,域名还是不变的以及一个注解,并且引用了前面打入的证书
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-httpsnamespace: devannotations:nginx.ingress.kubernetes.io/rewrite-target: /spec:ingressClassName: nginxrules:- host:http:paths:- path: /pathType: Prefixbackend:service:name: tomcat-serviceport:number: 8080tls:- hosts:- tomcat.test.comsecretName: tls-secret
输入https://tomcat.test.com:30725进行访问
需要注意的是端口要换成443对应的30725端口
至此,有关K8S的知识就分享到这里,希望大家能把这些技术掌握好,在工作上会有很大的帮助和提升,落了之前的内容可以查阅往期文章,需要同步电子资料或者技术支持可以文末加微。