乐趣区

关于kubernetes:不背锅运维粗讲K8S的Service及分享现撸案例

Service 存在的意义

Kubernetes 中的 Service 是一种网络形象,用于将一组 Pod 裸露给其余组件,例如其余 Pod 或内部用户。Service 能够作为一个负载均衡器,为一组 Pod 提供繁多的 IP 地址和 DNS 名称,并通过选择器来将流量路由到这些 Pod。

Services 的存在有以下几个意义:

  1. 通明的服务发现:  Kubernetes 应用 Service 作为一种通明的服务发现机制。应用 Service 能够将 Pod 暗藏在前面,这样其余组件能够应用 Service 的 DNS 名称来拜访它们,而不须要晓得 Pod 的理论 IP 地址和端口号。
  2. 负载平衡:  Service 能够将流量路由到一组 Pod 上,并应用标签选择器将流量平均地调配给这些 Pod。这使得能够轻松地进行程度扩大,以满足一直增长的负载。
  3. 稳固的 IP 地址:  Kubernetes 为每个 Service 调配一个稳固的 IP 地址,这个 IP 地址与 Pod 的生命周期无关。这意味着能够在 Pod 启动和进行时保持稳定的服务地址,并且无需手动更改任何配置。
  4. 内部拜访:  通过将 Service 类型设置为 NodePort 或 LoadBalancer,能够将 Service 裸露给内部用户或内部负载均衡器。这使得能够轻松地将 Kubernetes 集群与内部服务和用户集成。

总之,Service 是 Kubernetes 中十分重要的一部分,能够提供通明的服务发现、负载平衡、稳固的 IP 地址和内部拜访。在理论生产环境中,应用 Service 是构建牢靠和可扩大应用程序的要害。

Pod、Service、Label 的关系

在 Kubernetes 中,Pod 是最小的可部署单元,它是由一个或多个容器组成的。Pod 提供了一个运行环境,其中蕴含应用程序所需的资源,如存储、网络和命名空间。

Service 是 Kubernetes 中的一种形象,用于定义一组 Pod,这些 Pod 执行雷同的工作,并且能够通过 Service 的 IP 地址和端口号进行拜访。Service 容许应用程序通过固定的 IP 和端口号进行拜访,而不用思考后端 Pod 的 IP 和端口号。

在 Kubernetes 中,Pod 和 Service 之间有一种严密的关系。Service 应用标签选择器来确定哪些 Pod 应该成为它的后端。一旦 Service 抉择了一组 Pod,它将为这些 Pod 调配一个固定的 IP 和端口号,这些 IP 和端口号将用于拜访这些 Pod。

当 Pod 被创立或删除时,Service 会自动更新它的后端列表。这意味着当 Pod 被增加到 Service 的后端时,它们将主动成为 Service 的一部分,并且能够通过 Service 的 IP 和端口号进行拜访。同样地,当 Pod 被删除时,它们将主动从 Service 的后端列表中删除,这样拜访它们的申请就不会被发送到曾经不存在的 Pod 上。

因而,Pod 和 Service 之间的关系是十分严密的,Service 为一组 Pod 提供了一个稳固的网络地址,并且自动更新它的后端列表以确保拜访这些 Pod 时的高可用性和可靠性。

在 Kubernetes 中,Pod、Service 和标签之间有着亲密的关系。标签(Label)是 Kubernetes 中的一种机制,它容许你为对象增加任意的元数据,例如版本、环境、用处等等。

Pod 能够应用标签进行分类和分组,通过给 Pod 打上特定的标签,能够不便地对它们进行抉择和治理。同样地,Service 也能够应用标签选择器来抉择具备特定标签的 Pod 作为后端。标签能够被利用于任何 Kubernetes 对象,包含 Pod、Service、ReplicaSet 等等。

当创立一个 Service 时,能够应用标签选择器来指定 Service 所选取的 Pod 的标签。例如,能够通过以下形式创立一个 Service,它将抉择所有标有 app=goweb-demo 的 Pod 作为它的后端:

