【云原生 • Kubernetes】(五)学了这么久的 Kubernetes 终于可以访问 Pod 了!!

2,947 阅读7分钟

📣 大家好,我是Zhan,一名个人练习时长一年半的大二后台练习生🏀

📣 这篇文章是学习 Kubernetes第五篇学习笔记📙

📣 如果有不对的地方,欢迎各位指正🙏🏼

📣 与君同舟渡,达岸各自归🌊


🔔 引语

在上篇文章【云原生 • Kubernetes】(四) k8s 原来不是直接创建 Pod!! - 掘金 (juejin.cn)中,我们讲解了 Kubernetes 中 四种Controller 的使用,了解到了,是 Controller 让 Pod 有了 运维的能力 以及更好的 管理,不过在文章末尾处我也提到了:Pod 无法提供网络服务、以及实现负载均衡,因此为了让 Pod 提供对外的网络访问,本文将会讲解 Service

  • 什么是 Service 以及 Service 的作用与特性
  • Service 与 Pod 之间又是什么样的关系
  • 如何使用和配置 Service
  • Service 有哪些类型

1️⃣ 什么是 Service

官网地址:kubernetes.io/zh-cn/docs/…

1.1 定义

官网给出的定义是:Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法

通俗来讲,Service 是为 Pod 提供网络服务的一种方式

1.2 为什么需要 Service

在上文中我们也提到了,仅仅靠控制器无法提供网络服务,如果一组 Pod(例如 MySQL) 为集群内的其他的 Pod(Java) 提供服务,那么 Java 如何找到 MySQL 的 IP 地址,如果 MySQL 具有多个副本,又当如何呢?

有点类似于 SpringCloud 中的 注册中心,front pod 无需关心它们调用了哪个 backend pod,如果 backend pod 发生了何种变化,也无需 front pod 知情,Service 定义的抽象能够做到这种解耦。

1.3 Service 与 Ingess 的区别

ServiceIngressKubernetes 中用于管理和公开应用程序的两个重要概念,它们有着不同的作用和功能。

  • Service 是 Kubernetes 中的一种抽象,Service 允许应用程序内部的各个组件(Pod)能够通过Service名称和端口号来相互通信,而不需要直接暴露Pod的IP地址。
  • Ingress 是 Kubernetes 中的一种资源对象,Ingress可以将外部的HTTP请求路由到 Kubernetes 集群内部的Service,从而实现从集群外部访问应用程序的能力
  • 简而言之:
    • Service 用于在Kubernetes 内部 管理和访问应用程序的不同组件
    • Ingress 用于从集群 外部 公开应用程序的路由和访问方式
  • 通常情况下,Ingress会使用一个反向代理来处理外部的请求,并将其转发到相应的Service上

2️⃣ 特性

  • Pod 通过 Label 与 Service 进行关联。这与 Controller 中的 Selector 一样,通过标签进行筛选。
  • Service 生命周期与 Pod 无关,不会因为 Pod 的重新创建而改变 IP。无论 Service 关联的 Pod 如何增缩,它的 IP 都不会变化。
  • Service 提供了一种逻辑上的稳定网络端点,它可以将 请求负载均衡 到后端的多个Pod实例上,从而实现应用程序的高可用性和扩展性。
  • 可以对集群外部提供访问端口。只是方便测试,在上面我们说的是通常使用情况,一般我们不会这么去用。
  • 集群内部可以通过服务名字进行访问,不需要直接暴露Pod的IP地址。

3️⃣ 使用 Service

3.1 配置文件

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: nginx  
  labels:  
    app: nginx  
spec:  
  replicas: 3  
  template:  
    metadata:  
      name: nginx  
      labels:  
        app: nginx  
    spec:  
      containers:  
        - name: nginx  
          image: nginx:1.7.9  
          imagePullPolicy: IfNotPresent  
          ports:  
            - containerPort: 80  
      restartPolicy: Always  
  selector:  
    matchLabels:  
      app: nginx  
