微服务架构在Kubernetes上的实现

640?wx_fmt=jpeg

上一篇文章中,我们讨论了最近的微服务趋势,以及伴随微服务架构可能出现的一些复杂问题。在接下来的几周内,我们将深入探讨这个问题。我们将探讨不同设计选择中固有的权衡,以及可以采取哪些措施来缓解这些问题。

然而,在深入之前,我认为花一点时间来了解当今微服务中的最新技术状态是有意义的。我们首先回顾一下领先的容器管理和服务编排框架Kubernetes。如今,Kubernetes和微服务几乎是同义词,所以最好彻底了解它们是如何组合在一起的。

Kubernetes

640?wx_fmt=png

与微服务本身非常相似,容器近年来已成为现代可扩展架构中不可或缺的一部分。与微服务一样,容器已经流行起来,因为它们为开发过程提供了真正的好处:它们可靠,易于扩展,并提供了一个很好的抽象,隔离了Web服务的核心组件。

特别是,一种容器化技术已远远超过其他技术。这是正确的,我们的微服务之旅的下一站是看看Kubernetes和Docker,它是现代微服务设施的主力。简单地说,Kubernetes是现代基于容器的DevOps和微服务以及容器携手并进的黄金标准。 

640?wx_fmt=png

Kubernetes能够如此迅速地获得如此多的优势,根因在于它能够将配置与编排分开。这种复杂程度应该不足为奇,因为Kubernetes来自谷歌的内部项目Borg,它是谷歌在分布式系统上的数十年经验总结。使用Kubernetes,你可以指定服务的外观,实例数,冗余类型,服务所在位置。然后,该工具自动计算从现状到创建该服务需要进行哪些更改。可以把它想象成SQL,你没有指定数据库如何添加或转换每个行。你可以指定数据的外观,数据库会指出如何实现数据。Kubernetes也是一样的。

Kubernetes特点

640?wx_fmt=png

Kubernetes提供的是将容器视为服务定义的能力。Kubernetes可以处理纯容器。即使你想在不进入微服务领域的情况下只部署容器,Kubernetes在管理和部署方面也能为你提供很多帮助。你在群集中的服务器上安装Kubernetes软件,Kubernetes主进程将自动部署你的软件。

除了基本的容器外,Kubernetes还可以使用它所称的Pod。Pod是由一个或多个服务组成的单独定义。Pod可以包含从单独运行的单个服务器到完整的多容器服务,例如数据库容器与键值存储和一个包含在一起的http服务器相结合。Pod是Kubernetes的基本构建块。

最后一个元素是服务。在Kubernetes中,服务就像是将Pod组合到应用程序中的配方。虽然Pod是具有生命周期的具体部署,但服务更抽象。它描述了一个单独的组件,如后端或数据库。

结合所有这些能力的是Kubernetes命令行工具kubectl。虽然Kubernetes提供的抽象很棒,但命令行工具非常强大,允许你使用kubectl命令描述对架构的复杂更改。总而言之,kubectl CLI工具包含近50种不同的命令,用于处理在修改基于容器的微服务部署过程中出现的所有情况(你总会出现出错的时候)。

动手实践一番

640?wx_fmt=png

虽然高层次描述很有帮助,但实际上没有什么比实际部署Kubernetes服务能更好的理解它的了。我们在这里没有做任何高深的东西,只是展示如何部署一个简单的“Hello World”服务,但它应该是有益的。

我们在Go中编写了一个简单的服务器,用“Hello World”响应http请求。代码非常简单:

package main	
   import (	
   "fmt"	
   "log"	
   "net/http"	
   "os"	
)	
func handler(w http.ResponseWriter, r *http.Request) {	
   log.Print("Hello world received a request.")	
   version := os.Getenv("VERSION")	
   if version == "" {	
      version = "v1"	
   }	
   log.Println(version)	
   fmt.Fprintf(w, "Hello world %s\n",version)	
}	
func main() {	
   log.Print("Hello world sample started.")	
   http.HandleFunc("/api/hello", handler)	
   port := os.Getenv("PORT")	
   if port == "" {	
   port = "8080"	
   }	
   log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))	
}

运行它的第一步是将其构建到Docker容器中。为此,我们从基础Go Docker镜像开始构建以下Dockerfile。

 # Use the official Golang image to create a build artifact.	
 # https://hub.docker.com/_/golang	
 FROM golang as builder	
 # Copy local code to the container image.	
 WORKDIR /go/src/github.com/haseebh/hello-world	
 COPY . .	
 RUN go build -o helloworld-v1 main/helloworld-v1.go	
 # Use a Docker multi-stage build to create a lean production image.	
 # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds	
 FROM alpine	
 COPY --from=builder /go/src/github.com/haseebh/hello-world-v1 /helloworld-v1	
 ENV PORT 8080	
 # Run the web service on container startup.	
 CMD ["/helloworld-v1"]

