赞
踩
docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的cgroup,namespace,以及AUFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术
由于隔离的进程独立于宿主和其它的隔离进程,因此也称为容器
Docker从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。
使得Docker技术比虚拟机技术更为轻便、快捷。
虚拟机:可以理解为模拟运行的一整套操作系统(提供了运行态环境、其他系统环境)和跑在上面的应用。
传统虚拟机:是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行应用进程
容器:容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
1、更高效的利用系统资源
2、更快速的启动时间
3、一致的运行环境
4、持续交付和部署
5、更轻松的迁移
6、更轻松的维护和扩展
特性 | 容器 | 虚拟机 |
---|---|---|
特性 | 秒级 | 分钟级 |
硬盘使用 | MB | GB |
性能 | 接近原生 | 较弱 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
由客户端(Clients)、主机(Host)和仓库(Registries)三部分组成
Docker使用客户端-服务器(C/S)架构模式,使用远程API来管理和创建Docker容器。
Docker machine:简化版的命令行工具
操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含一些为运行时准备的一些配置参数(如:匿名卷、环境变量、用户等)
镜像不包含任何动态数据,其内容在构建之后也不会改变。
因为镜像包含操作系统完整的root文件系统,其体积往往是庞大的,因此在Docker设计时将其设计为分层存储的架构。镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何 改变只发生在自己这一层。在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西, 任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为 基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
镜像(Image)和容器(Container)的关系,就像Java中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
镜像使用分层存储,容器也一样。容器运行时,是以镜像为基础创建一个当前容器的存储层,把这个为容器运行时读写而准备的存储层为容器存储层
生命周期:容器存储层的生存周期和容器一样,所以存储层的信息都会随容器删除而丢失。
容器不应该向其存储层內写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 Volume数据卷、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失
仓库概念:镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。
特性: 一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
标签:通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过<仓库名:标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认标签。
以 centos镜像为例, centos是仓库的名字,其内包含有不同的版本标签,如,6.9、7.5。我们可以通过cenηtos:6.9,或者 centos:7.5来具体指定所需哪个版本的镜像。如果忽略了标签,比如 centos,那将视为 centos: c latest。
仓库名经常以两段式路径形式出现,比如 study/ ngInx,前者往往意味着 Docker Registry多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 DockerRegistry的软件或服务。
常用的 Registry是官方的 Docker hub,这也是默认的 Registry。除此以外,还有 Cores的 Quay.io,
Cores相关的镜像存储在这里; Google的 Google Container Registry, Kubernetes的镜像使用的就
是这个服务。
国內的一些云服务商提供了针对 Docker hub的镜像服务,这些镜像服务被称为加速器。常见的有阿里
云加速器、 Daocloud加速器等。使用加速器会直接从国内的地址下载 Docker hub的镜像,比直接从
Docker hub下载速度会提高很多。
国内也有一些云服务商提供类似于 Docker hub的公开服务。比如网易云镜像服务、
Daocloud镜像市场、阿里云镜像库等。
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry.。 Docker官方提供了
Docker Registry镜像,可以直接使用做为私有 Registry服务。
开源的 Docker Registry镜像只提供了 Docker Registry AP的服务端实现,足以支持 docker命令,不
影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本
Docker Trusted Registry中,提供了这些高级功能。
除了官方的 Docker Registry外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以
及一些高级功能。比如, VMWare harbor和 Sonatype Nexus
Docker在1.13版本之后,从2017年的3月1日开始,版本命名规则变为如下:
项目 | 说明 |
---|---|
版本格式 | YY.MM |
Stabel版本 | 每个季度发行 |
Edge版本 | 每个月发行 |
同时Docker划分为CE和EE:
版本 | 说明 | 收费 |
---|---|---|
CE社区版 | 支持周期3个月 | 免费 |
EE企业版 | 强调安全 | 付费 |
官方安装指南地址:https://docs.docker.com/engine/installation
Docker CE支持64位版本CentOS 7,并且要求内核版本不低于3.10。
旧版本的Docker称为docker或者docker-engine,使用以下命令卸载旧版本
sudo yum remove docker docker-common docker-selinux docker-engine
sudo yum install docker-ce
1、查看内核版本:
uname -r
2、卸载旧版本:
sudo yum remove docker
3、安装:
yum install docker-ce
注意:如果安装的是centos7 minimal版本,执行安装会有如下提示,“没有可用软件包”,No package docker-ce available.Error: Nothing to do
这个时候需要安装必要的软件依赖及更新增加docker-ce yum源。
1、安装依赖:sudo yum install -y yum-utils device-mapper-persistent-data lvm2
2、加载docker-ce的yum源:sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
3、再执行安装命令:yum install docker-ce
4、启动Docker:systemctl start docker
5、查看Docker启动信息:docker info
6、启动一个基于hello-world镜像的容器:docker run hello-world
若能正常输出Hello from Docker!等信息,则说明安装成功。
在测试或开发环境中Docker官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS系统上可以使用这套脚本安装:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把Docker CE的Edge版本安装在系统中。
设置开启启动:
sudo systemctl enable docker
sudo systemctl start docker
默认情况下,docker命令会使用Unix socket与Docker引擎通讯
而只有root用户和docker组的用户才可以访问Docker引擎的Unix socket
一般Linux系统上不会直接使用root用户进行操作
因此,需要将使用docker的用户加入docker用户组
建立docker组:
sudo systemctl start docker
将当前用户加入docker组:
sudo usermod -aG docker $USER
启动一个基于hello-world镜像的容器:
docker run hello-world
1、删除docker安装包:
sudo yum remove docker-ce
2、删除docker镜像:
sudo rm rf /var/lib/docker
国内从Docker Hub拉取镜像有时会遇到困难,此时可以配置镜像加速器
Docker官方和国内很多云服务商都提供了国内加速器服务
例如:
1、Docker官方提供的中国registry mirror
2、阿里云加速器
3、DaoCloud加速器
4、163加速器
默认的镜像拉取地址可以通过docker info命令查看,
默认的镜像拉取地址: https://index.docker.io/v1/(这个地址有的时候是比较慢的)
对于使用systemd的系统,请在/etc/docker/daemon.json中写入如下内容(如果文件不存在请新建该文件)
{
"registry-mirrors":["http://hub-mirror.c.163.com","http://f1361db2.m.daocloud.io"]
}
重新启动服务生效
先让daemon生效:
sudo systemctl daemon-reload
再重启docker:
sudo systemctl restart docker
列出所有容器:
docker ps -a
删除docker容器:
docker rm -f 容器ID
删除容器:
docker rmi hello-world
配置加速器之后,如果拉取镜像仍然十分缓慢,请手动检查加速器配置是否生效,在命令行执行
docker info
如果从结果中看到
Registry Mirrors:http://hub-mirror.c.163.com
说明配置成功。
docker运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,docker会从镜像仓库下载该镜像。
从docker镜像仓库获取镜像的命令是docker pull。
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
具体的选项可以通过docker pull --help命令看到;
Docker镜像仓库地址:地址的格式一般是<域名/IP>[:端口号]。默认地址是Docker Hub。
仓库名:如之前所说,这里的仓库名是两段式名称:<用户名>/<软件名>。
对于Docker Hub,如果不给出用户名,则默认为library,也就是官方镜像:
docker pull ubuntu:16.04
上面没有给出Docker镜像仓库地址,则从Docker Hub获取镜像,镜像名称为ubuntu:16.04,没有用户名,则从library/ubuntu仓库中获取标签为16.04的镜像。
有了镜像后,就能够以这个镜像为基础启动并运行一个容器。
以上面的ubuntu:16.04为例,如果打算启动里面的bash并且进行交互式操作的话,可以执行下面的命令
docker run -it --rm ubuntu:16.04 bash
-it:这是两个参数,一个是-i:交互式操作,一个是-t终端。
–rm:这个参数是说容器退出后随之将其删除。
ubuntu:16.04:这是指用ubuntu:16.04镜像为基础来启动容器。
bash:放在镜像名后的是命令,这里我们希望有个交互式Shell,因此用的是bash
最后通过exit退出容器
docker image ls 或 docker images
列表的分别是:仓库名、标签、镜像ID、创建时间、所占空间大小
docker system df
仓库名、标签均为的镜像,称为虚悬镜像(dangling image)
docker image ls -f dangling=true
一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。
docker image prune
创建一个Dockerfile文件: touch Dockerfile
编辑Dockerfile文件:vim Dockerfile
文件如下:
FROM ubuntu:16.04
CMD echo "study.163.com"
构建一个虚悬镜像:docker build .
1、如果要删除本地的镜像,可以使用docker image rm命令
其格式为:docker image rm [选项] <镜像1> [<镜像2>...]
其中,<镜像>可以是镜像短ID、镜像长ID、镜像名 或者 镜像摘要
2、使用docker image ls -q 来配合docker image rm,这样可以批量删除想要删除的镜像。
删除所有仓库名为ubuntu的镜像:docker image rm $(docker image ls -q ubuntu)
3、或者删除所有在ubuntu:16.04之前的镜像
docker image rm $(docker image ls -q -f before=ubuntu:16.04)
4、删除所有镜像:docker image rm $(docker image ls -q)
如果镜像存在容器,是不能删除的
因为Docker的容器是轻量级的,用户可以随时删除和新创建容器 方式一:基于镜像新建一个容器并启动 1、新建并启动【docker run】 输出一个 “Hello World”,之后终止容器:docker run ubuntu:16.04 /bin/echo 'Hello World' 方式二:启动已终止容器(将在终止状态(stopped)的容器重新启动) docker container start(或者docker start) 启动一个bash终端,允许用户进行交互: docker run -t -i ubuntun:16.04 /bin/bash(等价于:docker run -it ubuntu:16.04 bash) -t:让docker分配一个伪终端并绑定到容器的标准输入上 -i:让容器的标准输入保持打开 当利用docker run 来创建容器时,docker在后台运行的标准操作包括: 1、检查本地是否存在指定的镜像,不存在就从公有仓库下载 2、利用镜像创建并启动一个容器 3、分配一个文件系统,并在只读的镜像层外面挂载一层可读写层 4、从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 5、从地址池配置一个ip地址给容器 6、执行用户指定的应用程序 7、执行完毕后容器被终止
如果不使用-d参数运行容器,eg:docker run hello-world会把日志打印在控制台;
如果使用了-d参数运行容器,eg:docker run -d hello-world不会输出日志,只会打印容器id(输出结果可以用docker logs <容器id>查看);
注:容器是否会长久运行,是和docker run指定的命令有关,和-d参数无关。
终止运行中的容器:docker container stop 容器ID
查看终止状态的容器:docker container ls -a 容器ID
重启终止状态的容器:docker container start 容器ID
重启一个运行态的容器:docker container restart 容器ID
docker exec后边可以跟多个参数
只用-i时:由于没有分配伪终端,界面没有我们熟悉的Linux命令提示符,但命令执行结果仍然可以返回。
-i -t一起使用时:可以看到我们熟悉的Linux 命令提示符。
docker exec -it 容器ID /bin/bash
导出本地某个容器:docker export 容器ID > 导出文件名.tar
1、从容器快照文件导入为镜像:
cat 导出文件名.tar | docker import - 镜像用户/镜像名:镜像版本
eg:cat test_export_docker_1.tar | docker import - study/ubuntu:1.0
2、也可以通过指定URL或者某个目录来导入:
docker import http://study.163.com/image.tgz example/imagerepo
1、删除一个处于终止状态的容器:docker container rm ubuntu:16.04
如果要删除一个运行中的容器,可以添加-f参数。Docker会发送SIGKILL信号给容器。
2、删除所有终止状态的容器:docker container prune
1、镜像的定制实际上就是定制每一层所添加的配置、文件。
2、我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,这个脚本就是Dockerfile。
Dockerfile:是一个文本文件,包含一条条指令,每一条指令构建一层,
因此每一条指令的内容,就是描述该层应当如何构建。
定制一个nginx镜像:
1、创建目录:mkdir mynginx
2、进入目录:cd mynginx
3、创建一个Dockerfile文件:touch Dockerfile
4、编辑Dockerfile文件:vim Dockerfile
文件内容如下:
FROM nginx
RUN echo ‘Hello,Docker!’ > /usr/share/nginx/html/index.html #将Hello,Docker!写入index.html中
所谓定制镜像,一定是以一个镜像为基础,在其上进行定制。
基础镜像必须指定,并且必须是Dockerfile中的第一条指令。
Docker Hub有很多高质量的官方镜像,eg:nginx、redis、mysql、tomcat等。
Docker Hub还提供了基础操作系统镜像,eg:ubuntun、centos等
Docker Hub还存在一个特殊的镜像:scratch
这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
如果以scrach为基础镜像的话,意味着不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
RUN指令是用来执行命令行 命令的。
RUN指令的两种格式:
shell格式:RUN <命令>
eg:RUN echo '<hl>Hello,Docker!</h1>' > /usr/share/nginx/html/index.html
exec格式:RUN ["可执行文件","参数1","参数2"]
解压文件:RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
编译:RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install
每一个RUN都是启动一个容器、执行命令、然后提交存储层文件变更
在Dockerfile文件所在目录执行:docker build -t mynginx:1.0 .
格式:COPY <源路径>...<目标路径>
COPY ["<源路径1>",..."<目标路径>"]
eg:COPY package.json /usr/src/app
源路径可以是多个,甚至可以是通配符
eg:COPY hom* /mydir/
COPY hom?.txt /mydir/
在COPY和ADD指令选择时,可遵循这样的原则:
所有的文件复制均使用COPY,仅在需要自动解压缩的场合使用ADD
CMD指令的两种格式:
shell格式:CMD <命令>
exec格式:CMD ["可执行文件","参数1","参数2"]
在指定了ENTRYPOINT指令后,再用CMD指定具体参数
CMD指令就是永远指定默认的容器主进程启动命令的。
ENTRYPOINT的目的和CMD一样。
当指定了ENTRYPOINT后,CMD的含义就发生了改变,不再是直接的运行其命令,而是将CMD的内容作为参数传给ENTRYPOINT指令
变为:<ENTRYPOINT> "<CMD>"
两种格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
eg:设置环境变量:ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"
使用环境变量:$VERSION
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。