Docker入门到实践(上)

    Docker是一个开源的应用容器引擎,开发可以打包自己的应用或者是依赖包上传到可移植的容器里,然后进行发布到任何linux机器上,也可实现虚拟化

    容器是完全使用沙箱机制的,相互之间不会存在任何接口,几乎没有额外的性能开销,很容易的在机器和数据中兴运行,最重要的是不依赖任何语言,框架或者是操作系统

    Docker项目是实现轻量级的操作系统虚拟化解决方案,docker的基础是LXC等技术,在LXC的基础上,docker进行封装,使得用户不用关心容器的管理,操作更加简单;

那么Docker和传统虚拟化(KVM,XEN等)有什么区别吗?

docker是在操作系统层面上实现的虚拟化技术,直接复用本地操作系统,而传统的虚拟化是在硬件基础上的,虚拟出自己的系统,然后再在系统上部署相应的软件服务

【基本概念】

1)镜像(Image)

docker镜像就是一个只读的模板,例如:一个镜像包含一个完整的操作系统环境,里面仅安装了服务应用程序

镜像可以用来创建容器的,docker提供了一个很简单的机制来创建或者更新现有的镜像,用户甚至可以直接从第三方获取已经做好的镜像来使用,

2)容器(Container)

docker利用容器运行应用

容器是从镜像创建的运行实例,可以被启动,停止,删除等操作,每个容器都是相互隔离的,从而实现安全性

可以把容器看作是一个简易版的Linux系统环境(包括root用户权限,进程空间,用户空间,网络空间等)运行在其中的应用程序

Ps:镜像是只读的,容器在运行启动的时候创建了可写层,作为最上层

3)仓库(Repository)

仓库 是集中存放镜像文件的场所,分为公有仓库(Public)和私有仓库(Private)两种形式,

最大的公开仓库是Dcoekr Hub,存放了数量庞大的镜像供用户下载,国内的公开仓库包括Docker Pool等,可以提供大陆用户更稳定快速的访问,当然用户可以在本地网络内创建一个私有仓库。

Ps:docker仓库的概念跟Git类似,注册服务器可以理解为GitHub这样的托管服务

【Docker安装】

# docker search centos    #搜索可用的docker镜像

# docker pull docker.io/centos    #下载镜像

安装docker之后启动docker服务,并设置开机自启

[root@localhost ~]# systemctl start docker 
[root@localhost ~]# chkconfig docker on

 [Docker镜像]

Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,docker会从镜像仓库下载(默认是Docker Hub公共注册服务器中的仓库)

1)获取镜像

可以使用docker pull命令从仓库获取所需要镜像,下载过程中,会输出镜像的每一层信息。

例如:# docker pull docker.io/centos

[root@localhost ~]# docker pull nginx 
Using default tag: latest
Trying to pull repository docker.io/library/nginx ... 
latest: Pulling from docker.io/library/nginx
f2aa67a397c4: Pull complete 
3c091c23e29d: Pull complete 
4a99993b8636: Pull complete 
Digest: sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884
Status: Downloaded newer image for docker.io/nginx:latest

下载完成后,我们可以随时使用该镜像,例如创建一个容器,让其中运行bash应用

[root@localhost ~]# docker run -t -i e934aafc2206 /bin/bash 
[root@4069ed2f1da9 /]#

 2)列出本地镜像

 # docker images 

 

Ps:参数详解:

REPOSITORY:镜像仓库名称

TAG:镜像标记,默认latest

IMAGE ID:镜像ID

CREATE:创建时间

SIZE:镜像大小

3)创建镜像

创建镜像很多种方法,用户可以从docker hub获取已有的镜像并更新,也可以利用本地文件系统创建一个

修改已有的镜像

先试用pull下载的镜像启动容器

[root@localhost ~]# docker run -itd --name Centos7.x e934aafc2206 /bin/bash
ae890b0784421c6ade9dca9fd7e02523a3e1aaf15d211b0d173e417cd2b83942

[root@ae890b078442 /]# yum install -y net-tools httpd httpd-server 

