赞
踩
上一篇介绍了单独nginx部署和tomcat部署,然后nginx转向tomcat的部署方式。本文使用k8s的ingress来部署nginx指向tomcat。
ingress介绍
参考https://www.cnblogs.com/gaofeng-henu/p/12463697.html
Ingress是kubernetes中用来对集群外部进来的请求进行负载、路由控制的一种机制。通过ingress,可以方便的将集群内的service以http或https方式对外提供服务,而且不用将各个服务再单独暴露。Ingress功能由Ingress resource和Ingress Controllers共同协作完成。
Ingress resource
Ingress resource是kubernetes中的一种资源,是类似于pod、deployment的一种API对象,可以通过kubectl命令创建、销毁、更新,其对应的Kind是Ingress,可以在其spec属性中定义服务路由的规则信息。通常Ingress resource中定义的规则需要支持以下的特性:
基于内容路由
对每一个主机都可以单独设置TLS/SSL连接信息
Ingress Controllers
Ingress resource只是定义了路由的规则信息,真正利用这些信息对请求进行控制是通过Ingress Controllers来实现的。不像kube-controller-manager中的其他controller组件,它们是被作为集群的一部分随着集群直接安装好,Ingress controllers 需要我们自己来安装启动,并且kubernetes支持很多种实现来满足不同需求,具体参考Ingress Controllers。
在kubernetes中,Ingress Controller以pod形式运行,监控API Server的/ingress接口后端的backend services,如果service发生变化,Ingress Controller自动更新转发规则。如Nginx Ingress Controller的工作过程如下:
端口竞争
通常情况下,我们部署在kubernetes集群中的应用需要给外部访问,这时我们需要在kubernetes中定义NodePort、LoadBalancer等类型的Servcie来实现,具体参考Service。其中LoadBalancer需要在提供相应机制的云环境中才能使用,所以在自建的kubernetes集群中都是通过NodePort类型的Service来实现,就是将宿主机的port的Service的Port做个映射,通过访问宿主机的端口来对service进行访问。在kubernetes集群中只有一个应用,或者应用数量比较少,能够正确分配各个应用对应的宿主机端口时还可以应付。随着应用的追加,端口的映射就变的混乱起来,有的应用还会因为限制必须使用特定的端口号,而这些端口号可能前期已经分配给了别的应用,这时就出现了端口竞争
服务动态更新
为了避免端口竞争,可以在系统中部署反向代理服务(nginx、HAproxy)等,这时可以把对外的集群服务都通过反向代理服务来暴露,这样就带来了另一个问题,当有新的服务追加进来,或者旧的服务需要删除,这时还要重新编辑反向代理的配置文件,然后对反向代理服务进行升级。上线/下线一个应用却需要编辑另一个应用的配置文件,服务的升级、回滚等等都需要考虑,不仅麻烦还容易出错
1)下载启动文件mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
2)下载nginx-ingress-controller镜像
mandatory.yaml中指定的原始镜像是quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0,在国内可能没有办法下载,改成从阿里镜像仓库下载,并且push到自己的私有仓库harbor
docker pull registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.30.0
push到私有仓库harbor
- docker tag registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.30.0 10.38.150.64:8090/library/nginx-ingress-controller
-
- docker push 10.38.150.64:8090/library/nginx-ingress-controller:latest
3)修改mandatory.yaml中deployment的image地址
4)启动服务
kubectl apply -f mandatory.yaml
此时创建一个namespace:ingress-nginx, nginx-ingress-controller的服务也启动了,在集群内部
5)需要暴露nginx-ingress-controller,启动一个nodeport的service
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
可以修改下里面的http和https的对外端口,不指定的话集群会随机分配
- 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
- nodePort: 32080 #http对外端口
- - name: https
- port: 443
- targetPort: 443
- protocol: TCP
- nodePort: 32443 ##https对外端口
- selector:
- app.kubernetes.io/name: ingress-nginx
- app.kubernetes.io/part-of: ingress-nginx

6)启动service
7)前一篇文章我们已经创建了tomcat的名为idat2server的服务,这里我们可以创建一个ingress-resouce来指向这个服务
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: ingress-nginx
- namespace: default
- annotations:
- kubernetes.io/ingress.class: "nginx"
- spec:
- rules:
- - host: seagate.hadoop.idat #指定一个域名
- http:
- paths:
- - path: #此处可以指定跳转的url比如 /serviceA
- backend:
- serviceName: idat2server #之前启动的集群服务名称
- servicePort: 8099

8)启动ingress-resouce,并查看启动的ingress
9)因为在ingress指定了一个域名seagate.hadoop.idat,我们在访问这个域名时需要做一个映射,映射的地址是我们启动的ingress-nginx-controller的deployment的节点ip:k8node1.wux.chin.seagate.com/10.38.150.64
修改hosts文件C:\Windows\System32\drivers\etc\hosts,添加映射
10)接下来根据域名seagate.hadoop.idat和service暴露的外部nodeport端口32080访问网站
在完成ingress部署后,第10步访问主页并登录的时候,我这里出现问题,打开页面很慢,而且登录也很慢,打开调试界面会出现很多js,png,css一直在pending的情况,就是这些资源没有被快速的请求到。这个问题困扰很久,在查看了多篇文章后,总结可能是在请求后端tomcat的时候有些节点无法访问的问题。
于是进入ingress-nginx-controler里面去curl每个节点是否通畅
后端tomcat的三个节点
ingress-nginx-controller节点
执行命令进入ingress-nginx-controller
kubectl exec nginx-ingress-controller-864d6dbb5d-85q2n -ti -n ingress-nginx -- /bin/bash
根据内部ip去curl三个节点的url,可以看到第一个节点192.168.6.83是可以curl通的,但是另外两个节点无法curl通,问题原因是ingress-nginx-controller其实的启动在节点k8node1.wux.chin.seagate.com上的,与192.168.6.83的pod在同一个节点,在内部访问时通过local是可以访问到,但是其他两个pod是在另外两个节点上,直接curl无法curl通,说明还是网络的问题。
那么原因清楚了,就是在页面访问的时候,其实每个资源就是一个请求,每个请求又总是轮询的会在三个pod之间切换,当访问到节点1时正确返回资源,当访问到节点2,3时因为网络问题无法返回资源,就出现页面资源pengding或者超时的问题,导致页面加载很慢。那么如何修改呢?修改kube-proxy的网络模式ipvs模式,这个网络上也有文章可以参考,这里也简单描述下步骤
a)首先可以查看kube-proxy当前的模式,可以看到没有指定,所以使用的默认的iptables模式
b)首先添加ipvs模块,添加/etc/sysconfig/modules/ipvs.modules文件
vi /etc/sysconfig/modules/ipvs.modules
给与执行权限
chmod 755 /etc/sysconfig/modules/ipvs.modules
生效
bash /etc/sysconfig/modules/ipvs.modules
修改kube-proxy模式,mode项更改为ipvs,原来为空
kubectl edit cm kube-proxy -n kube-system
c)重置kube-proxy,并查看模式已经更改为ipvs
kubectl get pods -n kube-system |grep kube-proxy|awk '{print $1}'| xargs kubectl delete pod -n kube-system
d)重新去部署你的项目,测试下curl的页面,成功。并使用域名访问页面,访问慢的问题解决了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。