一.关于 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
构建本地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也能映射,但阿里云必须带这个.
第三个外网访问,必须要安全组开放
网友评论