关于后端:service-2-暴露服务的-3种-方式

3次阅读

共计 4385 个字符,预计需要花费 11 分钟才能阅读完成。

【k8s 系列】k8s 学习十九,service 2

之前咱们简略的理解一下 k8s 中 service 的玩法,明天咱们来分享一下 service 波及到的相干细节,咱们开始吧

为什么要有 服务 Service?

因为服务能够做到让内部的客户端不必关怀服务器的数量,服务外部有多少个 pod,也能够失常连贯到服务器,并能够失常进行业务解决

咱们能够举一个例子,客户端 –> 前端 –> 后盾

客户端将流量打到前端的 Service 上,前端的 Service 会将流量给到任意一个 pod 下面,而后 流量进而打到后盾服务的 Service 上,最终申请到后盾服务的任意 pod 下面

这个时候,客户端无需晓得到底是哪个 pod 提供的服务,也无需晓得提供 pod 的地址,只须要晓得前端服务的 地址和端口即可

新建一个 demo 服务

咱们能够简略些一个 Service 的 yaml 文件,而后部署起来,对于 Service 资源管控哪一些 pod,咱们依然是应用 标签来进行管控的

例如咱们的 minikube 环境中有这样 3 个 标签为 appxmt-kubia 的 pod

咱们能够这样写 Service 清单:

kubia-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: kubia-service
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: xmt-kubia

此处的 selector 选择器,和后面咱们说到的 ReplicaSet 的做法是统一的,此处是 Service 裸露一个 80 端口,映射到 pod 的 8080 端口

咱们也能够裸露多个端口,然而裸露多个端口的话,必须要写 name,例如这样

运行 kubectl create -f kubia-service.yaml,部署一个 Service 资源

kubectl get svc 能够看到如下 svc 的资源列表

能够通过在 pod 外部拜访 svc 的 ip 来查看是否能够申请胜利

通过命令选中任意 pod,在 pod 中执行 curl 命令,申请 http 接口

kubectl exec kubia-rs-sxgcq -- curl -s 10.106.228.254

果然是能够申请通过的

当然,咱们也是能够通过齐全进入到 pod 外部,来拜访 Service 的地址

kubectl exec -it kubia-rs-sxgcq -- /bin/sh

此处的 Cluster IP意思是集群外部的 IP,只用于在集群外部进行拜访的,以后咱们创立的服务的目标就是,集群外部的其余 pod,可能通过拜访这个 Service 的 IP 10.106.228.254 来拜访 该 Service 管控的一组 pod

通过日志,咱们能够看出实际上申请胜利了的,咱们应用任意一个 pod,来申请 Service,而后 Service 来将流量打到本人管控的一组 pod 中,最终失去响应,能够画个图了解一波

Endpoint

看了下面 Service 和 pod 的关系,给人的感觉是不是 Service 和 pod 如同是直连的,其实并不是这样的,其实 他俩之间还有一个要害的资源,那就是 Endpoint

Endpoints 这个资源就是裸露一个服务的 IP 地址和端口的列表

kubectl get endpoints kubia-service

Endpoints: 172.17.0.6:8080,172.17.0.7:8080,172.17.0.8:8080

如上咱们能够看到 Endpoints 裸露了服务的 IP 地址和端口列表

当有客户端连贯到服务的时候,服务代理就会抉择这些 IP 和 端口 对中的一个发送申请

裸露服务

下面的做法都是在 k8s 集群外部裸露服务的 IP,这个 IP 是虚构 IP,只能在集群外部拜访,且须要拜访对应的端口才行

那么,咱们如何裸露服务的端口,供内部的客户端,或者是内部的服务进行调用呢?

相似于这样的申请

对于 Service 资源裸露的形式有如下 3 种:

  • NodePort
  • LoadBalance
  • Ingress

三种形式各有优劣,上面咱们来具体的看看

service 之 NodePort

NodePort,看到命名咱们就能够晓得是在每个集群节点都会关上一个端口,内部客户端能够拜访集群节点的 IP + PORT 就能够拜访到咱们裸露的服务,进而能够将流量申请到 服务管控的一组任意 pod 上

咱们能够看看以后我的试验环境的 service 类型

上述 service 类型都是 Cluster IP 的,因而,咱们须要将现有 svc 批改成 NodePort 或者从新创立一个新的 service,就能够把这里的 TYPE 设置为 NodePort

编写 NodePort 类型的 Service