---  
apiVersion: v1  
kind: Service  
metadata:  
  name: nginx  
spec:  
  # 通过标签进行筛选
  selector:  
    app: nginx  
  ports:  
	  # Service 的端口
    - port: 80  
	  # Pod 的端口,也就是 Container 中应用服务的端口
      targetPort: 80  
      # 暴露外部服务的端口,如果不写会自动分配,固定在 30000-32767 
      nodePort: 30080  
      # 通信协议:TCP / UDP
      protocol: TCP  
  # Service 的类型,NodePort 代表公开NGINX应用程序
  type: NodePort

3.2 配置解释

在spec部分:

  • selector 指定了Service将路由到具有标签 app: nginxPod
  • ports 定义了Service的端口配置,这里将容器端口 80 映射到 Service 的端口 80。同时指定了 NodePort30080,表示该 Service 将在所有节点上的30080端口上公开。
  • protocol 设置为 TCP,表示使用 TCP协议 进行通信。
  • 最后,Service的 type 设置为 NodePort,表示使用NodePort类型的Service来公开NGINX应用程序。

3.3 测试使用

至此,成功创建好一个 Service,我们可以做到:

  • 在同一个命名空间下的其他容器,可以通过 curl Service的IP:port 访问到 Pod 的 targetPort
    • 查看 Service 的 IP 的方法:kubectl get services -o wide
    • 可以创建一个 busybox:1.28 去进行测试,使用命令 wget Service的IP:80,就可以拉取到 index.html
  • 在容器外部访问该Service对应的Pod,可以访问 节点IP:NodePort 访问到 Nginx 的 Index.html
    • 查看 Pod 在哪个结点上:kubectl get pods -o wide,拿到该节点所在的服务器的公网 IP
    • 浏览器访问:http://节点IP:30080 就可以访问到 index.html

3.4 负载均衡

为了验证访问 Service 是否会有负载均衡,我们分别进入这三个容器:

  • 修改它们的 Index.html 分别为:Nginx-01、Nginx-02、Nginx-03
  • 然后在某个节点不断的使用命令访问:curl Service的IP:port,这里我们可以看到他们三者都会出现

4️⃣ 类型 type

上文中我们演示的类型为:NodePod,表示使用NodePort类型的Service来公开NGINX应用程序。而 type 其实有四种类型:

  • ClusterIP : 在集群内部暴露 Service,只能被集群内部的其他对象访问,通常用于内部服务发现,不会向集群外部访问。
    • 比如在一个 Web 应用中,你可能需要连接到一个数据库,但是这个数据库并不需要在应用之外暴露,这时就可以使用 ClusterIP 类型的 Service,让应用可以访问到数据库。
  • NodePort : 将 Service 暴露在 Node 的某个端口上,从而可以通过 Node 的 IP 和 端口号来访问 Service,通常用于开发和测试环境
  • LoadBalancer : 通过云服务提供的负载均衡器来将 Service 暴露到公网上,使得外部用户可以访问 Service
    • 适用于需要将应用程序公开给公共互联网,或者需要通过云平台提供的负载均衡器来处理流量分发的情况。
  • ExternalName : 将 Service 映射到一个 DNS 名称上,从而可以通过 DNS 名称来访问 Service,通常用于外部访问服务
    • 适用于需要将Service名称解析为外部DNS名称的情况,例如连接到集群外部的数据库或其他服务。

💬 总结

为了解决 Controller 无法提供网络服务、以及实现负载均衡的问题,Service 应运而生,实现了 Pod 之间的通信,通过Service名称和端口号来相互通信,而不需要直接暴露Pod的IP地址,与 Ingress 之间的区别也要记住,Controller 是 内部 管理和访问应用程序的不同组件,Ingress 是 外部 公开应用程序的路由和访问方式。


🍁 友链


✒ 写在最后

都看到这里啦~,给个点赞再走呗~,也欢迎各位大佬指正以及补充,在评论区一起交流,共同进步!也欢迎加微信一起交流:Goldfish7710。咱们明天见~