什么是Docker镜像?
- Docker镜像是由文件系统叠加而成
- 最底端是一个文件引导系统, 即bootfs, 当一个容器启动后, 它会被移到内存中, 而文件引导系统则会被卸载, 以留出更多内存供磁盘映像使用
- 第二层是root文件系统rootfs, rootfs可以是一种或多种操作系统, root文件系统永远只能是只读状态, 并且Docker利用联合加载技术在root文件系统上加载更多的只读文件系统. 联合加载指的是一次同时加载多个文件系统, 但是在外面看起来只能看到一个文件系统, 联合加载会将各层文件系统叠加到一起, 这样最终的文件系统会包含所有底层的文件和目录
- Docker将这样的文件系统称为镜像, 当容器启动时, Docker会在镜像的最顶层加载一个读写系统, 在Docker中执行的程序即在读写层执行
镜像相关命令
# 列出所有镜像
docker images
补充: 本地镜像都保存在 /var/lib/docker目录下
# 拉取镜像, :后跟镜像标签, 若不指定, 则会自动拉取lastest标签的镜像
docker pull ubuntu:12.04
# 查找镜像
docker search ubuntu
Docker commit创建镜像
# 登录dockerhub, 注销为logout
docker login
# 创建镜像, docker commit [容器ID] 用户名/仓库名:镜像标签
docker commit -m "for test" -a "xinzhang" bf0e685e1a88 xinzhang0618/ubuntu-test:20220516
-m 指定提交信息
-a 指定author
# 查看提交的镜像的详细信息
docker inspect xinzhang0618/ubuntu-test:20220516
Dockerfile构建镜像
- docker run 命令会覆盖CMD命令
- Dockerfile中只能指定一条CMD指令, 若有多条也只有最后一条生效 ```json docker run -it ubuntu /bin/bash 等价于 CMD [“/bin/bash”] 还可以指定参数 CMD [“/bin/bash”,”-l”]
<a name="rAWHf"></a>
### ENTRYPOINT
类似CMD, 但docker run命令行指定的任何参数都会被当做参数再次传递给ENTYPOINT中指令中指定的命令
```json
ENTRYPOINT ["/user/sbin/nginx"]
CMD ["-h"]
----------------------
构建镜像
docker build -t="jamtur01/static_web"
运行容器, 指定参数则以前台模式运行, 否则走CMD -h后台模式运行
docker run -it jamtur01/static_web -g "daemon off"
WORKDIR
从镜像创建新容器时, 在容器内部设置一个工作目录, ENTRYPOINT, /, CMD 指定的程序会在这个目录下执行
WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
ENTRYPOINT ["rackup"]
先将工作目录切换后安装软件, 后又切换了启动目录
容器启动时可通过-w 来覆盖工作目录
docker run -it -w /var/log ubuntu pwd
ENV
在镜像构建过程中设置环境变量
- 新的环境变量可以在后续任何的RUN指令中使用
- 新的环境变量也会持久保存到从镜像创建的任何容器中 ```shell ENV TARGET_DIR=/opt/app RVM_PATH=/home/rvm WORKDIR $TARGET_DIR
也可以在运行容器时通过-e来传递环境变量, 这些变量仅会在运行时有效
docker run -it -e “WEB_PORT=8080” ubuntu
<a name="VHUQ2"></a>
### USER
指定镜像会以哪个用户运行, 可以指定USER, GROUP的各种组合, 不指认默认为root
```shell
USER user:group
VOLUMN
向容器添加卷, 一个卷是可以存在于一个或者多个容器内特定的目录, 这个目录可以绕过联合文件系统, 并提供共享数据或者对数据持久化的功能
- 卷可以在容器间共享和重用
- 一个容器可以不是必须和其他容器共享卷
- 对卷的修改是立时生效的
- 对卷的修改不会对更新镜像产生影响
- 卷会一直存在知道没有任何容器再使用它
卷可以让我们将数据(源代码), 数据库或其他内容添加到镜像中而不是提交到镜像中, 并且允许在多个容器间共享这些内容, 可以利用此功能来测试容器和内部的应用程序代码, 管理日志或者处理容器内部的数据库
# 指定多个卷
VOLUMN ["/opt/project","/data"]
ADD
用来将构建环境(Dockerfile文件所在的目录)下的文件和目录复制到镜像中
- 如果是归档文件, 则会解压缩
- 如果路径中的目录不存在, Docker会创建全路径下的任何目录, 文件和目录都为0755, UID,GID都为0
- 如果存在同名文件, 则不会被覆盖
ADD latest.tar.gz /var/www/wordpress/
COPY
类似ADD, 但不会做文件提取或解压的工作, 目的位置必须是容器内的一个绝对路径
COPY conf.d/ /etc/apach2/
LABEL
为Docker镜像添加元数据, label=”value”, 可通过docker inspect查看标签信息
LABEL location="China" type="daa"
STOPSIGAL
用来设置停止容器时发送什么系统调用信号给容器, 信号必须是内核系统调用表中合法的数, 比如9, 或者SIGNAME格式中的信号名称, 如SIGKILL
ARG
用来定义可以在docker build命令运行时传递给构建运行时的变量(可以设默认值), 在构建时使用—build-arg指定
- 不要用arg传递证书或秘钥, 因为这些会在构建历史中暴露 ```shell ARG webapp_user=user
docker build —build-arg webapp_user=user2 jamtur01/webapp
<a name="o4HuX"></a>
### ONBUILD
- 为镜像添加剂触发器, 当一个镜像被用做其他镜像的基础镜像时(比如用户的镜像需要从某未准备好的位置添加源代码, 或者用户需要执行特定于构建镜像的环境的构建脚本), 该镜像中的触发器将会被执行.
- 触发器会在构建过程中插入新指令, 可以认为这些指令是紧跟在FROM之后指定的, 触发器可以是任何构建指令
- 可以通过docker inspect查看ONBUILD指令
- ONBUILD触发器会按照在父镜像中指定的顺序执行, 并且只能被继承一次(不会在孙镜像中执行)
如下示例, ONBUILD指令会使用ADD指令将构建环境所在的目录下的内容全部添加到镜像中的/var/www/目录下<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/281275/1652756141300-5f7563fa-09f5-4ae0-a647-c1504a54be4c.png#clientId=u33456b8d-808b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=281&id=u931f20bf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=351&originWidth=807&originalType=binary&ratio=1&rotation=0&showTitle=false&size=214848&status=done&style=none&taskId=u14948209-5e1f-4b4b-8985-2578cd3694c&title=&width=645.6)
<a name="A2nTh"></a>
## 推送镜像
```shell
docker push 用户名/仓库名
删除镜像
# 同时删除多个
docker rmi 镜像1 镜像2
# 删除所有
docker rmi `docker images -aq`
上一篇:Docker入门
下一篇:在测试中使用Docker