docker learning (six)

A, Dockerfile
use Dockerfile can allow users to create a custom image.

1. The basic structure
Dockerfile command statements consist of rows, and supports comment lines beginning with #.
General, Dockerfile divided into four parts: the base image information, perform a maintainer information, instructions and image containers start command.
Example
# This uses dockerfile The Ubuntu Image
# VERSION 2 - On. 1
# the Author: docker_user
# the Command the format: Instruction [arguments / Command] ..
# Base Image to use, the this AS MUST BE SET The First Line
the FROM Ubuntu
# the Maintainer: docker_user <docker_user AT email.com> (@docker_user)
MAINTAINER docker_user [email protected]
# Commands to Update at The Image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring to main Universe" >> / etc / APT /sources.list
RUN APT-GET Update && -y install nginx APT-GET
RUN echo "\ ndaemon OFF;" >> /etc/nginx/nginx.conf
A new new Commands Creating the when # Container
CMD / usr / sbin / nginx
where a start must specify the image name is based, the following recommended instructions maintainer information.
Is a mirror behind the operation instruction, instruction RUN e.g., image will follow the instruction RUN command. Each run a RUN command, add a new layer mirror and submit.
Finally CMD command to specify the operation command when running the container.
The following is a more complex example
# the Nginx
#
# VERSION 0.0.1
the FROM Ubuntu
the MAINTAINER on Victor Vieux <[email protected]>
the RUN APT-GET && APT-GET Update the install the inotify -Y-apache2 Nginx OpenSSH-Server Tools
# over Firefox the VNC
#
# 0.3 VERSION
the FROM Ubuntu
# the Install VNC, Xvfb in Order to Create A 'Fake' Firefox the display and
the RUN-APT APT-GET GET Update && the install Firefox -Y x11vnc Xvfb
the RUN mkdir /.vnc
# A password the Setup
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way, but it does the trick)
RUN bash -c 'echo "firefox" >> /.bashrc'
EXPOSE 5900
CMD ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION 0.1
FROM ubuntu
RUN echo foo > bar
# Will output something like ===> 907ad6c2736f
FROM ubuntu
RUN echo moo > oink
# Will output something like ===> 695d7793cbe4
# You᾿ll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.

2. Instruction
general instruction format is INSTRUCTION arguments, including the instruction FROM, MAINTAINER, RUN like.

2.1FROM
format FROM <image> or FROM <image>: <tag> .
Must first instruction FROM instruction. Further, when creating a plurality of mirrors in the same Dockerfile may be used a plurality FROM instruction (once per image).

2.2MAINTAINER
format MAINTAINER <name>, specify maintainer information.

2.3RUN
format RUN <command> or RUN [ "executable", "param1 ", "param2"].
The former will be run in a shell command terminal, i.e., / bin / sh -c; the latter is performed using the exec. Other terminal may specify a second manner, e.g. RUN [ "/ bin / bash" , "-c", "echo hello"].
Each RUN command to execute the specified command on the basis of the current mirror, and submit a new image. When the command is longer can use \ to wrap.

2.4CMD
supports three formats
a.CMD [ "executable", "param1 ", "param2"] use exec execution, the recommended way;
b.CMD param1 param2 executed in the Command / bin / sh, the application needs to provide interaction;
c.CMD [ "param1", "param2 "] is provided to the default parameters ENTRYPOINT;
specified command is executed when starting container, each Dockerfile only a command CMD. If you specify multiple commands, only the last one will be executed.
If the user starts when the container is specified to run the command, CMD specified command will be overwritten.

2.5EXPOSE
format EXPOSE <port> [<port> ...].
Tell the server port number Docker containers exposed, interconnect systems for use. Need -P, Docker hosts are automatically assigned when you start a container port forwarding to a specific port.

2.6ENV
format ENV <key> <value>. Specifies an environment variable, subsequent RUN command is used, and the container is maintained at runtime.

例如
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

2.7ADD
format ADD <src> <dest>.
This command copies the specified <src> into the container <dest>. Wherein <src> may be a relative path of the directory Dockerfile; may also be a the URL; tar may also be a document (automatically extracting the directory).

