Service 是指向 pods 的,
Service 不是直接指向 Deployments 、ReplicaSets、StatefulSet,而是直接使用 labels 标签指向 Pod。
这种方式就提供了极大的灵活性,因为通过什么方式创建的 Pod 其实并不重要。
换句话说,
通过创建一个service服务,实现以各种方式访问到某个pod
一、关系图
在 Kubernetes 中 Service 主要有4种不同的类型,其中的 ClusterIP 是最基础的。
创建一个 NodePort 的 Service 时,它也会创建一个 ClusterIP。
而如果你创建一个 LoadBalancer,它就会创建一个 NodePort,然后创建一个 ClusterIP。
二、路由图
所有网络请求都要经过kube-proxy。
三、为什么需要service
假设有两个节点,节点有外网(4.4.4.1、4.4.4.2)和内网(1.1.1.1、1.1.1.2)的 IP 地址,
节点1的pod-nginx通过内部IP 地址(1.1.1.3)对pod-python 这个 Pod 的进行调用。
现在如果 pod-python 挂掉了重新创建了一个新的 pod-python 出来,系统会重新分配了一个新的 1.1.1.5 的 Pod IP 地址,这个时候 pod-nginx 就无法再达到 1.1.1.3 这个之前的地址了。
为了防止这种情况发生,我们就需要创建一个 Service 服务了!
四、service类型
1. internal_ip
内部ip,系统为node节点、pod、service都会创建内部ip,如下图中的1.1.x.x
2. ClusterIp
默认类型,系统为node节点、pod、service都会分配一个集群内部的Ip,这私有ip ,内部可以互相访问,外部无法访问集群内部。
为pod-python创建一个service,name叫service-python。
集群内部的所有 Pods 都可以通过 http://1.1.10.1:3000
或者 http://service-python:3000
来访问到后面的 python pods 的443端口。
上图中的 service-python 这个 Service 可以用下面的 yaml 文件来创建:
apiVersion: v1
kind: Service
metadata:
name: service-python
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
selector:
run: pod-python
type: ClusterIP
clusterIP主要在每个node节点使用iptables,将发向clusterIP对应端口的数据,转发到kube-proxy中。
然后kube-proxy自己内部实现有负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据转发给对应的pod的地址和端口。
3. NodePort
现在我们想让 ClusterIP Service 可以从集群外部进行访问,我们将Service定义为 NodePort 类型,注意其中的nodePort字段和type字段:
apiVersion: v1
kind: Service
metadata:
name: service-python
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
nodePort: 30080
selector:
run: pod-python
type: NodePort
在外部,可以通过4.4.4.1:30080或者4.4.4.2:30080访问到pod-python。
在内部,可以通过1.1.1.1:30080或1.1.1.2:30080访问到pod-python。
基于ClusterIp,另外在每个Node上开放一个端口,将service的port映射到每个node的一个指定内部port上,映射的每个node的内部port都一样。将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步导给对应的pod。可以从所有的位置访问这个地址。
4. LoadBalance
基于NodePort,云服务商在外部创建了一个负载均衡层,提供一个单独的ip,将流量导入到对应node。
LoadBalancer跟nodePort其实是同一种方式。
区别在于LoadBalancer比nodePort多了一步,就是可以调用cloud provider去创建LB来向节点导流。
其yaml定义为:
apiVersion: v1
kind: Service
metadata:
name: service-python
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
nodePort: 30080
selector:
run: pod-python
type: LoadBalancer
5. ExternalName
假设 pod-nginx 运行在 Kubernetes 集群中,但是 python api 服务在集群外部。
这里 pod-nginx 这个 Pod 可以直接通过 http://remote.server.url.com 连接到外部的 python api 服务上去,但是如果我们考虑到以后某个时间节点希望把这个 python api 服务集成到 Kubernetes 集群中去,还不希望去更改连接的地址,这个时候我们就可以创建一个 ExternalName 类型的 Service 服务了。
现在 pod-nginx 就可以很方便地通过 http://service-python:3000
进行通信了,就像使用 ClusterIP 服务一样,当我们决定将 python api 这个服务也迁移到我们 Kubernetes 集群中时,我们只需要将服务改为 ClusterIP 服务,并设置正确的标签即可,其他都不需要更改了。
将外部地址经过集群内部的再一次封装(实际上就是集群DNS服务器将CNAME解析到了外部地址上),实现了集群内部访问即可。要求kube-dns的版本为1.7或以上.
例如你们公司的镜像仓库,最开始是用ip访问,等到后面域名下来了再使用域名访问。你不可能去修改每处的引用。但是可以创建一个ExternalName,首先指向到ip,等后面再指向到域名。所有需要访问仓库的地方,统一访问这个服务即可。
其yaml文件可定义为:
kind: Service
apiVersion: v1
metadata:
name: service-python
spec:
ports:
- port: 3000
protocol: TCP
targetPort: 443
type: ExternalName
externalName: remote.server.url.com
https://www.cnblogs.com/zhoushiya/p/12259886.html
https://blog.csdn.net/m0_37556444/article/details/84991535
神作https://mp.weixin.qq.com/s/2qYgORto5voMliFSzqNrPw