主机时代比拼的是单个服务器物理性能(如CPU主频和内存)的强弱,那么在云时代,最为看重的则是凭借虚拟化技术所构建的集群处理能力。 虚拟化的概念早已经普遍应用到各类关键场景中。从20世纪60年代IBM推出的大型主机虚拟化,到后来以Xen、KVM为表明的虚拟机虚拟化,再到如今以Docker为表明的容器技术,虚拟化技术自身也在不断进行创新和突破。 虚拟化既能够经过硬件模拟来实现,也能够经过操做系统软件来实现。而容器技术则更为优雅,它充分利用了操做系统自己已有的机制和特性,能够实现远超传统虚拟机的轻量级虚拟化。所以,有人甚至把它称为“新一代的虚拟化”技术,并将基于容器打造的云平台亲切地称为“容器云”,Docker正是众多容器技术中的佼佼者python
Docker是基于Go语言实现的开源容器项目。它诞生于2013年年初,最初发起者是dotCloud公司(如今已经改成Docker )。Docker项目已加入Linux基金会,并遵循Apache 2.0协议。mysql
与大部分新兴技术的诞生同样,Docker也并不是“从石头缝里蹦出来的”,而是站在前人的肩膀上,就是Linux容器(Linux Containers, LXC)技术。IBM 开发者网站关于容器技术的描述十分准确:“容器有效地将由单个操做系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不须要指令级模拟,也不须要即时编译。容器能够在核心CPU本地运行指令,而不须要任何专门的解释机制。此外,也避免了准虚拟化(para-virtualization)和系统调用替换中的复杂性。LXC也经历了长期的演化,最先能够追溯到1982年Unix系列操做系统上的chroot工具。linux
在LXC的基础上,Docker进一步优化了容器的使用体验,首先,Docker提供了各类容器管理工具(如分发、版本、移植等),让用户无须关注底层的操做,更加简单明了地管理和使用容器;其次,Docker经过引入分层文件系统构建和高效的镜像机制,下降了迁移难度,极大地改善了用户体验。用户操做Docker容器就像操做应用自身同样简单。 早期的Docker代码实现是直接基于LXC的。自0.9版本开始,Docker开发了libcon-tainer项目做为更普遍的容器驱动实现,从而替换掉了LXC的实现。目前,Docker还积极推进成立了runC标准项目,并贡献给开放容器联盟,试图让容器的支持再也不局限于Linux操做系统,而是更安全、更开放、更具扩展性。简单地讲。 Docker容器理解为一种轻量级的沙盒(sandbox)。每一个容器内运行着一个或多个应用,不一样的容器相互隔离,容器之间也能够经过网络互相通讯。容器的建立和中止十分快速,几乎跟建立和终止原生应用一致;另外,容器自身对系统资源的额外需求也十分有限,远远低于传统虚拟机。不少时候,甚至直接把容器看成应用自己也没有任何问题。nginx
Docker的构想是要实现“Build, Ship and Run Any App, Anywhere”,即经过对应用的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)全生命周期进行管理,达到应用组件级别的“一次封装,处处运行”。这里的应用组件,既能够是一个Web应用、一个编译环境,也能够是一套数据库平台服务,甚至是一个操做系统或集群。c++
Docker 引擎由以下主要的组件构成: Docker 客户端(Docker Client) Docker 守护进程(Docker daemon) containerd 以及 runc。它们共同负责容器的建立和运行 最新的架构示意图:git
介绍Docker的三大核心概念:❑ 镜像(Image)❑ 容器(Container)❑ 仓库(Repository)只有理解了这三个核心概念,才能顺利地理解Docker容器的整个生命周期。web
Docker镜像相似于虚拟机镜像,能够将它理解为一个只读的模板。例如,一个镜像能够包含一个基本的操做系统环境,里面仅安装了Apache应用程序(或用户须要的其余软件)。能够把它称为一个Apache镜像。镜像是建立Docker容器的基础。经过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来建立和更新现有的镜像,用户甚至能够从网上下载一个已经作好的应用镜像,并直接使用。镜像能够理解成源代码。sql
Docker容器相似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。容器是从镜像建立的应用运行实例。它能够启动、开始、中止、删除,而这些容器都是彼此相互隔离、互不可见的。能够把容器看做一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间等)以及运行在其中的应用程序打包而成的盒子。容器能够理解成从镜像编译运行的应用程序。docker
镜像仓库,则是指存放镜像文件的地方,能够理解成源代码仓库,列如GitHub,或者GitLab。 每一个仓库集中存放某一类镜像,每每包括多个镜像文件,经过不一样的标签(tag)来进行区分。例如存放Ubuntu操做系统镜像的仓库,被称为Ubuntu仓库,其中可能包括16.0四、18.04等不一样版本的镜像。 目前,最大的公开仓库是官方提供的Docker Hub,其中存放着数量庞大的镜像供用户下载。国内很多云服务提供商阿里云仓库也提供了仓库的本地源,能够提供稳定的国内访问。shell
Docker引擎目前分为两个版本:社区版本(Community Edition, CE)和企业版本(Enterprise Edition, EE对于windows和 Mac 版本的Docker 都是社区提供的,在生产环境中不建议使用。因此重点学习在其Linux系统的上面的使用,以centos8为例安装学习:
#!/bin/bash
echo -e '卸载旧版本的docker'
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
echo -e '安装经常使用软件包'
yum install yum-utils device-mapper-persistent-data lvm2 -y
echo -e '添加 阿里Docker源'
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
echo '更新并安装Docker-CE'
sudo yum makecache fast
echo -e '安装docker-ce'
yum install -y docker-ce docker-ce-cli containerd.io
echo -e '设置Docker开机自启动'
systemctl enable docker
echo -e '启动docker'
systemctl start docker
echo -e '查看docker版本'
docker --version
echo -e '给docker换阿里源'
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": ["https://fl791z1h.mirror.aliyuncs.com"]
}
EOF
echo -e '重启docker服务'
systemctl restart docker
echo -e '查看docker信息'
docker info
exit
复制代码
安装过程出现的可能出现的问题排查: 因为最新的docker 依赖的container 的版本变化引发的安装问题
[root@localhost ~]# yum -y install docker-ce
上次元数据过时检查:0:00:32 前,执行于 2021年01月07日 星期四 08时07分56秒。
错误:
问题: package docker-ce-3:20.10.2-3.el7.x86_64 requires containerd.io >= 1.4.1, but none of the providers can be installed
- cannot install the best candidate for the job
- package containerd.io-1.4.3-3.1.el7.x86_64 is filtered out by modular filtering
# 出现上面的错误信息的时候 ,打开下面的连接 找到对应的 centos 版本,而后点进去找到继续找 下图所
https://mirrors.aliyun.com/docker-ce/linux/centos/
wget https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm
yum install containerd.io-1.4.3-3.1.el8.x86_64.rpm
# 在继续
yum -y install docker-ce
复制代码
docker image pull
或者 docker pull
镜像是运行容器的前提,可使用docker [image] pull
命令直接从Docker Hub镜像源来下载镜像。该命令的格式为 docker [image] pull NAME[:TAG]
NAME是镜像仓库名称(用来区分镜像), TAG是镜像的标签(每每用来表示版本信息)。一般状况下,描述一个镜像须要包括“名称+标签”信息
[root@localhost ~]# docker pull centos 获取一个镜像,不加 tag 标签的时候 默认拉去的 tag是latest
Using default tag: latest
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
复制代码
下载过程当中能够看出,镜像文件通常由若干层(layer)组成,7a0437f04f83这样的串是层的惟一id(实际上完整的id包括256比特,64个十六进制字符组成)。使用docker pull命令下载中会获取并输出镜像的各层信息。当不一样的镜像包括相同的层时,本地仅存储了层的一分内容,减少了存储空间
docker images
命令能够列出本地主机上已有镜像的基本信息[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest ae2feff98a0c 3 weeks ago 133MB
centos latest 300e315adb2f 4 weeks ago 209MB
portainer/portainer latest 62771b0b9b09 5 months ago 79.1MB
复制代码
能够看到几个字段信息: ❑ 来自于哪一个仓库,好比centos表示centos系列的基础镜像; ❑ 镜像的标签信息,好比latest表示不一样的版本信息。标签只是标记,并不能标识镜像内容; ❑ 镜像的ID(惟一标识镜像),若是两个镜像的ID相同,说明它们实际上指向了同一个镜像,只是具备不一样标签名称而已; ❑ 建立时间,说明镜像最后的更新时间; ❑ 镜像大小,优秀的镜像每每体积都较小
docker[image]inspect 镜像名称/镜像ID
命令能够获取该镜像的详细信息,包括制做者、适应架构、各层的数字摘要等docker history 镜像名称/镜像ID
命令查看镜像历史docker search 镜像名称
命令能够搜索Docker Hub官方仓库中的镜像docker rmi 镜像名称/镜像ID
或docker image rm 镜像名称/镜像ID
命令删除镜像docker image prune
命令来进行清理镜像使用Docker一段时间后,系统中可能会遗留一些临时的镜像文件,以及一些没有被使用的镜像可使用上述的命令清理掉 支持选项包括: ❑ -a, -all:删除全部无用镜像,不光是临时镜像 ❑ -filter filter:只清理符合给定过滤器的镜像 ❑ -f, -force:强制删除镜像,而不进行提示确认
docker [container] commit
命令基于已有容器建立镜像命令格式为 docker [container] commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 主要选项包括:OPTIONS ❑ -a, --author="":做者信息 ❑ -c, --change=[]:提交的时候执行Dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等 ❑ -m, --message="":提交消息 ❑ -p, --pause=true:提交时暂停容器运行
docker [container] import
从模板文件导入一个镜像命令格式为 docker [image] import [OPTIONS]file|URL|-[REPOSITORY [:TAG]]
docker [image] save
导出镜像到本地文件该命令支持-o、-output string参数,导出镜像到指定的文件中,就能够经过复制处处的文件给别人使用
// 保存当前的centos 镜像为centos_letest.tar 文件
docker save -o centon_letest.tar centos:latest
复制代码
docker [image] load
将导出的tar文件再导入到本地镜像库支持-i、-input string选项,从指定文件中读入镜像内容
docker load -i centon_letest.tar
复制代码
docker [image] push
命令上传镜像到仓库默认上传到Docker Hub官方仓库,相似 git push
容器是Docker的另外一个核心概念。简单来讲,容器是镜像的一个运行实例。所不一样的是,镜像是静态的只读文件,而容器带有运行时须要的可写文件层,同时,容器中的应用进程处于运行状态。
docker [container] create
命令新建一个容器使用docker [container] create命令新建的容器处于中止状态,可使用 docker[container] start
命令来启动它。
[root@localhost ~]# docker create -it centos:latest
27a89a80a2cb4e5c5fe0e24ef86cb2dac451219beeee3f11ac916fe2143f369a
复制代码
docker [container] start
启动容器[root@localhost ~]# docker start 27a89a80a2c
27a89a80a2c
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27a89a80a2cb centos:latest "/bin/bash" 6 minutes ago Up 4 seconds objective_lederberg
复制代码
docker [container] run
新建并启动容器等价于先执行docker [container]create
命令,再执行docker [container] start
命令 当利用docker [container] run来建立并启动容器时,Docker在后台运行的标准操做包括: ❑ 检查本地是否存在指定的镜像,不存在就从公有仓库下载 ❑ 利用镜像建立一个容器,并启动该容器 ❑ 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层 ❑ 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 ❑ 从网桥的地址池配置一个IP地址给容器 ❑ 执行用户指定的应用程序 ❑ 执行完毕后容器被自动终止
[root@localhost ~]# docker run -it --name centos-test centos:latest /bin/bash
[root@d078291e042a /]#
复制代码
经常使用选项
docker [container] logs
查看容器输出日志docker [container] pause
命令来暂停一个运行中的容器处于paused状态的容器,可使用docker [container] unpause
CONTAINER[CONTAINER...]命令来恢复到运行状态
docker [container] unpause命令来恢复到运行状态
docker [container] stop
来终止一个运行中的容器该命令会首先向容器发送SIGTERM信号,等待一段超时时间后(默认为10秒),再发送SIGKILL信号来终止容器,处于终止状态的容器,能够经过docker [container] start
命令来从新启动
docker [container] kill
直接发送SIGKILL信号来强行终止容器docker [container] restart
命令会将一个运行态的容器先终止,而后再从新启动docker [container] attach
链接到正在运行中的容器docker [container] exec
更加方便的工具exec命令,能够在运行中容器内直接执行任意命令docker exec -it 容器名称/容器ID /bin/bash
复制代码
docker [container] rm
命令来删除处于终止或退出状态的容器主要支持的选项包括:
❑ -f, --force=false:是否强行终止并删除一个运行中的容器
❑ -l, --link=false:删除容器的链接,但保留容器
❑ -v, --volumes=false:删除容器挂载的数据卷
docker [container] export
导出容器是指,导出一个已经建立的容器到一个文件,无论此时这个容器是否处于运行状态
docker export -o export_centos.tar 容器ID/容器名称
// -o 导出的文件名
复制代码
docker [container] import
命令导入变成镜像docker container inspect
查看容器详情docker [container] top
查看容器内进程docker [container] stats
查看统计信息docker [container] cp
命令支持在容器和主机之间复制文件本地的路径data复制到test容器的/tmp路径下 docker cp data test:/tmp
docker [container] diff
查看容器内文件系统的变动docker [container] port
命令能够查看容器的端口映射状况docker [container] update
命令能够更新容器的一些运行时配置,主要是一些资源限制份额支持的选项包括:
❑ -blkio-weight uint16:更新块IO限制,10~1000,默认值为0,表明着无限制
❑ -cpu-period int:限制CPU调度器CFS(Completely Fair Scheduler)使用时间,单位为微秒,最小1000
❑ -cpu-quota int:限制CPU调度器CFS配额,单位为微秒,最小1000
❑ -cpu-rt-period int:限制CPU调度器的实时周期,单位为微秒
❑ -cpu-rt-runtime int:限制CPU调度器的实时运行时,单位为微秒
❑ -c, -cpu-shares int:限制CPU使用份额;
❑ -cpus decimal:限制CPU个数;
❑ -cpuset-cpus string:容许使用的CPU核,如0-3,0,1
❑ -cpuset-mems string:容许使用的内存块,如0-3,0,1
❑ -kernel-memory bytes:限制使用的内核内存;
❑ -m, -memory bytes:限制使用的内存
❑ -memory-reservation bytes:内存软限制
❑ -memory-swap bytes:内存加上缓存区的限制,-1表示为对缓冲区无限制
❑ -restart string:容器退出后的重启策略
在生产环境中使用Docker,每每须要对数据进行持久化,或者须要在多个容器之间进行数据共享,这必然涉及容器的数据管理操做。 容器中的管理数据主要有两种方式: ❑ 数据卷(Data Volumes):容器内数据直接映射到本地主机环境; ❑ 数据卷容器(Data Volume Containers):使用特定容器维护数据卷。 首先介绍如何在容器内建立数据卷,而且把本地的目录或文件挂载到容器内的数据卷中。其次介绍如何使用数据卷容器在容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复。
数据卷(Data Volumes)是一个可供容器使用的特殊目录,它将主机操做系统目录直接映射进容器,相似于Linux中的mount行为 数据卷能够提供不少有用的特性: ❑ 数据卷能够在容器之间共享和重用,容器间传递数据将变得高效与方便 ❑ 对数据卷内数据的修改会立马生效,不管是容器内操做仍是本地操做 ❑ 对数据卷的更新不会影响镜像,解耦开应用和数据 ❑ 卷会一直存在,直到没有容器使用,能够安全地卸载它
docker volume create
建立数据卷Docker提供了volume子命令来管理数据卷,以下命令能够快速在本地建立一个数据卷:
docker volume create -d local test-vol 建立一个本地的数据卷
//
/var/lib/docker/volumes路径下,会发现所建立的数据卷 test-vol
复制代码
docker volume inspect
(查看详细信息)[root@localhost volumes]# docker volume inspect test-vol
[
{
"CreatedAt": "2021-01-07T16:36:32-05:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
"Name": "test-vol",
"Options": {},
"Scope": "local"
}
]
复制代码
docker volume ``ls
列出已有数据卷docker volume prune
清理无用数据卷docker volume rm
删除数据卷除了使用volume子命令来管理数据卷外,还能够在建立容器时将主机本地的任意路径挂载到容器内做为数据卷,这种形式建立的数据卷称为绑定数据卷 docker [container] run
命令的时候,可使用 -mount 选项来使用数据卷。
-mount
type选项支持三种类型的数据卷,包括:
❑ volume:普通数据卷,映射到主机/var/lib/docker/volumes路径下;
❑ bind:绑定数据卷,映射到主机指定路径下;
❑ tmpfs:临时数据卷,只存在于内存中
source:主机目录路径
destination:容器目录路径
type=bind,source=/path/on/host,destination=/path/in/container
type=volume,source=my-volume,destination=/path/in/container,volume-label="color=red",volume-label="shape=round"
type=tmpfs,tmpfs-size=512M,destination=/path/in/container
复制代码
docker run -itd --name centos-test --mount type=bind,source=/www,destination=/cen_www centos:latest
// 上面的命令至关下面
docker run -itd --name centos-test -v /www:/cen_www centos:latest
复制代码
Docker挂载数据卷的默认权限是读写(rw),用户也能够经过ro指定为只读:
docker run -itd --name centos-test -v /www:/cen_www:ro centos:latest
复制代码
若是须要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,可是它的目的是专门提供数据卷给其余容器挂载 首先,建立一个数据卷容器dbcontainer,并在其中建立一个数据卷挂载到/dbcontainer, 而后,能够在其余容器中使用 --volumes-from 来挂载dbcontainer容器中的数据卷,例如建立db1和db2两个容器,并从dbcontainer容器挂载数据卷:
docker run -itd --name dbcontainer -v /db_host:/dbdata centos:latest
docker run -itd --name db1 --volumes-from dbcontainer centos:latest
docker run -itd --name db2 --volumes-from dbcontainer centos:latest
复制代码
此时,容器db1和db2都挂载同一个数据卷到相同的/dbdata目录,三个容器任何一方在该目录下的写入,其余容器均可以看到 能够屡次使用 --volumes-from 参数来从多个容器挂载多个数据卷,还能够从其余已经挂载了容器卷的容器来挂载数据卷
Docker除了经过网络访问外,还提供了两个很方便的功能来知足服务访问的基本需求:一个是容许映射容器内应用的服务端口到本地宿主主机;另外一个是互联机制实现多个容器间经过容器名来快速访问
当容器中运行一些网络应用,要让外部访问这些应用时,能够经过-P或-p参数来指定端口映射。 当使用-P(大写的)标记时,Docker会随机映射一个49000~49900的端口到内部容器开放的网络端口 -p(小写的)则能够指定要映射的端口,而且,在一个指定端口上只能够绑定一个容器。 支持的格式有
HostPort:ContainerPort
eg:80 8080:8080
IP:HostPort:ContainerPort
eg:127.0.0.1:5000:5000
IP::ContainerPort
eg:127.0.0.1::5000 使用IP::ContainerPort
绑定localhost的任意端口到容器的5000端口,本地主机会自动分配一个端口
IP:ContainerPort/udp
eg:127.0.0.1:5000/udp
使用--link参数可让容器之间安全地进行交互 ,--link参数的格式为--link name:alias,其中name是要连接的容器的名称,alias是别名
// 先建立一个容器
docker run -it --rm --name centos-1 centos:latest
// 在建立一个容器
docker run -itd --name centos-2 --link centos-1:centos-1 centos:latest
复制代码
Docker至关于在两个互联的容器之间建立了一个虚机通道,并且不用映射它们的端口到宿主主机上。
在启动容器的时候并无使用-p和-P标记,从而避免了暴露数据库服务端口到外部网络上。
Docker经过两种方式为容器公开链接信息:
❑ 更新环境变量 查看容器的环境变量 : docker exec centos-1 env
使用env命令来查看容器的环境变量 ❑ 更新/etc/hosts文件
Dockerfile是一个文本格式的配置文件,用户可使用Dockerfile来快速建立自定义的镜像。 Dockerfile由一行行命令语句组成,而且支持以#开头的注释行。 通常而言,Dockerfile主体内容分为四部分:基础镜像信息、维护者信息、镜像操做指令和容器启动时执行指令
Dockerfile中指令的通常格式为 INSTRUCTION arguments
,包括“配置指令”(配置镜像信息)和“操做指令”
ARG 定义建立镜像过程当中使用的变量 惟一一个能够在FROM指令以前
FROM 指定基础镜像,必须为第一个命令(在没有ARG)
LABEL LABEL指令能够为生成的镜像添加元数据标签信息。这些信息能够用来辅助过滤出特定镜像
EXPOSE 声明镜像内服务监听的端口
ENV 指定环境变量,在镜像生成过程当中会被后续RUN指令使用,在镜像启动的容器中也会存在
ENTRYPOINT 指定镜像的默认入口命令,该入口命令会在启动容器时做为根命令执行,全部传入值做为该命令的参数
VOLUME 建立一个数据卷挂载点
USER 指定运行容器时的用户名或UID,后续的RUN等指令也会使用指定的用户身份
WORKDIR 为后续的RUN、CMD、ENTRYPOINT指令配置工做目录
ONBUILD 指定当基于所生成镜像建立子镜像时,自动执行的操做指令
STOPSIGNAL 指定所建立镜像启动的容器接收退出的信号值
HEALTHCHECK 配置所启动容器如何进行健康检查
SHELL 指定其余命令使用shell时的默认shell类型
复制代码
RUN 运行指定命令
CMD 用来指定启动容器时默认执行的命令
ADD 添加内容到镜像
COPY 复制内容到镜像
复制代码
ARG
: 定义建立镜像过程当中使用的变量惟一一个能够在FROM指令以前的指令,ARG指令定义的参数,在docker build命令中以--build-arg a_name=a_value形式赋值。若是docker build命令传递的参数,在Dockerfile中没有对应的参数,将警告
# 格式:
ARG <name>[=<default value>]
# 示例:
ARG VERSION="7.0"
FROM centos:${VERSION}
复制代码
FROM
: 指定所建立镜像的基础镜像tag或digest是可选的,若是不使用这两个值时,会使用latest版本的基础镜像
# 格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
#示例:
FROM mysql:5.6
复制代码
LABEL
: 指令能够为生成的镜像添加元数据标签信息使用LABEL指定元数据时,一条LABEL指定能够指定一或多条元数据,指定多条元数据时不一样元数据之间经过空格分隔。推荐将全部的元数据经过一条LABEL指令指定,以避免生成过多的中间镜像
# 格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
# 示例:
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
LABEL author="sun@qq.com" data="2021-1-1"
复制代码
EXPOSE
: 声明镜像内服务监听的端口EXPOSE并不会让容器的端口访问到主机。要使其可访问,须要在docker run运行容器时经过-p来发布这些端口,或经过-P参数来发布EXPOSE导出的全部端口
# 格式:
EXPOSE <port> [<port>...]
# 示例:
EXPOSE 80 443
EXPOSE 8080 EXPOSE 11211/tcp 11211/udp
复制代码
ENV
: 指定环境变量指令指定的环境变量在运行时能够被覆盖掉,如 docker run --env <key>=<value> built_image
#格式:
ENV <key> <value> #<key>以后的全部内容均会被视为其<value>的组成部分,所以,一次只能设置一个变量
ENV <key>=<value> ... #能够设置多个变量,每一个变量为一个"<key>=<value>"的键值对,若是<key>中包含空格,可使用\来进行转义,也能够经过""来进行标示;另外,反斜线也能够用于续行
# 示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy
复制代码
ENTRYPOINT
: 指定镜像的默认入口命令注ENTRYPOINT与CMD很是相似,不一样的是经过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当作参数再次传递给ENTRYPOINT。Dockerfile中只容许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令,在运行时,能够被--entrypoint参数覆盖掉,如 docker run --entrypoint
#格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
复制代码
VOLUME
:建立一个数据卷挂载点# 格式:
VOLUME ["/path/to/dir"]
# 示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:一个卷能够存在于一个或多个容器的指定目录,该目录能够绕过联合文件系统,并具备如下功能:
1 卷能够容器间共享和重用
2 容器并不必定要和其它容器共享卷
3 修改卷后会当即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它
复制代码
USER
: 指定运行容器时的用户名或UID# 格式:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
# 示例:
USER www
# 注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,经过docker run运行容器时,能够经过-u参数来覆盖所指定的用户。
复制代码
WORKDIR 为后续的RUN、CMD、ENTRYPOINT指令配置工做目录,经过WORKDIR设置工做目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。在使用** docker run -w **
**运行容器时,能够经过-w参数覆盖构建时所设置的工做目录 **
# 格式:
WORKDIR /path/to/workdir
# 示例:
WORKDIR /a (这时工做目录为/a)
WORKDIR b (这时工做目录为/a/b)
WORKDIR c (这时工做目录为/a/b/c)
复制代码
ONBUILD
: 指定当基于所生成镜像建立子镜像时,自动执行的操做指令#格式:
ONBUILD [INSTRUCTION]
#示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
# 注:当所构建的镜像被用作其它镜像的基础镜像,该镜像中的触发器将会被钥触发
复制代码
RUN
: 运行指定命令RUN用于在镜像容器中执行命令,其有如下两种命令执行方式:
shell执行
格式:
RUN <command>
exec执行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
注:RUN指令建立的中间镜像会被缓存,并会在下次构建中使用。若是不想使用这些缓存镜像,能够在构建时指定--no-cache参数,如:docker build --no-cache
复制代码
CMD
: 指令用来指定启动容器时默认执行的命令格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]
注: CMD不一样于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
复制代码
ADD
:添加内容到镜像格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
ADD hom* /mydir/ # 添加全部以"hom"开头的文件
ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
复制代码
COPY
:复制内容到镜像COPY与ADD指令功能相似,可是是不会自动解压文件,也不能访问网络资源,当使用本地目录为源目录时,推荐使用COPY
下载 nginx-1.18.0.tar.gz ,epel-release-latest-7.noarch.rpm 文件在同一目录之下 而且在当前目录下 新建 Dockerfile 文件
# This nginx Dockerfile
# Version 1.0
# Base images 基础镜像
FROM centos
#MAINTAINER 维护者信息
MAINTAINER xxxxx
#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH
#ADD 文件放在当前目录下,拷过去会自动解压
ADD ./nginx-1.18.0.tar.gz /usr/local/
ADD ./epel-release-latest-7.noarch.rpm /usr/local/
#RUN 执行如下命令
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www
#WORKDIR 至关于cd
WORKDIR /usr/local/nginx-1.8.0
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install
RUN echo "daemon off;" >> /etc/nginx.conf
#EXPOSE 映射端口
EXPOSE 80
#CMD 运行如下命令
CMD ["nginx"]
复制代码
docker build -t Name:Tag -f Dockerfile .
构建镜像
--add-host list | 添加自定义Host到ip的映射(主机:ip) |
---|---|
--build-arg list | 设置构建时的变量 |
--cache-from strings | 将镜像视为缓存源 |
--cgroup-parent string | 可选的容器父cgroup |
--compress | 使用gzip工具压缩构建的上下文 |
--console | 显示控制台输出,仅使用 buildkit,参数有:true、false、auto(默认为 auto) |
--cpu-period int | 限制CPU CFS(彻底公平的调度)的周期 |
--cpu-quota int | 限制CPU CFS(彻底公平的调度)的限额 |
-c, --cpu-shares int | 设置CUP的共享权重 |
--cpuset-cpus string | 容许执行的cpu个数 (0-3,0,1) |
--cpuset-mems string | 容许执行的MEM个数 (0-3,0,1) |
--disable-content-trust | 跳过镜像的验证(默认为 true) |
-f, --file string | 构建的Dockerfile的名称(默认为 ‘PATH/Dockerfile’) |
--force-rm | 老是移除中间容器 |
--iidfile string | 将镜像ID写入到指定文件 |
--isolation string | 容器隔离技术 |
--label list | 为镜像设置元数据 |
-m, --memory bytes | 内存限额 |
--memory-swap bytes | 若是启用无限交换,则交换限制等于内存加上交换:'-1'便可 |
--network string | 在构建期间为 RUN 指令设置网络模式(默认为 “default”) |
--no-cache | 在构建映像时不使用缓存(设定后,每次都会从新去拉取,默认使用缓存的) |
--platform string | 若是服务器具备多平台能力,则设置该平台 |
--pull | 老是尝试拉取该镜像的新版本 |
-q, --quiet | 镜像构建成功后禁止生成输出和打印镜像的ID |
--rm | 构建成功后删除中间容器(默认为 true) |
--security-opt strings | 安全选项 |
--shm-size bytes | 设定/dev/shm的大小 |
--squash | 将新建的镜像层压缩成一个新的镜像层 |
--stream | 将流附加到服务器以协商构建上下文 |
-t, --tag list | 名称和可选的标签(格式为 'name:tag' ) |
--target string | 设置须要构建的目标构建阶段 |
--ulimit ulimit | U 限制项 (默认为 []) |
默认状况下容器与容器、容器与宿主机的网络是隔离开来的,docker 网络须要解决的就是 容器于容器的之间的互通。
Docker网络模式 | 配置 | 说明 |
---|---|---|
host模式 | --net=host | 容器和宿主机共享Network namespace |
container模式 | --net=container:NAME_or_ID | 容器和另一个容器共享Network namespace,kubernetes中的pod就是多个容器共享一个Network namespace |
none模式 | --net=none | 容器有独立的Network namespace但并无对其进行任何网络设置,如分配veth pair 和网桥链接,配置IP等 |
bridge模式 | --net=bridge (默认为该模式) | 网络桥接模式,将自动生成独有的Network namespace |
自定义模式 | --net=自定义网络名称 | -- |
原理:若是启动容器的时候使用host模式,那么这个容器将不会得到一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出本身的网卡,配置本身的IP等,而是使用宿主机的IP和端口。可是,容器的其余方面,如文件系统、进程列表等仍是和宿主机隔离的。 使用host模式的容器能够直接使用宿主机的IP地址与外界通讯,容器内部的服务端口也可使用宿主机的端口,不须要进行NAT,host最大的优点就是网络性能比较好,可是docker host上已经使用的端口就不能再用了,网络的隔离性很差。 ** **
这个模式指定新建立的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新建立的容器不会建立本身的网卡,配置本身的 IP,而是和一个指定的容器共享 IP、端口范围等。一样,两个容器除了网络方面,其余的如文件系统、进程列表等仍是隔离的。两个容器的进程能够经过 lo 网卡设备通讯
使用none模式,Docker容器拥有本身的Network Namespace,可是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。须要咱们本身为Docker容器添加网卡、配置IP等。 这种网络模式下容器只有lo回环网络,没有其余网卡。none模式能够在容器建立时经过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性
当Docker进程启动时,会在主机上建立一个名为docker0
的虚拟网桥,此主机上启动的Docker容器会链接到这个虚拟网桥上。虚拟网桥的工做方式和物理交换机相似,这样主机上的全部容器就经过交换机连在了一个二层网络中 从docker0
子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上建立一对虚拟网卡veth pair
设备,Docker将veth pair设备的一端放在新建立的容器中,并命名为eth0(容器的网卡),另外一端放在主机中,以vethxxx这样相似的名字命名,并将这个网络设备加入到docker0网桥中。能够经过brctl show
命令查看 bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p
时,docker实际是在iptables作了NAT规则,实现端口转发功能。可使用iptables -t nat -vnL
查看
veth-pair
就是一对的虚拟设备接口,它都是成对出现的。一端连着协议栈,一端彼此相连着
按照如下方式建立了两个容器,在经过名称互联访问时候,链接不用
docker run -itd --name centos-bdg-01 centos:latest
docker run -itd --name centos-bdg-02 centos:latest
// 会出现如下问题
docker exec -it centos-bdg-01 ping centos-bdg-02
ping: centos-bdg-02: Name or service not known
复制代码
docker network ls
列出本地网络模式docker network ls
NETWORK ID NAME DRIVER SCOPE
63d9493bce38 bridge bridge local # 桥接模式
de1105dfa5a8 host host local # host模式
87441a7540aa none null local # none模式
复制代码
docker network create
建立一个网络模式docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.1.0 mynet
336cdb202d7a5d7f1fb3f8dc087d5d6e1b7aa46b3513186c8cb35bc1125a0784
docker network ls
NETWORK ID NAME DRIVER SCOPE
63d9493bce38 bridge bridge local
de1105dfa5a8 host host local
336cdb202d7a mynet bridge local
87441a7540aa none null local
建立自定义模式的docker容器
docker run -itd --name centos-net-01 --network mynet centos:latest
docker run -itd --name centos-net-02 --network mynet centos:latest
再次执行 能够发现容器之间是互通的
docker exec -it centos-net-01 ping centos-net-02
PING centos-net-02 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.162 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.160 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.181 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.158 ms
复制代码
docker network inspect
显示一个或多个网络上的详细信息docker network connect
将容器链接到网络docker network connect [OPTIONS] NETWORK CONTAINER
目前环境中有一下几个容器 centos-bdg-xx 走原始的桥接模式的 docker0 网卡 网段实在 172.17.0.0/16 centos-net-xx 走的是自定义的mynet模式的 mynet网卡 网段 在 192.168.0.0/16
怎么实现 centos-bdg-xx 到 centos-net-- 的通讯
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1573b7088604 centos:latest "/bin/bash" 6 minutes ago Up 6 minutes centos-net-02
22a4f34fb7b8 centos:latest "/bin/bash" 6 minutes ago Up 6 minutes centos-net-01
22844f330ba3 centos:latest "/bin/bash" 25 minutes ago Up 25 minutes centos-bdg-02
8f7ae3be00e3 centos:latest "/bin/bash" 25 minutes ago Up 25 minutes centos-bdg-01
docker network connect mynet centos-bdg-01
docker exec -it centos-bdg-01 ping centos-net-01
PING centos-net-01 (192.168.0.1) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=2 ttl=64 time=0.161 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=3 ttl=64 time=0.202 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=4 ttl=64 time=0.153 ms
docker network inspect mynet
····
"Containers": {
"1573b70886040ce5922a0366e866bd6c5ac91acd851dd53dd43b2c2fbc388389": {
"Name": "centos-net-02",
"EndpointID": "968dd40f23362c3066df4092a2be6955c8681eaf38e07e505344492bc383a8c9",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"22a4f34fb7b8becd82719d16cecf84c54ca48bc184964042aecec74d18d1c931": {
"Name": "centos-net-01",
"EndpointID": "b2c7cf4d66fdeeea5559bd81fd3166bf78e0e3064e5016e71e51ba5543c5ded4",
"MacAddress": "02:42:c0:a8:00:01",
"IPv4Address": "192.168.0.1/16",
"IPv6Address": ""
},
// 容器链接到自定义网卡中
"8f7ae3be00e349005326d1fd4ff57fd0e19867b66a23bbc73c9568c9467b7c6f": {
"Name": "centos-bdg-01",
"EndpointID": "22427d81dc7386d04c7502ae90c99b812503e8514a13c1e89207435a2ec9ebb4",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
}
复制代码
docker network rm
移除一个网络模式docker network prune
删除全部未使用的网络**
docker run -itd --restart always --name portainer-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
复制代码