Docker的英文本意是“搬运工”,在程序员的世界里,Docker搬运的是集装箱(Container),集装箱里装的是任意类型的App,开发者经过Docker能够将App变成一种标准化的、可移植的、自管理的组件,能够在任何主流系统中开发、调试和运行。mysql
说白了,docker是一种用了新颖方式实现的轻量级虚拟机,相似于VM,可是在原理和应用上和VM的差异仍是很大的.而且docker的专业叫法是应用容器(Application Container)。linux
为啥要用容器?
应用容器是个啥样子呢,一个作好的应用容器长得就像一个装好了一组特定应用的虚拟机同样,好比我如今想用mysql,那我就找个装好了mysql的容器就能够了,而后运行起来,我就能使用mysql了。nginx
为啥不能直接安装一个mysql?安装一个SQL Server也能够啊,但是有的时候根据每一个人电脑的不一样,在安装的时候可能会报出各类各样的错误,万一你的机器中毒了,你的电脑挂了,你全部的服务都须要从新安装.可是有了docker,或者说有了容器就不一样了,你就至关于有了一个能够运行起来的虚拟机,只要你能运行容器,mysql的配置就省了.并且若是你想换个电脑,直接把容器”端过来”就可使用容器里面的服务.git
Docker 基于 Go 语言开发,代码托管在Github上,并遵循Apache 2.0 开源协议。Docker 容器能够封装任何有效负载,几乎能够在任何服务器之间进行一致性运行。换句话说,开发者构建的应用只需一次构建便可多平台运行。运营人员只需配置他们的服务,便可运行全部的应用。程序员
如果利用容器的话,那么开发直接在容器里开发,测试的时候把整个容器给测试,测好了把测试后容器再上线就行了.经过容器,整个开发,测试和生产环境能够保持高度一致。github
此外容器也VM同样具备必定得隔离性,各个容器之间的数据和内存空间相互隔离,能够保证必定的安全性。web
Hyper-V、KVM和Xen等虚拟机管理程序都“基于虚拟化硬件仿真机制。这意味着,它们对系统要求很高.然而,容器却使用共享的操做系统。这意味着它们在使用系统资源方面比虚拟机管理程序要高效得多。容器不是对硬件进行虚拟化处理,而是驻留在一个Linux实例上。
Docker能够解决虚拟机可以解决的问题,同时也可以解决虚拟机因为资源要求太高而没法解决的问题。sql
•开发者使用一个标准的 image 来构建开发容器,开发完成以后,系统管理员就可使用这个容器来部署代码
•docker能够快速建立容器,快速迭代应用程序,并让整个过程可见,使团队中的其余成员更容易理解应用程序是如何建立和工做的。
•docker容器很轻!很快!容器的启动时间是次秒级的,节约开发、测试、部署的时间docker
•docker容器能够在几乎全部的环境中运行,物理机、虚拟机、公有云、私有云、我的电脑、服务器等等。
•docker容器兼容不少平台,这样就能够把一个应用程序从一个平台迁移到另一个。shell
•docker容器不须要 hypervisor ,他是内核级的虚拟化。
•一般只须要小小的改变就能够替代以往巨型和大量的更新工做。
那么既然容器和VM这么相似为啥不用VM?docker容器相对于VM仍是有不少优势的:
1.启动速度快,容器一般在一秒内能够启动.而VM要好久.
2.资源利用率高,一台普通服务器能够跑上千个容器,而跑VM就。。。。。。
3.性能开销小,VM须要额外的CPU和内存来完成OS的功能,这一部分占据了额外的资源.
为啥类似的功能在性能上会有如此巨大的差距呢?看一下他们的设计图,先看VM的:
下面的图片比较了 Docker 和传统虚拟化方式的不一样之处,
可见容器是在操做系统层面上实现虚拟化,直接复用本地主机的操做系统,而传统方式则是在硬件层面实现。
Docker优点和劣势
做为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具备众多的优点。
首先,Docker 容器的启动能够在秒级实现,这相比传统的虚拟机方式要快得多。
其次,Docker 对系统资源的利用率很高,一台主机上能够同时运行数千个 Docker 容器。
容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽可能小。传统虚拟机方式运行 10 个不一样的应用就要起 10 个虚拟机,而 Docker 只须要启动 10 个隔离的应用便可。
具体说来,Docker 在以下几个方面具备较大的优点。
更快速的交付和部署
对开发和运维(devop)人员来讲,最但愿的就是一次建立或配置,能够在任意地方正常运行。开发者可使用一个标准的镜像来构建一套开发容器,开发完成以后,运维人员能够直接使用这个容器来部署代码。 Docker 能够快速建立容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其余成员更容易理解应用程序是如何建立和工做的。 Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
更高效的虚拟化
Docker 容器的运行不须要额外的 hypervisor 支持,它是内核级的虚拟化,所以能够实现更高的性能和效率。
更轻松的迁移和扩展
Docker 容器几乎能够在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、我的电脑、服务器等。这种兼容性可让用户把一个应用程序从一个平台直接迁移到另一个。
更简单的管理
使用 Docker,只须要小小的修改,就能够替代以往大量的更新工做。全部的修改都以增量的方式被分发和更新,从而实现自动化而且高效的管理。
对比传统虚拟机总结
| 特性 | 容器 | 虚拟机 |
| ---------- | ------------------ | -------------- |
| 启动 | 秒级 | 分钟级 |
| 硬盘使用 | 通常为MB | 通常为GB |
| 性能 | 接近原生 | 弱于 |
| 系统支持量 | 单机支持上千个容器 | 单机最多几十个 |
docker使用C/S 架构,docker daemon 做为 server 端接受 client 的请求,并处理(建立、运行、分发容器),他们能够运行在一个机器上,也经过 socket或者 RESTful API 通讯
Docker daemon 通常在宿主主机后台运行。
Docker client以系统命令的形式存在,用户用docker命令来跟docker daemon 交互。
Docker 守护进程(Docker daemon)
如上图所示,Docker 守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是经过 Docker 客户端间接和其通讯。
Docker 客户端(Docker client)
Docker 客户端,其实是docker的二进制程序,是用户与 Docker 交互方式。它接收用户指令而且与背后的 Docker 守护进程通讯。
要理解 Docker 内部构建,须要理解如下三种部件:
1)Docker 镜像 - Docker images
2)Docker 仓库 - Docker registeries
3)Docker 容器 - Docker containers
Docker 镜像是 Docker 容器运行时的只读模板,镜像能够用来建立 Docker 容器。每个镜像由一系列的层 (layers) 组成。Docker 使用UnionFS(联合文件系统)来将这些层联合到单独的镜像中。UnionFS容许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,造成一个单独连贯的文件系统。正由于有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,好比升级到某个程序到新的版本,一个新的层会被建立。所以,不用替换整个原先的镜像或者从新创建(在使用虚拟机的时候你可能会这么作),只是一个新的层被添加或升级了。如今你不用从新发布整个镜像,只须要升级,层使得分发 Docker 镜像变得简单和快速。
每一个docker都有不少层次构成,docker使用 union file systems 将这些不一样的层结合到一个image 中去。
例如:centos镜像中安装nginx,就成了nginx镜像”,其实在此时Docker镜像的层级概念就体现出来了。底层一个centos操做系统镜像,上面叠加一个ngnx层,就完成了一个nginx镜像的构建。层级概念就不难理解,此时咱们通常centos操做系统镜像称为nginx镜像层的父镜像。
Docker 仓库用来保存镜像,能够理解为代码控制中的代码仓库。一样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像能够是本身建立,或者在别人的镜像基础上建立。
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上每每存放着多个仓库,每一个仓库中又包含了多个镜像,每一个镜像有不一样的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式,最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括 Docker Pool等,能够提供大陆用户更稳定快速的访问。
固然,用户也能够在本地网络内建立一个私有仓库。当用户建立了本身的镜像以后就可使用push命令将它上传到公有或者私有仓库,这样下次在另一台机器上使用这个镜像时候,只须要从仓库上pull下来就能够了。
*注:Docker 仓库的概念跟Git相似,注册服务器能够理解为 GitHub 这样的托管服务。
Docker 容器用来运行应用,一个Docker容器包含了全部的某个应用运行所须要的环境。每个 Docker 容器都是从 Docker 镜像建立的。Docker 容器能够运行、开始、中止、移动和删除。每个 Docker 容器都是独立和安全的应用平台。
容器是从镜像建立的运行实例。它能够被启动、开始、中止、删除。每一个容器都是相互隔离的、保证安全的平台。
能够把容器看作是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
*注:镜像是只读的,容器在启动的时候建立一层可写层做为最上层。
与虚拟机相比,容器有一个很大的差别,它们被设计用来运行"单进程",没法很好地模拟一个完整的环境。Docker设计者极力推崇“一个容器一个进程的方式”,若是你要选择在一个容器中运行多个进程,那惟一状况是:出于调试目的。
容器是设计来运行一个应用的,而非一台机器。你可能会把容器当虚拟机用,但你将失去不少的灵活性,由于Docker提供了用于分离应用与数据的工具,使得你能够快捷地更新运行中的代码/系统,而不影响数据。
Docker 从 0.9 版本开始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系统的交互图以下:
Docker 底层技术
docker底层的 2 个核心技术分别是 Namespaces 和 Control groups
Namespaces用来隔离各个容器
不一样用户的进程就是经过pid namespace 隔离开的,且不一样 namespace 中能够有相同pid。全部的LXC进程在docker中的父进程为docker进程,每一个lxc进程具备不一样的 namespace 。
有了pid namespace, 每一个 namespace 中的pid可以相互隔离,可是网络端口仍是共享 host 的端口。网络隔离是经过 net namespace 实现的,每一个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每一个 container 的网络就能隔离开来。docker默认采用veth的方式将 container 中的虚拟网卡同 host 上的一个docker bridge: docker0 链接在一块儿。
container 中进程交互仍是采用linux常见的进程间交互方法 (interprocess communication - IPC),包括常见的信号量、消息队列和共享内存。container 的进程间交互实际上仍是host 上具备相同pid namespace 中的进程间交互。
相似chroot,将一个进程放到一个特定的目录执行。mnt namespace 容许不一样 namespace 的进程看到的文件结构不一样,这样每一个 namespace 中的进程所看到的文件目录就被隔离开了。在container里头,看到的文件系统,就是一个完整的linux系统,有/etc、/lib 等,经过chroot实现。
UTS("UNIX Time-sharing System") namespace 容许每一个 container 拥有独立的 hostname 和 domain name, 使其在网络上能够被视做一个独立的节点而非 Host 上的一个进程。
每一个 container 能够有不一样的 user 和 group id, 也就是说能够在 container 内部用 container 内部的用户执行程序而非 Host 上的用户。
有了以上 6 种 namespace 从进程、网络、IPC、文件系统、UTS和用户角度的隔离,一个 container 就能够对外展示出一个独立计算机的能力,而且不一样 container 从 OS 层面实现了隔离。然而不一样 namespace 之间资源仍是相互竞争的,仍然须要相似ulimit来管理每一个 container 所能使用的资源 - -cgroup。
资源配额「cgroups」
cgroups 实现了对资源的配额和度量。 cgroups 的使用很是简单,提供相似文件的接口,在 /cgroup 目录下新建一个文件夹便可新建一个 group,在此文件夹中新建 task 文件,并将 pid 写入该文件,便可实现对该进程的资源控制。具体的资源配置选项能够在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法, 如 memory.usageinbytes 就定义了该 group 在 subsystem memory 中的一个内存限制选项。 另外,cgroups 中的 subsystem 能够随意组合,一个 subsystem 能够在不一样的 group 中,也能够一个 group 包含多个 subsystem - 也就是说一个 subsystem。
memory
内存相关的限制
cpu
在 cgroup 中,并不能像硬件虚拟化方案同样可以定义 CPU 能力,可是可以定义 CPU 轮转的优先级,所以具备较高 CPU 优先级的进程会更可能获得 CPU 运算。 经过将参数写入 cpu.shares ,便可定义改 cgroup 的 CPU 优先级 - 这里是一个相对权重,而非绝对值
blkio
block IO 相关的统计和限制,byte/operation 统计和限制 (IOPS 等),读写速度限制等,可是这里主要统计的都是同步 IO
devices
设备权限限制
docker官网:https://docs.docker.com
Docker值得关注的特性:
o文件系统隔离:每一个进程容器运行在一个彻底独立的根文件系统里。
o资源隔离:系统资源,像CPU和内存等能够分配到不一样的容器中,使用cgroup。
o网络隔离:每一个进程容器运行在本身的网络空间,虚拟接口和IP地址。
o日志记录:Docker将会收集和记录每一个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。
o变动管理:容器文件系统的变动能够提交到新的映像中,并可重复使用以建立更多的容器。无需使用模板或手动配置。
o交互式shell:Docker能够分配一个虚拟终端并关联到任何容器的标准输入上,
CentOS 系列安装 Docker,Docker 支持 CentOS6 及之后的版本。
CentOS6:
在RedHat/CentOS环境下安装Docker。官方文档要求Linux kernel至少3.8以上,且docker只能运行在64位的系统中。因为RHEL6和CentOS6的内核版本为2.6,所以必需要先升级内核。
升级内核(记住必定要升级,要否则会出现不少莫名奇怪的问题,建议用yum安装)
1-1)yum安装带aufs模块的3.10内核
[root@server4 ~]# cd /etc/yum.repos.d/ [root@server4 yum.repos.d]# wget http://www.hop5.in/yum/el6/hop5.repo [root@server4 yum.repos.d]# ls hop5.repo [root@server4 yum.repos.d]# yum -y install kernel-ml-aufs kernel-ml-aufs-devel
1-2)修改grub的主配置文件/etc/grub.conf,设置default=0,表示第一个title下的内容为默认启动的kernel(通常新安装的内核在第一个位置),
1-3)重启系统,这时候你的内核就成功升级了。
[root@server4 ~]# uname -r 3.10.0-327.el7.x86_64
1-4)可使用EPEL库安装 Docker,命令以下:
#yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm #yum install docker-io
1-5)启动docker服务
#service docker start
2-1)Prerequisites(先决条件)
Docker requires a 64-bit installation regardless of your CentOS version. Also, your kernel must be 3.10 at minimum, which CentOS 7 runs.
To check your current kernel version, open a terminal and use uname -r to display your kernel version:
[root@server4 yum.repos.d]# uname -r
3.10.0-327.el7.x86_64
2-2)Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。所以想要安装docker,只须要运行下面的 yum 命令:
[root@server4 yum.repos.d]# yum -y install docker
注:如出现如下报错
[root@server4 yum.repos.d]# yum -y install docker
Loaded plugins: plugins: fastestmirror, langpacks
Existing lock /var/run/yum.pid: another copy is running as pid 13120.
Another app is currently holding the yum lock; waiting for it to exit...
The other application is: PackageKit
Memory : 26 M RSS (429 MB VSZ)
Started: Fri Nov 11 10:27:44 2016 - 00:12 ago
State : Sleeping, pid: 13120
解决方法:
[root@server4 yum.repos.d]# rm -rf /var/run/yum.pid
2-3)启动 Docker 服务:
安装完成后,使用下面的命令来启动docker服务,并将其设置为开机启动:
[root@server4 ~]# systemctl enable docker [root@server4 ~]# systemctl start docker
2-4)查看docker版本
[root@server4 ~]# docker version Client: Version: 1.10.3 API version: 1.22 Package version: docker-common-1.10.3-46.el7.centos.14.x86_64 Go version: go1.6.3 Git commit: cb079f6-unsupported Built: Fri Sep 16 13:24:25 2016 OS/Arch: linux/amd64 Server: Version: 1.10.3 API version: 1.22 Package version: docker-common-1.10.3-46.el7.centos.14.x86_64 Go version: go1.6.3 Git commit: cb079f6-unsupported Built: Fri Sep 16 13:24:25 2016 OS/Arch: linux/amd64
2-5)查看docker版本:docker info
[root@server4 ~]# docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 1.10.3 Storage Driver: devicemapper Pool Name: docker-253:0-1785801-pool Pool Blocksize: 65.54 kB Base Device Size: 10.74 GB Backing Filesystem: xfs Data file: /dev/loop0 Metadata file: /dev/loop1 Data Space Used: 11.8 MB Data Space Total: 107.4 GB Data Space Available: 40.74 GB Metadata Space Used: 581.6 kB Metadata Space Total: 2.147 GB Metadata Space Available: 2.147 GB Udev Sync Supported: true Deferred Removal Enabled: false Deferred Deletion Enabled: false Deferred Deleted Device Count: 0 Data loop file: /var/lib/docker/devicemapper/devicemapper/data
以上是使用centos7软件源提供的docker安装程序
附:也能够按照官方文档安装
1.Log into your machine as a user with sudo or root privileges.
2.Make sure your existing yum packages are up-to-date.
3.Add the yum repo
$ sudo tee /etc/yum.repos.d/docker.repo<<-'EOF'
[dockerrepo]
name=DockerRepositorybaseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
注:若是咱们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可使用tee命令了。tee命令读取标准输入,把这些内容同时输出到标准输出和(多个)文件中
4.Install the Docker package
$ sudo yum install docker-engine
5.Start the Docker daemon.
$ sudo service dockerstart
6.Verify docker is installed correctly by running a test image in a container.
验证docker安装正确
以上是使用centos7软件源提供的docker安装程序
附:也能够按照官方文档安装
1.Log into your machine as a user with sudo or root privileges.
2.Make sure your existing yum packages are up-to-date.
3.Add the yum repo
$ sudo tee /etc/yum.repos.d/docker.repo<<-'EOF'
[dockerrepo]
name=DockerRepositorybaseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
注:若是咱们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可使用tee命令了。tee命令读取标准输入,把这些内容同时输出到标准输出和(多个)文件中
4.Install the Docker package
$ sudo yum install docker-engine
5.Start the Docker daemon.
$ sudo service dockerstart
6.Verify docker is installed correctly by running a test image in a container.
验证docker安装正确
$ sudo docker run hello-world
7.docker默认使用的是unix socket
[root@server4 ~]# ss -ax | grep docker u_str LISTEN 0 128 /var/lib/docker/network/files/8269c2bdc34721cabf2d2fa89b52bafd7fd1cd3f7d0c7456518c74b5cb704bdf.sock 53403 * 0 u_str LISTEN 0 128 /var/run/docker.sock 53301 * 0 u_str ESTAB 0 0 /var/run/docker.sock 55511 * 48920
附:直接输入docker命令来查看全部的Options和Commands,查看某一个command的详细使用方法:dockerCOMMAND--help
在以前的介绍中,咱们知道docker images 是docker的三大组件之一。
docker把下载的 images 存储到docker主机上,若是一个 image 不在主机上,docker会从一个镜像仓库下载,默认的仓库是 DOCKER HUB 公共仓库。
接下来将介绍更多关于docker images 的内容,包括:
•使用和管理本地主机上的 images
•建立一个基础的 images
•上传 images 到docker hub (公共 images 仓库)
•列出本地主机上已经存在的 images
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 50dae1ee8677 3 months ago 196.7 MB
在列出信息中,
•REPOSITORY:来自于哪一个仓库,好比 docker.io/centos
•TAG的标记,好比 latest
•IMAGE ID:镜像它的 ID 号
•CREATED:建立时间
•SIZE:镜像的 SIZE
一个仓库可能有一个 images 的都个发行版,好比ubuntu,他们有 10.04 12.04 12.10 13.04 14.04,每一个发行版的标记都不一样,可使用 tag 命令来指定 images
注:若是你不指定具体的发行版,好比仅使用ubuntu,那么docker会使用最新的发行版ubuntu:latest
提示:建议最好指定发行版,只有这样你才能够保证你真正使用的 image 是那个
咱们如何获取新的 images 呢?当咱们启动容器使用的 image 再也不本地主机上时,docker会自动下载他们。这很耗时,咱们可使用docker pull 命令来预先下载咱们须要的 image 。下面的例子下载一个centos 镜像。
[root@localhost ~]# docker pull docker.io/centos Using default tag: latest Trying to pull repository docker.io/library/centos ... latest: Pulling from docker.io/library/centos 08d48e6f1cff: Downloading [> ] 1.081 MB/70.48 MB
这样当咱们使用这个 image 来启动容器的时候,它就能够立刻启动了。
这样当咱们使用这个 image 来启动容器的时候,它就能够立刻启动了。
docker的一个特色是不少人由于各类不一样的用途建立了各类不一样的 images 。它们都被上传到了docker hub 共有仓库上,咱们能够在docker hub 的网站上来查找它们。使用docker search 命令。好比,当咱们须要 ruby 和sinatra做为 web 应用程序的开发时,咱们使用docker search 来搜索合适的image ,使用关键字sinatra
[root@localhost ~]# docker search sinatra
咱们看到返回了不少包含sinatra的 images 。其中包括 image 名字、描述、星级(表示该 image 的受欢迎程度)、是否官方建立、是否自动建立。官方的 images 是stackbrew项目组建立和维护的,automated 资源容许你验证 image 的来源和内容。
到目前为止,咱们看到了 2种 images 资源。好比ubuntu,被称为基础或则根镜像。这些基础镜像是docker公司建立、验证、支持、提供。他们每每使用一个单词做为他们的名字。还有一种类型,好比咱们选择的 training/sinatra镜像。它是由docker的用户建立并维护的,你能够经过指定 image 名字的前缀来指定他们,好比 training 。
如今咱们指定了一个 image , training/sinatra,咱们可使用docker pull 命令来下载它
[root@localhost ~]# docker pull docker.io/jdeathe/centos-ssh
下载过程当中,会输出获取镜像的每一层信息。
该命令实际上至关于#docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服
务器 registry.hub.docker.com 中的ubuntu仓库来下载标记为 12.04 的镜像。
有时候官方仓库注册服务器下载较慢,能够从其余仓库下载。从其它仓库下载时须要指定完整的仓库注册服务器地址。例如
#docker pull dl.dockerpool.com:5000/ubuntu:12.04
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 50dae1ee8677 3 months ago 196.7 MB docker.io/centos centos6 cf2c3ece5e41 4 months ago 194.6 MB
当镜像下载成功后,你能够看到 12 位的 hash 值像 05188b417f30,这是下载完整的镜像的精简 ID,这些短的镜像 ID 是完整镜像 ID 的前 12 个字符--可使用docker inspect 或者docker images --no-trunc来得到完整的镜像 ID
[root@localhost ~]# docker inspect docker.io/centos
或: --no-trunc来得到完整的镜像 ID
[root@localhost ~]# docker images --no-trunc
别人的镜像虽然好,但不必定适合咱们。咱们能够对他们作一些改变,有 2 个方法:
1.第一个方法:使用docker commit 来扩展一个 image
1-1先使用 image 启动容器,更新后提交结果到新的 image 。
[root@localhost ~]# docker run -it docker.io/centos /bin/bash [root@cfd9c030875b /]#
注意:记住容器的 ID ,稍后咱们还会用到
注意:记住容器的 ID ,稍后咱们还会用到
1-2在容器中添加mariadb-server应用。
[root@cfd9c030875b /]# yum -y install httpd [root@cfd9c030875b /]# exit
exit
当结束后,咱们使用 exit 来退出,如今咱们的容器已经被咱们改变了
exit
当结束后,咱们使用 exit 来退出,如今咱们的容器已经被咱们改变了
1-3使用docker commint命令来提交相应的副本。
[root@localhost ~]# docker commit -m "added httpd app" -a "docker chen" cfd9c030875b centos:httpd sha256:05653ceb4e74275edfbc16edaa1976410e0fd6a35b910d4d04d83f8e92353669
其中:
-m 来指定提交的说明信息,跟咱们使用的版本控制工具同样;
-a 能够指定更新的用户信息;以后是用来建立镜像的容器的 ID;
最后指定目标镜像的仓库名和 tag 信息。建立成功后会返回这个镜像的 ID信息。
其中:
-m 来指定提交的说明信息,跟咱们使用的版本控制工具同样;
-a 能够指定更新的用户信息;以后是用来建立镜像的容器的 ID;
最后指定目标镜像的仓库名和 tag 信息。建立成功后会返回这个镜像的 ID信息。
1-4)使用docker images 来查看新建立的镜像。
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos httpd 05653ceb4e74 About a minute ago 295.3 MB docker.io/centos latest 50dae1ee8677 3 months ago 196.7 MB docker.io/centos centos6 cf2c3ece5e41 4 months ago 194.6 MB
以后,可使用新的镜像来启动容器
以后,可使用新的镜像来启动容器
[root@localhost ~]# docker run -it centos:httpd /bin/bash [root@392e3fa371b7 /]# uname -r 3.10.0-327.el7.x86_64
2.第二个办法:从dockerfile来建立 image
使用docker commit 来扩展一个 image 比较简单,但它不容易在一个团队中分享它。咱们使用docker build 来建立一个新的 image 。为此,咱们须要建立一个dockerfile,包含一些如何建立咱们的image 的指令。
2-1)建立一个目录和一个dockerfile
[root@localhost ~]# mkdir -p /docker/httpd [root@localhost ~]# cd /docker/httpd [root@localhost httpd]# vim dockerfile #This is a comment FROM docker.io/centos MAINTAINER chen <chen@mail.com> RUN yum -y -q install httpd
Dockerfile基本的语法是
使用#来注释
FROM指令告诉 Docker 使用哪一个镜像做为基础(docker使用哪一个 image 源)
MAINTAINER是维护者的信息
RUN开头的指令会在建立中运行,好比安装一个软件包,在这里使用 yum来安装了一些软件
Dockerfile基本的语法是
使用#来注释
FROM指令告诉 Docker 使用哪一个镜像做为基础(docker使用哪一个 image 源)
MAINTAINER是维护者的信息
RUN开头的指令会在建立中运行,好比安装一个软件包,在这里使用 yum来安装了一些软件
2-2)编写完成Dockerfile后可使用docker build 来生成镜像。
[root@localhost httpd]# docker build -t="centos:httpd-1" .
其中:
-t 标记来添加 tag,指定新的镜像的用户信息。
“.”是Dockerfile所在的路径(当前目录),也能够替换为一个具体的Dockerfile的路径。
能够看到 build 进程在执行操做。它要作的第一件事情就是上传这个Dockerfile内容,由于全部的操做都要依据Dockerfile来进行。而后,Dockfile中的指令被一条一条的执行。每一步都建立了一个新的容器,在容器中执行指令并提交修改(就跟以前介绍过的docker commit 同样)。当全部的指令都执行完毕以后,返回了最终的镜像 id。全部的中间步骤所产生的容器都被删除和清理了。
*注意一个镜像不能超过 127 层
2-3)查看生成的镜像
[root@localhost httpd]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos httpd-1 a7e5b7ebdc89 8 minutes ago 338.5 MB centos httpd f8cadf4f19b7 13 minutes ago 338.5 MB docker.io/centos latest 50dae1ee8677 3 months ago 196.7 MB docker.io/centos centos6 cf2c3ece5e41 4 months ago 194.6 MB
2-4)从咱们新建的 images 开启容器
[root@localhost httpd]# docker run -it centos:httod-1 /bin/bash [root@dafdc2b34c56 /]#
2-5)还能够用docker tag 命令来修改镜像的标签。
[root@localhost httpd]# docker tag centos:httpd-1 centos:httod-1 [root@localhost httpd]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos httod-1 a7e5b7ebdc89 12 minutes ago 338.5 MB centos httpd-1 a7e5b7ebdc89 12 minutes ago 338.5 MB centos httpd f8cadf4f19b7 17 minutes ago 338.5 MB docker.io/centos latest 50dae1ee8677 3 months ago 196.7 MB docker.io/centos centos6 cf2c3ece5e41 4 months ago 194.6 MB
3.从本地文件系统导入
要从本地文件系统导入一个镜像,可使用openvz(容器虚拟化的先锋技术)的模板来建立:openvz的模板下载地址为http://openvz.org/Download/template/precreated。
先下载了一个centos-6-x86_64.tar.gz的镜像,以后使用如下命令导入:
用户能够经过docker push 命令,把本身建立的镜像上传到仓库中来共享。例如,用户在 Docker Hub 上,完成注册后,能够推送本身的镜像到仓库中。
这里有两种访问能够建立和注册一个 Docker Hub 帐户:
1.经过网站,(https://hub.docker.com)
2.经过命令行
你能够经过使用命令行输入 docker login 命令来建立一个 Docker Hub 帐号
#docker login
邮箱确认
一旦你填写完毕表格,请查看你的电子邮件,经过点击欢迎信息中的连接来激活您的帐户。
邮箱确认
一旦你填写完毕表格,请查看你的电子邮件,经过点击欢迎信息中的连接来激活您的帐户。
基本思路:
首先注册docker的帐户,而后使用docker login登陆。
使用docker push能够将本身的镜像上传上去了
若是有其余的仓库,例如:
docker push docker.sina.com.cn:5000/commit
dockerrmi镜像名或镜像id
[root@localhost httpd]# docker rmi centos:httod-1
注意:在删除 images 以前要先用dockerrm删掉依赖于这个 images 的容器
注意:在删除 images 以前要先用dockerrm删掉依赖于这个 images 的容器
当须要把一台机器上的镜像迁移到另外一台机器的时候,须要存出镜像与载入镜像。
10-1)存出镜像
若是要导出镜像到本地文件,可使用docker save 命令。
[root@localhost ~]# docker save -o centos-6-httpd.tar centos:httpd-1 [root@localhost ~]# ls centos-6-httpd.tar centos-6-httpd.tar
10-2)载入镜像
可使用docker load 从导出的本地文件中再导入到本地镜像库,例如
这将导入镜像以及其相关的元数据信息(包括标签等)
容器是 Docker 又一核心概念,简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机能够理解为模拟运行的一整套操做系统(提供了运行态环境和其余系统环境)和跑在上面的应用。
本章将具体介绍如何来管理一个容器,包括建立、启动和中止等。
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另一个是将在终止状态(stopped)的容器从新启动。
所须要的命令主要为docker run
下面的命令则启动一个 bash 终端,容许用户进行交互。
[root@localhost ~]# docker run -it docker.io/centos:centos6 [root@c88f4fefd1ff /]#
-t 选项让 Docker 分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,
-i则让容器的标准输入保持打开(即交互式),可使用—name给容器起个形象的名称。
在交互模式下,用户能够经过所建立的终端来输入命令,例如
-t 选项让 Docker 分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,
-i则让容器的标准输入保持打开(即交互式),可使用—name给容器起个形象的名称。
在交互模式下,用户能够经过所建立的终端来输入命令,例如
[root@c88f4fefd1ff /]# pwd / [root@c88f4fefd1ff /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 08:18 ? 00:00:00 /bin/bash root 12 1 0 08:20 ? 00:00:00 ps -ef
容器的核心为所执行的应用程序,所须要的资源都是应用程序运行所必需的。除此以外,并无其它的资源。能够在伪终端中利用ps或 top 来查看进程信息。
容器的核心为所执行的应用程序,所须要的资源都是应用程序运行所必需的。除此以外,并无其它的资源。能够在伪终端中利用ps或 top 来查看进程信息。
[root@c88f4fefd1ff /]# ps PID TTY TIME CMD 1 ? 00:00:00 bash 13 ? 00:00:00 ps
可见,容器中仅运行了指定的 bash 应用。这种特色使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。
可见,容器中仅运行了指定的 bash 应用。这种特色使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。
若是这个时候咱们正常退出,logout 或者 exit 或者Ctrl+d或者Ctrl+c,dockerps–a 查看容器处于 Exit 状态若是须要正常退出可使用 CTRL –p + CTRL -q ----就像先按 CTRL -p 而后 CTRL –q 退出伪终端
下面的命令输出一个“Hello World”,以后终止容器。
[root@localhost ~]# docker run docker.io/centos:latest /bin/echo 'hello world' htool world
这跟在本地直接执行 /bin/echo 'hello world' 几乎感受不出任何区别。
这跟在本地直接执行 /bin/echo 'hello world' 几乎感受不出任何区别。
当利用docker run 来建立容器时,Docker 在后台运行的标准操做包括:
1.检查本地是否存在指定的镜像,不存在就从公有仓库下载
2.利用镜像建立并启动一个容器
3.分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
4.从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
5.从地址池配置一个ip地址给容器
6.执行用户指定的应用程序
7.执行完毕后容器被终止
[root@localhost ~]# docker ps -a 
附:养成查看帮助的习惯
[root@localhost ~]# docker ps -h Usage: docker ps [OPTIONS] List containers -a, --all Show all containers (default shows just running) -f, --filter=[] Filter output based on conditions provided --format Pretty-print containers using a Go template --help Print usage -l, --latest Show the latest created container (includes all states) -n=-1 Show n last created containers (includes all states) --no-trunc Don't truncate output -q, --quiet Only display numeric IDs -s, --size Display total file sizes
docker start [contraiID]
容器处于 Exited 状态,能够直接启动
docker stop [容器 ID] docker kill [容器 ID]
可使用docker stop 来终止一个运行中的容器。此外,当Docker容器中指定的应用终结时,容器也自动终止。例如对于前面所讲中启动了一个终端的容器,用户经过 exit 命令或Ctrl+d来退出终端时,所建立的容器马上终止
终止状态的容器能够用docker ps -a 命令看到。例如
状态由 Up -> Exit
处于终止状态的容器,能够经过docker start 命令来从新启动。
docker restart 命令会将一个运行态的容器终止,而后再从新启动它。 docker restart [容器 ID]
更多的时候,须要让 Docker 容器在后台以守护状态(Daemonized)形式运行。此时,能够经过添加 -d 参数来实现。例以下面的命令会在后台运行容器。
[root@localhost ~]# docker run -d docker.io/centos /bin/bash -c "while true ; do echo hello world ; sleep 1 ; done" 
或
[root@localhost ~]# docker run -dt docker.io/centos /bin/bash 56c3adf740ba870818af856ab76fe43fa7f44d7a0f2fc26fc4b4558788585e3a [root@localhost ~]#
容器启动后会返回一个惟一的 id,也能够经过docker ps命令来查看容器信息。
1.docker run -d 运行提个新的容器,咱们经过-d 命令让他做为一个后台运行
2.centos:centos6 是一个咱们想要在内部运行命令的镜像
3./bin/sh -c 是咱们想要在容器内部运行的命令
4.while true; do echo hello weibo; sleep 1; done 这是一个简单的脚本,咱们仅仅只是每秒打印一次 hello word 一直到咱们结束它
容器启动后会返回一个惟一的 id,也能够经过docker ps命令来查看容器信息。
1.docker run -d 运行提个新的容器,咱们经过-d 命令让他做为一个后台运行
2.centos:centos6 是一个咱们想要在内部运行命令的镜像
3./bin/sh -c 是咱们想要在容器内部运行的命令
4.while true; do echo hello weibo; sleep 1; done 这是一个简单的脚本,咱们仅仅只是每秒打印一次 hello word 一直到咱们结束它
命令格式:docker inspect 容器ID或容器名
[root@localhost ~]# docker inspect 56c3adf740ba [ { "Id": "56c3adf740ba870818af856ab76fe43fa7f44d7a0f2fc26fc4b4558788585e3a", "Created": "2016-11-15T10:50:58.658378757Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 42710, "ExitCode": 0, "Error": "", "StartedAt": "2016-11-15T10:50:59.092432423Z", "FinishedAt": "0001-01-01T00:00:00Z" },
用docker inspect查看容器的ip地址
用docker inspect查看容器的ip地址
[root@localhost ~]# docker inspect -f '{{.NetworkSettings.IPAddress}}' 56c3adf740ba 172.17.0.4
用docker inspect查看容器执行的程序
用docker inspect查看容器执行的程序
[root@localhost ~]# docker inspect -f '{{.Config.Cmd}}' 56c3adf740ba {[/bin/bash]}
在使用 -d 参数时,容器启动后会进入后台。某些时候须要进入容器进行操做,有不少种方法,包括使用docker attach 命令或nsenter命令。
使用docker attach进入容器
docker attach 是Docker自带的命令。下面示例如何使用该命令。
[root@localhost ~]# docker attach 56c3adf740ba [root@56c3adf740ba /]#
或:
或:
[root@localhost ~]# docker attach --sig-proxy=false 56c3adf740ba [root@56c3adf740ba /]#
1.docker attach 容许咱们进入后台进程.
2.--sig-proxy=false 不使用容器转发信号,容许咱们使用 ctrl -c 来退出,执行dockerps查看在后台运行
可是使用 attach命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,全部窗口都会同步显示。当某个窗口因命令阻塞时,其余窗口也没法执行操做了。
1.docker attach 容许咱们进入后台进程.
2.--sig-proxy=false 不使用容器转发信号,容许咱们使用 ctrl -c 来退出,执行dockerps查看在后台运行
可是使用 attach命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,全部窗口都会同步显示。当某个窗口因命令阻塞时,其余窗口也没法执行操做了。
也能够执行docker exec进入运行的容器
docker exec -it 容器ID/名称 /bin/bash
以上命令返回一个命令界面,exec表明直接在容器中运行命令
以上命令返回一个命令界面,exec表明直接在容器中运行命令
[root@localhost ~]# docker exec -it 56c3adf740ba [root@56c3adf740ba /]#
安装
nsenter工具在util-linux包2.23版本后包含。若是系统中util-linux包没有该命令,能够按照下面的方法从源码安装
#wgethttps://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz #tar util-linux-2.24.tar.gz #cd util-linux-2.24 ./configure --without-ncurses&& make nsenter #cpnsenter /usr/local/bin
nsenter能够访问另外一个进程的名字空间。nsenter要正常工做须要有 root 权限
庆幸的是centos7使用的是util-linux-2.23,因此就直接使用系统提供的util-linux包了。
nsenter能够访问另外一个进程的名字空间。nsenter要正常工做须要有 root 权限
庆幸的是centos7使用的是util-linux-2.23,因此就直接使用系统提供的util-linux包了。
[root@localhost ~]# rpm -q util-linux util-linux-2.23.2-26.el7.x86_64
为了链接到容器,你还须要找到容器的第一个进程的PID,能够经过下面的命令获取。
为了链接到容器,你还须要找到容器的第一个进程的PID,能够经过下面的命令获取。
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
经过这个PID,就能够链接到这个容器:
nsenter --target $PID --mount --uts --ipc --net --pid
下面给出一个完整的例子。
下面给出一个完整的例子。
经过这个PID,就能够链接到这个容器:
nsenter --target $PID --mount --uts --ipc --net --pid
下面给出一个完整的例子。
下面给出一个完整的例子。
附:更简单的,建议你们下载 .bashrc_docker,并将内容放到 .bashrc中。
#wget ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker #echo "[ -f ~/.bashrc_docker ] &&. ~/.bashrc_docker" >> ~/.bashrc #source ~/.bashrc
这个文件中定义了不少方便使用 Docker 的命令,例如docker-pid能够获取某个容器的PID;而docker-enter 能够进入容器或直接在容器内执行命令。
这个文件中定义了不少方便使用 Docker 的命令,例如docker-pid能够获取某个容器的PID;而docker-enter 能够进入容器或直接在容器内执行命令。
echo $(docker-pid<container>) docker-enter <container> ls
容器导入和导出
导出容器:
docker export [容器 id] > [导出文件]
若是要导出本地某个容器,可使用docker export 命令。
[root@localhost ~]# docker export 56c3adf740ba > centos_web.tar [root@localhost ~]# ls anaconda-ks.cfg centos6.tar centos7.tar centos_web.tar
这样将导出容器快照到本地文件
这样将导出容器快照到本地文件
导入容器:
可使用docker import 从容器快照文件中再导入为镜像
cat centos6.tar | docker import – centos6:test
docker images
[root@localhost ~]# cat centos_web.tar | docker import - centos:web sha256:4429751684b5529cb70ddd080ada1462b3dfe2f48651c02a42c8ebd794a11c7d [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos web 4429751684b5 4 seconds ago 196.7 MB
此外,也能够经过指定 URL 或者某个目录来导入,例如
docker import http://example.com/exampleimage.tgzexample/imagerepo
*注:用户既可使用docker load 来导入镜像存储文件到本地镜像库,也可使用docker import 来导入一个容器快照到本地镜像库。这二者的区别在于容器快照文件将丢弃全部的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时能够从新指定标签等元数据信息。
此外,也能够经过指定 URL 或者某个目录来导入,例如
docker import http://example.com/exampleimage.tgzexample/imagerepo
*注:用户既可使用docker load 来导入镜像存储文件到本地镜像库,也可使用docker import 来导入一个容器快照到本地镜像库。这二者的区别在于容器快照文件将丢弃全部的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时能够从新指定标签等元数据信息。
删除容器
可使用dockerrm来删除一个处于终止状态的容器。
若是要删除一个运行中的容器,能够添加 -f 参数。Docker 会发送SIGKILL信号给容器。
docker rm [容器 id/容器 name]
[root@localhost ~]# docker rm -f 3db07fa904c9 3db07fa904c9
批量删除多个容器
docker rm $(docker ps –a –q)
[root@localhost ~]# docker rm -f $(docker ps -a) 56c3adf740ba e674da52f432 acb16411ba25 eea3221f0dac