1.docker的技术原理
1.1docker 新一代的PAAS平台
新一代的云应用平台技术则实现全方位的应用生命周期管理,关注开放性、应用的可移植性和云间相互操作性, 其代表者包括Cloud Foundry, OpenShift, Docker, Heroku, MoPaaS等PaaS技术或服务,除了在第一代PaaS 技术对用户在实现应用交付的加速所提供的功能外,具备以下大多数特征: 多语言和框架:支持多语言和框架以及语言框架的扩展机制 多服务:开放的核心服务以及服务的扩展机制 多云和多IaaS技术:支持多种IaaS技术和多云的部署,包括公有云和私有云
Docker也被称之为第三代Paas平台 Docker 究竟是什么?
dotCloud 不仅支持诸如 PHP、MySql 等传统技术框架,还包括 Node.js、MongoDB 等新兴技术。基于 dotCloud 提供 的开发工具和技术框架,你可以直接使用 dotCloud 的 SDK 编写代码和构建业务服务,并在联网的时候把这些代码 推送到云端,实现自动部署和测试。
1.2.Docker的技术原理介绍
Docker就是虚拟化的一种轻量级替代技术。Docker的容器技术不依赖任何语言、框架或系统,可以将App变成一种 标准化的、可移植的、自管理的组件,并脱离服务器硬件在任何主流系统中开发、调试和运行
简单的说就是,在 Linux 系统上迅速创建一个容器(类似虚拟机)并在容器上部署和运行应用程序,并通过配置文件 可以轻松实现应用程序的自动化安装、部署和升级,非常方便。因为使用了容器,所以可以很方便的把生产环境和开 发环境分开,互不影响,这是 docker 最普遍的一个玩法。
1.3.Docker相关的核心技术
1.4.Docker相关的核心技术之cgroups
Linux系统中经常有个需求就是希望能限制某个或者某些进程的分配资源。于是就出现了cgroups的概念, cgroup就是controller group ,在这个group中,有分配好的特定比例的cpu时间,IO时间,可用内存大小等。 cgroups是将任意进程进行分组化管理的Linux内核功能。最初由google的工程师提出,后来被整合进Linux内 核中。
cgroups中的 重要概念是“子系统”,也就是资源控制器,每种子系统就是一个资源的分配器,比如cpu子系 统是控制cpu时间分配的。首先挂载子系统,然后才有control group的。比如先挂载memory子系统,然后在 memory子系统中创建一个cgroup节点,在这个节点中,将需要控制的进程id写入,并且将控制的属性写入, 这就完成了内存的资源限制。
cgroups 被Linux内核支持,有得天独厚的性能优势,发展势头迅猛。在很多领域可以取代虚拟化技术分割资源。 cgroup默认有诸多资源组,可以限制几乎所有服务器上的资源:cpu mem iops,iobandwide,net,device acess等
1.5.Docker相关的核心技术之LXC
LXC是Linux containers的简称,是一种基于容器的操作系统层级的虚拟化技术。借助于namespace的隔离机制 和cgroup限额功能,LXC提供了一套统一的API和工具来建立和管理container。LXC跟其他操作系统层次的虚 拟化技术相比,最大的优势在于LXC被整合进内核,不用单独为内核打补丁
LXC 旨在提供一个共享kernel的 OS 级虚拟化方法,在执行时不用重复加载Kernel, 且container的kernel与host 共享,因此可以大大加快container的 启动过程,并显著减少内存消耗,容器在提供隔离的同时,还通过共享这 些资源节省开销,这意味着容器比真正的虚拟化的开销要小得多。 在实际测试中,基于LXC的虚拟化方法的IO和 CPU性能几乎接近 baremetal 的性能。
虽然容器所使用的这种类型的隔离总的来说非常强大,然而是不是像运行在hypervisor上的虚拟机那么强壮仍具有 争议性。如果内核停止,那么所有的容器就会停止运行。
• 性能方面:LXC>>KVM>>XEN • 内存利用率:LXC>>KVM>>XEN • 隔离程度: XEN>>KVM>>LXC
1.6. Docker相关的核心技术之AUFS
什么是AUFS? AuFS是一个能透明覆盖一或多个现有文件系统的层状文件系统。 支持将不同目录挂载到同一 个虚拟文件系统下,可以把不同的目录联合在一起,组成一个单一的目录。这种是一种虚拟的文件系统,文 件系统不用格式化,直接挂载即可。
Docker一直在用AuFS作为容器的文件系统。当一个进程需要修改一个文件时,AuFS创建该文件的一个副本。 AuFS可以把多层合并成文件系统的单层表示。这个过程称为写入复制( copy on write )。
AuFS允许Docker把某些镜像作为容器的基础。例如,你可能有一个可以作为很多不同容器的基础的CentOS 系统镜像。多亏AuFS,只要一个CentOS镜像的副本就够了,这样既节省了存储和内存,也保证更快速的容器部署。
使用AuFS的另一个好处是Docker的版本容器镜像能力。每个新版本都是一个与之前版本的简单差异改动, 有效地保持镜像文件最小化。但,这也意味着你总是要有一个记录该容器从一个版本到另一个版本改动的审计跟踪。
1.7.Docker原理之App打包
LXC的基础上, Docker额外提供的Feature包括:标准统一的 打包部署运行方案
为了最大化重用Image,加快运行速度,减少内存和磁盘 footprint, Docker container运行时所构造的运行环境,实际 上是由具有依赖关系的多个Layer组成的。例如一个apache 的运行环境可能是在基础的rootfs image的基础上,叠加了 包含例如Emacs等各种工具的image,再叠加包含apache及 其相关依赖library的image,这些image由AUFS文件系统加载 合并到统一路径中,以只读的方式存在,最后再叠加加载 一层可写的空白的Layer用作记录对当前运行环境所作的修 改。
有了层级化的Image做基础,理想中,不同的APP就可以既 可能的共用底层文件系统,相关依赖工具等,同一个APP的 不同实例也可以实现共用绝大多数数据,进而以copy on write的形式维护自己的那一份修改过的数据等
1.8. Docker全生命周期开发模式
2.Docker的基本概念
2.1.Docker Image
Docker Image是一个极度精简版的Linux程序运行环境,比如vi这种基本 的工具没有,官网的Java镜像包括的东西更少,除非是镜像叠加方式的, 如Centos+Java7 • Docker Image是需要定制化Build的一个“安装包”,包括基础镜像+应 用的二进制部署包
Docker Image内不建议有运行期需要修改的配置文件
Dockerfile用来创建一个自定义的image,包含了用户指定的软件依赖等。 当前目录下包含Dockerfile,使用命令build来创建新的image
Docker Image的最佳实践之一是尽量重用和使用网上公开的基础镜像
2.2.Docker Container
Docker Container是Image的实例,共享内核
Docker Container里可以运行不同Os的Image,比如Ubuntu的或者 Centos
Docker Container不建议内部开启一个SSHD服务,1.3版本后新增了 docker exec命令进入容器排查问题。
Docker Container没有IP地址,通常不会有服务端口暴露,是一个封闭的 “盒子/沙箱”
2.3.Docker Container的生命周期
2.4.Docker Daemon
Docker Daemon是创建和运行Container的Linux守护进程,也是Docker 最主要的核心组件
Docker Daemon 可以理解为Docker Container的Container
Docker Daemon可以绑定本地端口并提供Rest API服务,用来远程访问 和控制
2.5.Docker Registry/Hub
- Docker之所以这么吸引人,除了它的新颖的技术外,围绕官方Registry(Docker Hub)的生态圈也是相当吸引人眼球的地方。在Docker Hub上你可以很轻松下载 到大量已经容器化好的应用镜像,即拉即用。这些镜像中,有些是Docker官方维 护的,更多的是众多开发者自发上传分享的。而且 你还可以在Docker Hub中绑定 你的代码托管系统(目前支持Github和Bitbucket)配置自动生成镜像功能,这样 Docker Hub会在你代码更新时自动生成对应的Docker镜像。
问题点: Docker Hub是dotCloud公司私有的 国内曾有公司试图提供镜像服务,但被禁止 目前国内只有一个DaoCloud提供代理缓存服务
- Docker Hub - our SaaS service for sharing and managing your application stacks.
2.6.Docker 核心组件的关系
3. docker的基本操作命令
3.1.拉取镜像
docker pull NAME[:TAG]
如果不显示的指定TAG,则默认会选择latest标签,即下载仓库中最新版本的镜像
[图片上传失败...(image-123eaa-1590976102508)]
repository: 来自于哪个仓库,比如ubuntu仓库
TAG: 镜像的标签,比如16.4
IMAGE ID : 镜像的ID 号(唯一)
CREATE: 创建时间
SIZE: 镜像大小
使用docker inspect 命令可以获取镜像的详细信息.
docker inspect 61325bfc4914
[图片上传失败...(image-31c1de-1590976102508)]
docker inspect 返回的是一个json格式的消息,如果只需要其中的一项内容时,可以使用-f参数指定.例如获取镜像的Created信息.
docker inspect -f {{".Created"}} 613
[图片上传失败...(image-e8e919-1590976102508)]
3.2 查找镜像
docker search 命令可以搜索到远程仓库中共享的镜像,默认搜索docker hub 官网仓库中的镜像
docker serach TERM
-- automated= false 仅显示自动创建的镜像
-- no -trunc=false 输出信息不截断显示
-- s ,--stars =0 指定仅显示评价为指定星级以上的镜像
3.3 docker 容器镜像删除
先停止容器,然后再删除
docker stop $(docker ps -a -q)
如果想要删除所有container的话再加一个指令:
docker rm $(docker ps -a -q)
3.4 查看当前有些什么images
docker images
3.5 删除images
- 删除images, 通过image的tags 来指定
docker rmi
例如 dl.dockerpool.com:5000/ubuntu:latest 镜像,可以使用如下命令:
sudo docker rmi dl.dockerpool.com:5000/ubuntu
当同一个镜像有多个标签的时候,docker rmi 只是删除了该镜像多个标签中的指定标签而已,并不影响镜像文件.但是当镜像只剩下一个标签的时候就要小心了,此时再使用docker rmi 命令会彻底删除该镜像.
- 删除images,通过image的id来指定删除谁
docker rmi
- 想要删除untagged images,也就是那些id为
的image的话可以用
docker rmi $(docker images | grep "^" | awk "{print $3}")
- 要删除全部image的话
docker rmi $(docker images -q)
- 强制删除镜像.强制删除一个存在容器依赖的镜像,会造成遗留问题,使用docker images 查看本地的镜像列表时,原来被强制删除的镜像换了新的的ID 继续存在系统中.正确的做法是先删除依赖该镜像的所有容器,然后在删除该镜像.
docker rmi -f ubuntu
3.6 终止容器运行
docker stop [NAME]/[CONTAINER ID]:将容器退出
docker kill [NAME]/[CONTAINER ID]:强制停止一个容器。
3.7 docker 批量删除无用的容器或镜像
# 删除异常停止的docker容器
docker rm `docker ps -a | grep Exited | awk '{print $1}'`
# 删除名称或标签为none的镜像
docker rmi -f `docker images | grep '' | awk '{print $3}'`
3.8 创建镜像
3.8.1 基于已有镜像的容器创建
该方法主要是使用docker commit 命令,其命令格式是 docker commit [options] container [repository:[tag]] ,主要包括:
-a , -- author ="" 作者信息
-m, --message =“” 提交信息
-m, --message =“” 提交时暂停容器运行
下面将演示如何使用该命令创建一个新镜像。 首先启动一个镜像,并在其中修改操作,例如创建一个test 文件,之后退出。
$sudo docker run -ti unbutu:14.04 /bin/bash
root@a132s232md0:/# touch test
root@a132s232md0:/# exit
该容器已经和镜像不同了,使用commit 操作创建镜像
sudo docker commit -m "add file" -a "author" a132s232md0 test
查看本地镜像,可以看到新的镜像。
sudo docker images
3.8.2 使用dockerfile 创建镜像
- FROM
格式为 FROM
- MAINTAINER
格式为MAINTAINER
- RUN
格式为 RUN
- CMD
三种使用方式
- CMD <"excute", "param1" ,"param2"> ,使用exec 执行,推荐方式。
- CMD command param1 param2 在bin/sh 中执行,提供给需要交互的应用
- CMD ["param1" ,"param2"] 提供ENTRYPOINT 的默认参数
- EXPOSE
格式为 EXPOSE
例如
EXPOSE 22 80 8080
docker 容器可以暴露的端口号, 可以-p 映射端口。
- ENV
格式为ENV
- ADD
格式为ADD
该命令将复制指定的
- COPY
格式为COPY
复制本地主机的
当使用本地目录为源目录时,推荐使用COPY。
- ENTRYPOINT
有两种格式:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2(shell 中执行)
配置容器启动后执行的命令,并且不可被docker run 提供的参数覆盖。
每个dockerfile 中只有一个ENTRYPOINT,当指定多个ENTRYPOINT 时,只有最后一个生效。
- VOLUME
格式为VOLUME ["/data"]
创建一个可以从本地或其他容器挂载的挂载点,一般用来存放数据库和需要持久化的数据等。
- USER
格式为USER deamon
指定运行容器时的用户或者UID,后续的RUN也会使用指定用户。当服务不需要管理员权限时,可以通过该命令指定运行的用户。并且可以在之前创建需要的用户
例如: RUN groupadd -r postgres && useradd -r -g postgres postgres。 要临时获取管理员权限可以使用gosu,而不推荐sudo。
3.9 上传镜像
先在dockerhub 上注册账号,docker 默认上传到dockerhub 仓库。上传命令:docker push name[:tag]
sudo docker tag test:latest user/test:latest
sudo docker push user/test:latest
会提示输入账号密码
4. 创建和使用私有镜像仓库
4.1 通过官方提供的resigtry 镜像简单搭建一个私有的仓库
sudo docker run -d -p 5000:5000 registry
默认情况下,会将仓库创建在容器的/tmp/registry目录下。可以通过-v 参数来指定本地存储路径。
sudo docker run -d -p 5000:5000 registry -v /opt/data/registry:/tmp/registry registry
本地会启动一个私有仓库,监听端口为5000.
4.2 管理私有仓库
比如本地已有的私有镜像仓库的地址为192.168.1.5:5000,标记本地镜像为192.168.1.5:5000/nginx
sudo docker tag nginx:latest 192.168.1.5:5000/nginx
sudo docker push 192.168.1.5:5000/nginx
查看镜像
curl http://192.168.1.5:5000/v1/search
docker 官方文档
docker 中文社区