Docker的安装和命令使用

虚拟化技术虚拟化技术是对软件基础设施、操作系统、软件等IT资源进行有效的管理,使用户不再受物理资源的限制,提高计算机资源的利用率。虚拟化技术是云计算的基础,例如阿里云的云主机、腾讯云等都应用了虚拟化技术。虚拟化技术整体上包括两个方面:硬件虚拟化和软件虚拟化,具体分为:网络虚拟化、存储虚拟化、桌面虚拟化、服务器虚拟化等,我们平常说的最多的是服务器虚拟化。服务器虚拟化就是在同一个物理服务器上运行多个虚拟机,让服务器的cpu、内存、磁盘、I/O等硬件设施为每个虚拟机服务,在每个虚拟机中运行不同的软件,虚拟机之间是隔离状态。 服务器虚拟化主要有两种技术:1、Hypervisor也叫VMM(virtual machine monitor)即虚拟机监视器Hypervisor是一种将操作系统与硬件抽象分离的方法,实现在宿主机(host machine)上能同时运行多个客户机(guest machine),每个客户机就是一个虚拟机,这些虚拟机高效地分享宿主机的硬件资源。在服务器(宿主机)上安装操作系统,并安装hypervisor虚拟机管理软件,如VMware、VirtualBox等,由hypervisor管理多个虚拟机,每个虚拟机上需要安装客户操作系统、依赖库、应用软件。 容器化技术容器技术中docker引擎取代了hypervisor,docker引擎是运行在住宿操作系统上的一个进程,该进程管理了多个docker容器,每个docker容器集成了应用软件、依赖库,容器之间相互隔离。 技术对比: 资源占用:虚拟机由于是独立的操作系统,占用资源比docker多。启动速度:虚拟机包括操作系统,启动虚拟机相当于启动一个操作系统,容器则不一样,容器中只包括操作系统的内核,启动一个容器实例相当于启动一个进程,容器的启动速度比虚拟机快。体积:容器包括操作系统内核、软件及依赖库,虚拟机不仅包括软件和依赖库还将完整的操作系统打包进去,虚拟机的体积比容器大的多。docker简介Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 1、Docker daemon(Docker守护进程): Docker守护进程是部署在操作系统上,负责支撑Docker Container的运行以及本地Image的管理。2、Docker client: 用户不直接操作Docker daemon,用户通过Docker client访问Docker,Docker client提供pull、run等操作命令。3、Docker Image: Docker 镜像就是一个只读的模板。 例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Tomcat或用户需要的其它应用程序。 镜像可以用来创建 Docker 容器。 Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。4、Docker Container: Docker 利用容器来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。打个比方,镜像相当于类,容器相当于对象。5、Docker Registry: Docker 仓库分为公开仓库(Public)和私有仓库(Private)两种形式 最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。 用户也可以在本地网络内创建一个私有仓库。 当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。docker安装Docker可以运行MAC、Windows、Centos、DEBIAN、UBUNTU等操作系统上,提供社区版和企业版,基于Centos安装Docker。Centos6对docker支持的不好,使用docker建议升级到centos7。 1、在Centos7上安装Docker,直接通过yum安装即可: yum install -y docker完成后查看docker版本:docker info 或docker -v 启动docker:systemctl start docker 常用命令使用1.镜像仓库1)docker pull : 从镜像仓库中拉取或者更新指定镜像 ...

October 17, 2019 · 2 min · jiezi

Docker入门学习

