暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

docker 入门-镜像(三)

程序员的碎碎念 2020-04-15
345
上一篇:docker 入门-容器(二)

之前也说过镜像是可以从 Docker Hub 上的仓库下载的,在 Docker Hub 上的仓库有用户仓库和顶层仓库,顶层仓库是官方的,我们个人也可以上传自己的镜像到用户仓库,和 GitHub 一样

如果想对镜像有一个较简洁的全面了解,可以看看第一篇文章:Docker 入门(一)

基本使用

查看本地系统的所有镜像

sudo docker images

本地镜像存于/var/lib/docker,容器也在该目录下的containers中

拉取(下载)镜像

sudo docker pull 镜像名

这样拉取的是最新的镜像,可以用 tag 指定下载的版本

sudo docker pull 镜像名:tag

基于镜像创建容器

sudo docker run 镜像:tag

更多有关容器的操作请见文章:xxx

上传镜像到 Docker Hub

sudo  docker push 仓库名/镜像名

删除本地的镜像

sudo docker rmi 镜像名

查看 Docker Hub 上存在的镜像

sudo docker search 镜像名
# 或添加-s选项筛选星级:
sudo docker search -s 2 镜像名

构建镜像

构建镜像一般都是基于已有镜像构建新镜像,当然,也有从 0 开始构建的,我们暂且不讨论从 0 开始的

构建方式一:docker commit

这个很简单的,就是对一个容器执行 commit 命令就可以了

sudo docker commit 容器名或ID 仓库名/镜像名

当然也可以在 commit 时指定更多的描述:

选项全称意思例子
-a--author作者--author="xxx"
-m--message描述信息--message="xxxx"
-p--pause提交时是否暂停容器的运行--pause=true

例子:

sudo docker commit -m="描述" -a="me" 容器名 仓库名/镜像名:tag

构建方式二:docker build 命令 + Dockerfile 文件

先创建一个目录,然后在目录里创建一个文件 Dockerfile:

mkdir project
cd project
touch Dockerfile

这里的 project 目录就是我们的构建环境或称构建上下文。

然后开始编写 Dockerfile,下面是一个例子:

vim Dockerfile
# version:0.0.1
FROM ubuntu:14.04
MAINTAINER 作者 "邮箱"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'hi' > /usr/share/nginx/html/index.html
EXPOSE 80

解释: 一般开头都是这四行,说明一下镜像版本、作者信息和基于什么镜像开始构建,其余的都是一行一行的指令,每个指令都是要大写,后面一定要有参数选项。指令从上往下执行,每个指令都会创建一个新的镜像层并提交,下一条指令会基于上一条指令创建的镜像层创建新的镜像层。

最后,在这个构建环境下 build:

sudo docker build -t="仓库名/镜像名" .

注意末尾的点:.
,表示 docker 要在本地目录找 Dockerfile ,当然也可以指定搜索目录,比如指定 GitHub 上的一个 Dockerfile 文件目录。

Dockerfile 指令:

其实,我们在 Dockerfile 中编写的命令建议采用数组结构组织命令和参数选项,比如CMD ["/bin/bash", "-l"]
,意思就是把-l
传给/bin/bash

官方文档:https://docs.docker.com/engine/reference/builder/

指令解释特别的
RUN指定镜像被构建时要执行的指令,默认使用 shell 里面的命令包装器 /bin/sh -c 来执行
CMD指定容器启动时要执行的命令,比如sudo docker run -it 镜像名 /bin/true
翻译为 CMD 指令为:CMD ["/bin/true"]
只能用一条,多条则只执行最后一条,会被 docker run 覆盖
ENTRYPOINT和CMD类似,但 Dockerfile 中的 CMD 命令在和 docker run 冲突时会被覆盖,而 ENTRYPOINT 则不会,而且还可以接受所有 docker run 传入的参数,比如sudo docker run 镜像名 -g "daemon off;"
则是把-g "daemon off;"
参数传给了该镜像的 Dockerfile 中的 ENTRYPOINT 指令。
我们可以结合 ENTRYPOINT 和 CMD 的特性,做出有默认选项的命令,具体怎么玩,自己想想
WORKDIR指定该镜像创建的容器的工作目录,ENTRYPOINT 和 CMD 等指令会在这个目录下执行,也可以为 Dockerfile 中不同指令指定不同的工作目录举个例子吧:WORKDIR /opt/webapp/db
,RUN bundle install
,WORKDIR /opt/webapp
,ENTRYPOINT ["rackup"]
。当然,在运行时也可以添加-w
标志覆盖工作目录sudo docker run -it -w /var/log ubuntu pwd
ENV设置环境变量供后续的 RUN 指令使用,比如ENV RVM_PATH /home/rvm
后再执行:RUN gem install unicorn
就相当于:RVM_PATH=/home/rvm/ gem install unicorn

USER指定该镜像会以什么样的用户去运行,比如USER nginx
是以 nginx 用户的身份来运行,我们也可以指定用户名或 UID 和 组或 GID。
默认用户是 root
VOLUME给该镜像创建的容器添加卷。更多有关卷的内容,请见最后的拓展补充部分。
ADD将构建环境下的文件和目录复制到镜像中。比如在安装一个应用程序时,需要制定源文件和目的文件的位置:ADD software.lic /opt/application/software.lic
。以是否有/判断指定的是目录还是文件。
1、不能对构建环境之外的文件或目录进行 ADD 操作。2、会自动将压缩文件解压缩
COPY和 ADD 类似,但不会解压缩归档文件
ONBUILD为镜像添加触发器。当镜像被用作其他镜像的基础镜像时,该镜像的触发器被执行。触发器是在构建过程中插入新指令,我们可以认为是在 FROM 指令之后执行,触发器可以使任何构建指令。例子:ONBUILD ADD . /app/src
,ONBUILD RUN cd /app/src && make
我们可以对镜像使用 docker inspect 查看 ONBUILD 的内容。只被执行一次,而不会被孙子镜像再次执行。FROM和MATINTAINER和ONBUILD本身不能在ONBUILD中出现,即防止递归执行。

构建方式三:从本地模板导入

拓展补充

其实就是一种共享的挂载点。

卷是存在于一个或多个容器内的共享数据目录。对卷的修改是立即生效的,但对卷的修改并不会对镜像产生影响,因为卷的存在是为了把一些内容如数据、源代码、数据库等添加到容器中,而不是镜像中。卷会一直存在直到没有容器在使用它。

使用 nginx 镜像创建容器的一个例子

sudo docker run -d -p 80 --name 容器名 仓库名/镜像名 nginx -g "daemon off;"

解释: -p 80
的意思是 docker 的宿主机随机找一个端口号映射到容器的 80 端口,我们也可以指定内外端口的具体映射关系:-p 80:80
,也可以指定 IP 地址:-p 127.0.0.1:80:80
。而如果采用大写的-P
,意思即是容器直接对外公开在 Dockerfile 中 EXPOSE 设置的所有端口。

自动构建

通过绑定 Docker Hub 和 GitHub 账号,使得在 GitHub 上存在 Dockerfile 的仓库链接到 Docker Hub 从而在每次代码更新时由 Docker Hub 自动构建的方式。

但设置了自动构建的镜像就不能通过 docker push 来更新了,要通过 GitHub 来更新。


文章转载自程序员的碎碎念,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论