目录
例:使用Dockerfile构建SpringBoot应用镜像
例:使用Docker Compose 部署Spring Boot应用
Docker 简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。使用Docker,可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。
架构
Docker daemon(守护进程):运行在宿主机(DOCKER_HOST)的后台进程。可通过Docker客户端与之通信。
Client(客户端):Docker的用户界面,接受用户命令和配置标识,并与Docker daemon通信。
Images(镜像):创建Docker容器的说明,相当于系统安装光盘,使用它可以运行镜像中的程序。
Container(容器):镜像的可运行实例,通过Docker API或者CLI命令来启停、移动和删除容器等。
Register(注册中心):Docker仓库存放的位置,每个仓库可包含多个Docker标签,每个标签对应一个Docker镜像。默认的Docker Register是Docker Hub,上面存放着大量优秀的镜像,可用Docker命令下载并使用。
安装
Centos安装Docker
(1)移除旧版本Docker软件包
sudo yum -y remove docker
(2)安装yum-utils
sudo yum install -y yum-utils
(3)添加Docker的
sudo yum-config-manager \
--add-repo \
https://docs.docker.com/engine/installation/linux/repo_files/centos/docker.repo
(4)更新Yum包索引
sudo yum makecache fast
(5)安装最新版本Docker
sudo yum -y install docker-engine
如果想安装指定版本Docker,执行以下命令列出可用Docker版本
yum list docker-engine.x86_64 --showduplicates | sort -r
然后执行安装操作
sudo yum -y install docker-engine-<VERSION>
(6)启动Docker
sudo systemctl start docker
(7)如果镜像加载缓慢,可配置国内镜像源,编辑daemon.json文件
vim /etc/docker/daemon.json
加入内容
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
(8)使镜像配置生效并重启Docker服务
sudo systemctl daemon-reload
sudo systemctl restart docker.service
(9)验证是否安装正确
docker run hello-world
(10)查看版本
docker version
Ubuntu安装Docker
(1)更新apt包索引
sudo apt-get update
(2)安装HTTPS和CA证书使得apt能够通过HTTPS使用仓库
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
(3)添加官方GPG密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
(4)添加stable仓库
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
(5)更新apt包索引
sudo apt-get update
(6)安装最新版本Docker
sudo apt-get install docker-ce
(7)启动Docker
sudo systemctl start docker
(8)验证是否安装正确
docker run hello-world
(9)查看版本
docker version
常用命令
镜像常用命令
(1)搜索镜像
docker search <关键词>
(2)下载镜像
docker pull <镜像名称>
(3)列出已下载镜像
docker images
(4)列出镜像详细信息
docker inspect <镜像名称>
(5)查看镜像历史
docker history <镜像名称>
(6)删除本地镜像
docker rmi <镜像名称>
(7)删除所有镜像
docker rmi -f $(docker images)
(8)存出镜像
docker save -o <存出文件名称> <待存出镜像名称>
(9)载入镜像
docker load --input <待载入镜像文件名称>
(10)上传镜像
docker pull <镜像名称>
(11)将容器保存为镜像
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
容器常用命令
(1)新建并启动容器
docker run
参数选择:
-d:后台运行
-P:随机端映射
-p:指定端口映射
-network:指定网络模式。四种模式:(1)bridge:连接到默认的网桥,默认模式。(2)host:使用宿主机的网络。(3)container:NAME_or_ID:让新建的容器使用使用已有容器的网络配置。(4)none:不配置该容器的网络。
(2)列出容器
docker ps
(3)停止容器
docker stop <容器名称>/<容器ID>
(4)强制停止容器
docker kill <容器名称>/<容器ID>
(5)启动已停止容器
docker start <容器名称>/<容器ID>
(6)重启容器
docker restart
(7)进入容器
docker attach <容器名称>/<容器ID>
(8)删除容器
docker rm <容器名称>/<容器ID>
(9)创建容器
docker create <容器名称>/<容器ID>
(10)导出容器
docker export -o <导出文件名称> <待导出容器名称>/<待导出容器ID>
(11)导入容器
docker import <导入文件名称> - <仓库名称/标签名称>
使用 Dockerfile 定制镜像
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
在一个空白目录中,建立一个文本文件,并命名为 Dockerfile
$ mkdir myNginx
$ cd myNginx
$ touch Dockerfile
内容格式为
FROM <指定的基础镜像>
RUN <待执行的命令行命令>
使用了docker build 命令进行镜像构建
docker build [选项] <上下文路径/URL/->
Dockerfile 指令除了FROM和RUN之外,还有其它指令
copY <源路径> <目标路径>
目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 workdir 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。copY会保留源文件的各种元数据。
ADD 更高级的复制文件
ADD <源路径> <目标路径>
ADD 指令和 copY 的格式和性质基本一致。但是在 copY 基础上增加了一些功能。比如源文件可以是一个URL,而且如果源文件是一个压缩包,还会自动将其解压。
CMD 容器启动命令
CMD <命令>
容器即进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD指令用于指定默认的容器主进程的启动命令。
ENTRYPOINT 入口点
ENTRYPOINT <命令>
与CMD一样,都是指定容器程序及参数,差异在于CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖,而ENTRYPOINT指令指定的命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数。
ENV 设置环境变量
ENV <key> <value>
这个指令很简单,就是设置环境变量而已
ARG 构建参数
ARG <参数名>[=<默认值>]
构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。
VOLUME 定义匿名卷
VOLUME ["<路径1>", "<路径2>"...]
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
EXPOSE 声明端口
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE 的端口。
workdir 指定工作目录
workdir <工作目录路径>
使用 workdir 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,该目录需要已经存在, workdir 并不会帮你建立目录。
USER 指定当前用户
USER <用户名>
USER 指令和 workdir 相似,都是改变环境状态并影响以后的层。 workdir是改变工作目录, USER 则是改变之后层的执行 RUN , CMD 以及ENTRYPOINT 这类命令的身份。当然,和 workdir 一样, USER 只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换。
HEALTHCHECK 健康检查
HEALTHCHECK [选项] CMD <命令> ###设置检查容器健康状况的命令
HEALTHCHECK NONE ###如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
ONBUILD 为他人做嫁衣裳
ONBUILD <其它指令>
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , copY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
例:使用Dockerfile构建SpringBoot应用镜像
# 该镜像需要依赖的基础镜像
FROM java:8
# 将当前目录下的jar包复制到docker容器的/目录下
ADD dockerfile-0.0.1-SNAPSHOT.jar /dockerfile-0.0.1-SNAPSHOT.jar
# 运行过程中创建一个mall-tiny-docker-file.jar文件
RUN bash -c 'touch /dockerfile-0.0.1-SNAPSHOT.jar'
# 声明服务运行在8080端口
EXPOSE 8080
# 指定docker容器启动时运行jar包
ENTRYPOINT ["java", "-jar","/dockerfile-0.0.1-SNAPSHOT.jar"]
# 指定维护者的名字
MAINTAINER ProgramLife!
二、将打包好的dockerfile-0.0.1-SNAPSHOT.jar文件和Dockerfile文件放到同一文件夹,并在文件夹路径执行命令构建镜像
# -t 表示指定镜像仓库名称/镜像名称:镜像标签 .表示使用当前目录下的Dockerfile
docker build -t ProgramLife!/dockerfile:0.0.1-SNAPSHOT .
Docker Hub
Docker Hub是Docker 官方维护了一个公共仓库,大部分需求,都可以通过在 Docker Hub 中直接下载镜像来实现。
docker login
可以通过执行 docker login 命令来输入用户名、密码和邮箱来完成注册和登录。 注册成功后,本地用户目录的 .dockercfg 中将保存用户的认证信息。
查找镜像
sudo docker search <镜像名称>
下载镜像
sudo docker pull <镜像名称>
私有仓库
可以通过获取官方 registry 镜像来运行
$ sudo docker run -d -p 5000:5000 registry
这将使用官方的 registry 镜像来启动本地的私有仓库。默认情况下,仓库会被创建在容器的 /tmp/registry 下。可以通过 -v 参数来
将镜像文件存放在本地的指定路径。 例如下面的例子将上传的镜像放到/opt/data/registry 目录。
$ sudo docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
使用 docker tag 来标记一个镜像,然后推送它到仓库,别的机器上就可以下载下来了。例如私有仓库地址为192.168.7.26:5000 。
使用 docker tag 将 ba58 这个镜像标记为 192.168.7.26:5000/test (格式为 docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] )。
$ sudo docker tag ba58 192.168.7.26:5000/test
$ sudo docker push 192.168.7.26:5000/test
使用 curl 查看仓库中的镜像
curl http://192.168.7.26:5000/v1/search
从另外一台机器去下载这个镜像
$ sudo docker pull 192.168.7.26:5000/test
数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
在用 docker run 命令的时候,使用 -v 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
创建一个名为 web 的容器,并加载一个数据卷到容器的 /webapp 目录
$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py
删除数据卷
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
查看容器具体信息
$ docker inspect <容器名称>
在输出的内容中找到其中和数据卷相关的部分,可以看到所有的数据卷都是创建在主机的 /var/lib/docker/volumes/ 下面的
数据卷容器
如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
首先,创建一个名为 dbdata 的数据卷容器
$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
然后,在其他容器中使用 --volumes-from 来挂载 dbdata 容器中的数据卷。
$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
也可以从其他已经挂载了数据卷的容器来级联挂载数据卷
$ sudo docker run -d --name db3 --volumes-from db1 training/postgres
果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。
如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 dockerrm -v 命令来指定同时删除关联的容器。
备份
使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从主机挂载当前目录到容器的 /backup 目录
$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
使用了 tar 命令来将 dbdata 卷备份为容器中 /backup/backup.tar文件,也就是主机当前目录下的名为 backup.tar 的文件。
恢复
如果恢复数据到一个容器,首先创建一个带有空数据卷的容器 dbdata2
$ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
然后创建另一个容器,挂载 dbdata2 容器卷中的数据卷,并使用 untar 解压备份文件到挂载的容器卷中。
$ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busyBox tar xvf /backup/backup.tar
Docker Compose
Compose是一个用于定义和运行多容器Docker应用程序的工具,适合用在开发、测试、构建CI工作流的场景 。
Compose 中有两个重要的概念:
- 服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义。
安装Compose
一、下载
curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
三、查看是否安装完成
docker-compose --version
使用步骤
- 使用Dockerfle(或其他方式)定义应用程序环境,以便在任何地方重现该环境。
- 在docker-compose. Yml文件中定义组成应用程序的服务,以便各个服务在一个隔离的环境中一起运行。
- ·运行docker-composeup命令,启动并运行整个应用程序。
Compose 命令
build:构建(重新构建)项目中的服务容器
docker-compose build [options] [SERVICE...]
选项包括:
kill:强制停止服务容器
docker-compose kill [options] [SERVICE...]
logs:查看服务容器的输出
docker-compose logs [options] [SERVICE...]
pause:暂停一个服务容器
docker-compose pause [SERVICE...]
port:打印某个容器端口所映射的公共端口
docker-compose port [options] SERVICE PRIVATE_PORT
选项:
ps:列出项目中目前的所有容器
docker-compose ps [options] [SERVICE...]
pull:拉取服务依赖的镜像
docker-compose pull [options] [SERVICE...]
restart:重启项目中的服务
docker-compose restart [options] [SERVICE...]
rm:删除所有(停止状态的)服务容器
docker-compose rm [options] [SERVICE...]
选项:
run:在指定服务上执行一个命令
docker-compose run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]
scale:设置指定服务运行的容器个数
docker-compose scale [options] [SERVICE=NUM...]
start:启动已经存在的服务容器
docker-compose start [SERVICE...]
stop:停止已经处于运行状态的容器,但不删除它
docker-compose stop [options] [SERVICE...]
unpause:恢复处于暂停状态中的服务
docker-compose unpause [SERVICE...]
up:它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
docker-compose up [options] [SERVICE...]
migrate-to-labels:重新创建容器,并添加 label。
docker-compose migrate-to-labels
version:打印版本信息
docker-compose version
Compose 模板文件
默认的模板文件名称为 docker-compose.yml ,格式为 YAML 格式。
命令
build:指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 dockercompose.yml 文件的路径)。
build: /path/to/build/dir
cap_add:让容器拥有所有能力可以指定为:
cap_add:
- ALL
cap_drop:去掉 NET_ADMIN 能力可以指定为:
cap_drop:
- NET_ADMIN
command:覆盖容器启动后默认执行的命令
command: echo "hello world"
cgroup_parent:指定父 cgroup 组,意味着将继承该组的资源限制。
cgroup_parent: cgroups_1
container_name:指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。
container_name: docker-web-container
devices:指定设备映射关系。
devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
dns:自定义 DNS 服务器。可以是一个值,也可以是一个列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
dns_search:配置 DNS 搜索域。可以是一个值,也可以是一个列表。
dns_search: example.com
dns_search:
- domain1.example.com
- domain2.example.com
dockerfile:如果需要指定额外的编译镜像的 Dockefile 文件,可以通过该指令来指定。
dockerfile: Dockerfile-alternate
env_file:从文件中获取环境变量,可以为单独的文件路径或列表
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
environment:设置环境变量。你可以使用数组或字典两种格式。
environment:
RACK_ENV: development
SESSION_SECRET:
expose:暴露端口,但不映射到宿主机,只被连接的服务访问
expose:
- "3000"
- "8000"
extends:基于其它模板文件进行扩展
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
environment:
- DEBUG=true
db:
image: postgres
external_links:链接到 docker-compose.yml 外部的容器,甚至 并非 Compose 管理的外部容器。参数格式跟 links 类似。
external_links:
- redis_1
- project_db_1:MysqL
- project_db_1:postgresql
extra_hosts:类似 Docker 中的 --add-host 参数,指定额外的 host 名称映射信息。
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
image:指定为镜像名称或镜像 ID。如果镜像在本地不存在, Compose 将会尝试拉去这个镜像。
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
labels:为容器添加 Docker 元数据(Metadata)信息。例如可以为容器添加辅助说明信息
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com.startupteam.release: "rc3 for v1.0"
links:链接到其它服务中的容器。使用服务名称(同时作为别名)或服务名称:服务别名(SERVICE:ALIAS) 格式都可以。
links:
- db
- db:database
- redis
log_driver:类似 Docker 中的 --log-driver 参数,指定日志驱动类型。
log_driver: "json-file"
log_driver: "syslog"
log_driver: "none"
log_opt:日志驱动的相关参数。
log_driver: "syslog"
log_opt:
syslog-address: "tcp://192.168.0.42:123"
net:设置网络模式。使用和 docker client 的 --net 参数一样的值
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
pid:跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程 ID 来相互访问和操作。
pid: "host"
ports:暴露端口信息
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
security_opt:指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。
security_opt:
- label:user:USER
- label:role:ROLE
ulimits:指定容器的 ulimits 限制值
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
volumes:数据卷所挂载路径设置。
volumes:
- /var/lib/MysqL
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
volumes_driver:较新版本的 Docker 支持数据卷的插件驱动,可以通过 volumes_driver 来指定驱动。
volume_driver: mydriver
volumes_from:从另一个服务或容器挂载它的数据卷
volumes_from:
- service_name
- container_name
例:使用Docker Compose 部署Spring Boot应用
一、使用maven插件构建镜像
(1)搭建Docker Registry 2.0
docker run -d -p 7000:7000 --restart=always --name registry2 registry:2
(2)修改/usr/lib/systemd/system/docker.service文件
原来
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
改为
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:7050 -H unix://var/run/docker.sock
echo '{ "insecure-registries":["192.168.0.109:7000"] }' > /etc/docker/daemon.json
(4)使配置生效
systemctl daemon-reload
systemctl stop docker
systemctl start docker
(5)开启防火墙
firewall-cmd --zone=public --add-port=7050/tcp --permanent
firewall-cmd --reload
(6)修改Spring Boot应用pom.xml文件,增加
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>ProgramLife!/${project.artifactId}:${project.version}</imageName>
<dockerHost>http://192.168.0.109:7050</dockerHost>
<baseImage>java:8</baseImage>
<entryPoint>["java", "-jar","/${project.build.finalName}.jar"]
</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
mvn clean package
version: '1'
services:
# 指定服务名称
db:
# 指定服务使用的镜像
image: MysqL:8.0.15
# 指定容器名称
container_name: MysqL
# 指定服务运行的端口
ports:
- 3306:3306
# 指定容器中需要挂载的文件
volumes:
- /MysqL/log:/var/log/MysqL
- /MysqL/data:/var/lib/MysqL
- /MysqL/conf.d:/etc/MysqL
# 指定容器的环境变量
environment:
- MysqL_ROOT_PASSWORD=root
# 指定服务名称
docker-compose:
# 指定服务使用的镜像
image: ProgramLife!/docker-compose:0.0.1-SNAPSHOT
# 指定容器名称
container_name: docker-compose
# 指定服务运行的端口
ports:
- 8080:8080
# 指定容器中需要挂载的文件
volumes:
- /etc/localtime:/etc/localtime
- /spring/docker-compose/logs:/var/logs
三、在docker-compose.yml文件目录下运行命令
docker-compose up -d
注:本博客部分内容参考《Spring Cloud与Docker微服务架构实战》、《Docker技术入门与实战》
ProgramLife! 发布了10 篇原创文章 · 获赞 9 · 访问量 1万+ 私信 关注版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。