Tes Global 工程师总结的24条 Docker 实用建议

云计算
Tes Global的工程师Csaba Palfi从CLI、Dockerfiles、网络、卷、安全方面总结了他们学习与使用Docker过程中的经验,一共24条,非常实用。

Tes Global的工程师Csaba Palfi从CLI、Dockerfiles、网络、卷、安全方面总结了他们学习与使用Docker过程中的经验,一共24条,非常实用。

在TES GLOBAL,我们已经爱上Docker并从Docker的0.8版本开始就在生产环境中使用它。我们的很多开发者都参加了在DockerCon欧洲上的培训。下面是我们总结的一些tips,希望可以帮到已经有Docker基础的同学。

1. CLI

1.1 美化docker ps的输出

将Docker ps的输出通过管道到 less -S,这样表格式的行就不会被折叠。

docker ps - a | less -S 

1.2 刷新日志

docker的日志不会即时刷新,除非你使用了-F选项:

docker logs <containerid> -F 

1.3 从docker inspect中获取一个单一的值

docker inspect 默认会输出大量的 JSON 格式的数据。你可以用 jq,来得到某一特定键的值。或者你可以使用内置的 go 模板功能:

最后一个docker容器现在运转正常吗?

docker inspect --format '{{.State.Running}}' $(docker ps -lq) 

1.4 使用docker exec而不是sshd 或者 nsenter

如果你查看过 Docker 的发行版你会你会很清楚这个小技巧。exec 在是在1.3版本中添加的新功能,可以让你在容器里面运行一个新的进程。这样你就不必运行 sshd 或者在主机上安装 nscenter。

2. Dockerfiles

2.1 docker build支持git仓库

你不但可以从本地的 Dockerfile 中创建 Docker 镜像,你还可以简单的给 docker build 指定一个仓库的 URL ,然后 docker build 会为你做完余下的事情。

2.2 没有软件包列表

默认的镜像(如Ubuntu)是不包含软件包列表的,目的是让镜像体积更小。因此需要在任何的基础的 Dockerfile 中需要使用 apt-get update。

2.3 留意软件包的版本

注意软件包的安装,因为这些命令也是会缓存起来的。意味着如果你清空了缓存,你可能会得到不同的版本;或者如果缓存长期不更新,你可能不会得到最新的安全更新。

2.4 小体积的基础镜像

在Docker Hub上有一个官方的真正零体积的Docker镜像,它的名字叫做 scratch。所以如果你有这种需求,可以让你的镜像从零开始。而大多数的情况下,你最好还是从 busybox 开始,其大小只有2.5M。

2.5 FROM默认会获取最新的

如果在 FROM 关键字后你没有指定一个版本的 tag ,那么默认就会获取最新的。请注意这点,并确保尽可能的指定一个特定的版本。

2.6 shell或者是exec模式

在 Dockerfile 中可以通过两种方式来指定命令(如 CMD RUN 等)。如果你仅仅写下命令那么Docker 会将其包裹在 sh -c 命令中执行。你也可以写成一个字符串数组的形式。数组的写法不需要依赖容器中的 shell,因为其会使用 go 的 exec。Docker 的开发者建议使用后一种方式。

2.7 ADD vs COPY

ADD 和 COPY 都能在创建容器的时候添加本地的文件。但是 ADD 有一些额外的魔力,如添加远程的文件、unzip 或者 untar 一些文件包等。使用 ADD 之前请了解这种差别。

2.8 WORKDIR和ENV

每个命令都会创建一个新的临时镜像并在新的 shell 中运行,所以如果你在Dockerfile中不能运行  cd <directory> 或者 export <var>=<value>。使用 WORKDIR 在多个命令中设置工作目录并使用 ENV 来设置环境变量。

2.9 CMD和ENTRYPOINT

CMD是当一个镜像在运行时默认会执行的命令。默认的  ENTRYPOINT 是 /bin/sh -c,然后 CMD 会以参数的形式被传入。我们可以在 Dockerfile 中覆盖 ENTRYPOINT 以让我们的容器像在接受命令行参数(默认的参数在 Dockerfile中的CMD指定)。

Dockerfile中 

 

ENTRYPOINT /bin/ls 