docker简介1.什么是虚拟化在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件对资源充分利用虚拟化技术种类很多,例如:软件虚拟化、硬件虚化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等。 2.什么是Docker Docker是一个开源项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go语言实现。项目后来加入了Linux基金会,遵从了Apache2.0协议,项目代码在GitHub上进行维护。 Docker自开源后受到广泛的关注和讨论,以至于dotCloud公司后来都改名为Docker Inc。Redhat已经在其RHEL6.5中集中支持Docker;Google也在其PaaS产品中广泛应用。Docker项目的目标是实现轻量级的操作系统虚拟化解决方案。Docker的基础是Linux容器(LXC)等技术。在LXC的基础上Docker进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作Docker的容器就像操作一个快速轻量级的虚拟机一样简单。 3.为什么选择Docker?1)上手快用户只需要几分钟,就可以把自己的程序“Docker化”。Docker依赖于“写时复制”(copy:on-write)54681模型,使修改应用程序也非常迅速,可以说达到“随心所致,代码即改”的境界。随后,就可以创建容器来运行应用程序了。大多数Docker容器只需要不到1秒中即可启动。由于去除了管理程序的开销,Docker容器拥有很高的性能,同时同一台宿主机中也可以运行更多的容器,使用户尽可能的充分利用系统资源。2)职责的逻辑分类使用Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。Docker设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署的生产环境一致性。从而降低那种“开发时一切正常,肯定是运维的问题(测试环境都是正常的,上线后出了问题就归结为肯定是运维的问题)”3)快速高效的开发生命周期Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。(通俗一点说,Docker就像一个盒子,里面可以装很多物件,如果需要这些物件的可以直接将该大盒子拿走,而不需要从该盒子中一件件的取。)4)鼓励使用面向服务的架构Docker还鼓励面向服务的体系结构和微服务架构。Docker推荐单个容器只运行一个应用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或者服务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。(当然,可以在一个容器中运行多个应用程序) 4.容器与虚拟机比较下面的图片比较了Docker和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。与传统的虚拟机相比,Docker优势体现为启动速度快、占用体积小。 5.Docker服务器与客户端Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具Docker以及一整套RESTfulAPl。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。 6.Docker镜像与容器镜像是构建Docker的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的构建”部分。镜像是基于联合文件系统的一种层式结构,由一系列指令一步一步构建出来。例如:执行一个命令;打开一个窗口。也可以将镜像当作容器的“源代码”。镜像体积很小,非常“便携”,易于分享、存储和更新。 Docker可以帮助你构建和部署容器,你只需要把自己的应用程序或者服务打包放进容器即可。容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。容器基于镜像启动,一旦容器启动完成后,我们就可以登录到容器中安装自己需要的软件或者服务。所以Docker容器就是:一个镜像格式;一些列标准操作;一个执行环境。 Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Docker将这个模型运用到自己的设计中,唯一不同的是:集装箱运输货物,而Docker运输软件。和集装箱一样,Docker在执行上述操作时,并不关心容器中到底装了什么,它不管是web服务器,还是数据库,或者是应用程序服务器什么的。所有的容器都按照相同的方式将内容“装载”进去。Docker也不关心你要把容器运到何方:我们可以在自己的笔记本中构建容器,上传到Registry,然后下载到一个物理的或者虚拟的服务器来测试,在把容器部署到具体的主机中。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分钱,并且尽量通用。 7.Registry(注册中心)Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的Registry叫做Docker Hub。用户可以在Docker Hub注册账号,分享并保存自己的镜像(说明:在Docker Hub下载镜像巨慢,可以自己构建私有的Registry)。https://hub.docker.com/ Docker安装与启动1.安装Docker Docker官方建议在Ubuntu中安装,因为Docker是基于Ubuntu发布的,而且一般Docker出现的问题Ubuntu是最先更新或者打丁的。在很多版本的CentOS中是不支持更新最新的一些补丁包的。由于我们学习的环境都使用的是CentoS,因此这里我们馨诺我e头联输2-e医看裸颖这里建议安装在CentOS7.x以上的版本,在CentOS6.x的版本中,安装前需要安装其他很多的环境而且Docker很多补丁不支持更新。 yum包更新到最新 sudo yum update安装需要的软件包,yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 sudo yum instal1-y yum-utils device-mapper-persistent-data 1vm2设置yum源为阿里云 sudo yum-config-manager,-add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装docker-ce docker sudo yum install docker-ce安装后查看docker版本 docker-v2.设置ustc的镜像ustc是老牌的linux镜像服务提供者了,还在遥远的ubuntu5.04版本的时候就在用。ustc的docker镜像加速器速度很快。ustc docker mirror的优势之一就是不需要注册,是真正的公共服务。https:/lug.ustc.edu.cn/wiki/m...: vi/etc/docker/daemon.json在该文件中输入如下内容: “registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]3.Docker的启动与停止systemctl命令是系统服务管理器指令启动docker: systemct1 start docker停止docker: systemct1 stop docker重启docker: systemct1 restart docker查看docker状态: systemct1 status docker开机启动:| systemct1 enable docker查看docker概要信息 docker info查看docker帮助文档 docker--help常用命令1.镜像相关命令查看镜像 docker images REPOSITORY:镜像名称TAG.镜像标签IIMAGEID:镜像IDCREATED:镜像的创建日期(不是获取该镜像的日期)SIZE:镜像大小这些镜像都是存储在Docker宿主机的/var/lib/docker目录下 搜索镜像如果你需要从网络中查找需要的镜像,可以通过以下命令搜索 docker search 镜像名称NAME:仓库名称DESCRIPTION:镜像描述STARS:用户评价,反应一个镜像的受欢迎程度OFFICIAL:是否官方AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的拉取镜像拉取镜像就是从中央仓库中下”本地 ...

October 13, 2019 · 2 min · jiezi

构建安全可靠最小化的-Docker-镜像

