1.Docker介绍
1.1 先从认识容器开始
什么是容器?
先来看看容器较为官方的解释:
一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。
- 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
- 容器化软件适用于基于Linux和Windows的应用,在任何环境中都能够始终如一地运行。
- 容器赋予了软件独立性,使其免受外在环境差异(例如,开发和预演环境的差异)的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。
再来看看容器较为通俗的解释:
如果需要通俗的描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。
1.2 什么是Docker
- 官网 www.docker.com github https://github.com/docker/docker.github.io 开源的容器引擎,可以让开发者打包应用以及依赖的库,然后发布到任何流行的linux发行版上,移植很方便
- Docker是世界领先的软件容器平台。
- Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。Docke最初实现是基于LXC。
- Docker能够自动执行重复性任务,例如搭建和配置开发环境,从而解放了开发人员以便他们专注在真正重要的事情上:构建杰出的软件。
- 用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
- docker从1.13x开始,版本分为社区版ce和企业版ee,并且基于年月的时间线形式,当前最新稳定版为17.09
1.3 Docker的优势
- 启动非常快,秒级实现 资源利用率高,一台高配置服务器可以跑上千个docker容器
- 更快的交付和部署,一次创建和配置后,可以在任意地方运行 内核级别的虚拟化,不需要额外的hypevisor支持,会有更高的性能和效率 易
- 迁移,平台依赖性不强
1.4Docker核心概念
镜像(Image)——一个特殊的文件系统
操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。 镜像不包含任何动态数据,其内容在构建之后也不会被改变。
Docker设计时,就充分利用Union FS的技术,将其设计为分层存储的架构。 镜像实际是由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
容器(Container)——镜像运行时的实体
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等 。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。前面讲过镜像使用的是分层存储,容器也是如此。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照Docker最佳实践的要求,容器不应该向其存储层内写入任何数据 ,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此, 使用数据卷后,容器可以随意删除、重新run,数据却不会丢失。
仓库(Repository)——集中存放镜像文件的地方
镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。所以说:镜像仓库是Docker用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认标签。
这里补充一下Docker Registry公开服务和私有Docker Registry的概念:
Docker Registry公开服务是开放给用户使用、允许用户管理镜像的Registry服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的Registry公开服务是官方的Docker Hub ,这也是默认的Registry,并拥有大量的高质量的官方镜像,网址为:hub.docker.com/ 。在国内访问Docker Hub可能会比较慢国内也有一些云服务商提供类似于Docker Hub的公开服务。
除了使用公开服务外,用户还可以在本地搭建私有Docker Registry 。Docker官方提供了Docker Registry镜像,可以直接使用做为私有Registry服务。开源的Docker Registry镜像只提供了Docker Registry API的服务端实现,足以支持Docker命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。
2.Docker安装
[root@localhost ~]# curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2424 100 2424 0 0 3612 0 --:--:-- --:--:-- --:--:-- 3612
[root@localhost ~]# ls
anaconda-ks.cfg
[root@localhost ~]# yum install docker
Loaded plugins: fastestmirror
Determining fastest mirrors
epel/x86_64/metalink | 5.6 kB 00:00:00
* base: mirror.vpshosting.com.hk
* epel: mirror.pregi.net
* extras: mirror.vpshosting.com.hk
* updates: mirror.vpshosting.com.hk
base | 3.6 kB 00:00:00
docker-ce-stable | 3.5 kB 00:00:00
epel | 3.2 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
(1/6): docker-ce-stable/x86_64/updateinfo | 55 B 00:00:00
epel/x86_64/primary FAILED
启动docker
[root@localhost ~]# systemctl start docker
[root@localhost ~]# ps aux |grep docker
root 1467 1.0 2.5 563876 25376 ? Ssl 23:43 0:00 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2
root 1471 0.0 0.7 263856 7288 ? Ssl 23:43 0:00 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
root 1554 0.0 0.0 112704 960 pts/0 R+ 23:43 0:00 grep --color=auto docker
3. Docker镜像管理
//下载docker镜像
[root@localhost ~]# docker pull centos
//如果下载很慢可以配置加速器
vi /etc/docker/daemon.json//加入如下内容
{
"registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"]
}
说明:这个url为加速器地址,需要同学们自行到阿里云申请 配置完加速器,重启docker服务,再次docker pull centos会快很多
//查看本地的镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/centos latest 75835a67d134 7 weeks ago 200 MB
docker search xxx //搜索镜像,其中xxx是关键词
[root@localhost ~]# docker search ubuntun
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/matriphe/ubuntunginxphp Ubuntu 14.04.1 (phusion/baseimage-docker) ... 1 [OK]
docker.io docker.io/adrianeguez/ubuntunode ubuntunode 0
docker.io docker.io/aravindgan/ubuntunodeag 0
docker.io docker.io/bordet/ubuntunano 0
docker.io docker.io/ddmsnsysu/ubuntunginx
docker tag centos knightlai //给镜像打标签
[root@localhost ~]# docker tag centos knightlia
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
knightlia latest 75835a67d134 7 weeks ago 200 MB
docker.io/centos latest 75835a67d134 7 weeks ago 200 MB
docker run -itd centos //把镜像启动为容器,-i表示让容器的标准输入打开,-t表示分配一个伪终端,-d表示后台启动,要把-i -t -d 放到镜像名字前面
[root@localhost ~]# docker run -itd centos
b91248c025fc5268903dd6443367813324102af977acb749afa852a925e98005
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b91248c025fc centos "/bin/bash" 18 seconds ago Up 16 seconds elated_curie
docker rmi centos //用来删除指定镜像, 其中后面的参数可以是tag,如果是tag时,实际上是删除该tag。当后面的参数为镜像ID时,则会彻底删除整个镜像,所有标签也会一同删除
4.Docker通过容器创建镜像
docker run启动容器后,可以通过下面命令进入容器
//其中xxxxx为容器id,这个id可以用docker ps查看,最后面的bash为进入容器后我们要执行的命令,这样就可以打开一个终端
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b91248c025fc centos "/bin/bash" 3 minutes ago Up 3 minutes elated_curie
[root@localhost ~]# docker exec -it b91248 bash
[root@b91248c025fc /]# ls
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr
进入到该容器中,我们做一些变更,比如安装一些东西,然后针对这个容器进行创建新的镜像
在容器中执行 yum install -y net-tools,然后ctrl d退出容器
[root@b91248c025fc /]# yum install -y net-tools
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirror.vpshosting.com.hk
* extras: mirror.vpshosting.com.hk
* updates: mirror.vpshosting.com.hk
base | 3.6 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
.......................................................................................
docker commit -m "change somth" -a "somebody info" container_id new_image_name //container_id通过docker ps -a获取,后面的new_image_name为新镜像名字
[root@localhost ~]# docker commit -m "install net-tools" -a "test" b91248c025fc centos_with_nettool
sha256:d010d5769e4f0a66501f006eb5197f61f64eaed3eda86089d3606696f90be787
这个命令有点像svn的提交,-m 加一些改动信息,-a 指定作者相关信息 2c74d这一串为容器id,再后面为新镜像的名字
//我们可以查看刚刚提交上来的centos_with_nettool镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_with_nettool latest d010d5769e4f About a minute ago 300 MB
docker.io/centos latest 75835a67d134 7 weeks ago 200 MB
knightlia latest 75835a67d134 7 weeks ago 200 MB
5.Docker使用模板创建镜像
我们可以到这个网站下载镜像:http://openvz.org/Download/templates/precreated
导入该镜像的命令为:cat centos-7-x86_64-minimal.tar.gz|docker import - centos7
[root@localhost ~]# cat centos-7-x86_64-minimal.tar.gz|docker import - centos7
sha256:0e037beb491d18db28cfa0ff20855106925a60058908aef350b6effdf90e0c1f
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7 latest 0e037beb491d 48 seconds ago 435 MB
centos_with_nettool latest d010d5769e4f 17 minutes ago 300 MB
docker.io/centos latest 75835a67d134 7 weeks ago 200 MB
knightlia latest 75835a67d134 7 weeks ago 200 MB
- 把现有镜像,导出为一个文件: docker save -o aming-centos.tar test
- 我们还可以用该文件恢复本地镜像: docker load --input aming-centos.tar 或者 docker load < aming-centos.tar
6.Docker容器管理
- docker create -it centos6 bash //这样可以创建一个容器,但该容器并没有启动
- docker start container_id //启动容器后,可以使用 docker ps 查看到,有start 就有stop,和restart 之前
- 我们使用的docker run 相当于先create再start
- docker run -it centos bash 这样进入了一个虚拟终端里面,我们可以运行一些命令,使用命令exit或者ctrl d 退出该bash,当退出后这个容器也会停止。
- docker run -d 可以让容器在后台运行比如:docker run -d centos bash -c "while :; do echo "123"; sleep 2; done"
- docker run --name web -itd centos bash // --name 给容器自定义名字
- docker run --rm -it centos bash -c "sleep 30" //--rm 可以让容器退出后直接删除,在这里命令执行完容器就会退出
- docker logs 可以获取到容器的运行历史信息,
- 用法如下 docker logs container_id docker attach
- 可以进入一个后台运行的容器,比如 docker attach container_id //但是attach命令不算好用,比如我们想要退出终端,就得exit了,这样容器也就退出了,
- 还有一种方法 docker exec -it container_id bash //可以临时打开一个虚拟终端,并且exit后,容器依然运行着
- docker rm container_id //container_id是ps的时候查看到的,这样就可以把container删除,如果是运行的容器,可以加-f docker export container_id > file.tar // 导出容器,
- 可以迁移到其他机器上,需要导入 cat file.tar |docker import - aming_test //这样会生成aming_test的镜像
7.Docker仓库管理
docker pull registry //下载registry 镜像,registy为docker官方提供的一个镜像,我们可以用它来创建本地的docker私有仓库。
[root@localhost ~]# docker pull registry
Using default tag: latest
Trying to pull repository docker.io/library/registry ...
latest: Pulling from docker.io/library/registry
d6a5679aa3cf: Pull complete
ad0eac849f8f: Pull complete
2261ba058a15: Pull complete
f296fda86f10: Pull complete
bcd4a541795b: Pull complete
Digest: sha256:5a156ff125e5a12ac7fdec2b90b7e2ae5120fa249cf62248337b6d04abc574c8
Status: Downloaded newer image for docker.io/registry:latest
docker run -d -p 5000:5000 registry //以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口
[root@localhost ~]# docker run -d -p 5000:5000 registry
e161b8bb48748e2f2a8683d326e250064620dfc32c5973109533b0b1fbba5b6d
//以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口
curl 127.0.0.1:5000/v2/_catalog //可以访问本地的私有云仓库
[root@localhost ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":[]}
//此时我们的仓库没有任何镜像
我们上传一个镜像到我们的私有云仓库首先要docker tag 0e037beb491d 192.168.139.135:5000/centos
[root@localhost ~]# docker tag 0e037beb491d 192.168.139.135:5000/centos
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7 latest 0e037beb491d 46 minutes ago 435 MB
centos latest 0e037beb491d 46 minutes ago 435 MB
192.168.139.135:5000/centos latest 0e037beb491d 46 minutes ago 435 MB
centos_with_nettool latest d010d5769e4f About an hour ago 300 MB
docker.io/centos latest 75835a67d134 7 weeks ago 200 MB
knightlia latest 75835a67d134 7 weeks ago 200 MB
docker.io/registry latest 2e2f252f3c88 2 months ago 33.3 MB
- docker push 192.168.139.135:5000/centos //将镜像上传到本地的私有云上
[root@localhost ~]# docker push 192.168.139.135:5000/centos
The push refers to a repository [192.168.139.135:5000/centos]
788edba9eaa8: Pushed
latest: digest: sha256:2f788c4abc6156f1a62ac8201d6f04a0bb6be66593533ea5ccc0e3a5d8fed232 size: 529
- curl 192.168.139.135:5000/v2/_catalog //可以查看到推送上来的镜像
[root@localhost ~]# curl 192.168.139.135:5000/v2/_catalog
{"repositories":["centos"]}
8.Docker数据管理
- 1. 挂载本地的目录到容器里 docker run -tid -v /data/:/data centos bash //-v 用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动创建
- 2. 挂载数据卷 其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如上面我们没有指定,它就生成了一个名字为relaxed_franklin,这个名字可以使用命令 docker ps 看最右侧一列
- docker run -itd --volumes-from relaxed_franklin aming123 bash 这样,我们使用aming123镜像创建了新的容器,并且使用了 relaxed_franklin 容器的数据卷
- 3. 定义数据卷容器 有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
- 首先建立数据卷容器 docker run -itd -v /data/ --name testvol centos bash //注意这里的/data/是容器的/data目录,并非本地的/data/目录。
- 然后让其他容器挂载该数据卷 docker run -itd --volumes-from testvol aming123 bash
9.Docker数据卷的备份与恢复
- 备份
- mkdir /data/backup
- docker run --volumes-from testvol -v /data/backup/:/backup centos tar cvf /backup/data.tar /data/
- 说明:首先我们需要使用testvol数据卷新开一个容器,同时我们还需要把本地的/vol_data_backup/目录挂载到该容器的/backup下,这样在容器中/backup目录里面新建的文件,我们就可以直接在/data/backup/目录中看到了。 然后再把/data/目录下面的文件打包到成data.tar文件放到/backup目录下面。
- 恢复 思路: 先新建一个数据卷容器,再建一个新的容器并挂载该数据卷容器,然后再把tar包解包。
- 新建数据卷容器:docker run -itd -v /data/ --name testvol2 centos bash
- 挂载数据卷新建容器,并解包:docker run --volumes-from testvol2 -v /data/backup/:/backup centos tar xf /backup/data.tar