当我们结束后,使用exit提出来之后,容器已经被我们改变了,使用docker commit命令来提交更新后的副本

格式:docker commit   [容器ID]  [目标镜像仓库名:tag信息]

[root@localhost ~]# docker commit  b73ba30f94d0  Centos7.4/web:version1
sha256:6c317c7092f42b5f44f02027738cc4f9fb27806693230afd02f0b66af1803847

ps:docker commit 后面可以加上-m参数,用来指定提交说明信息;-a可以指定更新用户信息;其实这些都可以省略

我们docker images查看新提交的镜像

 #之后再使用这个镜像启动容器,进入到容器里面,我们会发现之前的操作记录都会保存在里面

[root@localhost ~]# docker run -itd --name centoswebserver 6c317c7092f4 /usr/sbin/init /sbin/bash    
0a2b120aaec9297368535074f09d9f274eb98996bdc6837ad59c2666df1de33a

【利用dockerfile来创建镜像】

使用户docker commit来扩展一个镜像比较简单,但是不便于分享,我们可以通过docker build来创建一个新的镜像,但是前提是我们需要创一个dockerfile,包含一些如何创建镜像的指令

Dockerfile基本语法是:

*使用#注释

*FROM指令告诉docker使用哪个镜像作为基础

*接着是维护者信息

*RUN开头的指令会在创建中运行,比如说安装一个软件包,在这里使用apt-get来安装了一些软件

编写dockerfile后可以使用docker build来生成镜像

[root@localhost ~]# vim dockerfile 

FROM docker.io/centos:latest
MAINTAINER hexunbixiaoyu
RUN yum install -y pcre-devel openssl-devel
RUN yum install -y httpd httpd-devel httpd-server
RUN echo "This is hexun.com" >> /var/www/html/index.html
EXPOSE 80
CMD ["/usr/sbin/apachectl","-D "FOREGROUD"]

[root@localhost ~]# docker build -t="docker.io/centos"  .

PS:其中-t标记来添加tag,指定新的景象用户信息、“.”时候dpclerfile所在的路径(当前目录)也可以替换为一个具体的dockerfile路径

执行的过程中我们可以看到build进程在执行操作,要做的第一件事情就是上传dockerfile内容,因为所有的操作都要一句dockerfile来进行,然后dockerfile中的指令被一条一条的执行,每一步都创建一个新的容器,在容器中执行指令并提交修改(这一点和之前介绍的docker cimmit一样)当所有的指令都执行完毕之后 ,返回最终的镜像ID,所有的中间步骤所产生的容器都被删除和清理;

Ps:注意一个镜像不能超过127层

此外还可以利用ADD命令赋值本地文件到镜像,用EXPOSE命令来向外开放端口 ,用CMD命令来描述容器启动后台运行的程序等

还可以用docker tag 命令来修改镜像标签名称

# docker tag ce1247d52651 docker.io/centos:Version 

【从本地文件系统导入 】

要从本地系文件系统导入一个镜像,可以使用openvz(容器须奴话先锋技术)的模板来创建;openvz的模板下载地址为https://openvz.org/Download/templates/precreated

 #cat centos-7-x86_64-minimal.tar.gz | docker import - centos7:7.33

上传镜像

用户可以通过docker push命令,把自己创建的镜像上传到仓库中来共享.例如:将做好的镜像上传到自己的docker hub仓库中

上传docker hub镜像需注意其过程:

自定义镜像之是存在本地images列表的

1:登陆docker hub:docker login

2:修改需要上传的镜像标签tag:docker tag <imageID> <namespace>/<image name>:<version tag>

3:开始上传:docker push <namespace>/<image name>:<version tag>

# docker push  bixiaoyu/dockercentos:1.1

下载镜像docker pull <nemaspace>/<image name>:<version tag>

# docker pull bixiaoyu/dockercentos:1.1

 [存出和载入镜像]

如果要导出镜像到本地文件,可以使用docker save 命令 

格式:docker save -o  <镜像最新名称> <REPOSITOR>

# docker save -o centos.tar centos/docker:version2

# 载入镜像

可以使用docker load 从导出的本地文件中在导入到本地镜像;这将导入镜像以及其相关的元数据信息(包括标签等)

# docker load --input centos.tar 

或者

docker load < centos.tar 

镜像的实现原理】

Docke镜像是如何实现增量的修改和维护呢?每个镜像都有很多层次的构成,docker使用union FS将这些不同的层集合到一个镜像中

PS:通常Union FS有两个用途,一方面可以实现不借助LVM,RAID将多个disk挂载到同一个目录下,另一个更常用的就是将一个制度的分支和一个可写的分支联合在一起,Live CD正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作,Docker在AUFS上构建的容器也就是利用了类似的原理

【Docker容器】

容器是docker又一核心概念

简单的是独立运行的一个或一组应用,以及它们的运行状态环境,对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行状态环境和其他系统环境 )和跑在上面的应用