容器化部署越来越多的用于企业的生产环境中,如何构建可靠、安全、最小化的 Docker 镜像也就越来越重要。本文将针对该问题,通过原理加实践的方式,从头到脚帮你撸一遍。文章比较长,主要通过五个部分对容器镜像进行讲解。分别是: 镜像的构建讲解了镜像的手动构建与自动构建过程。镜像的存储与UnionFS联合文件系统讲解了镜像的分层结构以及UnionFS联合文件系统,以及镜像层在UnionFS上的实现。最小化镜像构建讲解了为什么需要最小化镜像,同时如何进行最小化构建。容器镜像的加固容器镜像加固的具体方式。容器镜像的审查高质量的项目中容器镜像也需要向代码一样进行审查。读者可以根据各自情况选择性阅读。 原文发自我的个人网站: GitDiG.com,参考链接构建安全可靠、最小化的 Docker 镜像.1. 构建镜像1.1 手动构建手动构建 Docker 镜像的流程图,如下: 现在依次按照流程采用命令行的方式手动构建一个简单的Docker 镜像。 1.1.1 创建容器并增加文件取busybox作为本次试验的基础镜像,因为它足够小,大小才 1.21MB。 $: docker run -it busybox:latest sh/ # touch /newfile/ # exit通过以上的操作,我们完成了流程图的前三步。创建了一个新容器,并在该容器上创建了一个新问题。只是,我们退出容器后,容器也不见了。当然容器不见了,并不表示容器不存在了,Docker 已经自动保存了该容器。如果在创建时,未显示设置容器名称,可以通过以下方式查找该消失的容器。 # 列出最近创建的容器$: docker container ls -n 1CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESc028c091f964 busybox:latest "sh" 13 minutes ago Exited (0) 27 seconds ago upbeat_cohen# 查询容器的详情$: docker container inspect c028c091f964...1.1.2 提交变更生成镜像手动构建镜像,很简单。先找到发生变更的容器对象,对其变更进行提交。提交完成后,镜像也就生成了。不过此时的镜像只有一个自动生成的序列号唯一标识它。为了方便镜像的检索,需要对镜像进行命名以及标签化处理。 命令行操作如下: # 提交变更, 构建镜像完成$: docker commit -a JayL -m "add newfile" c028c091f964sha256:01603f50694eb62e965e85cae2e2327240e4a68861bd0e98a4fb4ee27b403e6d# 对镜像进行命名, 原镜像ID取前几位就可以了$: docker image tag 01603f50694eb62e9 busybox:manual# 验证新镜像$: docker run busybox:manual ls -al newfile-rw-r--r-- 1 root root 0 Jun 15 05:25 newfile通过以上两步过程就完成了Docker 镜像手动创建。非常简单是不是。但是也非常麻烦,必须先创建新容器在提交变更,生成镜像。整个过程完全可以通过脚本化处理,这也是下节要说的,自动化构建Docker 镜像。 ...

June 30, 2019 · 5 min · jiezi

如何对Docker-Image进行审查

本文节选自我的博客文章:构建可靠、安全、最小化的 Docker 镜像: 原理与实践.正如Code Review一样,代码审查可以大大提升企业项目的质量。容器镜像同样作为开发人员或是运维人员的产出物,对其进行审查也是必要的。 虽然我们可以通过docker命令结合文件系统浏览的方式进行容器镜像的审查,但其过程需要人工参与,很难做到自动化,更别提将镜像审查集成到CI过程中了。但一个好的工具可以帮我们做到这点。 向大家推荐一个非常棒的开源项目dive,具体安装请参考其项目页。它不但可以方便我们查询具体镜像层的详细信息,还可以作为CI持续集成过程中的镜像审查之用。使用它可以大大提升我们审查镜像的速度,并且可以将这个过程做成自动化。 该项目的具体动态操作图示如下: 如果作为镜像审查之后,可以进行如下命令操作: $: CI=true dive <image-id>Fetching image... (this can take a while with large images)Parsing image...Analyzing image... efficiency: 95.0863 % wastedBytes: 671109 bytes (671 kB) userWastedPercent: 8.2274 %Run CI Validations... Using default CI config PASS: highestUserWastedPercent SKIP: highestWastedBytes: rule disabled PASS: lowestEfficiency从输出信息可以得到很多有用的信息,集成到CI过程也就非常容易了。 dive本身就提供了.dive-ci作为项目的CI配置: rules: # If the efficiency is measured below X%, mark as failed. # Expressed as a percentage between 0-1. lowestEfficiency: 0.95 # If the amount of wasted space is at least X or larger than X, mark as failed. # Expressed in B, KB, MB, and GB. highestWastedBytes: 20MB # If the amount of wasted space makes up for X% or more of the image, mark as failed. # Note: the base image layer is NOT included in the total image size. # Expressed as a percentage between 0-1; fails if the threshold is met or crossed. highestUserWastedPercent: 0.20集成到CI中,增加以下命令即可: ...

June 20, 2019 · 1 min · jiezi

Docker学习之Image镜像

我们知道Image(镜像)是Docker的三大组件之一,Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像。接下来先看看,怎样去获取镜像。获取镜像DockerHub 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像。从 Docker 镜像仓库获取镜像的命令是 docker pull 。其命令格式为: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。 Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub。仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名> 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。先看一个例子,这里拉取ubuntu的一个镜像: root@huangche-PC:/# docker pull ubuntu:18.0418.04: Pulling from library/ubuntu6abc03819f3e: Pull complete 05731e63f211: Pull complete 0bd67c50d6be: Pull complete Digest: sha256:f08638ec7ddc90065187e7eabdfac3c96e5ff0f6b2f1762cf31a4f49b53000a5Status: Downloaded newer image for ubuntu:18.04 上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:18.04 ,因此将会获取官方镜像 library/ubuntu仓库中标签为 18.04 的镜像。其中library表示组。 从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。如:6abc03819f3e: Pull complete ,并且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。 ...

