分享

Docker+Jenkins实现可持续交付对微服务

fc013 发表于 2017-4-8 16:06:04 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 1 20052



问题导读:

1.微服务的架构是怎样的?
2.怎样创建定义的Dockerfile?
3.怎样实现持续交付?








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

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

微服务示例

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

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

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

640.jpg

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

Dockerfiles

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

[mw_shl_code=text,true]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[/mw_shl_code]

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

[mw_shl_code=xml,true]<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>[/mw_shl_code]

Jenkins管道

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

640.jpg

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

[mw_shl_code=text,true]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
        }      
    }
}[/mw_shl_code]

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

[mw_shl_code=text,true]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
        }      
    }
}[/mw_shl_code]

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

[mw_shl_code=bash,true]docker run -d --name registry -p 5000:5000 registry[/mw_shl_code]

测试

需要在 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.

[mw_shl_code=text,true]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[/mw_shl_code]

结论

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

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



来源:weixin
作者:博云

本帖被以下淘专辑推荐:

已有(1)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条