Kubernetes 服务发现使用介绍

Posted 愿许浪尽天涯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes 服务发现使用介绍相关的知识,希望对你有一定的参考价值。

Kubernetes 服务发现使用介绍

一、基本介绍

Kubernetes 中 Pod 是有生命周期的,每个 Pod 都有属于自己的 IP 地址。 但是当我们创建和删除 Pod 时,它的 IP 地址并不是固定的。那么也就是说,当我们把 Pod 的 IP 提供给前端应用时,服务不可用的几率相当较大。官方说明

不过呢,Kubernetes 定义了一种 Service 资源,每个 Service 都有一个固定的 VIP 地址。我们可以 通过标签匹配的方式,来将 Service 自动的绑定到合适的 Pod 应用上,并且当我们请求 Service 时,它还会将请求转发到后端的 Pod 应用。

  1. 每个 node 主机上都会运行 Kube-Proxy 组件,并通过 APIServer 来实时监控 Service 和 Endpoints 服务。
  2. 当用户创建出含有标签选择器的 Service 时,Endpoints 也会随着创建出来,用来存放 Service 匹配到 Pod 的 IP 地址。
  3. Kube-Proxy 监控到 Service 和 Endpoints 发生改变后,将会对 iptablesipvs 进行规则配置(来实现基于四层的路由转发)
  4. 最终,用户通过 Kube-Proxy 提供的路由转发,来实现服务的映射访问。

上面其实是针对于 Pod 应用的,还有一种情况是 Pod 要访问外部的应用,如:现在有三台主机组成的一个 RabbitMQ 集群。此时 Pod 访问其中任意一台主机的 RabbitMQ 服务都是可以的,但是这样的话并没有冗余性。

所以我们可以通过直接 创建出 Service,但不给它配置标签选择器。这样的话,Endpoints 也就不会自动的创建出来。 接下来,我们便可以自定义的来创建 Endpoints,这里我们只需要将 Endpoints 名称和 Service 名称配置成一样的即可。

Service,Endpoints 与 Pod 的关系:

二、Kubernetes 服务发现使用介绍

[root@k8s-master01 ~]# vim nginx-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-web
  labels:
    app: nginx
spec:
  containers:
  - name: nginx-web
    image: nginx:1.18.0
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: index
  volumes:
  - hostPath:
      path: /app/nginx/html
    name: index
[root@k8s-master01 ~]# mkdir -p /app/nginx/html && echo "This is Nginx:80" > /app/nginx/html/index.html
[root@k8s-master01 ~]# kubectl create -f nginx-web.yaml

1.ClusterIP

通过使用 K8s 内部定义的 IP 地址,来实现集群内部的服务访问(因为是在内部定义的,所以在外部并不能直接访问)

[root@k8s-master01 ~]# vim nginx-web-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-web
spec:
  type: ClusterIP							# Service 的默认类型
  ports:
  - name: nginx-web
    port: 8080								# Service 的显示端口
    targetPort: 80							# Pod 的服务端口
  selector:
    app: nginx
[root@k8s-master01 ~]# kubectl create -f nginx-web-svc.yaml

验证:

2.Headless Service

无头服务,主要适用于那种不需要 ClusterIP 的服务,通过配置标签选择器,CoreDNS 便可以将 Service 的名称解析到 Pod 应用上。

[root@k8s-master01 ~]# vim nginx-web-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-web
spec:
  ports:
  - name: nginx-web
    port: 8080
    targetPort: 80
  clusterIP: "None"
  selector:
    app: nginx
[root@k8s-master01 ~]# kubectl create -f nginx-web-svc.yaml


因为 CoreDNS 组件主要就是用来给 Service 提供一个域名和 IP 的对应解析关系,但是我们这里配置的无头服务,也就是说这个 Service 并没有提供 ClusterIP 地址。所以我们下面解析的时候,直接就解析到 Service 匹配到的 Pod 应用上。

需要了解的是,当我们配置的是无头服务时,Kube-Proxy 并不会将这个无头服务加入到 iptablesipvs 规则中。不过,我们可以通过在容器内部,以域名的方式去访问。如上图,我们使用 nc 命令判断容器到 nginx-web 域名的连通性是正常的。

3.NodePort

通过在所有的 node 主机上映射一个端口,之后便可以通过任意一台 node 主机的 IP 地址和映射端口 来路由到 Service 上。

[root@k8s-master01 ~]# vim nginx-web-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-web
spec:
  type: nodePort
  ports:
  - name: nginx-web
    port: 8080
    targetPort: 80
    nodePort: 30080
  selector:
    app: nginx
[root@k8s-master01 ~]# kubectl create -f nginx-web-svc.yaml


Service 除了上面那几种类型,还可以使用 LoadBalancer 和 ExternalName 类型。

  • LoadBalancer:在 NodePort 基础上,通过借助 Cloud Provider(云厂商)来创建外部负载均衡器,并将请求转发到 NodePort 上。
  • ExternalName:用于将集群外部的服务引入到集群内部中,从而达到可以在集群内部直接使用(通过 CoreDNS 实现)
[root@k8s-master01 ~]# vim nginx-web-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-web
spec:
  type: ExternalName
  ports:
  - name: nginx-web
    port: 80
    targetPort: 80
    externalName: www.baidu.com
[root@k8s-master01 ~]# kubectl create -f nginx-web-svc.yaml

以上是关于Kubernetes 服务发现使用介绍的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes-Service介绍-服务发现

K8S/Kubernetes组件介绍

01-Kubernetes介绍,基础组件,原理,架构。

kubernetes资源对象介绍及常用命令

Kubernetes in Action 5 服务:让客户端发现pod并与之通信

Kubernetes in Action 5 服务:让客户端发现pod并与之通信