美文网首页Spring Boot我爱编程架构社区
Docker部署Spring boot 应用 快速入门

Docker部署Spring boot 应用 快速入门

作者: 蓝点工坊 | 来源:发表于2018-05-25 16:17 被阅读215次

    一.关于 Docker

    docker 可以理解是运行Linux和Mac OS X上的轻量级虚拟机,他相对于VMWare,Virtual Box这类完整的虚拟机相比,占用资源少,大量重用宿主资源,而且可以编程创建. 而且可以统一开发,测试和发布环境,是运行基于Linux后台服务器的利器.

    有三个重要概念

    • 镜像(Image)
    • 容器(Container)
    • 仓库(Repository)

    理解了这三个概念,就理解了 Docker 的整个生命周期。

    Docker 镜像

    Docker 镜像就是一个只读的模板。镜像的定义文件取名为 Dockerfile. 类似于shell格式

    Docker 容器

    Docker 利用容器来运行应用。

    容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

    可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

    Docker 仓库

    仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

    仓库分为公开仓库(Public)和私有仓库(Private)两种形式。

    最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool 等,可以提供大陆用户更稳定快速的访问。

    二.关于spring boot 的Docker 发布准备

    发布形式

    spring boot 为了简化开发,可以把应用,tomcat 服务统一打包在一个jar中,因此在Docker 发布spring boot 可以直接拷贝最终jar到docker中,另外一种方法把源码拷入docker 在,docker里面下载编译工具maven,jdk等自行编译,后面一种方法构建docker用时较长,每次都是重新下载相关jar依赖编译,不推荐.

    因此我们假设已经在本机编译好jar,每拷入这个jar即可.

    代码准备

    用 IDEA或Eclipse 配置发布版有一点步骤,为了简单操作,我们直接采用maven 命令来编译一个简单的Spring boot项目.

    程序的输出很简单,在浏览器访问docker 对应端口,输出一行提示,

    我们手动构造一个简单项目

    mkdir hello-docker ; cd hello-docker # 项目目录

    编辑pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.bluedrum.springdemo</groupId>
        <artifactId>bluedrum-spring-boot-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.1.RELEASE</version>
            <relativePath/>
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <docker.image.prefix>springio</docker.image.prefix>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
    
    
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <version>0.4.13</version>
                    <configuration>
                        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                        <dockerDirectory>src/main/docker</dockerDirectory>
                        <resources>
                            <resource>
                                <targetPath>/</targetPath>
                                <directory>${project.build.directory}</directory>
                                <include>${project.build.finalName}.jar</include>
                            </resource>
                        </resources>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    编辑源代码

    mkdir -p src/main/java/cn/bluedrum/springdemo

    在springdemo创建java文件 SampleController.java

    package cn.bluedrum.springdemo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    
    @Controller
    @SpringBootApplication
    public class SampleController {
    
        @ResponseBody
        @RequestMapping(value = "/")
        String home(){
            return "Hello Docker World2";
        }
    
        public static void main(String[] args) {
            SpringApplication.run(SampleController.class,"--server.port=8081");
        }
    }
    

    注意 "--server.port=8081",表示启动tomcat 端口是8081(而不是缺省的8080)

    编译成 jar

    这里要安装maven,
    编译成jar

    mvn package

    本地测试,需要安装jdk
    运行:

    java -jar target/bluedrum-spring-boot-demo-1.0-SNAPSHOT.jar

    如果程序正确运行,浏览器访问 http://localhost:8081/,可以看到页面 “Hello Docker World2” 字样

    三.本地Docker 发布

    Docker 标准推荐操作系统是 Ubuntu 64位,如 14.04 ,16.06版本. 其它的操作系统的需要使用置virtual box 虚拟机上的Ubuntu上运行Docker,

    但 新的Docker 在Mac 下开发的一个 MacOS Hypervisor framework,相当于在其构造一个性能很高的专用虚拟机.

    因此在你看这篇文章时,Mac OSX和Ubuntu 64均是标准的Docker 安装环境.

    Mac OS X安装

    可以下载 Docker 社区版,安装
    https://store.docker.com/editions/community/docker-ce-desktop-mac

    安装后会有一个图标出现在顶部

    image.png

    所有配置均可用图形界面,为了提高docker image 下载速度,可以使用
    国内docker 加速网站,
    常见有 http://www.daocloud.io/mirror
    阿里云的加速服务 http://dev.aliyun.com

    image.png

    构建本地docker 容器

    首先要编辑Dockerfile 文件

    FROM java:8
    EXPOSE 8081
    VOLUME /tmp
    ADD bluedrum-spring-boot-demo-1.0-SNAPSHOT.jar app.jar
    RUN sh -c 'touch /app.jar'
    ENV JAVA_OPTS=""
    ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
    

    以下是解释
    FROM 表示本image是哪一个基础image继承而来, java:8是带有jdk8运行环境的image

    EXPOSE 8081 表示本docker 要把本地8081进行映射,这个测试在mac下无所谓,但在阿里云这样docker 必须有这一句,否则映射会失败.

    VOLUME /tmp VOLUME 指定了数据文件目录为/tmp。其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp ,这样做是因为docker 重启后所有数据丢失,持久数据保存在VOLUME指定目录下才会下次使用.

    ADD表示把文件拷入docker ,并改名成 app.jar

    ENTRYPOINT 表示docker 启动执行第一个指令,这里是调用java 启动 jar

    命令行构建

    构建容器方法有两种,一种是调用docker build 指令手动建
    在Dockerfile 所在目录执行如下指令(注意,这个jar必须和Dockerfile同一路径下)

    docker build -t hxy .

    build表示构建容器,. 表示构建文件在当前目录. -t 指明本容器的tag名字,方便调用.

    这是一个成功调用,

    docker build -t hxy .
    Sending build context to Docker daemon  63.43MB
    Step 1/7 : FROM java:8
     ---> d23bdf5b1b1b
    Step 2/7 : EXPOSE 8081
     ---> Using cache
     ---> af40c4f0bb64
    Step 3/7 : VOLUME /tmp
     ---> Using cache
     ---> 5a0abb6e6149
    Step 4/7 : ADD bluedrum-spring-boot-demo-1.0-SNAPSHOT.jar app.jar
     ---> 135b017b65bd
    Step 5/7 : RUN sh -c 'touch /app.jar'
     ---> Running in b3089dd7490a
    Removing intermediate container b3089dd7490a
     ---> 472354c65e33
    Step 6/7 : ENV JAVA_OPTS=""
     ---> Running in 01cec8aeaaa9
    Removing intermediate container 01cec8aeaaa9
     ---> fb2dd3c02514
    Step 7/7 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
     ---> Running in c2a93f997776
    Removing intermediate container c2a93f997776
     ---> de32f8f2ac97
    Successfully built de32f8f2ac97
    Successfully tagged hxy:latest
    
    

    Successfully built de32f8f2ac97 这里指明image ID. 在后续的操作中用使用

    启动docker 容器

    以下表示启动指定image .

    docker run de32f8f2ac97 -p 8081:8081

    -p <本地端口>:<docker端口> 表示把docker 端口映射到本地端口来.

    测试用 http://localhost:8081 有输出即可

    还有一种调用是用tag调用,不指定话默认用最新那个

    docker run -t hxy -p 8081:8081

    停止容器实例

    docker stop 484b1a9b8a49 #用docker ps 查看
    docker stop -t hxy

    maven插件构建

    这里也可采用maven插件docker-maven-plugin 调docker 命令,优点是编译完后自动构建,并且有推送到远程仓库功能

    这里关键是在pom.xml有其申明,其中dockerDirectory 是指明Dockerfile所在目录,

     <artifactId>docker-maven-plugin</artifactId>
                    <version>0.4.13</version>
                    <configuration>
                        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                        <dockerDirectory>.</dockerDirectory>
                        <resources>
                            <resource>
                                <targetPath>/</targetPath>
                                <directory>${project.build.directory}</directory>
                                <include>${project.build.finalName}.jar</include>
                            </resource>
                        </resources>
                    </configuration>
    

    执行命令,这里执行编译,并枸造docker 实例

    mvn package docker:build

    四.docker 调试

    查看运行实例 docker ps

    查看所有运行实例

    CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                    NAMES
    484b1a9b8a49        de32f8f2ac97                         "sh -c 'java $JAVA_O…"   2 minutes ago       Up 2 minutes        8081/tcp                 angry_visvesvaraya
    c54ede741112        springio/bluedrum-spring-boot-demo   "sh -c 'java $JAVA_O…"   2 days ago          Up 2 days           0.0.0.0:8081->8081/tcp   agitated_swirles
    
    

    这里第一列 CONTAINER ID 即可容器ID,后续各项操作均要用到此ID
    PORTS是用来判断网络映射状态, 如果为空,表示完全没有网络映射,如网络出问题,没有侦听服务

    如果为 8081/tcp 形式表示,只在docker 启动了端口侦听,但没有映出来,因此外部是无法访问的.

    0.0.0.0:8081->8081/tcp 只有这样形式,表示外部的8081端口,映射到内部端口,这样才是正常工作

    docker images

    查看所有image

    REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
    hxy                                  latest              de32f8f2ac97        About an hour ago   685MB
    springio/bluedrum-spring-boot-demo   latest              7df85e003c92        2 days ago          695MB
    docker-demo                          latest              af850b972103        2 days ago          669MB
    <none>                               <none>              da7283718e15        2 days ago          669MB
    <none>                               <none>              381c4e1fa40c        3 days ago          653MB
    <none>                               <none>              3ef8dca1797a        3 days ago          674MB
    hub.c.163.com/wuxukun/maven-aliyun   3-jdk-8             676639454cb4        15 months ago       653MB
    java                                 8                   d23bdf5b1b1b        16 months ago 
    

    注意这里的size 表示占用空间大小,所以本地docker 如果不用,尽量删掉

    连接docker 内部控制台

    有时我们想连接docker 内部的虚拟机进行各种命令来分析测试,

    docker exec -ti <CONTAINER ID> bash

    以下是一个例, -t 表示attach 到某个容器上,i 表示交互模式,本句完整意思在某个容器上以交互模式执行bash ,相当进入控制台.

    docker exec -ti 36976f3c166b bash
    root@36976f3c166b:/# uname -a
    Linux 36976f3c166b 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 GNU/Linux
    root@36976f3c166b:/# cat /proc/cpuinfo
    processor   : 0
    vendor_id   : GenuineIntel
    cpu family  : 6
    model       : 42
    model name  : Intel(R) Core(TM) i7-2720QM CPU @ 2.20GHz
    

    删除容器

    docker rm <容器ID>
    注意正在运行容器,需要用 docker stop 后才能删除

    删除镜像

    docker rmi <image ID>

    五,在阿里云运行容器

    在阿里云,我们采用ubuntu 64bit .有两种方法来运行容器,一种还是象本地操作来传统的命令行,另外一种采用阿里云的容器服务,后面相当于用网页来图形式操作,并且有日志/监控等运维界面.

    本文中仍然采用命令行来运行. 以便适合主题快速入门.

    安装docker

    用apt安装 docker 的版本太低

    apt-get install docker.io

    版本为1.6

    阿里云建议采用 dokcer ce版(社区版).用如下命令安装,版本较新

    curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

    uname -a
    116~14.04.1-Ubuntu SMP Mon Aug 14 16:07:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
    docker --version
    Docker version 18.05.0-ce, build f150324

    修改docker 缺省配置

    新版的docker 配置放在/etc/docker/daemon.json

    {
      "bip": "192.168.1.5/24",
     "debug": true,
     "registry-mirrors": ["https://fzxn****.mirror.aliyuncs.com"]
    }
    

    --bip 指定docker 的虚拟网卡的ip地址, 缺省的网卡地址 172.18.xxx.xxx 而阿里云内网网卡也是172.19 网段,这两个很容易冲突,造成映射失败.

    "registry-mirrors" 是阿里云docker 加速网址,可到阿里云控制台申请,

    启动docker

    service docker start

    上传文件

    Dockerfile ,jar 各种文件用 scp 上传到阿里云服务器

    构建运行

    还是用 docker build/run 进行构建,跟本地是一样的

    测试

    首先用本地测试 用 curl
    如果有输出即表示成功

    curl http://127.0.0.1:8081
    Hello Docker World2

    外网测试 ,需要用阿里云控制台,用安全组打开这个端口,外网才能访问


    image.png

    用外网ip 或网址测试后输出后表示成功

    问题测试

    首先要判断一下,网卡是否有网址冲突(docker ps 中ports 为空),如有需要用 --bip参数错开私有网址
    另外要有EXPOSE 指令,在本地测试时,没有expose也能映射,但阿里云必须带这个.
    第三个外网访问,必须要安全组开放

    相关文章

      网友评论

      本文标题:Docker部署Spring boot 应用 快速入门

      本文链接:https://www.haomeiwen.com/subject/ncohjftx.html