如今
Docker
的使⽤已经⾮常普遍,特别是在⼀线互联⽹公司,使⽤
Docker
技术可以帮助企业快速⽔平扩展
服务,从⽽达到弹性部署业务的能⼒。在云服务概念兴起之后,
Docker
的使⽤场景和范围进⼀步发展,如今
在微服务架构越来越流⾏的情况下,微服务
+ Docker
的完美组合,更加⽅便微服务架构运维部署落地。
什么是 Docker
Docker
最初是
dotCloud
公司创始⼈
Solomon Hykes
在法国期间发起的⼀个公司内部项⽬,它是基于
dotCloud
公司多年云服务技术的⼀次⾰新,并于
2013
年
3
⽉以
Apache 2.0
授权协议开源,主要项⽬代码
在
GitHub
上进⾏维护。
Docker
项⽬后来还加⼊了
Linux
基⾦会,并成⽴推动 开放容器联盟(
OCI
)。
Docker
属于
Linux
容器的⼀种封装,提供简单易⽤的容器使⽤接⼝,它是⽬前最流⾏的
Linux
容器解决⽅
案。
Docker
将应⽤程序与该程序的依赖打包在⼀个⽂件⾥⾯,运⾏这个⽂件,就会⽣成⼀个虚拟容器。程序
在这个虚拟容器⾥运⾏,就好像在真实的物理机上运⾏⼀样,有了
Docker
,就不⽤担⼼环境问题了。
总体来说,
Docker
的接⼝相当简单,⽤户可以⽅便地创建和使⽤容器,把⾃⼰的应⽤放⼊容器。容器还可以
进⾏版本管理、复制、分享、修改,就像管理普通的代码⼀样。
为什么要使⽤ Docker
容器除了运⾏其中应⽤外,基本不消耗额外的系统资源,使得应⽤的性能很⾼,同时系统的开销尽量⼩。传
统虚拟机⽅式是运⾏
10
个不同的应⽤就要启动
10
个虚拟机,⽽
Docker
只需要启动
10
个隔离的应⽤即
可。
具体说来,
Docker
在如下⼏个⽅⾯具有较⼤的优势。
- 更快速的交付和部署,开发者可以使⽤⼀个标准的镜像来构建⼀套开发容器,开发完成之后,运维⼈员 可以直接使⽤这个容器来部署代码。
- 更⾼效的虚拟化,Docker 容器的运⾏不需要额外的 hypervisor ⽀持,它是内核级的虚拟化,因此可以 实现更⾼的性能和效率。
- 更轻松的迁移和扩展,Docker 容器⼏乎可以在任意的平台上运⾏,包括物理机、虚拟机、公有云、私有 云、个⼈电脑、服务器等。
- 更简单的管理,使⽤ Docker,只需要⼩⼩的修改,就可以替代以往⼤量的更新⼯作。
Docker 相关概念
Docker
是
CS
架构,主要有两个概念,具体如下。
- Docker daemon:运⾏在宿主机上,Docker 守护进程,⽤户通过 Docker client(Docker 命令)与 Docker daemon 交互。
- Docker client:Docker 命令⾏⼯具,是⽤户使⽤ Docker 的主要⽅式,Docker client 与 DockerGitChat
daemon
通信并将结果返回给⽤户,
Docker client
也可以通过
socket
或者
RESTful API
访问远程的
Docker daemon
。
Docker
的组成有三个主要概念,具体如下。
- Docker image:镜像是只读的,镜像中包含有需要运⾏的⽂件。镜像⽤来创建 container,⼀个镜像可 以运⾏多个 container;镜像可以通过 Dockerfifile 创建,也可以从 Docker hub/registry 上下载。
- Docker container:容器是 Docker 的运⾏组件,启动⼀个镜像就是⼀个容器,容器是⼀个隔离环境, 多个容器之间不会相互影响,保证容器中的程序运⾏在⼀个相对安全的环境中。
- Docker hub/registry:共享和管理 Docker 镜像,⽤户可以上传或者下载上⾯的镜像,官⽅地址可点击 这⾥查看,也可以搭建⾃⼰私有的 Docker registry。
镜像就相当于打包好的版本,镜像启动之后运⾏在容器中,仓库就是装存储镜像的地⽅。
接下来创建⼀个
Spring Boot
项⽬,然后给项⽬添加
Docker
⽀持,最后对项⽬进⾏部署。
Spring Boot 项⽬
在
pom.xml
中,使⽤
Spring Boot 2.x
相关依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
添加
web
和测试依赖:
<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>
</dependencies>
创建⼀个
DockerController
,在其中有⼀个
index()
⽅法,访问时返回:
Hello Docker!
@RestController
public class DockerController {
@RequestMapping("/")
public String index() {
return "Hello Docker!";
}
}
启动类:
@SpringBootApplication
public class DockerApplication {
public static void main(String[] args) {
SpringApplication.run(DockerApplication.class, args);
}
}
添加完毕后启动项⽬,启动成功后浏览器访问⽹址:
http://localhost:8080/
,⻚⾯返回:
Hello Docker!
,说明
Spring Boot
项⽬配置正常。
项⽬添加 Docker ⽀持
在
pom.xml
中添加
Docker
镜像名称:
<properties>
<docker.image.prefix>springboot</docker.image.prefix>
</properties>
plugins
中添加
Docker
构建插件:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Docker maven plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</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>
<!-- Docker maven plugin -->
</plugins>
</build>
- ${docker.image.prefifix},⾃定义的镜像名称
- ${project.artifactId},项⽬的 artifactId
- ${project.build.directory},构建⽬录,缺省为 target
- ${project.build.fifinalName},产出物名称,缺省为 ${project.artifactId}-${project.version}
在⽬录
src/main/docker
下创建
Dockerfifile
⽂件,
Dockerfifile
⽂件⽤来说明如何来构建镜像。
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD spring-boot-docker-1.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
这个
Dockerfifile
⽂件很简单,构建
JDK
基础环境,添加
Spring Boot Jar
到镜像中,简单解释⼀下。
- FROM,表示使⽤ JDK 8 环境为基础镜像,如果镜像不是本地的将会从 DockerHub 进⾏下载。
- VOLUME,VOLUME 指向了⼀个 /tmp 的⽬录,由于 Spring Boot 使⽤内置的 Tomcat 容器,Tomcat 默 认使⽤ /tmp 作为⼯作⽬录,这个命令的效果是:在宿主机的 /var/lib/docker ⽬录下创建⼀个临时⽂件并 把它链接到容器中的 /tmp ⽬录。
- ADD,复制⽂件并且重命名。
- ENTRYPOINT,为了缩短 Tomcat 的启动时间,添加 java.security.egd 的系统属性指向 /dev/urandom 作为 ENTRYPOINT。
这样
Spring Boot
项⽬添加
Docker
依赖就完成了,下⾯解释⼀下什么是
Dockerfifile
?
Dockerfifile 介绍
Docker
镜像是⼀个特殊的⽂件系统,除了提供容器运⾏时所需的程序、库、资源、配置等⽂件外,还包含了
为运⾏时准备的⼀些配置参数(如匿名卷、环境变量、⽤户等)。镜像不包含任何动态数据,其内容在构建
之后也不会被改变。
镜像的定制实际上就是定制每⼀层所添加的配置、⽂件。如果可以把每⼀层修改、安装、构建、操作的命令
都写⼊⼀个脚本,⽤这个脚本来构建、定制镜像,那么之前提及的⽆法重复的问题、镜像构建透明性的问
题、体积的问题就都会解决,这个脚本就是
Dockerfifile
。
Dockerfifile
是⼀个⽂本⽂件,其内包含了⼀条条的指令(
Instruction
),每⼀条指令构建⼀层,因此每⼀条指
令的内容,就是描述该层应当如何构建。有了
Dockerfifile
,当需要定制⾃⼰额外的需求时,只需在
Dockerfifile
上添加或者修改指令,重新⽣成
image
即可,省去了敲命令的麻烦。
Dockerfifile
⽂件格式如下:
##Dockerfile ⽂件格式
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
#(1)第⼀⾏必须指定基础镜像信息
FROM ubuntu
# (2)维护者信息
MAINTAINER docker_user [email protected]
# (3)镜像操作指令
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/
sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# (4)容器启动执⾏指令
CMD /usr/sbin/nginx
Dockerfifile
分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执⾏指令。⼀开始必须要指
明所基于的镜像名称,接下来⼀般会说明维护者信息;后⾯则是镜像操作指令,如
RUN
指令。每执⾏⼀条
RUN
指令,镜像添加新的⼀层,并提交;最后是
CMD
指令,来指明运⾏容器时的操作命令。
Spring Boot
应⽤
Docker
部署需要使⽤
Dockerfifile
定义部署⽅案。
构建环境
建议在
Linux
环境下安装
Docker
,
Window
环境搭建⽐较复杂且容易出错,使⽤
Centos7 + yum
来安装
Docker
环境很⽅便。
Docker 安装
Docker
软件包已经包括在默认的
CentOS-Extras
软件源⾥,因此想要安装
Docker
,只需要运⾏下⾯的
yum
命令:
yum install docker
安装完成后,使⽤下⾯的命令来启动
docker
服务,并将其设置为开机启动:
service docker start
chkconfig docker on
LCTT
译注,此处采⽤了旧式的
sysv
语法,如采⽤
CentOS 7
中⽀持的新式
systemd
语法,如下:
systemctl start docker.service
systemctl enable docker.service
使⽤
‘Docker
中国
’
加速器:
vi /etc/docker/daemon.json
#添加后:
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"live-restore": true
}
重新启动:
systemctl restart docker
测试:
docker version
输⼊上述命令,返回
docker
的版本相关信息,证明
docker
安装成功。
安装 JDK
yum -y install java-1.8.0-openjdk*
- 配置环境变量
- 打开 vim /etc/profifile
- 添加以下内容
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64
export PATH=$PATH:$JAVA_HOME/bin
修改完成之后,使其⽣效:
source /etc/profile
输⼊
java -version
返回版本信息则安装正常。
安装 MAVEN
下载地址可点击这⾥查看
:
## 解压
tar vxf apache-maven-3.5.2-bin.tar.gz
## 移动
mv apache-maven-3.5.2 /usr/local/maven3
修改环境变量, 在
/etc/profifile
中添加以下⼏⾏:
MAVEN_HOME=/usr/local/maven3
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin
记得执⾏
source /etc/profifile
使环境变量⽣效。
输⼊
mvn -version
返回版本信息则安装正常。
这样整个构建环境就配置完成了。
使⽤ Docker 部署 Spring Boot 项⽬
将项⽬
spring-boot-docker
复制到服务器中,进⼊项⽬路径下进⾏打包测试。
#打包
mvn clean package
#启动
java -jar target/spring-boot-docker-1.0.jar
看到
Spring Boot
的启动⽇志后表明环境配置没有问题,接下来使⽤
DockerFile
构建镜像。
mvn package docker:build
第⼀次构建可能有点慢,当看到以下内容的时候表明构建成功:
...
Step 1 : FROM openjdk:8-jdk-alpine
---> 224765a6bdbe
Step 2 : VOLUME /tmp
---> Using cache
---> b4e86cc8654e
Step 3 : ADD spring-boot-docker-1.0.jar app.jar
---> a20fe75963ab
Removing intermediate container 593ee5e1ea51
Step 4 : ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
---> Running in 85d558a10cd4
---> 7102f08b5e95
Removing intermediate container 85d558a10cd4
Successfully built 7102f08b5e95
[INFO] Built springboot/spring-boot-docker
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 54.346 s
[INFO] Finished at: 2018-03-13T16:20:15+08:00
[INFO] Final Memory: 42M/182M
[INFO] ------------------------------------------------------------------------
使⽤
docker images
命令查看构建好的镜像:
docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
springboot/spring-boot-docker latest 99ce9468da74 6 seconds
ago 117.5 MB
springboot/spring-boot-docker
就是我们构建好的镜像,下⼀步就是运⾏该镜像:
docker run -p 8080:8080 -t springboot/spring-boot-docker
启动完成之后使⽤
docker ps
查看正在运⾏的镜像:
docker ps
CONTAINER ID IMAGE COMMAND CREAT
ED STATUS PORTS NAMES
049570da86a9 springboot/spring-boot-docker "java -Djava.security" 30 se
conds ago Up 27 seconds 0.0.0.0:8080->8080/tcp determined_mahavira
可以看到构建的容器正在在运⾏,访问浏览器:
http://192.168.0.x:8080/
,返回:
Hello Docker!
说明使⽤
Docker
部署
Spring Boot
项⽬成功!
常⽤命令
除过以上使⽤的
Docker
命令外,还有⼀些其他常⽤的命令,通过这些命令可以查看容器的相关状态。
拉取
docker
镜像:
docker pull image_name
查看宿主机上的镜像,
Docker
镜像保存在
/var/lib/docker
⽬录下
:
docker images
删除镜像:
docker rmi docker.io/tomcat:7.0.77-jre7 或者 docker rmi b39c68b7af30
查看当前有哪些容器正在运⾏:
docker ps
查看所有容器:
docker ps -a
启动、停⽌、重启容器命令:
docker start container_name/container_id
docker stop container_name/container_id
docker restart container_name/container_id
后台启动⼀个容器后,如果想进⼊到这个容器,可以使⽤
attach
命令:
docker attach container_name/container_id
删除容器的命令:
docker rm container_name/container_id
删除所有停⽌的容器:
docker rm $(docker ps -a -q)
查看当前系统
Docker
信息:
docker info
从
Docker hub
上下载某个镜像:
docker pull centos:latest
docker pull centos:latest
通过这些命令可以发现
Docker
的使⽤⽅式⾮常灵活,可以把项⽬做成镜像来管理,部署的时候直接下载对
应版本的镜像直接运⾏即可。
总结
Docker
是容器化技术的基础,服务编排、弹性⽔平扩充都依赖于
Docker
的使⽤,使⽤
Docker
部署
Spring
Boot
项⽬,可以把项⽬当做版本库⼀样管理,不需要关注环境、迁移等问题。
Spring Boot
是微服务开发的
基础,
Docker
是容器化部署的基础,两者结合使⽤更加⽅便微服务架构运维部署落地。