前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零到一,构建你的持续交付流程(四):利用Docker,将服务容器化

从零到一,构建你的持续交付流程(四):利用Docker,将服务容器化

作者头像
御剑
发布2021-10-19 14:13:02
7040
发布2021-10-19 14:13:02
举报
文章被收录于专栏:微言码道

在持续交付的过程中,我喜欢将服务容器化,包括后端,前端都是。

当然移动端肯定就不在能容器化之列了,这个是额外要考虑的。

本篇,继续从零到一,构建你的持续交付流程,这是第四篇,本系列其它文章是:

  1. 从零到一,构建你的持续交付流程(一):一个持续交付流程的构思
  2. 从零到一,构建你的持续交付流程(二):好的工程实践是必要的前提
  3. 从零到一,构建你的持续交付流程(三):搭建基于Jenkins+Docker的持续交付环境

一)

提醒

持续交付的形态应该与最终项目或产品的部署形态二进制保持一致。如果你最终在生产上的部署形态是rpm包,那持续交付也应该是rpm包。不保持一致的持续交付,则失去了它本来应有的价值。

我更喜欢用Docker将服务容器化,我觉得这样在服务管理上比较方便。

明确点说就是:

  • 单个服务时,你可以用单个镜像来管理
  • 多个服务时,在单个机器上部署可以考虑docker compose (开发或测试环境)
  • 多个服务多个机器部署,则可以考虑docker swam或更重量级的k8s。

而且,对持续集成来说,管理docker服务非常方便,重启,停止或更新

代码语言:javascript
复制
#启动XX服务
docker start XXService
#关闭XX服务
docker stop XXService

如上,服务的管理都是比较方便的。

当然,这并不意味着只能用Docker,如果你是Jar或War,或RPM也好,DEB也好,Systemctl服务也行,都可以。但是切记,持续交付的二进制产物必须与实际生产保持一致,否则价值就大大降低了。

二)

接下来,我将分别简单就三种模式进行阐述:

  1. 将基于JDK的后端服务容器化管理
  2. 将基于npm的前端服务容器化管理
  3. 将一个后端服务+一个前端服务合并起来进行容器化管理

我需要再解释下,这个系列并不是技术教程,不会就涉及到的Docker知识一步一步的解释与说明。后续我会做Docker的专题系列。本系列的目标着重在让大家知道一个持续交付是如何构建起来的。这个过程中涉及到的技术仅做简单解释。

为了便于演示,整个过程,我会用我的myddd starter生成一个后端项目及一个前端项目来配合说明。访问https://starter.myddd.org 来快速生成项目。

如图所示,请使用myddd starter来快速生成项目,以配合后续的操作。

三)

请在myddd starter中,随便生成一个myddd-java的项目就好。生成的项目是基于gradle的,带了一些示例代码,也带了单元测试。非常方便我们接下来的演示。

之所以使用myddd-java,是因为这是Java+Spring Boot,大家熟悉,而且默认数据库是H2内存数据库,方便我们操作。而myddd-vertx则是kotlin+vertx结合,大多数人可能并不熟悉。

代码语言:javascript
复制
#如果需要本地编译,请安装gradle,我当前用的是gradle 7.2
gradle build

尝试gradle build,你可以成功的构建它。

生成与编译项目

比如,我生成了一个名称为test-backend的myddd-java项目,构建完后,可以在test-backend-bootstrap的build的libs目录下,找到最终运行的Jar。

你可以尝试在本机,使用java来运行

代码语言:javascript
复制
java -jar test-backend-bootstrap-1.0.0-SNAPSHOT.jar

这是一个基于Spring Boot的最终的fat jar。只要你的JDK不低于11,它就能正常运行。

当然,我们的目的不是这样,我们是希望以docker的容器化的模式来管理这个服务。

构建镜像

在项目的根目录下,新建名称为Dockerfile的文件。

代码语言:javascript
复制
# syntax=docker/dockerfile:1
  
#构建镜像
FROM openjdk:11.0.12-jre-slim
WORKDIR /app
COPY ./test-backend-bootstrap/build/libs/test-backend-bootstrap-1.0.0-SNAPSHOT.jar .
CMD ["java","-jar","/app/test-backend-bootstrap-1.0.0-SNAPSHOT.jar"]

在这里中,我仅仅简单解释下

  • 行1,申明你用的哪个dockerfile的语法。最新的就是这个了。
  • 行4,这个是指我们以OpenJDK 11为基础镜像,因为我们这是一个基于JDK11的Java应用。
  • 行5,这个是指在构建过程中,容器中进入的默认目录就是app,后面文件复制啊什么,就会以这个目录为标准来定位文件
  • 行6,这个,就是将我们先前生成的jar包,复制到"."(这有个点,别忽略了),也就是/app这个目录
  • 行7,最后,容器启动时,我们执行这个命令,这个相当于"java -jar /app/test-backend-bootstrap-1.0.0-SNAPSHOT.jar"

在项目当前目录下,执行以下构建镜像的命令

代码语言:javascript
复制
docker build -t test-backend:1 .

我们构建一个名为"test-backend"的镜像,tag为1。

第一次可能会下载一些基础镜像,时间会有点久。

然后,运行docker images来查看是否在本地生成成功。

代码语言:javascript
复制
REPOSITORY        TAG             IMAGE ID       CREATED         SIZE
test-backend      1               9455edc604ee   4 minutes ago   274MB

