安装

安装最新版

uname -r  # docker要求Ubuntu系统的内核版本高于 3.10
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun  # 使用脚本安装 Docker
docker -v  # 查看docker版本
sudo service docker start  # 启动docker
Docker需要用户具有sudo权限,为了避免每次命令都输入sudo,可以把用户加入Docker用户组
sudo usermod -aG docker 用户名

镜像加速

Docker 中国官方镜像加速

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.m.daocloud.io"]
}
EOF
systemctl daemon-reload
systemctl restart docker

开机自启

systemctl enable docker

基本命令

镜像

搜索镜像

docker search REPOSITORY

获取镜像

docker pull REPOSITORY:TAG  # 不加TAG的话将下载最新版本

列出所有下载的镜像

docker images ls

运行镜像

docker run [OPTIONS] <image id> [COMMAND] [ARG...]

OPTIONS说明:


-d: 后台运行容器,并返回容器ID
-p: 端口映射,格式为:主机端口:容器端口
-P:Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口
-v: 目录映射,格式为:主机目录:容器目录
-i: 以交互模式运行容器,通常与 -t 同时使用
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
-m: 限制内存使用上限,如 -m 256M
--memory-swap: 容器可以使用的物理内存和可以使用的swap之和
--name="xxx": 为容器指定一个名称
--rm:容器停止运行后,自动删除容器文件

例:

docker run -it -p 80:80 -v /www/test:/www:ro 6ba5da94eee6

删除镜像

docker rmi <image id>

容器

启动容器

docker start <container-id>

进入容器

docker exec <container-id> bash

停止容器

docker stop <container-id>

删除容器

docker rm <container-id>

停用并删除所有容器

docker stop $(docker ps -q) & docker rm $(docker ps -aq)

清理所有处于终止状态的容器

docker container prune

列出正在运行的容器

docker ps

列出所有容器(包括终止运行的容器)

docker ps -a

查看容器日志

docker logs <container id>

容器动态添加删除端口

通过inspect命令查看容器ip

docker inspect <containerId> |grep IPAddress

增加一个端口映射,比如8081->81

iptables -t nat -A  DOCKER -p tcp --dport 8081 -j DNAT --to-destination <containerIP>:81

如果加错了或者想修改:

先显示行号查看

sudo iptables -t nat -vnL DOCKER --line-number

如果需要删除规则3

sudo iptables -t nat -D DOCKER 3

数据管理

数据卷

  • 数据卷 可以在容器之间共享和重用
  • 数据卷 的修改会立马生效
  • 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

    创建一个数据卷

    docker volume create <volume name>

    查看所有的数据卷

    docker volume ls

    查看指定数据卷的信息

    docker volume inspect <volume name>

    启动一个挂载数据卷的容器

    在用 docker run 命令的时候,使用 --mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷

下面创建一个名为 web 的容器,并加载一个 数据卷 到容器的 /webapp 目录。

$ docker run -d -P \
    --name web \
    # -v my-vol:/wepapp \
    --mount source=my-vol,target=/webapp \
    training/webapp \
    python app.py

删除数据卷

docker volume rm <volume name>

数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷

无主的数据卷可能会占据很多空间,要清理请使用以下命令

docker volume prune

挂载主机目录

挂载一个主机目录作为数据卷

使用 --mount 标记可以指定挂载一个本地主机的目录到容器中去。

$ docker run -d -P \
    --name web \
    # -v /src/webapp:/opt/webapp \
    --mount type=bind,source=/src/webapp,target=/opt/webapp \
    training/webapp \
    python app.py

上面的命令加载主机的 /src/webapp 目录到容器的 /opt/webapp目录。本地目录的路径必须是绝对路径。Docker 挂载主机目录的默认权限是 读写,用户也可以通过增加 readonly 指定为 只读


Dockerfile 指令

COPY 复制文件

COPY [--chown=<user>:<group>] <源路径>... <目标路径>

COPY 指令将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

<源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则

COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等

ADD 更高级的复制文件

ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能

最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合

CMD 容器启动命令

  • shell 格式:CMD <命令>
  • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]

如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:

CMD echo $HOME

在实际执行中,会将其变更为:

CMD [ "sh", "-c", "echo $HOME" ]

ENV 设置环境变量

格式有两种:

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

VOLUME 定义匿名卷

格式为:

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

EXPOSE 声明端口

格式为:

EXPOSE <端口1> [<端口2>...]

要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射

WORKDIR 指定工作目录

格式为:

WORKDIR <工作目录路径>

使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录


Docker Compose

安装

二进制包

curl -L https://github.com/docker/compose/releases/download/v2.3.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
最新发行的版本地址:https://github.com/docker/compose/releases

PIP 安装

x86_64 架构的 Linux 建议按照上边的方法下载二进制包进行安装,如果您计算机的架构是 ARM (例如,树莓派),再使用 pip 安装
pip3 install -U docker-compose

卸载

二进制包

rm /usr/local/bin/docker-compose

PIP 安装

pip3 uninstall docker-compose

核心概念

镜像(image)

Docker 镜像(Image)就是一个只读的模板。例如:一个镜像可以包含一个完整的操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。

镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,看看下面这张图:

右边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker内部的实现细节,并且能够在docker宿主机的文件系统上访问到。统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。

仓库(repository)

仓库(Repository)是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括 时速云 、网易云 等,可以提供大陆用户更稳定快速的访问。当然,用户也可以在本地网络内创建一个私有仓库。

当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。

容器(container)

Docker 利用容器(Container)来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。

一个运行态容器被定义为一个可读写的统一文件系统加上隔离的进程空间和包含其中的进程。下面这张图片展示了一个运行中的容器。

正是文件系统隔离技术使得Docker成为了一个非常有潜力的虚拟化技术。一个容器中的进程可能会对文件进行修改、删除、创建,这些改变都将作用于可读写层。

×