Service 存在的意义
Kubernetes 中的 Service 是一种网络形象,用于将一组 Pod 裸露给其余组件,例如其余 Pod 或内部用户。Service 能够作为一个负载均衡器,为一组 Pod 提供繁多的 IP 地址和 DNS 名称,并通过选择器来将流量路由到这些 Pod。
Services 的存在有以下几个意义:
- 通明的服务发现: Kubernetes 应用 Service 作为一种通明的服务发现机制。应用 Service 能够将 Pod 暗藏在前面,这样其余组件能够应用 Service 的 DNS 名称来拜访它们,而不须要晓得 Pod 的理论 IP 地址和端口号。
- 负载平衡: Service 能够将流量路由到一组 Pod 上,并应用标签选择器将流量平均地调配给这些 Pod。这使得能够轻松地进行程度扩大,以满足一直增长的负载。
- 稳固的 IP 地址: Kubernetes 为每个 Service 调配一个稳固的 IP 地址,这个 IP 地址与 Pod 的生命周期无关。这意味着能够在 Pod 启动和进行时保持稳定的服务地址,并且无需手动更改任何配置。
- 内部拜访: 通过将 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 的三种拜访类型:
- ClusterIP:默认的拜访类型,将创立一个虚构 IP 地址,代表一组后端 Pod。只能从集群外部拜访该 Service,内部无法访问。
- NodePort:将在每个 Node 上公开一个端口,并将该端口重定向到 Service。能够通过 Node 的 IP 地址和该端口拜访该 Service。能够从集群内部拜访该 Service,但须要在防火墙中关上该端口。
- 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
- 筹备 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
- 创立 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$
- 筹备 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 端口。
- 创立 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 命令行下进行创立。
- 创立 deployment 要创立一个名为 nginx-deployment 的 Deployment 并应用最新版本的 nginx 镜像
kubectl create deployment my-deployment001 --image=192.168.11.247/web-demo/goweb-demo:20221229v3 --replicas=3
- 裸露 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 的总结:
- 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 与内部服务连接起来。
- Service Selector Service Selector 是用来抉择要将流量转发到哪个 Pod 的标签。每个 Service 都会指定一个或多个 Selector,用于确定应该抉择哪些 Pod。在创立 Service 时,能够指定标签选择器以抉择相干 Pod。
- 端口 Service 的端口指的是该 Service 的监听端口。Service 能够监听多个端口,每个端口都能够关联一个或多个后端 Pod。端口也能够分为两个类型:端口和指标端口。端口是 Service 监听的端口,而指标端口是后端 Pod 的端口。
- 负载平衡 k8s Service 能够通过三种负载平衡算法来将流量调配到后端 Pod 中:
- Round Robin:这是最常见的负载平衡算法。它按程序调配流量到每个 Pod,而后循环上来。
- Session Affinity:这种算法会将同一客户端的所有申请都发送到同一个后端 Pod 中。这有助于保护状态,并确保在会话期间一致性。
- IPVS:这是一种高级的负载平衡算法,它应用 Linux 内核中的 IPVS 模块来实现流量散发。
- 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