什么是容器?
先来看看容器较为官方的解释:
一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。
再来看看容器较为通俗的解释:
如果需要通俗的描述容器的话,我觉得容器就是一个存放东西的地方,就像书包可以装各种文具、衣柜可以放各种衣服、鞋架可以放各种鞋子一样。我们现在所说的容器存放的东西可能更偏向于应用比如网站、程序甚至是系统环境。
镜像(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命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。
[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
//下载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时,则会彻底删除整个镜像,所有标签也会一同删除
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
我们可以到这个网站下载镜像: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 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
[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
[root@localhost ~]# curl 192.168.139.135:5000/v2/_catalog
{"repositories":["centos"]}