记录一些特别容易遗忘的 Docker 知识细节

  1. 镜像实际上是文件夹,每个镜像命令会产生出单独的一层。我们删除文件不一定能够删得掉,可删除的文件也只是在联合文件系统里面增加一个“被删除层”。
  2. 容器像是集装箱。这通常是启动内部代理的一个方法。docker 寻求的解决方案不是虚拟化,而是进程间的软隔离。
    1
    2
    3
    4
    5
    6
    # 启动 docker 容器
    docker run -d -p 2222:22 --name 容器名 镜像名
    # -d 守护容器,就是后台运行,退出命令窗口容器也不会停止
    # -it 交互式容器 退出命令窗口容器就停止运行了
    # -p 宿主机端口和容器端口映射
    # 8081:80 宿主机端口: 容器公开的端口
  3. Docker 同hypervisor的区别是,hypervisor总是起了多个内核。实际上阿里开源的容器技术 pouch,也是基于多 hypervisor 的。

  4. docker inspect 既可以查看容器,也可以查看镜像。用以下的命令单独查看一个属性:

    1
    docker inspect -f '{{.NetworkSettings.IPAddress}}' [ID /Name]
  5. docker 的设计者对基于 docker 构建的软件架构的思路是:container -> service(compose 领域) -> Swarm -> stack。一个服务等于一个镜像的多个 runtime instances。一个 stack 等于可以被编排在一起的,共享依赖的多个 service,而且可以be orchestrated and scaled together。Essentially, it turns a pool of Docker containers into one single, virtual Docker host. 本质上,swarm把一池子的容器变成一个docker主机。
  6. 可以帮助管理docker的曾经的手段:vagrant、docker-machine。
  7. docker 的一等公民有:container(service)、volume、network、image,它们都是可以命名的。docker 中服务名和容器名都可以代替 IP。
  8. docker的三根柱子:namespace、control group、unionfs,第四根柱子:container format。

label

Label 是键值对,是 metadata,是贯穿于 Docker 各个资源的,包括引擎、镜像、容器、卷、网络、Swarm 节点、服务等。类似 consul 的标签。是一系列可能复合路径的键值对。用label命令打到镜像上,与tag不同,不代表版本,代表的是属性。

键 key:格式要求只可以包含字母和数字,以及.,-。推荐使用类似于 Java 那种反向域名格式,如 com.example.mytag。
值 value:格式必须是字符串,除了普通字符串外,还可以是 JSON, XML, CSV 或者 YAML,当然,需要先进行序列化。

当资源很少的时候,我们可以直接对一个个资源进行操作,但是,在管理很多资源的时候,这么做就变得不大现实。经常的需求是针对某一类的资源进行操作,而不是一个个的操作。这种情况,经常会使用 label 来帮助实现。

后台运行 docker 问题

不知道为什么,直接docker run -d abc 容器总是会得到直接退出的结果。
根据docker-container-will-automatically-stop-after-docker-run-d的结果,没有准备 -t 的 unattached 状态的容器,在运行一起来的时候,bash 就会退出。所以正确的用法恐怕是docker run -td abc
示例:

1
2
3
docker run -td fb5fe65dd4e2
# 注意,exec 必须要有两个参数,startup command 也是必须的,等于另起了一个 bash。
docker exec -it 1d766b0ac408 /bin/bash

-t的用处是启动一个tty,让这个os处在一种可以被attach的状态,这就可以不让它自动退出了。