【云原生|K8s系列第5篇】:实战使用Service暴露应用

简介: 本期文章是K8s系列第5篇,主要是实战使用Service暴露应用。通过本期文章:我们将学习了解 Kubernetes 中的 Service,学习标签(Label) 和 标签选择器(Label Selector) 对象如何与 Service 关联,最后在 Kubernetes 集群外用 Service 暴露应用。————————————————版权声明:本文为CSDN博主「程序员洲洲」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_51484460/article/details/1260

本期文章是K8s系列第5篇,主要是实战使用Service暴露应用。通过本期文章:我们将学习了解 Kubernetes 中的 Service,学习标签(Label) 和 标签选择器(Label Selector) 对象如何与 Service 关联,最后在 Kubernetes 集群外用 Service 暴露应用。


在前期的文章中,已经介绍了一些云原生入门的知识及简单实战,感兴趣的同学可以去我的云原生专栏中学习,任意门:云原生学习专栏

前言:学习目标


本期的学习目标是:

学习 Kubernetes 中的 Service。

学习标签(Label) 和 标签选择器(Label Selector) 对象如何与 Service 关联。

在 Kubernetes 集群外用 Service 暴露应用。

1、K8s Service介绍

Kubernetes Pod 实际上是拥有生命周期的。 当一个工作 Node 挂掉后, 在 Node 上运行的 Pod 也会消亡。 ReplicaSet 会自动地通过创建新的 Pod 驱动集群回到目标状态,以此可以保证应用程序正常运行。


换一个例子来说明,目前有一个具有3个副本数的用作图像处理的后端程序。这些副本是可替换的,前端系统不应该关心后端副本,即使 Pod 丢失或重新创建。


这也就是说,Kubernetes 集群中的每个 Pod (即使是在同一个 Node 上的 Pod )都有一个唯一的 IP 地址,因此需要一种方法自动协调 Pod 之间的变更,以便应用程序保持运行。


Kubernetes 中的服务(Service)是一种抽象概念,它定义了 Pod 的逻辑集和访问 Pod 的协议。Service 使从属 Pod 之间的松耦合成为可能。 和其他 Kubernetes 对象一样, Service 用 YAML (更推荐) 或者 JSON 来定义. Service 下的一组 Pod 通常由 LabelSelector 来标记。


尽管每个 Pod 都有一个唯一的 IP 地址,但是如果没有 Service ,这些 IP 不会暴露在集群外部。Service 允许你的应用程序接收流量。Service 也可以用在 ServiceSpec 标记type的方式暴露。


ClusterIP (默认) - 在集群的内部 IP 上公开 Service 。这种类型使得 Service 只能从集群内访问。


NodePort - 使用 NAT 在集群中每个选定 Node 的相同端口上公开 Service 。使用: 从集群外部访问Service。是 ClusterIP 的超集。


LoadBalancer - 在当前云中创建一个外部负载均衡器(如果支持的话),并为 Service 分配一个固定的外部IP。是 NodePort 的超集。


ExternalName - 通过返回带有该名称的 CNAME 记录,使用任意名称(由 spec 中的externalName指定)公开 Service。不使用代理。这种类型一般需要kube-dns的v1.7或更高版本。


2、Service 和 Label 关系示意图

Service 通过一组 Pod 路由通信。Service 是一种抽象,它允许 Pod 死亡并在 Kubernetes 中复制,而不会影响应用程序。在依赖的 Pod (如应用程序中的前端和后端组件)之间进行发现和路由是由Kubernetes Service 处理的。


Service 匹配一组 Pod 是使用 标签(Label)和选择器(Selector), 它们是允许对 Kubernetes 中的对象进行逻辑操作的一种分组原语。标签(Label)是附加在对象上的键/值对,可以以多种方式使用,如:


指定用于开发,测试和生产的对象

嵌入版本标签

使用 Label 将对象进行分类


3、实战使用Service暴露应用

接下来,我们将实战如何使用kubectl expose命令在集群外公开Kubernetes应用程序。我们还将学习如何使用kubectl label命令查看并将标签应用到对象。


实战使用的环境是在线终端是预先配置好的Linux环境,可以作为常规控制台使用(可以输入命令)


3.1 创建新服务

让我们验证一下应用程序是否正在运行。我们将使用kubectl get命令并查找现有的Pods:、

$ kubectl get pods
NAME                                  READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-fb5c67579-pgxxl   1/1     Running   0          51s
$


我们有一个名为kubernetes的服务,它是在minikube启动集群时默认创建的。为了创建一个新服务并将其公开给外部通信,我们将使用expose命令,将NodePort作为参数(minikube还不支持LoadBalancer选项)。

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080


接下来,让我们列出集群中当前的服务:

$ kubectl get services
NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes            ClusterIP   10.96.0.1       <none>        443/TCP          7m37s
kubernetes-bootcamp   NodePort    10.110.52.119   <none>        8080:30349/TCP   97s


现在有一个服务叫做kubernetes-bootcamp。这里我们看到服务接收了一个唯一的集群IP、一个内部端口和一个外部IP(节点的IP)。


要找出外部打开了哪些端口(通过NodePort选项),我们将运行如下的describe service命令:

$ kubectl describe services/kubernetes-bootcamp
Name:                     kubernetes-bootcamp
Namespace:                default
Labels:                   app=kubernetes-bootcamp
Annotations:              <none>
Selector:                 app=kubernetes-bootcamp
Type:                     NodePort
IP Families:              <none>
IP:                       10.110.52.119
IPs:                      10.110.52.119
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  30349/TCP
Endpoints:                172.18.0.6:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>


创建一个名为NODE_PORT的环境变量,分配节点端口的值:

$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
$ echo NODE_PORT=$NODE_PORT
NODE_PORT=30349


