Kubernetes 服务发现使用介绍
一、基本介绍
二、Kubernetes 服务发现使用介绍
1.ClusterIP
2.Headless Service
3.NodePort
一、基本介绍
Kubernetes 中 Pod 是有生命周期的,每个 Pod 都有属于自己的 IP 地址。 但是当我们创建和删除 Pod 时,它的 IP 地址并不是固定的。那么也就是说,当我们把 Pod 的 IP 提供给前端应用时,服务不可用的几率相当较大。官方说明
不过呢,Kubernetes 定义了一种 Service 资源,每个 Service 都有一个固定的 VIP 地址。我们可以 通过标签匹配的方式,来将 Service 自动的绑定到合适的 Pod 应用上,并且当我们请求 Service 时,它还会将请求转发到后端的 Pod 应用。
- 每个 node 主机上都会运行 Kube-Proxy 组件,并通过 APIServer 来实时监控 Service 和 Endpoints 服务。
- 当用户创建出含有标签选择器的 Service 时,Endpoints 也会随着创建出来,用来存放 Service 匹配到 Pod 的 IP 地址。
- Kube-Proxy 监控到 Service 和 Endpoints 发生改变后,将会对 iptables 或 ipvs 进行规则配置(来实现基于四层的路由转发)
- 最终,用户通过 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 并不会将这个无头服务加入到 iptables 或 ipvs 规则中。不过,我们可以通过在容器内部,以域名的方式去访问。如上图,我们使用 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