编辑
2023-06-11
K8S
00
请注意,本文编写于 591 天前,最后修改于 591 天前,其中某些信息可能已经过时。

目录

1.什么是 Service
2.为什么需要 Service
3.特性
4.Service 和 Pod 关系
5.使用 Service
6.多端口
7.类型 type
7.1 ClusterIP 类型
7.2 NodePort 类型
7.3 LoadBalancer 类型
7.4 ExternalName 类型
8.内部通信

1.什么是 Service

官网地址: https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/

将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。

通俗定义: Service 用来为 pod 提供网络服务的一种方式。

2.为什么需要 Service

问题: 如果一组 Pod(称为“后端”)为集群内的其他 Pod(称为“前端”)提供功能, 那么前端如何找出并跟踪要连接的 IP 地址,以便前端可以使用提供工作负载的后端部分?

image.png

如果这是一个图片处理后端,它运行了 3 个副本。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态。Service 定义的抽象能够解耦这种关联

image.png

3.特性

  • Service 通过 label 关联对应的 Pod
  • Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重新创建而改变 IP
  • 提供了负载均衡功能,自动转发流量到不同 Pod
  • 可对集群外部提供访问端口
  • 集群内部可通过服务名字访问

4.Service 和 Pod 关系

image.png

5.使用 Service

yml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 1 template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 imagePullPolicy: IfNotPresent ports: - containerPort: 80 restartPolicy: Always selector: matchLabels: app: nginx --- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - port: 8080 #service 端口 targetPort: 80 #容器端口 nodePort: 31001 #node 节点端口 固定在 30000-32767 之间 type: NodePort

image.png

解释

访问外网nginx,根据分配的node节点ip再去根据对外开放的31001端口去访问,根基我的虚拟机有两个node节点128和129,访问这两个node节点的ip+31001端口都可以访问。

6.多端口

yml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 1 template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 imagePullPolicy: IfNotPresent ports: - containerPort: 80 restartPolicy: Always selector: matchLabels: app: nginx --- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - port: 8080 #service 端口 name: write targetPort: 80 #容器端口 nodePort: 31001 #node 节点端口 固定在 30000-32767 之间 - port: 8081 name: read targetPort: 80 nodePort: 31002 type: NodePort

访问31002或31001端口都可以。

7.类型 type

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/

对一些应用的某些部分(如前端),可能希望将其暴露给 Kubernetes 集群外部的 IP 地址。

Kubernetes ServiceTypes 允许指定你所需要的 Service 类型。

  • ClusterIP:在集群内部暴露 Service,只能被集群内部的其他对象访问,通常用于内部服务发现,不会向集群外部暴露。
  • NodePort:将 Service 暴露在 Node 的某个端口上,从而可以通过 Node 的 IP 地址和端口号来访问 Service,通常用于开发和测试环境。
  • LoadBalancer:通过云服务商提供的负载均衡器来将 Service 暴露到公网上,使得外部用户可以访问 Service。
  • ExternalName:将 Service 映射到一个 DNS 名称上,从而可以通过 DNS 名称来访问 Service,通常用于访问外部服务。

7.1 ClusterIP 类型

  • 这是最常用的 Service 类型之一。在集群内部创建一个虚拟 IP 地址,它可以被其他在同一集群内的 Pod 访问,但不能被集群外部的请求所访问。这种类型的服务通常用于内部服务的暴露,例如数据库或者缓存服务。比如在一个 Web 应用中,你可能需要连接到一个数据库,但是这个数据库并不需要在应用之外暴露。这时候,你可以使用 ClusterIP 类型的 Service,让应用可以访问到数据库。

7.2 NodePort 类型

  • 这种类型的 Service 将会创建一个端口,并绑定到每个集群节点上,从而允许外部流量访问 Service。这个类型通常用于公共服务的暴露,例如 Web 应用或者 API。比如你需要在集群外部访问到一个运行在集群中的 Web 应用,你就可以创建一个 NodePort 类型的 Service,通过指定 Service 的 nodePort 字段,来将 Service 暴露给集群外部。

  • 如果你将 type 字段设置为 NodePort,则 Kubernetes 控制平面将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)。

7.3 LoadBalancer 类型

  • 这种类型的 Service 类似于 NodePort,但是会在云厂商中创建一个负载均衡器。这个类型通常用于在云平台上部署应用。云平台的负载均衡器将流量分发到集群中的节点。这个类型的 Service 只能在云平台上使用,并且需要云厂商提供支持。

7.4 ExternalName 类型

  • 这种类型的 Service 允许 Service 到任何需要访问的 CNAME DNS 条目的转发。与其它类型的 Service 不同,它并不会代理请求到任何 Pod。相反,它将请求转发到配置的外部地址。这种类型的 Service 通常用于将服务代理到集群外部的其他服务。比如你有一个运行在外部网络上的服务,你希望在 Kubernetes 集群中使用该服务,这时候你可以创建一个 ExternalName 类型的 Service,将服务的 DNS 解析到 Kubernetes 集群中。

8.内部通信

yml
apiVersion: apps/v1 kind: Deployment metadata: name: mysql labels: app: mysql spec: selector: matchLabels: app: mysql replicas: 1 template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql/mysql-server:8.0 env: - name: MYSQL_ROOT_PASSWORD value: root ports: - name: mysql containerPort: 3306 --- apiVersion: v1 kind: Service metadata: name: mysql spec: selector: app: mysql ports: - name: mysql port: 3306 targetPort: 3306 type: ClusterIP
yml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: hostNetwork: true containers: - name: nginx image: nginx:latest #command: ["/bin/sh", "-c"] #args: #- apt-get update && apt-get install -y mysql-client && nginx -g 'daemon off;' ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - name: http port: 8081 targetPort: 80 type: ClusterIP
  1. 进入 nginx 访问mysql
  2. mysql -h mysql -uroot -ppassword
  3. 注意:这里的 mysql 是 MySQL Service 的名称,而不是 Pod 的名称。

本文作者:松轩(^U^)

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

Document