goweb-demo-v1.yaml

apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo

在这个例子中,Service 应用 selector 字段来抉择具备 app=goweb-demo 标签的 Pod 作为它的后端。这意味着只有那些标记为 app=goweb-demo 的 Pod 能力被 Service 拜访。

标签是 Kubernetes 中十分重要的一个概念,它使得对 Pod 和 Service 的抉择和治理变得更加灵便和高效。通过应用标签,能够轻松地对应用程序的不同版本、环境和用处进行分类和分组,并依据须要创立相应的 Pod 和 Service 来满足应用程序的需要。

Service 的拜访类型

Kubernetes 中的 Service 对象能够指定不同的拜访类型,以便在集群内和集群外提供不同级别的拜访。上面是 Kubernetes 中 Service 的三种拜访类型:

  1. ClusterIP:默认的拜访类型,将创立一个虚构 IP 地址,代表一组后端 Pod。只能从集群外部拜访该 Service,内部无法访问。
  2. NodePort:将在每个 Node 上公开一个端口,并将该端口重定向到 Service。能够通过 Node 的 IP 地址和该端口拜访该 Service。能够从集群内部拜访该 Service,但须要在防火墙中关上该端口。
  3. LoadBalancer:将在内部创立一个负载均衡器,并将流量路由到 Service。负载均衡器能够将流量路由到多个后端 Pod,以进步可用性和性能。须要应用内部负载均衡器的云平台反对,例如 AWS ELB 或 GCP GCLB。

另外,还有一种名为 ExternalName 的拜访类型,能够将 Service 映射到集群内部的 DNS 名称,而不是集群外部的 Pod。该拜访类型通常用于将 Service 映射到内部服务,例如数据库或 API 网关。

能够应用 kubectl 命令行或 YAML 文件来指定 Service 的拜访类型和其余配置。例如,在 YAML 文件中,能够将 Service 的类型指定为 type: ClusterIP、type: NodePort 或 type: LoadBalancer,具体取决于须要提供的拜访级别。

实战开撸:案例 1

  1. 筹备 Deployment yaml 配置文件
kubectl create deployment goweb-demo --image=192.168.11.247/web-demo/goweb-demo:20221229v3 --replicas=3 --dry-run=client -o yaml > my-deployment.yaml

上述命令将应用名为“192.168.11.247/web-demo/goweb-demo:20221229v3”的镜像创立一个名为“goweb-demo”的 Deployment,并设置 3 个正本。–dry-run=client 选项使 kubectl 只查看配置文件的语法,而不会理论创立 Deployment。-o yaml 选项指定输入格局为 YAML,并将其重定向到 my-deployment.yaml 文件中。上面是咱们失去的 my-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: goweb-demo
  name: goweb-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: goweb-demo
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: goweb-demo
    spec:
      containers:
      - image: 192.168.11.247/web-demo/goweb-demo:20221229v3
        name: goweb-demo
        resources: {}
status: {}

编辑 my-deployment.yaml 文件以更改 Deployment 的任何其余配置选项。例如,您能够为 Deployment 指定标签,设置容器端口,配置健康检查等。上面是我调整后的 my-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: goweb
  template:
    metadata:
      labels:
        app: goweb
    spec:
      containers:
      - name: goweb-container
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
  1. 创立 Deployment
tantianran@test-b-k8s-master:~/goweb-demo$ kubectl apply -f my-deployment.yaml
deployment.apps/goweb-demo created
tantianran@test-b-k8s-master:~/goweb-demo$ kubectl get deployments
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
goweb-demo   3/3     3            3           8m25s
tantianran@test-b-k8s-master:~/goweb-demo$ 
tantianran@test-b-k8s-master:~/goweb-demo$ kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
goweb-demo-654c45b968-9wcr8   1/1     Running   0          5s
goweb-demo-654c45b968-jsw8z   1/1     Running   0          5s
goweb-demo-654c45b968-mngq7   1/1     Running   0          5s
tantianran@test-b-k8s-master:~/goweb-demo$ 
  1. 筹备 Service yaml 配置文件 当初应用 go 语言开发的 web demo 曾经跑起来了,而且跑了 3 个 pod 正本,接下来就要对外提供拜访,我的 goweb demo 利用对外提供拜访的端口是 8090。

