从Docker 到Jenkins 到Ansible的部署经验

https://www.cnblogs.com/itdragon/p/10011816.html

工作中,除了开发功能,还负责系统的部署工作。我从频繁的部署工作中,逐渐找到了一些偷懒的方法。从传统的Java -jar命令启动服务,到通过Docker 容器构建部署服务,再后来通过自动化部署工具Jenkins来完成部署,最后再结合Ansible完成远程部署。一步步的进步极大的减少部署工作,提高了工作效率(增加了许多划水时间)。

Docker
简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

Docker给我的印象很深,没有什么环境是docker pull 解决不了的,

常用命令
docker ps , docker ps 默认显示运行中的容器,-a 显示所有,-l显示近期创建的容器

docker start xxx , 启动xxx容器

docker restart xxx , 重启xxx容器

docker run xxx , 创建并运行xxx容器

docker build -t xxx . ,使用 Dockerfile 创建镜像

docker stop xxx , 关闭容器

docker rm xxx , 删除容器

docker images , 查看所有镜像

docker rmi xxx , 删除xxx镜像

docker exec -it xxx sh , 进入xxx容器中,用quit退出

docker logs -f xxx --tail 500 , 查看xxx容器的日志,显示最后500行,常用命令

docker inspect xxxx , 查看容器配置信息

docker-compose -f app.yml up -d , 按照app.yml文件配置以debug形式启动

docker-compose -f app.yml down , 按照app.yml文件配置形式关闭
使用场景
第一步:在gradle项目加入docker插件,即在gradle.build 文件中加入以下代码。需要注意的有插件的版本,项目打包后的名称,Dockerfile文件目录

dependencies {
classpath("se.transmode.gradle:gradle-docker:1.2")
}

apply plugin: 'docker'

task buildDocker(type: Docker, dependsOn: build) {
push = false
applicationName = "项目名"
dockerfile = file('src/main/docker/Dockerfile文件目录')
doFirst {
copy {
from jar
into stageDir
}
}
}
第二步:创建Dockerfile文件,文件目录要和第一步中设置的保持一致。需要配置jdk镜像和基本的启动参数

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD 项目jar名称.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENV PORT="6666"
ENV DB_CONNECTION="jdbc:mysql://ip:port/database"
ENV DB_USER="user"
ENV DB_PASSWORD="password"
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar --spring.datasource.url=$DB_CONNECTION --spring.datasource.usernam=$DB_USER --spring.datasource.password=$DB_PASSWORD --port=$PORT"]
第三步:将jar拷贝到服务器上,然后执行编译,运行的docker命令

一)、通过gradle的bootJar,将项目打包。同时需要把引入的第三方jar也要一起打入到项目jar中。

二)、Windows系统中可以通过Xftp将jar和Dockerfile文件拷贝同一个目录下。Linux系统可以通过scp命令上传文件。

三)、执行docker ps,查看当前运行的容器,执行docker stop和docker rm 关闭和删除之前旧版本的容器

四)、找到jar的目录,并在当前目录下,执行 docker build -t 镜像名称 . 的命令编译项目,注意后面的点不要漏了。

五)、编译成功后执行 docker run --name 容器名 -v /tmp:/tmp -p 对外开发的端口:项目启动的端口 镜像名:latest 。启动容器

六)、执行docker ps,查看容器启动是否正常启动。同时执行docker logs -f 容器名 --tail 500,查看容器启动日志,检查是否有异常

七)、最后浏览器访问一下,已确保部署成功。

全称大概需要几分钟的时间,虽然不算麻烦。可次数多了,就很麻烦了。有没有什么好的工具帮助我们完成这一系列操作呢?答案是肯定的。

Jenkins
简介
The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.

Jenkins 的logo是一个管家的形象,很贴切。对它的理解比较肤浅。他通过管理Git上的项目,来确保每次打包的jar都是最新的。同时在构建成功后执行我们输入的shell命令,来达到自动化部署的工作。

使用场景
第一步:创建一个负责编译的Jenkins项目,

在Jenkins控制台页面,点击页面左上角的“新建”按钮。再输入项目名后,可以选择创建一个空项目,也可以在页面最下面选择copy from 其他项目。不管如何创建,我们需要Jenkins管理项目的源码,构建和构建后的操作。