kubia-service-nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: kubia-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 31200
  selector:
    app: xmt-kubia
  • 编写根本的 NodePort 类型的 Service 资源清单

    • 指定服务类型为 NodePort
    • 留神此处是 ports,也就是说能够配置多个端口映射,咱们也能够裸露多个端口,之前的文章有说到,裸露多个端口的时候,是须要写 name 的,name 记得须要合乎 k8s 的命名标准
    • 指定裸露的端口为 31200(内部客户端通过 IP + 31200 就可能拜访到服务治理的一组 pod 的,pod 的端口是 8080)
    • 留神,如果这里不指定 nodePort 端口,那么 k8s 会随机调配一个端口,默认端口范畴是 30000 – 32767,咱们也能够批改 k8s 默认端口范畴,批改地位为:/etc/kubernetes/manifests/kube-apiserver.yaml

运行后查看成果

这个时候,该服务曾经裸露了 31200 端口了,咱们能够在咱们的 window 上通过 telnet ip port 的形式来拜访咱们这台云服务试验环境,然而请记得在云服务器的防火墙处关上 31200 端口

咱们通过内部客户端申请工作节点的 IP + 裸露的 port,是这样的流程:

内部客户端流量从节点的 31200 端口打入,会被重定向到 service 管控的一组任意 pod 上

service 之 LoadBalance

咱们能够想一下下面的 NodePort 的形式有什么毛病?

下面裸露了服务的端口,然而咱们拜访的时候须要指定工作节点的 ip + port,如果咱们指定的工作节点呈现了故障,那么内部客户端申请服务就会呈现无响应,除非客户端晓得其余失常工作节点的 IP

因而,这个时候,负载均衡器就上场了

创立 LoadBalance 类型的 服务,只须要将上述 NodePort 的资源清单中 type: NodePort 批改成 type: LoadBalance 即可

LoadBalance

LoadBalance 负载均衡器,咱们能够放在节点的后面,确保内部客户端发送的申请可能发送到衰弱的节点上,并且相对不会将内部的申请发送到状态异样的工作节点上

应用 LoadBalance 之后,上述的流程就变成了这个样子的:

这个时候,对于客户端,只须要拜访固定的 IP + port 就能够轻松的拜访到衰弱的工作节点上的 pod 了

service 之 Ingress

当初咱们一起来看看裸露服务的第三种办法,应用 ingress 控制器

为什么要有 ingress?

往上面看,应用 LoadBalance 的时候,LoadBalance 须要一个公网的 IP,且只能提供给一个 Service

那么如果是有多个 Service 的时候,咱们就要部署多个 LoadBalance 负载均衡器 了,因而 ingress 就出马了

ingress 能够做什么呢?

ingress 能够做到只须要一个公网 IP,就能够为多个 Service 提供准入和拜访,咱们能够了解为 ingress 像 nginx 一样通过路由来辨认给多个服务的申请

简略流程能够是这个样子的:

这样,应用 ingress 就比应用 LoadBalance 要不便多了,然而具体应用的时候,还是看本人的需要是什么,来抉择适合的形式

写一个 ingress 的 demo

写 ingress demo 之前,咱们先确认咱们试验环境中 是否开启了 ingress 控制器

minikube addons list

我的环境是开启的,如果没有开启的话,能够执行命令开启 ingress 管制

minikube addons enable ingress

开启时候,咱们能够查看到有对于 ingress 的 pod

kubectl get po --all-namespaces

开始创立 ingress 资源

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: hello.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubia-nodeport-svc
            port:
              number: 80
  • ingress 资源,填写的 apiVersion 为 networking.k8s.io/v1,如果 k8s 是 1.17 之前的,那么 apiVersion 须要填写 extensions/v1beta1
  • ingressClassName: nginx 指定规定会退出到 nginx 中
  • rules,咱们能够看出这个规定是能够增加多条的,这也证实了 ingress 是能够通过多个路由来给多个服务提供拜访的

创立 ingress 资源,查看成果

当初,咱们就能够在任意客户端(前提是可能拜访的通 k8s 这台机器或集群),配 置一下本地 host,hello.example.com 指向 ingress 的 ip 即可

配置实现后,客户端能够向 hello.example.com 发动申请了,能够欢快地游玩

咱最初来看看内部客户端拜访 ingress 地址后原理是怎么的?

如上图,咱们能够看出,内部客户端拜访域名:hello.example.com

  • 内部客户端先去找 DNS 拿到 hello.example.com 对应的 IP(ingress 控制器的 ip)
  • 客户端向 ingress 控制器 发送 http 申请,host 中会带上 域名,ingress 会去查问 该域名对应的服务(找 ingress 资源查),进而找到 endpoint ip 和 port 映射列表
  • 最终 ingress 控制器,间接把流量打到 service 管控的一组任意 pod 下面

这里的流量是 ingress 控制器间接打到 pod 上,而不是通过 service 转发

明天就到这里,学习所得,若有偏差,还请斧正

欢送点赞,关注,珍藏

敌人们,你的反对和激励,是我保持分享,提高质量的能源

好了,本次就到这里

技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。

我是 阿兵云原生,欢送点赞关注珍藏,下次见~

正文完
 0