- 了解Docker用途和基本运行原理
- 掌握Docker常见使用方式
- 了解Docker的部分高级应用
- 了解Dockerfile的用法以及基本结构
- 学会如何构建并部署自己的容器
Docker简介
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口
安装Docker
略
Docker的基本使用
以安装、运行一个Docker的UI管理平台为例
使用docker命令时碰到permission denied那是因为用户没有权限,参考https://www.jianshu.com/p/1354e0506753
下载镜像
docker pull portainer/portainer
pull失败参考https://www.cnblogs.com/wang50902/p/11378202.html设置镜像网站,重启docker服务,重启daemon:
systemctl daemon-reload
systemctl restart docker
查看镜像列表
docker images
启动容器运行该镜像:
docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -v /var/run/docker.sock -v portainer_data:/data portainer/portainer
现在,该管理平台已经运行在docker中,可以通过9000端口进行访问并设置密码
在主机中查看容器列表
docker ps
或者
docker container ls
注意:
- 如果使用云服务器,请检查服务器防火墙设置(包括操作系统防火墙,以及云服务提供商的防火墙)。并且不推荐将端口设置为80、443等HTTP默认端口,在未备案的情况下,云服务提供商一般不会提供这两个端口的HTTP访问。
- 如果使用本地虚拟机,本地访问时直接使用虚拟机IP即可。跨设备访问(比如使用另一台电脑/手机访问)时,需要将网络设置为NAT模
式,访问时需访问物理机的IP及NAT设置的端口。
以上述操作为例,说明docker的基本用法
docker pull
用法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
作用: 远程拉取Docker镜像,与git pull类似。Docker Hub是Docker官方维护的公共镜像库,你可以将自己的Docker上传分享给别人,也可以从别人那里下载
对于镜像的搜索,可以上Docker Hub官网搜索,也可以使用docker search命令。例如:
docker search mysql
效果:
docker run
对于一般的用户, docker run 命令是最常用也是最复杂的命令之一。 docker run 命令用于创建并运行容器。完整的命令参数及用法参见Docker官方文档,下面仅以刚刚执行过的 docker run 命令为例,说明部分常用的参数意义。
用法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
注意:将参数放在需要启动的镜像名前,以免引起不必要的错误。如,应使
用 docker run -v /var/run/docker.sock:/var/run/docker.sock portainer ,而不
是 docker run portainer -v /var/run/docker.sock:/var/run/docker.sock
- -d
- –detach ,以后台模式运行容器并打印容器ID。类似于Linux命令中的 nohup {command} & 。一般情况下,运行服务都会添加此参数,否则容器会在前台运行。
- -p
- –publish ,将容器的端口发布至主机,与端口映射相似。 : 前为使用的主机端口, : 后为容器的端口,二者可以不同,即可以将容器中的一个端口映射至主机的任一未占用端口。
- –name
容器的名字,即在 docker ps 中查看到的 NAMES ,方便辨识容器。如果不指定此参数,Docker会随机生成一个名字。 - -v
绑定的外部数据集。 : 前为主机中的文件或路径, : 后的为容器中的文件或路径。需要存储数据或者使用主机中资源的容器需要设置该参数。在刚刚执行过的 docker run 命令中,由于要通过该平台管理docker,因此要将docker接收socket请求的docker.sock 路径传入容器;同时,为了方便数据的管理、备份以及数据安全,将容器中的数据存储到容器外,即 portainer_data 文件夹中。需要注意的是,本例中填写的路径是相对路径,数据会存储在docker安装路径下的 volumes 文件夹中。默认的安装路径是 /var/lib/docker ,即本例中数据会存储在 /var/lib/docker/volumes/portainer_data 中。 - –restart
容器的重启策略,通常与 -d 参数一起使用。默认选项为 no 。 docker run 在退出时会产生一系列状态码,例如0为正常退出、127为容器调用的命令不存在等。这个参数控制了容器退出(包括正常退出、遇到错误退出)时,是否进行重启。本例中使用的 always 选项策略,为无论容器因何退出,都将重启以保证服务的正常运行。 - -e
容器的环境变量。某些容器需要指定初始的参数来保证应用的正常运行,例如MySQL容器在启动时需要指定初始密码(或设置为允许空密码、自动生成随机密码)来保证MySQL的访问及安全:
docker run -e MYSQL_ROOT_PASSWORD=1234567890 mysql
Docker在运行“服务类容器”(如MySQL、Nginx等)之外,还可能会运行“工作类容器”(某些一次性或有限次执行的脚本等)
docker exec
本节使用MySQL容器为例,在学习 exec 命令前要拉取并运行MySQL容器:
docker pull mysql
docker run -d -e MYSQL_ROOT_PASSWORD=1234567890 -p 8006:3306 --name mysql mysql
docker exec 命令用于在容器中执行命令。
用法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG…]
其含义为:在容器CONTAINER中,执行命令COMMAND [ARG…]
查看mysql容器中home文件夹中的文件(在mysql容器中执行 ls ~ )
docker exec mysql ls ~
由于home文件夹中没有文件,该命令没有输出
在mysql容器的home文件夹中创建文件
docker exec mysql touch ~/test_exec.tmp
再次查看容器中home文件夹中的文件
docker exec mysql ls ~
可以查看到新建的文件,说明命令执行成功
对于更加复杂的指令,可以调用容器中的bash来执行
docker exec mysql /bin/bash
然而,执行这句命令之后不会有任何输出,也不会要求继续输入。正确的命令应该为:
docker exec -it mysql /bin/bash
这样,就相当于进入了容器内部,可以像在一般Linux设备中执行命令。在本例中,可以用此方法管理MySQL数据库:
mysql -uroot -p
root@24c575abf8ed:/# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
要退出容器bash时,输入 exit 命令即可
-i 参数
–interactive ,即使没有连接,也保持容器的标准输入打开。不加 -i 参数时,如果没有输入流衔接,bash就会关闭。
-t 参数
–tty ,分配一个“冒充的”终端设备。与 -i 结合使用,就会达到产生一个模拟终端,并保持正常交互的作用。
-d 参数
–detach ,与 run 命令中的 -d 参数类似,这里的 -d 参数也是将命令在后台运行
常用Docker命令
Docker CLI 文档中包含了更加详细和全面的docker命令用法。
容器生命周期管理
- run:创建并启动容器
- start/stop/restart:启动/停止/重启容器
- kill:杀掉容器
- rm:删除容器
- pause/unpause:暂停运行/恢复运行容器
- create:创建容器(但不启动)
- exec:在容器中执行命令
容器管理操作
- ps:列出本地容器
- inspect:查看容器或镜像的元数据
- top:查看容器中正在运行的进程信息
- attach:连接到正在运行中的容器
由于一般容器都以守护态后台运行,无法通过attach命令进入容器,常用进入容器的命令为 exec -it CONTAINER /bin/bash - logs:获取容器日志
- wait:阻塞运行直到容器停止,然后打印出它的退出代码
- export:将文件系统作为一个tar归档文件导出
- port:列出指定容器的端口映射
system
system df:查看磁盘使用情况
system events:查看实时事件
system info:查看docker系统信息
system prune:删除无用数据
stats:查看各个容器的运行状态
容器rootfs操作
commit:从容器创建一个新的镜像
cp:在容器与主机之间拷贝数据
diff:检查容器里文件结构的更改
容器镜像仓库操作
login/logout:登录/登出Docker镜像仓库,默认为Docker Hub
pull:拉取/更新镜像
push:将镜像上传到镜像仓库
search:从Docker Hub查找镜像
本地镜像管理
images:列出本地镜像
rmi:删除本地镜像
tag:标记本地镜像,将其归入某一仓库
build:使用Dockerfile创建镜像
history:查看镜像的创建历史
save:将镜像保存成tar归档文件
load:导入镜像的tar归档文件
import:从归档文件中创建镜像
容器信息查看
version:查看容器版本信息
构建定制镜像
Dockerfile
Dockerfile是一个用来构建镜像的文本文件,文件中包含了一条条构建镜像所需的指令和说明。本节使用一个的Nginx镜像,运行一个简单的HTML网页来说明Dockerfile如何工作。官方文档提供的Dockerfile 最佳实践会提供更多有用的细节。
- 编写Dockerfile
FROM nginx
RUN echo 'This is an Nginx running in a container built by me.' > /usr/share/nginx/html/index.html
Dockerfile文件的构成
详细用法参见Dockerfile reference
- FROM:定制的镜像基于FROM的镜像。在本例中,基础镜像为Nginx镜像,后续对镜像的更改都是在Nginx镜像基础上操作的。
- RUN:在构建时执行命令。
提示:由于Dockerfile的每条指令都会在docker上新建一层,如果一条或多条指令会产生不需要的缓存文件(比如编译带来的临时文件、下载的代码或安装包、其他缓存等),最好将几条命令用 && 连在一起,从而减少资源占用。例如,使用:
RUN apt-get update && apt-get install -y
package-a
package-b
而不是:
RUN apt-get update
RUN apt-get install -y package-a
RUN apt-get install -y package-b
- COPY:将文件或文件夹在上下文路径及制定路径间复制。用法为 COPY {SRC} {DST} ,其中SRC、DST分别为源路径、目标路径。
- ADD:与COPY功能和用法类似,ADD会在复制压缩文件时自动解压缩。
- CMD:在运行时执行命令
- ENTRYPOINT:配置容器启动后执行的命令。
- ENV:定义环境变量。
- ARG:定义只在构建时有效的环境变量。
- VOLUME:定义匿名数据卷。
- EXPOSE:声明端口。
- WORKDIR:指定工作目录。
- USER:用于指定执行命令的用户和用户组。
- HELTHCHECK:用于指定某个程序或指令来监控容器的运行状态。
- ONBUILD:用于延迟构建命令的执行,即仅在镜像被引用(FROM)时才会被执行
使用Dockerfile构建镜像
构建镜像
docker build -t nginx:hello_docker .
注意:命令后面有一个 . ,其作用稍后会介绍到。
查看构建的镜像
docker images
运行构建的镜像
docker run -p 8008:80 -d nginx:hello_docker
注意:不要将镜像的tag落下,否则运行的将是官方的空白Nginx镜像,而不是自己构建的镜像
可以试着访问下看是否成功
构建时用到的命令
-t 参数
–tag ,将容器以“名字:标签”格式命名
.
. 为上下文路径。构建时需要将指定目录中的文件一起打包给Docker引擎使用。如果未说明最后一个参数,默认上下文路径就是Dockerfile所在位置。由于Docker引擎会将路径下的所有内容打包,因此这个路径中最好不要放与当前Docker无关的文件。
使用已存在的容器构建镜像
很多时候我们可能不会直接编写Dockerfile来构建镜像,而是拉取并运行已存在的镜像,对容器进行修改。以前文已经创建好的MySQL容器为例:
- 将对容器的修改保存为镜像 docker commit mysql mysql:commit_mysql
上传镜像
docker login登陆Docker Hub账号,docker push上传镜像
上传在之前制作好的 hello_docker 镜像
docker push nginx:hello_docker
然而,这样是无法上传的,会显示 denied: requested access to the resource is denied 。由于nginx镜像实际上
是 library/nginx 镜像,直接push上传到的是这个官方库,没有权限上传就无法上传成功。
更改镜像标签
docker tag nginx:hello_docker {username}/hello_world
其中,将 username 替换为已经登录的Docker Hub账号
再次上传镜像,就可以在Docker Hub上查看到上传的镜像了