CMD ["-a"

我们覆盖了命令行但是netrypoint仍然是ls 

 

docker run training/ls -l 

2.10 将ADD置于末尾

如果文件发生改变,ADD 会让缓存失效。不要 在Dockerfile 中添加经常变化的东西,以避免让缓存失效。将你的代码放在最后,将库和依赖放在最前。对于 Node.js 的应用来说,这意味着将 package.json 放在前面,运行 nmp install 然后添加你的代码。

3. Docker的网络

Docker 有一个内置的 IP 池,用来指定容器的 ip 地址。它对外是不可见的,通过桥接的网口可以访问到。

3.1 查找端口的映射

docker run 接收显式的端口映射作为参数,或者你可以通过 -P 选项来映射所有的端口。第二种做法的好处是能防止冲突。可以通过以下命令查找指定的端口:

docker port containerID portNumber 

或者

docker inspect --format '{{.NetworkSettings.Ports}}' 

containerID 

3.2 容器的IP地址

每一个容器都拥有自己属于私有网段的 IP 地址(默认是172.17.0.0/16)。IP 可能会在重启的时候发生变化,如果你想知道其地址,可以用:

docker inspect --format '{{.NetworkSettings.IPAddress}}' containerID 

Docker 会尝试检查冲突,在需要的情况下会使用不同的网段的地址。

3.3 接管主机的网络

docker run --net=host 能重用网络。但是请不要这么做。

4. 卷(volume)

一个绕过目录或者单一文件写时复制(copy-on-write)的文件系统,接近零负载(绑定挂载)。

4.1 卷的内容在docker commit的时候不会被保存

在镜像建立后写入你的卷没有太多的意义。

4.2 卷默认是可读可写的

但是有一个 :ro 的标志。

4.3 卷和容器是分开存在的

卷只要有一个容器使用他们就会存在。可以在容器之间通过 --volumes-from 选项共享。

4.4 挂载你的docker.sock

你可以仅仅挂载 docker.sock 就能让你的容器访问到 Docker 的 API 。然后你可以在该容器中运行 Docker 的命令。这样容器甚至还可以杀死自己,在一个容器里面运行一个 Docker的守护者进程是没有必要的。

5. 安全

5.1 以root身份运行Docker

Docker API 能给 root 的访问权限,因为你可以将/映射成一个卷,然后读或者写。或者你可以通过 --net host 接管宿主机的网络。不要暴露 Docker API 如果你需要请使用 TLS。

5.2 Dockerfile中的USER

默认下 Docker 可以以 root 的身份运行任何命令,但是你可以使用 USER。Docker 没有用户的命名空间,因此容器将用户看作是宿主机上的用户。但是仅仅是 UID 因而你需要在容器里面添加该用户。

5.3 使用TLS操作Docker API

Docker 1.3版本添加了对 TLS 的支持。他们使用手动的验证机制:客户端和服务端都有一个 Key。把 Key 看做是 root 用户的密码。从1.3版本开始,Boot2docker 默认使用 TLS 并且会为你生成 key。

另外生成 Key 需要 OpenSSL 1.0.1 以上版本的支持,然后 Docker daemon 进程需要加上 --tls-verify 选项运行,Docker 会使用安全的端口(2376)。

本文出自:http://www.open-open.com/lib/view/open1419219210718.html

 

责任编辑:Ophira 来源: OPEN经验库
相关推荐

2015-08-03 09:49:24

2018-04-18 08:36:48

Linux命令运维

2019-07-29 16:05:48

前端DockerNode.js

2010-10-20 10:26:28

2018-08-17 15:33:37

2015-02-04 09:19:03

Web优化

2020-07-10 14:25:32

Python编程代码

2020-09-17 16:11:04

软件开发 技术

2009-04-13 11:50:14

经验交流职业分析面试

2013-07-17 13:03:19

创业者创业总结

2013-07-18 09:42:47

创业总结

2022-02-14 11:14:34

Java工程师开发

2010-08-17 16:55:57

HCSE高级网络工程师

2021-03-12 15:18:45

算法 Facebook技术

2020-08-24 09:01:07

算法开源技术

2009-09-08 17:50:01

2015-08-26 14:18:25

Web前端工程师价值

2013-07-16 10:38:41

游戏设计师移动游戏手机游戏

2019-10-29 16:29:28

运维架构开发

2015-05-04 13:24:12

工程师OpenStack公有云
点赞
收藏

51CTO技术栈公众号