LOADING

Follow me

译文 | 使用Docker和Jenkins进行微服务持续交付【zoues.com】
三月 29, 2017|DockerPaaS

译文 | 使用Docker和Jenkins进行微服务持续交付【zoues.com】

译文 | 使用Docker和Jenkins进行微服务持续交付【zoues.com】

译文 | 使用Docker和Jenkins进行微服务持续交付

作者:Piotr Mińkowski 

翻译:袁思思

来源:SZone

原文链接:https://dzone.com/articles/microservices-continuous-delivery-with-docker-and


Docker,微服务,持续交付是编程世界中当前最流行的话题。在一个环境中,包含几十个微服务相互通信,这似乎是非常重要的自动化测试、创建和部署进程。Docker是一个优秀的微服务解决方案,因为它可以创建和运行隔离的容器服务。


今天我将演示如何创建一个基础的持续交付管道,使用流行的软件自动化工具Jenkins,做一个微服务示例。



微服务示例


在我进入这篇文章的核心主题前,我先说说关于架构和用于微服务示例创建的工具。示例应用包含两个微服务示例互相通信(账户,客户),一个发现服务器(Eureka),和一个API网关(Zuul)。使用Spring Boot和Spring Cloud架构来实施。资源代码可以在GitHub上获得。Spring Cloud支持微服务发现和网关在box外——我们只要在maven项目配置文件(pom.xml)中定义正确的相关性。


下面的图片说明了采用解决方案架构是可见的。客户,账户REST API服务,发现服务,和网关正在隔离的Docker容器内运行。网关是微服务系统的入口。与所有其他服务相互作用。在发现服务中,代理请求选择微服务搜索它的地址。在每个账户或客户微服务存在多个实例的情况下,请求用Ribbon 和Feign 客户端负载均衡。


账户和客户服务在启动后,把它们自己登记到发现服务中。它们之间也有相互作用的可能性——例如,如果我们想要发现和返回所有客户的账户细节。

译文 | 使用Docker和Jenkins进行微服务持续交付


