Kubernetes之Service详解

文章目录

  • 前言
  • 一、Service 概念
  • 二、Service 流量策略
    • 2.1 外部流量策略
    • 2.1 内部流量策略
  • 三、Service 使用
    • 3.1 一般用法
      • 3.1.1 Cluster IP模式
      • 3.1.2 NodePort模式
    • 3.2 多端口 Service
    • 3.3 外部服务 Service
      • 3.3.1 Service绑定负载均衡
      • 3.3.2 Service转发流量至外部服务
  • 总结


前言

在kubernetes集群中每个Pod都有自己的 IP 地址。使用Service可以实现不需要显式地在它们之间创建链接,创建了一个简洁的网络。而且Kubernetes网络实现了以下功能:

  • Pod 中的容器通过环回网络;
  • 集群网络提供不同 Pod 之间的通信;
  • Service 资源应用程序从集群外部访问;
  • Service用于集群内的访问。

一、Service 概念

Service是kubernetes核心资源之一,Service定义了一个服务的访问入口地址,前端的应用(pod)或者ingress通过这个地址访问其背后一组由Pod副本组成的集群实例。

在解决服务发现和服务通信的问题上,kubernetes使用了一种独特的方法:Service,Service没有共用一个负载均衡的IP(通常做法是共用一个IP,用端口进行区分),反而是给每个Service分配了一个全局虚拟IP,也叫Cluster IP,这样的好处在于服务调用就变成TCP通信问题。

众所周知,Pod的Endpoint地址随着容器生命周期发生改变,新部署的Pod地址和之前的Pod地址不尽相同,Kubernetes Service定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略,通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector来实现。如果要了解无 Selector 的其他方法,请参阅3.2

二、Service 流量策略

2.1 外部流量策略

设置spec.externalTrafficPolicy字段

  • Local:流量只发给本机的Pod。
  • Cluster:流量可以转发到集群中其他节点上的Pod。
    说明 您的服务类型为虚拟集群IP或负载均衡时,才能设置外部流量策略。
    如果流量策略是Local并且没有节点本地端点,则 kube-proxy 不会为相关服务转发任何流量。

2.1 内部流量策略

设置spec.internalTrafficPolicy字段

  • Local:流量只发给本机的Pod。
  • Cluster:流量可以转发到集群中其他节点上的Pod。
    如果流量策略是Local并且没有节点本地端点,则 kube-proxy 会丢弃流量。

三、Service 使用

3.1 一般用法

3.1.1 Cluster IP模式

最常用的模式,通常用在集群内的两个服务相互访问

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

该配置创建了一个名为“my-service”的服务对象,它可以将my-service:80流量转发到任何带有标签app=MyApp且端口为9376的 Pod 上 。
Kubernetes 为该服务分配一个 IP 地址(有时称为“Cluster IP”),我们可以使用Cluster IP和服务名称进行访问。仅限定在集群内访问。

3.1.2 NodePort模式

在集群的每一个Node节点分配静态端口 (the NodePort) 绑定后端Pod服务。ClusterIPService 路由到的ServiceNodePort是自动创建的。外部服务可以通过NodePort请求集群Pod,方式:
好处在于给开发者们设置自己的负载均衡器的自由,或者将Kubernetes配置在完全支持负载均衡的云环境上,或者甚至可以直接开放一个或者多个节点的IP。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: MyApp
  ports:
      # By default and for convenience, the `targetPort` is set to the same value as the `port` field.
    - port: 80
      targetPort: 80
      # Optional field
      # By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
      nodePort: 30007

请注意,此服务显示为:spec.ports[].nodePort 和.spec.clusterIP:spec.ports[].port。如果设置–nodeport-addresses kube-proxy 的标志或 在kube-proxy 配置了等效字段,则将忽略节点 IP。

3.2 多端口 Service

对于某些服务,您需要公开多个端口。Kubernetes 允许在服务对象上配置多个端口定义。当为一个服务使用多个端口时,必须提供所有端口名称,以便明确这些名称。例如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
    - name: https
      protocol: TCP
      port: 443
      targetPort: 9377

名字写法与 Kubernetes 一样,端口名称只能包含小写字母数字字符和-. 端口名称也必须以字母数字字符开头和结尾。

3.3 外部服务 Service

3.3.1 Service绑定负载均衡

在支持负载均衡器的云提供商上,将type 字段设置LoadBalancer可以为服务提供负载均衡(例如:SLB、CLB)。负载均衡器的实际创建是异步发生的,有关已配置的均衡器的信息会发布在 Service的.status.loadBalancer字段中。例如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

注意:可用于 LoadBalancer 类型的服务的协议集仍由云提供商定义。
一些云提供商允许指定loadBalancerIP. 在这些情况下,负载均衡器是使用用户指定的loadBalancerIP. 如果loadBalancerIP未指定该字段,则使用临时 IP 地址设置 loadBalancer。如果您指定 aloadBalancerIP 但云提供商不支持该功能,则loadbalancerIP设置的字段将被忽略。
以阿里云为列,我们需要如下配置:
service.beta.kubernetes.io/alicloud-loadbalancer-address-type决定负载均衡器是否是公网还是内网

apiVersion: v1
kind: Service
metadata:
  name: my-service
annotations:
  service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet
  service.beta.kubernetes.io/alicloud-loadbalancer-force-override-listeners: 'true'
  service.beta.kubernetes.io/alicloud-loadbalancer-id: xxxx
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: xx.xxx.xxx.xx

注意: 如果在SLB设置了externalTrafficPolicy: Local类型,这种类型的SLB地址只有在Node中部署了对应的后端Pod,才能被访问。因为SLB的地址是集群外使用,如果集群节点和Pod不能直接访问,请求不会到SLB,会被当作Service的扩展IP地址,被kube-proxy的iptables或ipvs转发。

3.3.2 Service转发流量至外部服务

我们有时在进行服务迁移,或者集群迁移,又或者想把某个外部服务像内部服务一样连接,需要将一个集群的流量转发到另一个集群的流量,我们可以使用如下写法,即不指定selector app字段,手动配置endpoint

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于此 Service 没有选择器,因此不会自动创建相应的 Endpoints 对象。您可以通过手动添加 Endpoints 对象,手动将服务映射到其运行的网络地址和端口:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

Endpoints 对象的名称必须和Service 同名。


总结

对于许多想要使用Service的人来说,以上的信息应该足够了。但是我们可以尝试理解Service背后的原理

1、ClusterIP 如何保证唯一
2、 kube-proxy在你的集群中使用的那种模式,
3、iptables和IPVS有何不同
如果你的集群规模特别大,如有10000个Pod。那么请使用IPVS模式吧,IPVS 专为负载平衡而设计,并基于内核哈希表。因此,可以通过基于 IPVS 的 kube-proxy 实现大量服务的性能一致性。同时,基于 IPVS 的 kube-proxy 具有更复杂的负载平衡算法(最少连接数、局部性、加权、持久性)。

你可能感兴趣的:(kubernetes,kubernetes,docker,容器)