K8s的Service资源是一种为一组功能相同的Pod提供统一不变的流量入口的资源。这里介绍两种典型的Service类型:ClusterIP Service、NodePort Service
ClusterIP Service
ClusterIP Service通过集群的内部IP暴露服务,使得服务只能够在集群内部被访问。这也是默认Service类型。下面我们通过RS创建一组Pod,然后通过ClusterIP Service统一流量入口。使得无论RS的Pod无论怎么变化,都可以被访问到
# API组、版本
apiVersion: apps/v1
# 资源类型
kind: ReplicaSet
metadata:
# RS名称
name: my-kubia-rs-1
spec:
# 副本数量
replicas: 3
# 标签选择器
selector:
matchLabels:
app: kubia
# Pod 模板
template:
metadata:
# 标签信息
labels:
app: kubia
spec:
# 容器信息
containers:
- name: my-kubia-1
image: luksa/kubia
# 仅用于展示容器所使用的端口
ports:
- containerPort: 8080
protocol: TCP
---
# API组、版本
apiVersion: v1
# 资源类型
kind: Service
metadata:
name: kubia-service
spec:
# Service类型
type: ClusterIP
# 标签选择器
selector:
app: kubia
ports:
- port: 9696 # 服务监听端口
targetPort: 8080 # 服务将请求转发到的目标端口
效果如下所示
由于集群内各Pod之间的网络是互通的,故我们可以先通过Pod的IP、Port来访问验证下Pod是否可以正常工作。效果如下所示
现在我们尝试通过服务的IP、Port进行访问,效果如下所示。不难看出服务同时具有负载均衡的功能了
此外,还可以通过sessionAffinity配置服务的会话亲和性。当配置为ClientIP时,其可以保证将来自相同客户端IP的请求总是转发至同一个Pod中
apiVersion: v1
kind: Service
spec:
# 基于客户端IP的会话亲和性
sessionAffinity: ClientIP
需要注意的是,当Service暴露多个端口时,需要给每个端口指定名字。如下所示
apiVersion: v1
kind: Service
spec:
ports:
- name: http-port #名为http-port的端口转发
port: 80 # 服务监听端口
targetPort: 3080 # 服务将请求转发到的目标端口
- name: https-port #名为https-port的端口转发
port: 443 # 服务监听端口
targetPort: 3443 # 服务将请求转发到的目标端口
- name: test-port #名为test-port的端口转发
port: 69 # 服务监听端口
targetPort: 3069 # 服务将请求转发到的目标端口
NodePort Service
该类型的服务类似于ClusterIP Service,集群内部的Pod可以直接通过该服务的IP、Port来访问服务。不同之处在于该NodePort Service还会在K8s集群中每个节点打开一个端口,同时将节点上该端口的流量进行转发重定向到该服务当中。这也是该服务类型名称的由来。此时一方面,Pod就可以通过任意节点的IP、NodePort Service在集群该节点打开的端口来访问访问服务;另一方面,如果K8s集群外的客户端可以访问K8s集群节点的话,就可以实现将K8s中的服务暴露给外部客户端了。而不仅仅是集群内的Pod才能访问了。示例配置文件如下所示
# API组、版本
apiVersion: apps/v1
# 资源类型
kind: ReplicaSet
metadata:
# RS名称
name: my-kubia-rs-1
spec:
# 副本数量
replicas: 3
# 标签选择器
selector:
matchLabels:
app: kubia
# Pod 模板
template:
metadata:
# 标签信息
labels:
app: kubia
spec:
# 容器信息
containers:
- name: my-kubia-1
image: luksa/kubia
# 仅用于展示容器所使用的端口
ports:
- containerPort: 8080
protocol: TCP
---
# API组、版本
apiVersion: v1
# 资源类型
kind: Service
metadata:
# 资源名称
name: my-nodeport-service-1
spec:
# Service类型
type: NodePort
selector:
app: kubia
ports:
- port: 80 # 服务监听端口
targetPort: 8080 # 服务将请求转发到Pod的目标端口
# 在集群各节点所打开的端口, 使得可以通过集群中任一节点IP、nodePort端口号访问该服务
nodePort: 30123
效果如下所示,我们可以直接通过服务的集群IP、端口访问服务。这点与ClusterIP Service并无二异
现在我们尝试通过集群节点IP、NodePort Service在节点上打开的端口来访问服务。效果如下所示
服务发现
环境变量
当服务先创建、Pod后创建时,在创建Pod过程中会把活跃Service的IP、Port信息写入该Pod的环境变量当中。具体地,服务IP、Port的环境变量名分别为{ServiceName}_SERVICE_HOST、{ServiceName}_SERVICE_PORT。其中,ServiceName是服务名称的大写,服务名称中的横线被转换成下划线
# 查看指定Pod中的环境变量
kubectl exec <Pod的名称> env
效果如下所示。这样集群内的Pod就可以通过环境变量获取服务的IP、Port。但如果先创建Pod、再创建服务的话,此时Pod当中就不会存在后续所创建服务的环境变量了
DNS
集群中的Pod还可以通过服务FQDN全限定域名作为服务的IP进行访问。FQDN的名称规则为
Note
Service的集群IP是一个虚拟IP,故无法ping通是正常的
参考文献
-
Kubernetes in Action中文版 Marko Luksa著 -
深入剖析Kubernetes 张磊著
原文始发于微信公众号(青灯抽丝):Kubernetes Service之ClusterIP Service、NodePort Service
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/42008.html