June 18, 2019 · 1 min · jiezi

Docker-之-ubuntu-安装

Docker 作为一种新兴的虚拟化方式,Docker 跟传统的虚拟机方式相比具有众多的优势。Docker 可以更高效的利用系统资源、更快速的启动时间、一致的运行环境、持续交付和部署、更轻松的迁移、更轻松的维护和扩展。 博主第一次使用Docker就深深喜欢上了这种方式,一次配置,到处运行,不用再反反复复的配置环境可以说是非常的方便了。本篇博客就来说一说Docker的安装及基本使用方法,后续还会不定时的更新Docker系列博客。 对比传统虚拟机Docker是什么?Docker属于容器的一种技术封装,提供更为简单易用的使用接口,让开发运维人员可以更方便快捷的使用容器。 特性容器虚拟机启动秒级分钟级硬盘使用一般为 MB一般为 GB性能接近原生弱于系统支持量单机支持上千个容器一般几十个从上面对比来看,容器的各方面性能及特性是优于虚拟机的。 Docker 的安装Docker是一个开放源码的产品,分为 社区版(Community Edition,缩写为 CE)和 企业版(Enterprise Edition,缩写为 EE)。社区版是免费的,而企业版包含一些收费服务,一般来说个人开发者用社区版就足够了,本篇博文的教程也只是针对社区版。 安装环境及版本: 系统:ubuntu 18.04 LTSDocker 版本:18.9.05英文好的小伙伴也可以直接阅读官方文档,本文只详细介绍 Ubuntu 系统下的 Docker 安装,其他系统的安装请自行参考官方文档。 MacWindowsCentOSDebianFedoraUbuntu其他Linux版本卸载老版本一般来说Ubuntu系统中默认是不会安装Docker的,但是如果安装了老版本的话可以使用下面的命令进行卸载。 $ sudo apt-get remove docker docker-engine docker.io containerd runc安装 Docker CE安装Docker CE有多种不同的方式: 设置Docker的存储库,然后安装。这种方式便于安装及更新,也是最推荐的方式。下载DEB软件包,手动安装并完全手动管理升级。在测试和开发环境中,部分用户选择使用自动便捷脚本来安装Docker。本篇博客将介绍第一种安装方式。 设置 Docker 存储库 更新apt包索引:$ sudo apt-get update允许apt通过HTTPS使用存储库来安装软件:$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common添加Docker官方 GPG 密钥:$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -添加完成之后,使用下面命令进行验证秘钥,通过搜索指纹的最后8个字符,验证现在是否具有指纹9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88的密钥 ...

April 25, 2019 · 2 min · jiezi

Docker 使用简介

