容器,可以理解为“打包好的程序运行环境”。对开发、运维、测试三方来说,都需要搭建同一套环境,因此容器技术可以为三方都提供了一套便捷可复现的程序运行环境。
我们如果将机器看作程序运行的环境,那么打包好的虚拟机也可以被理解为一种”打包好的程序运行环境“。容器与虚拟机对比,其最大的优点在于 轻量化。虚拟机通常包括了完整的独立的操作系统功能,而容器则可以通过共享操作系统来实现轻量化。相比于虚拟机中操作系统GB级别的内存占用,容器则可以做到MB级别。
容器技术只隔离应用程序的运行时环境,但容器之间可以共享同一个操作系统,这里的运行时环境指的是程序运行依赖的各种库以及配置。
从性能上说,容器能够达到与物理机系统几乎一致的执行性能,而且体积小,启动快,总之优点可以浓缩成一个字——快!
但是缺点也很多,以docker为例:
- 采用client-server方式,如果server宕机那么所有容器都寄了。
- debug很麻烦,非常麻烦
- 虚拟机,比如openstack可以通过neutron来灵活构建各种网络架构,而docker在网络方面的支持不大行
- 相较于虚拟机,容器无法实现“Build once,run everywhere”,因为容器技术只是打包了用户空间的系统调用,但是系统调用真正执行的地方在于宿主的内核。因此如果宿主的内核版本不同,则行为不一定一致。
docker是基于Go语言开发的一个开源的容器技术实现。
docker的实现是基于Linux系统的NameSpace和Control Groups机制的,因此必须部署在Linux系统上。windows和mac上使用的Docker Desktop本质上还是在Linux虚拟机上安装Docker。
docker的应用场景包括:
- Web应用的自动化打包和发布:对一些自动化构建与部署工具,其会从源代码仓库拉取代码后打包,构建成功后写入到docker镜像后推送到镜像服务器,然后通知应用服务器拉取镜像文件启动应用
- 数据科学中更好的复现:Kaggle等很多DM竞赛中会要求参赛者提供自己的docker镜像,以进行复现
- 微服务架构:容器技术为微服务的解耦和持续交付提供了便利
- QPS扩容:新增一个容器可以轻松地对当前网络服务进行水平扩展,提高对高峰流量的抵抗能力
- 培训小白:丢给他一个docker镜像,轻松保证了开发环境的一致性
docker中有几个概念:
- Dockerfile:容器对象的配置文件
- image:docker根据dockerfile所生成的镜像对象
- container:容器实体所运行的进程
- docker registry:docker镜像的仓库
而一个基本的容器部署过程可以被描述为:
- 根据需求,编写dockerfile
- 执行
docker build
,docker对dockerfile进行“编译”,得到image - 指定一个image执行
docker run
,docker将其加载到内存中启动,对应的进程就是container
docker指令
docker run
来在容器内指定运行一个镜像并执行一定指令
docker run ubuntu:latest /bin/echo "hello world"
- -i:允许对容器内的标准输入进行交互
- -t:在容器内指定一个终端进行交互
- -d:让容器在后台运行
- --name:指定容器的名称
- -P:让容器内部的网络端口随机映射到我们的主机上
- -p:指定端口映射规则,比如
-p 3000:5000
将容器的5000端口映射到主机的3000端口上 - -v:挂载主机的目录到容器中,比如
-v /mydir:/data
将主机的mydir目录同步挂载到容器的data目录 - --volumes-from:指定另一个镜像,并使两者共享其挂载点
docker rm
移除指定容器
- -f:强制移除
docker start
启动一个已停止的容器,包含了对容器文件系统的挂载
docker stop
关闭一个正在运行的容器,包含了对容器文件系统的卸载
docker restart
重启一个容器(可以是正在运行的),不包含对容器文件系统挂载或卸载
docker exec
进入一个正在运行的容器(后台运行中)
docker ps
来查看当前本机的所有容器及其状态
- -a:打印详细信息
docker images
查看当前主机上的所有镜像和状态
docker logs
查看指定容器内部的标准输出
- -f:实时监控并刷新输出
docker pull
从镜像仓库中拉取或更新指定镜像
docker search
从镜像仓库中搜索指定镜像
docker rmi
删除指定镜像
docker export
导出指定容器,得到一个镜像的快照文件。常用于制作基础镜像
- -o:指定导出的文件
docker import
导入指定快照文件。支持通过网络导入
构建自己的镜像需要编写Dockerfile
Dockerfile的每一行会依次执行,其效果相当于在基础镜像上套上一个新的层。Dockerfile中最多127层。每个指令的前缀必须大写
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
- FROM:指定基础镜像源
- MAINTAINER:声明构建者
- RUN:执行命令
- ENV:声明环境变量
- ADD:添加主机文件到容器中(压缩文件会自动解压)
- COPY:添加主机文件到容器中
- WORKDIR:指定工作目录
- EXPOSE:指定容器内应用可使用的端口
- CMD:启动容器时默认执行的命令。如果在
docker run
时指定了启动指令,则该条被覆盖 - VOLUME:在容器内新建主机目录的挂载点。但是不能指定主机上对应的目录,只相当于声明了“该容器有这些挂载点”
docker build
将Dockerfile构建为镜像文件
- -t:指定镜像名称与版本
- -f:指定Dockerfile文件路径