如上所示,出现这么个东西,表示你的镜像就生成成功啦 。

运行镜像

代码语言:javascript
复制
docker run --name=test-backend -d -p 8080:8080 test-backend:1

#如果你想查看日志
docker logs -f test-backend

如无意外,你能看到服务启动成功了。

是不是挺简单的?

四)

好,我们再来搞个前端的项目。

我们要学会举一反三,前端也好,后端也好,构建docker镜像服务的原理是一模一样的。

生成前端项目

好,再次访问https://starter.myddd.org, 生成一个myddd-web项目,这是一个基于typescript+react的项目。

举例说明,你生成了一个名称为test-front的项目。

生成完成后,执行以下命令

代码语言:javascript
复制
# 编译项目
npm install
# 以开发的模式运行它
npm run serve

访问https://127.0.0.1:3000, 你能见到这样的一个默认首页

如果需要编译生成包

代码语言:javascript
复制
npm run buildProd

成功后,dist目录下的文件就是最终的静态文件了,一般情况下,我们会把这上放到nginx上去。

制作镜像

同样,我们的目的还是要把这个也做成容器服务。

在项目目录下,创建一个Dockerfile的文件

代码语言:javascript
复制
# syntax=docker/dockerfile:1

FROM nginx:alpine
COPY ./dist /usr/share/nginx/html

好吧,这个就更简单了。

  • 行3,这个服务是基于nginx
  • 行4,我们把dist下的文件都复制到了nginx的默认主目录,也就是/usr/share/nginx/html

下一步,执行以下命令

代码语言:javascript
复制
docker build -t test-front:1 .

同理,我们用docker images来查看

代码语言:javascript
复制
REPOSITORY        TAG             IMAGE ID       CREATED          SIZE
test-front        1               813afab9fac1   33 seconds ago   23.5MB
test-backend      1               9455edc604ee   29 minutes ago   274MB

运行镜像

代码语言:javascript
复制
docker run --name=test-front -d -p 80:80 test-front:1

#如果要查看日志
docker logs -f test-front

同理后,访问https://127.0.0.1, 你可以见到刚刚在开发模式下一样的页面了。

五)

是不是挺简单的?

我们已经把后端,前端都做成了镜像服务,并且都能基于docker来方便的管理这些服务。

但是通常一个项目或产品,有前端,后端,数据库,可能还有缓存redis等,如果一个个来管理,非常麻烦。

在单台机器上,我们可以利用docker compose来集中式的管理服务,这个就非常方便了。

docker compose非常适合开发或测试环境,在单台机器上进行部署与管理服务。(如果是生产,则不适合了,生产你需要考虑docker swam或更复杂的k8s等技术了)

创建docker compse文件

先在合适的地方,创建一个test-compose目录(名称无所谓)

在test-compose目录下,新建docker-compose.yml文件。

文件内容如下:

代码语言:javascript
复制
  version: "3.9"
  
  services:
    test-backend:
      image: test-backend:1
      container_name: test-backend
      ports:
        - "8080:8080"
    test-front:
     image: test-front:1
     container_name: test-front
     ports:
       - "80:80"
     depends_on:
       - test-backend

简单解释下:

  • 行1: docker compose语法版本,最新为3.9
  • 行3:定义服务集,我们这个示例中包括一个后端test-backend以及一个前端test-front服务
  • 行4: 定义其中一个服务,名称为test-backend,镜像为test-backend:1,容器名称为 test-backend,开放的端口为8080
  • 行9-15: 定义另一个服务test-front

具体请参阅docker compose文档。

服务集的的启动与停止

基于docker compose来管理多个服务,它们的启动与停止就非常方便

代码语言:javascript
复制
#启动服务,-d表示运行在后台
docker-compose up -d

#停止服务
docker-compose stop

就是这么简单。

docker compose非常适合你的开发环境,或者你的测试环境。

提醒

在实际中,测试环境尽量应该是生产环境的mini版本,包括部署方式。因为生产大多不可能是docker compose来部署的,所以测试环境最好也不要使用docker compose。

六)

如上所说,将我们的服务,包括后端+前端用docker来管理,其实原理上非常简单,并不复杂。

虽然这个示例极其简单,但复杂的东西无非是在简单的东西之上再添加。只要你能理解这个过程,后面添加新的复杂的东西,就更轻易能理解了。

好了,我们已经学会怎么让我们的服务容器化了。

上面的过程我们都是手动在操作。这当然不是我们的目的。

上面这些过程,我们完全可以让Jenkins Pipeline来帮我们自动化的执行。这样就并不需要人工反复的执行这些东西了。

下一篇:从零到一,构建你的持续交付流程(四):使用Jenkins Pipeline,让一切自动化与流程化

附):

本篇文章中所涉及到的所有用myddd starter生成的项目,已放在github上,你可以访问https://starter.myddd.org, 来生成这些项目,也可以使用github上现成的示例。

https://github.com/lingen/continuous_delivery_example.git

同时,这个地址我们在下一篇文章中使用Jenkins会用到

备注:myddd.org是我个人维护的基于DDD理念的全栈式领域驱动开源基础框架,官网是https://myddd.org

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微言码道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一)
  • 二)
  • 三)
  • 四)
  • 五)
  • 六)
  • 附):
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档