一.关于 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