K8S中通过Service和Ingress暴露服务

5,248 阅读3分钟

K8S应用服务暴露的几种方式

上一篇文章中介绍了如何在K8S平台中基于SideCar模式部署一个Java应用。但此时我们部署的Java服务只能在集群内部通过Pod IP进行访问,无法暴露到公网对外提供服务。在K8S中,有以下方式可以将我们的应用服务对外进行暴露:

通过Service暴露应用服务

  • NodePort
    MXuUTH.png
apiVersion: v1
kind: Service
metadata:
  name: app-svc
  labels:
    app: demo-app
spec:
  type: NodePort
  ports:
 - port: 80 //service 集群IP的端口
    targetPort: 8062 //service管理的后端应用的端口
    nodePort: 30062 //service在集群内所有节点上暴露的端口
  selector:
    app: demo-app //选择器,选择关联的POD标签

集群外的服务可以通过集群的任一节点的公网IP和NodePort访问应用服务。但基于以下的几点原因,不建议在生产环境使用NodePort方式暴露服务:

  1. 增加部署管理难度: 服务部署时需要关注NodePort是否已经被占用,即使不指定端口,使用K8S随机分配的端口,这样也造成服务部署混乱,不便于管理。
  2. 安全问题: 集群暴露多个公网IP、端口给集群外部,容易产生安全问题。
  3. 增加客户端开发成本: 客户端需要维护多个IP,当某个节点宕机无法提供服务时,需要客户端去处理这种错误,增加客户端开发成本,导致强耦合。
  • LoadBalancer
    MXug0g.md.png
apiVersion: v1
kind: Service
metadata:
  name: app-svc
  labels:
    app: demo-app
spec:
  type: LoadBalancer
  ports:
  - port: 80 
    targetPort: 8062 
  selector:
    app: demo-app

当云服务商提供了负载均衡器时,就会把负载均衡的IP写入service的的external-ip中。否则此时service会一直处于pending状态。

Mb4aGj.png
因为客户端通过LoadBalancer访问服务,通过LB提供了负载均衡机制,解决了客户端需要维护多个IP的问题。并且集群内部不再需要暴露公网IP和端口,提升了集群的安全性。

通过Ingress暴露服务

MXuI10.png

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  tls: //开启tls
  - hosts:
    - mydomain.com //需要开启tls的域名
    secretName: demo-tls //挂载的secret
  rules:
  - host: mydomain.com
    http:
      paths:
      - path: /bar
        backend:
          serviceName: app-svc //Ingress关联的service
          servicePort: 80 //service端口

通过在k8S中部署Ingress Controller,并编写相应的Ingress规则并可以将我们的服务暴露。与LoadBalancer相比,其优势在于所有服务都可以通过一个公网IP暴露,通过域名和路径转发到不同的服务,是一个反向代理机制。而LoadBalancer机制则是每个服务都需要一个携带公网IP的LoadBalancer。


Service工作机制

Pod中承载的是我们具体的后端服务,我们通过定义Deployment中的spec.replicas属性,说明有几个Pod能同时提供服务。而Service便是对这一组Pod的抽象,通过Service中的spec.selector属性,确定service管理的Pod所具有的标签。Pod的IP、端口组成了EndPoint。Service通过API Server动态监听所管理的POD的创建、销毁等事件,并将可提供服务的POD信息写入EndPoints中。

MOQeKK.md.png
通过轮询或Session亲和机制,让这组Pod统一对外提供服务,使服务高可用。客户端也不在需要时刻关注后端Pod的状态变化,彻底解耦。


Ingress工作机制

为了实现服务的反向代理,K8S集群中必须部署Ingress Contoller。目前使用较多的是Ingress-Nginx。我们编写的Ingress规则会被解析为相应的Nginx规则,并写入到了Nginx Pod的nginx.conf文件中。例如我们上文中的Ingress规则,会被大致翻译为这样的nginx配置,Ingress中的host被写入Nginx的server块,path被写入location块。

MXeHne.md.png


参考资料

  1. K8S官网 kubernetes.io/docs/concep…
  2. Kubernetes In Action Chapter5(Services: enabling clients to discover and talk to pods)