【K8S】Service服务详解,看这一篇就够了!!

k8s用命名空间namespace把资源进行隔离,默认状况下,相同的命名空间里的服务能够相互通信,反之进行隔离。前端

1.1 Service

Kubernetes中一个应用服务会有一个或多个实例(Pod,Pod能够经过rs进行多复本的创建),每一个实例(Pod)的IP地址由网络插件动态随机分配(Pod重启后IP地址会改变)。为屏蔽这些后端实例的动态变化和对多实例的负载均衡,引入了Service这个资源对象,以下所示:node

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  type: ClusterIP
  ports:
    - port: 80
       targetPort: 80
  selector:  #service经过selector和pod创建关联
    app: nginx

根据建立Service的type类型不一样,可分红4种模式:nginx

  • ClusterIP: 默认方式。根据是否生成ClusterIP又可分为普通Service和Headless Service两类:
    • 普通Service:经过为Kubernetes的Service分配一个集群内部可访问的固定虚拟IP(Cluster IP),实现集群内的访问。为最多见的方式。
    • Headless Service:该服务不会分配Cluster IP,也不经过kube-proxy作反向代理和负载均衡。而是经过DNS提供稳定的络ID来访问,DNS会将headless service的后端直接解析为podIP列表。主要供StatefulSet使用。
  • NodePort:除了使用Cluster IP以外,还经过将service的port映射到集群内每一个节点的相同一个端口,实现经过nodeIP:nodePort从集群外访问服务。
  • LoadBalancer:和nodePort相似,不过除了使用一个Cluster IP和nodePort以外,还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的nodePort),实现从集群外经过LB访问服务。
  • ExternalName:是 Service 的特例。此模式主要面向运行在集群外部的服务,经过它能够将外部服务映射进k8s集群,且具有k8s内服务的一些特征(如具有namespace等属性),来为集群内部提供服务。此模式要求kube-dns的版本为1.7或以上。这种模式和前三种模式(除headless service)最大的不一样是重定向依赖的是dns层次,而不是经过kube-proxy。
    好比,在service定义中指定externalName的值"my.database.example.com":

此时k8s集群内的DNS服务会给集群内的服务名 ..svc.cluster.local 建立一个CNAME记录,其值为指定的"my.database.example.com"。
当查询k8s集群内的服务my-service.prod.svc.cluster.local时,集群的 DNS 服务将返回映射的CNAME记录"foo.bar.example.com"。后端

备注: 前3种模式,定义服务的时候经过selector指定服务对应的pods,根据pods的地址建立出endpoints做为服务后端;Endpoints Controller会watch Service以及pod的变化,维护对应的Endpoint信息。kube-proxy根据Service和Endpoint来维护本地的路由规则。当Endpoint发生变化,即Service以及关联的pod发生变化,kube-proxy都会在每一个节点上更新iptables,实现一层负载均衡。 而ExternalName模式则不指定selector,相应的也就没有port和endpoints。 ExternalName和ClusterIP中的Headles Service同属于Headless Service的两种状况。Headless Service主要是指不分配Service IP,且不经过kube-proxy作反向代理和负载均衡的服务。api

1.2 Port

Service中主要涉及三种Port: * port 这里的port表示service暴露在clusterIP上的端口,clusterIP:Port 是提供给集群内部访问kubernetes服务的入口。网络

  • targetPort

containerPort,targetPort是pod上的端口,从port和nodePort上到来的数据最终通过kube-proxy流入到后端pod的targetPort上进入容器。app

  • nodePort

nodeIP:nodePort 是提供给从集群外部访问kubernetes服务的入口。负载均衡

总的来讲,port和nodePort都是service的端口,前者暴露给从集群内访问服务,后者暴露给从集群外访问服务。从这两个端口到来的数据都须要通过反向代理kube-proxy流入后端具体pod的targetPort,从而进入到pod上的容器内。less

1.3 IP

使用Service服务还会涉及到几种IP:google

  • ClusterIP

Pod IP 地址是实际存在于某个网卡(能够是虚拟设备)上的,但clusterIP就不同了,没有网络设备承载这个地址。它是一个虚拟地址,由kube-proxy使用iptables规则从新定向到其本地端口,再均衡到后端Pod。当kube-proxy发现一个新的service后,它会在本地节点打开一个任意端口,建立相应的iptables规则,重定向服务的clusterIP和port到这个新建的端口,开始接受到达这个服务的链接。

  • Pod IP

Pod的IP,每一个Pod启动时,会自动建立一个镜像为gcr.io/google_containers/pause的容器,Pod内部其余容器的网络模式使用container模式,并指定为pause容器的ID,即:network_mode: "container:pause容器ID",使得Pod内全部容器共享pause容器的网络,与外部的通讯经由此容器代理,pause容器的IP也能够称为Pod IP。

  • 节点IP

Node-IP,service对象在Cluster IP range池中分配到的IP只能在内部访问,若是服务做为一个应用程序内部的层次,仍是很合适的。若是这个service做为前端服务,准备为集群外的客户提供业务,咱们就须要给这个服务提供公共IP了。指定service的spec.type=NodePort,这个类型的service,系统会给它在集群的各个代理节点上分配一个节点级别的端口,能访问到代理节点的客户端都能访问这个端口,从而访问到服务。

相关文章
相关标签/搜索