Docker
docker概念
Docker 扩展了 Linux 容器(Linux Containers),或着说 LXC,通过一个高层次的 API 为进程单独提供了一个轻量级的虚拟环境。Docker 利用了 LXC, cgroups 和 Linux 自己的内核。一个 Docker 容器并不包含一个单独的操作系统,而是基于已有的基础设施中操作系统提供的功能来运行的。
- Docker类似虚拟机的概念,但是与虚拟化技术的不同点在于下面几点:
- 虚拟化技术依赖物理CPU和内存,是硬件级别的;而docker构建在操作系统上,利用操作系统的containerization技术,所以docker甚至可以在虚拟机上运行。
- 虚拟化系统一般都是指操作系统镜像,比较复杂,称为“系统”;而docker开源而且轻量,称为“容器”,单个容器适合部署少量应用,比如部署一个redis、一个memcached。
- 传统的虚拟化技术使用快照来保存状态;而docker在保存状态上不仅更为轻便和低成本,而且引入了类似源代码管理机制,将容器的快照历史版本一一记录,切换成本很低。
- 传统的虚拟化技术在构建系统的时候较为复杂,需要大量的人力;而docker可以通过Dockfile来构建整个容器,重启和构建速度很快。更重要的是Dockfile可以手动编写,这样应用程序开发人员可以通过发布Dockfile来指导系统环境和依赖,这样对于持续交付十分有利。
- Dockerfile可以基于已经构建好的容器镜像,创建新容器。Dockerfile可以通过社区分享和下载,有利于该技术的推广。
Docker 会像一个可移植的容器引擎那样工作。它把应用程序及所有程序的依赖环境打包到一个虚拟容器中,这个虚拟容器可以运行在任何一种 Linux 服务器上。这大大地提高了程序运行的灵活性和可移植性,无论需不需要许可、是在公共云还是私密云、是不是裸机环境等等。
- 使用man docker-docker命令 可以查看docker各个命令的使用手册。
- Docker也是一个云计算平台,它利用Linux的LXC、AUFU、Go语言、cgroup实现了资源的独立,可以很轻松的实现文件、资源、网络等隔离,其最终的目标是实现类似PaaS平台的应用隔离。
Docker 由下面这些组成:- Docker 服务器守护程序(server daemon),用于管理所有的容器。
- Docker 命令行客户端,用于控制服务器守护程序。
- Docker 镜像:查找和浏览 docker 容器镜像。
docker特性
- 文件系统隔离:每个进程容器运行在完全独立的根文件系统里。
- 资源隔离:可以使用cgroup为每个进程容器分配不同的系统资源,例如CPU和内存。
- 网络隔离:每个进程容器运行在自己的网络命名空间里,拥有自己的虚拟接口和IP地址。
- 写时复制:采用写时复制方式创建根文件系统,这让部署变得极其快捷,并且节省内存和硬盘空间。
- 日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。
- 变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。
- 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次性交互shell。
两个基础概念images与container
Container和Image 在Docker的世界里,Image是指一个只读的层(Layer),这里的层是AUFS里的概念。
Docker使用了一种叫AUFS的文件系统,这种文件系统可以让你一层一层地叠加修改你的文件,最底下的文件系统是只读的,如果需要修改文件,AUFS会增加一个可写的层(Layer),这样有很多好处,例如不同的Container可以共享底层的只读文件系统(同一个Kernel),使得你可以跑N多个Container而不至于你的硬盘被挤爆了!这个只读的层就是Image!而如你所看到的,一个可写的层就是Container。
- Image和Container区别仅仅是一个是只读的层,一个是可写的层,你可以使用docker commit 命令,将你的Container变成一个Image,也就是提交你所运行的Container的修改内容,变成一个新的只读的Image,这非常类似于git commit命令。
启动docker
- service docker start/stop/restart 来控制docker的启动与重启。
镜像的获取与容器的使用
镜像可以看作是包含有某些软件的容器系统,比如ubuntu就是一个官方的基础镜像,很多镜像都是基于这个镜像“衍生”,该镜像包含基本的ubuntu系统。再比如,hipache是一个官方的镜像容器,运行后可以支持http和websocket的代理服务,而这个镜像本身又基于ubuntu。
- 使用run则通过image开启一个新的container: docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
- -it意思是将容器的bash和当前的bash关联即交互式容器,
- --name=名字 若没有指定name会自动命名一个name。
- -d 则是在以后台方式启动命令,command结束后容器依旧会停止。
- -p --publish=[] 指定映射哪些端口,[]内可指定宿主机端口和ip
- 重新启动已经停止的容器:docker start [-i] 容器名
- 停止容器:使用stop会向容器中发送停止命令停止容器,kill会直接停止容器。
- 删除容器:docker rm 容器名,不能删除运行中的容器,只能删除已经停止的容器。
持久化容器与镜像
- 通过容器生成新的镜像:运行中的镜像称为容器。你可以修改容器(比如删除一个文件),但这些修改不会影响到镜像。使用docker commit <container> [repo] 将一个container固化为一个新的image,后面的repo为镜像名。
- docker rmi <image ID>: 删除一个或多个image
- 持久化容器:export命令用于持久化容器,docker export <CONTAINER ID> > /tmp/export.tar,docker import导入容器。
- 持久化镜像:Save命令用于持久化镜像:docker save 镜像ID > /tmp/save.tar,docker load 导入镜像。
- export-import与save-load的区别
导出后再导入(export-import)的镜像会丢失所有的历史,而保存后再加载(save-load)的镜像没有丢失历史和层(layer)。这意味着使用导出后再导入的方式,你将无法回滚到之前的层(layer),同时,使用保存后再加载的方式持久化整个镜像,就可以做到层回滚。(可以执行docker tag [LAYER ID] [IMAGE NAME]来回滚之前的层)。
容器日志与进程
- docker logs [-f][-t] [--tail] 容器名
- -f --follows=true|false 默认为false
- -t --timestamps=true|false 默认为false 返回结果加时间
- --tail=‘all‘ 选择返回结尾处多少数量的日志,不指定返回所有
- docker top 容器名 查看运行中容器的进程
- 在运行中的容器中启动新的进程 docker exec [-d][-i][-t] 容器名 [command][arg]
在docker中部署node
- 启动时设置-p:docker run -p=0.0.0.0:8888:80 --name=test -it 镜像名
- 启动后会将容器的80端口映射到宿主机的8888端口
- host 必须设置为 0.0.0.0,表示监听所有的 IP 地址。如果 host 使用 127.0.0.1,在容器外将无法访问服务。