Docker 是使用 GoLang 开发的开源容器引擎,可以方便的打包开发好的应用,然后分发到任意 linux 主机上。 与传统的虚拟机相比拥有以下优势: 高效的系统资源利用率由于不需要进行硬件虚拟和运行完整的操作系统等额外开销,无论是应用执行速度、内存损耗或者文件存储速度, Docker 都更加高效 更快的启动速度Docker 容器应用直接运行与宿主内核,无需启动完整的操作系统,可以做到秒级启动 一致的运行环境Docker 镜像提供了除内核外的完整运行环境,确保了应用运行环境的一致性 持续交付和部署可以通过 Docker 镜像来实现服务的持续交付、部署。使用 Dockerfile 来构建镜像,使用持续集成系统进行集成测试;使用镜像结合持续部署系统进行自动部署 迁移轻松只需要迁移镜像及镜像运行的数据就可在其他主机或平台运行 易于维护和扩展由于使用镜像进行部署,使维护更为容易。由于支持在镜像的基础上进行定制,使得扩展变得更简单。而官方也维护了一大批高质量的镜像,大大降低了镜像的制作成本 基本概念仓库Docker 提供了仓库(Repository)用于存放制作好的镜像,方便使用者获取,在本地可通知配置多个 Repository 。 拉取可以使用命令来拉取镜像: docker pull [repo url>/]image name> 默认的 repo url 是 hub.docker.com ,拉取默认仓库中的镜像时是不需要 url 的。如拉取 debian : docker pull debian 。 推送我们也可将自己制作好的镜像推送到仓库,以便分发,使用命令: docker push [<repo url>/]<image name>[:<image tag>> 搜索使用 docker search 命令则可搜索默认 repo url 内的镜像。 镜像加速 由于默认 repo url 在国外,为了加快拉取速度,需要指定其为国内的,向 /etc/docker/daemon.json 中添加: { "registry-mirrors": ["https://registry.docker-cn.com"]}便可使用 Docker 在中国的镜像加速站。 ...

April 21, 2019 · 2 min · jiezi

认识docker

一、Docker工作原理二、Docker容器和虚拟机对比三、镜像容器管理1、Docker关键组件2、Docker架构3、Docker内部组件镜像(Image)——一个特殊的文件系统Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)容器(Container)——镜像运行时的实体容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等仓库(Repository)——集中存放镜像文件的地方镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务Docker采用了C/S架构。客户端和服务端可以运行在一个机器上,也可以通过socket或者RESTful API 来进行通信。Docker Daemon: 一般在宿主机后台运行,等待接收客户端的消息Docker Client:则为客户提供一系列可执行的命令, 用户使用这些命令跟docker daemon交互Docker daemon:Docker daemmon是Docker架构中的主要用户接口。首先,它提供了API Server用于接收来自Docker client的请求,其后根据不同的请求分发给Docker daemon的不同模块执行相应的工作Image managerment:需要创建DOcker容器时,可通过镜像管理(image management)部分的distribution和registry模块从Docker registry中下载镜像,并通过镜像管理的image、reference和layer存储镜像的元数据,通过镜像存储驱动graphdriver将镜像文件存储于具体的文件系统中Network:当需要为Docker容器创建网络环境时,通过网络模块network调用libnetwork创建并配置Docker容器的网络环境Volume:当需要为容器创建数据卷volume时,则通过volume模块调用某个具体的volumedrive,来创建一个数据卷并负责后续的挂载操作Execdriver:当需要限制Docker容器运行资源或执行用户指令操作时,则通过execdrive来完成Libcontainer:是对cgroups和namespace的二次封装,execdrive是通过libcontainer来实现对容器的具体管理,包括利用UTS、IPC、PID、Network、Mount、User等namespace实现容器之间的资源隔离和利用cgroups实现对容器的资源限制.当运行容器的命令执行完毕后,一个实际的容器就处于运行状态,该容器具有独立的文件系统、相对安全且相互隔离的运行环境.1、用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者2、Engine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式的存在。3、Job的运行过程中,当需要容器镜像时,则从Docker Registry中下载镜像,并通过镜像管理驱动graphdriver将下载镜像以Graph的形式存储;当需要为Docker创建网络环境时,通过网络管理驱动networkdriver创建并配置Docker容器网络环境;当需要限制Docker容器运行资源或执行用户指令等操作时,则通过execdriver来完成。libcontainer是一项独立的容器管理包,networkdriver以及execdriver都是通过libcontainer来实现具体对容器进行的操作。1、容器和虚拟机对比2、Docker的优势3、Docker的劣势4、Docker的应用场景Docker 的的优势:持续部署和测试发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。Docker可以保证测试环境、开发环境、生产环境的一致性。可移植性容器可以移动到任意一台Docker主机上,而不需要过多关注底层系统。弹性伸缩更快速配合K8S可以很容易的无状态应用的弹性伸缩,只需要改一个yml的数字即可。利用docker能在几秒钟之内启动大量的容器,这是虚拟机无法办到的,快速启动,秒级和分钟级的对比。资源利用率高由于docker不需要Hypervisor实现硬件资源虚拟化,docker容器和内核交互,几乎没有性能损耗,性能优于通过Hypervisor层与内核层的虚拟化。一台机器启动上前台容器也没问题。对硬件无要求不需要CPU支持虚拟化Docker 的的劣势资源隔离docker是利用cgroup实现资源隔离的,只能限制资源消耗的最大值,而不能隔绝其他应用程序占用自己的资源; docker属于进程之间的隔离,虚拟机可实现系统级别隔离;安全性问题一个用户拥有执行docker的权限,可以删除任何用户创建的容器。兼容性问题docker目前还在版本快速更新中,细节功能调整较大,一些核心的模块依赖于高版本的内核,存在兼容性的问题。1、Docker安装2、认识镜像和容器3、镜像容器管理什么是镜像?镜像是一个多层的联合只读的文件系统。什么是容器?容器是在镜像基础上加上读写层。容器即进程。构建镜像的过程?镜像->镜像+可写层+执行命令->commit为新的镜像(新的一层)->镜像+可写层+执行命令->commit为新的镜像(新的一层)->…典型文件系统启动 :一个典型的 Linux 文件系统由 bootfs 和 rootfs 两部分组成,bootfs(boot file system) 主要包含 bootloader 和 kernel,bootloader 主要用于引导加载 kernel,当 kernel 被加载到内存中后 bootfs 会被 umount 掉rootfs (root file system)包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc 等标准目录和文件加载过程:bootfs 时会先将 rootfs 设为 read-only,然后在系统自检之后将 rootfs 从 read-only 改为 read-write,Docker文件系统启动:Docker 在 bootfs 自检完毕之后并不会把 rootfs 的 read-only 改为 read-write,而是利用 union mount(UnionFS 的一种挂载机制)将 image 中的其他的 layer 加载到之前的 read-only 的 rootfs 层之上,每一层 layer 都是 rootfs 的结构,并且是read-only 的。所以,我们是无法修改一个已有镜像里面的 layer 的!只有当我们创建一个容器,也就是将 Docker 镜像进行实例化,系统会分配一层空的 read-write 的 rootfs ,用于保存我们做的修改DockerfileFROM centosENV TZ “Asia/Shanghai"ADD echo.sh /opt/echo.shRUN chmod +x /opt/echo.shCMD ["/opt/echo.sh”]docker build -t test -f Dockerfile . 镜像工作原理:如果运行中的容器修改一个已经存在的文件,那么会将该文件从下面的只读层复制到读写层,只读层的这个文件就会覆盖(隐藏),但还存在。如果删除一个文件,在最上层会被标记隐藏,实际只读层的文件还存在。这就实现了文件系统隔离,当删除容器后,读写层的数据将会删除,只读镜像不变。查看具体的挂载逻辑[root@centos7 l]# mount|grep overlayoverlay on /var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/merged type overlay (rw,relatime,seclabel,lowerdir=/var/lib/docker/overlay2/l/A6JYT4QIFZMKOPIGY675JWKS7F:/var/lib/docker/overlay2/l/4L4SUINS3DX6XPD5BL2J54JQDT,upperdir=/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/diff,workdir=/var/lib/docker/overlay2/56375ce93fd54484061ef08a48a7093905be680dd14754642970616127b30fca/work)Overlay和overlay2的区别overlay: 只挂载一层,其他层通过最高层通过硬连接形式共享(增加了磁盘inode的负担)overlay2: 逐层挂载(最多128层)基础镜像的层信息docker pull centostree -L 2 /var/lib/docker/overlay2/构建后镜像的层信息cd layer_dockerfile/docker build -t centos:test -f ./Dockerfile .tree -L 2 /var/lib/docker/overlay2/每一层都包含了”该层独有的文件”以及”和其低层共享的数据的连接”,在Docker 1.10之前的版本中,目录的名字和镜像的UUID相同,而Docker 1.10后则采用了新的存储方式,可以看到目录名和下载镜像的UUID并不相同Diff存放挂载点的具体的文件内容Link对应l目录的链接源的名称Lower根没有lower,其它的lower指向的父层的链接L:”l“目录包含一些符号链接作为缩短的层标识符. 这些缩短的标识符用来避免挂载时超出页面大小的限制docker run -idt –name centos_con centos:test /bin/bashtree -L 2 /var/lib/docker/overlay2/多出的两层“……”为读写层,“…..-init”为初始层。初始层:初始层中大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。读写层:所有对容器做出的改变都记录在读写层Diff存放挂载点的具体的文件内容Link对应l目录的链接源的名称Lower根没有lower,其它的lower指向的父层的链接Merged如果是读写层会有一个MergedCommit:容器提交为镜像docker run -idt –name test centosTouch liweidocker commit 6de test2Create:创建容器但是不启动docker create –name nginx-con -p80:80 nginx:latestStart:启动容器docker start nginx-conStop:停止容器docker stop nginx-conKill:杀掉容器,和停止相比不友好docker kill nginx-conPause:暂停容器docker pause nginx-conUnpause:恢复暂停的容器docker unpause nginx-conRun:创建且启动容器docker run -idt –restart=always –name nginx_con -v /tmp/:/mnt -p 88:80 -e arg1=arg1 nginxDocker attach nginx_conCtrl+^p+^qCP:宿主机和容器之间copy文件docker cp docker_install.sh nginx_con:/optdocker exec nginx_con ls /optdocker cp nginx_con:/opt/docker_install.sh ./1.shExec:执行命令,也可附加到容器docker exec nginx_con ls /optAttach:附加到容器docker attach nginx_condocker exec -it nginx_con /bin/bashLogs:查看容器日志docker logs –f nginx_conInspect:查看元数据,可以查看镜像和容器docker inspect nginx_conPort:查看容器端口映射docker port nginx_conTop:查看容器中正在运行的进程docker top nginx_conPs:查看容器docker psdocker ps -adocker ps -aq查看正在运行的容器,加上-a查看所有容器(包含停止和暂停状态的容器)Rm:删除容器docker rm nginx_con 删除容器docker rm -f nginx_con 强行删除容器Export:导出容器docker pull busyboxdocker run -itd busyboxdocker export 983989307eef>busybox.tarImport:导入容器docker import busybox.tar busybox:1.3Save:导出镜像docker save busybox:1.3>busybox1.3.tarLoad:导入镜像docker load -i busybox1.3.tar Tag:镜像打标签docker tag busybox:1.3 192.168.199.160/test/busybox:latestBuild:从dockerfile构建镜像FROM centosENV TZ “Asia/Shanghai"ADD echo.sh /opt/echo.shRUN chmod +x /opt/echo.shCMD ["/opt/echo.sh”]docker build -t centos:test -f Dockerfile . Pull:从 registry拉取镜像docker pull nginx 从dockerhub上拉取docker pull 192.168.199.160/test/nginx:latest 从内网harbor上拉取Push:推送镜像到仓库[第一次需要输入密码,后续不需要了]docker login 192.168.199.160adminHarbor12345docker push 192.168.199.160/test/busybox:latestInfo、version、eventsdocker info 查看docker相关信息信息Docker version 查看docker相关版本信息Docker events 查看docker事件【注】1、创建容器后防火墙不要再动2、cmd会被覆盖的问题,需要注意,可能会导致/bin/bash 把启动命令覆盖了,启动不了的问题例如docker run -idt –restart=always –name nginx_con -v /tmp/:/mnt -p 88:80 -e arg1=arg1 nginx /bin/bash3、cmd的命令都会在挂在后执行。 ...

