guojh's Blog.

Docker笔记

字数统计: 2k阅读时长: 7 min
2019/05/29

Docker是一种虚拟容器技术,可以将数据、代码、依赖环境等打包,对开发、重复测试、快速部署等过程都十分有帮助。 这里记录一下Docker的基础知识,方便日后查看。 本文参考资料包括《第一本Docker书》、Docker官网资料及相关博客。

更新信息

  • 2019-05-29 初始版本

Docker基础概念

容器

  • 管理程序虚拟化:通过中间层将一台或多台独立的机器虚拟运行在物理硬件之上
  • 容器虚拟化:直接运行在操作系统内核之上的用户空间。"操作系统级虚拟化"

容器只能运行与底层宿主机相同或相似的操作系统,因此在OS X和Windows运行则需要虚拟环境。

优势:容器不需要模拟层和管理层,降低了开销。同一宿主机可以运行更多的容器,充分利用系统资源。

Docker

Docker是一个把开发的应用程序自动部署到容器的开源引擎,基于Go语言并遵从Apache2.0开源协议。也被称为轻量级虚拟化技术。

用处:

  • 开发人员可以轻松构建、运行并分享docker容器
  • 创建轻量化隔离环境,用于开发、测试等
  • 构建自动化和构建管理,方便协作者使用统一、一致的开发环境
  • 容器化的程序构建一次,可在各平台上运行
  • 等等

Docker组件:

  • Docker客户端和服务器,也称为Docker引擎:

    Docker客户端向服务器或守护进程发出请求,服务器或守护进程完成工作并返回结果;

    可远程连接

  • Docker镜像(Image):

    用于创建docker容器的模板,体积很小。处于Docker生命周期中构建或打包阶段

  • Docker容器(Container):

    基于镜像启动起来,独立运行的一个或一组应用。处于启动或执行阶段

    Docker容器就是一个镜像格式、一系列标准操作、一个执行环境

  • 仓库registry:

    Docker Hub保存公共和私有仓库 https://hub.docker.com/

docker在各平台上安装可以参考官方网站 https://docs.docker.com/

GitHub上一个很好的资源:docker-cheat-sheet https://github.com/wsargent/docker-cheat-sheet

1 Docker容器

以下命令可能需要root权限使用。 另外,在容器中安装软件包之前,最好先更换下源,否则速度较慢。

基础命令

1
2
3
4
5
6
# 查看帮助
docker -h
docker [命令] --help

# 查看docker是否正常工作
docker info

docker run

创建并运行容器,等于docker create+docker start

创建(但不运行)一个容器用docker create

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -it 交互容器(-i: interactive, -t: terminal)
# 使用ubuntu作为镜像;最后表示在容器运行什么命令.
docker run -it ubuntu /bin/bash

# -d 守护式容器(-t: daemon),没有交互式对话,适合运行后台应用程序及服务
docker run -d ubuntu /bin/sh -c "while true; do echo hello docker; sleep 1; done"
docker logs daemon_dave # 获取容器日志
docker logs -f daemon_dave # 持续跟踪日志内容

# --name 进行容器命名
docker run --name bob_the_container -it ubuntu /bin/bash

# -p 进行端口映射,[host_port]:[container_port]
docker run -it -p 7776:22 -p 7777:80 /bin/bash

# -v 进行本地路径映射,[container_path]:[host_path]
docker run -it -v $PWD:/root/code /bin/bash

# 退出交互容器(在容器中使用)
exit

其他命令

1
2
3
4
# 显示容器列表(运行中)
docker ps
# 显示所有容器列表(运行+非运行)
docker ps -a
1
2
3
4
5
# 重启容器
docker start -ia <容器名或id>
# 退出任意指定容器
docker stop <容器名或id>
docker kill <容器名或id>
1
2
3
4
# 删除容器(需先停止容器)
docker rm <容器名或id>
# 删除所有容器
docker rm `docker ps -a -q`
1
2
3
4
5
6
7
8
# 在运行的容器中运行后台任务
docker exec -d daemon_dave touch /etc/new_config_file

# 在运行的容器中运行交互命令(既是容器是一个守护容器也可以通过这种方式进入交互界面)
docker exec -it daemon_dave /bin/bash

# root权限
docker exec -it -u root daemon_dave /bin/bash

2 Docker镜像和仓库

这部分中许多概念和Git和CMake类似,可以类比理解。

镜像与容器的关系:Docker容器可以看作是Docker镜像的一个实例。

Docker镜像由文件系统叠加而成。镜像栈的最底部称为基础镜像base image。Docker中运行的程序在最顶层读写层执行。

