了解Kubernetes中的Service和Endpoint

目录
  • Srevice
  • Service 的创建及现象
  • Service 定义
  • Endpoint slices
  • 创建 Endpoint、Service
    • Service
    • 创建应用
    • 创建 Endpoint

Srevice

Service 是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。如果我们使用 Deployment 部署 pod,则可以以 Deployment 为对象创建 Service。

在 K8S 中,每个 Pod 都有其自己唯一的 ip 地址,而 Service 可以为多个 Pod(一组)提供相同的 DNS 名,并且可以在他们直接进行负载均衡。

假如有一组 nginx pod,如果 nginx 动态伸缩改变或因为某些原因 ip/端口发生改变,那么其 ip 和 端口都不是固定的,而且我们很难确定它新扩容的 pod 的地址是什么,又万一 pod 被删除,ip 不再可用。

又假如一组 pod 称为前端,如 web 服务,另一组 pod 称为后端,例如 mysql。那么 前端 如何查找并跟踪要连接的 ip 地址,以便前端可以使用工作负载的后端部分?

这真是 Service 要解决的问题。Kubernetes Service 定义了一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。当使用 Service 为一组 pod (Deployment 的方式创建的)创建服务时,无论我们创建了多少个 pod 副本,这些 pod 怎么变化,前端不需要关心它们调用了哪个后端副本,而且不需要知道后端 pod 的状态也不需要跟踪 pod。Service 把前后端的这种关联抽象化,把它们解耦了。

Service 的创建及现象

现在按照下面的命令快速创建 pod,pod 将会在各个节点中部署运行。

kubectl create deployment nginx --image=nginx:latest --replicas=3
kubectl expose deployment nginx --type=LoadBalancer --port=80

然后执行命令查看 Service:

kubectl get services

也就是说外部访问端口是 30424。

NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        3d6h
nginx        LoadBalancer   10.101.132.236   <pending>     80:30424/TCP   39s

这时,我们可以通过公网和端口访问这个 Service。

我们可以查看此 Service 的 yaml 文件:

kubectl get service nginx -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-04-23T07:40:35Z"
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "369738"
  uid: 8dc49805-2fc8-4407-adc0-8e31dc24fa79
spec:
  clusterIP: 10.101.132.236
  clusterIPs:
  - 10.101.132.236
  externalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 30424
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer: {}

有了标准的 yaml 文件模板,我们可以很方便地修改并定制一个 Service。

我们查看通过 Deployment 创建的 pod:

kubectl get pods -o wide
NAME                        IP              NODE       NOMINATED NODE   READINESS GATES
nginx-55649fd747-9fzlr    192.168.56.56    instance-2   <none>           <none>
nginx-55649fd747-ckhrw    192.168.56.57    instance-2   <none>           <none>
nginx-55649fd747-ldzkf    192.168.23.138   instance-1   <none>           <none>

注:pod 在哪个节点中运行,我们是不一样的。

当我们通过外部网络访问时,Service 会自动提供其中一个 pod 给我们,但是这个过程较为复杂,我们这里先将表面现象。

               ------------
               |          |
--- 公网ip -->  |   pod1   |
               |   pod2  |
               |   pod3  |
               ------------

然后我们通过命令查看 iptables 配置:

iptables-save

然后查找 random 关键字:

你可以看到有三个 default/nginx, 第一个 pod 被访问的机会都是 0.33333...,然后 2/3 的概率中,2/3 的 0.5 的概率选择第二个 pod,剩下的 1/3 概率选择第三个 pod。

如果要访问 pod,可以以任意部署了 nginx pod 的节点的 ip 进行访问。由于 master 不能部署 pod,所以不能通过 master 的 ip 进行访问。

当然,它并不是直接都是 0.33333.. 这样的,iptables 的规则有点复杂,这里难以讲清楚,我们只需要知道 外网能够访问 Service,而 Service 通过 iptable 为我们转发流量。即使 Deployment 部署的 pod 不在同一个节点上, k8s 的 dns 服务等会正确处理的,我们不需要手动配置这些网络。

Service 定义

在上一小节中,介绍了 Service 的创建方法(kubectl expose ...),也介绍了其依赖的 iptables,这里将继续学习 Service 的定义方法。

因为之前我们是通过 Deployment 进行操作,直接为一个 deployment 中的 pod (副本)统一映射。当然我们也可以为不同的 pod 进行网络映射。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 6666
      targetPort: 80