January 30, 2019 · 2 min · jiezi

容器和容器镜像的区别,您真的了解吗

很多刚刚接触容器技术的朋友,不容易弄清楚容器,容器镜像和Docker这几个词的区别和联系。我们首先来看容器和容器镜像。举个例子,执行命令行docker search nginx,搜索结果的一条条记录就是一个个容器镜像。所谓镜像,就是一个静态概念,一个镜像由若干只读层(read-only layer)构成。上图左边是Docker镜像的内部实现细节,我们能看到多个只读层叠加在一起,层与层之间通过指针关联,这些层能够在运行Docker的宿主机的文件系统上访问到。Linux的统一文件系统(union file system)技术将这些叠加的只读层合并成一个文件系统,该系统为这些只读层提供了一个统一的视角,从而为Docker的用户隐藏了多层的存在。从Docker用户的视角出发,一个Docker镜像只存在一个文件系统,即上图右边所示。这些文件系统的设计是Docker实现细节,一般情况下我们不用去深究。但如果您足够好奇,使用命令sudo tree浏览目录 /var/lib/docker即可:比如我用命令docker images浏览下载到本地的docker镜像:其中一个叫jerry-nginx的镜像,是一个web应用,它的所有内容能在/var/lib/docker目录下的这个目录查到:讲完了容器镜像,我们再来看容器。容器和容器镜像一样,也是若干层的叠加,唯一区别是所有只读层的最上面一层,是一层可读可写层,如上图绿色图例所示。初学者可以记住这个简单的公式:容器 = 容器镜像 + 可读可写层我们如果用命令docker ps –all查看本机所有容器列表,会发现有的容器处于运行状态,有的处于退出状态。因此,一个处于运行状态的容器(running container)包含一个可读写的文件系统加上隔离的进程空间。容器里的进程可以对这个可读写文件系统内的文件进行修改、删除、创建等操作。镜像里每一层其实都能在docker文件夹的containers子目录下找到:上图每一个红色文件夹代表镜像里的一层,蓝色文件包含了该层运行时的日志文件,或者网络相关配置等。做个实验:ubuntu这个容器执行结束后,使用find / -name i042416.txt文件,这说明docker运行时能对宿主机的文件系统进行写操作。下面分析几个常用的易混淆的命令。docker create <image-id>先看它的帮助文档:试着执行以下:产生一个输出id:7ee10851c3f1e53bbd35e5f196f34de560afa1a20d9bf1ced587630dbcda877bcreate创建的容器,状态变为created:docker create命令给通过命令行传入的容器镜像创建了一个新的可读可写层,从而生成了一个新的容器实例:然后再执行docker start,输入docker create创建的容器实例ID,就可以启动这个容器实例了。而docker run其实就是docker create和docker start这两个命令合二为一的版本。希望这篇文章能帮助大家理解容器和容器镜像的区别。要获取更多Jerry的原创文章,请关注公众号"汪子熙":

