关于docker
- 一、基本概念
- 什么是docker?
- docker组件:
- 我们能用docker做什么
- Docker与配置管理:
- Docker的技术组件
- Docker资源
- Docker与虚拟机对比
- 二、安装docker
- 三、镜像命令
- 启动命令
- 帮助命令
- 列出本地主机上的镜像
- 在远程仓库中搜索镜像
- 查看占据的空间
- 删除镜像
- 下载镜像
- 四、容器命令
- 启动容器
- 交互模式启动容器
- 列出正在运行的容器
- 日志-运行进程-内部细节
- 启动停止重启容器
- 删除容器
- 启动守护式容器
- 进入正在运行的容器
- 五、容器数据卷
- 六、下载加速配置
- 七、搭建docker私有仓库(Registry)
- 八、Dockerfile
- 九、虚悬镜像
一、基本概念
什么是docker?
Docker是一个能把开发的应用程序自动部署到容器的开源引擎。由docker公司团队编写,基于Apache2.0开源授权协议发行。
docker职责的逻辑分离,使用docker,开发人员只需要关心容器中运行的应用程序,运维人员只需要关心如何管理容器。docker设计目的之一就是加强开发人员写代码的开发环境和应用程序要部署的生成环境的一致性,从而降低”开发时以切正常,肯定是运维的问题“的风险。
docker具有快速、高效的开发生命周期,它能缩短代码从开发、测试到部署、上线运行的周期,让应用程序具备可移植性,易于构建,并易于协作。
docker鼓励面向服务的架构,docker推荐单个容器只运行一个应用程序,这样可形成分布式的应用程序模型。在这种模型下,应用程序或服务可表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序变得非常简单,同时提高了程序的内省性。(当然也可一个容器运行多个进程的应用程序)
docker组件:
docker客户端和服务器;
docker镜像;
Registry;
docker容器。
dokcer客户端和服务器:
docker是采用(C/S)架构程序,客户端只需要向docker服务器或守护进程发出请求,服务器和守护进程将完成所有工作并返回结果。
docker镜像:
镜像是docker世界的基石,用户基于镜像来运行自己的容器,镜像也是dokcer生命周期中的构建部分,镜像是基于联合文件系统的一种层式的结构,有一系列指令一步一步构建出来。例如:
添加一个文件
执行一个命令
打开一个端口
也可以把镜像当作容器的"源代码",镜像体积很小,易于分享、存储和更新。
Rigistry:
docker用Rigistry来保存用户构建的镜像,Registry分公共和私有两种,docker公司运营的公共Registry叫Docker Hub,用户也可以在docker Hub注册账号,分享并保存自己的镜像。有些私有镜像包含有源代码或专利信息等,或者只在组织、团队内部可见的镜像。也可以架设自己的私有Rigistry,私有Rigistry可受到防火墙的保护,满足一些组织的特殊需求。
容器:
容器是基于镜像启动起来的,容器中可以运行一个或多个进程。docker可以帮助你构建和部署容器,只需要把应用程序或服务打包放进容器即可。我们可以认为,镜像是docker生命周期中构建或打包阶段,而容器则是启动或执行阶段。总结起来,docker容器就是:
一个镜像格式;
一系列标准的操作;
一个执行环境
docker借鉴了标准集装箱的概念,标准集装箱将货物运往世界各地,docker将这个模型运用到自己的设计哲学中,唯一不同是,集装箱运输货物,而docker运输软件。
每个容器都包含一个软件镜像,也就是容器的"货物",与真正 的货物一样,容器里的软件镜像可以进行一些操作,例如:镜像可以被创建、启动、关闭、重启以及销毁。docker执行上述操作时,不关心里面有什么,不管是web服务器,还是数据库,或者应用服务器,所有容器都按照相同的方式将内容"装载"进去。
docker不关心你要把容器运到何方,可以在笔记本构建容器,上传到Rigistry,然后找个物理或虚拟服务器测试,再把容器部署到主机集群中去。像标准集装箱一样,dokcer容器易于替换,可以叠加,易于分发,并且尽量通用。
使用docker,可以快速构建一个应用程序服务器、一个消息总线、一套实用工具、一个持续集成(CI)测试环境或者任意一种应用程序、服务或工具。
我们能用docker做什么
docker容器可以为各种测试环境提供很好的沙盒环境,并且,容器具有"标准性"的特征,非常适合为服务创建构建块。docker应用场景如下:
加速本地开发和构建流程,使其更加高效、更加轻量化,本地开发人员可以构建、运行并分享容器,容器可以在开发环境中构建,然后轻松提交到测试环境中,并最终进入生产环境。
能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。这点在面向服务的架构和重度依赖微型服务的部署中尤其实用。
用docker创建隔离的环境来进行测试。例如,用Jenkins CI这样的持续集成工具启动一个用于测试的容器。
docker可以让开发者在本机构建一个复杂的程序或架构来进行测试,而不是一开始就在生产环境部署、测试。
构建一个多用户的平台即服务(PaaS)基础设施。
为开发、测试提供一个轻量级的独立沙盒环境,或者将独立的沙盒环境用户技术教学,如shell、编程教学。
提供软件即服务(SaaS)应用程序,如Memcached即服务。
高性能、超大规模的宿主机部署。
Docker与配置管理:
自动化运维工具:Ansible、Puppet、chef。docker包含一套镜像构建和镜像管理的解决方案,现代配置管理工具的原动力之一就是"黄金镜像"模型。 然而,使用黄金镜像的结果就是充斥了大量、无管理状态的镜像,镜像数量庞大、版本混乱不堪。随着镜像使用,不确定性、环境混乱加剧,镜像本身也越笨重,最终不得不手动修正镜像不合符设计和难以管理的配置层,因为底层的镜像缺乏适当的灵活性。
与传统镜像相比,docker显得轻松,镜像是分层的,可以对其进行迅速迭代,数据表明,docker的特性确实可以减轻许多传统镜像管理的麻烦,docker现在还难以完全取代配置管理工具,但是从幂等性和内省性来看。取得了非常好的效果。
docker本身需要在主机上安装、管理和部署,主机也需要被管理起来,这样,docker容器需要编配、管理和部署,也经常需要与外部服务和工具通信,而这些恰恰是配置管理工具所擅长。
docker显著的特点:对不同宿主机、应用程序和服务,会表现出不同的特性与架构,docker可以是短生命周期的,也可以用于恒定的环境。可以用一次即销毁,也可以提供持久的服务。这些行为不会增加docker的复杂性,也不会和配置管理工具产生重合。基于这些行为,基本不需要担心管理状态的持久性,也不必担心状态的复杂性,因为容器的生命周期往往比较短,而重建容器的代价通常也比传统的状态修复要低。
当然,并非所有的基础设施都具备这样的"特性",在未来一段时间,docker这种与理想化的工作负载可能会与传统的基础设备部署共存一段时间。长期运行的设备主机仍是很多组织中具有不可替代的地位,由于多样化的管理需求,以及管理docker的需求,在绝大多数组织中,docker和配置管理工具可能都需要部署。
Docker的技术组件
docker可以运行于任何现代linux内核的x64主机,推荐内核时3.8及以上,docker开销低,可以用于台式机、笔记本。
一个原生的linux容器格式,docker称为libcontainer,libcontainer也是现在dokcer容器的默认格式。
linux内核命名空间(namespace),用于隔离文件系统、进行和网络。
文件隔离系统:每个容器都有自己的root文件系统。
进程隔离:每个容器都运行在自己的进程环境中
网络隔离:容器间的虚拟网络接口和IP地址都是分开的。
资源隔离和分组:使用cgroups(即control group,linux内核特性之一)将cpu和内存之类的资源独立分配给每个docker容器。
写时复制:文件系统都是通过写时复制创建的,这就意味着文件系统时分层的、快速的、而且占用的磁盘空间更小。
日志:容器产生的STDOUT、STDERR和STDIN这些IO流会被收集并记入日志,用来进行日志分析和故障排错。
交互式SHELL:用户可以创建一个伪tty终端,将其连接到STDIN,为容器提供一个交互式的shell
Docker资源
Docker官方主页
Docker Hub
Docker官方文档
Docker官方博客
Docker与虚拟机对比
一、虚拟机
虚拟机(virtual machine)就是带环境安装的一种解决方案。
它可以在一种操作系统里面运行另一种操作系统,比如在Windows10系统里面运行Linux系统CentOS7。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样。
原来:传统虚拟机技术基于主操作系统上的虚拟机管理系统(VirtualBox 和 VMWare等),创建虚拟机(虚拟出各种硬件)。在虚拟机上安装从操作系统,在从操作系统种安装部署各种应用。
缺点:资源占用多,冗余步骤多,启动慢
二、Docker
Linux 容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
Linux 容器不是模拟一个完整的操作系统而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统.
Docker 容器是在操作系统层面上实现虚拟技术,直接复用本地主机操作系统,虚拟机则是在硬件层面实现实现虚拟化。这使得 Dokcer 占用体积小、启动速度快。
Docker 来了什么变化?
- 一次构建,随处运行
- 更快速的应用交付和部署,通过加载镜像运行即可
- 更便捷的扩容和缩容,使应用扩容由原来的天级变为分钟级甚至秒级
- 更简单的系统运维,运维同学不再受环境配置的困扰
- 更高效的计算资源利用,一台物理机可以运行多个容器实例,大大提升物理服务器的 CPU 和内存的利用率。
docker run含义
二、安装docker
- 1.安装前准备
uname -r #查看下内核版本,建议3.10以上
升级内核及升级系统包
yum -y update:升级所有包同时也升级软件和系统内核;
yum -y upgrade:只升级所有包,不升级软件和系统内核
- 2.卸载docker旧版本
docker version #查看当前docker版本
yum erase docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce
yum可能会报告您没有安装这些软件包。/var/lib/docker/卸载 Docker 时,不会自动删除存储的映像、容器、卷和网络。
删除相关配置文件
find /etc/systemd -name '*docker*' -exec rm -f {} \;
find /etc/systemd -name '*docker*' -exec rm -f {} \;
find /lib/systemd -name '*docker*' -exec rm -f {} \;
3.安装docker
- 3.1 安装依赖gcc gcc-c++
yum -y install gcc gcc-c++
- 3.2 设置存储库
在新主机上首次安装 Docker Engine 之前,需要设置 Docker 存储库。之后,您可以从存储库安装和更新 Docker。
安装yum-utils软件包(提供yum-config-manager 实用程序)并设置存储库。
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖,设置docker镜像源为阿里云的yum源作为docker仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 3.3 更新yum软件包索引
yum makecache fast #创建缓存(非必选项)
- 3.4 查看docker可用版本
yum list docker-ce --showduplicates | sort -r
- 3.5 安装docker
选择一个版本安装:yum install docker-ce-版本号
yum -y install docker-ce-18.03.1.ce
安装docker最新版:yum install docker-ce docker-ce-cli containerd.io
- 3.6 启动docker,并设置开机自启动
systemctl start docker && systemctl enable docker
systemctl stop docker #停止
- 3.7 测试docker是否安装成功
docker run hello-world
三、镜像命令
启动命令
启动、停止、重启docker命令
启动docker:
systemctl start docker
停止docker:
systemctl stop docker
重启docker:
systemctl restart docker
查看docker状态;
systemctl status docker
开机启动:
systemctl enable dqsker
帮助命令
查看docker概要信息:
docker info
查看docker总体帮助文档:
docker --help
查看docker命令帮助文档:
docker 具体命令 --help
列出本地主机上的镜像
docker images -参数
参数:
-a:列出所有镜像(含历史镜像)
-q:只显示镜像ID
-f:过滤
各个选项说明:
REPOSITORY: 表示镜像的仓库源
TAG: 镜像的标签版本号
IMAGE ID: 镜像ID
CREATED: 镜像创建时间
SIZE: 镜像大小
同一仓库源可以有多个 TAG版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用ubuntu:latest 镜像
查看本地仓库镜像:
docker images -a
在远程仓库中搜索镜像
docker search 镜像名称((默认取docker hub中搜索))
参数:
-f:过滤
--limit 数量:只展示前几项
举例:docker search redis --limit 5
镜像名称[:tag]
参数:
tag为标签版本号(默认下载最新版)
举例:docker pull ubuntu
查看占据的空间
docker system df 查看镜像(Images)/容器(Containers)/数据卷(Local Volumes)所占的空间
删除镜像
docker rmi 镜像名称/ID
docker rmi -f hello-world #强制删除
docker rmi 镜像1 镜像2 镜像3 #可以使用空格分隔,删除多个镜像
docker rmi -f $(docker images -qa) #删除全部
下载镜像
docker pull 镜像名称
举例:
docker pull tomcat
docker pull redis
docker pull unbuntu
docker pull mysql:5.7
四、容器命令
启动容器
2.5.1 新建启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常用的参数:
- --name:为容器指定一个名称
- -d:后台运行容器并返回容器ID,也即启动守护式容器
- -i:以交互模式(interactive)运行容器,通常与-t同时使用
- -t:为容器重新分配一个伪输入终端(tty),通常与-i同时使用。也即启动交互式容器(前台有伪终端,等待交互)
- -e:为容器添加环境变量
- -P:随机端口映射。将容器内暴露的所有端口映射到宿主机随机端口
- -p:指定端口映射
-p指定端口映射的几种不同形式:
- -p hostPort:containerPort :端口映射,例如-p 8080:80
- -p ip:hostPort:containerPort :配置监听地址,例如 -p 10.0.0.1:8080:80
- -p ip::containerPort :随机分配端口,例如 -p 10.0.0.1::80
- -p hostPort1:containerPort1 -p hostPort2:containerPort2 :指定多个端口映射,例如-p 8080:80 -p 8888:3306
举例:
docker run -it ubuntu /bin/bash
交互模式启动容器
进入交互模式
运行容器时,可以使容器进入交互模式,便于管理,命令如下
docker run -it --name=myu01 ubuntu bash
#ubuntu交互模式,自定义容器名称myu01
-i 交互模式
-t 分配一个伪输入终端tty
ubuntu 镜像名称
bin/bash(或者bash) shell交互的接口
- 例如
docker run -it ubuntu /bin/bash
docker run -it --name=myu01 ubuntu bash
-#ubuntu交互模式,自定义容器名称myu01
退出交互模式:
- 1 方式1:在交互shell中,输入exit即可退回宿主机,但是容器会停止;
- 2 方式2:使用快捷键ctrl + P + Q,容器仍然在运行
列出正在运行的容器
docker ps [OPTIONS]
常用参数:
-a:列出当前所有正在运行的容器+历史上运行过的容器
-l:显示最近创建的容器
-n:显示最近n个创建的容器
-q:静默模式,只显示容器编号
docker ps -n 1
日志-运行进程-内部细节
docker logs 容器ID或容器名 #查看容器日志
docker top 容器ID或容器名 #查看容器内运行的进程
docker inspect 容器ID或容器名 #查看容器内部细节
启动停止重启容器
docker start 容器ID或容器名 #启动已经停止的容器
docker restart 容器ID或容器名 #重启容器
docker stop 容器ID或容器名 #停止容器
docker kill 容器ID或容器名 #强制停止容器
删除容器
docker rm 容器ID或容器名 #删除容器(删除容器是 docker rm,删除镜像是 docker rmi,注意区分)
docker rm -f 容器ID或容器名 #强制删除正在运行的容器
一次删除多个容器实例:
docker rm -f ${docker ps -a -q}
docker ps -a -q | xargs docker rm
启动守护式容器
- -d:后台运行容器并返回容器ID,也即启动守护式容器
docker run -d redis
进入正在运行的容器
#进入正在运行的容器(进入正在运行的容器,并以命令行交互:)
docker exec -it 容器ID l
#重新进入正在运行的容器(exit退出会导致容器停止)
docker attach 容器ID
docker exec 和 docker attach 区别:
- attach直接进入容器启动命令的终端,不会启动新的进程,用exit退出会导致容器的停止
- exec是在容器中打开新的终端,并且可以启动新的进程,用exit退出不会导致容器的停止
如果有多个终端,都对同一个容器执行了 docker attach,就会出现类似投屏显示的效果。一个终端中输入输出的内容,在其他终端上也会同步的显示。
举例:
docker exec -it e36c0f50ec13 bash
2.5.9 容器和宿主机文件拷贝
docker cp 容器ID:容器内路径 目的主机路径 #容器内文件拷贝到宿主机
docker cp 主机路径 容器ID:容器内路径 #宿主机文件拷贝到容器中
举例:
docker cp 79443d0c6126:/tmp/josh.txt /tmp
docker cp /tmp/askage.sh 79443d0c6126:/tmp
2.5.10 导入和导出容器
export:导出容器的内容流作为一个tar归档文件(对应import命令);
import:从tar包中的内容创建一个新的文件系统再导入为镜像(对应export命令)
导出docker export 容器ID > tar文件名
docker export 79443d0c6126 >myu10.tar #会导出到linux服务器你所在的目录下
导入
cat tar文件 | docker import - 自定义镜像用户/自定义镜像名:自定义镜像版本号
cat myu10.tar | docker import - test/ubuntu_my:1.1 #导入后用docker images确认
docker run -it 1d5b4b7fb0c8 bash #重启导入的test/ybuntu_my系统
2.5.11 提交容器副本使之成为一个新的镜像
docker commit -m="提交的描述信息”-a="作者”容器ID 要创建的目标镜像名:[标签名]
docker commit -m="vim cmd add”-a="josh” e36c0f50ec13 vim_ubuntu:1.3
五、容器数据卷
1.容器数据卷的概念
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过UnionFS,提供一些用于持续存储或共享数据。
特性:卷设计的目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
特点:
- 数据卷可以在容器之间共享或重用数据
- 卷中的更改可以直接实施生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
2.运行一个带有容器卷存储功能的容器实例:
docker run -it --privileged=true -v 宿主机绝对路径目录:容器内目录[rw | ro] 镜像名
3.查看容器绑定的数据卷可以使用docker inspect
权限:
rw:读写
ro:只读。如果宿主机写入内容,可以同步给容器内,容器内可以读取。
4.容器卷的继承:
启动一个容器
docker run -it --privileged=true /tmp/test:/tmp/docker --name u1 ubuntu /bin/bash
使用 --volumes-from 继承 u1的容器卷映射配置
docker run -it --privileged=true --volumes-from u1 --name u2 ubuntu
5.例1:主机与容器双向互写文件
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu
touch touch /tmp/docker_data/aaa.txt
ll /tmp/host_data/ #宿主机查看同步情况
7.例2:容器只读,主机写入
docker run -it --privileged=true -v /tmp/mydocker/u:/tmp/u:ro --name u2 ubuntu
所有命令示意图
六、下载加速配置
-
登录阿里云,搜索:容器镜像服务
-
安装/升级Docker客户端
推荐安装1.10.0以上版本的Docker客户端,参考文档docker-ce -
配置镜像加速器
针对Docker客户端版本大于 1.10.0 的用户
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://edfnnsgx.mirror.aliyuncs.com"]
}
EOF
重载docker
systemctl daemon-reload && systemctl restart docker
七、搭建docker私有仓库(Registry)
Docker Registry是官方提供的工具,用于构建私有镜像仓库。
3.1 环境搭建
Docker Registry也是Docker Hub提供的一个镜像,可以直接拉取运行。
1.拉取镜像
docker pull registry
2.启动Docker Registry
docker run -d -p 5000:5000 -v /app/myregistry/:/tmp/registry --privileged=true registry
3.验证(查看私服中的所有镜像),Registry会返回json格式的所有镜像目录
curl http://192.168.31.22:5000/v2/_catalog #IP和端口为docker主机IP
3.2 向Registry私仓中上传镜像
从Hub上下载ubuntu镜像到本地并成功运行
docker pull ubuntu
docker run -it ubuntu /bin/bash
原始的ubuntu镜像是不带着ifconfig命令的,外网连通的情况下,安装ifconfig命令并测试通过
apt-get update
apt-get install -y net-tools
安装完成后,commit我们自己的新镜像
docker commit -m="ifconfig cmd add" -a="josh" 7d651c27c792 joshubuntu:1.2
启动我们的新镜像并和原来的对比
docker stop 7d651c27c792 #停掉原来的ubuntu
docker images
docker run -it 90c4fb740827 /bin/bash #启动个新的测试ifconfig
将新镜像修改符合docker镜像规范,按照公式:docker tag 镜像:Tag Host:Port/Repository:Tag自己host主机IP地址,填写同学你们自己的,不要粘贴错误,使用命令 docker tag 将joshubuntu:1.2 这个镜像修改为
192.168.31.233:5000/zzyyubuntu:1.2
docker tag joshubuntu:1.2 192.168.31.223:5000/joshubuntu:1.2
docker images #检验
配置docker允许接收http请求:
修改/etc/docker/daemon.json,添加insecure-registries允许http:
{
"registry-mirros": ["https://xxxx.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.xxx.xxx:5000"]
}
然后重启docker:(新版本的docker会立即生效)
centos6 的命令
chkconfig daemon-reload
service docker restart
centos7 的命令
systemctl daemon-reload
systemctl restart docker
重启容器
docker run -d -p 5000:5000 -v /app/myregistry/:/tmp/registry --privileged=true registry
3.3 推送到私仓
1.添加一个对应私仓地址的tag
推送到私服库
docker push 192.168.31.223:5000/joshubuntu:1.2
再次验证私服库
curl http://192.168.31.223:5000/v2/_catalog
3.4 pull到本地并运行
1.复制一份到主机
将192.168.31.223:5000/joshubuntu复制一份到主机(可忽略次步骤)
docker run -it 90c4fb740827 /bin/bash #运行一个192.168.31.223:5000/joshubuntu虚拟机
docker export d44bf231d4e2 >bak.tar #将虚拟机打包到Linux
docker rmi -f 90c4fb740827 #删掉原有的包
2.pull到本地
curl -XGET http://192.168.31.223:5000/v2/_catalog
docker pull 192.168.31.223:5000/joshubuntu:1.2
八、Dockerfile
1 Dockerfile概念
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
1.1 构建步骤:
1.编写Dockerfile文件
2.docker build 命令构建镜像
3.docker run 依据镜像运行容器实例
1.2 构建过程
Dockerfile编写:
- 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
- 指令按照从上到下顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层并对镜像进行提交
Docker引擎执行Docker的大致流程:
1.docker从基础镜像运行一个容器
2.执行一条指令并对容器做出修改
3.执行类似docker commit的操作提交一个新的镜像层
4.docker再基于刚提交的镜像运行一个新容器
5.执行Dockerfile中的下一条指令,直到所有指令都执行完成
2 Dockerfile保留字
1 FROM 基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板。Dockerfile第一条必须是FROM
-
FROM 镜像名
FROM hub.c.163.com/library/tomcat -
MAINTAINER
镜像维护者的姓名和邮箱地址
非必须
-MAINTAINER ZhangSan zs@163.com -
RUN
容器构建时需要运行的命令。有两种格式:
shell格式:
等同于在终端操作的shell命令
格式:RUN <命令行命令>
RUN yum -y install vim
# 格式:RUN ["可执行文件" , "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"] # 等价于 RUN ./test.php dev offline
RUN是在docker build时运行
- EXPOSE
当前容器对外暴露出的端口。
# EXPOSE 要暴露的端口
# EXPOSE <port>[/<protocol] ....
EXPOSE 3306 33060
- WORKDIR
指定在创建容器后, 终端默认登录进来的工作目录。
ENV CATALINA_HOME /usr/local/tomcat
WORKDIR $CATALINA_HOME
- USER
指定该镜像以什么样的用户去执行,如果不指定,默认是root。(一般不修改该配置)
# USER <user>[:<group>]
USER patrick
- ENV
用来在构建镜像过程中设置环境变量。这个环境变量可以在后续的任何RUN指令或其他指令中使用
# 格式 ENV 环境变量名 环境变量值
# 或者 ENV 环境变量名=值
ENV MY_PATH /usr/mytest
# 使用环境变量
WORKDIR $MY_PATH
- VOLUME
容器数据卷,用于数据保存和持久化工作。类似于 docker run 的-v参数。
# VOLUME 挂载点
# 挂载点可以是一个路径,也可以是数组(数组中的每一项必须用双引号)
VOLUME /var/lib/mysql
-
ADD
将宿主机目录下(或远程文件)的文件拷贝进镜像,且会自动处理URL和解压tar压缩包。 -
COPY
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件目录复制到新的一层镜像内的<目标路径>位置。
COPY src dest
COPY ["src", "dest"]
# <src源路径>:源文件或者源目录
# <dest目标路径>:容器内的指定路径,该路径不用事先建好。如果不存在会自动创建
- CMD
指定容器启动后要干的事情。
有两种格式:
- shell格式
# CMD <命令>
CMD echo "hello world"
- exec格式
# CMD ["可执行文件", "参数1", "参数2" ...]
CMD ["catalina.sh", "run"]
- 参数列表格式
# CMD ["参数1", "参数2" ....],与ENTRYPOINT指令配合使用
Dockerfile中如果出现多个CMD指令,只有最后一个生效。CMD会被docker run之后的参数替换。
例如,对于tomcat镜像,执行以下命令会有不同的效果:
# 因为tomcat的Dockerfile中指定了 CMD ["catalina.sh", "run"]
# 所以直接docker run 时,容器启动后会自动执行 catalina.sh run
docker run -it -p 8080:8080 tomcat
# 指定容器启动后执行 /bin/bash
# 此时指定的/bin/bash会覆盖掉Dockerfile中指定的 CMD ["catalina.sh", "run"]
docker run -it -p 8080:8080 tomcat /bin/bash
CMD是在docker run时运行,而 RUN是在docker build时运行。
- ENTRYPOINT
用来指定一个容器启动时要运行的命令。
类似于CMD命令,但是ENTRYPOINT不会被docker run后面的命令覆盖,这些命令参数会被当做参数送给ENTRYPOINT指令指定的程序。
ENTRYPOINT可以和CMD一起用,一般是可变参数才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。
当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行期命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令,它们两个组合会变成 “”。
例如:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
对于此Dockerfile,构建成镜像 nginx:test后,如果执行;
- docker run nginx test,则容器启动后,会执行 nginx -c /etc/nginx/nginx.conf
- docker run nginx:test /app/nginx/new.conf
,则容器启动后,会执行 nginx -c /app/nginx/new.conf
3 构建镜像
创建名称为Dockerfile的文件,示例:
FROM ubuntu
MAINTAINER lee<lee@xxx.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN apt-get update
RUN apt-get install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "install ifconfig cmd into ubuntu success ....."
CMD /bin/bash
编写完成之后,将其构建成docker镜像。
命令:
# 注意:定义的TAG后面有个空格,空格后面有个点
# docker build -t 新镜像名字:TAG .
docker build -t ubuntu:1.0.1 .
九、虚悬镜像
虚悬镜像:仓库名、标签名都是 的镜像,称为 dangling images(虚悬镜像)。
在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像。
例如:
# 构建时候没有镜像名、tag
docker build .
列出docker中的虚悬镜像:
docker image ls -f dangling=true
虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:
# 删除所有的虚悬镜像
docker image prune
参考《第一本docker书》内容
参考尚硅谷docker教学视频