k8s篇- Service对象详解

为什么需要 Service:

每个Pod被创建后,都会有它自己的IP,但由于Pod存在生命周期,经常会被创建与销毁,一旦重新创建POD,该POD的IP就会发生变化。所以,这些POD应用需要对外提供一个统一的访问入口,即固定IP,外部才能正常访问,这个统一的访问入口就是service。


Service 定义:

我们可以将多个POD划分到同一个逻辑组中,并统一向外提供服务,这个逻辑组就是一个service。POD是通过Label Selector加入到指定的service中。Service相当于是一个负载均衡器,用户请求会先到达service,再由service转发到它内部的某个POD上(默认以round-robin方式转发)。

请求(集群内部或外部) -> Service -> POD1,POD2,...

一、Service四种类型

k8s中共有4种类型的service,不同service类型是通过 services.spec.type 字段来指定。

  • ClusterIP:用于集群内部访问。该类型会为service分配一个IP,集群内部请求先到达service,再由service转发到其内部的某个POD上。
  • NodePort:用于集群外部访问。该类型会将Service的Port映射到集群的每个Node节点上,然后在集群之外,就能通过Node节点上的映射端口访问到这个Service。
  • LoadBalancer:用于集群外部访问。该类型是在所有Node节点前又挂了一个负载均衡器,作为集群外部访问的统一入口,外部流量会先到达LoadBalancer,再由它转发到集群的node节点上,通过nodePort再转发给对应的service,最后由service转发到后端Pod中。
  • ExternalName:创建一个DNS别名(即CNAME)并指向到某个Service Name上,也就是为某个Service Name添加一条CNAME记录,当有请求访问这个CNAME时会自动解析到这个Service Name上。

Headless Service:

Service作为访问入口,它可以用 IP 或 service_name(要借助于内部DNS解析)这两种方式来访问。当创建好service时,系统会自动为Service分配一个IP,我们也可以通过services.spec.clusterIP 字段手动指定一个IP,但若这个字段设置为None,系统就不会再为这个service分配IP,后面就只能通过service_name来访问,而这种没有IP的service,就被称为Headless Service

也就是,Headless表示这个service没有分配IP信息,只能通过service_name来访问。

service字段说明:

services.spec.
    clusterIP: 设置service的IP。若省略该字段,默认由系统随机分配
    ports:
        port: 设置service的访问端口
        targetPort: 设置service下的后端POD端口
        nodePort: 设置映射到node节点上的端口。当type为NodePort或LoadBalancer时,需要为service指定一个映射在Node节点上的端口
    selector: 设置标签选择器。POD根据匹配此标签来加入到此service下
    type: 定义service类型,可选值有ClusterIP(默认), NodePort, LoadBalancer, ExternalName
    sessionAffinity: 可选值是ClientIP或None。默认值为None,表示以round-robin方式将请求转发到后端Pod,若值为ClientIP,表示保持连接,请求始终会被调度到同一个Pod上

1. ClusterIP类型

需要将 services.spec.type 设置为 ClusterIP,该类型会为service分配一个IP,这个IP只能在集群内部访问,用户请求先到达service,再由service转发到其内部的某个POD上。

默认service是以round-robin方式将请求转发到后端Pod,若始终要转发到同一个POD上,需要设置services.spec.sessionAffinity。

请求(集群内部)---> service_ip/service_name:8080 -> POD1:80,POD2:80,POD3:80

示例1:带有IP的Service

第一步:创建一个ClusterIP类型的Service(手动指定IP或省略ClusterIP字段)

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
spec:
  selector: 					#设置标签选择器。POD通过匹配此label来选择是否要加入到这个Service下
    app: myweb01
  type: ClusterIP 				#设置service类型为ClusterIP
  ClusterIP: 172.17.202.174     #为service指定一个IP,这个IP在集群内部可访问。若省略该字段,系统会自动分配一个IP
  ports:
  - name: nginx
    port: 8080
    protocol: TCP
    targetPort: 80
  sessionAffinity: None

第二步:创建POD(加入到此service中)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: svc01-pod-demo
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myweb01
  template:
    metadata:
      labels:
        app: myweb01
    spec:
      containers:
      - name: myweb01
        image: nginx:1.7.9
        ports:
        - name: http
          containerPort: 80

第三步:查看Service

$ kubectl get svc my-service
NAME          TYPE         CLUSTER-IP       EXTERNAL-IP    PORT(S)     AGE
my-service    ClusterIP    172.17.202.174   <none>         8080/TCP    4s

$ kubectl describe svc my-service
Name:              my-service
Namespace:         default
Labels:            <none>
Annotations:       ...
Selector:          app=myweb01 			#service会通过匹配此label,选择哪些POD加入到这个service下
Type:              ClusterIP
IP:                172.17.2.14
Port:              nginx  8080/TCP
TargetPort:        80/TCP
Endpoints:         172.16.1.12:80,172.16.2.17:80,172.16.2.45:80 	#表示当前已加入到此service下的POD
Session Affinity:  None
Events:            <none>

第四步:集群内部访问Service

  • 直接访问Service的IP;
  • 直接访问Service的Name(依靠DNS解析):同一个Namespace下直接通过servicename访问,跨Namespace访问需要加上namespace,如{servicename}.{namespace};
  • 通过环境变量访问:将service的一些IP、端口等信息,通过环境变量方式传到Pod里;
              集群内的Pod和Node
                     |
                     | curl 172.17.2.14:8080
                     | curl my-service:8080
                     | curl $service_name:$service_port
                     |
               ——————↓———————
              |  my-service  |
              |  172.17.2.14 |
              '——————↓———————'
                     |
 ____________________|_________________________
|           /        |          \              |
|          /         |           \             |
|       POD1         |          POD3           |
|  172.16.1.12:80    |      172.16.2.17:80     |
|                   POD2                       |
|              172.16.2.45:80                  |
|                                      
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值