这里我们使用了 selector 选择器,一般 pod 的 Label 都会有 app,表示此 pod 的名称(一般是镜像名称)。port、targetPort 分别是 pod 端口、提供给外界访问的端口。

当我们不通过 Deployment 或者 job 等对象处理 pod 时,可以通过 selector 来选择合适的 pod。

Service 能够将一个接收 容器或者 pod 的端口 targetPort 映射到任意的 port 端口,port 是外部可以访问的端口。 如果使用 kubectl expose 去映射端口,会默认随机提供一个 30xxx 端口。而使用 yaml ,默认情况下,targetPort 将被设置为与 port 字段相同的值。

Endpoint slices

”端点切片(Endpoint Slices) 提供了一种简单的方法来跟踪 Kubernetes 集群中的网络端点 (network endpoints)。它们为 Endpoints 提供了一种可伸缩和可拓展的替代方案。“

在 Kubernetes 中,EndpointSlice 包含对一组网络端点的引用。 指定选择器后控制面会自动为设置了 选择算符 的 Kubernetes 服务创建 Endpoint。

也就是说创建 Service(带选择运算符) 会自动创建 Endpiont。

我们查看默认命名空间的 endpoint:

kubectl get endpoints
NAME         ENDPOINTS                                            AGE
kubernetes   10.170.0.2:6443                                      3d7h
nginx        192.168.56.24:80,192.168.56.25:80,192.168.56.26:80   59m

这些都是 pod 的 ip 和端口,也就是说,通过 Endpoint 我们跟踪 Kubernetes 集群中的网络端点 (network endpoints)变得更加任意。不过这样解释是很难明白的,笔者翻了很多次资料,一点点试错才搞懂。接下来我们一步步来上手操作,然后一点点理解这些操作的含义。

创建 Endpoint、Service

接下来我们手动创建 Service 和 Endpoint 和 ,需要先创建 Service ,再创建 Endpoint (这两者创建顺序可以随意)。

Service

我们先删除之前创建的 service。

kubectl delete service nginx

编写 service.yaml 文件内容如下如下:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - protocol: TCP
      port: 6666
      targetPort: 80

应用这个 Service:

kubectl apply -f service.yaml

查看 service :

kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   3d12h
nginx        ClusterIP   10.98.113.242   <none>        6666/TCP    6s

由于此 Service 没有映射任何 pod 等,因此没有任何用处,但是此时已经可以给开发人员一个交待了,或者说确定下 nginx 的 Service 端口和地址。至于真正的 nginx 服务,后面再确定。创建 Service 和 Endpoint 的顺序是任意的,只是这里我们提出抽象,先约定 端口,再提供服务,所以先创建 Service。

创建应用

我们随便找台 worker 或者 master 节点,创建一个 nginx 容器:

docker run -itd -p 80:80 nginx:latest

为什么不用 pod,直接创建容器?因为我们处于开发阶段,如果把 nginx 改成 mysql,我们要 Debug 呢?测试自己的数据库呢?要模拟数据呢?我们在生产时再通过 Deployment 创建应用,但是此时我们可以使用自己的数据库或者本地应用。

官方文档说:

  • 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
  • 希望服务指向另一个 名字空间(Namespace) 中或其它集群中的服务。
  • 你正在将工作负载迁移到 Kubernetes。 在评估该方法时,你仅在 Kubernetes 中运行一部分后端。

总之,我们创建了 Service,可以提供了抽象,至于怎么提供这个服务,我们可以使用 pod ,也可以直接使用命令执行机器上的二进制程序,也可以通过 docker 提供。而且 mysql 可能是在外部服务提供的,或者 mysql 直接部署在宿主机上,而不使用容器和 pod,我们可以通过 Endpoint 来跟踪 mysql 服务的端口。

然后查询这个容器的 ip,:

docker inspect {容器id} | grep IPAddress

笔者得到的是:"IPAddress": "172.17.0.2",可以试试 curl 172.17.0.2 ,看看是否能够访问 nginx,如果没问题我们来进行下一步。

创建 Endpoint

创建一个 endpoint.yaml 文件,内容如下(注意替换ip为你容器访问ip):

apiVersion: v1
kind: Endpoints
metadata:
  name: nginx
subsets:
  - addresses:
      - ip: 172.17.0.2
    ports:
      - port: 80

然后应用 yaml:

kubectl apply -f endpoint.yaml

查看 endpoint:

kubectl get endpoints
# 不能填写成 endpoint

然后访问 Service 的 ip:

curl 10.99.142.242:6666

也可以通过公网访问此 IP。

如果 Endpoint 需要跟踪多个 ip (多个 pod 或者容器或者应用),可以使用:

  - addresses:
      - ip: 172.17.0.2
      - ip: 172.17.0.3
      - ip: 172.17.0.4
      ... ...

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 配置Kubernetes外网访问集群

    查询 Service 关于 Service,读者可以查看官方文档的资料:https://kubernetes.io/zh/docs/concepts/services-networking/service/ Service 是 k8s 中为多个 pod 公开网络服务的抽象方法.在 k8s 中,每个 pod 都有自己的 ip 地址,而且 Service 可以为一组 pod 提供相同的 DNS ,使得多个 pod 之间可以相互通讯,k8s 可以在这些 pod 之间进行负载均衡. 查询 pod: ku

  • Kubernetes控制节点的部署

    标签和nodeSelector 标签(Label)是附加到 Kubernetes 对象上的键值对,如果用 json 表示附加到 metadata 的 label: "metadata": { "labels": { "key1" : "value1", "key2" : "value2" } } yaml: metadata: labels: key1: "value1&quo

  • Kubernetes集群的组成介绍

    Kubernetes集群的组成 我们谈起 Kubernetes 和应用部署时,往往会涉及到容器.节点.Pods 等概念,还有各种术语,令人眼花缭乱.为了更好地摸清 Kubernetes,下面我们将介绍 Kubernetes 中与应用程序部署(deployment)和执行(execution)相关的知识. Kubernetes 集群由多个组件(components).硬件(hardware).软件(software)组成,它们共同工作来管理容器化(containerized)应用的部署和执行,这些

  • Minikube搭建Kubernetes集群

    Minikube 打开 https://github.com/kubernetes/minikube/releases/tag/v1.19.0 下载最新版本的二进制软件包(deb.rpm包),再使用 apt 或 yum 安装. 或者直接下载 minikube 最新版本二进制文件(推荐). curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.19.0/minikube-linu

  • Kubernetes关键组件与结构组成介绍

    架构组成 我们可以看一下这两张图,所表示的都是关于 Kubernetes 集群的架构. 一个 kubernetes 集群是由一组被称为节点(Node)的机器或虚拟机组成,集群由 master.worker 节点组成,每个机器至少具有一个 worker 节点. Master 在前面两个图中,可以看到 Master 是由一组称为控制平面组件组成的,我们可以打开 /etc/kubernetes/manifests/ 目录,里面是 k8s 默认的控制平面组件. . ├── etcd.yaml ├── k

  • kubernetes中的namespace、node、pod介绍

    namepace.node.pod? 当我们讨论 k8s 时总是会讨论集群,k8s 中的每个集群由多个机器/虚拟机组成,集群也被称为 命名空间(namespace),命名空间是虚拟的,因此也叫虚拟集群. Namespace 是对一组资源和对象的抽象集合. node 是集群中的单个机器/虚拟机,node 有两种,一种是 master ,一种是 worker.master 用来运行 kubernetes 服务,例如 API Server:worker 是真正工作的节点,用来运行你的容器. maste

  • 使用kubeadm命令行工具创建kubernetes集群

    目录 命令行工具 通过软件仓库安装 二进制文件下载安装 ubutu & centos 快速安装 创建 kubernetes 集群 1,创建 Master 2,然后初始化集群网络. 3,加入集群 清除环境 命令行工具 主要有三个工具,命令行工具使用 kube 前缀命名. kubeadm:用来初始化集群的指令. kubelet:在集群中的每个节点上用来启动 Pod 和容器等. kubectl:用来与集群通信的命令行工具. 通过软件仓库安装 方法 ① 此方法是通过 Google 的源下载安装工具包.

  • Kubernetes部署实例并配置Deployment、网络映射、副本集

    Deployment Deployment 是 Kubernetes 提供的一种自我修复机制来解决机器故障维护的问题. 当我们单独使用 docker 部署应用时,为了应用挂了后能够重启,我们可以使用 --restart=always 参数,例如: docker run -itd --restart=always -p 666:80 nginx:latest 但是这种方式只能单纯重启容器,并不具备从机器故障中恢复的能力. Kubernetes Deployment 是一个配置,它可以指挥 Kube

  • 了解Kubernetes中的Service和Endpoint

    目录 Srevice Service 的创建及现象 Service 定义 Endpoint slices 创建 Endpoint.Service Service 创建应用 创建 Endpoint Srevice Service 是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法.如果我们使用 Deployment 部署 pod,则可以以 Deployment 为对象创建 Service. 在 K8S 中,每个 Pod 都有其自己唯一的 ip 地址,而 Service 可以为多个 Po

  • k8s 中的 service 如何找到绑定的 Pod 及实现 Pod 负载均衡的方法

    目录 k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡 前言 endpoint kube-proxy userspace 模式 iptables ipvs kernelspace 服务发现 环境变量 DNS 总结 参考 k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡 前言 Service 资源主要用于为 Pod 对象提供一个固定.统一的访问接口及负载均衡的能力. service 是一组具有相同 label pod 集合的抽

  • 如何在kubernetes中创建Pod

    目录 如何创建Pod? kubectl工具 如何创建Pod? 在之前的文章中,我们介绍了容器和Pod的区别和关系.我们知道Pod是k8s调度的最小单位,而一个Pod中可以有多个容器,那么我们如何来定义一个我们自己的Pod呢? 在k8s中,我们通常使用编写配置文件的方式创建一个Pod,配置文件的格式通常采用yaml格式,(yaml格式如何表示list.key-value键值对,这些知识在前一篇文章中说过了),编写好yaml文件之后,通过下面的办法来启动一个Pod: kubectl create -

  • 一文详解kubernetes 中资源分配的那些事

    目录 概要 一个nginx的配置 我们进入nginx容器所在目录看下 cpu.shares cpu.cpu.cfs_period_us.cpu.cfs_quota_us 资源使用率数据来源 下kubelet相关配置:** 概要 在k8s中,kube-scheduler是Kubernetes中的调度器,用于将Pod调度到可用的节点上.在调度过程中,kube-scheduler需要了解节点和Pod的资源需求和可用性情况,其中CPU和内存是最常见的资源需求.那么这些资源的使用率是怎么来的呢?当Pod调

  • Android实现从activity中停止Service的方法

    本文实例讲述了Android实现从activity中停止Service的方法.分享给大家供大家参考,具体如下: 1.在AndroidManifest.xml注册Service <service android:name=".service.SensorService" > <intent-filter> <action android:name="ITOP.MOBILE.SIMPLE.SERVICE.SENSORSERVICE"/>

  • Android中使用Service实现后台发送邮件功能实例

    本文实例讲述了Android中使用Service实现后台发送邮件功能.分享给大家供大家参考,具体如下: 程序如下: import android.app.Activity; import android.content.Intent; import android.content.res.Resources.NotFoundException; import android.os.Bundle; import android.widget.TextView; public class A05Ac

  • Android中的Service相关全面总结

    1.Service的种类 按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程上,  服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL.相应bindService会方便很多.  主进程被Kill后,服务便会终止.  非常常见的应用如:HTC的音乐播放服务,天天动听音乐播放服务. 远程服务(Remote) 该服务是独立的进程,  服务为独立的进程,对应进程名格式为所在包名

  • 详解Android中的Service

    Service简介: Service是被设计用来在后台执行一些需要长时间运行的操作. Android由于允许Service在后台运行,甚至在结束Activity后,因此相对来说,Service相比Activity拥有更高的优先级. 创建Service: 要创建一个最基本的Service,需要完成以下工作:1)创建一个Java类,并让其继承Service 2)重写onCreate()和onBind()方法 其中,onCreate()方法是当该Service被创建时执行的方法,onBind()是该S

  • .NET 中Worker Service的使用入门

    译者注: 请先完成以下准备工作,以便于您理解本文. 1.下载并安装最新的 .NET SDK:https://dotnet.microsoft.com/download 2.命令行运行 dotnet new Worker -n "MyService" 命令,创建一个 Worker Service 项目. 什么是 .NET Core Worker Service? Worker Service 是使用模板构建的 .NET 项目,该模板提供了一些有用的功能,可以将常规控制台应用程序变得更加强

  • java实现在普通类中注入service或mapper

    普通类中注入service或mapper 1.类加@Component注解 2.注入需要引入的service @Autowired private UserService userService; 3.建静态文件 private static UserService users; 4.初始化方法 @PostConstruct public void init() { users= userService; } 5.调用 users.selectUser(user); mapper为null的情况

随机推荐