赞
踩
目录
8、Dockerfile中的命令COPY和ADD命令有什么区别?
32、无状态或有状态的应用程序,那个更适合Docker容器?
56、docker stack 和docker compose的区别?
59、docker stack 和docker compose的区别?
60、docker compose可以使用json来替代yaml么?
69、使用docker-compose时如何保证容器1先于容器2运行?
73、在容器退出后,我们使用docker ps命令无法查看,此时数据是否会丢失?
76、仓库(repository)、注册服务器(registry)、注册索引(index)之间有何关系?
77、从非官方仓库(如dl.dockerpool.com)下载镜像时,有时会提示【Error: Invaild registry endpoint...】?
80、docker与LXC(Linux container)有何不同?
Docker是一个容器化平台,以容器的形式将我们的应用程序及其所有依赖项打包在一起,以确保我们的应用程序在任何环境中无缝运行,可以理解为一个应用打包、分发、部署的工具。
我们也可以把它理解为一个轻量的虚拟机,Docker只虚拟我们的软件需要的运行环境,多余的一点都不要,而普通虚拟机则是一个完整而庞大的系统,包含各种不管我们要不要的软件。
我们需要明确的是,Docker不是虚拟化方法,它依赖于实际实现基于容器的虚拟化或操作系统级虚拟化的其他工具,为此,Docker最初使用LXC驱动程序,然后移动到libcontainer,现在重命名为runc。
Docker主要专注于在应用程序容器内自动部署应用程序,应用程序容器旨在打包和运行单个服务,而系统容器则设计为运行多个进程,如虚拟机。
因此,Docker被视为容器化系统上的容器管理或应用程序部署工具。
特性 | 普通虚拟机 | Docker |
---|---|---|
跨平台 | 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 | 支持的系统非常多,各类windows和Linux都支持 |
性能 | 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 | 性能好,只虚拟软件所需运行环境,最大化减少没用的配置 |
自动化 | 需要手动安装所有东西 | 一个命令就可以自动部署好所需环境 |
稳定性 | 稳定性不高,不同系统差异大 | 稳定性好,不同系统都一样部署方式 |
docker pull:拉取或者更新指定镜像
docker push:将镜像推送至远程仓库
docker rm:删除容器
docker rmi:删除镜像
docker images:列出所有镜像
docker ps:列出所有容器
Docker镜像是Docker容器的源代码,Docker镜像用于创建容器,可以使用build命令创建镜像。
镜像可以理解为是我们下载的gz或zip压缩包,只不过这个镜像文件中包括微型计算机(文件系统,网络)及其它内容,比如我们下载tomcat的镜像文件,其中就包括:微型计算机 + Tomcat环境+Jdk环境 = Tomcat镜像。
Docker镜像也可理解为是一个root文件系统,比如官方镜像ubuntu:16.04就包含完整的一套Ubuntu16.04最小系统的root文件系统。
Docker容器是镜像创建出来的一个运行的系统,也可以理解为是一个进程,其中包括应用程序及其所有依赖项,作为操作系统的独立进程运行。
镜像(Image)和容器(Container)的关系,可以更通俗的理解为是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。
运行、已暂停、重新启动、已退出
FROM:指定基础镜像
LABEL:功能是为镜像指定标签
RUN:运行指定的命令
CMD:容器启动时要运行的命令
COPY与ADD的区别COPY的SRC只能是本地文件,其他用法一致
当镜像用作另一个镜像构建的基础时,ONBUILD指令向镜像添加将在稍后执行的触发指令,如果要构建将用作构建其他镜像的基础的镜像(例如,可以使用特定于用户的配置自定义的应用程序构建环境或守护程序)。
打包:将软件运行所需的依赖&第三方库&软件打包到一起,变成一个安装包。
分发:将打包好的安装包上传到一个镜像仓库,其他人可以便捷的获取和安装。
部署:拿着“安装包”就可以一个命令运行起来个人的应用,自动模拟出一摸一样的运行环境,不管是在Windows/Mac/Linux环境。
应用程序的打包和发布
应用程序隔离
持续集成
部署微服务
快速搭建测试环境
提供PaaS平台级产品
秒级的交付和部署
保证环境一致性
高效的资源利用
弹性的伸缩
动态调度迁移成本低
使用最广泛的开源容器.
一种操作系统的虚拟化技术 linux 内核
依赖于Linux内核特性:NameSpace和Cgroups
一个简单的应用程序打包工具
提供简单的应用程序打包工具
开发人员和运维人员职责逻辑分离
多环境保持一致。消除了环境的差异。
docker cp 命令用于容器与主机之间的数据拷贝。
主机到容器:docker cp /www 96f7f14e99ab:/www/
容器到主机:docker cp 96f7f14e99ab:/www /tmp/
上面这个96f7f14e99ab是容器ID。
是Docker的本机群集,它将Docker主机池转变为单个虚拟Docker主机,Docker Swarm提供标准的Docker API,任何已经与Docker守护进程通信的工具都可以使用Swarm透明地扩展到多个主机。
容器是一种轻量级、可移植、自包含的软件打包技术,使得应用程序几乎可以在任何地方以相同的方式运行。
容器虚拟化:秒级启动,系统支持量为单机上千个容器,磁盘使用的单位一般为MB,性能接近原生。
传统虚拟化:分钟级启动,支持Linux、Windows、Mac操作系统,系统支持量一般为几十个,磁盘实验单位一般为GB,性能较弱。
表示命名空间隔离,主要就是将用户空间通过namespace技术隔离开,使得容器内的进程互不影响,共同使用一个内核。
资源限制、优先级分配、资源统计、任务控制
不能。
镜像:image,相当于是一个root文件系统。
容器:container,image和container的关系就像是面向对象程序设计里的类和实例,image是静态的定义,container是镜像运行时的实体。
仓库:repository,代码控制中心,用来保存image。
18.03.1-CE。
docker容器包括应用程序及其所有依赖项,其作为操作系统的独立进程运行。
运行、已暂停、重新启动、已退出。
每个容器都在自己的命名空间中运行,但使用与所有其它容器完全相同的内核,发生隔离是因为内核知道分配给进程的命名空间,并且在API调用期间确保进程只能访问自己命名空间内的资源。
操作系统的一个功能是允许将全局资源(如网络和磁盘)共享到进程,如果将这些全局资源包装在命名空间中,则可以使其仅对在同一命名空间中运行的进程可见。
启动Nginx容器(随机端口映射)并挂载本地文件目录到容器html的命令:
docker run -d -P --name nginx2 -v /home/nginx:/usr/share/nginx/html nginx
FROM:指定基础镜像。
RUN:运行指定的命令。
CMD:容器启动时要运行的命令。
WORKDIR:(默认在/根目录)终端登录进去的落脚点,类似于cd,如果无该目录,则自动创建后再cd进去。
ENV:设置环境常量,方便下文引用。
ONBUILD:触发器,当镜像用作另一个镜像构建的基础(例如可使用特定于用户的配置自定义的应用程序构建环境或守护程序)时,ONBUILD指令向镜像添加将在稍后执行的触发指令。
VOLUME:自建容器卷。
EXPOSE:当前容器对外界暴露出的端口。
LABEL:为镜像指定标签。
MAINTAINER:镜像维护者的姓名和邮箱地址。
COPY表示直接拷贝,ADD表示拷贝+解压功能。
详解如下:
二者都是只复制目录中的文件,而不包含目录本身。
COPY能干的事ADD都能干,甚至还有附加功能。
ADD可以支持拷贝的时候顺带解压缩文件,以及添加远程文件(不在本宿主机上的文件),COPY的<src>只能是本地文件
只是文件拷贝的话可以用COPY,有额外操作可以用ADD代替。
docker官方建议当要从远程复制文件时,尽量用curl/wget命令来代替ADD,因为用ADD的时候会创建更多的镜像层,镜像层的size也大。
通过添加到Linux内核版本2.6.24的名称空间功能,可实现容器的概念,容器将其ID添加到每个进程,并向每个系统调用添加心得访问控制检查,由clone()系统调用访问,该调用允许创建先前全局命名空间的单独实例。
如果由于Linux内核中可用的功能而可以使用容器,那么显而易见的问题是非Linux系统如何运行容器。
Docker for Mac和Windows都使用Linux VM来运行容器。
Docker Toolbox用于在Virtual Box VM中运行容器。
但docker早就在Windows中使用Hyper-V,在MAC中用Hypervisor.framework。
最好为Docker Container创建无状态应用程序,我们可以从应用程序中创建一个容器,并从应用程序中取出可配置的状态参数,现在我们可以在生产和具有不同参数的QA环境中运行相同的容器,这有助于在不同场景中重用相同的镜像,使用Docker Containers比使用有状态应用程序更容易扩展无状态应用程序。
volumes+环境变量注入+只读文件系统
是docker本级集群,它将docker主机池转变为单个虚拟docker主机,其提供标准的docker API,任何与docker守护进程通信的工具都可以使用swarm透明的扩展到多个主机。
在每次提交之后不断地集成所有提交到存储库的代码,并编译检查错误。
bind mount:直接把宿主机目录映射到容器内,适合挂代码目录和配置文件,可挂到多个容器上。
volume:由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据,可挂到多个容器上。
tmpfs mount:适合存储临时文件,存储在宿主机内存中,不可多容器共享。
要想多容器之间互通,从 Web 容器访问 Redis 容器,我们只需要把他们放到同个网络中就可以了。
先通过docker network create 网络名称,来创建虚拟网络,之后在启动各个服务的时候将其指定使用该网络就可以了。
也可以通过编写docker-compose的yaml配置文件,再使用docker-compose相关命令来运行相关服务。
在后台运行只需要加一个 -d 参数docker-compose up -d
查看运行状态:docker-compose ps
停止运行:docker-compose stop
重启:docker-compose restart
重启单个服务:docker-compose restart service-name
进入容器命令行:docker-compose exec service-name sh
查看容器运行log:docker-compose logs [service-name]
docker使用了常见的C/S架构,也就是client-sever模式,docker client复制处理用户输入的各种命令,如docker run、docker build等,但实际上真正工作的是docker server,也就是docker daemon,不过,我们可以发现,比较有意思的是docker client和docker daemon可以运行在同一台机器上。
docker守护进程运行在主机上,之后通过socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器,守护进程和客户端依然可以运行在同一台机器上。
Linux中的PID、IPC、网络资源是全局的,而namespace机制是一种资源隔离方案,在该机制下,这些资源就不再是全局的了,而是属于某个特定的namespace,各个namespace下的资源,互不干扰。
虽然有了namespace技术可以实现资源隔离,但进程还是可以不受控制的访问系统资源,比如CPU、内存、磁盘、网络等,于是我们就为了控制一下容器中进程对资源的访问,docker采用control groups技术,也就是cgroup,有了cgroup就可以控制容器中进程对资源的消耗了,比如控制某个容器使用内存的上线、可以在那个CPU上运行等等。
有了上面两项技术,容器看起来就像是独立的操作系统了。
docker client客户端、docker daemon守护进程、docker image镜像、docker contain容器,一共四部分。
docker attach方法。
使用exec命令:docker exec -i -t 784fd3b294d7 /bin/bash
docker image(docker镜像)实际上是由一层一层的文件系统组成,这种层级的文件系统就是unionFS,它是一种分层、轻量级并且高性能的文件系统,联合加载会将各层文件系统叠加起来,这样最终的文件系统就会包含所有底层的文件和目录。
虚拟化允许我们在相同的硬件上运行多个完全不同的操作系统,每个客户操作系统都经历了引导、加载内核等所有过程,我们可以拥有非常严格的安全性。
虚拟化方法分为三类:仿真、半虚拟化、基于容器的虚拟化。
是一个基于云的注册表服务,允许我们链接到代码存储库,构建镜像并测试它们,存储手动推送的镜像以及指向docker云的链接,以便我们可以将镜像部署到主机。
docker hub为整个开发流程中的容器镜像发现,分发和变更管理,用户和团队协作以及工作流自动化提供了集中资源。
docker使用了一系列不同的存储驱动来管理镜像内的文件系统并运行容器,这些存储驱动与docker卷(volume)有些不通。
存储引擎管理着能够在多个容器之间共享的存储。
当镜像被docker run命令创建时,就会在镜像最上层添加一个可写的层,也就是容器层,所有对于运行时容器的修改其实都是对这个容器读写层的修改。
容器和镜像的区别就在于所有镜像都是只读的,而每一个容器其实等于镜像加上一个可读写的层,也就是同一个镜像可以对应多个容器。
unionFS其实是一种为Linux操作系统设计的用于将多个文件系统联合到同一个挂载点的文件系统服务。
而AUFS也就是advanced unionFS其实就是unionFS的升级版本,它能够提供更加优秀的性能和效率。
AUFS只是docker使用的存储驱动的一种,除此之外docker还只吃了不同的存储驱动,如devicemapper、overlay2、ZFS和VFS等。
在最新的docker中,overlay2取代了AUFS成为推荐的存储驱动,但在没有该驱动的机器上,仍然会使用AUFS作为docker的默认驱动。
FROM 镜像:指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令。
MAINTAINER 名字:说明新镜像的维护人信息。
RUN 命令:在所基于的镜像上执行命令,并提交到新的镜像中。
CMD [“要运行的程序“,”参数1,“参数2“]:指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能最后一条被执行。
EXPOSE 端口号:指定新镜像加载到Docker时要开启的端口。
ENV 环境变量 变量值:设置一个环境变量的值,会被后面的RUN使用。
ADD 源文件/目录 目标文件/目录:将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL。
COPY 源文件/目录 目标文件/目录:将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中。
VOLUME [“目录“]:在容器中创建一个挂载点。
USER 用户名/UID:指定运行容器时的用户。
WORKDIR 路径:为后续的RUN、CMD、ENTRYPOINT指定工作目录。
ONBUILD 命令:指定所生成的镜像作为一个基础镜像时所要运行的命令。
HEALTHCHECK:健康检查。
ENTRYPOINT指令本身也可以包含参数,变动的参数不会被覆盖。
-d 指定容器为后台运行
-i 打开stdin,用于控制台交互
-t 可以支持只终端登录
-u 指定用户
-大P 随机生成端口
-小p 指定端口
方法一:通过docker的日志进行排查
docker logs 容器名称 查看docker容器日志
docker ps -a 查看容器的运行状态
docker rm 容器名称 删除容器
docker rmi 镜像名称 删除完之后从新构建镜像和容器
方法二:通过初始化的命令启动容器进行排查
awk '{if (NR%2==1){print NR}}' file3 //偶数行
awk '{if(NR%2==0){print NR}}' file3 //奇数行
awk 'NR==3{print}' | awk '{print $4}'
pod
label:标签
replication controller:生命pod副本的数量
replicaset:有状态
deployment:无状态
service:服务
volume:存储卷
namespace:命令空间
docker是单机使用的,无法有效集群。
随着容器数量的上升,管理成本也越来越高。
没有有效的容灾或是自愈机制。
没有预设编译模板,无法实现快速、大规模的容器调度。
没有统一的配置管理中心。
没有容器生命周期的管理工具。
没有图形化运维工具。
docker compose是单机部署的,集群部署可使用docker stack。
单机部署案例:docker-compose up -d xxx.yaml
集群部署案例:docker stack depoly xxx.yaml
docker在进行多服务部署和管理时通常用docker stack解决大规模部署管理问题。
docker在1.12版本集成docker swarm,内置新的容器编排工具docker stack,通过提供期望状态、滚动升级、简单易用、扩缩容、健康检查等特性简化应用的管理。
docker stack可以完成docker本身做不到的事情,就是它可以完成容器编排。
stack是swarm mode的一部分,即使是单机使用,也需要一个swarm节点,它强化了service的概念,服务可理解为发布到生产环境时某组容器的预期状态 ,以及强化了( 复制集、 容器重启策略、回滚策略、服务更新策略 )等生产特性。
stack不支持build指令,而docker compose不支持deploy指令。
docker stack几乎能做docker-compose所有的事情,不过后续统一还是使用kubernetes更香。
总而言之,docker stack适用于生产环境的编排工具,而docker-compose更适合被定义为单机容器编排的工具。
docker是单机使用的,无法有效集群。
随着容器数量的上升,管理成本也越来越高。
没有有效的容灾或是自愈机制。
没有预设编译模板,无法实现快速、大规模的容器调度。
没有统一的配置管理中心。
没有容器生命周期的管理工具。
没有图形化运维工具。
docker compose是单机部署的,集群部署可使用docker stack。
单机部署案例:docker-compose up -d xxx.yaml
集群部署案例:docker stack depoly xxx.yaml
docker在进行多服务部署和管理时通常用docker stack解决大规模部署管理问题。
docker在1.12版本集成docker swarm,内置新的容器编排工具docker stack,通过提供期望状态、滚动升级、简单易用、扩缩容、健康检查等特性简化应用的管理。
docker stack可以完成docker本身做不到的事情,就是它可以完成容器编排。
stack是swarm mode的一部分,即使是单机使用,也需要一个swarm节点,它强化了service的概念,服务可理解为发布到生产环境时某组容器的预期状态 ,以及强化了( 复制集、 容器重启策略、回滚策略、服务更新策略 )等生产特性。
stack不支持build指令,而docker compose不支持deploy指令。
docker stack几乎能做docker-compose所有的事情,不过后续统一还是使用kubernetes更香。
总而言之,docker stack适用于生产环境的编排工具,而docker-compose更适合被定义为单机容器编排的工具。
可以的,使用docker-compose -f docker-compose.json up命令。
容器编排的工具,允许我们跨越不同主机来管理多个容器。
我们可以使用swarm来将多个docker主机变成单个主机,以便于管理。
可使用docker pull <image_name>命令将镜像从docker hub拉倒本地系统。
帮助运维人员创建和运行虚拟机的软件,使我们能够使用单个主机来支持多个来宾虚拟机,管理程序通过划分主机的系统资源并将资源分配各已安装的来宾环境来实现这一点,所以我们可以在单个主机操作系统上安装多个操作系统。
管理程序有native和托管两种。
native:本机管理程序或裸机管理程序,直接在底层主机系统上运行,使我们可以直接访问主机系统的硬件,并且还不需要基本服务器操作系统。
托管:使用底层主机操作系统。
启动:docker start <container_id>
停止:docker stop <container_id>
终止:docker kill <container_id>
创建容器->运行容器->暂停容器(可选)->取消暂停容器(可选)->启动容器->停止容器->重启容器->杀死容器->销毁容器。
是存储为字符串的键值对,使我们能够将元数据添加到docker对象,例如容器、网络、本地守护进程、镜像、swarm节点和服务。
一种开源的容器化技术,可使用它来构建和容器化我们的应用程序,由docker引擎 rest api、docker命令行界面(CLI)、docker守护进程三个组件支持。
使用docker exec -it <container_id> bash命令。
docker-compose在继续下一个容器之前不会等待容器准备就绪,为了控制执行顺序,可使用【取决于(depends_on)】条件。
来看个在docker-compose.yaml文件中使用的示例:
- version: "2.4"
-
- services:
-
- backend:
-
- build: .
-
- depends_on:
-
- - db
-
- db:
-
- image: postgres
docker run IMAGE env
docker相关的本地资源存放在/var/lib/docker目录下,其中container目录存放的是容器信息,graph目录存放的是镜像信息,aufs目录存放的是具体的镜像底层文件。
整体上应当尽量保持镜像功能的明确和内容的精简。
应当尽量选取满足需求但有比较小的基础系统镜像,清理编译生成的文件、安装包的缓存等临时文件。
安装各个软件的时候应指定准确的版本号,避免引入不需要的依赖。
从安全的角度来看,应当尽量使用系统的库和依赖。
在我们使用dockerfile创建镜像的时候,需要添加.dockerignore文件或者使用干净的工作目录。
容器退出后会处于终止(exited)状态,此时可使用docker ps -a查看,此时数据不会丢失,还可通过docker start启动,只有删除容器之后才会清除数据。
这种操作方式我们一般是不推荐使用的,如果真的有了此类需求,建议还是使用额外的进程管理机制,比如我们可以使用supervisord来管理所有运行的进程。
使用docker create创建容器或使用docker run创建并运行容器时,可使用-c| -sup-share[=0]参数来调整同期使用CPU的权重,使用-m|-memory参数来调整容器使用内存的大小。
仓库(repository)是存放一组关联镜像的集合,如同一应用的不同版本的镜像,注册服务器(registry)则是存放实际的镜像的地方,注册索引(index)则是负责维护用户账号、权限、搜索、标签等相关功能的管理,注册服务器(registry)根据注册索引(index)来实现认证管理。
出现上述问题原因是因为docker自1.3.0版本之后,加强了对镜像安全性的校验,需手动添加对非官方镜像的信任(DOCKER_ORTS="-insecure-registry dl.dockerpool.com:5000"),之后重启docker服务。
Ubuntu系统下docker配置文件放在/etc/default/docker,centOS系统下docker配置文件放在/etc/sysconfig/docker。
docker默认存放位置是/var/lib/docker,如果我们希望将docker的本地文件存储到其它分区的话,可以使用Linux软连接的方式来做。
LXC利用Linux上的相关技术实现容器,docker则在部分地方做了优化。
首先在移植性上,docker通过抽象容器配置,使得容器可以从一个平台轻易地移植到另一个平台。
docker镜像系统基于AUFS的镜像系统为容器的分发带来很多便利,镜像层只需要存储一份,实现了高效率的存储。
docker的版本管理类似于GIT的版本管理理念,用户可以更方便的创建和管理镜像。
docker周边有各种各样的工具(如配置管理、云平台)对docker提供支持,以及基于docker的pass、CI等系统,使得docker的应用更加方便和多样。
首先我们应该明确的是两者的定位完全不同。
vagrant类似于boot2docker(一款运行docker的最小内核),是一套虚拟机的管理环境,vagrant可以在多种系统上和虚拟机中运行,可以在Windows、Mac等非Linux平台上为docker提供支持,自身具有很好的包装性和移植性。
原生docker自身只能运行在Linux平台上,但启动和运行的性能比虚拟机要快,往往更适合快速开发和部署应用的场景。
docker不是虚拟机,而是进程隔离,对于资源消耗很少,单一开发环境下vagrant是虚拟机上的封装,虚拟机本身会很消耗资源。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。