现在我们可以使用curl、节点的IP和外部暴露的端口来测试应用程序是否暴露在集群外:

$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-pgxxl | v=1


3.2 使用labels

部署自动为Pod创建了一个标签。使用description部署命令,我们可以看到标签的名称:

kubectl describe deployment


让我们使用这个标签来查询Pods列表。我们将使用kubectl get pods命令,参数是-l,后面是标签值:

$ kubectl get pods -l app=kubernetes-bootcamp
NAME                                  READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-fb5c67579-pgxxl   1/1     Running   0          15m


我们也可以这样做来列出现有的服务:


$ kubectl get services -l app=kubernetes-bootcamp
NAME                  TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes-bootcamp   NodePort   10.110.52.119   <none>        8080:30349/TCP   10m


获取Pod的名称并将其存储在POD_NAME环境变量中:

$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
$ echo Name of the Pod: $POD_NAME
Name of the Pod: kubernetes-bootcamp-fb5c67579-pgxxl


接下来要应用一个新标签,我们使用label命令,后面跟着对象类型、对象名称和新标签:

$ kubectl label pods $POD_NAME version=v1
pod/kubernetes-bootcamp-fb5c67579-pgxxl labeled


这将为我们的Pod应用一个新标签(我们把应用版本钉在了Pod上),我们可以用describe Pod命令来检查它:

kubectl describe pods $POD_NAME


我们在这里看到标签现在连接到我们的Pod。现在我们可以使用新标签查询:

$ kubectl get pods -l version=v1
NAME                                  READY   STATUS    RESTARTS   AGE
kubernetes-bootcamp-fb5c67579-pgxxl   1/1     Running   0          18m


3.3 删除服务

需要删除服务,使用delete service命令。标签也可以在这里使用:

$ kubectl delete service -l app=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted


确认服务已消失:

$ kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m


这证实了我们的服务已被删除。为了确认路由没有暴露,我们可以查询之前暴露的IP和端口:

$ curl $(minikube ip):$NODE_PORT
curl: (7) Failed to connect to 10.0.0.12 port 30349: Connection refused


这证明了应用程序从集群外部无法再访问。我们可以确认应用程序仍在运行,并在pod内卷起:

$ kubectl exec -ti $POD_NAME -- curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-fb5c67579-pgxxl | v=1


我们在这里看到,应用程序启动了。这是因为部署正在管理应用程序。如果要关闭应用程序,还需要删除Deployment。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
运维 Cloud Native 持续交付
深入理解云原生架构及其在现代企业中的应用
随着数字化转型的浪潮席卷全球,企业正面临着前所未有的挑战与机遇。云计算技术的迅猛发展,特别是云原生架构的兴起,正在重塑企业的IT基础设施和软件开发模式。本文将深入探讨云原生的核心概念、关键技术以及如何在企业中实施云原生策略,以实现更高效的资源利用和更快的市场响应速度。通过分析云原生架构的优势和面临的挑战,我们将揭示它如何助力企业在激烈的市场竞争中保持领先地位。
|
2月前
|
运维 Cloud Native 安全
云原生技术在现代企业中的应用与挑战####
本文探讨了云原生技术在现代企业IT架构中的关键作用,分析了其带来的优势和面临的主要挑战。通过实际案例分析,揭示了如何有效应对这些挑战,以实现业务敏捷性和技术创新的平衡。 ####
|
2月前
|
Cloud Native 持续交付 开发者
云原生技术在现代企业中的应用与实践####
本文深入探讨了云原生技术的核心概念及其在现代企业IT架构转型中的关键作用,通过具体案例分析展示了云原生如何促进企业的敏捷开发、高效运维及成本优化。不同于传统摘要仅概述内容,本部分旨在激发读者对云原生领域的兴趣,强调其在加速数字化转型过程中的不可或缺性,为后续详细论述奠定基础。 ####
|
2月前
|
Kubernetes Cloud Native 物联网
云原生技术在现代软件开发中的应用与挑战####
本文探讨了云原生技术的兴起背景、核心理念及其在现代软件开发中的广泛应用。通过具体案例分析,揭示了云原生架构如何促进企业数字化转型,并指出了在实施过程中面临的主要挑战及应对策略。 ####
|
2月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
158 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
2月前
|
人工智能 缓存 异构计算
云原生AI加速生成式人工智能应用的部署构建
本文探讨了云原生技术背景下,尤其是Kubernetes和容器技术的发展,对模型推理服务带来的挑战与优化策略。文中详细介绍了Knative的弹性扩展机制,包括HPA和CronHPA,以及针对传统弹性扩展“滞后”问题提出的AHPA(高级弹性预测)。此外,文章重点介绍了Fluid项目,它通过分布式缓存优化了模型加载的I/O操作,显著缩短了推理服务的冷启动时间,特别是在处理大规模并发请求时表现出色。通过实际案例,展示了Fluid在vLLM和Qwen模型推理中的应用效果,证明了其在提高模型推理效率和响应速度方面的优势。
云原生AI加速生成式人工智能应用的部署构建
|
2月前
|
Cloud Native JavaScript Docker
云原生技术:构建现代应用的基石
在数字化转型的浪潮中,云原生技术如同一艘承载梦想的航船,引领企业驶向创新与效率的新海域。本文将深入探索云原生技术的核心价值,揭示其如何重塑软件开发、部署和运维模式,同时通过一个简易代码示例,展现云原生应用的构建过程,让读者领略到云原生技术的魅力所在。
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(五)
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(五)
260 0
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(五)
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(四)
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(四)
244 0
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(四)
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(三)
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(三)
253 0
KUBERNETES04_Service服务ClusterIP、NodePort方式、Ingress域名访问、路径重写、限流操作(三)