2.8COPY
format COPY <src> <dest>.
Copy the local host <src> (Dockerfile directory located relative path) into the container <dest>.
When using a local directory as the source directory, it is recommended to use COPY.

2.9ENTRYPOINT
two formats:
a.ENTRYPOINT [ "Executable", "the param1", "param2"]
b.ENTRYPOINT the param1 param2 Command (execute the shell).
Configuration of the container after start command, and is not covered by the parameter supplied docker run.
Only one each Dockerfile EntryPoint, when a plurality of designated, only the last onset.

2.10VOLUME
format VOLUME [ "/ data"].
Create a local host can mount from the mount point or other containers, generally used to store databases and data needs to be retained.

2.11USER
format USER daemon.
User name or UID run at specified container, subsequent RUN will use the specified user.
When the service does not require administrator privileges, you can specify a user to run this command. And you can create a user needs before, for example: RUN groupadd -r postgres && useradd -r -g postgres postgres. To temporarily obtain administrator privileges can
use gosu, not recommended sudo.

2.12WORKDIR
format WORKDIR / path / to / workdir.
For subsequent RUN, CMD, ENTRYPOINT instructions to configure the working directory.
WORKDIR plurality of instructions may be used, if the subsequent command parameter is a relative path, before the command will be specified based on the path. For example
the WORKDIR / A
the WORKDIR B
the WORKDIR C
the RUN pwd
the final path / a / b / c.

2.13ONBUILD
format ONBUILD [INSTRUCTION].
When configured as a mirror image created when a new operation command created other base image mirrored performed.
For example, Dockerfile creates a mirrored image-A using the following content.
[...]
ONBUILD the ADD. / App / src
ONBUILD RUN / usr / local / bin / Python-Build --dir / App / src
[...]
If you create a new image based on image-A, the new Dockerfile when using FROM image-a specifies the base image, is performed automatically ONBUILD instruction contents, is equivalent to adding two instructions later.
Image-A the FROM
#Automatically The following RUN
. / App / the src the ADD
the RUN / usr / local / bin / Python Build---dir / App / the src
using ONBUILD instruction image, indicated in the label recommended, e.g. ruby: 1.9 -onbuild.

3. Create a mirror
after their completion Dockerfile, you can create mirrored by docker build command.
The basic form is Dockerfile docker build [option] path, this command will read the specified path (includes subdirectories), and all content sent to the server at the Docker path, to create a mirrored by the server. It is generally recommended to place an empty directory Dockerfile directory. It can also make directories and files in the path Docker ignored by .dockerignore file (each line to add a matching pattern).
To specify the label information mirrored by the -t option, for example,
$ sudo docker build -t myrepo / myapp / tmp / test1 /

 

Second, the underlying implementation
Docker underlying core technologies include namespaces (Namespaces) on Linux, the control group (Control groups), Union File System (Union file systems) and container formats (Container format).

We know that the traditional virtual machine to simulate the operating system environment provides a complete set of hardware to the virtual machine running on the host through the host hypervisor. See the virtual machine system environment can be limited, and it is isolated from each other. This direct approach to achieve the most complete package of resources, but a lot of time often means a waste of system resources. For example, the host and virtual machine systems for the Linux system, for example, an application running in a virtual machine operating environment can actually make use of the host system.

We know that in the operating system, including the kernel, file system, network, PID, UID, IPC, memory, hard drive, CPU, etc., all resources are shared by direct application process. To achieve virtualization, in addition to implement restrictions on memory, CPU, network IO, hard disk IO, storage space, etc., but also implement file systems, network, PID, UID, IPC, and so isolated from each other. The former is relatively easy to implement some of the latter requires in-depth support of the host system.

With the Linux system to achieve perfect namespace features, programmers can already achieve all of the above requirements, allow certain processes to run in isolation from one another namespace. Although we all share the same kernel and certain environments (such as some system commands and system libraries) is running, but not see each other, the system has only thought of their own existence. This mechanism is the container (Container), the use of the name space to do the rights of isolation control, use cgroups do resource allocation.

1. The basic architecture
Docker using the C / S architecture, including client and server. Docker daemon as a server accepts requests from clients and deal with these requests (create, run, distribute containers). The client and server can either run on a machine, but also to communicate through the socket or RESTful API.

 

 


Docker daemon host typically in a host background, waiting to receive a message from the client. Docker client was to provide users with a series of executable commands, users achieve with Docker daemon to interact with these commands.

2. namespace
name space is a powerful feature of the Linux kernel. Each container has its own separate namespace, run applications which are like running the same operating system independent. Namespace ensures independent from other between the vessel.

2.1 pid namespace
different users is through the process pid namespace is isolated, and different namespace can have the same pid. All LXC process in the parent process is in Docker Docker processes, each process has a different name LXC space. And because allowing nested, it is possible to easily achieve Docker nested containers.

2.2 net名字空间
有了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。Docker 默认采用 veth 的方式,将容器中的虚拟网卡同 host 上的一 个Docker网桥 docker0 连接在一起。

2.3 ipc名字空间
容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存等。然而同 VM 不同的是,容器的进程间交互实际上还是 host 上具有相同 pid 名字空间中的进程间交互,因此需要在 IPC 资源申请时加入名字空间信息,每个 IPC 资源有一个唯一的 32位 id。

2.4mnt名字空间
类似 chroot,将一个进程放到一个特定的目录执行。mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个名字空间中的容器在 /proc/mounts 的信息只包含所在名字空间的 mount point。

2.5uts名字空间
UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。

2.6user名字空间
每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。
*注:关于 Linux 上的名字空间,这篇文章 介绍的很好。

3.控制组
控制组(cgroups)是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。
控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。
控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。

4.联合文字系统
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into asingle virtual filesystem)。

联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。

Docker 目前支持的联合文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。

5.容器格式
最初,Docker 采用了 LXC 中的容器格式。自 1.20 版本开始,Docker 也开始支持新的 libcontainer 格式,并作为默认选项。对更多容器格式的支持,还在进一步的发展中。

6.Docker网络实现
Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair)。建议先熟悉了解这两部分的基本概念再阅读本章。

6.1基本原理
首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。

Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。

Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 veth pair )。

6.2创建网络参数
Docker 创建一个容器的时候,会执行如下操作:
创建一对虚拟接口,分别放到本地主机和新容器中;
a.本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9;
b.容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的名字空间可见;
c.从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。
d.完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。
可以在 docker run 的时候通过 --net 参数来指定容器的网络配置,有4个可选值:
a.--net=bridge 这个是默认值,连接到默认的网桥。
b.--net=host 告诉 Docker 不要将容器网络放到隔离的名字空间中,即不要容器化容器内的网络。此时容器使用本地主机的网络,它拥有完全的本地主机接口访问权限。容器进程可以跟主机其它 root 进程一样可以打开低范围的端口,可以访问本地网络服务比如 D-bus,还可以让容器做一些影响整个主机系统的事情,比如重启主机。因此使用这个选项的时候要非常小心。如果进一步的使用 --privileged=true ,容器会被允许直接配置主机的网络堆栈。
c.--net=container:NAME_or_ID 让 Docker 将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过 lo 环回接口通信。
d.--net=none 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己

6.3网络配置细节
用户使用 --net=none 后,可以自行配置网络,让容器达到跟平常一样具有访问网络的权限。通过这个过程,可以了解 Docker 配置网络的细节。

首先,启动一个 /bin/bash 容器,指定 --net=none 参数。
$ sudo docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#
在本地主机查找容器的进程 id,并为它创建网络命名空间。
$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
检查桥接网卡的 IP 和子网掩码信息。
$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...
创建一对 “veth pair” 接口 A 和 B,绑定 A 到网桥 docker0 ,并启用它
$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up
将B放到容器的网络命名空间,命名为 eth0,启动它并配置一个可用 IP(桥接网段)和默认网关。
$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1
以上,就是 Docker 配置网络的具体过程。
当容器结束后,Docker 会清空容器,容器内的 eth0 会随网络命名空间一起被清除,A 接口也被自动从
docker0 卸载。
此外,用户可以使用 ip netns exec 命令来在指定网络名字空间中进行配置,从而配置容器内的网络。

Guess you like

Origin www.cnblogs.com/muxi0407/p/12023638.html