当利用docker run来创建容器时,docker在后台运行的标准操作包括:

#检查本地是否存在指定的镜像,不存在就从公有仓库下载

#利用镜像创建并启动一个容器

#分配一个文件系统,并在只读的镜像层外面在封装一层读写层

#从宿主机配置的网桥接口中关联一个虚拟接口到容器中去

#从地址池配置一个IP地址给容器

#执行用户指定的容器

#执行完毕后容器被终止

当我们docker start命令将已经终止的容器启动运行,我们会发现容器的核心为所执行的应用程序,所需要的资源都是应用程序运行必须的,除此之外,我们可以进入容器,利用ps或者top来查看一下进程信息;可见,容器仅仅是运行了指定的bash应用,这种特点,对docker资源利用非常高 ,是真正意义上的轻量级虚拟化

要获取docker容器启动输出信息,可以通过docler logs 命令来输出

【导出和导入容器】

导出容器

[root@www-jfedu-net ~]# docker export b54d8cc3a14c > version.tar

 这样将导出的容器快照到本地文件

导入容器快照

可以使用docker import从容器快照文件中再导入为镜像,例如

# cat version.tar | docker import - version2
sha256:d7d484184868990927f83fe4ace8ce7c0f55d14bcf7ed3ec479d7357e2aff2f6

 Ps:用户既可以使用docker load来导入镜像存储文件到本地images镜像库,也可以使用docker import 来导入一个容器快照到本地镜像库,这两者区别在于容器快照文件将丢失所有的历史记录和元数据信息(只保存容器当时的快照状态)而镜像存储文件将保存完整的记录,体积也大,此外,从容器快照文件导入时可以重新指定标签等元数据信息;

[Docker网络通信]

基于Docker run创建的docker容器时,可以使用--net选项指定容器的的网络模式,Docker默认有一下四种网络模式:

host模式:使用--net=host指定;

container模式:使用--net=container:NAME或者ID指定

none模式,使用--net=none指定

bridge模式,使用--net=bridge指定,默认设置;

1)Host模式:

默认docker容器运行会分配独立的network Namespace隔离子系统,基于host模式,容器将不会获得独立的Network Namespace,而是和宿主机共用一个network namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口

2)Container模式详解:

container模式指定新建的容器与容器之间共享network namespace,而不是和宿主机共享,也就是说新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP和端口范围。同样两个容器除了网络方面相同之外,其他的如文件系统,进程列表还是隔离的,

3)None模式详解

None模式与其他模式都不同,如果处于None模式,docker容器拥有自己的network Namespace,但是并不为docker容器进行任何网络配置,也就是说None模式下容器没有任何网路配置,包括网卡IP,路由信息,需要手工为docker容器添加网卡,配置IP等,典型的pipework工具为docker容器指定IP等信息;

4)Bridge桥接模式

Bridge模式是docker默认的网络模式,该模式会为每一个docker容器分配network namespace,设置IP,路由等配置,默认会将docker容器连接到一个虚拟网桥交换Docker0上

image.png

猜你喜欢

转载自blog.51cto.com/11880730/2114564