Service定义了pods的逻辑集合和访问这个集合的策略。 Pods集合是通过定义Service时提供的Label选择器完成的
Service的引入旨在保证pod的动态变化对访问端透明,访问端只需要知道service的地址,由service来提供代理
Service的抽象使得前端客户和后端Pods进行了解耦,支持ClusterIP, NodePort以及LoadBalancer三种类型
1.port
k8s集群内部服务之间访问service的入口。即clusterIP:port是service暴露在clusterIP上的端口,例如mysql容器暴露了3306端口,集群内其他容器通过13306端口访问mysql服务,但是外部流量不能访问mysql服务,因为mysql服务没有配置NodePort。对应的
service.yaml如下: apiVersion: v1 kind: Service metadata: name: mysql-service spec: ports: - port: 13306 targetPort: 3306 selector: name: mysql-pod
2.nodePort
外部流量访问k8s集群中service入口的一种方式(另一种方式是LoadBalancer),即nodeIP:nodePort是提供给外部流量访问k8s集群中service的入口。比如外部用户要访问k8s集群中的一个Web应用,那么我们可以配置对应service的type=NodePort,nodePort=8001。其他用户就可以通过浏览器http://node:8001访问到该web服务。而数据库等服务可能不需要被外界访问,只需被内部服务访问即可,那么我们就不必设置service的NodePort。
apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort // 有配置NodePort,外部流量可访问k8s中的服务 ports: - port: 8000 targetPort: 80 // 容器暴露端口 nodePort: 8001 // nodePort selector: name: nginx-pod
3.targetPort
容器的端口,targetPort是pod上的端口,从port和nodePort上来的流量,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。
制作容器时暴露的端口一致(使用DockerFile中的EXPOSE),对应的service.yaml如下
apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort // 有配置NodePort,外部流量可访问k8s中的服务 ports: - port: 8000 targetPort: 80 // 容器暴露端口 selector: name: nginx-pod
4.hostPort
这是一种直接定义Pod网络的方式。hostPort是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的IP加上来访问Pod了,具体的yaml文件如下:
apiVersion: v1 kind: Pod metadata: name: influxdb spec: containers: - name: influxdb image: influxdb ports: - containerPort: 8086 hostPort: 8086
这样做有个缺点,因为Pod重新调度的时候该Pod被调度到的宿主机可能会变动,这样就变化了,用户必须自己维护一个Pod与所在宿主机的对应关系。
使用了 hostPort 的容器只能调度到端口不冲突的 Node 上,除非有必要(比如运行一些系统级的 daemon 服务),不建议使用端口映射功能。如果需要对外暴露服务,建议使用 NodePort Service。