在命令行下创立一个将容器端口 8090 映射到 Node 的端口 30080 上的 Service 对象,能够应用以下命令:

kubectl create service nodeport goweb --tcp=80:8090 --node-port=30080

其中,goweb 是 Service 对象的名称,默认也是用此名称与 deployment 中定义的 label “app: goweb” 保持一致,–tcp=80:8090 示意将容器端口 8090 映射到 Service 的端口 80 上,–node-port=30080 示意将 Service 的端口 30080 映射到 Node 的端口 30080 上。

tantianran@test-b-k8s-master:~/goweb-demo$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
goweb        NodePort    10.111.227.27   <none>        80:30080/TCP   5s    app=goweb
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        96d   <none>
tantianran@test-b-k8s-master:~/goweb-demo$ 

应用 –dry-run=client -o yaml 失去 my-service.yaml 文件,而后应用 kubectl apply 命令将其利用到集群中

kubectl create service nodeport goweb --tcp=80:8090 --node-port=30080 --dry-run=client -o yaml > my-service.yaml 

my-service.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: goweb
  name: goweb
spec:
  ports:
  - name: 80-8090
    nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb
  type: NodePort
status:
  loadBalancer: {}

在这个示例中,咱们创立了一个名为“goweb”的服务,它将流量路由到标签为“app=goweb”的 Pod 上。该服务类型被设置为 NodePort,并指定了端口号为 30080。服务监听 80 端口,将流量转发到 Pod 上的 8090 端口。

  1. 创立 service
tantianran@test-b-k8s-master:~/goweb-demo$ kubectl apply -f my-service.yaml 
service/goweb created
tantianran@test-b-k8s-master:~/goweb-demo$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
goweb        NodePort    10.104.241.81   <none>        80:30080/TCP   7s    app=goweb
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        96d   <none>

tantianran@test-b-k8s-master:~/goweb-demo$ kubectl get ep
NAME         ENDPOINTS                                                  AGE
goweb        10.244.240.19:8090,10.244.240.38:8090,10.244.240.56:8090   16s
kubernetes   192.168.11.13:6443                                         96d
tantianran@test-b-k8s-master:~/goweb-demo$ 

要在集群外拜访该服务,能够应用任何节点的 IP 地址和 NodePort 端口号。例如,如果节点的 IP 地址为 192.168.11.14,则能够应用 http://192.168.1.14:30080 拜访该服务。

实战开撸:案例 2

在案例 1 中,都是应用 yaml 进行创立,并且分享了如何疾速失去一个 yaml。那么本案例 2,全程在 kubectl 命令行下进行创立。

  1. 创立 deployment 要创立一个名为 nginx-deployment 的 Deployment 并应用最新版本的 nginx 镜像
kubectl create deployment my-deployment001 --image=192.168.11.247/web-demo/goweb-demo:20221229v3 --replicas=3
  1. 裸露 Deployment 的端口
kubectl expose deployment my-deployment001 --port=80 --target-port=8090 --type=NodePort

其中,my-deployment001 是你要裸露端口的 Deployment 的名称,80 是你要应用的 Service 的端口,8090 是你要将流量路由到的 Pod 的端口,–type 是 Service 的类型,通常是 ClusterIP、NodePort 或 LoadBalancer。下面的命令中,将创立一个类型为 NodePort 的 Service,并将其裸露在随机调配的端口上。

查看 Service

tantianran@test-b-k8s-master:~/goweb-demo$ kubectl get svc my-deployment001
NAME               TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
my-deployment001   NodePort   10.109.238.29   <none>        80:32537/TCP   3m48s

这将列出 Service 的详细信息,包含 Service 的 IP 地址、端口和类型,下面随机调配的端口是 32537。