拉取开源镜像

1
2
3
4
5
6
7
8
9
# 列出本地已有的所有镜像
docker images
# 删除镜像
docker rmi gjgjh/mytest
docker rmi `docker images -a -q` # 删除所有镜像
# 搜索镜像。也可以在Docker hub官网搜索
docker search ubuntu
# 拉取特定版本官方Ubuntu镜像
docker pull ubuntu:16.04

除了使用别人的开源镜像,下面是两种方法自己构建镜像。

commit命令构建镜像

类似git提交变更。在容器中作出修改后,将修改提交为一个新镜像。

为自己的镜像命名:user_name/repo_name:tag_name,与官方命名(不加user_name)区分开。其中,如果不指定版本号,则tag_name默认是latest。一个具体例子:

1
2
3
4
5
docker run -it ubuntu /bin/bash
apt-get update
apt-get install vim # 做出的修改
exit
docker commit <容器名或id> gjgjh/myubuntu:v1.1.0 # commit也可以像git一样加-m等参数

Dockerfile构建镜像

1
2
3
4
# 新建一个目录和Dockerfile文件
mkdir test
cd test
touch Dockerfile

Dockerfile文件是通过一些指令来构建Docker镜像的,举个例子:

1
2
3
4
5
6
7
8
9
# 文件名:myubuntu.Dockerfile
# 从基础镜像运行一个容器
FROM ubuntu:16.04
# 标识镜像的作者信息
MAINTAINER gjgjh "guojinhui4@gmail.com"
# 执行相关指令
RUN apt-get update && apt-get install -y build-essential
# 指定容器启动时要运行的命令,类似第2节docker run时指定的命令
ENTRYPOINT ["/bin/bash"]

在Dockerfile相同目录下执行下面命令开始构建镜像:

1
docker build -t="gjgjh/mytest:v1.0" .

这里构建的工作原理:

  • docker从基础镜像运行一个容器
  • 执行一条指令,对容器做出修改
  • 执行类似docker commit的操作,提交一个新的镜像层
  • docker再基于刚提交的镜像运行下一个新容器
  • 执行Dockerfile下一条指令,直到所有指令执行完毕

可以看出,如果某条命令失败,没有正常结束,那么用户仍然可以得到一个半成品镜像,这将有助于调试找出失败指令。如果不想要这样的构建缓存机制,可以在docker build时加上—no-cache参数。

其他Dockerfile指令

RUN:镜像构建时要运行的命令

CMD:容器启动时要运行的命令。命令及参数放于数组结构中。会被命令行指定的命令覆盖。只能指定一条,否则只有最后一个CMD指令有效

ENTRYPOINT:命令行中参数会再次传递给ENTRYPOINT

WORKDIR:设置工作目录。会被命令行-w参数覆盖

ENV:环境变量,持久保存到该镜像创建的任何容器中。命令行-e参数只是运行时有效

VOLUME:本地文件或目录挂载到镜像(创建的容器)。而docker cp命令可以从容器复制文件到本地,非常常用。

COPY & ADD:将构建环境下的文件和目录复制到镜像。区别是COPY不会去做解压等工作

LABEL:添加元数据,以键值对形式展现。

其他指令和用法可参考官网 https://docs.docker.com/engine/reference/builder/

上传本地镜像

类似可以将代码推送到github远程管理一样,也可以将本地镜像推送到Docker Hub:

1
2
# 先docker login登录后再push到Docker Hub
docker push gjgjh/mytest:v1.0

保存本地镜像文件

1
2
3
4
5
# 保存镜像到本地文件
docker save -o mytest.tar gjgjh/myubuntu:latest

# 从镜像文件加载镜像
docker load -i mytest.tar

4 一些重要的Docker镜像

  • Docker+ROS开发环境镜像:gjgjh/ros_vins
  • 深度学习环境镜像:nvidia/cuda:10.2-devel-centos7

个人理解错误的地方还请不吝赐教,转载请标明出处

CATALOG
  1. 1. 更新信息
  2. 2. Docker基础概念
    1. 2.1. 容器
    2. 2.2. Docker
  3. 3. 1 Docker容器
    1. 3.1. 基础命令
    2. 3.2. docker run
    3. 3.3. 其他命令
  4. 4. 2 Docker镜像和仓库
    1. 4.1. 拉取开源镜像
    2. 4.2. commit命令构建镜像
    3. 4.3. Dockerfile构建镜像
      1. 4.3.1. 其他Dockerfile指令
    4. 4.4. 上传本地镜像
    5. 4.5. 保存本地镜像文件
  5. 5. 4 一些重要的Docker镜像