这次就不探究用Spring Boot和Spring Cloud架构实施微服务的细节了。如果对示例应用开发的细节描述感兴趣,可以在我的博客里阅读(https://piotrminkowski.wordpress.com/2017/02/05/part-1-creating-microservice-using-spring-cloud-eureka-and-zuul/)。通常,Spring架构对微服务有一个完整的支持,使用所有Netflix OSS工具,比如Ribbon, Hystrix,和Eureka。在博客中,我描述了如何实施服务发现,分布式追踪,负载均衡,记录跟踪ID传播,和这些解决方案的微服务API网关。



Dockerfiles


示例资源代码中的每个服务都有一个Docker镜像创建定义的Dockerfile。这非常的简单。这是Dockerfile的账户服务。我们用OpenJDK作为基础镜像。来自目标的JAR文件增加到镜像中,然后使用 java -jar 命令运行。服务在端口2222运行,在外部公开。

FROM openjdk

MAINTAINER Piotr Minkowski <piotr.minkowski@gmail.com>

ADD target/account-service.jar account-service.jar

ENTRYPOINT [“java”, “-jar”, “/account-service.jar”]

EXPOSE 2222


还必须在JAR清单里设置主要类别。我们在pom.xml模式中使用spring-boot-maven-plugin 来实现。下面可以看到片段。我们也设置创建 finalName 中断目标JAR文件版本号。Dockerfile和Maven创建定义和所有其他微服务非常类似。

<build>

  <finalName>account-service</finalName>

  <plugins>

    <plugin>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-maven-plugin</artifactId>

      <version>1.5.2.RELEASE</version>

      <configuration>

        <mainClass>pl.piomin.microservices.account.Application</mainClass>

        <addResources>true</addResources>

      </configuration>

      <executions>

        <execution>

          <goals>

            <goal>repackage</goal>

          </goals>

        </execution>

      </executions>

    </plugin>

  </plugins>

</build>



Jenkins管道


为了我们的微服务,使用管道插件来创建持续交付。设置Jenkins,除了标准插件,还需要Docker管道插件CloudBees。下面图中有4个管道定义可以看看。

译文 | 使用Docker和Jenkins进行微服务持续交付


这是发现服务用Groovy语言写的管道定义。执行需要5歩。在Checkout步骤里,把变更pull到项目远程Git资源库中。然后用MVN安装命令创建项目,Maven版本从 pom.xml读取。在镜像步骤,从发现服务Dockerfile创建一个Docker镜像,然后把镜像push到本地注册表。在第四步,用公开的默认端口运行创建的镜像,连接docker容器主机名可见。最后,账户管道从no wait选项开始,意味着资源管道结束,将不会等待账户管道执行完成。

node {

    withMaven(maven:’maven’) {

        stage(‘Checkout’) {

            git url: ‘https://github.com/piomin/sample-spring-microservices.git’, credentialsId: ‘github-piomin’, branch: ‘master’

        }

        stage(‘Build’) {

            sh ‘mvn clean install’

            def pom = readMavenPom file:’pom.xml’

            print pom.version

            env.version = pom.version

        }

        stage(‘Image’) {

            dir (‘discovery-service’) {

                def app = docker.build “localhost:5000/discovery-service:${env.version}”

                app.push()

            }

        }

        stage (‘Run’) {

            docker.image(“localhost:5000/discovery-service:${env.version}”).run(‘-p 8761:8761 -h discovery –name discovery’)

        }

        stage (‘Final’) {

            build job: ‘account-service-pipeline’, wait: false

        }      

    }

}


账户管道非常类似。主要的区别是,在第四步里,账户服务容器连接到发现容器。我们需要去连接那些容器,因为 account-service 把自己登记到发现服务中,并且必须使用主机名连接它。

node {

    withMaven(maven:’maven’) {

        stage(‘Checkout’) {

            git url: ‘https://github.com/piomin/sample-spring-microservices.git’, credentialsId: ‘github-piomin’, branch: ‘master’

        }

        stage(‘Build’) {

            sh ‘mvn clean install’

            def pom = readMavenPom file:’pom.xml’

            print pom.version

            env.version = pom.version

        }

        stage(‘Image’) {

            dir (‘account-service’) {

                def app = docker.build “localhost:5000/account-service:${env.version}”

                app.push()

            }

        }

        stage (‘Run’) {

            docker.image(“localhost:5000/account-service:${env.version}”).run(‘-p 2222:2222 -h account –name account –link discovery’)

        }

        stage (‘Final’) {

            build job: ‘customer-service-pipeline’, wait: false

        }      

    }

}


类似管道也为客户和网关服务定义了。在每个微服务上,作为Jenkinsfile,在主项目目录里它们是可见的。每个镜像在管道执行期间创建,也push到本地Docker注册表里。为了使本地注册表在我们的主机上,需要pull并且运行Docker资源库镜像,在pull或push的时候,也使用注册表地址作为一个镜像名称前缀。本地注册表在它默认的5000端口公开。你可以看到push镜像到本地注册表的列表,通过调用REST API,例如http://localhost:5000/v2/_catalog. 

docker run -d –name registry -p 5000:5000 registry



测试


需要在 discovery-service-pipeline上发动创建。这个管道将不仅为发现服务运行创建,也调用启动下一管道在最后创建(account-service-pipeline) 。


同样的规则也配置在 account-service-pipeline ,调用customer-service-pipeline 和为customer-service-pipeline, 调用gateway-service-pipeline.


因此,在所有的管道结束,你可以通过使用docker ps 命令,检查运行docker容器列表。应该看到5个容器:本地注册表和4个微服务。


还可以检查每个容器的日志,通过运行docker logs 命令——例如docker logs account。如果一切运行顺利,应该可以调用一个服务http://localhost:2222/accounts 或者通过Zuul网关http://localhost:8765/account/account.

CONTAINER ID        IMAGE                                           COMMAND                  CREATED             STATUS              PORTS                    NAMES

fa3b9e408bb4        localhost:5000/gateway-service:1.0-SNAPSHOT     “java -jar /gatewa…”   About an hour ago   Up About an hour    0.0.0.0:8765->8765/tcp   gateway

cc9e2b44fe44        localhost:5000/customer-service:1.0-SNAPSHOT    “java -jar /custom…”   About an hour ago   Up About an hour    0.0.0.0:3333->3333/tcp   customer

49657f4531de        localhost:5000/account-service:1.0-SNAPSHOT     “java -jar /accoun…”   About an hour ago   Up About an hour    0.0.0.0:2222->2222/tcp   account

fe07b8dfe96c        localhost:5000/discovery-service:1.0-SNAPSHOT   “java -jar /discov…”   About an hour ago   Up About an hour    0.0.0.0:8761->8761/tcp   discovery

f9a7691ddbba        registry                                        “/entrypoint.sh /e…”   About an hour ago   Up About an hour    0.0.0.0:5000->5000/tcp   registry



结论


我已经展示了使用Docker和Jenkins的微服务的持续交付环境的基础示例。你可以轻松的发现所提出的解决方案的局限性。例如,我们在它们之间互相连接Docker容器来通信,或者所有的工具和微服务在同样的机器上运行。


更高级的示例,我们可以用Jenkins slaves在不同的机器或者Docker容器上运行(更多https://piotrminkowski.wordpress.com/2017/03/13/jenkins-nodes-on-docker-containers/),工具像是编排和集群工具Kubernetes,或者Docker-in-Docker容器模拟多个Docker机器。我希望这篇文章是对微服务和持续交付的好介绍,并且庄主你理解基础的理念。我想你可以期待在不久的将来,关于这个项目的我更多最新的文章。

 

译文 | 使用Docker和Jenkins进行微服务持续交付

上期回顾

私有云 混合云 自动化运维

关于BoCloud博云

BoCloud 博云,为企业级客户提供针对互联网化、大数据业务应用、去IOE 化(X86 服务器规模化应用)的底层云化架构和智能云运维系统,运用最新容器技术协助企业完成IT 系统云架构的实施和运维, 帮助企业客户降低成本、提升效率、简化运维、提高系统可靠性和安全性。凭借对客户业务流程和应用的深刻理解,以及先进技术产品的持续研发, BoCloud 博云以创新云技术支撑企业核心业务,促进企业IT 系统的不断进化。

www.bocloud.com.cn

译文 | 使用Docker和Jenkins进行微服务持续交付
no comments
Share

发表评论