当前位置: 首页 > 科技观察

微服务架构在Kubernetes上的实现

时间:2023-03-17 11:40:37 科技观察

【编者按】本文是微服务网格系列的第二篇。通过目前最好的微服务部署平台Kubernetes,详细讲解微服务的部署过程,让用户对微服务有一个具体的认识,同时为后续结合Istio部署更复杂的服务打下基础。在上一篇文章中,我们讨论了最近的微服务趋势,以及微服务架构可能出现的一些复杂情况。在接下来的几周内,我们将深入探讨这个问题。我们将探讨不同设计选择中固有的权衡,以及可以采取哪些措施来减轻这些影响。然而,在深入研究之前,我认为花点时间了解当今微服务的最新技术是有意义的。我们首先回顾领先的容器管理和服务编排框架Kubernetes。Kubernetes和微服务如今几乎是同义词,因此最好彻底了解它们是如何组合在一起的。与Kubernetes本身非常相似,容器近年来已成为现代可扩展架构不可或缺的一部分。与微服务一样,容器之所以流行,是因为它们为开发过程提供了真正的好处:它们可靠、易于扩展,并提供了一个很好的抽象来隔离Web服务的核心组件。如果想和更多的Kubernetes技术高手交流,可以加我微信liyingjiese,备注“加群”。群里每周都有全球各大公司的最佳实践和行业最新动态。特别是,一种容器化技术已经远远超过了其他技术。没错,我们微服务之旅的下一站是看看Kubernetes和Docker,它们是现代微服务安装的主力军。简而言之,Kubernetes是现代基于容器的DevOps的黄金标准,微服务和容器齐头并进。随着容器化的兴起,管理大型Docker部署和基于容器的服务出现了多种相互竞争的技术。您可能还记得其中一些已退役的解决方案:DockerSwarm、ApacheMesos、OpenStackMagnum等。但是,现在Kubernetes已经淘汰了竞争对手。它是AWS、Azure、GoogleCloud和许多私有云提供商(如RedHat和Pivotal)原生附带的唯一容器化解决方案。Kubernetes能够如此迅速地获得如此多优势的根源在于它能够将配置与编排分开。这种复杂程度应该不足为奇,因为Kubernetes来自谷歌的内部项目Borg,这是谷歌数十年分布式系统经验的结晶。使用Kubernetes,您可以指定服务的外观、实例数量、冗余类型和服务位置。然后,该工具会自动计算需要进行哪些更改才能从现状创建服务。将其视为SQL,您无需指定数据库如何添加或转换每一行。您可以指定数据的外观,数据库将确定如何具体化数据。Kubernetes也是如此。Kubernetes特性Kubernetes提供的是将容器视为服务定义的能力。Kubernetes可以处理纯容器。即使你只想部署容器而不进入微服务领域,Kubernetes也可以在管理和部署方面为你提供很多帮助。您在集群中的服务器上安装Kubernetes软件,Kubernetes主进程会自动部署您的软件。除了基本的容器,Kubernetes还可以使用它所谓的Pod。Pod是由一个或多个服务组成的单一定义。Pod可以包含任何内容,从单独运行的单个服务器到完整的多容器服务,例如结合键值存储和包含的http服务器的数据库容器。Pod是Kubernetes的基本构建块。***一个要素是服务。在Kubernetes中,服务就像将Pod组合成应用程序的食谱。Pod是具有生命周期的具体部署,而服务则更为抽象。它描述了一个单独的组件,例如后端或数据库。结合所有这些功能的是Kubernetes命令行工具kubectl。虽然Kubernetes提供的抽象很棒,但命令行工具非常强大,允许您使用kubectl命令描述对模式的复杂更改。总而言之,kubectlCLI工具包括近50个不同的命令来处理修改基于容器的微服务部署时出现的所有情况(你总是会出错)。动手实践虽然高级描述很有帮助,但实际上没有什么比实际部署Kubernetes服务更能更好地理解它了。我们在这里没有做任何高级的事情,只是展示如何部署一个简单的“HelloWorld”服务,但它应该是有益的。我们用Go编写了一个简单的服务器,用“HelloWorld”响应http请求。代码非常简单:packagemainimport("fmt""log""net/http""os")funchandler(whttp.ResponseWriter,r*http.Request){log.Print("Helloworldreceivedrequest.")version:=os.Getenv("VERSION")ifversion==""{version="v1"}log.Println(version)fmt.Fprintf(w,"Helloworld%s\n",version)}funcmain(){log.Print("Helloworldsamplestarted.")http.HandleFunc("/api/hello",handler)port:=os.Getenv("PORT")ifport==""{port="8080"}log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s",port),nil))}运行它的第一步是将它构建到Docker容器中。为此,我们从基础GoDocker映像开始构建以下Dockerfile。#UsetheofficialGolangimagetocreateabuildartifact。#https://hub.docker.com/_/golangFROMgolangasbuilder#Copylocalcodetothecontainerimage.WORKDIR/go/src/github.com/haseebh/hello-worldCOPY..RUNgobuild-ohelloworld-v1main/helloworld-v1.go#UseaDock-stagebuildtocreatealpineproductionimage。#https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-buildsFROMalpineCOPY--from=builder/go/src/github.com/haseebh/hello-world-v1/helloworld-v1ENVPORT8080#Runthewebserviceoncontainerstartup.CMD["/helloworld-v1"]现在我们只需要构建它。选择一个镜像标签,然后运行以下两个Docker命令来构建和保存镜像:#Buildthecontaineronyourlocalmachinedockerbuild-t。#Pushthecontainerdockerregistrydockerpush在部署之前还有一步。虽然我们已经定义了将进入我们的Pod的内容,但我们还没有定义我们的服务。让我们创建一个简单的服务定义,称为HelloService。我们将其保存在hello-service.yml服务定义文件中。apiVersion:v1kind:Servicemetadata:name:helloworld-v1spec:ports:-port:80protocol:TCPtargetPort:8080selector:app:helloworld-v1type:LoadBalancer---apiVersion:apps/v1kind:Deploymentmetadata:name:helloworld-v1labels:app:helloworld-v1spec:replicas:1selector:matchLabels:app:helloworld-v1template:metadata:labels:app:helloworld-v1spec:containers:-name:helloworld-kubernetes#replacewithyouractualimageimage:端口:-containerPort:8080现在我们拥有了我们需要的一切。我们的形象已经建立,我们已经基于它定义了一个服务。现在我们终于可以使用Kubernetes部署它了。我们将使用kubectl命令行工具将其部署在我们的集群上:kubectlapply-fhelloworld-go-v1.yaml要获取服务负载均衡器IP,请运行以下命令:kubectlgetsvchelloworld-v1-owide注意外部IP。现在,当我们访问负载均衡器地址时,我们可以看到已部署的服务。内容不多,但是“HelloWorld”向我们展示了一切正常!关键组件构建此服务使我们能够演示大多数主要的Kubernetes组件。首先,我们布置Dockerfile以创建服务代码。要在Kubernetes中实际创建服务,我们需要使用YAML来定义它。我们的定义采用我们定义的图像并提供一些关键信息:它应该部署在哪里、版本和其他配置信息。之后,我们将服务部署到Pod上。在Kubernetes模型中,Pod与容器密切相关。许多部署,例如我们的部署,都使用单个pod进行服务。严格来说,Kubernetes不管理容器,它管理容器。有时这些容器与一个Pod是一对一的关系,有时有多个容器关联到一个Pod。***,我们看到了编排的原则。在定义了我们希望如何部署API之后,我们只需将配置文件推送到Kubernetes,剩下的就交给它了。使用kubectl,我们能够指定我们想要的架构,Kubernetes会处理剩下的事情。当我们稍后查看具有多个版本和复杂部署的更复杂的示例时,我们将更清楚地看到这个简单想法的力量。深入了解部署简单服务仅仅是个开始。Kubernetes原生支持微服务,这是部署基本甚至更复杂的微服务架构的好方法,而且不会有太多麻烦。但要真正利用微服务的可扩展性,您需要了解更多。在下一篇文章中,我们将介绍Istio。使用微服务方法,我们能够将单个应用程序分解为多个服务。我们在第一篇文章中看到,这种方法为处理复杂系统提供了更多的开发人员敏捷性和更好的抽象。在这里,我们看到了如何使用Kubernetes在实践中部署微服务。下周,我们将开始研究微服务领域的一些新兴概念,例如微服务网格,向您展示这些技术的真正能力。