一、前言
在一主多从的k8s集群中, 当我们使用 Deployment 创建某个镜像的多副本时,每个副本都是均匀分配到个个Work 节点上,并且每个Pod 都有自己的内网Ip ,那么问题来了,我们应该用哪个Pod的IP 来访问Pod ? 如果使用某一个Pod的内网ip来访问,那这个Pod 宕机了, 那集群岂不是挂了?
二、Service 的服务发现和负载均衡
k8s 官方对Service 的定义是:将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。使用 Kubernetes,你无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡。说直白点k8s 中可以使用Service 来对网络的抽象,就有点类似于Nginx 的机制。
当用户的请求打到 Service 上之后, Service 会自动将请求分发到集群的个个Pod上,当某一个Pod 发生故障, Service 会及时发现, 并且将该Pod “剔除” , 后续请求不会给它。
1、测试
1. 首先创建出一组Pod
kubectl create deployment mynginx --image=nginx --replicas=3
2. 将每个Nginx 的的默认页面改成自定义的内容。
3. 创建一个Service服务, 并对外暴露 8000 端口
# 语法:kubectl expose deployment <Deployment名称> --port=<Service对外端口> --target-port=<目标端口>
kubectl expose deployment mynginx --port=8000 --target-port=80
4. 访问Service 地址,可以看到实现了负载均衡的效果
5. 关闭其中的一台服务器,看是否可以正常访问
注意:如上图所示, 当 Deployment 重新拉起Pod, 但是访问的内容并不是之前的内容, 那是因为当时存储的数据是在Pod 中, 并没有将数据挂在出来, 所以导致数据丢失了, 后面的章节会介绍这个知识点。
三、多端口Service
对于某些服务,可能需要公开多个端口。 Kubernetes 允许我们在 Service 对象上配置多个端口定义。 为服务使用多个端口时,必须提供所有端口名称,以使它们无歧义。 例如:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
四、Service 类型
k8s ServiceTypes 的取值如下:
- ClusterIP:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType。
- NodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。
- LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。
- ExternalName:通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。
1、常用的ClusterIP 与 NodePort比较
在创建 Service 的时候,常用的两种方式 -- ClusterIP 与 NodePort。 顾名思义, ClusterIP 是集群ip的意思,NodePort 是节点端口的意思。ClusterIP是默认的配置,在创建 Service 的时候, 可以手动指定方式
# 默认不加 --type 等于 --type=ClusterIP
kubectl expose deployment mynginx --port=8000 --target-port=80 --type=NodePort
那么两者道理有什么区别呢?如下图:
ClusterIP 只能在内网访问(ServiceIp 是在内网暴露的IP ), 而 NodePort 会在节点随机暴露一个端口,然后可以使用节点IP进行外网访问。(默认 k8s 随机暴露的端口在 30000 ~ 32767 之间)