用户在使用阿里云容器服务kubernetes的时候经常遇到需要访问部署在容器服务平台上的应用的场景。无论是在kubernetes集群内部访问应用,还是通过外部进行应用的访问,用户都会遇到些问题,本文主要是对用户在访问kubernetes平台上的应用时遇到的普遍问题进行解决方案的总结。
基础内容普及
应用对外暴露访问的方式
前提:
应用部署类型选择deployment;然后为该deployment创建service;
方式一 创建service
service有三种类型,ClusterIP,NodePort和LoadBalancer类型;对应阿里云上分别为虚拟集群IP,节点端口和负载均衡;在容器服务控制台创建服务的时候可以进行类型的选择。具体创建service可以参考阿里云文档创建服务。
方式二 创建路由
在创建了service的基础上,在阿里云上可以利用路由功能绑定service,通过域名的方式进行内部应用的暴露。
域名可以使用容器服务平台自带的域名, 容器服务平台负责解析;也可以使用用户自己的域名,但是该域名需要用户自行解析,比如通过用户自己的DNS。
具体创建路由可以参考阿里云文档通过web界面创建路由。
区别
方式一:
1、对外部应用暴露service最终还是通过IP:port的方式对容器服务平台内部应用进行访问;
2、对集群内部的应用来说,可以通过service名称来进行服务的访问。
方式二:通过域名的方式进行服务的暴露。
场景一 通过NodePort类型的service进行服务的访问
写在前面:
不建议用在生产环境,以下两种方案的宗旨在于深入理解该类型以及与其他相关云产品的关联。
原理:
NodePort类型的service顾名思义就是kubernetes在创建这样类型的service的时候会在集群中的每一个节点(master和worker)上开通一个port,任何转发到任一节点上该端口的请求都会被转发到对应的服务上,最后转发到服务所对应的应用上。
注:NodePort端口默认范围为30000-32767。
方案一 利用master节点
阿里云kubernetes集群master节点通过SLB进行了访问连接,以便于用户登录集群进行操作。借助该SLB并结合NodePort类型的service,我们可以将SLB_IP:nodeport的方式进行服务的对外暴露。
优点:
可以快速的通过SLB访问到应用。
缺点:
由于使用到了master节点的SLB,所以会增大master节点的流量负担,适用于临时测试。
方案二 利用worker节点
由于worker节点当前没有对外暴露,所以需要通过SLB将worker节点暴露出去。
第一步,首先我们需要手动创建一个SLB实例;
第二步,将集群中的worker节点挂在该SLB实例下面;也可以挂一部分,但是要保证这些node节点不会被删除掉。
第三步,通过访问SLB_IP:nodeport的方式进行服务的对外暴露;
优点:
SLB的流量仅通过worker节点,不会影响master节点;
缺点:
1、需要用户自己配置SLB并且没开通一个端口都需要开通。
2、需要注意不要删除掉挂载在SLB下的worker节点。
注:
场景二 通过LoadBalancer类型的service进行服务的访问
前提
在创建service的时候选择负载均衡->公网访问的类型。(如果本地环境能跟线上VPC打通的话,也可以选择负载均衡->内网访问的类型)。
方案及原理
在阿里云容器服务kubernetes上创建LoadBalancer类型的service会做两件事情:
首先,为应用创建一个NodePort(通NodePort类型的service);
其次,自动创建阿里云SLB服务;
最后,自动设置SLB前端监听端口和后端监听端口;前端监听端口为服务端口,后端监听端口为NodePort的端口。
通过上面的操作,服务就通过SLB暴露出去了。访问应用时只需要访问SLB_IP:service_port就可以了。
优点:
暴露服务简洁明了,自动化配置SLB,通过SLB IP:service_port即可访问应用。
缺点:
每个服务都独占一个SLB,如果需要暴露的服务量太大的话,会占用较多的SLB资源。
场景三 通过域名进行服务的访问
原理
阿里云容器服务提供路由功能,可使用默认域名和自定义域名,路由具体原理为kubernetes中的ingress(nginx),通过将service对应的IP地址刷新到nginx的upstream并配置相应的域名即可实现基于域名的应用访问。
方案
阿里云容器服务kubernetes上创建路由,填入使用默认后缀域名或者自定义域名(自定义域名需要用户解析),选择绑定的服务后点击创建即可完成了路由的创建。在路由界面选取域名进行应用的访问。同时可以通过设置访问PATH来区分访问到的服务。
多个路由后端设置
在kubernetes上使用路由功能创建出的路由,不论在哪个namespace下面都是显示的同一个端点IP,这是因为在路由对应的ingress前端只有一个SLB,该端点IP即为该SLB的IP地址。
如上图所示,如果需要多个路由后端,需要用户做两件事情:
1、 在kube-system为nginx-ingress-controller创建多个LB类型的service;此时会有多个service对应nginx-ingress-controller这个deployment,同时也会有多个SLB(无论公网还是内网类型)指向nginx-ingress-controller这个deployment;
2、 在创建路由时,选择自定义域名方式进行创建,不同的域名在DNS上对应不同的SLB后端;提前做好service对应域名的规划很重要。
比如在第一步我们创建了三个SLB,分别为10.10.10.10、11.11.11.11和12.12.12.12;在创建路由时创建了三个自定义域名,分别为red.selfdefine.com、yellow.selfdefine.com和blue.selfdefine.com;并且我们分别在DNS中将上面的三组分别对应解析,比如red.selfdefine.com解析到10.10.10.10上,以此类推;那么最后通过域名进行应用访问的时候,会访问到不通的SLB后端。
说明:
此时有的用户应该在界面上注意到了,无论哪种域名在界面上显示的端点都是一个,这个是当前界面上路由只支持一个SLB的问题,但是并不会对添加多个SLB后端的功能产生问题。
总结
建议在测试环境可以使用NodePort的service;
建议在生产环境使用LoadBalancer类型的service;
集群内部应用间的访问可以直接使用service的clusterip即可;