这样,就曾经胜利地创立了一个 Deployment 并将其裸露在一个端口上。当初,能够应用 Service 的 IP 地址和端口来拜访应用程序。如果你应用的是 NodePort 类型的 Service,你能够在任何节点上应用 Service 的节点 IP 地址和端口来拜访它。如果你应用的是 LoadBalancer 类型的 Service,Kubernetes 会在你的云提供商中主动创立一个负载均衡器,并将流量路由到你的 Service。

关上浏览器,拜访看看:

最初的总结

Kubernetes (k8s) Service 是一个形象层,它为一组 Pod 提供了一个稳固的拜访地址和 DNS 名称。在 k8s 中,Service 是通过控制器和负载均衡器来实现的,它能够将流量分发给后端 Pod 实例,并确保它们的可用性和可靠性。上面是对 Kubernetes Service 的总结:

  1. Service 类型 k8s Service 有四种类型,别离是 ClusterIP、NodePort、LoadBalancer 和 ExternalName。不同类型的 Service 有不同的用处,抉择适合的类型十分重要。
  • ClusterIP:这是最罕用的类型。它为 Pod 提供了一个稳固的虚构 IP 地址,只能从集群外部拜访。
  • NodePort:它为 Pod 提供了一个动态的端口号,能够通过任何节点的 IP 地址和该端口拜访 Service。它将申请转发到相应的 Pod,反对内部拜访。
  • LoadBalancer:这种类型须要云服务商提供的负载均衡器反对。它为 Service 调配一个公共 IP 地址,并将流量负载平衡到 Pod 中。
  • ExternalName:它将 Service 映射到一个内部地址或 DNS 名称,而不是抉择 Pod。它通常用于将 k8s 外部的 Service 与内部服务连接起来。
  1. Service Selector Service Selector 是用来抉择要将流量转发到哪个 Pod 的标签。每个 Service 都会指定一个或多个 Selector,用于确定应该抉择哪些 Pod。在创立 Service 时,能够指定标签选择器以抉择相干 Pod。
  2. 端口 Service 的端口指的是该 Service 的监听端口。Service 能够监听多个端口,每个端口都能够关联一个或多个后端 Pod。端口也能够分为两个类型:端口和指标端口。端口是 Service 监听的端口,而指标端口是后端 Pod 的端口。
  3. 负载平衡 k8s Service 能够通过三种负载平衡算法来将流量调配到后端 Pod 中:
  • Round Robin:这是最常见的负载平衡算法。它按程序调配流量到每个 Pod,而后循环上来。
  • Session Affinity:这种算法会将同一客户端的所有申请都发送到同一个后端 Pod 中。这有助于保护状态,并确保在会话期间一致性。
  • IPVS:这是一种高级的负载平衡算法,它应用 Linux 内核中的 IPVS 模块来实现流量散发。
  1. DNS k8s Service 通过 DNS 来提供一个稳固的拜访地址。在创立 Service 时,k8s 会将其关联的 Pod 的 IP 地址注册到 k8s 集群的 DNS 中,并应用 Service 名称和 Namespace 作为 DNS 条目。这样,客户端能够通过 Service 名称和命名空间来拜访该 Service,k8s DNS 将解析这个名称并将其映射到 Service 关联的 Pod IP 地址。

在 k8s 中,每个 Pod 都有一个惟一的 IP 地址,然而这个 IP 地址在 Pod 从新调度或者 Pod 数量发生变化时可能会发生变化。这种变动可能会导致客户端连贯中断,因而 k8s Service 提供了一个稳固的拜访地址,使得客户端能够通过 Service 名称来拜访 Pod 而不须要关怀其 IP 地址的变动。这种形式也使得 k8s Service 非常适合于微服务架构,因为它能够将多个 Pod 组合成一个逻辑单元,并通过一个稳固的拜访地址对外提供服务。

本文转载于(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/9HBcSLkcxLZ8dA-0kqtLcA

退出移动版