继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Docker部署Spring boot 应用 快速入门

哔哔one
关注TA
已关注
手记 462
粉丝 93
获赞 543

一.关于 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@SpringBootApplicationpublic 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 -aLinux 36976f3c166b 4.9.87-linuxkit-aufs #1 SMP Wed Mar 14 15:12:16 UTC 2018 x86_64 GNU/Linuxroot@36976f3c166b:/# cat /proc/cpuinfoprocessor   : 0vendor_id   : GenuineIntel
cpu family  : 6model       : 42model 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也能映射,但阿里云必须带这个.
第三个外网访问,必须要安全组开放



作者:蓝点工坊
链接:https://www.jianshu.com/p/2a32a4fc9852

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP