容器实现封闭的环境主要要靠两种技术,一种是看起来是隔离的技术,称为 namespace(命名空间)。在每个 namespace 中的应用看到的,都是不同的 IP 地址、用户空间、进程 ID 等。另一种是用起来是隔离的技术,称为 cgroup(网络资源限制),即明明整台机器有很多的 CPU、内存,但是一个应用只能用其中的一部分。
所谓镜像(Image),就是在你焊好集装箱的那一刻,将集装箱的状态保存下来。就像孙悟空说:“定!”,集装箱里的状态就被“定”在了那一刻,然后这一刻的状态会被保存成一系列文件。无论在哪里运行这个镜像,都能完整地还原当时的情况。
当程序员根据产品设计开发完毕之后,可以将代码连同运行环境打包成一个容器镜像。这个时候集装箱就焊好了。接下来,无论是在开发环境、测试环境,还是生产环境运行代码,都可以使用相同的镜像。就好像集装箱在开发、测试、生产这三个码头非常顺利地整体迁移,这样产品的发布和上线速度就加快了。
启动一个容器需要一个叫 entrypoint 的东西,也就是入口。一个容器启动起来之后,会从这个指令开始运行,并且只有这个指令在运行,容器才启动着。如果这个指令退出,整个容器就退出了。
容器还有一个很酷的功能,就是镜像里面带应用。这样的话,应用就可以像集装箱一样,到处迁移,启动即可提供服务。而不用像虚拟机那样,要先有一个操作系统的环境,然后再在里面安装应用。
镜像运行的方式和操作系统不太一样,一个是 -d,因为它是一个应用,不需要像操作系统那样有交互命令行,而是以后台方式运行,-d 就是 daemon 的意思。
要通过 Dockerfile将这些代码放到容器镜像里面,Dockerfile 的格式应该包含下面的部分:
按照上面说的格式,可以有下面的 Dockerfile。
FROM ubuntu:14.04
RUN echo "deb http://archive.ubuntu.com/ubuntu trusty main restricted universe multiverse" > /etc/apt/sources.list
RUN echo "deb http://archive.ubuntu.com/ubuntu trusty-updates main restricted universe multiverse" >> /etc/apt/sources.list
RUN apt-get -y update
RUN apt-get -y install nginx
COPY test.html /usr/share/nginx/html/test.html
ENTRYPOINT nginx -g "daemon off;"
将代码、Dockerfile、脚本,放在一个文件夹下。
[nginx]# ls
Dockerfile test.html
现在我们编译这个 Dockerfile。
docker build -f Dockerfile -t testnginx:1 .
编译过后,我们就有了一个新的镜像。
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
testnginx 1 3b0e5da1a384 11 seconds ago 221MB
接下来,我们就可以运行这个新的镜像。
# docker run -d -p 8081:80 testnginx:1
f604f0e34bc263bc32ba683d97a1db2a65de42ab052da16df3c7811ad07f0dc3
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f604f0e34bc2 testnginx:1 "/bin/sh -c 'nginx -…" 2 seconds ago Up 2 seconds 0.0.0.0:8081->80/tcp youthful_torvalds
73ff0c8bea6e nginx "nginx -g 'daemon of…" 33 minutes ago Up 33 minutes 0.0.0.0:8080->80/tcp modest_payne
Docker 可以限制对于 CPU 的使用,我们可以分几种的方式。
Docker 会限制容器内存使用量,下面是一些具体的参数。
为了运行 Docker,有一个 daemon 进程 Docker Daemon 用于接收命令行。
为了描述 Docker 里面运行的环境和应用,有一个 Dockerfile,通过 build 命令称为容器镜像。容器镜像可以上传到镜像仓库,也可以通过 pull 命令从镜像仓库中下载现成的容器镜像。
通过 Docker run 命令将容器镜像运行为容器,通过 namespace 和 cgroup 进行隔离,容器里面不包含内核,是共享宿主机的内核的。对比虚拟机,虚拟机在 qemu 进程里面是有客户机内核的,应用运行在客户机的用户态。
此文章为12月Day3学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。