现在我们只需要构建它。选择一个镜像tag,然后运行以下两个Docker命令来构建和保存镜像:

 # Build the container on your local machine	
 docker build -t <image-tag> .	
 # Push the container to docker registry	
 docker push <image-tag>

在我们部署之前还有一步。虽然我们已经定义了将进入我们的Pod的内容,但我们还没有定义我们的服务。让我们做一个简单的服务定义,称为Hello Service。我们将它保存在hello-service.yml服务定义文件中。

apiVersion: v1	
kind: Service	
metadata:	
   name: helloworld-v1	
spec:	
   ports:	
      - port: 80	
      protocol: TCP	
      targetPort: 8080	
    selector:	
       app: helloworld-v1	
    type: LoadBalancer	
---	
apiVersion: apps/v1	
kind: Deployment	
metadata:	
   name: helloworld-v1	
   labels:	
      app: helloworld-v1	
spec:	
   replicas: 1	
   selector:	
      matchLabels:	
         app: helloworld-v1	
   template:	
      metadata:	
         labels:	
            app: helloworld-v1	
      spec:	
         containers:	
            - name: helloworld-kubernetes	
            # replace <image-tag> with your actual image	
              image: <image-tag>	
              ports:	
                - containerPort: 8080

现在我们已经拥有了所需的一切。我们的镜像已经构建,我们已经根据它定义了一项服务。现在我们终于可以使用Kubernetes来部署它了。我们将使用kubectl命令行工具将其部署在我们的集群上:

kubectl apply -f helloworld-go-v1.yaml

要获取服务负载均衡器IP,请运行以下命令:

kubectl get svc helloworld-v1 -o wide

记下外部IP。

现在,当我们访问负载均衡器地址时,我们可以看到已部署的服务。它并不多,但“Hello World”向我们展示了这一切都奏效了!

关键组件

640?wx_fmt=png

构建此服务使我们能够演示大多数主要的Kubernetes组件。首先,我们布置了Dockerfile来为服务创建代码。要在Kubernetes中实际创建服务,我们需要使用YAML来定义它。我们的定义采用我们定义的镜像并提供一些关键信息:应该部署的位置,版本以及其他配置信息。

之后,我们在Pod上部署了该服务。在Kubernetes模型中,Pod与容器密切相关。许多部署(如我们的部署)使用单个Pod进行服务。严格来说,Kubernetes不管理容器,它管理。有时这些容器与Pod有一对一的关系,有时候有多个容器关联到一个Pod。

最后,我们看到了编排的原则。在定义了我们希望如何部署API之后,我们只是将配置文件推送到Kubernetes并完成其余工作。使用kubectl,我们能够指定我们想要的架构,Kubernetes负责其余的工作。当我们稍后查看更复杂的示例时,通过多个版本和复杂的部署,我们将更清楚地看到这个简单想法的强大功能。

深入了解

640?wx_fmt=png

部署简单的服务只是一个开始。Kubernetes原生支持微服务,它能用很好的方式来部署基本的,甚至更复杂的微服务架构,而不会有太多的麻烦。但要真正利用微服务的可扩展性,你还需要知道更多。

在下一篇文章中,我们将介绍Istio。通过微服务方法,我们能够将单一的应用程序分解为多种服务。我们在第一篇文章中看到,这种方法为处理复杂系统提供了更多的开发人员敏捷性和更好的抽象。在这里,我们看到了如何使用Kubernetes在实践中部署微服务。下周,我们将开始研究微服务领域中的一些新兴概念,如微服务网格,以向你展示这些技术的真正能力。

原文链接:https://medium.com/faun/microservices-orchestration-with-kubernetes-1cbb737cfa46

基于Kubernetes的DevOps实战培训

640?wx_fmt=png

基于Kubernetes的DevOps战培训将于2019年9月27日在上海开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:容器特性、镜像、网络;Kubernetes架构、核心组件、基本功能;Kubernetes设计理念、架构设计、基本功能、常用对象、设计原则;Kubernetes的数据库、运行时、网络、插件已经落地经验;微服务架构、组件、监控方案等,点击下方图片或者阅读原文链接查看详情。

640?wx_fmt=jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值