Docker 基础教程(包括 Docker 的安装、使用及 Dockerfile 编写)
跟着技术潮流学习了一波 Docker ,感受到 Docker 强大的优势及魅力。并在工作中使用 Docker 搭建了 TI DM8168 、 Freescale i.MX6Q 、 Allwinner H3 的开发环境;使用 Docker 发布了直播推流的微服务。以下为个人学习 Docker 的一些基础教程,包括了 Docker 的安装、使用及 Dockerfile 的编写。
安装 Docker
自动安装
sudo apt-get install curl # 安装 curl
curl -s https://get.docker.io/ubuntu/ | sudo sh # 自动安装脚本
手动安装
sudo apt-get install docker.io # 手动安装: Ubuntu 下安装 docker.io
查看 Docker 信息
sudo docker info # 查看 docker 信息
sudo docker images # 查看已经安装的 docker 镜像
修改使用中国的 docker hub 镜像源
修改配置文件 /etc/default/docker 如下:
DOCKER_OPTS="--registry-mirror=http://aad0405c.m.daocloud.io"
重启 Docker 服务
sudo service docker restart
下载 Ubuntu 的 Docker 镜像
64 位 ubuntu 下载官方镜像
sudo docker pull ubuntu
32 位 ubuntu 下载构建的 32 位镜像
https://github.com/docker-32bit/ubuntu # 构建脚本地址
git clone https://github.com/docker-32bit/ubuntu.git # 克隆构建脚本
cd ubuntu && sudo ./build-image.sh # 执行构建脚本来构建 docker image 32bit/ubuntu:16.04
构建好的 docker 镜像下载: https://openvz.org/Download/template/precreated
运行 Ubuntu 的 Docker 镜像
64 位 ubuntu 运行 ubuntu 的 docker 镜像
sudo docker run -i -t ubuntu /bin/bash # 执行交互式 docker 容器中 bash 终端
# (可在终端下执行 hostname 命令查看主机名,也可以用 apt-get 在终端中安装应用, exit 退出终端和容器)
sudo docker run --name test_x64 -i -t ubuntu /bin/bash # 指定容器名称为 test_x64 并执行 docker 容器中 bash 终端
32 位 ubuntu 下运行之前构建的 32 位 ubuntu 的 docker 镜像
sudo docker run -i -t 32bit/ubuntu:xenial /bin/bash # 执行交互式 docker 容器中 bash 终端
# (可在终端下执行 hostname 命令查看主机名,也可以用 apt-get 在终端中安装应用, exit 退出终端和容器)
sudo docker run --name test_x86 -i -t 32bit/ubuntu:xenial /bin/bash # 指定容器名称为 test_x86 并执行 docker 容器中 bash 终端
查看 Docker 容器
sudo docker ps # 查看正在运行的 docker
sudo docker ps -a # 查看所有的 docker 包括停止的和运行的
sudo docker ps -l # 查看最后一次运行的容器,包括运行的和禁止的
sudo docker ps -n x # 查看最后 x 次个容器,包括运行的和禁止的
常用 Docker 运行相关命令
sudo docker start test_x64 # 重新启动已停止的容器名为 test_x64 的容器(会沿用 docker run 命令时的参数来运行)
sudo docker start test_x86 # 重新启动已停止的容器名为 test_x86 的容器(会沿用 docker run 命令时的参数来运行)
sudo docker attach test_x64 # 重新附着到名为 test_x64 的容器上
sudo docker attach test_x86 # 重新附着到名为 test_x86 的容器上
sudo docker stop test_x64 # 停止正在运行的名为 test_x64 的容器
sudo docker stop test_x86 # 停止正在运行的名为 test_x86 的容器
sudo docker kill test_x64 # 快速停止正在运行的名为 test_x64 的容器
sudo docker kill test_x86 # 快速停止正在运行的名为 test_x86 的容器
sudo docker rm test_x64 # 删除停止的名为 test_x64 的容器(运行中的 docker 无法删除)
sudo docker rm test_x86 # 删除停止的名为 test_x86 的容器(运行中的 docker 无法删除)
注:使用容器 ID ,也可以使用容器名称来代替 ID
后台运行
sudo docker run --name daemon_dave -d ubuntu /bin/sh -c "while true;do echo hello world ;sleep 2;done" # 使用 -d 参数置于后台运行
查看 Docker 运行日志
sudo docker logs daemon_dave # 查看名为 daemon_dave 的 docker 日志来看都做了什么
sudo docker logs -f daemon_dave # 类似于 tail -f 监控名为 daemon_dave 的 docker 日志
sudo docker logs --tail 10 daemon_dave # 查看名为 daemon_dave 的 docker 的最后10条日志
sudo docker logs -f --tail 0 daemon_dave # 查看名为 daemon_dave 的 docker 的最新日志
sudo docker logs -t daemon_dave # 使用 -t 参数来查看名为 daemon_dave 的 docker 添加了时间的日志,方便调试
在 Docker 容器中执行命令
sudo docker exec -d daemon_dave touch ~/cmd.test # 运行一个后台进程, docker 内执行进程 touch ~/cmd.test
sudo docker exec -t -i daemon_dave /bin/bash # 在容器中打开一个类似于 shell 的交互式任务
注: docker 1.3 版本引入 exec 命令,早期版本不支持
Docker 容器自动重启
sudo docker run --restart=always --name daemon_dave -d ubuntu /bin/sh -c "while true;do echo hello world ;sleep 2;done"
# 使用 --restart 参数自动重启容器,当容器执行异常停止时可以自动重启
查看 Docker 容器的信息
sudo docker inspect daemon_dave # 使用 docker inspect 查看名为 daemon_dave 容器的详细信息
sudo docker inspect --format='{{.State.Running}}' daemon_dave # 指定格式查看运行状态
sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' daemon_dave # 指定格式查看 ip 地址
sudo docker inspect --format '{{.Name}} {{.NetworkSettings.IPAddress}}' daemon_dave test_x64 # 同时查看多个容器
常用 Docker 镜像操作相关命令
sudo docker images # 查看当前系统中所有 docker 镜像
sudo docker images ubuntu # docker images 后指定镜像名查看指定名称的 docker 镜像
# (本地镜像都保存在 Docker 宿主机的 /var/lib/docker 目录下。在 /var/lib/docker/containers 下可以查看所有容器)
sudo docker pull ubuntu # 从 docker 官方拉取 ubuntu 仓库中标签为 latest 的官方镜像
sudo docker run -t -i --name next_container ubuntu /bin/bash # 当本地仓库中若名为 ubuntu 的镜像不存在,则自动从官方拉取镜像
sudo docker pull fedora # 手动拉取名为 fedora 的 docker 镜像
sudo docker search puppet # 查找名为 puppet 的镜像( docker search 查找 docker hub 上所有公共的可用的镜像)
sudo docker rmi fedora # 删除名为 fedora 的镜像(可以一次删除多个镜像)
sudo docker rmi `docker images -a -q` # 删除所有 docker 镜像
sudo docker tag magiche/test_nginx magiche/test_nginx_nginx_test_proj # 给镜像打上标签,方便 push 后查找
sudo docker push magiche/test_nginx # 将本地的镜像推送到 Docker hub 上(需要先用 docker login 登陆)
Docker hub 仓库操作
登录 Docker hub
sudo docker login # 登陆 docker hub
需要先在 https://hub.docker.com 上注册一个账号
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: magiche
Password:
Login Succeeded
构建自己的容器,可以在容器中安装所需要的应用,然后提交到仓库
sudo docker commit 8adc57ed42cc magiche/first_test # 提交当前构建的镜像
提交当前构建的镜像,提交时可以录入更多信息以便标识镜像
sudo docker commit -m=" A new custom image" --author=" HeYabin" 8adc57ed42cc magiche/first_test
使用 docker commit 可以创建镜像。提交的只是和当前镜像差异的部分。
编写 Dockerfile 并构建镜像
编写 Dockerfile 文件,文件名首字母大写,使用 docker build 命令构建命令时默认使用当前目录下 Dockerfile 文件来构建。
# Docker file for nginx
#
# VERSION 0.0.1 # 版本信息
FROM ubuntu:latest # 基准镜像
MAINTAINER HeYabin "xxxxxxxxx@qq.com" # 作者信息
RUN apt-get update # 镜像构建时执行的命令
RUN apt-get install -y nginx # 镜像构建时执行的命令
#RUN ["apt-get", "install", "-y", "nginx"] # 以上命令可以使用 exec 格式防止字符串错乱
RUN echo 'Hi, I am in your test container >/usr/share/nginx/html/index.html' # 镜像构建时执行的命令
EXPOSE 80 # 导出80端口
sudo docker build -t="magiche/test_nginx:first" . # 从 Dockerfile 构建一个镜像(推荐方式)
sudo docker history magiche/test_nginx # 使用 docker history 查看容器是如何构建出来的
将 GitHub 或 BitBucket 中含有 Dockerfile 文件的仓库连接到 Docker Hub 可以实现自动构建。
测试刚刚构建的 Docker 镜像
sudo docker run -d -p 80 --name test_web magiche/test_nginx nginx -g "daemon off;"
# -d 选项告诉 Docker 以分离( detached )的方式在后台运行,
# 命令: nginx -g "daemon off;" 以前台方式启动 nginx
# -p 选项用于告诉容器哪个端口提供给外部(宿主机),也可以指定宿主机端口和 docker 端口的映射关系
sudo docker run -d -p 80:80 --name test_web magiche/test_nginx nginx -g "daemon off;"
# 将 Docker 的 80 端口映射到宿主机的 80 端口
sudo docker run -d -p 127.0.01::80 --name test_web magiche/test_nginx nginx -g "daemon off;"
# 将 Docker 的 80 端口绑定到特定网络接口的随机端口
sudo docker run -d -p 127.0.01:8080:80 --name test_web magiche/test_nginx nginx -g "daemon off;"
# 将 Docker 的 80 端口绑定到特定网络接口的 8080 端口
sudo docker run -d -P --name test_web magiche/test_nginx nginx -g "daemon off;"
# 将 Docker 中所有声明的端口绑定到宿主机的随机端口
Dockerfile 编写示例
# 示例 Dockerfile ,请勿用该 Dockerfile 构建镜像 # 使用“ # ”号注释
#
# VERSION 0.0.1 # 版本信息
FROM ubuntu:latest # 基准镜像
MAINTAINER HeYabin "xxxxxxxxx@qq.com" # 作者信息
RUN apt-get update # 镜像构建时执行的命令
RUN apt-get install -y nginx # 镜像构建时执行的命令
#RUN ["apt-get", "install", "-y", "nginx"] # 可以使用 exec 格式防止字符串错乱,与上句等效
RUN echo 'Hi, I am in your test container >/usr/share/nginx/html/index.html' # 镜像构建时执行的命令
CMD ["/bin/bash","-l"] # 容器启动时要运行的命令,一个 Dockerfile 中只能指定一个 CMD 指令,多个 CMD 指令会使用最后一个指令,且该 CMD 指令会被 run 时传递的参数覆盖
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"] # 与 CMD 相似,但不会被 run 时传递的参数覆盖,而是将 run 时传递的参数传递给 ENTRYPOINT 指定的命令,确实要覆盖则在 run 时使用 --entrypoint 参数来覆盖
ENV TARGET_DIR /opt/app # 指定在构建镜像过程中设置环境变量,在构建的容器中运行 env 可以查看环境变量
WORKDIR $TARGET_DIR # 用于在创建容器时指定一个工作目录, ENTRYPOINT 和 / 或 CMD 指定的程序会在这个目录下运行,可以使用 -w 标志来覆盖这个工作目录
USER nginx # 用来指定该镜像是以什么身份去运行(用户身份可以使用 user 、 user:group 、 uid 、 uid:gid 、 user:gid 、 uid:group ),可以在 run 命令时使用 -u 来覆盖该指定的用户
VOLUME ["/opt/project"] # VOLUME 用来向基于镜像创建的容器中添加卷(卷可以对其他容器共享,卷一直存在直到没有容器使用它)
VOLUME ["/opt/project",“/data”] # 可以使用数组的方式创建多个卷
ADD software.lic /opt/application/software.lic # ADD 用于将构建环境下的文件复制到镜像中
ADD latest.tar.gz /var/www/wordpress/ # 添加 tar archive 及 gzip 、 bzip2 、 xz 指定为源文件时 Docker 会自动解开归档文件(使用 ADD 指令后后续指令都不能使用之前构建的缓存)
COPY conf.d/ /etc/apache2/ # 仅做拷贝而不提取文件,将本地 conf.d 文件夹中文件复制到容器镜像 /etc/apache2 目录下, COPY 会自动创建所需要的目录
ONBUILD ADD . /app/src # ONBUILD 指令用于给镜像添加触发器,当该镜像用作其他镜像的基础镜像时会触发 ONBUILD 添加的动作,相当于在引用该镜像的 Dockfile 中 FROM 后添加了 ADD . /app/src
ONBUILD RUN cd /app/src&&make # 可以使用 docker inspect 指令查看镜像构建时使用的 ONBUILD 指令
EXPOSE 80 # 导出 80 端口
导入导出构建的 Docker 镜像
sudo docker save 32bit/ubuntu:xenial > ubuntu_16.04_32bit.tar # 导出 docker 镜像
sudo docker load < ubuntu_16.04_32bit.tar # 导入 docker 镜像