December 21, 2018 · 1 min · jiezi

Docker技术三大要点:cgroup, namespace和unionFS的理解

www.docker.com的网页有这样一张有意思的动画:从这张gif图片,我们不难看出Docker网站想传达这样一条信息, 使用Docker加速了build,ship和run的过程。Docker最早问世是2013年,以一个开源项目的方式被大家熟知。Docker的奠基者是dotcloud,一家开发PaaS平台的技术公司。不过可惜的是,这家公司把Docker开源之后,于2016年倒闭了,因为其主业务PaaS无法和微软,亚马逊等PaaS业界巨头竞争,不禁让人唏嘘。Docker其实是容器化技术的具体技术实现之一,采用go语言开发。很多朋友刚接触Docker时,认为它就是一种更轻量级的虚拟机,这种认识其实是错误的,Docker和虚拟机有本质的区别。容器本质上讲就是运行在操作系统上的一个进程,只不过加入了对资源的隔离和限制。而Docker是基于容器的这个设计思想,基于Linux Container技术实现的核心管理引擎。为什么资源的隔离和限制在云时代更加重要?在默认情况下,一个操作系统里所有运行的进程共享CPU和内存资源,如果程序设计不当,最极端的情况,某进程出现死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉大部分系统资源,这在企业级产品场景下是不可接受的,所以进程的资源隔离技术是非常必要的。我当初刚接触Docker时,以为这是一项新的技术发明,后来才知道,Linux操作系统本身从操作系统层面就支持虚拟化技术,叫做Linux container,也就是大家到处能看到的LXC的全称。LXC的三大特色:cgroup,namespace和unionFS。cgroup:CGroups 全称control group,用来限定一个进程的资源使用,由Linux 内核支持,可以限制和隔离Linux进程组 (process groups) 所使用的物理资源 ,比如cpu,内存,磁盘和网络IO,是Linux container技术的物理基础。namespace:另一个维度的资源隔离技术,大家可以把这个概念和我们熟悉的C++和Java里的namespace相对照。如果CGroup设计出来的目的是为了隔离上面描述的物理资源,那么namespace则用来隔离PID(进程ID),IPC,Network等系统资源。我们现在可以将它们分配给特定的Namespace,每个Namespace里面的资源对其他Namespace都是透明的。不同container内的进程属于不同的Namespace,彼此透明,互不干扰。我们用一个例子来理解namespace的必要。假设多个用户购买了一台Linux服务器的Nginx服务,每个用户在该服务器上被分配了一个Linux系统的账号。我们希望每个用户只能访问分配给其的文件夹,这当然可以通过Linux文件系统本身的权限控制来实现,即一个用户只能访问属于他本身的那些文件夹。但是有些操作仍然需要系统级别的权限,比如root,但我们肯定不可能给每个用户都分配root权限。因此我们就可以使用namespace技术:我们能够为UID = n的用户,虚拟化一个namespace出来,在这个namespace里面,该用户具备root权限,但是在宿主机上,该UID =n的用户还是一个普通用户,也感知不到自己其实不是一个真的root用户这件事。同样的方式可以通过namespace虚拟化进程树。在每一个namespace内部,每一个用户都拥有一个属于自己的init进程,pid = 1,对于该用户来说,仿佛他独占一台物理的Linux服务器。对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为1),其他进程的PID依次递增,A和B空间都有PID为1的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。从图中我们可以看到,进程3在父命名空间里面PID 为3,但是在子命名空间内,他就是1.也就是说用户从子命名空间 A 内看进程3就像 init 进程一样,以为这个进程是自己的初始化进程,但是从整个 host 来看,他其实只是3号进程虚拟化出来的一个空间而已。看下面的图加深理解。父容器有两个子容器,父容器的命名空间里有两个进程,id分别为3和4, 映射到两个子命名空间后,分别成为其init进程,这样命名空间A和B的用户都认为自己独占整台服务器。Linux操作系统到目前为止支持的六种namespace:unionFS:顾名思义,unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。要理解unionFS,我们首先要认识bootfs和rootfs。1. boot file system (bootfs):包含操作系统boot loader 和 kernel。用户不会修改这个文件系统。一旦启动完成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放出内存。同样内核版本的不同的 Linux 发行版,其bootfs都是一致的。2. root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp就是我下面这张图里的这些文件夹:等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。不同的Linux版本,实现unionFS的技术可能不一样,使用命令docker info查看,比如我的机器上实现技术是overlay2:看个实际的例子。新建两个文件夹abap和java,在里面用touch命名分别创建两个空文件:新建一个mnt文件夹,用mount命令把abap和java文件夹merge到mnt文件夹下,-t执行文件系统类型为aufs:sudo mount -t aufs -o dirs=./abap:./java none ./mntmount完成后,到mnt文件夹下查看,发现了来自abap和java文件夹里总共4个文件:现在我到java文件夹里修改spring,比如加上一行spring is awesome, 然后到mnt文件夹下查看,发现mnt下面的文件内容也自动被更新了。那么反过来会如何呢?比如我修改mnt文件夹下的aop文件:而java文件夹下的原始文件没有受到影响:实际上这就是Docker容器镜像分层实现的技术基础。如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。而新镜像就是从基础镜像上一层层叠加新的逻辑构成的。这种分层设计,一个优点就是资源共享。想象这样一个场景,一台宿主机上运行了100个基于debian base镜像的容器,难道每个容器里都有一份重复的debian拷贝呢?这显然不合理;借助Linux的unionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被所有基于这个镜像的容器共享。当某个容器修改了基础镜像的内容,比如 /bin文件夹下的文件,这时其他容器的/bin文件夹是否会发生变化呢?根据容器镜像的写时拷贝技术,某个容器对基础镜像的修改会被限制在单个容器内。这就是我们接下来要学习的容器 Copy-on-Write 特性。容器镜像由多个镜像层组成,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /text,上层的 /text 会覆盖下层的 /text,也就是说用户只能访问到上层中的文件 /text。假设我有如下这个dockerfile:FROM debianRUN apt-get install emacsRUN apt-get install apache2CMD ["/bin/bash"]执行docker build .看看发生了什么。生成的容器镜像如下:当用docker run启动这个容器时,实际上在镜像的顶部添加了一个新的可写层。这个可写层也叫容器层。容器启动后,其内的应用所有对容器的改动,文件的增删改操作都只会发生在容器层中,对容器层下面的所有只读镜像层没有影响。要获取更多Jerry的原创文章,请关注公众号"汪子熙": ...

December 21, 2018 · 1 min · jiezi