第二步:创建一个负责运行的Jenkins项目

以同样的方式创建项目,在构建触发器上,选择第一步创建的项目,构建的Shell命令是先删除之前的容器,然后在重新运行容器。若之前的容器不存在,则会构建失败。所以第一次构建的时候把第一行命令删掉。解决方案傻乎乎的,只是因为没有花时间去处理。

第三步:选择编译项目,点击立即构建,当第一个项目构成成功后,会自动触发运行项目。等待两个项目都成功后,就可以访问浏览器,检查功能。

有了Jenkins,一切变得轻松很多。但他也有一个较大的弊端,就是使用前必须要先安装。特别是在客户的服务器上,也许别人就只跑这一个服务,你给别人整了一个Jenkins,似乎有点大材小用了。有没有好的解决方法?答案是肯定的。

Ansible
简介
Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.

从接触到使用Ansible大概有一天的时间,对它的理解也是比较肤浅。我单纯的认为,他可以帮助我们在服务器之间传输文件,同时还可以执行一些shell命令。抱着这样的想法,我们可以通过Jenkins完成自动化编译,再通过Ansible传输资源文件到部署的环境中,同时执行启动Shell命令。

使用场景
第一步:修改Jenkins运行项目的构建Shell,将之前的docker run改成

ansible-playbook ansible命令文件路径/app.yaml
第二步:创建Ansible脚本文件app.yaml,目录和第一步中设置的保存一致,模版大致如下

  • hosts: '需要部署的远程服务ip'
    tasks:

    • name: "关闭旧版本的容器"
      shell: docker stop xxx
      ignore_errors: true
    • name: "删除旧版本的容器"
      shell: docker rm xxx
      ignore_errors: true
    • name: "删除之前的旧文件"
      shell: rm -rf /旧文件路径/*
    • name: "传输Dockerfile文件"
      copy:
      src=/文件目录/Dockerfile
      dest=/远程服务指定目录
    • name: "传输Jar文件"
      copy:
      src=/jar目录/xxx.jar
      dest=/远程服务指定目录
    • name: "构建docker 镜像"
      shell: chdir=/jar所在目录 nohup docker build -t 镜像名 .
    • name: "启动容器"
      shell: nohup docker run --name 容器名 -v /挂载路径/:/挂载路径/ -p 对外端口:服务端口 -d 镜像名:latest
      第三步:在Jenkins上构建编译项目。

前后端项目的部署
到这里,三种部署的流程就完成了。如果你熟悉Docker的方式构建,再用Jenkins和Ansible的时候,就会简单很多。我在实际开发中,项目是前后端分离的。公司做了两个方案,

第一种:前后端分开部署,即Jenkins上有四个项目。前端和后端各两个项目。这样的好处就是前后端互不影响。不会因为对方的错误而从新编译。缺点也是有的,很难保证对方部署的环境是最新的。

第二种:把前后端放在一个项目中,一次构建完成两个项目的打包部署。缺点是构建慢,优点就是保证两端的代码都是最新的,适合发布到预发布环境和正式环境。

那么,针对前后端一起部署的需求,Jenkins和Ansible同样也需要简单的修改。其思路就是Jenkins负责编译项目,将资源文件压缩,再通过Ansible上传到其他服务器上。执行解压,构建,启动的命令。

看起来视乎很简单,但有一个坑希望你们跨过去。前端打包需要npm或者其他工具,但是你的服务器上没有安装。此时请务必通过Jenkins控制台,或者用Jenkins帐号登录服务器安装这些工具。笔者就是通过root帐号登录服务器安装的npm,通过Jenkins编译时提示没有权限。

部署经验Docker的更多相关文章

  1. 从Docker 到Jenkins 到Ansible的部署经验

    从Docker 到Jenkins 到Ansible的部署经验 工作中,除了开发功能,还负责系统的部署工作.我从频繁的部署工作中,逐渐找到了一些偷懒的方法.从传统的Java -jar命令启动服务,到通过 ...

  2. 本地部署 Misago Docker + 配置 HTTPS 笔记

    最近答应帮朋友做个论坛网站,想借此机会捡起 Python 在 GitHub 找了一圈,打算借用以 Python+Django 开发的 Misago 这个论坛系统 由于作者在今年更新的 Misago 0 ...

  3. 使用Docker构建持续集成与自动部署的Docker集群

    为什么使用Docker " 从我个人使用的角度讲的话  部署来的更方便 只要构建过一次环境 推送到镜像仓库 迁移起来也是分分钟的事情 虚拟化让集群的管理和控制部署都更方便 hub.docke ...

  4. docker:(5)利用docker -v 和 Publish over SSH插件实现war包自动部署到docker

    在 docker:(3)docker容器挂载宿主主机目录 中介绍了运行docker时的一个重要命令 -v sudo docker run -p : --name tomcat_xiao_volume ...

  5. Ubuntu16.04 部署安装Docker容器 & 注意事项

    一.部署安装Docker容器 1.1 Ubuntu下安装 crul sudo apt install curl curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多 ...

  6. 把ABP框架部署到Docker中

    本文旨在将Abp项目部署到Docker容器中,借助Gitee存储,Jenkins持续构建,利用Docker Compose生成镜像.启动镜像,在官网给定的Abp项目中,虽然用到了Dockerfile. ...

  7. .net4.5部署到docker容器

    .net4.5部署到docker容器 部署到windows容器 部署到linux容器 部署到windows容器 由于.net本身就是运行在windows平台的,所以它与windows容器也是更加适合, ...

  8. aspnetcore2.1 部署到docker (访问出现404)

    Dockerfile FROM microsoft/dotnet:2.1-aspnetcore-runtime WORKDIR /app COPY ./publish . ENTRYPOINT [&q ...

  9. .net core Ocelot实现API网关并部署在docker中

    基于Ocelot(http://ocelot.readthedocs.io)搭建的API网关demo 软件以及系统版本:  Asp.Net Core 2.2 Ocelot 13.5.0 CentOS ...

随机推荐

  1. Helper Files

    常用帮助类 C#语法糖 Net 通用工具类 Helloweba Front Program Resources jqGrid   Highcharts  jQuery实现的加载页面过渡效果   jQu ...

  2. mac 下测试各种IE版本

    背景 作为前端开发,在谈到兼容性时不得不谈到IE浏览器,那么,如果在mac上该怎么测试各种版本的IE呢 方法 1. 下载VirtualBox虚拟器 2. 下载安装了对应版本的windows系统,htt ...

  3. winform无边框窗体点击任务栏最小化

    protected override CreateParams CreateParams { get { const int WS_MINIMIZEBOX = 0x00020000; // Winus ...

  4. 全--教程API, gem 'rest-client'(用于发简单请求); 请求测试;

    安装:rest-client4400✨ gem install rest-client 一个简单的HTTP和REST client for Ruby. 可以用它来发HTTP请求 基本用法: requi ...

  5. wireshark抓取mysql数据包

    最近在学习搭建数据库服务,因为跟产品相关所以需要从流量中拿到mysql的数据包.然后就想着在本机搭建mysql数据库,然后连接,用wireshark抓就行了. MySQL搭建用的是XAMPP,想说XA ...

  6. LeetCode 275. H-Index II

    275. H-Index II Add to List Description Submission Solutions Total Accepted: 42241 Total Submissions ...

  7. 1-18 编译安装内核支持ntfs文件系统

    大纲: 源码编译Linux内核 使用Linux内核模块 实战:编译一个NTFS内核模块,实现Linux挂载NTFS文件系统并实现读写功能 =============================== ...

  8. 51nod-1103-抽屉原理

    1103 N的倍数  题目来源: Ural 1302 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 一个长度为N的数组A,从A中选出若干个数,使得 ...

  9. vue-router防跳墙控制

    vue-router防跳墙控制 因为在实际开发中,从自己的角度来看,发现可以通过地址栏输入地址,便可以进入本没有权限的网页.而我们一般只是操作登录页面,其他页面很少考虑,此刻特来尝试解决一下 基于vu ...

  10. week13《java程序设计》第13次作业总结

    week13<java程序设计>第13次作业总结 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 答: 1.IP与端口:ip和域名相对应,可找 ...