Service
Kubernetes Pod 是有?命周期的,它们可以被创建,也可以被销毁,然??旦被销毁?命就永远结束。 通过
ReplicationController 能够动态地创建和销毁 Pod 。 每个 Pod 都会获取它??的 IP 地址,即使这些 IP 地址不总是稳定可依赖的。 这会导致?个问题:在 Kubernetes 集群中,如果?组 Pod (称为 backend)为其它 Pod (称为
frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 Pod 中的哪些 backend 呢
Kubernetes Service 定义了这样?种抽象:?个 Pod 的逻辑分组,?种可以访问它们的策略 —— 通常称为微服务。
这?组 Pod 能够被 Service 访问到,通常是通过 Label Selector (查看下?了解,为什么可能需要没有 selector 的
Service )实现的
Kubernetes 提供了简单的 Endpoints API,只要 Service 中的?组 Pod 发?变更,应?程序就会被更新。 对? Kubernetes 集群中的应?,Kubernetes 提供了基于 VIP 的?桥的?式访问 Service ,再由Service 重定向到 backend Pod
三种ip
Node
节点的IP
地址Pod
的IP地址Service
的IP
地址Node IP
是Kubernetes
集群中节点的物理网卡IP
地址(一般为内网),所有属于这个网络的服务器之间都可以直接通信,所以Kubernetes
集群外要想访问Kubernetes
集群内部的某个节点或者服务,肯定得通过Node IP
进行通信
Pod IP
是每个Pod
的IP
地址,它是Docker Engine
根据docker0
网桥的IP
地址段进行分配的
Cluster IP
是一个虚拟的IP
,仅仅作用于Kubernetes Service
这个对象,由Kubernetes
自己来进行管理和分配地址,当然我们也无法ping
这个地址,他没有一个真正的实体对象来响应,他只能结合Service Port
来组成一个可以通信的服务。
?个 Service 在 Kubernetes 中是?个 REST 对象,和 Pod 类似。 像所有的 REST 对象?样, Service 定义可以基
于 POST ?式,请求 apiserver 创建新的实例。 例如,假定有?组 Pod ,它们对外暴露了 9376 端?,同时还被打上
"app=MyApp" 标签
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376 #pod端口
kubectl create -f myservice.yaml
将创建?个名称为 “my-service” 的 Service 对象,它会将请求代理到使? TCP 端? 9376,并且具有标签
"app=MyApp" 的 Pod 上。 这个 Service 将被指派?个 IP 地址(通常称为 “Cluster IP”),它会被服务的代理使?(?下?)。 该 Service 的 selector 将会持续评估,处理结果将被 POST 到?个名称为 “my-service” 的 Endpoints 对象上
Service 能够将?个接收端?映射到任意的 targetPort 。 默认情况下, targetPort 将被设置为与
port 字段相同的值。 可能更有趣的是, targetPort 可以是?个字符串,引?了 backend Pod 的?个端?的名称。 但
是,实际指派给该端?名称的端?号,在每个 backend Pod 中可能并不相同。 对于部署和设计 Service ,这种?式会
提供更?的灵活性。 例如,可以在 backend 软件下?个版本中,修改 Pod 暴露的端?,并不会中断客户端的调?。
Kubernetes Service 能够?持 TCP 和 UDP 协议,默认 TCP 协议。
没有 selector 的 Service
Service 抽象了该如何访问 Kubernetes Pod ,但也能够抽象其它类型的 backend,例如:
在Kubernetes
集群中,每个Node
会运行一个kube-proxy
进程, 负责为Service
实现一种 VIP(虚拟 IP,就是我们上面说的clusterIP
)的代理形式,现在的Kubernetes
中默认是使用的iptables
这种模式来代理。这种模式,kube-proxy
会监视Kubernetes master
对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会添加上 iptables 规则,从而捕获到达该 Service 的 clusterIP(虚拟 IP)和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某一个个上面。 对于每个 Endpoints 对象,它也会安装 iptables 规则,这个规则会选择一个 backend Pod。
默认的策略是,随机选择一个 backend。 我们也可以实现基于客户端 IP 的会话亲和性,可以将 service.spec.sessionAffinity
的值设置为 "ClientIP" (默认值为 "None")
定义Service
的时候可以指定一个自己需要的类型的Service
,如果不指定的话默认是ClusterIP
类型
可以使用的服务类型如下:
如果设置 type 的值为 "NodePort",Kubernetes master 将从给定的配置范围内(默认:30000-32767)分配端口,每个 Node 将从该端口(每个 Node 上的同一端口)代理到 Service。该端口将通过 Service 的 spec.ports[*].nodePort 字段被指定,如果不指定的话会自动生成一个端口。
需要注意的是,Service 将能够通过 :spec.ports[].nodePort 和 spec.clusterIp:spec.ports[].port 而对外可见
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: myapp
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
name: myapp-http
创建该服务
$ kubectl create -f service-demo.yaml
查看Service对象信息:
$ kubectl get svc
ExternalName
是 Service 的特例,它没有 selector,也没有定义任何的端口和 Endpoint。 对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
当查询主机 my-service.prod.svc.cluster.local (后面服务发现的时候我们会再深入讲解)时,集群的 DNS 服务将返回一个值为 my.database.example.com 的 CNAME 记录。 访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在 DNS 层,而且不会进行代理或转发。 如果后续决定要将数据库迁移到 Kubernetes 集群中,可以启动对应的 Pod,增加合适的 Selector 或 Endpoint,修改 Service 的 type,完全不需要修改调用的代码
原文:https://www.cnblogs.com/g2thend/p/12745129.html