service

Posted 看,未来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了service相关的知识,希望对你有一定的参考价值。

文章目录

Service 定义

Service 用于为一组提供服务的 Pod 抽象一个稳定的网络访问地址。通过 Service 的定义,能够为客户端应用提供稳定的访问地址和负载均衡功能,以及屏蔽后端 Endpoint 的变化,是 kubernetes 实现微服务的核心资源。

nametyperequiredbackup
versionstring1
kindstring1Service
metadateobject1
m.namestring1Service 名称,可配置用于访问
m.namespacestring1和上面那个,详见我的 CoreDNS 博文
m.labels[]list
m.annotationlist
specobject1详细数据
s.selector[]list1将选择具有指定 label 标签的 Pod 作为管理范围
s.typestring1Service 的类型,指定 Service 的访问方式。默认值为 ClusterIP。见下方注释1
s.clusterIPstring当 service.type == ClusterIP 时,用以配置对应 IP;如果不指定,将由系统自动生成;如果是无头 Service,将此项设置为 None。Headless Service 后文再说。
s.sessionAffinitystring是否支持 Session。可选值为 ClientIP,默认值为 None。ClientIP 表示将同一个客户端IP来的访问请求全都转发到同一个后端 Pod、
s.ports[]listService 端口列表
s.p.namestring端口名称
s.p.protocolstring端口协议,支持 TCP/UDP,默认是 TCP
s.p.portint服务监听的端口号
s.p.targetPortint需要转发到后端 Pod 的端口号
s.p.nodePortint当 spec.type == NodePort 时,指定映射到宿主机的端口号
statusobject当 spec.type == LoadBalancer 时,设置外部负载均衡器的地址
status.loadBalancerobject外部负载均衡器
status.l.ingressobject外部负载均衡器
status.l.i.ipstring
status.l.i.hostnamestring

注1:

  • spec.type
    Service 的类型,指定 Service 的访问方式,默认值为 ClusterIP。
    (1)ClusterIP:虚拟服务 IP 地址,该地址用于 kubernetes 集群内部的 Pod 访问,在 Node 上 kube-proxy 通过设置的 iptables 规则进行转发。
    (2)NodePort:使用宿主机的端口,使能够访问各 Node 的外部客户端通过 Node 的 IP 地址和端口号就能访问服务。
    (3)LoadBalance:使用外接负载均衡器完成到服务的负载均衡分发,需要在 spec.status.loadBalance 字段指定外部负载均衡器的地址。

注2:这个 targetPort,可以直接用 pod 中的 ports.name,这一点让我有点迷惑,有个问题亟待求证:
(1)如果两个 Pod 有同样的 ports.name,但是却对应着不同的 ContainerPort 呢,会怎么样?


负载分发策略

对Service的访问被分发到了后端的Pod上去,目前kubernetes提供了两种负载分发策略:

如果不定义,默认使用kube-proxy的策略,比如随机、轮询等。

基于客户端地址的会话保持模式,即来自同一个客户端发起的所有请求都会转发到固定的一个Pod上,这对于传统基于Session的认证项目来说很友好,此模式可以在spec中添加sessionAffinity: ClusterIP选项。

我们来做个实验:1、创建三个 pod:

apiVersion: apps/v1
kind: Deployment      
metadata:
name: pc-deployment
namespace: dev
spec:
replicas: 3
selector:
  matchLabels:
    app: nginx-pod
template:
  metadata:
    labels:
      app: nginx-pod
  spec:
    containers:
    - name: nginx
      image: nginx:1.17.1
      ports:
      - containerPort: 80

2、查看创建结果

[root@k8s-master wlf]# kubectl get pods -n w -o wide --show-labels
NAME                             READY   STATUS   RESTARTS   AGE     IP               NODE                   NOMINATED NODE   READINESS GATES   LABELS
pc-deployment-6696798b78-2jpf4   1/1     Running   0         2m50s   10.244.102.155   localhost.localdomain   <none>           <none>            app=nginx-pod,pod-template-hash=6696798b78
pc-deployment-6696798b78-lggkb   1/1     Running   0         2m50s   10.244.102.156   localhost.localdomain   <none>           <none>            app=nginx-pod,pod-template-hash=6696798b78
pc-deployment-6696798b78-vsxj8   1/1     Running   0         2m50s   10.244.102.154   localhost.localdomain   <none>           <none>            app=nginx-pod,pod-template-hash=6696798b78

3、为了方便后面的测试,修改下三台nginx的index.html页面。

kubectl exec -it pc-deployment-6696798b78-2jpf4 -n w /bin/sh
echo "10.244.102.155" > /usr/share/nginx/html/index.html

4、测试一下是否写入成功

[root@k8s-master wlf]# curl 10.244.102.154
10.244.102.154

5、创建集群负载服务:

apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: w
spec:
selector:
  app: nginx-pod
clusterIP: 10.97.97.97 # service的ip地址,如果不写,默认会生成一个
type: ClusterIP
ports:
 - port: 80  # Service端口      
  targetPort: 80 # pod端口

6、 查看service的详细信息

# 在这里有一个Endpoints列表,里面就是当前service可以负载到的服务入口[root@k8s-master wlf]# kubectl describe svc service-clusterip -n w
Name:             service-clusterip
Namespace:         w
Labels:           <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:             ClusterIP
IP:                10.97.97.97
Port:             <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.102.154:80,10.244.102.155:80,10.244.102.156:80
Session Affinity: None
Events:           <none>

7、查看ipvs的映射规则【rr 轮询】

TCP  10.97.97.97:80 rr
 -> 10.244.102.154:80           Masq    1      0          0        
 -> 10.244.102.155:80           Masq    1      0          0        
 -> 10.244.102.156:80           Masq    1      0          0   

8、默认访问测试

是轮询吧。

9、修改分发策略

apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: dev
spec:
selector:
  app: nginx-pod
clusterIP: 10.97.97.97 # service的IP地址,如果不写,默认会生成一个
type: ClusterIP
sessionAffinity: ClientIP # 修改分发策略为基于客户端地址的会话保持模式
ports:
   - port: 80 # Service的端口
    targetPort: 80 # Pod的端口

10、再测试


无头 service

开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况,kubernetes提供了HeadLiness Service,这类Service不会分配Cluster IP,如果想要访问service,只能通过service的域名进行查询。

创建一个无头service:

apiVersion: v1
kind: Service
metadata:
name: service-headliness
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
type: ClusterIP
ports:

  • port: 80
    targetPort: 80
    进入pod 中:

kubectl exec -it pc-deployment-6696798b78-2jpf4 -n w bash
root@pc-deployment-6696798b78-2jpf4:/# cat /etc/resolv.conf
nameserver 10.96.0.10
search w.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
通过Service的域名进行查询:

dig @10.96.0.10 service-headliness.w.svc.cluster.local

service-headliness.w.svc.cluster.local.30 IN A10.244.102.155
service-headliness.w.svc.cluster.local.30 IN A10.244.102.154
service-headliness.w.svc.cluster.local.30 IN A10.244.102.156


参考文献

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/

以上是关于service的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在电子邮件中折叠/展开 DIV?哪些客户支持这一点?

看完这一篇,再也不怕面试官问到IntentService的原理

services.volumes 不支持的配置选项

使用 ***Service 的 Android http 隧道

itms-services // action=purchaseIntent 没有打开应用

Service-Worker addEventListener,如何使用事件参数?