0基础学做网站,宝安龙华积分商城网站建设,微商网站,32套网站后台管理系统模板Docker介绍
容器历史
1、Chroot Jail 就是常见的chroot命令的用法。它在1979年的时候就出现了#xff0c;被认为是最早的容器化技术之一。它可以把一个进程的文件系统隔离起来。 2、The FreeBSD Jail #xff08;监狱#xff09;实现了操作系统级别的虚拟化#xff0c;他…Docker介绍
容器历史
1、Chroot Jail 就是常见的chroot命令的用法。它在1979年的时候就出现了被认为是最早的容器化技术之一。它可以把一个进程的文件系统隔离起来。 2、The FreeBSD Jail 监狱实现了操作系统级别的虚拟化他是操作系统级别虚拟化技术的先驱之一。2000年伴随FreeBSD4.0版的发布 3、Linux VServer http://linux-vserver.org 使用添加到Linux内核的系统级别的虚拟化功能实现的专用虚拟服务器。允许创建许多独立的虚拟专用服务器VPS这些虚拟专用服务器在单个物理服务器上全速同时运行从而有效地共享硬件资源。VPS提供与传统Linux服务器几乎相同的操作系统环境。可以在这样的VPS上启动所有服务例如ssh邮件Web和数据库服务器而无需或者在特殊情况下只需进行很少的修改就像在任何真实服务器上一样。每个VPS都有自己的用户账户数据库和root密码并且与其他虚拟机服务器隔离但它们共享相同的硬件资源。 4、Solaris Containers 也是操作系统级别的虚拟化技术专为X866和SPARC系统设计。Solaris容器是系统资源控制和通过“区域”提供边界隔离的组合。 5、OpenVZ 是一种Linux中操作系统级别的虚拟化技术。它允许创建多个安全隔离的Linux容器即VPS。 6、Process Containers 由Google的工程师开发一般被称为cgroups。 7、LXC 为Linux Container的简写。可以提供轻量级的虚拟化以便隔离进程和资源而且不需要提供指令解释机制以及全虚拟化的其他复杂性。容器有效地将由单个操作系统管理的资源划分到孤立的组中以更好地在孤立的组之间平衡有冲突的资源使用需求。Linux Container 提供了在单一可控主机节点上支持多个相互隔离的server Container同时执行的机制。Linux COntainer有点像chroot提供了一个拥有自己进程和网络空间的虚拟环境但又有别于虚拟机因为lxc是一种操作系统层次上的资源虚拟化。 8、Warden 在最初阶段Warden使用LXC作为容器运行时。如今已被CloudFoundy取代。 9、LMCTFY 是Google的容器技术栈的开源版本。Google的工程师一直在与docker的libertainer团队合作并将libertainerde核心概念进行抽象并移植到此项目中该项目的进展不明估计会被libcontainer取代。 10、Docker 是一个可以将应用及其依赖打包到几乎可以在任何服务器上运行的容器工具。 11、RKT 是Rocket的缩写他是一个专注安全和开放标准的应用程序引擎。 总上所述docker并不是第一个容器化技术但它确实最知名的一个。
Docker是什么
Docker码头工人是一个开源项目诞生于2013年初最初是dotCloud公司后由于Docker开源后大受欢迎就将公司名改为Docker Inc总部位于美国加州的旧金山内部的一个开源的PAAS服务的业余项目。它基于Google公司推出的Go语言实现。项目后来加入了Linux基金会遵从了Apache2.0协议项目代码在GitHub上进行维护。 Docker是基于Linux内核实现Docker是最早采用LXC技术LXC是Linux原生支持的容器技术可以提供轻量级的虚拟化可以说docker就是基于LXC发展起来的提供LXC的高级封装标准的配置方法在LXC的基础上docekr提供了一系列更强大的功能。而虚拟化技术KVM基于模块实现后来Docker改为自己研发并开源的runc技术运行容器彻底抛弃了LXC。 Docker相比虚拟机的交付速度更快资源消耗更低Docker采用客户端/服务端架构使用远程API来管理和创建容器其可以轻松的创建一个轻量级的、可移植的、自给自足的容器docker的三大理念是build构建、ship运输、run运行Docker遵从Apache2.0协议并通过namespace及cgroup等来提供容器的资源隔离与安全保障等所以Docker容器在运行时不需要类似虚拟机空运行的虚拟机占用物理机6%~8%性能的额外资源开销因此可以大幅提高资源利用率总而言之Docker是一种用了新颖方式实现的轻量级虚拟机类似于VM但是在原理和应用上和VM的差别还是很大的并且Docker的专业叫法是应用容器Application Container。 Docker的主要目标BuildShip and Run Any AppAnywhere即通过对应用组件的封装Packaging、分发Distribution、部署Deployment。运行Runtime等生命周期的管理达到应用组件级别的“一次封装到处运行”。这里的应用组件既可以是一个Web应用也可以是一套数据库服务甚至是一个操作系统。将应用运行在Docker容器上可以实现跨平台跨服务器只需一次配置准备好相关的应用环境即可实现到处运行保证研发和生产环境的一致性解决了应用和运行环境的兼容性问题从而极大提升了部署效率减少故障的可能性。 使用Docker容器化封装应用程序的意义
统一基础设施环境-docker环境 硬件的组成配置操作系统的版本运行时环境的异构 统一程序打包装箱方式-docker镜像 Java程序python程序nodejs程序 统一程序部署运行方式-docker容器 java -jar……—docker run ……python manage.py……—docker run ……npm run dev ……—docker run ……
Docker和虚拟机物理主机 容器和虚拟机比较
传统虚拟机是虚拟出一个主机硬件并且运行一个完整的操作系统然后在这个操作系统上安装和运行软件容器内的应用直接运行在宿主机的内核之上容器并没有自己的内核也不需要虚拟硬件相当轻量化每个容器间是互相隔离每个容器内都有一个属于自己的独立文件系统独立的进程空间网络空降用户空间等所以在同一个宿主机上的多个容器之间彼此不会互相影响
容器和虚拟机比较
资源利用率更高开销更小不需要启动单独的虚拟机OS内核占用硬件资源可以将服务器性能压榨到极致虚机一般会有5%~20%的损耗容器运行基本无损耗所以生产中一台物理机只能运行数十个虚拟机但是一般可以运行数百个容器启动速度更快可以在数秒内完成启动占用空间更小容器一般占用的磁盘空间以MB为单位而虚拟机以GB集成性更好和CI/CD持续集成/持续部署相关技术结合性更好实现打报警箱发布测试可以一键运行做到自动化并快速的部署管理实现高效的开发生命周期
使用虚拟机是为了更好的实现服务运行环境隔离每个虚拟机都有独立的内核虚拟化可以实现不同操作系统的虚拟机但是通常一个虚拟机只运行一个服务很明显资源利用率比较低且造成不必要的性能损耗我们创建虚拟机的目的是为了运行应用程序比如Nginx、PHP、Tomcat等web程序使用虚拟机无疑带来了一些不必要的资源开销但是容器技术则基于减少中间运行环节带来较大的性能提升。 根据实验一个运行着Centos的KVM虚机启动后在不做优化的情况下虚机自己就占用100~200M内存。此外用户应用运行在虚机里它对宿主机操作系统的调用就不可避免地要经过虚拟化软件的拦截和处理这本身又是一层性能损耗尤其对计算资源、网络和磁盘I/O的损耗非常大。 比如。一台96G内存的物理服务器为了运行java程序的虚拟机一般需要分配4核8G的资源只能运行13台左右的虚机但是改为在docker容器上运行Java程序每个容器只需要分配4G内存即可同样的物理服务器就可以运行25个左右的容器运行数量相当于提高一倍可以大幅节省IT支出通常情况下至少可以节约一半以上的物理设备
Docker的组成
Docker主机Host一个物理机或虚拟机用于运行Docker服务进程和容器也称为宿主机node节点Docker服务端ServerDocker守护进程运行Docker容器Docker客户端Client客户端使用docker命令或其他工具调用docker APIDocker镜像Images镜像可以理解为创建实例使用的模板本质上就是一些程序文件的集合Docker仓库Registry保存镜像的仓库可以搭建私有仓库harborDocker容器Container容器是从镜像生成对外提供服务的一个或一组服务其本质就是将镜像中的程序启动后生成进程 Namespace
一个宿主机运行了N个容器多个容器共用一个OS必然带来以下问题
怎样保证每个容器都有不同的文件系统并且互不影响一个docker主进程内的各个容器都是其子进程那么如何实现同一个主进程下不同类型的子进程各个容器子进程间能相互通信内存数据吗每个容器怎么解决IP及端口分配的问题多个容器的主机名能一样吗每个容器都要不要有root用户怎么解决账户重名问题
namespace是Linux系统的底层概念在内核层实现即有一些不同类型的命名空间被部署在核内各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核各docker容器运行在宿主机的用户空间每个容器都要有类似于虚拟机一样的相互隔离的运行空间但是容器技术是在一个进程内实现运行指定服务的运行环境并且还可以保护宿主机内核不受其他进程的干扰和影响如文件系统网络空间进城空间目前主要通过以下技术实现容器运行空间的相互隔离
隔离类型功能系统调用参数内核版本MNT Namespacemount提供磁盘挂载点和文件系统的隔离能力CLONE_NEWNS2.4.19IPC NamespaceInter Process Communication提供进程间通信的隔离能力包括信号量消息队列和共享内存CLONE_NEWIPC2.6.19UTS NamespaceUNIX Timesharing System提供内核主机名和域名隔离能力CLONE_NEWUTS2.6.19PID Namespace Process Identification提供进程隔离能力CLONE_NEWPID2.6.24Net Namespacenetwork提供网络隔离能力包括网络设备网络栈端口等CLONE_NEWNET2.6.29User Namespaceuser提供用户隔离能力包括用户和组CLONE_NEWUSER3.8
MNT Namespace
每个容器都要有独立的根文件系统有独立的用户空间以实现在容器里面启动服务并且使用容器的运行环境即一个宿主机是ubuntu的服务器可以在里面启动一个centos运行环境的容器并且在容器里面启动一个nginx服务此nginx运行时使用的运行环境就是centos系统目录的运行环境但是在容器里面是不能访问宿主机的资源宿主机是使用了chroot技术把容器锁定到一个指定的运行目录里面。
IPC Namespace
一个容器内的进程通信允许一个容器内的不同进程内存、缓存等数据访问但是不能跨容器直接访问其他容器的数据。
UTS Namespace
UTS namespace UNIX Timesharing System 包含了运行内核的名称、版本、底层体系结构类型等信息用于系统标识其中包含了主机名hostname和域名domainname它使得一个容器拥有属于自己主机名标识这个主机名标识独立于宿主机系统和其他上的机器。
PID Namespace
Linux系统中有一个PID为1的进程init/systemd是其他所有进程的父进程那么在每个容器内也要有一个父进程来管理下属的子进程那么多个容器的进程通PID namespace进程隔离比如PID编号重复、容器内的主进程生成与回收子进程等
NET Namespace
每一个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP协议栈等Docker使用network namespace启动一个vethX接口这样你的容器将拥有它自己的桥接IP地址通常是docker0而docker0实质就是Linux的虚拟网桥网桥是在OSI七层模型的数据链路层的网络设备通过mac地址对网络进行划分并且在不同网络直接传递数据。
User Namespace
各个容器内可能会出现重名的用户和用户组名称或重复的用户UID或者GID那么怎么隔离各个容器内的用户空间呢 User Namespace允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的用户UID和GID只是会把用户的作用范围限制在每个容器内即A容器和B容器可以有相同的用户名称和ID账户但是此用户的有效范围仅是当前容器内不能访问另外一个容器内的文件系统级相互隔离、互不影响、永不相见。
Control groups
Linux Cgroups的全称是Linux Control Groups是Linux内核的一个功能最早由Google的工程师主要是Paul Menage和Rohit Seth在2006年发起最早的名称为进程容器process containers。在2007年时因为在Linux内核中容器container这个名词有许多不同的意义为避免混乱被重命名为cgroup并且被合并到2.6.24版的内核中去。自那以后又添加了很多功能。 如果不对一个容器做任何资源限制则宿主机会允许其占用无限大的内存空间有时候会因为代码bug程序会一直申请内存直到把宿主机内存占完为了避免此类的问题出现宿主机有必要对容器进行资源分配限制比如CPU、内存等。 Cgroups最主要的作用就是限制一个进程组能够使用的资源上限包括CPU、内存、磁盘、网络带宽等。此外还能够对进程进行优先级设置资源的计量以及资源的控制比如将进程挂起和恢复等操作。
验证系统 cgroups
Cgroups在内核层默认已经开启从Centos和Ubuntu不同版本对比显然内核较新的支持的功能更多。 Centos7.4 cgroups
[rootjk-k8s ~]# cat /etc/redhat-releaseCentOS Linux release 7.4.1708 (Core)[rootjk-k8s ~]#[rootjk-k8s ~]# grep CGROUP /boot/config-3.10.0-693.el7.x86_64CONFIG_CGROUPSy# CONFIG_CGROUP_DEBUG is not setCONFIG_CGROUP_FREEZERyCONFIG_CGROUP_PIDSyCONFIG_CGROUP_DEVICEyCONFIG_CGROUP_CPUACCTyCONFIG_CGROUP_HUGETLByCONFIG_CGROUP_PERFyCONFIG_CGROUP_SCHEDyCONFIG_BLK_CGROUPy# CONFIG_DEBUG_BLK_CGROUP is not setCONFIG_NETFILTER_XT_MATCH_CGROUPmCONFIG_NET_CLS_CGROUPyCONFIG_NETPRIO_CGROUPy[rootjk-k8s ~]#cgroups中内存模块
[rootjk-k8s ~]# grep MEMCG /boot/config-3.10.0-693.el7.x86_64CONFIG_MEMCGyCONFIG_MEMCG_SWAPyCONFIG_MEMCG_SWAP_ENABLEDyCONFIG_MEMCG_KMEMycgroups具体实现
blkio块设备IO限制cpu使用调度程序为cgroup任务提供CPU访问cpuacct产生cgroup任务的CPU资源报告cpuset如果是多核心的cpu这个子系统会为cgroup任务分配单独的cpu和内存devices允许或拒绝cgroup任务对设备访问freezer暂停和恢复cgroup任务memory设置每个cgroup的内存限制以及产生内存资源报告net_cls标记每个网络包以供cgroup方便使用ns命名空间子系统perf_event增加了对每group的检测跟踪的能力可以检测属于某个特定的group的所有线程以及运行在特定CPU上的线程
查看系统cgroups
[rootjk-k8s ~]# ll /sys/fs/cgroup/总用量 0drwxr-xr-x 5 root root 0 8月 19 09:46 blkiolrwxrwxrwx 1 root root 11 8月 19 09:46 cpu - cpu,cpuacctlrwxrwxrwx 1 root root 11 8月 19 09:46 cpuacct - cpu,cpuacctdrwxr-xr-x 5 root root 0 8月 19 09:46 cpu,cpuacctdrwxr-xr-x 3 root root 0 8月 19 09:46 cpusetdrwxr-xr-x 5 root root 0 8月 19 09:46 devicesdrwxr-xr-x 3 root root 0 8月 19 09:46 freezerdrwxr-xr-x 3 root root 0 8月 19 09:46 hugetlbdrwxr-xr-x 5 root root 0 8月 19 09:46 memorylrwxrwxrwx 1 root root 16 8月 19 09:46 net_cls - net_cls,net_priodrwxr-xr-x 3 root root 0 8月 19 09:46 net_cls,net_priolrwxrwxrwx 1 root root 16 8月 19 09:46 net_prio - net_cls,net_priodrwxr-xr-x 3 root root 0 8月 19 09:46 perf_eventdrwxr-xr-x 3 root root 0 8月 19 09:46 pidsdrwxr-xr-x 5 root root 0 8月 19 09:46 systemd[rootjk-k8s ~]#[rootjk-k8s ~]# cat /sys/fs/cgroup/cpu/docker/5a1b43275caa1f8c9fff9ea8ccd3813d4a25acf698f15a3ec5eacd77948833b5/cpuacct.usage109845268[rootjk-k8s ~]#[rootjk-k8s ~]# cat /sys/fs/cgroup/memory/docker/5a1b43275caa1f8c9fff9ea8ccd3813d4a25acf698f15a3ec5eacd77948833b5/memory.limit_in_bytes9223372036854771712[rootjk-k8s ~]# cat /sys/fs/cgroup/memory/docker/5a1b43275caa1f8c9fff9ea8ccd3813d4a25acf698f15a3ec5eacd77948833b5/memory.max_usage_in_bytes12566528[rootjk-k8s ~]#容器管理工具
LXC
官网https://linuxcontainers.org Linux Container 可以提供轻量级的虚拟化功能以便隔离进程和资源包括一系列容器的管理工具软件如lxc-createlxc-startlxc-attach等但这技术功能不完善目前较少使用。
docker
docker相当于增强版的LXC功能更为强大和易用也是当前最主流的容器前端管理工具 docker先启动一个容器也需要一个外部模板也称为镜像docker的镜像可以保存在一个公共的地方共享使用只要把镜像下载下来就可以使用最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像一个镜像可以被启动为多个容器。 docker的镜像是分层的镜像底层为库文件且只读层即不能写入也不能删除数据从镜像加载启动为一个容器后会生成一个可写层其写入的数据会复制到宿主机上对应容器的目录但是容器内的数据在删除容器后也会被随之删除。
pouch
https://github.com/alibaba/pouch Pouch小袋子起源于2011年并于2017年11月19日上午在中国开源年会现场阿里巴巴正式开源了基于Apache2.0协议的容器技术Pouch。Pouch是一款轻量级的容器技术拥有快速高效、可移植性高、资源占用少等特性主要帮助阿里更快的做到内部业务的交付同时提高超大规模下数据中心的物理资源利用率 目前的容器方案大多基于Linux内核提供的cgroup和namespace来实现隔离然后这样轻量级方案存在弊端
容器间容器与宿主机间共享一个内核内核实现的隔离资源维度不足
面对如此的内核现状阿里巴巴采取了三个方面的工作来解决容器的安全问题
增强容器的隔离维度比如网络带宽、磁盘使用量给内核提交patch修复容器的资源可见性问题cgroup方面的bug实现基于Hypervisor的容器通过创建新内核来实现容器隔离
Podman
https://podman.io 虽然目前docker是管理Linux容器最好的耳工具注意没有之一但是podman的横空出现即将改变这一点 什么是Podman Podman即Pod Manager tool从名称上可以看出和kubernets的pod的密切联系不过就其功能来说简言之alias docker podman是centos8新集成的功能或许不就的未来会替代docker Podman是一个为Kubernetes而生的开源的容器管理工具原来是CRI-O即容器运行时接口CRI和开放容器计划OCI项目的一部分后来被分离成一个单独的项目叫libpod。其可在大多数Linux平台上使用它是一种无守护程序的容器引擎用于在Linux系统上开发管理和运行任何符合Open Container InitiativeOCI标准的容器和容器镜像。 Podman提供了一个与docker兼容的命令前端Podman里面87%的指令都和docker cli相同因此可以简单地为docker cli别名即“alias docker podman”事实上podman使用的一些库也是docker的一部分。
Podman和docker不同之处
docker需要在系统上运行一个守护进程docker daemon这会产生一定的开销而podman不需要启动容器的方式不同 docker cli 命令通过 API 跟 docker engine引擎交互告诉它我想创建一个 container然后 docker engine 才会调用 OCI containner runtimerunc 来启动一个container。这代表container的process进程不会是docker cli 的chlid process子进程而是Docker Engine 的 child process。Podman是直接给OCI container runtimerunc进行交互来创建container的所以container process 直接是podman的child process。因为docker有docker daemon所以docker启动的容器支持 –restart策略但是podman不支持docker需要使用root用户来创建容器这可能会产生安全风向尤其是当用户知道docker run命令的 –privileged选项时。podman既可以由root用户运行也可以由非特权用户运行docker在Linux上作为守护进程运行扼杀了容器社区的创新。如果要更改容器的工作方式则需要更改docker守护程序并将这些更改推送到上游。没有守护进程容器基础结构更加模块化更容易进行更改。podman的无守护进程架构更加灵活和安全。
Docker的优势
快速部署短时间内可以部署成百上千个应用更快速交付到线上高效虚拟化不需要额外hypervisor支持基于Linux内核实现应用虚拟化相比虚拟机大幅提高性能和效率节省开支提高服务器利用率降低IT支持简化配置将运行环境打包保存至容器使用时直接启动即可环境统一将开发测试生产的应用运行环境进行标准化统一减少环境不一样带来的各种问题快速迁移和扩展可实现跨平台运行物理机、虚拟机、公有云等环境良好的兼容性可以方便将应用从A宿主机迁移到B宿主机甚至是A平台迁移到B平台更好的实现面向服务的架构推荐一个容器只运行一个应用实现分布的应用模型可以方便的进行横向扩展符合开发中高内聚低耦合的要求减少不同服务器之间的相互影响
Docker的缺点
多个容器共用宿主机的内核各应用之间的隔离不如虚拟机彻底由于和宿主机之间的进程也是隔离的需要进入容器查看和调试容器内进程等资源变得比较困难和繁琐如果容器内进程需要查看和调试需要在每个容器内都需要安装相应的工具这也造成存储空间的重复浪费
容器的核心技术
容器规范
OCI官网https://opencontainers.org 容器技术除了docker之外还有coreOS的rkt还有阿里的Pouch为了保证容器生态的标准性和健康可持续发展包括Linux基金会、Docker、微软、红帽、谷歌和IBM等公司在2015年6月共同成立了一个叫Open Container InitiativeOCI的组织其目的就是制定开放的标准的容器规范目前OCI一共发布了两个规范分别是runtime spec和image format spec有了这两个规范不同的容器公司开发的容器只要兼容这两个规范就可以保证容器的可移植性和相互可操作性性。
容器runtime
runtime是真正运行容器的地方因此为了运行不同的容器runtime需要和操作系统内核紧密合作相互在支持以便为容器提供相应的运行环境 runtime类型
LXCLinux上早期的runtime在2013年docker刚发布的时候就是采用lxc作为runtimedocker把lxc复杂的容器创建与使用方式简化为docker自己的一套命令体系。随着docker的发展原有的lxc不能满足docker的需求比如跨平台功能Libcontainer随着docker的不断发展重新定义容器的实现标准将底层实现都抽象化到Libcontainer的接口。这就意味着底层容器的实现方式变成了一种可变的方案无论是使用namespace、cgroups技术抑或是使用systemd等其他方案只要实现了Lincontainer定义的一组接口docker都可以运行。这也为docker实现全面的跨平台带来了可能。runc早期libcontainer是docker公司控制的一个开源项目OCI的成立后docker把libcontainer项目移交给了OCI组织runc就是在libcontainer的基础上进化而来是目前docker默认的runtimerunc遵守OCI规范rkt是CoreOS开发的容器runtime也符合OCI规范所以使用rktruntime也可以运行docker容器
容器管理工具
管理工具连接runtime与用户对用户提供图形或命令方式操作然后管理工具将用户操作传递给runtime执行。
lxc是lxd的管理工具Runc的管理工具是docker enginedocker engine包含后台deamon和cli两部分大家经常提到的docker就是指的docker enginerkt的管理工具是 rkt cli
容器定义工具
容器定义工具允许用户定义容器的属性和内容以方便容器能够被保存、共享和重建。 Docker image是docker容器的模板runtime依据docker image创建容器 Dockerfile包含N个命令的文本文件通过dockerfile创建出docker image ACIApp container image与docker image类似是CoreOS开发的rkt容器的镜像格式
镜像仓库
统一保存镜像而且是多个不同镜像版本的地方叫做镜像仓库
Docker hubdocker官方的公共仓库已经保存了大量的常用镜像可以方便大家直接使用阿里云网易等第三方镜像的公共仓库Image registrydocker官方提供的私有仓库部署工具无web管理界面目前使用较少Harborvmware提供自带web界面自带认证功能的镜像私有仓库目前有很多公司使用
容器编排工具
当多个容器在多个主机运行的时候单独管理容器是相当复杂而且很容易出错而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的也无法实现动态伸缩功能因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能这就是容器编排引擎 容器编排通常包括容器管理、调度、集群定义和服务发现等功能
Docker composedocker官方实现单机容器的编排工具Docker swarmdocker官方开发的容器编排引擎支持overlay networkMesosMarathonMesos是Apache下的开源分布式资源管理框架它被称为是分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发的后在Twitter得到广泛使用。通用的集群组员调度平台Mesos资源分配与marathon容器编排平台一起提供容器编排引擎功能KubernetesGoogle领导开发的容器编排引擎内部项目为Borg且其同时支持docker和CoreOS当前已成为容器编排工具的标准
docker依赖的技术
容器网络
docker自带的网络docker network仅支持管理单机的容器网络当多主机运行的时候需要使用第三方开源网络例如calico、flannel等
服务发现
容器的动态扩容特性决定了容器IP也会随之变化因此需要有一种机制开源自动识别并将用户请求动态转发到新创建的容器上Kubernetes自带服务发现功能需要结合kube-dns服务解析内部域名
容器监控
可以通过原生命令docker ps/top/stats查看容器运行状态另外可以使用prometheus、heapster等第三方监控工具监控容器的运行状态
数据管理
容器的动态迁移会导致其在不同的host之前迁移因此如何保证与容器相关的数据也能随之迁移或随时访问可以使用逻辑卷/存储挂载等方式解决
日志收集
docker原生的日志查看工具docker logs但是容器内部的日志需要通过ELK等专门的日志收集分析和展示工具进行处理
Docker安装及基础命令介绍
Docker安装准备
https://www.docker.com OS版本的选择 docker目前支持多种操作系统的安装运行如CentosUbuntuRedhatDebianFedoraMacWindows在Linux系统上需要内核版本在3.10或以上 docker版本选择 docker版本号之前一直是0.x版本或1.x版本从2017年3月1号开始改为每个季度发布一次稳定版其版本号规则也统一变更为YY.MM例如20.10表示2020年10月发布的 docker之前没有区分版本但是2017年推出将docker更名为新的项目Mobygithub地址https://github.com/moby/moby Moby项目属于Docker项目全新上游docker将是一个隶属于Moby的子产品而且之后的版本开始区分CEDocker Community Edition社区版本和EEDocker Enterprise Edition企业收费版,CE社区版和EE企业版都是每个季度发布一个新版本但是EE版提供后期安全维护1年而CE版是4个月。
安装和删除方法
官方文档https://docs.docker.com/engine/install/ 阿里云文档https://developer.aliyun.com/mirror/docker-ce?spma2c6h.13651102.0.0.3e221b11guHCWE
Centos安装和删除docker
官方文档https://docs.docker.com/engine/install/centos/ CentOS 6 因内核太旧即使支持安装docker但会有各种问题不建议安装 CentOS 7的extras源虽然可以安装docker但包比较旧建议从官方源或镜像源站点下载安装docker CentOS 8 有新技术podman代替docker 因此建议在CentOS 7 上安装 docker
# extras 源中包名为docker[rootcentos7 ~]# yum list docker已加载插件fastestmirrorLoading mirror speeds from cached hostfile* base: mirrors.bupt.edu.cn* extras: mirrors.neusoft.edu.cn* updates: mirrors.nju.edu.cn可安装的软件包docker.x86_64 2:1.13.1-209.git7d71120.el7.centos extras下载rpm包安装
官方rpm包下载地址https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ 阿里镜像下载地址https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/
通过yum源安装
由于官网yum源太慢下面使用阿里云的yum源进行安装
rm -rf /etc/yum.repos.d/*# centos 7 安装docker依赖三个yum源BaseExtrasdocker-cewget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repowget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repowget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum clean allyum install docker-ce -ysystemctl enable --now docker删除docker
yum remove docker-ce# 删除docker资源存放的相关文件rm -ef /var/lib/dockerDocker 程序环境
Centos7 查看docker相关文件
[rootcentos ~]# rpm -ql docker-ce/usr/bin/docker-init/usr/bin/docker-proxy/usr/bin/dockerd/usr/lib/systemd/system/docker.service/usr/lib/systemd/system/docker.socket[rootcentos ~]#[rootcentos ~]# rpm -ql docker-ce/usr/bin/docker-init/usr/bin/docker-proxy/usr/bin/dockerd/usr/lib/systemd/system/docker.service/usr/lib/systemd/system/docker.socket[rootcentos ~]#[rootcentos ~]# rpm -ql docker-ce-cli/usr/bin/docker/usr/libexec/docker/cli-plugins/docker-app/usr/libexec/docker/cli-plugins/docker-buildx/usr/share/bash-completion/completions/docker/usr/share/doc/docker-ce-cli-20.10.17/usr/share/doc/docker-ce-cli-20.10.17/LICENSE/usr/share/doc/docker-ce-cli-20.10.17/MAINTAINERS/usr/share/doc/docker-ce-cli-20.10.17/NOTICE/usr/share/doc/docker-ce-cli-20.10.17/README.md/usr/share/fish/vendor_completions.d/docker.fish/usr/share/man/man1/docker-attach.1.gz/usr/share/man/man1/docker-build.1.gz/usr/share/man/man1/docker-builder-build.1.gz/usr/share/man/man1/docker-builder-prune.1.gz/usr/share/man/man1/docker-builder.1.gz/usr/share/man/man1/docker-checkpoint-create.1.gz/usr/share/man/man1/docker-checkpoint-ls.1.gz/usr/share/man/man1/docker-checkpoint-rm.1.gz/usr/share/man/man1/docker-checkpoint.1.gz/usr/share/man/man1/docker-commit.1.gz/usr/share/man/man1/docker-config-create.1.gz/usr/share/man/man1/docker-config-inspect.1.gz/usr/share/man/man1/docker-config-ls.1.gz/usr/share/man/man1/docker-config-rm.1.gz/usr/share/man/man1/docker-config.1.gz/usr/share/man/man1/docker-container-attach.1.gz/usr/share/man/man1/docker-container-commit.1.gz/usr/share/man/man1/docker-container-cp.1.gz/usr/share/man/man1/docker-container-create.1.gz/usr/share/man/man1/docker-container-diff.1.gz/usr/share/man/man1/docker-container-exec.1.gz/usr/share/man/man1/docker-container-export.1.gz/usr/share/man/man1/docker-container-inspect.1.gz/usr/share/man/man1/docker-container-kill.1.gz/usr/share/man/man1/docker-container-logs.1.gz/usr/share/man/man1/docker-container-ls.1.gz/usr/share/man/man1/docker-container-pause.1.gz/usr/share/man/man1/docker-container-port.1.gz/usr/share/man/man1/docker-container-prune.1.gz/usr/share/man/man1/docker-container-rename.1.gz/usr/share/man/man1/docker-container-restart.1.gz/usr/share/man/man1/docker-container-rm.1.gz/usr/share/man/man1/docker-container-run.1.gz/usr/share/man/man1/docker-container-start.1.gz/usr/share/man/man1/docker-container-stats.1.gz/usr/share/man/man1/docker-container-stop.1.gz/usr/share/man/man1/docker-container-top.1.gz/usr/share/man/man1/docker-container-unpause.1.gz/usr/share/man/man1/docker-container-update.1.gz/usr/share/man/man1/docker-container-wait.1.gz/usr/share/man/man1/docker-container.1.gz/usr/share/man/man1/docker-context-create.1.gz/usr/share/man/man1/docker-context-export.1.gz/usr/share/man/man1/docker-context-import.1.gz/usr/share/man/man1/docker-context-inspect.1.gz/usr/share/man/man1/docker-context-ls.1.gz/usr/share/man/man1/docker-context-rm.1.gz/usr/share/man/man1/docker-context-update.1.gz/usr/share/man/man1/docker-context-use.1.gz/usr/share/man/man1/docker-context.1.gz/usr/share/man/man1/docker-cp.1.gz/usr/share/man/man1/docker-create.1.gz/usr/share/man/man1/docker-diff.1.gz/usr/share/man/man1/docker-events.1.gz/usr/share/man/man1/docker-exec.1.gz/usr/share/man/man1/docker-export.1.gz/usr/share/man/man1/docker-history.1.gz/usr/share/man/man1/docker-image-build.1.gz/usr/share/man/man1/docker-image-history.1.gz/usr/share/man/man1/docker-image-import.1.gz/usr/share/man/man1/docker-image-inspect.1.gz/usr/share/man/man1/docker-image-load.1.gz/usr/share/man/man1/docker-image-ls.1.gz/usr/share/man/man1/docker-image-prune.1.gz/usr/share/man/man1/docker-image-pull.1.gz/usr/share/man/man1/docker-image-push.1.gz/usr/share/man/man1/docker-image-rm.1.gz/usr/share/man/man1/docker-image-save.1.gz/usr/share/man/man1/docker-image-tag.1.gz/usr/share/man/man1/docker-image.1.gz/usr/share/man/man1/docker-images.1.gz/usr/share/man/man1/docker-import.1.gz/usr/share/man/man1/docker-info.1.gz/usr/share/man/man1/docker-inspect.1.gz/usr/share/man/man1/docker-kill.1.gz/usr/share/man/man1/docker-load.1.gz/usr/share/man/man1/docker-login.1.gz/usr/share/man/man1/docker-logout.1.gz/usr/share/man/man1/docker-logs.1.gz/usr/share/man/man1/docker-manifest-annotate.1.gz/usr/share/man/man1/docker-manifest-create.1.gz/usr/share/man/man1/docker-manifest-inspect.1.gz/usr/share/man/man1/docker-manifest-push.1.gz/usr/share/man/man1/docker-manifest-rm.1.gz/usr/share/man/man1/docker-manifest.1.gz/usr/share/man/man1/docker-network-connect.1.gz/usr/share/man/man1/docker-network-create.1.gz/usr/share/man/man1/docker-network-disconnect.1.gz/usr/share/man/man1/docker-network-inspect.1.gz/usr/share/man/man1/docker-network-ls.1.gz/usr/share/man/man1/docker-network-prune.1.gz/usr/share/man/man1/docker-network-rm.1.gz/usr/share/man/man1/docker-network.1.gz/usr/share/man/man1/docker-node-demote.1.gz/usr/share/man/man1/docker-node-inspect.1.gz/usr/share/man/man1/docker-node-ls.1.gz/usr/share/man/man1/docker-node-promote.1.gz/usr/share/man/man1/docker-node-ps.1.gz/usr/share/man/man1/docker-node-rm.1.gz/usr/share/man/man1/docker-node-update.1.gz/usr/share/man/man1/docker-node.1.gz/usr/share/man/man1/docker-pause.1.gz/usr/share/man/man1/docker-plugin-create.1.gz/usr/share/man/man1/docker-plugin-disable.1.gz/usr/share/man/man1/docker-plugin-enable.1.gz/usr/share/man/man1/docker-plugin-inspect.1.gz/usr/share/man/man1/docker-plugin-install.1.gz/usr/share/man/man1/docker-plugin-ls.1.gz/usr/share/man/man1/docker-plugin-push.1.gz/usr/share/man/man1/docker-plugin-rm.1.gz/usr/share/man/man1/docker-plugin-set.1.gz/usr/share/man/man1/docker-plugin-upgrade.1.gz/usr/share/man/man1/docker-plugin.1.gz/usr/share/man/man1/docker-port.1.gz/usr/share/man/man1/docker-ps.1.gz/usr/share/man/man1/docker-pull.1.gz/usr/share/man/man1/docker-push.1.gz/usr/share/man/man1/docker-rename.1.gz/usr/share/man/man1/docker-restart.1.gz/usr/share/man/man1/docker-rm.1.gz/usr/share/man/man1/docker-rmi.1.gz/usr/share/man/man1/docker-run.1.gz/usr/share/man/man1/docker-save.1.gz/usr/share/man/man1/docker-search.1.gz/usr/share/man/man1/docker-secret-create.1.gz/usr/share/man/man1/docker-secret-inspect.1.gz/usr/share/man/man1/docker-secret-ls.1.gz/usr/share/man/man1/docker-secret-rm.1.gz/usr/share/man/man1/docker-secret.1.gz/usr/share/man/man1/docker-service-create.1.gz/usr/share/man/man1/docker-service-inspect.1.gz/usr/share/man/man1/docker-service-logs.1.gz/usr/share/man/man1/docker-service-ls.1.gz/usr/share/man/man1/docker-service-ps.1.gz/usr/share/man/man1/docker-service-rm.1.gz/usr/share/man/man1/docker-service-rollback.1.gz/usr/share/man/man1/docker-service-scale.1.gz/usr/share/man/man1/docker-service-update.1.gz/usr/share/man/man1/docker-service.1.gz/usr/share/man/man1/docker-stack-deploy.1.gz/usr/share/man/man1/docker-stack-ls.1.gz/usr/share/man/man1/docker-stack-ps.1.gz/usr/share/man/man1/docker-stack-rm.1.gz/usr/share/man/man1/docker-stack-services.1.gz/usr/share/man/man1/docker-stack.1.gz/usr/share/man/man1/docker-start.1.gz/usr/share/man/man1/docker-stats.1.gz/usr/share/man/man1/docker-stop.1.gz/usr/share/man/man1/docker-swarm-ca.1.gz/usr/share/man/man1/docker-swarm-init.1.gz/usr/share/man/man1/docker-swarm-join-token.1.gz/usr/share/man/man1/docker-swarm-join.1.gz/usr/share/man/man1/docker-swarm-leave.1.gz/usr/share/man/man1/docker-swarm-unlock-key.1.gz/usr/share/man/man1/docker-swarm-unlock.1.gz/usr/share/man/man1/docker-swarm-update.1.gz/usr/share/man/man1/docker-swarm.1.gz/usr/share/man/man1/docker-system-df.1.gz/usr/share/man/man1/docker-system-events.1.gz/usr/share/man/man1/docker-system-info.1.gz/usr/share/man/man1/docker-system-prune.1.gz/usr/share/man/man1/docker-system.1.gz/usr/share/man/man1/docker-tag.1.gz/usr/share/man/man1/docker-top.1.gz/usr/share/man/man1/docker-trust-inspect.1.gz/usr/share/man/man1/docker-trust-key-generate.1.gz/usr/share/man/man1/docker-trust-key-load.1.gz/usr/share/man/man1/docker-trust-key.1.gz/usr/share/man/man1/docker-trust-revoke.1.gz/usr/share/man/man1/docker-trust-sign.1.gz/usr/share/man/man1/docker-trust-signer-add.1.gz/usr/share/man/man1/docker-trust-signer-remove.1.gz/usr/share/man/man1/docker-trust-signer.1.gz/usr/share/man/man1/docker-trust.1.gz/usr/share/man/man1/docker-unpause.1.gz/usr/share/man/man1/docker-update.1.gz/usr/share/man/man1/docker-version.1.gz/usr/share/man/man1/docker-volume-create.1.gz/usr/share/man/man1/docker-volume-inspect.1.gz/usr/share/man/man1/docker-volume-ls.1.gz/usr/share/man/man1/docker-volume-prune.1.gz/usr/share/man/man1/docker-volume-rm.1.gz/usr/share/man/man1/docker-volume.1.gz/usr/share/man/man1/docker-wait.1.gz/usr/share/man/man1/docker.1.gz/usr/share/man/man5/Dockerfile.5.gz/usr/share/man/man5/docker-config-json.5.gz/usr/share/man/man8/dockerd.8.gz/usr/share/zsh/vendor-completions/_dockerDocker 命令帮助
官方文档https://docs.docker.com/reference/ docker命令是最常使用的docker客户端命令其后面可以加不同的参数以实现不同的功能
# docker 命令格式# COMMAND 分为 # Management Commands 指定管理员的资源对象类型较新的命令用法将命令按资源类型进行分类方便使用# Commands 对不同资源操作的命令不分类使用容易产生混乱docker [OPTIONS] COMMAND# docker 命令有很多子命令可以用下面方法查看帮助# docker 命令帮助man dockerdockerdocker --help# docker 子命令帮助man docker -COMMANDdocker COMMAND --help查看docker相关信息
查看docker版本
[rootcentos ~]# docker versionClient: Docker Engine - CommunityVersion: 20.10.17API version: 1.41Go version: go1.17.11Git commit: 100c701Built: Mon Jun 6 23:05:12 2022OS/Arch: linux/amd64Context: defaultExperimental: trueServer: Docker Engine - CommunityEngine:Version: 20.10.17API version: 1.41 (minimum version 1.12)Go version: go1.17.11Git commit: a89b842Built: Mon Jun 6 23:03:33 2022OS/Arch: linux/amd64Experimental: falsecontainerd:Version: 1.6.7GitCommit: 0197261a30bf81f1ee8e6a4dd2dea0ef95d67ccbrunc:Version: 1.1.3GitCommit: v1.1.3-0-g6724737docker-init:Version: 0.19.0GitCommit: de40ad0查看docker详细信息
[rootcentos ~]# docker info
Client:Context: defaultDebug Mode: false # client端是否开启debugPlugins:app: Docker App (Docker Inc., v0.9.1-beta3)buildx: Docker Buildx (Docker Inc., v0.8.2-docker)scan: Docker Scan (Docker Inc., v0.17.0)Server:Containers: 0 # 当前主机运行的容器总数Running: 0 # 正在运行的容器个数Paused: 0 # 暂停的容器个数Stopped: 0 # 停止的容器个数Images: 0 # 当前服务器的镜像个数Server Version: 20.10.17 # 服务端版本Storage Driver: overlay2 # 正在使用的存储引擎Backing Filesystem: xfs # 后端文件系统即服务器的磁盘文件系统Supports d_type: true # 是否支持 d_typeNative Overlay Diff: true # 是否支持差异数据存储userxattr: falseLogging Driver: json-file # 日志类型Cgroup Driver: cgroupfs # Cgroups类型Cgroup Version: 1Plugins: # 插件Volume: local # 卷Network: bridge host ipvlan macvlan null overlay # overlay 跨主机通信Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog # 日志类型Swarm: inactive # 是否支持 swarmRuntimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runcDefault Runtime: runc # 默认使用的容器运行时Init Binary: docker-init # 初始化容器的守护进程即pid为1的进程containerd version: 0197261a30bf81f1ee8e6a4dd2dea0ef95d67ccb # 版本runc version: v1.1.3-0-g6724737 # runc版本init version: de40ad0 # init 版本Security Options: # 安全选项seccomp # 安全计算模块即制容器操作Profile: default # 默认的配置文件Kernel Version: 3.10.0-693.el7.x86_64 # 宿主机内核版本Operating System: CentOS Linux 7 (Core) # 宿主机操作系统OSType: linux # 宿主机操作系统类型Architecture: x86_64 # 宿主机架构CPUs: 2 # 宿主机CPU数量Total Memory: 1.792GiB # 宿主机总内存Name: centos # 宿主机 hostnameID: E66M:LPI3:YB2Z:LJKN:LNB2:P7Z3:6HYX:DSFF:KISM:SSJX:PVIF:B2ZM # 宿主机 IDDocker Root Dir: /var/lib/docker # 宿主机关于docker数据的保存目录Debug Mode: false # server 端是否开启debugRegistry: https://index.docker.io/v1/ # 仓库路径Labels:Experimental: false # 是否是测试版Insecure Registries: 127.0.0.0/8 # 非安全的镜像库Live Restore Enabled: false # 是否开启活动重启 重启docker-daemon 不关闭容器查看docker0网卡
在docker安装启动后默认会生成一个名称为docker0的网卡且默认IP地址为172.17.0.1
Docker存储引擎
AUFS是一种UnionFs是文件级的存储驱动。Aufs是之前的UnionFS的重新实现2006年由JunjiroOkajima开发所谓UnionFS就是把不同物理位置的目录合并mount到同一个目录中。简单来说就是支持将不同目录挂载到一个虚拟文件系统下。这种可以层层地叠加修改文件。无论底下有多少都是只读的最上系统可写的。当需要修改一个文件时AUFS常见该文件的一个副本使用CoW将文件从只读层复制到可写进行修改结果也保存在Docker中底下的只读层就是image可写层就是Container。aufs被拒绝合并到主线Linux。其代码被批评为“denseunreadableuncommented 密集、不可读、未注释”。相反OverlayFS被合并到Linux内核中。在多次尝试将aufs合并到主线内核失败后作者放弃了AUFS是docker18.06及更早版本的首选存储驱动程序在内核3.13上运行ubuntu14.04时不支持overlay2Overlay一种UnionFS文件系统Linux内核3.18后支持Overlay2Overlay的升级版到目前为止所有Linux发行版推荐使用的存储类型也是docker默认使用的存储引擎为overlay2需要磁盘分区支持d-type功能因此需要系统磁盘的额外支持相对AUFS来说Overlay2有以下优势更简单的设计从3.18开始就进入了Linux内核主线资源消耗更少devicemapper因为Centos7.2和RHEL7.2的之前版本内核版本不支持overlay2默认使用的存储驱动程序最大数据容量只支持100G且性能不佳当前较新版本的CentOS已经支持overlay2因此推荐使用overlay2另外此存储引擎已在Docker Engine 18.09中弃用ZFSSun-2005/btrfsOracle-2007目前没有广泛使用VFS用于测试环境适用于无法使用copy-on-write时的情况。此存储驱动程序的性能很差通常不建议用于生产
Docker官方推荐首选存储引擎为overlay2其次为devicemapper但是devicemapper存在使用空间方面的一些限制虽然可以通过后期配置解决但是官方依然推荐使用overlay2以下是生产故障示例https://www.cnblogs.com/youruncloud/p/5736718.html
docker服务进程
通过查看docker进程了解docker的运行及工作方式
docker的进程关系
docker相关的四个进程
dockerd服务器程序被client直接访问其父进程为宿主机的systemd守护进程docker-proxy每个进程docker-proxy实现对应一个需要网络通信的容器管理宿主机和容器之间端口映射其父进程为dockerd如果容器不需要网络则无需启动containerd被dockerd进程调用以实现与runc交互containerd-shim真正运行容器的载体每个容器对应一个containerd-shim进程其父进程为containerd
容器的创建与管理过程
通信流程 1.dockerd通过grpc和containerd模块通信dockerd由libcontainerd负责和containerd进行交换docker和containerd通信socket文件/run/containerd/containerd.sock 2.containerd在docker启动时被启动然后containerd启动grpc请求监听containerd处理grpc请求根据请求做相应动作 3.若是runstart或是exec容器containerd拉起一个container-shim并进行相应的操作 4.container-shim被拉起后start/exec/create拉起runc进程通过exit、control文件和containerd通信通过父子进程关系和SIGCHLD监控容器中进程状态 5.在整个容器生命周期中container通过epoll监控容器文件监控容器事件
gRPC简介
官网https://www.grpc.io
gRPC是Google开发的一款高性能、开源和通用的RPC框架支持众多语言客户端
Docker 服务管理
docker服务基于C/S结构可以实现基于本地和远程方式进行管理
# Dockerd守护进程启动选项
-H tcp://host:portunix:///path/to/socket,fd://* or fd://socketfd# 守护进程默认配置
-H unix:///var/run/docker.sock# 使用Docker客户端命令选项
-H tcp://host:portunix:///path/to/socket,fd://* or fd://socketfd# 客户端默认配置
-H unix:///var/run/docker.sock# docker客户端也可以使用环境变量DOCKER_HOST,代替 -H选项
export DOCKER_HOSTtcp://docker-server:2375镜像管理
镜像结构和原理
镜像即创建容器的模板含有启动容器所需要的文件系统及所需要的内容因此镜像主要用于方便和快速的创建启动容器。 镜像里面是一层层的文件系统叫做Union FS联合文件系统联合文件系统可以将几层目录挂载到一起就想千层饼洋葱头俄罗斯套娃一样形成一个虚拟文件系统虚拟文件系统的目录结构就像普通Linux的目录结构一样镜像通过这些文件再加上宿主机的内核共同提供了一个Linux的虚拟环境每一层文件系统叫做一层layer联合文件系统可以对每一层文件系统设置三种权限只读readonly、读写readwrite、和写出whiteout-able但是镜像中每一层文件系统都是只读的构建镜像的时候从一个最基本的操作系统开始每个构建提交的操作都相当于做一层的修改增加了一层文件系统一层层往上叠加上层的修改会覆盖底层该位置的可见性这也很容易理解就像上层把底层遮住了一样当使用镜像的时候我们只会看到一个完全的整体不知道里面有几层。 一个典型的Linux文件系统由bootfs和rootfs两部分组成 bootfsboot file system主要包含bootloader和kernelbootloader主要用于引导加载kernelLinux刚启动时会加载bootfs文件系统当boot加载完后kernel被加载到内存中后接管系统的控制权bootfs会被umount掉 rootfsroot file system包含的就是典型Linux系统中的 /dev/proc/bin/etc等标准目录和文件不同的Linux发行版如ubuntu 和 CentOS主要在rootfs这一层会有所区别。 一般的镜像通常都比较小官方提供的Ubuntu镜像只有60M多点而CentOS基础镜像也只有200M左右一些其他版本的镜像甚至只有几M比如busybox 才1.22MAlpine镜像也只有5M左右。镜像直接调用宿主机的内核镜像中提供rootfs也就是只需要包括最基本的命令配置文件和程序库等相关文件就可以了。
容器、镜像和父镜像关系
查看镜像的分层结构
[rootcentos7 ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
1efc276f4ff9: Pull complete
baf2da91597d: Pull complete
05396a986fd3: Pull complete
6a17c8e7063d: Pull complete
27e0d286aeab: Pull complete
b1349eea8fc5: Pull complete
Digest: sha256:790711e34858c9b0741edffef6ed3d8199d8faa33f2870dea5db70f16384df79
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest# 查看镜像分层历史
[rootcentos7 ~]# docker image history nginx
IMAGE CREATED CREATED BY SIZE COMMENT
b692a91e4e15 2 weeks ago /bin/sh -c #(nop) CMD [nginx -g daemon… 0B
missing 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
missing 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
missing 2 weeks ago /bin/sh -c #(nop) ENTRYPOINT [/docker-entr… 0B
missing 2 weeks ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
missing 2 weeks ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
missing 2 weeks ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
missing 2 weeks ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
missing 2 weeks ago /bin/sh -c set -x addgroup --system -… 61.1MB
missing 2 weeks ago /bin/sh -c #(nop) ENV PKG_RELEASE1~bullseye 0B
missing 2 weeks ago /bin/sh -c #(nop) ENV NJS_VERSION0.7.6 0B
missing 2 weeks ago /bin/sh -c #(nop) ENV NGINX_VERSION1.23.1 0B
missing 2 weeks ago /bin/sh -c #(nop) LABEL maintainerNGINX Do… 0B
missing 2 weeks ago /bin/sh -c #(nop) CMD [bash] 0B
missing 2 weeks ago /bin/sh -c #(nop) ADD file:0eae0dca665c7044b… 80.4MB[rootcentos7 ~]# docker inspect nginx
[{Id: sha256:b692a91e4e1582db97076184dae0b2f4a7a86b68c4fe6f91affa50ae06369bf5,RepoTags: [nginx:latest],RepoDigests: [nginxsha256:790711e34858c9b0741edffef6ed3d8199d8faa33f2870dea5db70f16384df79],Parent: ,Comment: ,Created: 2022-08-02T05:17:19.274343015Z,Container: 5f19bc2cd794cd60ec845cbed7a60c85003dc56f26ee807f9eea2480bc465b76,ContainerConfig: {Hostname: 5f19bc2cd794,Domainname: ,User: ,AttachStdin: false,AttachStdout: false,AttachStderr: false,ExposedPorts: {80/tcp: {}},Tty: false,OpenStdin: false,StdinOnce: false,Env: [PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,NGINX_VERSION1.23.1,NJS_VERSION0.7.6,PKG_RELEASE1~bullseye],Cmd: [/bin/sh,-c,#(nop) ,CMD [\nginx\ \-g\ \daemon off;\]],Image: sha256:0417134432daa8913f92f7bf71641a8fa7ab3405c91b717dde22c855e71eef4d,Volumes: null,WorkingDir: ,Entrypoint: [/docker-entrypoint.sh],OnBuild: null,Labels: {maintainer: NGINX Docker Maintainers docker-maintnginx.com},StopSignal: SIGQUIT},DockerVersion: 20.10.12,Author: ,Config: {Hostname: ,Domainname: ,User: ,AttachStdin: false,AttachStdout: false,AttachStderr: false,ExposedPorts: {80/tcp: {}},Tty: false,OpenStdin: false,StdinOnce: false,Env: [PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,NGINX_VERSION1.23.1,NJS_VERSION0.7.6,PKG_RELEASE1~bullseye],Cmd: [nginx,-g,daemon off;],Image: sha256:0417134432daa8913f92f7bf71641a8fa7ab3405c91b717dde22c855e71eef4d,Volumes: null,WorkingDir: ,Entrypoint: [/docker-entrypoint.sh],OnBuild: null,Labels: {maintainer: NGINX Docker Maintainers docker-maintnginx.com},StopSignal: SIGQUIT},Architecture: amd64,Os: linux,Size: 141538863,VirtualSize: 141538863,GraphDriver: {Data: {LowerDir: /var/lib/docker/overlay2/65721405d33c804de8b1ce344e01ea1cb20a15b526846ddd0914236141d12a74/diff:/var/lib/docker/overlay2/769ff70d994c30f2c3aca1a752b6320d7908f4a7aebd56ef58557b9d39cb3170/diff:/var/lib/docker/overlay2/ecbbdc176f03365bcf157e7409d045d16173793abb43d908328c28aa5235af85/diff:/var/lib/docker/overlay2/14a39e34b10a24fab8c7dccff4a3fcd34bdede808fda2921fcb2c033b1871e92/diff:/var/lib/docker/overlay2/3826983a7f0fa4365113c866622eb0af797919100279ba1db6bdd352330e4699/diff,MergedDir: /var/lib/docker/overlay2/7194cc85a5c2bf12f4d2fb0e2c57ff356c47981bda94be0e9bcf503391080797/merged,UpperDir: /var/lib/docker/overlay2/7194cc85a5c2bf12f4d2fb0e2c57ff356c47981bda94be0e9bcf503391080797/diff,WorkDir: /var/lib/docker/overlay2/7194cc85a5c2bf12f4d2fb0e2c57ff356c47981bda94be0e9bcf503391080797/work},Name: overlay2},RootFS: {Type: layers,Layers: [sha256:92a4e8a3140f7a04a0e5a15793adef2d0e8889ed306a8f95a6cfb67cecb5f212,sha256:e3257a399753c995f54856b0cea3c2b6aa1a95d9a7b542668a46fa4eacf62d53,sha256:3a89c8160a43d70433241934b1d418f641e6d207a10b558b67f8aafdb15416b0,sha256:f91d0987b144553456431bcb8cc8ddf5d03362701bc2ffc128ce2bd57182defb,sha256:bdc7a32279ccdf5aba13d3e50b7b16103e03ff8ef27424ac1a33df24e5a9f602,sha256:b539cf60d7bb42871a005e949b550800b99fada0b1c1bca01654e8a506ba2138]},Metadata: {LastTagTime: 0001-01-01T00:00:00Z}}
]
[rootcentos7 ~]# docker save nginx -o nginx.tar
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest b692a91e4e15 2 weeks ago 142MB
[rootcentos7 ~]# ll -h nginx.tar
-rw------- 1 root root 140M 8月 22 23:00 nginx.tar[rootcentos7 ~]# mkdir data
[rootcentos7 ~]# tar -xf nginx.tar -C data/
[rootcentos7 ~]# ll data/
总用量 16
drwxr-xr-x 2 root root 50 8月 2 13:17 0b71b9002c2056073a621264c914f1778296599761548ff1e34d39dc883ed029
drwxr-xr-x 2 root root 50 8月 2 13:17 19dee729285a1f8f34b15874db48c7b4b60f6041914f2cad9b1de169795de836
drwxr-xr-x 2 root root 50 8月 2 13:17 1c65531519b901e0508c411808f7dc2497a6549926bda748896f59aaddc4eed4
drwxr-xr-x 2 root root 50 8月 2 13:17 6387aff546d7c159c6e082ea910391bc9c331ff19f75c73d45780def09a8c989
drwxr-xr-x 2 root root 50 8月 2 13:17 75e6a412e4bda1a8b9e5690c6f8c218c0649ca965207ff15f4f2e114e859ec86
-rw-r--r-- 1 root root 7653 8月 2 13:17 b692a91e4e1582db97076184dae0b2f4a7a86b68c4fe6f91affa50ae06369bf5.json
drwxr-xr-x 2 root root 50 8月 2 13:17 e9bee565b6a50b23d35427abf3f6756a842c5d75d3c8e3d63f412cb3dae90409
-rw-r--r-- 1 root root 586 1月 1 1970 manifest.json
-rw-r--r-- 1 root root 88 1月 1 1970 repositories[rootcentos7 ~]# cat data/manifest.json
[{Config:b692a91e4e1582db97076184dae0b2f4a7a86b68c4fe6f91affa50ae06369bf5.json,RepoTags:[nginx:latest],Layers:[1c65531519b901e0508c411808f7dc2497a6549926bda748896f59aaddc4eed4/layer.tar,e9bee565b6a50b23d35427abf3f6756a842c5d75d3c8e3d63f412cb3dae90409/layer.tar,6387aff546d7c159c6e082ea910391bc9c331ff19f75c73d45780def09a8c989/layer.tar,75e6a412e4bda1a8b9e5690c6f8c218c0649ca965207ff15f4f2e114e859ec86/layer.tar,0b71b9002c2056073a621264c914f1778296599761548ff1e34d39dc883ed029/layer.tar,19dee729285a1f8f34b15874db48c7b4b60f6041914f2cad9b1de169795de836/layer.tar]}][rootcentos7 ~]# du -sh data/*
12K data/0b71b9002c2056073a621264c914f1778296599761548ff1e34d39dc883ed029
16K data/19dee729285a1f8f34b15874db48c7b4b60f6041914f2cad9b1de169795de836
80M data/1c65531519b901e0508c411808f7dc2497a6549926bda748896f59aaddc4eed4
12K data/6387aff546d7c159c6e082ea910391bc9c331ff19f75c73d45780def09a8c989
12K data/75e6a412e4bda1a8b9e5690c6f8c218c0649ca965207ff15f4f2e114e859ec86
8.0K data/b692a91e4e1582db97076184dae0b2f4a7a86b68c4fe6f91affa50ae06369bf5.json
60M data/e9bee565b6a50b23d35427abf3f6756a842c5d75d3c8e3d63f412cb3dae90409
4.0K data/manifest.json
4.0K data/repositories搜索镜像
官网https://hub.docker.com
执行docker search命令进行搜索
Usage: docker search [OPTIONS] TERMOptions:-f, --filter filter Filter output based on conditions provided--format string Pretty-print search using a Go template--limit int Max number of search results (default 25)说明
OFFICIAL官方
AUTOMATED使用第三方docker服务来帮助编译镜像可以在互联网上面直接拉取到镜像减少了繁琐的编译过程例查找centos镜像
[rootcentos7 ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 7288 [OK]
kasmweb/centos-7-desktop CentOS 7 desktop for Kasm Workspaces 24
couchbase/centos7-systemd centos7-systemd images with additional debug… 4 [OK]
dokken/centos-7 CentOS 7 image for kitchen-dokken 3
continuumio/centos5_gcc5_base 3
dokken/centos-stream-9 2
dokken/centos-stream-8 2
spack/centos7 CentOS 7 with Spack preinstalled 1
spack/centos6 CentOS 6 with Spack preinstalled 1
datadog/centos-i386 0
dokken/centos-6 CentOS 6 image for kitchen-dokken 0
ustclug/centos Official CentOS Image with USTC Mirror 0
dokken/centos-8 CentOS 8 image for kitchen-dokken 0
corpusops/centos-bare https://github.com/corpusops/docker-images/ 0
bitnami/centos-extras-base 0
corpusops/centos centos corpusops baseimage 0
couchbase/centos-72-java-sdk 0
couchbase/centos-72-jenkins-core 0
couchbase/centos-70-sdk-build 0
bitnami/centos-base-buildpack Centos base compilation image 0 [OK]
couchbase/centos-69-sdk-nodevtoolset-build 0
fnndsc/centos-python3 Source for a slim Centos-based Python3 image… 0 [OK]
couchbase/centos-69-sdk-build 0
dokken/centos-5 EOL DISTRO: For use with kitchen-dokken, Bas… 0
spack/centos-stream 0搜索点赞100个以上的镜像
[rootcentos7 ~]# docker search --filterstars100 centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 7288 [OK]alpine介绍
Alpine操作系统是一个面向安全的轻型Linux发行版。它不同于通常Linux发行版Alpine采用了musl libc 和 busybox以减小系统的体积和运行时资源消耗但功能上比busybox又完善的多因此得到开源社区越来也多的青睐。在保持瘦身的同时Alpine还提供了自己的包管理工具apk可以通过https://pkgs.alpinelinux.org/packages 查询包信息也可以直接通过apk命令直接查询和安装各种软件。 Alpine由非商业组织维护的支持广泛场景的Linux发行版它特别为资深/重度Linux用户而优化关注安全性能和资源效能。Alpine镜像可以适用于更多常用场景并且是一个优秀的可以适用于生产的基础系统/环境。 Alpine Docker镜像也继承了Alpine Linux发行版的这些优势。相比于其他Docker镜像它的容量非常小仅仅只有5M左右且拥有非常友好的包管理机制。官方镜像来自docker-alpine项目。 目前Docker官方已开始推荐使用Alpine替代之前的Ubuntu作为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快镜像安全性提高主机之间的切换更方便占用更少磁盘空间等。 下表是官方镜像的大小比较
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest dd8bae8d259f Less than a second ago 124MB
alpine latest 9c6f07244728 12 days ago 5.54MB
ubuntu latest df5de72bdb3b 2 weeks ago 77.8MB
centos latest 5d0da3dc9764 11 months ago 231MBAlpine官网https://www.alpinelinux.orgAlpine官方仓库https://github.com/alpinelinuxAlpine官方镜像https://hub.docker.com/_/alpine/Alpine官方镜像仓库https://github.com/gliderlabs/docker-alpineAlpine阿里云镜像仓库https://mirrors.aliyun.com/alpine/
alpine管理软件
# 修改源替换成阿里源将里面 dl-cdn.alpinelinux.org 改成 mirrors.aliyun.com
vi /etc/apk/repositories
https://mirrors.aliyun.com/alpine/v3.16/main
https://mirrors.aliyun.com/alpine/v3.16/community# 更新源
apk update# 安装软件
apk add vim # 删除软件
apk del openssh openntp vim例
/ # apk --help
apk-tools 2.12.9, compiled for x86_64.usage: apk [OPTIONS...] COMMAND [ARGUMENTS...]Package installation and removal:add Add packages to WORLD and commit changesdel Remove packages from WORLD and commit changesSystem maintenance:fix Fix, reinstall or upgrade packages without modifying WORLDupdate Update repository indexesupgrade Install upgrades available from repositoriescache Manage the local package cacheQuerying package information:info Give detailed information about packages or repositorieslist List packages matching a pattern or other criteriadot Render dependencies as graphviz graphspolicy Show repository policy for packagessearch Search for packages by name or descriptionRepository maintenance:index Create repository index file from packagesfetch Download packages from global repositories to a local directorymanifest Show checksums of package contentsverify Verify package integrity and signatureMiscellaneous:audit Audit system for changesstats Show statistics about repositories and installationsversion Compare package versions or perform tests on version stringsThis apk has coffee making abilities.
For more information: man 8 apk/ # apk add nginx
(1/2) Installing pcre (8.45-r2)
(2/2) Installing nginx (1.22.0-r1)
Executing nginx-1.22.0-r1.pre-install
Executing nginx-1.22.0-r1.post-install
Executing busybox-1.35.0-r17.trigger
OK: 7 MiB in 16 packages/ # apk info nginx
nginx-1.22.0-r1 description:
HTTP and reverse proxy server (stable version)nginx-1.22.0-r1 webpage:
https://www.nginx.org/nginx-1.22.0-r1 installed size:
1124 KiB/ # apk manifest nginx
sha1:d21a96358a10b731f8847e6d32799efdc2a7f421 etc/logrotate.d/nginx
sha1:cbf596ddb3433a8e0d325f3c188bec9c1bb746b3 etc/nginx/fastcgi.conf
sha1:da38e2a0dded838afbe0eade6cb837ac30fd8046 etc/nginx/fastcgi_params
sha1:9b85e5091018455091d7f135c4a160ad9487516a etc/nginx/mime.types
sha1:44195d2ab691d6251a0ac0190aebf7a1c2eea05d etc/nginx/nginx.conf
sha1:379c1e2a2a5ffb8c91a07328d4c9be2bc58799fd etc/nginx/scgi_params
sha1:cc2fcdb4605dcac23d59f667889ccbdfdc6e3668 etc/nginx/uwsgi_params
sha1:b56312b641dffaa622d197625f4b867817824475 usr/sbin/nginx
sha1:7b2a4da1a14166442c10cbf9e357fa9fb53542ca usr/share/nginx/http-default_server.conf
sha1:35db17c18ce0b9f84a3cc113c8a9e94e19f632b1 var/lib/nginx/logs
sha1:c3f02ca81f7f2c6bde3f878b3176f225c7781c7d var/lib/nginx/modules
sha1:0510312d465b86769136983657df98c1854f0b60 var/lib/nginx/run
sha1:835b9dec419c01420e78602527a9fba8c463521c var/lib/nginx/html/50x.html
sha1:c51a3f0e6de4eb802d5630941c3fd9e1d0efae4b var/lib/nginx/html/index.htmlDebian(Ubuntu)建议安装的基础包
在很多软件官方提供的镜像都使用的是DebianUbuntu的系统比如nginxtomcatmysqlhttpd等但镜像内缺少很多常用的调试工具当需要进入容器内进行调试管理时可以安装以下常用工具包
apt update # 安装软件钱需要先更新索引
apt install procps # 提供topps,free等命令
apt install psmic # 提供pstree,killall等命令
apt install iputils-ping # 提供ping命令
apt install net-tools # 提供netstat网络工具等下载镜像
从docker仓库下载镜像到本地命令格式如下
docker pull [OPTION] NAME[:TAG|GIGEST]
OPTIONS:-a,--all-tags Download all tagged images in the repository--disable-content-trust Skip image verification (default true)--platform string Set platform if server is multi-platform capable-q,--quit Suppress verbose outputNAME:是镜像名一般的形式 仓库服务器端口/项目名称/镜像名称
:TAG:即版本号如果不指定:TAG则下载最新版镜像镜像下载说明
[rootcentos7 ~]# docker pull hello-world
Using default tag: latest # 默认下载最新版本
latest: Pulling from library/hello-world
2db29710123e: Pull complete # 分层下载
Digest: sha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625 # 摘要
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest # 下载的完整地址镜像下载保存的路径 /var/lib/docker/overlay2/镜像ID 注意镜像下载完成后会自动解压缩比官网显示的可能会大很多如centos8.1.1911下载时只有70M下载完后显示237M 例从docker官网下载镜像
docker pull hello-world
docker pull alpine
docker pull busybox
docker pull nginx
docker pull centos
docker pull centos:centos7.7.1908
docekr pull docker.io/library/mysql:5.7.29
docker pull mysql:5.6.47docker镜像加速配置
docker镜像官方的下载站点是https://hub.docker.com/ 从国内下载官方的镜像站点有时候会很慢因此可以更改docker配置文件添加一个加速器可以通过加速器达到加速下载镜像的目的。国内有许多公司都提供了docker加速镜像比如阿里云腾讯云网易云等。
1.安装/升级Docker客户端
推荐安装1.10.0以上版本的Docker客户端参考文档 docker-ce2.配置镜像加速器
修改daemon配置文件 /etc/docker/daemon.json
mkdir -p /etc/docker
cat EOF | sudo tee /etc/docker/daemon.json
{
registry-mirrors:[https://docker.mirrors.ustc.edu.cn]
}
EOF# 网易云https://hub-mirror.c.163.com/
# 腾讯云https://mirror.ccs.tencentyun.comsystemctl daemon-reload
systemctl restart docker查看本地镜像
docker images可以查看下载至本地的镜像
docker images [OPTIONS] [REPOSITORY[:TAG]]
docker image ls [OPTIONS] [REPOSITORY[:TAG]]# 常用选项
-q,--quiet Only show numberic IDs
-a,--all Show all images (default hides intermediate images)--digests Show digests--no-trunc Dont truncate output
-f,--filter filter Filter output based on conditions provided--format string Pretty-print images using a Go template执行结果的显示信息说明
REPOSITORY # 镜像所属的仓库名称
TAG # 镜像版本号标识符默认为latest
IMAGE ID # 镜像唯一ID标识如果ID相同说明是同一个镜像有多个名称
VREATED # 镜像在仓库中被创建时间
SIZE # 镜像的大小Repository仓库
由某特定的docker镜像的所有迭代版本组成的镜像仓库一个Registry中可以存在多个RepositoryRepository可分为“顶层仓库”和“用户仓库”Repository用户仓库名称一般格式为“用户名/仓库名”每个Repository仓库可以包含多个Tag每个标签对应一个镜像
镜像导出
利用docker save命令可以将本地镜像导出为一个tar文件然后复制到其他服务器进行导入使用
docker save [OPTIONS] IMAGE [IMAGE...]# 选项
-o,--output string write to a file,instead of STDOUT常见用法
docker save -o /path/file.tar IMAGE1 IMAGE2 ...
docker save IMAGE1 IMAGE2... /path/file.tar镜像导入
利用docker load 命令可以将镜像导出的压缩文件再导入
docker load [OPTIONS]# 选项
-i,--input string Read from tar archive,instead of STDIN
-q,--quiet Suppress the load output常见用法
docker load -i /path/file.tar
docker load /path/file.tar删除镜像
docker rmi 命令可以删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
docker image rm [OPTIONS] IMAGE [IMAGE...]# 选项
-f,--force Force removal of the image--no-prune Do not delete untagged parents常见用法
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest dd8bae8d259f Less than a second ago 124MB
alpine latest 9c6f07244728 13 days ago 5.54MB
ubuntu latest df5de72bdb3b 2 weeks ago 77.8MB
hello-world latest feb5d9fea6a5 11 months ago 13.3kB
centos latest 5d0da3dc9764 11 months ago 231MB
centos centos7.7.1908 08d05d1d5859 2 years ago 204MB# 根据IMAGE ID删除镜像
[rootcentos7 ~]# docker rmi 08d
Untagged: centos:centos7.7.1908
Untagged: centossha256:50752af5182c6cd5518e3e91d48f7ff0cba93d5d760a67ac140e2d63c4dd9efc
Deleted: sha256:08d05d1d5859ebcfb3312d246e2082e46cb307f0e896c9ac097185f0b0b19e56
Deleted: sha256:034f282942cd6c3abf9384601a57f080f8f75cc7f58527db8e07573d9d14ab46# 根据REPOSITORY名称删除镜像
[rootcentos7 ~]# docker rmi centos
Untagged: centos:latest
Untagged: centossha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59# 删除多个镜像
[rootcentos7 ~]# docker rmi debian ubuntu
Untagged: debian:latest
Untagged: debiansha256:875e4e2bae4d7ff53fe7f3672b15630439479fd10da081477a14208122fe8f31
Deleted: sha256:dd8bae8d259fed93eb54b3bca0adeb647fc07f6ef16745c8ed4144ada4d51a95
Deleted: sha256:655ed1b7a4286ce965b8942644f665a3aeafac315f023b3d75fabdbd4be12dd0
Untagged: ubuntu:latest
Untagged: ubuntusha256:34fea4f31bf187bc915536831fd0afc9d214755bf700b5cdb1336c82516d154e
Deleted: sha256:df5de72bdb3b711aba4eca685b1f42c722cc8a1837ed3fbd548a9282af2d836d
Deleted: sha256:629d9dbab5edeac7fa51f205839d7f9bb629a5e83548da3a183fb66c22fe7af7# 删除所有镜像
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 9c6f07244728 13 days ago 5.54MB
hello-world latest feb5d9fea6a5 11 months ago 13.3kB
[rootcentos7 ~]# docker rmi -f docker images -q
Untagged: alpine:latest
Untagged: alpinesha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad
Deleted: sha256:9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5
Deleted: sha256:994393dc58e7931862558d06e46aa2bb17487044f670f310dffe1d24e4d1eec7
Untagged: hello-world:latest
Untagged: hello-worldsha256:7d246653d0511db2a6b2e0436cfd0e52ac8c066000264b3ce63331ac66dca625
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE镜像打标签
docker tag可以给镜像打标签类似起别名但通常要遵守一定的命名规范才可以上传到指定的仓库
# 格式
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]# TARGET_IMAGE[:TAG]格式一般形式
仓库主机FQDN或IP[:端口]/项目名或用户名/image名字:版本# TAG 默认为latest**总结**企业使用镜像及常见操作搜索、下载、导出、导入、删除
docker search centos
docker pull alpine
docker images
docker save /opt/centos.tar centos
docker load /opt/centos.tar
docker rmi 镜像ID/镜像名称容器操作基础命令
容器相关命令
[rootcentos7 ~]# docker containerUsage: docker container COMMANDManage containersCommands:attach Attach local standard input, output, and error streams to a running containercommit Create a new image from a containers changescp Copy files/folders between a container and the local filesystemcreate Create a new containerdiff Inspect changes to files or directories on a containers filesystemexec Run a command in a running containerexport Export a containers filesystem as a tar archiveinspect Display detailed information on one or more containerskill Kill one or more running containerslogs Fetch the logs of a containerls List containerspause Pause all processes within one or more containersport List port mappings or a specific mapping for the containerprune Remove all stopped containersrename Rename a containerrestart Restart one or more containersrm Remove one or more containersrun Run a command in a new containerstart Start one or more stopped containersstats Display a live stream of container(s) resource usage statisticsstop Stop one or more running containerstop Display the running processes of a containerunpause Unpause all processes within one or more containersupdate Update configuration of one or more containerswait Block until one or more containers stop, then print their exit codesRun docker container COMMAND --help for more information on a command.启动容器
docker run 可以启动容器进入到容器并随机生成容器ID和名称
启动第一个容器
[rootcentos7 ~]# docker run hello-worldHello from Docker!This message shows that your installation appears to be working correctly.To generate this message, Docker took the following steps:1. The Docker client contacted the Docker daemon.2. The Docker daemon pulled the hello-world image from the Docker Hub.(amd64)3. The Docker daemon created a new container from that image which runs theexecutable that produces the output you are currently reading.4. The Docker daemon streamed that output to the Docker client, which sent itto your terminal.To try something more ambitious, you can run an Ubuntu container with:$ docker run -it ubuntu bashShare images, automate workflows, and more with a free Docker ID:https://hub.docker.com/For more examples and ideas, visit:https://docs.docker.com/get-started/[rootcentos7 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES46f601445bd8 hello-world /hello 30 seconds ago Exited (0) 29 seconds ago festive_sammet[rootcentos7 ~]#启动容器的流程 启动容器的用法
docker run [选项] [镜像名] [shell命令] [参数]# 选项-i Keep STDIN open even if not attached,通常和-t一起用-t 分配 pseudo-TTY通常和-i一起使用注意对应容器必须运行shell才支持进入-d 后台运行默认前台运行--name string 容器名称--h,--hostname string 容器 hostname--rm 容器关闭后自动删除容器-p list 指定要映射的端口到内部容器开放的端口-P 随机映射端口到内部容器开放的端口49000~49900--dns list 设置DNS--entrypoint string 运行指令--restart policy-e,--env[] 设置环境变量--env-file[]-–restart 容器的重启策略可以指定四种不同的policy
no默认策略在容器退出时不重启容器no-failure在容器非正常退出时退出状态非0才会重启容器on-failure3在容器非正常退出时重启容器最多重启3次always在容器退出时总是重启容器unless-stopped在容器退出时总是重启容器但是不考虑在Docker守护进程启动时就已经停止的容器
**注意**容器启动后如果容器内没有前台运行的进程将自动退出停止
# 运行容器 启动容器时会自动随机字符作为容器名[rootcentos7 ~]# docker pull alpineUsing default tag: latestlatest: Pulling from library/alpine59bf1c3509f3: Pull completeDigest: sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300Status: Downloaded newer image for alpine:latestdocker.io/library/alpine:latest[rootcentos7 ~]# docker run alpine[rootcentos7 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESbc5efb3b7f37 alpine /bin/sh 3 seconds ago Exited (0) 2 seconds ago elated_villani# 一次性运行容器中的命令# 启动容器在执行完shell命令就退出用于测试[rootcentos7 ~]# docker pull busyboxUsing default tag: latestlatest: Pulling from library/busybox5cc84ad355aa: Pull completeDigest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678Status: Downloaded newer image for busybox:latestdocker.io/library/busybox:latest[rootcentos7 ~]# docker run busybox echo Hello chensirHello chensir[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES[rootcentos7 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES4ce437d13ae3 busybox echo Hello chensir 17 seconds ago Exited (0) 17 seconds ago optimistic_goldberg# 指定容器名称[rootcentos7 ~]# docker run --name pine alpine[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES[rootcentos7 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES9c34dd8204d0 alpine /bin/sh 7 seconds ago Exited (0) 6 seconds ago pine# 运行交互式容器并退出[rootcentos7 ~]# docker run -it busybox sh/ # exit# 使用exit退出容器后 容器也停止了[rootcentos7 ~]# docker ps -lCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES4b3203a20472 busybox sh 10 seconds ago Exited (0) 3 seconds ago brave_pascal[rootcentos7 ~]# docker run -it busybox sh/ # # 在容器中 同时按三个键 ctrlpq 退出后 容器不会停止[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES6ad4551530b5 busybox sh 9 seconds ago Up 8 seconds jolly_mestorf# 设置容器内的主机名[rootcentos7 ~]# docker run -it --name a1 -h chensir.ink alpine/ # hostnamechensir.ink/ # cat /etc/hosts127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopbackfe00::0 ip6-localnetff00::0 ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters172.17.0.3 chensir.ink chensir# 一次性运行容器退出后立即删除用于测试[rootcentos7 ~]# docker run --rm alpine cat /etc/issueWelcome to Alpine Linux 3.15Kernel \r on an \m (\l)[rootcentos7 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES什么是守护式容器
能够长期运行无需交互式会话适合运行应用程序和服务
privileged 选项
大约在0.6版—–privileged选项被引入docker。使用该参数container内的root拥有真正的root权限。否则container内的root只是外部的一个普通用户权限。privileged启动的容器可以看到很多host上的设备并且可以执行mount。甚至允许你在docker容器中启动docker容器。
查看容器信息
显示当前存在容器
docker ps [OPTIONS]
docker container ls [OPTIONS]
# 选项
-a Show all containers (default shows just running)
-q Only display numeric IDs
-s Display total file sizes
-f Filter output based on conditions provided
-l Show the latest created container (includes all states)
-n Show n last created containers (includes all states)
(default -1)示例
# 显示运行的容器docker ps# 显示全部容器包括退出状态的容器docker ps -a# 显示全部容器包括退出状态的容器的 容器IDdocker ps -aq# 显示全部容器包括退出状态的容器的大小docker ps -as# 显示最新创建的容器停止的容器也能显示docker ps -l# 显示指定状态的容器docker ps -f statusexiteddocker ps -f statusrunning查看容器内的进程
docker top CONTAINER [PS OPTIONS]示例
[rootcentos7 ~]# docker run -d httpdUnable to find image httpd:latest locallylatest: Pulling from library/httpda2abf6c4d29d: Already existsdcc4698797c8: Pull complete41c22baa66ec: Pull complete67283bbdd4a0: Pull completed982c879c57e: Pull completeDigest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32Status: Downloaded newer image for httpd:latestec9e58e706932e56509ce001191e7b52cd5f16b6b1ec25852a2947872aff3cff[rootcentos7 ~]# docker top ec9UID PID PPID C STIME TTY TIME CMDroot 15067 15047 0 04:33 ? 00:00:00 httpd -DFOREGROUND33 15094 15067 0 04:33 ? 00:00:00 httpd -DFOREGROUND33 15095 15067 0 04:33 ? 00:00:00 httpd -DFOREGROUND33 15096 15067 0 04:33 ? 00:00:00 httpd -DFOREGROUND查看容器资源使用情况
docker stats [OPTIONS] [CONTAINER...]# 选项-a,--all Show all containers (default shows just running)--format string Pretty-print images using a Go template--no-stream Disable streaming stats and only pull the first result--no-trunc Do not truncate output查看容器的详细信息
docker inspect 可以查看docker各种对象的详细信息包括镜像容器网络等
docker inspect [OPTIONS] NAME|ID [NAME|ID...]# 选项-f string Format the output using the given Go trmplate-s Display total file sizes if the type is container删除容器
docker rm 可以删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]docker container rm [OPTIONS] CONTAINER [CONTAINER...]# 选项-f Force the removal of a running container (uses SIGKILL)-v Remove示例
# 删除所有的容器docker rm -f docker ps -aq# 删除指定状态的容器docker rm -f docker ps -qf statusexited# 删除所有停止的容器docker container prune -f容器的启动和停止
docker start|stop|restart|pause|unpause 容器ID# 批量正常启动或关闭所有容器docker start docker ps -qadocker stop docker ps -qa给正在运行的容器发信号
docekr kill 可以给容器发信号默认SIGKILL即9
docker kill [OPTIONS] CONTAINER [CONTAINER...]# 选项-s string Signal to send to the container (default KILL)示例
# 关闭容器docker kill nginx# 强制关闭所有容器docker kill docker ps -qa进入正在运行的容器
使用attach命令
docker attach 容器名attach类似于vnc操作会在同一个容器的多个会话界面同步显示所有使用此方式进入容器的操作都是同步显示的且使用exit退出后容器自动关闭不推荐使用需要进入到有shell环境的容器
使用exec命令
在运行中的容器启动新进程可以执行单次命令及进入容器测试环境使用此方式使用exit退出容器还在运行推荐此方式
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]# 常用选项
-d Detached mode:run command in the background
-e Set environment variables
-i Keep STDIN open even if not attached
-t Allocate a psedu-TTY# 常见用法
docker exec -it 容器ID sh|bash使用nsenter命令
nsenter命令需要通过PID进入到容器内部且退出后仍能正常运行不过需要事先使用docker inspect 获取到容器的PID目前凡是使用较少此工具来自于until-linux包
# 安装nsenter命令
yum install -y util-linux# 获取容器的IP
docker inspect -f {{.NetworkSettings.IPAddress}} 容器ID# 获取容器的PID通过PID进入到容器内
docker inspect -f {{.State.Pid}} 容器ID
nsenter -t Pid -m -u -i -n -p脚本方式
将nsenter命令写入到脚本进行调用方便进入容器看日志或排错
cat docker-in.sh
#!/bin/bash
docker_in(){NAME_ID$1PID$(docker inspect -f {{.State.Pid}} ${NAME_ID})nsenter -t ${PID} -m -u -i -n -p
}
docker_in $1示例
[rootcentos7 ~]# vim docker-in.sh
[rootcentos7 ~]# cat docker-in.sh
#!/bin/bash
docker_in(){NAME_ID$1PID$(docker inspect -f {{.State.Pid}} ${NAME_ID})nsenter -t ${PID} -m -u -i -n -p
}
docker_in $1
[rootcentos7 ~]# chmod x docker-in.sh
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd056baa9925 nginx /docker-entrypoint.… 39 minutes ago Up 38 minutes 80/tcp nginx03
4fb4c31a6342 nginx /docker-entrypoint.… 39 minutes ago Up 38 minutes 80/tcp nginx01
[rootcentos7 ~]# ./docker-in.sh fd05
rootfd056baa9925:/# exit
logout
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd056baa9925 nginx /docker-entrypoint.… 40 minutes ago Up 39 minutes 80/tcp nginx03
4fb4c31a6342 nginx /docker-entrypoint.… 40 minutes ago Up 39 minutes 80/tcp nginx01暴露所有容器端口
容器启动后默认处于预定义的NAT网络中所以外部网络的主机无法直接访问容器中网络服务 docker run -P 可以将事先容器预定义的所有端口映射宿主机的网卡的随机端口 使用随机端口时当停止容器后在启动可能会导致端口发生变化
# 示例 映射容器所有暴露端口至随机本地端口
docker run -d -P nginxdocker port 可以查看容器的端口映射关系
docker port CONTAINER [PRIVATE_PORT[/PROTO]]# 示例
docker port nginx01
docker port nginx01 53/udp指定端口映射
docker run -p 可以将容器的预定义的指定端口映射到宿主机的相应端口 注意多个容器映射到宿主机端口不能冲突但容器内使用的端口可以相同
# 方式1容器80端口映射到宿主机本地随机端口
docker run -p 80 --name nginx-test-port1 nginx# 方式2容器80端口映射到宿主机本地端口81
docker run -p 81:80 --name nginx-test-port2 nginx# 方式3宿主机本地IP宿主机本地端口容器端口
docker run -p 10.0.0.100:82:80 --name nginx-test-port3 nginx# 方式4宿主机本地IP苏知机本地随机端口容器端口
docker run -p 10.0.0.100::80 --name nginx-test-port4 nginx# 方式5宿主机本机IP宿主机本地端口容器端口/协议默认为tcp协议
docker run -p 10.0.0.100:83:80/udp --name nginx-test-port5 nginx# 方式6一次映射多个端口协议
docker run -p 8080:80/tcp -p 8443:443/tcp -p 53:53/udp --name-test-port6 nginx修改已经创建的容器的端口映射关系
[rootcentos7 ~]# docker run -d -p 80:80 --name nginx01 nginx
cd1db7f176806254fdf3089f32fcbd0094ec376ea3d8d4e481093cad353d9d48
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cd1db7f17680 nginx /docker-entrypoint.… 2 minutes ago Up 2 minutes 0.0.0.0:80-80/tcp, :::80-80/tcp nginx01
[rootcentos7 ~]# ll /var/lib/docker/containers/cd1db7f176806254fdf3089f32fcbd0094ec376ea3d8d4e481093cad353d9d48/
总用量 28
-rw-r----- 1 root root 2302 8月 23 08:29 cd1db7f176806254fdf3089f32fcbd0094ec376ea3d8d4e481093cad353d9d48-json.log
drwx------ 2 root root 6 8月 23 08:29 checkpoints
-rw------- 1 root root 2904 8月 23 08:29 config.v2.json
-rw-r--r-- 1 root root 1512 8月 23 08:29 hostconfig.json
-rw-r--r-- 1 root root 13 8月 23 08:29 hostname
-rw-r--r-- 1 root root 174 8月 23 08:29 hosts
drwx--x--- 2 root root 6 8月 23 08:29 mounts
-rw-r--r-- 1 root root 69 8月 23 08:29 resolv.conf
-rw-r--r-- 1 root root 71 8月 23 08:29 resolv.conf.hash
[rootcentos7 ~]# systemctl stop docker
[rootcentos7 ~]# vim /var/lib/docker/containers/cd1db7f176806254fdf3089f32fcbd0094ec376ea3d8d4e481093cad353d9d48/hostconfig.json
PortBindings:{80/tcp:[{HostIp:,HostPort:80}]}
# PortBindings 后面的 80/tcp 对应的是容器内部的80端口HostPort对应的是映射到宿主机的端口80修改此处为8000
PortBindings:{80/tcp:[{HostIp:,HostPort:8000}]}
[rootcentos7 ~]# systemctl start docker
[rootcentos7 ~]# docker port nginx01
80/tcp - 0.0.0.0:8000
80/tcp - :::8000查看容器的日志
docker logs 可以查看容器中运行的进程在控制台输出的日志信息 格式
docker logs [OPTIONS] CONTAINER
# 选项
--details Show extra details provided to logs
-f,--follow Follow log output
--since string Show logs since timestamp
--tail string Number of lines to show from the end of the logs (default all)
-t,--timestamps Show timestamps
--until string Show logs before a timestamp示例
# 查看所有日志
docker logs 容器ID# 查看倒数几行的日志
docker logs --tail 行数 容器ID# 显示日志时间
docker logs --tail 行数 -t 容器ID# 持续跟踪日志
docker logs -f 容器ID传递运行命令
容器需要有一个前台运行的进程才能保持容器的运行通过传递运行参数是一种方式另外也可以在构建镜像的时候指定容器启动时运行的前台命令 容器里的PID为1的守护进程的实现方式
服务类如NginxTomcatApache但服务不能停命令类如tail -f /etc/hosts主要用于测试环境注意 tail -f 服务访问日志会产生不必要的磁盘IO
[rootcentos7 ~]# docker run -d alpine
fc8dc5bee8367725a759f15417316a619b098af88f1ad7f7113fa314dd6e3f34
[rootcentos7 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc8dc5bee836 alpine /bin/sh 6 seconds ago Exited (0) 5 seconds ago exciting_chebyshev
[rootcentos7 ~]# docker run -d alpine tail -f /etc/hosts
05a4c6863bcc9d7c4b9f0abeec2316a9cce0f0e3f2aeb37bfa57fcd2bcdf8d52
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05a4c6863bcc alpine tail -f /etc/hosts 2 seconds ago Up 1 second vigilant_lumiere
[rootcentos7 ~]# docker exec -it 05a sh
/ # ps aux
PID USER TIME COMMAND1 root 0:00 tail -f /etc/hosts7 root 0:00 sh13 root 0:00 ps aux
[rootcentos7 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05a4c6863bcc alpine tail -f /etc/hosts About a minute ago Up About a minute vigilant_lumiere容器内部的hosts文件
容器会自动将容器的ID加入自己的/etc/hosts文件中并解析成容器的IP
[rootcentos7 ~]# docker run -it centos /bin/bash
[root8f4c940da642 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 8f4c940da642 # 默认会将实例的ID 添加到自己的hosts文件
[root8f4c940da642 /]# hostname
8f4c940da642
[root8f4c940da642 /]# ping 8f4c940da642
PING 8f4c940da642 (172.17.0.3) 56(84) bytes of data.
64 bytes from 8f4c940da642 (172.17.0.3): icmp_seq1 ttl64 time0.071 ms
64 bytes from 8f4c940da642 (172.17.0.3): icmp_seq2 ttl64 time0.059 ms
64 bytes from 8f4c940da642 (172.17.0.3): icmp_seq3 ttl64 time0.058 ms
^C
--- 8f4c940da642 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev 0.058/0.062/0.071/0.010 ms# 修改容器的hosts文件
[rootcentos7 ~]# docker run -it --rm --add-host chensir.ink:8.8.8.8 --add-host chensir.com:6.6.6.6 busybox
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
8.8.8.8 chensir.ink
6.6.6.6 chensir.com
172.17.0.4 4397ad2a1497
/ # ping chensir.ink
PING chensir.ink (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq0 ttl127 time70.911 ms
64 bytes from 8.8.8.8: seq1 ttl127 time69.407 ms
64 bytes from 8.8.8.8: seq2 ttl127 time64.564 ms
64 bytes from 8.8.8.8: seq3 ttl127 time69.504 ms
^C
--- chensir.ink ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max 64.564/68.596/70.911 ms
/ # ping chensir.com
PING chensir.com (6.6.6.6): 56 data bytes
^C
--- chensir.com ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss指定容器DNS
容器的dns服务器采用宿主机的dns地址可以用下面方式指定其他的DNS地址
将dns地址配置在宿主机在容器启动时加选项 --dnsx.x.x.x在/etc/docker/daemon.json 文件中指定
# 容器的DNS默认从宿主机的DNS获取
[rootcentos7 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 10.0.0.1
[rootcentos7 ~]#
[rootcentos7 ~]# docker run -it --rm centos sh
sh-4.4# cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 10.0.0.1# 指定DNS地址
[rootcentos7 ~]# docker run -it --rm --dns 1.1.1.1 --dns 8.8.8.8 centos bash
[root3e9468f64df2 /]# cat /etc/resolv.conf
search localdomain
nameserver 1.1.1.1
nameserver 8.8.8.8# 指定domain名
[rootcentos7 ~]# docker run -it --rm --dns 1.1.1.1 --dns 8.8.8.8 --dns-search a.com --dns-search b.com busybox
/ # cat /etc/resolv.conf
search a.com b.com
nameserver 1.1.1.1
nameserver 8.8.8.8# 配置文件指定DNS和搜索domain名
[rootcentos7 ~]# vim /etc/docker/daemon.json
{storage-driver: overlay2,registry-mirrors: [https://docker.mirrors.ustc.edu.cn],dns: [114.114.114.114,8.8.8.8],dns-search: [chensir.ink,chensir.xyz]
}
[rootcentos7 ~]# systemctl restart docker
[rootcentos7 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 10.0.0.1
[rootcentos7 ~]# docker run -it centos bash
[root8d3436934bb1 /]# cat /etc/resolv.conf
search chensir.ink chensir.xyz
nameserver 114.114.114.114
nameserver 8.8.8.8# 用--dns指定优先级高
[rootcentos7 ~]# docker run -it --rm --dns 8.8.4.4 centos bash
c[root61c97fb7deb7 /]# cat /etc/resolv.conf
search chensir.ink chensir.xyz
nameserver 8.8.4.4容器内和宿主机之间复制文件
docker cp [OPTION] CONTAINER:SRC_PATH DEST_PATH|-
dpcker cp [OPTION] SRC_PATH|- CONTAINER:DEST_PATH
Options:-a,--archive Archive mode (copy all uid/gid information)-L,--follow-link Always follow symbol link in SRC_PATH使用systemd控制容器运行
[rootcentos7 ~]# vim /etc/systemd/system/hello.service
[Unit]
DescriptionHello world
DescriptionHello world
Afterdocker.service
Requiresdocker.service
[Service]
TimeoutStartSec0
ExecStartPre-/usr/bin/docker kill busybox-hello
ExecStartPre-/usr/bin/docker rm busybox-hello
ExecStartPre-/usr/bin/docker pull busybox
ExecStart/usr/bin/docker run --name busybox-hello busybox /bin/sh -c while true;do echo Hello world; sleep 1; done
ExecStop/usr/bin/docker kill busybox-hello
[Install]
wantedBymulti-user.target[rootcentos7 ~]# systemctl daemon-reload
[rootcentos7 ~]# systemctl enable --now hello.service传递环境变量
有些容器运行时需要传递变量可以使用 -e 参数 或 - - env-file 参数文件 实现
[rootcentos7 ~]# docker run --name mysql01 mysql:5.7.31
WARNING: IPv4 forwarding is disabled. Networking will not work.
2022-08-23 02:08:2300:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.31-1debian10 started.
2022-08-23 02:08:2300:00 [Note] [Entrypoint]: Switching to dedicated user mysql
2022-08-23 02:08:2300:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.31-1debian10 started.
2022-08-23 02:08:2300:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specifiedYou need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD[rootcentos7 ~]# docker run --name mysql-test1 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD123456 -e MYSQL_DATABASEwordpress -e MYSQL_USERwpuser -e MYSQL_PASSWORD123456 -d -p 3306:3306 mysql:5.7.31
WARNING: IPv4 forwarding is disabled. Networking will not work.
ba743ba4068b36c7b2ff804decbb0c5f22aaa8ab0b20ce8bc4c4380ccc990674[rootcentos7 ~]# docker run --name mysql-test2 -v /root/mysql/:/etc/conf.d -v /data/mysql2:/var/lib/mysql --env-fileenv.list -d -p 3307:33077 mysql:5.7.31[rootcentos7 ~]# cat /root/mysql/mysql-test.cnf
[mysqld]
server-id100
log-binmysql-bin[rootcentos7 ~]# cat env.list
MYSQL_ROOT_PASSWORD123456
MYSQL_DATABASEwordpress
MYSQL_USERwpuser
MYSQL_PASSWORDwppassDocker镜像制作和管理
Docker镜像说明
Docker镜像中有没有内核
从镜像大小上来说一个比较小的镜像只有1M多点或者几M而内核文件需要几十M因此镜像里面是没有内核的镜像在被启动为容器后将直接使用宿主机的内核而镜像本身则只提供相应的rootfs即系统正常运行所必须的用户空间的文件系统比如/dev//proc/bin/etc等目录容器当中/boot目录时空的而/boot当中保存的就是与内核相关的文件和目录。
为什么没有内核
由于容器启动和运行过程中是直接使用了宿主机的内核不会直接调用物理硬件所以不会涉及到硬件驱动因此也无需容器内拥有自己的内核和驱动。而如果使用虚拟机技术对应每个虚拟机都有自己独立的内核。
容器中的程序后台运行会导致此容器启动后立即退出
Docker容器如果希望启动后能持续运行就必须有一个能前台持续运行的进程如果在容器中启动系统的服务如httpdphp-fpm等均为后台进程模式运行就导致docker在前台没有运行的应用这样的容器启动后会立即退出。所以一般会将服务程序以前台方式运行对于有一些可能不知道怎么实现前台运行的程序只需要在你启动的该程序之后添加类似于tailtop这种可以前台运行的程序即可。比较常用的方法如 tail -f /etc/hosts 。
# httpd
ENTRYPOINT [/usr/sbin/apache2]
CMD [-D,FOREGROUND]# nginx
ENTRYPOINT [/usr/sbin/nginx,-g,daemon off;]# 用脚本运行容器
cat run_haproxy.sh
#!/bin/bash
haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hoststail -n1 Dockerfile
CMD [run_haproxy.sh]docker镜像生命周期 制作镜像方式
Docker镜像制作类似于虚拟机的镜像模板制作即按照公司的实际业务需求将需要安装的软件、相关配置等基础环境配置完成然后将其做成镜像最后再从镜像批量生成容器实例这样可以极大的简化相同环境的部署工作 Docker的镜像制作分为手动制作基于容器和自动制作基于Dockerfile企业通常都是基于Dockerfile制作镜像
# 通过修改现有容器将之手动构建为镜像
docker commit# 通过Dockerfile文件批量构建为镜像
docker build将现有容器通过docker commit手动构建镜像
基于容器手动制作镜像步骤
docker commit
docker commit [OPTION] CONTAINER [REPOSITORY[:TAG]]
# 选项
-a,--author string Author
-c,--change list Apply Dockerfile instruction to the created image
-m,--message string Commit message
-p,--pause Pause container during commit (default true)# 说明
制作镜像和CONTAINER状态无关停止状态也可以制作镜像
如果没有指定[REPOSITORY[:TAG]]REPOSITORY和TAG都为none
提交的时候标记TAG号生产中常用后期可以根据TAG标记创建不同版本的镜像以及创建不同版本的容器基于容器手动制作镜像步骤具体如下 1.下载一个系统的官方基础镜像如CentOS 或 Ubuntu 2.基于基础镜像启动一个容器并进入到容器 3.在容器里面做配置操作
安装基础命令配置运行环境安装服务和配置服务放业务程序和代码
4.提交为一个新镜像 docker commit 5.基于自己的镜像创建容器并测试访问
基于busybox制作httpd镜像
[rootcentos7 ~]# docker run -it --name b1 busybox
WARNING: IPv4 forwarding is disabled. Networking will not work.
/ # ls
bin dev etc home proc root sys tmp usr var
/ # mkdir /data/html -p
/ # echo httpd website in busybox /data/html/index.html
/ # httpd --help
BusyBox v1.34.1 (2021-12-29 21:12:15 UTC) multi-call binary.Usage: httpd [-ifv[v]] [-c CONFFILE] [-p [IP:]PORT] [-u USER[:GRP]] [-r REALM] [-h HOME]
or httpd -d/-e/-m STRINGListen for incoming HTTP requests-i Inetd mode-f Dont daemonize-v[v] Verbose-p [IP:]PORT Bind to IP:PORT (default *:80)-u USER[:GRP] Set uid/gid after binding to port-r REALM Authentication Realm for Basic Authentication-h HOME Home directory (default .)-c FILE Configuration file (default {/etc,HOME}/httpd.conf)-m STRING MD5 crypt STRING-e STRING HTML encode STRING-d STRING URL decode STRING
/ # exit# 格式1
[rootcentos7 ~]# docker commit -a chensirrootchensir.ink -c CMD /bin/httpd -fv -h /data/html -c EXPOSE 80 b1 httpd-busybox:v1.0
sha256:0b59f1b5b2b1dca5f0386098a558b09593f652761c8a40e8723abdba2a0b43ce
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd-busybox v1.0 0b59f1b5b2b1 4 seconds ago 1.24MB# 格式2
[rootcentos7 ~]# docker commit -a chensirrootchenisr.ink -c CMD [/bin/httpd,-f,-v,-h,/data/html] -c EXPOSE 80 b1 httpd-busybox:v1.0
sha256:4100f91eb2e4949651fa401949791c746e34ae65e35fdbf456aa3bd55d703c72[rootcentos7 ~]# docker run -d -P --name httpd01 httpd-busybox:v1.0
WARNING: IPv4 forwarding is disabled. Networking will not work.
5a68de75aa05b374faeef9e08de92ffa3679cfaa240700f6ff1614576e24f3c4
[rootcentos7 ~]# docker port httpd01
80/tcp - 0.0.0.0:49157
80/tcp - :::49157
[rootcentos7 ~]# docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} httpd01
172.17.0.2# 对应格式1
[rootcentos7 ~]# docker inspect -f {{.Config.Cmd}} httpd01
[/bin/sh -c /bin/httpd -fv -h /data/html]# 对应格式2
[rootcentos7 ~]# docker inspect -f {{.Config.Cmd}} httpd01
[/bin/httpd -f -v -h /data/html][rootcentos7 ~]# docker exec -it httpd01 sh
/ # pstree -p
httpd(1)
/ # ps aux
PID USER TIME COMMAND1 root 0:00 /bin/httpd -f -v -h /data/html8 root 0:00 sh14 root 0:00 ps aux
/ # read escape sequence
[rootcentos7 ~]# curl 172.17.0.2
httpd website in busybox
[rootcentos7 ~]# curl 127.0.0.1:49157
httpd website in busybox
[rootcentos7 ~]# docker commit -a chensirchensirchensir.ink b1 httpd-busybox:v2.0
sha256:b83d0a45c90bbfc368b57629af1985ec3f6d4bf05b870650fd7b73eb72c9771a
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd-busybox v2.0 b83d0a45c90b 6 seconds ago 1.24MB
httpd-busybox v1.0 fc393ccc5dd0 16 minutes ago 1.24MB
[rootcentos7 ~]# docker run -d --name web2 -p 81:80 httpd-busybox:v2.0 /bin/httpd -fv -h /date/html
WARNING: IPv4 forwarding is disabled. Networking will not work.
ef52ca935dc26a7283bc5a9de537f8fb1540de81f12729356c011041744fb6b0基于官方镜像生成的容器制作tomcat镜像
下载官方的tomcat镜像并运行
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[rootcentos7 ~]# docker run -d -p 8080:8080 tomcat
Unable to find image tomcat:latest locally
latest: Pulling from library/tomcat
0e29546d541c: Pull complete
9b829c73b52b: Pull complete
cb5b7ae36172: Pull complete
6494e4811622: Pull complete
668f6fcc5fa5: Pull complete
dc120c3e0290: Pull complete
8f7c0eebb7b1: Pull complete
77b694f83996: Pull complete
0f611256ec3a: Pull complete
4f25def12f23: Pull complete
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
WARNING: IPv4 forwarding is disabled. Networking will not work.
38cedc776327713d0d3081ddc26f0097b4f2b5a0981cc08a9afdfc0056e24434
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
38cedc776327 tomcat catalina.sh run 2 minutes ago Up 2 minutes 0.0.0.0:8080-8080/tcp, :::8080-8080/tcp gracious_booth
[rootcentos7 ~]# curl -I 127.0.0.1:8080
HTTP/1.1 404
Content-Type: text/html;charsetutf-8
Content-Language: en
Transfer-Encoding: chunked
Date: Tue, 23 Aug 2022 15:47:57 GMT修改容器
[rootcentos7 ~]# docker exec -it 38c bash
root38cedc776327:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root38cedc776327:/usr/local/tomcat# ls webapps
root38cedc776327:/usr/local/tomcat# ls webapps.dist/
ROOT docs examples host-manager manager
root38cedc776327:/usr/local/tomcat# cp -a webapps.dist/* webapps/
root38cedc776327:/usr/local/tomcat# ls webapps
ROOT docs examples host-manager manager
root38cedc776327:/usr/local/tomcat# exit
exit
[rootcentos7 ~]# curl -I 127.0.0.1:8080
HTTP/1.1 200
Content-Type: text/html;charsetUTF-8
Transfer-Encoding: chunked
Date: Tue, 23 Aug 2022 15:52:21 GMT提交新镜像
[rootcentos7 ~]# docker commit -m add webapps app -a chensir 38c tomcat:9.0.37-v1
sha256:399beff7540e7ade5ec2f34a794a3e972351dd66b2ccab1fb73604d7a1b3518f
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 9.0.37-v1 399beff7540e 4 seconds ago 684MB
tomcat latest fb5657adc892 8 months ago 680MB
[rootcentos7 ~]# docker history tomcat:9.0.37-v1
IMAGE CREATED CREATED BY SIZE COMMENT
399beff7540e 43 seconds ago catalina.sh run 4.43MB add webapps app
fb5657adc892 8 months ago /bin/sh -c #(nop) CMD [catalina.sh run] 0B
missing 8 months ago /bin/sh -c #(nop) EXPOSE 8080 0B
missing 8 months ago /bin/sh -c set -eux; nativeLines$(catalin… 0B
missing 8 months ago /bin/sh -c set -eux; savedAptMark$(apt-m… 20.2MB
missing 8 months ago /bin/sh -c #(nop) ENV TOMCAT_SHA512c2d2ad5… 0B
missing 8 months ago /bin/sh -c #(nop) ENV TOMCAT_VERSION10.0.14 0B
missing 8 months ago /bin/sh -c #(nop) ENV TOMCAT_MAJOR10 0B
missing 8 months ago /bin/sh -c #(nop) ENV GPG_KEYSA9C5DF4D22E9… 0B
missing 8 months ago /bin/sh -c #(nop) ENV LD_LIBRARY_PATH/usr/… 0B
missing 8 months ago /bin/sh -c #(nop) ENV TOMCAT_NATIVE_LIBDIR… 0B
missing 8 months ago /bin/sh -c #(nop) WORKDIR /usr/local/tomcat 0B
missing 8 months ago /bin/sh -c mkdir -p $CATALINA_HOME 0B
missing 8 months ago /bin/sh -c #(nop) ENV PATH/usr/local/tomca… 0B
missing 8 months ago /bin/sh -c #(nop) ENV CATALINA_HOME/usr/lo… 0B
missing 8 months ago /bin/sh -c #(nop) CMD [jshell] 0B
missing 8 months ago /bin/sh -c set -eux; arch$(dpkg --print-… 343MB
missing 8 months ago /bin/sh -c #(nop) ENV JAVA_VERSION11.0.13 0B
missing 8 months ago /bin/sh -c #(nop) ENV LANGC.UTF-8 0B
missing 8 months ago /bin/sh -c #(nop) ENV PATH/usr/local/openj… 0B
missing 8 months ago /bin/sh -c { echo #/bin/sh; echo echo $J… 27B
missing 8 months ago /bin/sh -c #(nop) ENV JAVA_HOME/usr/local/… 0B
missing 8 months ago /bin/sh -c set -eux; apt-get update; apt-g… 11.3MB
missing 8 months ago /bin/sh -c apt-get update apt-get install… 152MB
missing 8 months ago /bin/sh -c set -ex; if ! command -v gpg /… 18.9MB
missing 8 months ago /bin/sh -c set -eux; apt-get update; apt-g… 10.7MB
missing 8 months ago /bin/sh -c #(nop) CMD [bash] 0B
missing 8 months ago /bin/sh -c #(nop) ADD file:c03517c5ddbed4053… 124MB
# 删除当前的容器
[rootcentos7 ~]# docker rm -f 38c
38c
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES利用新镜像启动容器
[rootcentos7 ~]# docker run -d -p 8080:8080 --name tomcat tomcat:9.0.37-v1
[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff4f232c7ce0 tomcat:9.0.37-v1 catalina.sh run 15 hours ago Up 5 minutes 0.0.0.0:8080-8080/tcp, :::8080-8080/tcp tomcat
[rootcentos7 ~]# hostname -I
10.0.0.14 172.17.0.1测试新镜像启动的容器
浏览器访问 http://10.0.0.14:8080 出现画面即可
基于Ubuntu的基础镜像利用apt安装手动制作nginx的镜像
# 启动容器[rootcentos7 ~]# docker run -it -p 80 --name nginx_ubuntu ubuntu bash# 查看ubuntu系统信息rootd35021705364:/# cat /etc/os-releaseNAMEUbuntuVERSION20.04.3 LTS (Focal Fossa)IDubuntuID_LIKEdebianPRETTY_NAMEUbuntu 20.04.3 LTSVERSION_ID20.04HOME_URLhttps://www.ubuntu.com/SUPPORT_URLhttps://help.ubuntu.com/BUG_REPORT_URLhttps://bugs.launchpad.net/ubuntu/PRIVACY_POLICY_URLhttps://www.ubuntu.com/legal/terms-and-policies/privacy-policyVERSION_CODENAMEfocalUBUNTU_CODENAMEfocal# 更新源rootd35021705364:/# apt updateGet:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]Get:2 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]Get:3 http://security.ubuntu.com/ubuntu focal-security/universe amd64 Packages [888 kB]Get:4 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]Get:5 http://security.ubuntu.com/ubuntu focal-security/multiverse amd64 Packages [27.5 kB]Get:6 http://security.ubuntu.com/ubuntu focal-security/main amd64 Packages [2091 kB]Get:7 http://archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB]Get:8 http://archive.ubuntu.com/ubuntu focal/restricted amd64 Packages [33.4 kB]Get:9 http://archive.ubuntu.com/ubuntu focal/multiverse amd64 Packages [177 kB]Get:10 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 Packages [1462 kB]Get:11 http://archive.ubuntu.com/ubuntu focal/main amd64 Packages [1275 kB]Get:12 http://archive.ubuntu.com/ubuntu focal/universe amd64 Packages [11.3 MB]Get:13 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages [1183 kB]Get:14 http://archive.ubuntu.com/ubuntu focal-updates/restricted amd64 Packages [1572 kB]Get:15 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages [2547 kB]Get:16 http://archive.ubuntu.com/ubuntu focal-updates/multiverse amd64 Packages [30.2 kB]Get:17 http://archive.ubuntu.com/ubuntu focal-backports/universe amd64 Packages [27.4 kB]Get:18 http://archive.ubuntu.com/ubuntu focal-backports/main amd64 Packages [55.1 kB]Fetched 23.3 MB in 28s (841 kB/s)Reading package lists... DoneBuilding dependency treeReading state information... Done34 packages can be upgraded. Run apt list --upgradable to see them.# 安装nginxrootd35021705364:/# apt install -y nginxReading package lists... DoneBuilding dependency treeReading state information... DoneThe following additional packages will be installed:fontconfig-config fonts-dejavu-core iproute2 libatm1 libbsd0 libcap2 libcap2-bin libelf1 libexpat1 libfontconfig1 libfreetype6 libgd3 libicu66libjbig0 libjpeg-turbo8 libjpeg8 libmnl0 libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-streamlibpam-cap libpng16-16 libssl1.1 libtiff5 libwebp6 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxml2 libxpm4 libxslt1.1 libxtables12nginx-common nginx-core tzdata ucfSuggested packages:iproute2-doc libgd-tools fcgiwrap nginx-doc ssl-certThe following NEW packages will be installed:fontconfig-config fonts-dejavu-core iproute2 libatm1 libbsd0 libcap2 libcap2-bin libelf1 libexpat1 libfontconfig1 libfreetype6 libgd3 libicu66libjbig0 libjpeg-turbo8 libjpeg8 libmnl0 libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-streamlibpam-cap libpng16-16 libssl1.1 libtiff5 libwebp6 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxml2 libxpm4 libxslt1.1 libxtables12 nginxnginx-common nginx-core tzdata ucf0 upgraded, 40 newly installed, 0 to remove and 34 not upgraded.Need to get 15.8 MB of archives.After this operation, 60.8 MB of additional disk space will be used.Get:1 http://archive.ubuntu.com/ubuntu focal/main amd64 libbsd0 amd64 0.10.0-1 [45.4 kB]Get:2 http://archive.ubuntu.com/ubuntu focal/main amd64 libcap2 amd64 1:2.32-1 [15.9 kB]Get:3 http://archive.ubuntu.com/ubuntu focal/main amd64 libelf1 amd64 0.176-1.1build1 [44.0 kB]Get:4 http://archive.ubuntu.com/ubuntu focal/main amd64 libmnl0 amd64 1.0.4-2 [12.3 kB]Get:5 http://archive.ubuntu.com/ubuntu focal/main amd64 libxtables12 amd64 1.8.4-3ubuntu2 [28.4 kB]Get:6 http://archive.ubuntu.com/ubuntu focal/main amd64 libcap2-bin amd64 1:2.32-1 [26.2 kB]Get:7 http://archive.ubuntu.com/ubuntu focal/main amd64 iproute2 amd64 5.5.0-1ubuntu1 [858 kB]Get:8 http://archive.ubuntu.com/ubuntu focal/main amd64 libatm1 amd64 1:2.5.1-4 [21.8 kB]Get:9 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libexpat1 amd64 2.2.9-1ubuntu0.4 [74.4 kB]Get:10 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 tzdata all 2022a-0ubuntu0.20.04 [294 kB]Get:11 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libicu66 amd64 66.1-2ubuntu2.1 [8515 kB]Get:12 http://archive.ubuntu.com/ubuntu focal/main amd64 libpam-cap amd64 1:2.32-1 [8352 B]Get:13 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libssl1.1 amd64 1.1.1f-1ubuntu2.16 [1321 kB]Get:14 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libxml2 amd64 2.9.10dfsg-5ubuntu0.20.04.4 [640 kB]Get:15 http://archive.ubuntu.com/ubuntu focal/main amd64 ucf all 3.0038nmu1 [51.6 kB]Get:16 http://archive.ubuntu.com/ubuntu focal/main amd64 libpng16-16 amd64 1.6.37-2 [179 kB]Get:17 http://archive.ubuntu.com/ubuntu focal/main amd64 libxau6 amd64 1:1.0.9-0ubuntu1 [7488 B]Get:18 http://archive.ubuntu.com/ubuntu focal/main amd64 libxdmcp6 amd64 1:1.1.3-0ubuntu1 [10.6 kB]Get:19 http://archive.ubuntu.com/ubuntu focal/main amd64 libxcb1 amd64 1.14-2 [44.7 kB]Get:20 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libx11-data all 2:1.6.9-2ubuntu1.2 [113 kB]Get:21 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libx11-6 amd64 2:1.6.9-2ubuntu1.2 [575 kB]Get:22 http://archive.ubuntu.com/ubuntu focal/main amd64 fonts-dejavu-core all 2.37-1 [1041 kB]Get:23 http://archive.ubuntu.com/ubuntu focal/main amd64 fontconfig-config all 2.13.1-2ubuntu3 [28.8 kB]Get:24 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libfreetype6 amd64 2.10.1-2ubuntu0.2 [341 kB]Get:25 http://archive.ubuntu.com/ubuntu focal/main amd64 libfontconfig1 amd64 2.13.1-2ubuntu3 [114 kB]Get:26 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libjpeg-turbo8 amd64 2.0.3-0ubuntu1.20.04.1 [117 kB]Get:27 http://archive.ubuntu.com/ubuntu focal/main amd64 libjpeg8 amd64 8c-2ubuntu8 [2194 B]Get:28 http://archive.ubuntu.com/ubuntu focal/main amd64 libjbig0 amd64 2.1-3.1build1 [26.7 kB]Get:29 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libwebp6 amd64 0.6.1-2ubuntu0.20.04.1 [185 kB]Get:30 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libtiff5 amd64 4.1.0git191117-2ubuntu0.20.04.3 [162 kB]Get:31 http://archive.ubuntu.com/ubuntu focal/main amd64 libxpm4 amd64 1:3.5.12-1 [34.0 kB]Get:32 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libgd3 amd64 2.2.5-5.2ubuntu2.1 [118 kB]Get:33 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 nginx-common all 1.18.0-0ubuntu1.3 [37.7 kB]Get:34 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libnginx-mod-http-image-filter amd64 1.18.0-0ubuntu1.3 [14.8 kB]Get:35 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libxslt1.1 amd64 1.1.34-4ubuntu0.20.04.1 [151 kB]Get:36 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libnginx-mod-http-xslt-filter amd64 1.18.0-0ubuntu1.3 [13.0 kB]Get:37 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libnginx-mod-mail amd64 1.18.0-0ubuntu1.3 [42.8 kB]Get:38 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libnginx-mod-stream amd64 1.18.0-0ubuntu1.3 [67.3 kB]Get:39 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 nginx-core amd64 1.18.0-0ubuntu1.3 [425 kB]Get:40 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 nginx all 1.18.0-0ubuntu1.3 [3620 B]Fetched 15.8 MB in 9s (1680 kB/s)debconf: delaying package configuration, since apt-utils is not installedSelecting previously unselected package libbsd0:amd64.(Reading database ... 4127 files and directories currently installed.)Preparing to unpack .../00-libbsd0_0.10.0-1_amd64.deb ...Unpacking libbsd0:amd64 (0.10.0-1) ...Selecting previously unselected package libcap2:amd64.Preparing to unpack .../01-libcap2_1%3a2.32-1_amd64.deb ...Unpacking libcap2:amd64 (1:2.32-1) ...Selecting previously unselected package libelf1:amd64.Preparing to unpack .../02-libelf1_0.176-1.1build1_amd64.deb ...Unpacking libelf1:amd64 (0.176-1.1build1) ...Selecting previously unselected package libmnl0:amd64.Preparing to unpack .../03-libmnl0_1.0.4-2_amd64.deb ...Unpacking libmnl0:amd64 (1.0.4-2) ...Selecting previously unselected package libxtables12:amd64.Preparing to unpack .../04-libxtables12_1.8.4-3ubuntu2_amd64.deb ...Unpacking libxtables12:amd64 (1.8.4-3ubuntu2) ...Selecting previously unselected package libcap2-bin.Preparing to unpack .../05-libcap2-bin_1%3a2.32-1_amd64.deb ...Unpacking libcap2-bin (1:2.32-1) ...Selecting previously unselected package iproute2.Preparing to unpack .../06-iproute2_5.5.0-1ubuntu1_amd64.deb ...Unpacking iproute2 (5.5.0-1ubuntu1) ...Selecting previously unselected package libatm1:amd64.Preparing to unpack .../07-libatm1_1%3a2.5.1-4_amd64.deb ...Unpacking libatm1:amd64 (1:2.5.1-4) ...Selecting previously unselected package libexpat1:amd64.Preparing to unpack .../08-libexpat1_2.2.9-1ubuntu0.4_amd64.deb ...Unpacking libexpat1:amd64 (2.2.9-1ubuntu0.4) ...Selecting previously unselected package tzdata.Preparing to unpack .../09-tzdata_2022a-0ubuntu0.20.04_all.deb ...Unpacking tzdata (2022a-0ubuntu0.20.04) ...Selecting previously unselected package libicu66:amd64.Preparing to unpack .../10-libicu66_66.1-2ubuntu2.1_amd64.deb ...Unpacking libicu66:amd64 (66.1-2ubuntu2.1) ...Selecting previously unselected package libpam-cap:amd64.Preparing to unpack .../11-libpam-cap_1%3a2.32-1_amd64.deb ...Unpacking libpam-cap:amd64 (1:2.32-1) ...Selecting previously unselected package libssl1.1:amd64.Preparing to unpack .../12-libssl1.1_1.1.1f-1ubuntu2.16_amd64.deb ...Unpacking libssl1.1:amd64 (1.1.1f-1ubuntu2.16) ...Selecting previously unselected package libxml2:amd64.Preparing to unpack .../13-libxml2_2.9.10dfsg-5ubuntu0.20.04.4_amd64.deb ...Unpacking libxml2:amd64 (2.9.10dfsg-5ubuntu0.20.04.4) ...Selecting previously unselected package ucf.Preparing to unpack .../14-ucf_3.0038nmu1_all.deb ...Moving old data out of the wayUnpacking ucf (3.0038nmu1) ...Selecting previously unselected package libpng16-16:amd64.Preparing to unpack .../15-libpng16-16_1.6.37-2_amd64.deb ...Unpacking libpng16-16:amd64 (1.6.37-2) ...Selecting previously unselected package libxau6:amd64.Preparing to unpack .../16-libxau6_1%3a1.0.9-0ubuntu1_amd64.deb ...Unpacking libxau6:amd64 (1:1.0.9-0ubuntu1) ...Selecting previously unselected package libxdmcp6:amd64.Preparing to unpack .../17-libxdmcp6_1%3a1.1.3-0ubuntu1_amd64.deb ...Unpacking libxdmcp6:amd64 (1:1.1.3-0ubuntu1) ...Selecting previously unselected package libxcb1:amd64.Preparing to unpack .../18-libxcb1_1.14-2_amd64.deb ...Unpacking libxcb1:amd64 (1.14-2) ...Selecting previously unselected package libx11-data.Preparing to unpack .../19-libx11-data_2%3a1.6.9-2ubuntu1.2_all.deb ...Unpacking libx11-data (2:1.6.9-2ubuntu1.2) ...Selecting previously unselected package libx11-6:amd64.Preparing to unpack .../20-libx11-6_2%3a1.6.9-2ubuntu1.2_amd64.deb ...Unpacking libx11-6:amd64 (2:1.6.9-2ubuntu1.2) ...Selecting previously unselected package fonts-dejavu-core.Preparing to unpack .../21-fonts-dejavu-core_2.37-1_all.deb ...Unpacking fonts-dejavu-core (2.37-1) ...Selecting previously unselected package fontconfig-config.Preparing to unpack .../22-fontconfig-config_2.13.1-2ubuntu3_all.deb ...Unpacking fontconfig-config (2.13.1-2ubuntu3) ...Selecting previously unselected package libfreetype6:amd64.Preparing to unpack .../23-libfreetype6_2.10.1-2ubuntu0.2_amd64.deb ...Unpacking libfreetype6:amd64 (2.10.1-2ubuntu0.2) ...Selecting previously unselected package libfontconfig1:amd64.Preparing to unpack .../24-libfontconfig1_2.13.1-2ubuntu3_amd64.deb ...Unpacking libfontconfig1:amd64 (2.13.1-2ubuntu3) ...Selecting previously unselected package libjpeg-turbo8:amd64.Preparing to unpack .../25-libjpeg-turbo8_2.0.3-0ubuntu1.20.04.1_amd64.deb ...Unpacking libjpeg-turbo8:amd64 (2.0.3-0ubuntu1.20.04.1) ...Selecting previously unselected package libjpeg8:amd64.Preparing to unpack .../26-libjpeg8_8c-2ubuntu8_amd64.deb ...Unpacking libjpeg8:amd64 (8c-2ubuntu8) ...Selecting previously unselected package libjbig0:amd64.Preparing to unpack .../27-libjbig0_2.1-3.1build1_amd64.deb ...Unpacking libjbig0:amd64 (2.1-3.1build1) ...Selecting previously unselected package libwebp6:amd64.Preparing to unpack .../28-libwebp6_0.6.1-2ubuntu0.20.04.1_amd64.deb ...Unpacking libwebp6:amd64 (0.6.1-2ubuntu0.20.04.1) ...Selecting previously unselected package libtiff5:amd64.Preparing to unpack .../29-libtiff5_4.1.0git191117-2ubuntu0.20.04.3_amd64.deb ...Unpacking libtiff5:amd64 (4.1.0git191117-2ubuntu0.20.04.3) ...Selecting previously unselected package libxpm4:amd64.Preparing to unpack .../30-libxpm4_1%3a3.5.12-1_amd64.deb ...Unpacking libxpm4:amd64 (1:3.5.12-1) ...Selecting previously unselected package libgd3:amd64.Preparing to unpack .../31-libgd3_2.2.5-5.2ubuntu2.1_amd64.deb ...Unpacking libgd3:amd64 (2.2.5-5.2ubuntu2.1) ...Selecting previously unselected package nginx-common.Preparing to unpack .../32-nginx-common_1.18.0-0ubuntu1.3_all.deb ...Unpacking nginx-common (1.18.0-0ubuntu1.3) ...Selecting previously unselected package libnginx-mod-http-image-filter.Preparing to unpack .../33-libnginx-mod-http-image-filter_1.18.0-0ubuntu1.3_amd64.deb ...Unpacking libnginx-mod-http-image-filter (1.18.0-0ubuntu1.3) ...Selecting previously unselected package libxslt1.1:amd64.Preparing to unpack .../34-libxslt1.1_1.1.34-4ubuntu0.20.04.1_amd64.deb ...Unpacking libxslt1.1:amd64 (1.1.34-4ubuntu0.20.04.1) ...Selecting previously unselected package libnginx-mod-http-xslt-filter.Preparing to unpack .../35-libnginx-mod-http-xslt-filter_1.18.0-0ubuntu1.3_amd64.deb ...Unpacking libnginx-mod-http-xslt-filter (1.18.0-0ubuntu1.3) ...Selecting previously unselected package libnginx-mod-mail.Preparing to unpack .../36-libnginx-mod-mail_1.18.0-0ubuntu1.3_amd64.deb ...Unpacking libnginx-mod-mail (1.18.0-0ubuntu1.3) ...Selecting previously unselected package libnginx-mod-stream.Preparing to unpack .../37-libnginx-mod-stream_1.18.0-0ubuntu1.3_amd64.deb ...Unpacking libnginx-mod-stream (1.18.0-0ubuntu1.3) ...Selecting previously unselected package nginx-core.Preparing to unpack .../38-nginx-core_1.18.0-0ubuntu1.3_amd64.deb ...Unpacking nginx-core (1.18.0-0ubuntu1.3) ...Selecting previously unselected package nginx.Preparing to unpack .../39-nginx_1.18.0-0ubuntu1.3_all.deb ...Unpacking nginx (1.18.0-0ubuntu1.3) ...Setting up libexpat1:amd64 (2.2.9-1ubuntu0.4) ...Setting up libxau6:amd64 (1:1.0.9-0ubuntu1) ...Setting up libssl1.1:amd64 (1.1.1f-1ubuntu2.16) ...debconf: unable to initialize frontend: Dialogdebconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)debconf: falling back to frontend: Readlinedebconf: unable to initialize frontend: Readlinedebconf: (Cant locate Term/ReadLine.pm in INC (you may need to install the Term::ReadLine module) (INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)debconf: falling back to frontend: TeletypeSetting up nginx-common (1.18.0-0ubuntu1.3) ...debconf: unable to initialize frontend: Dialogdebconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)debconf: falling back to frontend: Readlinedebconf: unable to initialize frontend: Readlinedebconf: (Cant locate Term/ReadLine.pm in INC (you may need to install the Term::ReadLine module) (INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)debconf: falling back to frontend: TeletypeSetting up libatm1:amd64 (1:2.5.1-4) ...Setting up libjbig0:amd64 (2.1-3.1build1) ...Setting up libcap2:amd64 (1:2.32-1) ...Setting up tzdata (2022a-0ubuntu0.20.04) ...debconf: unable to initialize frontend: Dialogdebconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)debconf: falling back to frontend: Readlinedebconf: unable to initialize frontend: Readlinedebconf: (Cant locate Term/ReadLine.pm in INC (you may need to install the Term::ReadLine module) (INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)debconf: falling back to frontend: TeletypeConfiguring tzdata------------------Please select the geographic area in which you live. Subsequent configuration questions will narrow this down by presenting a list of cities,representing the time zones in which they are located.1. Africa 3. Antarctica 5. Arctic 7. Atlantic 9. Indian 11. SystemV 13. Etc2. America 4. Australia 6. Asia 8. Europe 10. Pacific 12. USGeographic area: 6Please select the city or region corresponding to your time zone.1. Aden 13. Barnaul 25. Dushanbe 37. Jerusalem 49. Macau 61. Pyongyang 73. Taipei 85. Vientiane2. Almaty 14. Beirut 26. Famagusta 38. Kabul 50. Magadan 62. Qatar 74. Tashkent 86. Vladivostok3. Amman 15. Bishkek 27. Gaza 39. Kamchatka 51. Makassar 63. Qostanay 75. Tbilisi 87. Yakutsk4. Anadyr 16. Brunei 28. Harbin 40. Karachi 52. Manila 64. Qyzylorda 76. Tehran 88. Yangon5. Aqtau 17. Chita 29. Hebron 41. Kashgar 53. Muscat 65. Rangoon 77. Tel_Aviv 89. Yekaterinburg6. Aqtobe 18. Choibalsan 30. Ho_Chi_Minh 42. Kathmandu 54. Nicosia 66. Riyadh 78. Thimphu 90. Yerevan7. Ashgabat 19. Chongqing 31. Hong_Kong 43. Khandyga 55. Novokuznetsk 67. Sakhalin 79. Tokyo8. Atyrau 20. Colombo 32. Hovd 44. Kolkata 56. Novosibirsk 68. Samarkand 80. Tomsk9. Baghdad 21. Damascus 33. Irkutsk 45. Krasnoyarsk 57. Omsk 69. Seoul 81. Ujung_Pandang10. Bahrain 22. Dhaka 34. Istanbul 46. Kuala_Lumpur 58. Oral 70. Shanghai 82. Ulaanbaatar11. Baku 23. Dili 35. Jakarta 47. Kuching 59. Phnom_Penh 71. Singapore 83. Urumqi12. Bangkok 24. Dubai 36. Jayapura 48. Kuwait 60. Pontianak 72. Srednekolymsk 84. Ust-NeraTime zone: 70 # 配置时区Current default time zone: Asia/ShanghaiLocal time is now: Wed Aug 24 15:05:46 CST 2022.Universal Time is now: Wed Aug 24 07:05:46 UTC 2022.Run dpkg-reconfigure tzdata if you wish to change it.Setting up libcap2-bin (1:2.32-1) ...Setting up libx11-data (2:1.6.9-2ubuntu1.2) ...Setting up libpng16-16:amd64 (1.6.37-2) ...Setting up libmnl0:amd64 (1.0.4-2) ...Setting up libwebp6:amd64 (0.6.1-2ubuntu0.20.04.1) ...Setting up fonts-dejavu-core (2.37-1) ...Setting up ucf (3.0038nmu1) ...debconf: unable to initialize frontend: Dialogdebconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)debconf: falling back to frontend: Readlinedebconf: unable to initialize frontend: Readlinedebconf: (Cant locate Term/ReadLine.pm in INC (you may need to install the Term::ReadLine module) (INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)debconf: falling back to frontend: TeletypeSetting up libjpeg-turbo8:amd64 (2.0.3-0ubuntu1.20.04.1) ...Setting up libxtables12:amd64 (1.8.4-3ubuntu2) ...Setting up libbsd0:amd64 (0.10.0-1) ...Setting up libelf1:amd64 (0.176-1.1build1) ...Setting up libpam-cap:amd64 (1:2.32-1) ...debconf: unable to initialize frontend: Dialogdebconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)debconf: falling back to frontend: Readlinedebconf: unable to initialize frontend: Readlinedebconf: (Cant locate Term/ReadLine.pm in INC (you may need to install the Term::ReadLine module) (INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)debconf: falling back to frontend: TeletypeSetting up libjpeg8:amd64 (8c-2ubuntu8) ...Setting up libnginx-mod-mail (1.18.0-0ubuntu1.3) ...Setting up libxdmcp6:amd64 (1:1.1.3-0ubuntu1) ...Setting up libxcb1:amd64 (1.14-2) ...Setting up fontconfig-config (2.13.1-2ubuntu3) ...Setting up iproute2 (5.5.0-1ubuntu1) ...debconf: unable to initialize frontend: Dialogdebconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)debconf: falling back to frontend: Readlinedebconf: unable to initialize frontend: Readlinedebconf: (Cant locate Term/ReadLine.pm in INC (you may need to install the Term::ReadLine module) (INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)debconf: falling back to frontend: TeletypeSetting up libicu66:amd64 (66.1-2ubuntu2.1) ...Setting up libnginx-mod-stream (1.18.0-0ubuntu1.3) ...Setting up libfreetype6:amd64 (2.10.1-2ubuntu0.2) ...Setting up libx11-6:amd64 (2:1.6.9-2ubuntu1.2) ...Setting up libtiff5:amd64 (4.1.0git191117-2ubuntu0.20.04.3) ...Setting up libfontconfig1:amd64 (2.13.1-2ubuntu3) ...Setting up libxml2:amd64 (2.9.10dfsg-5ubuntu0.20.04.4) ...Setting up libxpm4:amd64 (1:3.5.12-1) ...Setting up libgd3:amd64 (2.2.5-5.2ubuntu2.1) ...Setting up libxslt1.1:amd64 (1.1.34-4ubuntu0.20.04.1) ...Setting up libnginx-mod-http-image-filter (1.18.0-0ubuntu1.3) ...Setting up libnginx-mod-http-xslt-filter (1.18.0-0ubuntu1.3) ...Setting up nginx-core (1.18.0-0ubuntu1.3) ...invoke-rc.d: could not determine current runlevelinvoke-rc.d: policy-rc.d denied execution of start.Setting up nginx (1.18.0-0ubuntu1.3) ...Processing triggers for libc-bin (2.31-0ubuntu9.2) ...# 查看nginx版本rootd35021705364:/# nginx -vnginx version: nginx/1.18.0 (Ubuntu)rootd35021705364:/# grep include /etc/nginx/nginx.confinclude /etc/nginx/modules-enabled/*.conf;include /etc/nginx/mime.types;include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;rootd35021705364:/# grep root /etc/nginx/sites-enabled/defaultroot /var/www/html;# deny access to .htaccess files, if Apaches document root# root /var/www/example.com;rootd35021705364:/# echo Nginx website in Docker /var/www/html/index.htmlrootd35021705364:/# exitexit# 提交为镜像[rootcentos7 ~]# docker commit -a chensir -m nginx-ubuntu:20.04 nginx_ubuntu nginx_ubuntu20.04:v1.18.0sha256:b33b57cff5d3c68c56b5826490ddcb0c9e7751f2d275a9d6d1e43d63764f78b0[rootcentos7 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEnginx_ubuntu20.04 v1.18.0 b33b57cff5d3 5 seconds ago 169MB# 从制作的新镜像启动容器并测试访问[rootcentos7 ~]# docker run -d -p 80 --name nginx-web nginx_ubuntu20.04:v1.18.0 nginx -g daemon off;06098c8bc2ec93978167950adfa5e827c75174aba306337165813a9e950b1972[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES06098c8bc2ec nginx_ubuntu20.04:v1.18.0 nginx -g daemon of… 2 seconds ago Up 2 seconds 0.0.0.0:49162-80/tcp, :::49162-80/tcp nginx-web[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES06098c8bc2ec nginx_ubuntu20.04:v1.18.0 nginx -g daemon of… 2 seconds ago Up 2 seconds 0.0.0.0:49162-80/tcp, :::49162-80/tcp nginx-web[rootcentos7 ~]# docker port nginx-web80/tcp - 0.0.0.0:4916280/tcp - :::49162[rootcentos7 ~]# curl 127.0.0.1:49162Nginx website in Docker基于CentOS的基础镜像利用yum安装手动制作nginx的镜像
[rootcentos7 ~]# docker pull centos:centos7.7.1908centos7.7.1908: Pulling from library/centosf34b00c7da20: Pull completeDigest: sha256:50752af5182c6cd5518e3e91d48f7ff0cba93d5d760a67ac140e2d63c4dd9efcStatus: Downloaded newer image for centos:centos7.7.1908docker.io/library/centos:centos7.7.1908[rootcentos7 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEcentos centos7.7.1908 08d05d1d5859 2 years ago 204MB[rootcentos7 ~]# docker run -it centos:centos7.7.1908 bash# 修改时区[root0b3db04f3a72 /]# rm -f /etc/localtime[root0b3db04f3a72 /]# ln -s ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime# 更改yum源[root0b3db04f3a72 /]# yum install -y wget[root0b3db04f3a72 /]# wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo[root0b3db04f3a72 /]# wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo[root0b3db04f3a72 /]# yum install -y nginx# 安装相关软件和工具# yum 安装 nginx[root0b3db04f3a72 /]# yum install -y nginx# 安装常用命令[root0b3db04f3a72 /]# yum install -y vim curl iproute net-tools# 清理yum缓存[root0b3db04f3a72 /]# rm -rf /var/cache/yum/*# 修改服务的配置信息关闭服务后台运行# 关闭nginx后台运行[root0b3db04f3a72 /]# vim /etc/nginx/nginx.confuser nginx;daemon off; # 关闭后台运行# 准备程序和数据# 自定义web界面[root0b3db04f3a72 /]# rm -rf /usr/share/nginx/html/index.html[root0b3db04f3a72 /]# echo Nginx Page in Docker /usr/share/nginx/html/index.html# 提交为镜像# docker commit命令在宿主机基于容器ID提交为镜像[rootcentos7 ~]# docker commit -a chensir -m nginx yum v1 -c EXPOSE 80 443 0b3db04f3a72 chensir/centos-nginx:1.16.1.v1sha256:3f649568eaca282c2ff0864d725bb0310862849e9393abfb14f49fa60d7071f7[rootcentos7 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEchensir/centos-nginx 1.16.1.v1 3f649568eaca 17 seconds ago 322MBcentos centos7.7.1908 08d05d1d5859 2 years ago 204MB# 从制作的镜像启动容器[rootcentos7 ~]# docker run -d -p 8080:80 --name my-centos-nginx chensir/centos-nginx:1.16.1.v1 /usr/sbin/nginxdf983ecee256956f34af0ca6089331bd9bd1863ad24d35defef05c86e6cab5f2[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdf983ecee256 chensir/centos-nginx:1.16.1.v1 /usr/sbin/nginx 5 seconds ago Up 5 seconds 443/tcp, 0.0.0.0:8080-80/tcp, :::8080-80/tcp my-centos-nginx# 访问测试镜像[rootcentos7 ~]# curl 127.0.0.1:8080Nginx Page in Docker利用DockerFile文件执行docker build自动构建镜像
Dockerfile使用详解
Dockerfile介绍
Dockerfile是一种被Docker程序解释执行的脚本由一条条的命令组成的没条命令对应Linux下面的一条命令Docker程序将这些DockerFile指令再翻译成真正的Linux命令其有自己的书写方式和支持的命令Docker程序读取DockerFile并根据指令生成Docker镜像相比手动制作的镜像方式DockerFile更能直观的展示镜像是怎么产生的有了DockerFile当后期有额外的需求时只要在之前的DockerFile添加或者修改响应的命令即可重新的Docker镜像避免了重复手动制作镜像的麻烦类似与shell脚本一样可以方便高效的制作镜像。 Docker守护程序Dockerfile逐一运行指令如有必要将每个指令的结果提交到新镜像然后最终输出新镜像的ID。Docker守护程序将自动清理之前发送的上下文 请注意每条指令都是独立运行的并会导致创建新镜像比如 RUN cd/tmp对下一条指令不会有任何影响。 Docker将尽可能用中间镜像层缓存以显著加速docker build命令的执行过程这由Using cache控制台输出中的消息提示
Dockerfile镜像制作和使用流程 Dockerfile文件的制作镜像的分层结构 # 按照业务类型或系统类型等方式划分创建目录环境方便后期镜像比较多的时候进行分类[rootcentos7 ~]# mkdir -p /data/dockerfile/{web/{nginx,apache,tomcat,jdk},system/{centos,ubuntu,alpine,debin}}[rootcentos7 ~]# tree /data/dockerfile//data/dockerfile/├── system│ ├── alpine│ ├── centos│ ├── debin│ └── ubuntu└── web├── apache├── jdk├── nginx└── tomcatDockerfile文件格式
Dockerfile 是一个有特定语法格式的文本文件 Dockerfile 官方说明https://docs.docker.com/engine/reference/builder/ 帮助man 5 dockerfile Dockerfile文件说明
每一行Dockerfile的指令开头指令不区分大小写但是惯例使用大写使用#开始作为注释每一行只支持一条指令没调指令可以携带多个参数指令按文件的顺序从上至下进行执行每个指令的执行会生成一个新的镜像层为了减少分层和镜像大小尽可能将多条指令合并成一条指令制作镜像一般可能需要反复多次每次执行Dockerfile都按顺序执行从头开始已经执行过的指令已经缓存不需要在执行如果后续有一行新的指令没执行过其往后的指令将会重新执行所以为加速镜像制作将最常变化的内容放下dockerfile的文件的后面
Dockerfile相关指令
ADDCOPYENVEXPOSEFROMLABELSTOPSIGNALUSERVOLUMEWORKDIRFROM指定基础镜像
定制镜像需要先有一个基础镜像在这个基础镜像上进行定制。 FROM 就是指定基础镜像此指令通常必须放在Dockerfile文件第一个非注释行。后续的指令都是运行于此基准镜像所提供的的运行环境 基础镜像可以是任何可用镜像文件默认情况下docker build会在docker主机上查找指定的镜像文件若不存在则会从docker hub registry上拉取所需的镜像文件。如果找不到指定的镜像文件docker build会返回一个错误信息 如何选择合适的镜像呢 对于不同的软件官方都提供了相关的docker镜像比如nginx、redis、mysql、httpd、tomcat等服务类的镜像也有操作系统类如centos、ubuntu、debian等。建议使用官方镜像比较安全。
FROM [--platformplatform] image [AS name]FROM [--platformplatform] image[:tag] [AS name]FROM [--platformplatform] image[digest] [AS name]# 说明--platform 指定镜像的平台比如linux/amd64,linux/arm64,or windows/amd64tag 和 digest是可选项如果不指定默认为latest说明关于scrach镜像
FROM scratch # 所有镜像的起源镜像相当于object类参考链接https://hub.docker.com/_/scratch?tabdescriptionhttps://docs.docker.com/develop/develop-images/baseimages/该镜像是一个空的镜像可以用于构建busybox等超小镜像可以说是真正的从零开始构建属于自己的镜像该镜像在构建基础镜像例如Debian和busybox或超最小镜像仅包含一个二进制文件及其所需内容例如hello-world的上下文中最有用。# 示例FROM ubuntuFROM ubuntu:bionicFROM debian:buster-slimLABEL指定镜像元数据
可以指定镜像元数据如镜像作者等
LABEL keyvalue keyvalue key:value...# 示例LABEL com.example.vendorACME IncorporatedLABEL com.example.label-with-valuefooLABEL version1.0LABEL descriptionThis text illustrates that label-values can span multiple lines一个镜像可以有多个label还可以写在一行中即多个标签写法可以减少镜像的大小
# 多标签写法LABEL multi.label1value1 multi.label2value2 othervalue3# 多行格式LABEL multi.label1value1 \multi.label2value2 \othervalue3docker inspect 命令可以查看LABEL
docker inspect centos:centos7.7.1908Labels: {org.label-schema.build-date: 20191024,org.label-schema.license: GPLv2,org.label-schema.name: CentOS Base Image,org.label-schema.schema-version: 1.0,org.label-schema.vendor: CentOS}RUN执行shell命令
RUN指令用来在构建镜像阶段需要执行FROM指定镜像所支持的shell命令。 通常各种基础镜像一般都支持丰富的shell命令 注意RUN可以写多个每一个RUN指令都会建立一个镜像层所以尽可能合并成一条指令比如将多个shell命令通过连接一起成为一条指令 每个RUN都是独立运行的和前一个RUN无关
# shell 格式相当于 /bin/sh -c 命令 此种形式支持环境变量RUN 命令# exec 格式此种形式不支持环境变量注意是双引号不能是单引号RUN [可执行文件,参数1,参数2]# exec格式可以指定其他shellRUN [/bin/bash,-c,echo hello chensir]说明
shell格式中command通常是一个shell命令且以 /bin/sh -c 来运行它这意味着此进程在容器中的PID不为1不能接受Unix信号因此当使用 docker stop container 命令停止容器时此进程接收不到SIGTERM信号exec格式中的参数是一个JSON格式的数组其中executable为要运行的命令后面paramN为传递给命令的选项或参数然而此种格式指定的命令不会以 /bin/sh -c 来发起因此常见的shell操作如变量替换以及通配符(?,*)替换将不会进行不过如果要运行的命令依赖于shell特性的话可以将其替代换为类似下面的格式。RUN [/bin/bash,-c,executable,laram1]# 示例RUN echo h1Hello,Docker/h1 /usr/share/nginx/html/index.htmlRUN [/bin/bash,-c,echo hello world]RUN yum install -y epel-release yum install -y nginx rm -rf /usr/share/nginx/html/* echo h1docker test nginx/h1 /usr/share/nginx/html/index.html# 示例多个前后RUN命令独立无关和shell命令不同# world.txt并不存放在app内RUN cd /appRUN echo hello world.txtENV设置环境变量
ENV可以定义环境变量和值会被后续指令ENVADDCOPYRUN等通过 K E Y 或 KEY或 KEY或{KEY}进行引用并在容器运行时保存
# 变量赋值格式1 此格式只能对一个key赋值key之后的所有内容均会被视作其value的组成部分ENV key value # 变量赋值格式2 此格式可以支持多个key赋值定义多个变量建议使用减少镜像层# 如果value中包含空格可以以反斜杠 \ 进行转义也可以通过对value加引号进行标识反斜杠也可用于读行ENV key1value1 key2value2 ... # 只使用一次变量RUN keyvalue command# 引用变量RUN $key# 变量支持高级赋值格式${key:-word}${key:word}如果运行容器是需要修改变量可以执行下面通过基于exec机制实现 注意下面方式只影响容器运行时环境而不影响构建镜像的过程即只能覆盖 docker run时的环境变量而不会影响docker build时的环境变量的值
docker run -e | --env keyvalue# 说明-e,--env list # Set environment variables--env-file filename # Read in a file of environment variables# 示例两种格式功能相同# 格式1ENV myNameJohn Doe myDogRex\ The\ Dog myCatfluffy# 格式2ENV myName John DoeENV myDog Rex The DogENV myCat fluffy[rootcentos7 ~]# cat DockerfileFROM busyboxLABEL maintainerchensir rootchensir.inkENV NAME zhao xing chenRUN touch $NAME.txt[rootcentos7 ~]# cat build.sh#!/bin/bashTAG$1docker build -t test:$TAG .[rootcentos7 ~]# ./build.sh v5.0COPY复制文本
复制本地宿主机的文件 到容器中
COPY [--chownuser:group] src... dest# 路径中有空白字符时建议使用此格式COPY [--chownuser:group] [src,...dest]说明
可以是多个可以使用通配符通配符规则满足Go的filepath.Match规则必须是build上下文中的路径Dockerfile 所在目录的相对路径不能是其父目录中的文件如果是目录则其内部文件或子目录会被递归复制但目录自身不会被复制如果指定了多个或在其中使用了通配符则必须是一个目录且必须是以 / 结尾可以是绝对路径或者是WORKDIR指定的相对路径使用COPY指令源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等如果事先不存在它会被自动创建这包括其父目录路径即递归创建目录
COPY hom* /mydir/COPY hom?.txt /mydir/ADD复制和解包文件
该命令可以认为是增强版的COPY不仅支持COPY还支持自动解包。可以将复制指定的文件到容器中
ADD [--chownuser:group] src...destADD [--chownuser:group] [src,...dest]说明
可以是Dockerfile所在目录的一个相对路径也可是一个URL还可以是一个tar文件自动解压可以是绝对路径或是WORKDIR指定的相对路径如果是目录只复目录中的内容而非目录本身如果是一个URL下载后的文件权限自动设置为600如果为URL且不以/结尾则指定的文件将被下载并直接被创建如果以/结尾则文件名URL指定的文件将被直接下载并保存为/如果是一个本地文件系统上的打包文件如gzbz2xz它将被解包其行为类似 “tar -x” 命令但是通过URL获取到的tar文件将不会自动展开如果有多个或间接或直接使用了通配符则必须是一个以/结尾的目录路径如果不以/结尾。则被视作一个普通文件
CMD容器启动命令
一个容器中需要持续运行的进程一般只有一个CMD用来指定启动程序时默认执行的一个命令且其运行结束后容器也会停止所以一般CMD指定的命令为持续运行且为前台命令
如果docker run没有指定任何的执行命令或者dockerfile里面也没有ENTRYPOINT那么开启容器时就会执行CMD指定的默认命令前面介绍过的RUN命令是在构建镜像执行的命令注意二者的不同之处每个Dockerfile只能有一条CMD命令。如指定了多条只有最后一条被执行如果用户启动容器时用docker run xxx指定运行的命令则会覆盖CMD指定的命令
# 使用exec执行推荐方式第一个参数必须是命令的全路径此种形式而不支持环境变量CMD [executable,param1,param2]# 在 /bin/sh 中执行提供给需要交互的应用池中形式支持环境变量CMD command param1 param2# 提供给ENTRYPOINT命令的默认参数CMD [param1,param2]# 示例CMD [nginx,-g,daemon off]ENTRYPOINT入口点
功能类似于CMD配置容器启动后执行的命令及参数
# 使用exec执行ENTRYPOINT [executable,param1,param2]# shell中执行ENTRYPOINT command param1 param2ENTRYPOINT不能被docker run提供的参数覆盖而是追加即如果docker run命令有参数那么参数全部都会作为ENTRYPOINT的参数如果docker run后面没有额外的参数但是Dockerfile中的CMD里有即上面的第三种用法即Dockerfile中即有CMD也有ENTRYPOINT那么CMD的全部内容会作为ENYRTPOINT的参数如果docker run后面有额外参数同时Dockerfile中既有CMD也有ENTRYPOINT那么docker run后面的参数覆盖掉CMD参数内容最终作为ENTRYPOINT的参数可以通过docker run - -entrypoint string参数在运行时替换注意string不要加空格使用CMD要在运行时重新写命令本身然后在后面才能追加运行参数ENTRYPOINT则可以运行时无需重写命令皆可以直接接收新参数每个Dockerfile中只能有一个ENTRYPOINT当指定多个时只有最后一个生效
ARG构建参数
ARG指令在build阶段指定变量和ENV不同的是容器运行时不会存在这些环境变量
ARG name[default value]如果和ENV同名ENV覆盖ARG变量 可以用 docekr build --build-arg 参数名值 来覆盖 说明ARG和FROM
# FROM指令支持由第一个FROM之前的任何ARG指令声明的变量# 示例ARG CODE_VERSIONlatestFROM base:${CODE_VERSION}CMD /code/run-appFROM extras:${CODE_VERSION}CMD /code/run-extras# 在FROM之前声明的ARG在构建阶段之外所以它不能在FROM之后的任何指令中使用。要使用在第一个FROM之前声明的ARG的默认值请在构建阶段内使用没有值的SRG指令# 示例ARG VERSIONlatestFROM busybox:$VERSIONARG VERSIONRUN echo $VERSION image_versionVOLUME匿名卷
在容器中创建一个可以从本地主机或其他容器挂载的挂载点一般用来存放数据库和需要保存的数据等一般会将宿主机上的目录挂载至VOLUME指令指定的容器目录。即使容器后期被删除次宿主机的目录仍会保留从而实现容器数据的持久保存 宿主机的目录为 /var/lib/docker/volumes/volume_id/_data
VOLUME 容器内路径VOLUME [容器内路径1,容器内路径2]注意
Dockerfile中的VOLUME实现的是匿名数据卷无法指定宿主机路径和容器目录的挂载关系通过docker rm -fv 容器ID 可以删除容器的同时删除VOLUME指定的卷
# 示例在容器创建两个 /data/ , /data2的挂载点VOLUME [/data1,/data2]EXPOSE暴露端口
指定服务端的容器需要对外暴露监听的端口号以实现容器与外部通信 EXPOSE仅仅是声明容器打算使用什么端口而已并不会真正暴露端口即不会自动在宿主机进行端口映射 因此在启动容器时需要通过-P或-pDocker主机才会真正分配一个端口转发到指定暴露的端口才可使用 注意即使Dockerfile没有EXPOSE端口指令也可以通过docker run -p临时暴露容器内程序真正监听的端口所以EXPOSE相当于指定默认的暴露端口可以通过docker run -P/-p 进行真正暴露
EXPOSE port[/ protocol] [port[/ protocol]...]# 说明protocol用于指定传输层协议可为tcp或udp二者之一默认为TCP协议# 示例EXPOSE 80 443EXPOSE 11211/udp 11211/tcpWORKDIR指定工作目录
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录当运行容器后进入容器内WORKDIR指定的默认目录 WORKDIR指定工作目录或称当前目录以后各层的当前目录就被改为指定的目录如该目录不存在WORKDIR会自行创建
WORKDIR /path/to/workdir# 示例# 两次 RUN 独立运行不在同一个目录RUN cd /appRUN echo hello world.txt# 如果想实现相同目录可以使用 WORKDIRWORKDIR /appRUN echo hello world.txt# 可以使用多个WORKDIR指令后续命令如果参数是相对路径则会基于之前命令指定的路径WORKDIR /aWORKDIR bWORKDIR cRUN pwd# 最终路径为 /a/b/cONBUILD子镜像引用父镜像的指令
可以用来配置当构建当前镜像的子镜像时会自动触发执行的命令但在当前镜像构建时并不会执行即延迟到子镜像构建时才执行
ONBUILD [INSTRUCTION]# Dockerfile使用如下的内容创建了镜像 image-AONBUILD ADD https://chensir.ink/pic/a.png /dataONBUILD RUN rm -rf /*ONBUILD RUN /usr/local/bin/python-build --dir /app/src...# 如果基于image-A创建新的镜像image-B时新的Dockerfile中使用FROM image-A指定基础竟像时会自动执行ONBUILD指令内容等价于在后面添加了两条指令。FROM image-A# Automatically run the followingADD https://chensir.ink/pic/a.png /dataRUN /usr/local/bin/python-build --dir /app/src...说明
尽管任何指令都可以注册成为触发器指令但ONBUILD不能自我使用且不会触发FROM和MAINTAINER指令使用ONBUILD指令的镜像推荐在标签中注明例如 ruby:1.9-onbuild
USER指定当前用户
指定运行容器时的用户名或UID后续的RUN也会使用指定用户 当服务不需要管理员权限时可以通过该命令指定运行用户 这个用户必须是事先建立好的否则无法切换 如果没有指定USER默认是root身份执行
USER user[:group]USER UID[:GID]# 示例RUN groupadd -r mysql useradd -r -g mysql mysqlUSER mysqlHEALTHCHECK监控检查
检查容器的健康性
# 设置检查容器健康状况的命令HEALTHCHECK [选项] CMD 命令# 如果基础镜像有健康检查指令使用这行可以屏蔽掉其健康检查指令HEALTHCHECK NONE# HEALTHCHECK 支持下列选项--interval间隔 # 两次健康检查的间隔默认30秒--timeout时长 # 健康检查命令运行超时时间如果超过这个时间本次健康检查就被视为失败默认30秒--retries次数 # 当连续失败指定次数后则将容器状态视为 unhealthy默认3次--start-periodFDURATION # default0s# 检查结果返回值0 # success1 # unhealth2 # reserved# 示例FROM nginxRUN apt-get update apt-get install -y curl rm -rf /var/lib/spt/lists/*HEALTHCHECK --interval5s --timeout3s \CMD curl -fs http://localhost/ || exit 1STOPSIGNAL退出容器信号
STOPSIGNAL指令设置将被发送到容器退出的系统调用信号。该信号可以是与内核syscall表中的位置匹配的有效无符号数字也可以是SIGNAME格式的信号名称如SIGKILL
STOPSIGNAL signalSHELL指定shell
SHELL指令允许覆盖用于命令的shell形式的默认SHLL必须在Dockerfile中以JSON形式编写SHELL指令。
SHELL [executable,parameters]在Linux上默认SHELL程序 [“/bin/sh”,“-c”]在Windows上默认SHELL程序为 [“cmd”,“/S”,“/C”]。 SHELL指令在Windows上特别有用在Windows上有两个常用且往前不同的本机SHELL:cmd和powershell以及包括sh在内的备用shell SHELL指令可以出现多次。每个SHELL指令将覆盖所有先前的SHELL指令并影响所有后续的指令
.dockerignore文件
与.gitignore文件类似生成构建上下文时Docker客户端应忽略的文件和文件夹指定模式 .dockerignore使用Go的文件路径规则filepath.Match 完整的语法
# # 以#开头的行为注释* # 匹配任何非分隔符字符序列? # 匹配任何单个非分隔符\\ # 表示 \** # 匹配任意数量的目录包括零例如 **/*.go 将排除在所有目录中以.go结尾的所有文件包括构建上下文的根! # 表示取反可用于排除例外情况# 示例# 排除 test 目录下的所有文件test/*# 排除 md 目录下的 xttblog.md 文件md/xttblog.md# 排除 xttblog 为前缀的文件和文件夹xttblog?# 排除所有目录下的 .sql文件夹**/*.sql# 除了README的md不排外排除所有md文件但不排除README-secret.md*.md!README*.mdREADME-secret.md# 除了所有README的md文件以外的md都排除*.mdREADME-sevret.md!README*.mddockerfile构建过程和指令总结
Dockerfile 构建过程
从基础镜像运行一个容器执行一条指令对容器做出修改执行类似docker commit的操作提交一个新的中间镜像层可以利用中间层镜像创建容器进项调试和排错再基于刚提交的镜像运行一个新容器执行Dockerfile中的下一条指令直至所有指令执行完毕
Dockerfile指令总结
BUILDRUNBOTHFROMCMDWORKDIRLABELVOLUMEUSERCOPYEXPOSEENVADDENTRYPOINTRUNONBUILD.dockerignore
构建镜像docker build命令
docker build [OPTION] PATH | URL |-说明PATH | URL | - # 可以是本地路径也可以是URL路径。如设置为 -则从标准输入获取Dockerfile的内容-f,--file string # Dockerfile文件名默认为PATH/Dockerfile--force-rm # 总是删除中间层容器创建镜像失败时删除临时容器--no-cache # 不使用之前构建中创建的缓存-q --quietfalse # 不显示Dockerfile的RUN运行的输出结果--rmtrue # 创建镜像成功时删除临时容器-t --tag list # 设置注册名称、镜像名称、标签。格式为 注册名称/镜像名称:标签(标签默认为latest)Docker数据管理
容器数据管理介绍
Docker镜像由多个只读层叠加而成启动容器时Docker会加载只读镜像层并在镜像栈顶部添加一个读写层 如果运行中的容器修改了现有的一个已经存在的文件那该文件将会从读写层下面的只读层复制到读写层该文件的只读版仍然存在只是已经被读写层中该文件的副本所隐藏即“写时复制COW copy on write机制” 如果将正在运行中的容器修改生成了新的数据那么新产生的数据将会被复制到读写层进行持久化保存这个读写层也就是容器的工作目录也为写时复制COW机制
Docker容器的分层
容器的数据分层目录
LowerDirimage镜像层即镜像本身只读UpperDir容器的上层可读写容器变化的数据存放在此处MergedDir容器的文件系统使用Union FS联合文件系统将lowerdir和upperdir合并完成后给容器使用最终呈现给用户的统一视图WorkDir容器在宿主机的工作目录挂载后内容会被清空且在使用过程中其内容用户不可见
每个镜像层目录中都包含了一个文件link文件内容则是当前层对应的短标识符镜像层的内容则存放在diff目录 删除容器后所有数据目录都随之而删除
哪些数据需要持久化
有状态的协议
有状态协议就是通信双方要记住双方并且共享一些信息。而无状态协议的通信每次都是独立的与上一次的通信没什么关系。 “状态”可以理解为“记忆”有状态对应有记忆无状态对应无记忆
左侧是无状态的http请求服务右侧为有状态下层为不需要存储的服务上层为需要存储的部分服务
容器数据持久保存方式
如果要将写入到容器的数据永久保存则需要建工人那个器中的数据保存到宿主机的指定目录 Docker的数据类型分为两种
数据卷Data Volume直接将宿主机目录挂载至容器的指定的目录推荐使用此种方式此方式较常用数据卷容器Data Volume Container间接使用宿主机空间数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器然后让其他容器通过数据卷容器读写宿主机的数据此方式不常用
数据卷data volume
数据卷的特点和使用
数据卷实际上就是宿主机上的目录或是文件可以被直接mount到容器当中使用 实际生产环境中需要针对不同类型的服务、不同类型的数据存储要求做相应的规划最终保证服务的可扩展性、稳定性以及数据的安全性
数据卷使用场景
数据库日志输出静态web页面应用配置文件多容器间目录或文件共享
数据卷的特点
数据卷是目录或者文件并且可以在多个容器之间共同使用实现容器之间共享和重用对数据卷更改数据在所有容器里面会立即更新数据卷的数据可以持久保存及时删除使用该容器卷的容器也不影响在容器里面的写入数据不会影响到镜像本身即容器卷的变化不会影响镜像的更新依赖于宿主机目录宿主机出问题上面容器会受影响当宿主机较多时不方便统一管理匿名和命名数据卷在容器启动时初始化如果容器使用的镜像在挂载点包含了数据会开呗到新的初始化的数据卷中
数据卷使用方法
启动容器时可以指定使用数据卷实现容器数据的持久化数据卷有三种
指定宿主机目录或文件指定宿主机的具体路径和容器路径的挂载关系匿名卷不指定数据名称只指定容器内目录路径充当挂载点docker自动指定宿主机的路径进行挂载命名卷指定数据卷的名称和容器路径的挂载关系
# docker run 命令的以下格式可以实现数据卷-v,--volume[host-src:]container-dest[:options]optionsro 从容器内对此数据卷是只读不写此项默认为可读可写 rw 从容器内对此数据卷可读可写此为默认值# 指定宿主机目录或文件格式# 将宿主机目录挂载容器目录两个目录都可自动创建-v 宿主机绝对路径的目录或文件:容器目录或文件[:ro]# 匿名卷只指定容器内路径没有指定宿主机路径信息宿主句自动生成/var/lib/docker/vlumes/卷ID/_data目录并挂在至容器指定路径-v 容器内路径# 示例docker run --name nginx -v /etc/nginx nginx# 命名卷将固定的存放在/var/lib/docker/volumes/卷名/_data-v 卷名:容器目录路径# 可以通过以下命令事先创建如没有事先创建卷名docker run时也会自动创建卷docker volume create 卷名# 示例docker run -d -p 80:80 --name nginx01 -v vol1:/usr/share/nginx/html nginx# docker rm的 -v 选项可以上处容器时同时删除相关联的匿名卷# 管理卷命令docker volume COMMANDCommands:createinspectlsprunerm# 查看数据卷的挂载关系docker inspect --format{{.Mounts}} 容器ID# 删除所有数据卷docker volume rm docker volume ls -q数据卷容器
数据卷容器介绍 在Dockerfile中创建的是匿名数据卷无法直接实现多个容器之间共享数据 数据卷容器最大的功能是可以让数据在多个docker容器之间共享 相当于先要创建一个后台运行的容器作为Server用于提供数据卷这个卷可以为其他容器提供数据存储服务其他使用此卷的容器作为client端但此方法不常使用 缺点依赖一个Server的容器所以此Server出了问题其他Client容器都会受影响
使用数据卷容器
启动容器时指定使用数据卷容器 docker run 命令的一下选项可以实现数据卷容器
--volume-from 数据卷容器数据卷容器总结
将提供的容器Server删除已经运行的容器Client依然可以使用挂载的卷因为容器是通过挂载访问数据的但是无法创建新的卷容器客户端但是再把卷容器Server创建后即可正常创建卷容器Client此方式可以用于线上共享数据目录等环境因为即使数据卷容器被删除了其他已经运行的容器依然可以挂载使用 由此可知数据卷容器的功能知识将数据挂载信息传递给了其他使用数据卷容器的容器而数据卷容器本身并不是提供数据存储功能 数据卷容器可以作为共享的方式为其他容器提供文件共享类似于NFS可以在生产中启动一个实例挂载本地的目录然后其他的容器分别挂载此容器的目录即可保证各容器之间的数据一致性 数据卷容器的Server和Client可以不使用同一个镜像生成
网络管理
Docker默认的网络通信
Docker安装后默认的网络设置
docker容器创建后必不可少的要和其他主机或容器进行网络通信 Docker服务安装完成之后默认在每个宿主机会生成一个名称为docker0的网卡其IP地址都是172.17.0.1/16
创建容器后的网络配置
每次新建容器后
宿主机多了一个虚拟网卡和容器的网卡组合成一个网卡比如137veth8ca6e42if136而在容器内的网卡名为136可以看出和宿主机的网卡之间的关联容器会自动获取一个172.17.0.0/16网段的随机地址默认从172.17.0.2开始第二次为172.17.0.3以此类推容器获取的地址并不固定每次容器重启可能会发生地址变化
容器间的通信
同一个宿主机的不同容器可相互通信
默认情况下
同一个宿主机的不同容器之间可以相互通信
dockerd --icc Enable inter-container communication default true--iccfalse # 此配置可以禁止同一个宿主机的容器之间通信不同宿主机之前的容器IP地址重复默认不能相互通信
禁止同一个宿主机的不同容器间通信
[rootcentos7 ~]# vim /usr/lib/systemd/system/docker.serviceExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --iccfalse[rootcentos7 ~]# systemctl daemon-reload[rootcentos7 ~]# systemctl restart docker修改默认的网络设置
新建容器默认使用docekr0的网络配置可以修改默认指向自定义的网桥网络
# 用自定义的网桥代替默认的docker0# 查看默认网络[rootcentos7 ~]# ip a1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 00:1c:42:2d:76:72 brd ff:ff:ff:ff:ff:ffinet 10.0.0.14/24 brd 10.0.0.255 scope global dynamic eth0valid_lft 1219sec preferred_lft 1219secinet6 fe80::b56f:3e7e:8cac:f26d/64 scope linkvalid_lft forever preferred_lft forever3: docker0: NO-CARRIER,BROADCAST,MULTICAST,UP mtu 1500 qdisc noqueue state DOWNlink/ether 02:42:c6:6c:af:1d brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:c6ff:fe6c:af1d/64 scope linkvalid_lft forever preferred_lft forever[rootcentos7 ~]# yum install -y bridge-utils[rootcentos7 ~]# brctl addbr br0[rootcentos7 ~]# ip a a 192.168.100.1/24 dev br0[rootcentos7 ~]# brctl showbridge name bridge id STP enabled interfacesbr0 8000.000000000000 nodocker0 8000.0242c66caf1d no[rootcentos7 ~]# ip a1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 00:1c:42:2d:76:72 brd ff:ff:ff:ff:ff:ffinet 10.0.0.14/24 brd 10.0.0.255 scope global dynamic eth0valid_lft 1100sec preferred_lft 1100secinet6 fe80::b56f:3e7e:8cac:f26d/64 scope linkvalid_lft forever preferred_lft forever3: docker0: NO-CARRIER,BROADCAST,MULTICAST,UP mtu 1500 qdisc noqueue state DOWNlink/ether 02:42:c6:6c:af:1d brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:c6ff:fe6c:af1d/64 scope linkvalid_lft forever preferred_lft forever22: br0: BROADCAST,MULTICAST mtu 1500 qdisc noop state DOWN qlen 1000link/ether 72:ed:44:ff:22:a5 brd ff:ff:ff:ff:ff:ffinet 192.168.100.1/24 scope global br0valid_lft forever preferred_lft forever[rootcentos7 ~]# vim /usr/lib/systemd/system/docker.serviceExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock -b br0[rootcentos7 ~]# systemctl daemon-reload[rootcentos7 ~]# systemctl restart docker[rootcentos7 ~]# ps -ef |grep dockerdroot 6763 1 1 11:36 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock -b br0root 6911 6651 0 11:36 pts/1 00:00:00 grep --colorauto dockerd[rootcentos7 ~]# docker run --rm alpine hostname -i192.168.100.2容器名称互联
新建容器时docker会自动分配容器名称容器ID和IP地址导致容器名称容器ID和IP都不固定那么如何区分不同的容器实现和确定目标容器的通信呢解决方案是给容器起个固定的名称容器之间通过固定名称实现确定目标的通信 有两种固定名称
容器名称容器名称的别名
通过容器名称互联
容器名称介绍
即在同一个宿主机上的容器之间可以通过自定义的容器名称相互访问比如一个业务前端静态页面是使用nginx动态页面使用的是Tomcat另外还需要负载均衡调度器如haproxy对请求调度至nginx和Tomcat的容器由于容器在启动的时候其内部IP地址是DHCP随机分配的而给容器起个固定的名称则是相对比较固定的因此比较适用于此场景 注意如果被引用的容器地址变化必须重启当前容器才能生效
容器名称实现
docker run创建容器可使用 --link选项实现容器名称的引用
--link list# 格式# 先创建指定名称的容器docker run --name 容器名称# 再创建容器时引用上面容器的名称docker run --link 目标通信的容器ID或容器名称通过自定义容器别名互联
容器别名介绍
自定义的容器名称可能后期会发生变化那么一旦名称发生变化容器内程序之间也必须要随之发生变化比如程序通过固定的容器名称进行服务调用但是容器名称发生变化之后再使用之前的名称肯定是无法成功调用每次都进行更改的话又比较麻烦因此可以使用自定义别名的方式解决即容器名称可以随意更改只要不更改别名即可
容器别名实现
docker run --name 容器名称docker run -d --name 容器名称 --link 目标容器名称:容器别名docker run -d --name 容器名称 --link 目标容器名称:容器别名 容器别名 容器别名 # 可以是多个别名Docker网络连接模式
Docker网络支持5种网络模式
nonebridgehostcontainernetwork-name
# 查看默认的网络模式[rootcentos7 ~]# docker network lsNETWORK ID NAME DRIVER SCOPEadaac389304f bridge bridge local5feb362eb28e host host local00f34cf82248 none null local网络模式指定
# 默认新建的容器使用Bridge模式创建容器时docker run 命令使用以下指定网络模式docker run --network modeldocker run --netmodemodel: # 可以是以下值nonebridgehostcontainer:容器名或容器ID自定义网络名称bridge网络模式
bridge网络模式架构 bridge模式是docker的默认模式即不指定任何模式就是bridge模式也是使用比较多的模式此模式创建的容器会为每一个容器分配自己的网络IP等信息并将容器连接到一个虚拟网桥与外界通信。可以和外部网络之间进行通信通过SNAT访问网络使用DNAT可以让容器被外部主机访问所以此模式也称为NAT模式 此模式宿主机需要启动ip_forward功能 bridge网络模式特点
网络资源隔离不同宿主机的容器无法直接通信各自使用独立网络无需手动配置容器默认自动获取172.17.0.0/16的IP地址此地址可以修改可访问外网利用宿主机的物理网卡SNAT连接外网外部主机无法直接访问容器可以通过配置DNAT接收外网的访问性能较低因为可通过NAT望路转换带来更多的损耗端口管理繁琐每个容器必须手动指定唯一的端口容器产生端口冲突
bridge模式的默认设置
# 查看bridge模式信息[rootcentos7 ~]# docker network inspect bridge[{Name: bridge,Id: adaac389304f7654edfab8612d6d82ec5b13b6e81331a296c98fa6c824eb79dd,Created: 2022-08-26T13:11:24.08809319808:00,Scope: local,Driver: bridge,EnableIPv6: false,IPAM: {Driver: default,Options: null,Config: [{Subnet: 192.168.100.0/24,Gateway: 192.168.100.1}]},Internal: false,Attachable: false,Ingress: false,ConfigFrom: {Network: },ConfigOnly: false,Containers: {},Options: {com.docker.network.bridge.default_bridge: true,com.docker.network.bridge.enable_icc: true,com.docker.network.bridge.enable_ip_masquerade: true,com.docker.network.bridge.host_binding_ipv4: 0.0.0.0,com.docker.network.bridge.name: br0,com.docker.network.driver.mtu: 1500},Labels: {}}]# 查看宿主机的网络状态# 安装docker后 默认启动ip_forward[rootcentos7 ~]# cat /proc/sys/net/ipv4/ip_forward1[rootcentos7 ~]# iptables -vnL -t natChain PREROUTING (policy ACCEPT 2 packets, 424 bytes)pkts bytes target prot opt in out source destination1 64 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCALChain INPUT (policy ACCEPT 1 packets, 64 bytes)pkts bytes target prot opt in out source destinationChain OUTPUT (policy ACCEPT 3 packets, 984 bytes)pkts bytes target prot opt in out source destination0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCALChain POSTROUTING (policy ACCEPT 3 packets, 984 bytes)pkts bytes target prot opt in out source destination0 0 MASQUERADE all -- * !br0 192.168.100.0/24 0.0.0.0/0Chain DOCKER (2 references)pkts bytes target prot opt in out source destination0 0 RETURN all -- br0 * 0.0.0.0/0 0.0.0.0/0修改默认的bridge模式网络配置
[rootcentos7 ~]# vim /lib/systemd/system/docker.serviceExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --bip10.100.0.1/24[rootcentos7 ~]# systemctl daemon-reload[rootcentos7 ~]# systemctl restart docker[rootcentos7 ~]# docker network inspect bridge[{Name: bridge,Id: d1f65af6a2d6d9f8e73cf830c47236f5df50c7d04690bde64f499a43c82328eb,Created: 2022-08-26T14:04:28.64935944308:00,Scope: local,Driver: bridge,EnableIPv6: false,IPAM: {Driver: default,Options: null,Config: [{Subnet: 10.100.0.0/24,Gateway: 10.100.0.1}]},Internal: false,Attachable: false,Ingress: false,ConfigFrom: {Network: },ConfigOnly: false,Containers: {},Options: {com.docker.network.bridge.default_bridge: true,com.docker.network.bridge.enable_icc: true,com.docker.network.bridge.enable_ip_masquerade: true,com.docker.network.bridge.host_binding_ipv4: 0.0.0.0,com.docker.network.bridge.name: docker0,com.docker.network.driver.mtu: 1500},Labels: {}}]Host模式
如果指定host模式启动的容器那么新创建的容器不会创建自己的虚拟网卡而是直接使用宿主的网卡和IP地址因此在容器里面查看到的IP信息就是宿主机的信息访问容器的时候直接使用宿主机IP容器端口即可不过容器内除网络以外的其他资源如文件系统、系统进程等仍然和宿主机保持隔离 此模式由于直接使用宿主机的网络无需转换网络性能最高但是个容器使用的端口不能相同适用于运行容器端口比较固定的业务 Host网络模式特点
使用参数 - -network host 指定共享宿主机网络网络性能无损耗网络故障排除相对简单各容器网络无隔离网络资源无法分别统计端口管理困难容易产生端口冲突不支持端口映射
none模式
在使用none模式后Docker容器不会进行任何网洛洛配置没有网卡没有IP 也没有路由因此默认无法与外界通信需要手动添加网卡配置IP等所以极少使用 none模式特点
使用参数 - -network none 指定默认无网络功能无法和外部通信
Container模式
使用此模式创建的容器需指定和一个已经存在的容器共享一个网络而不是和宿主机共享网络新创建的容器不会创建自己的网卡也不会配置自己的IP而是和一个被指定的已经存在的容器共享IP和端口范围因此这个容器的端口不能被指定容器的端口冲突除了网络之外的文件系统、进程信息等仍然保持相互隔离两个容器的进程可以通过lo网卡进行通信 Container模式特点
使用参数 - -network container:名称或ID 指定与宿主机网络隔离容器间共享网络空间适合频繁的容器间的网络通信直接使用对方的网络较少使用
自定义网络模式
除了以上的网络模式也可以自定义网络使用自定义的网段地址网关等信息 注意自定义网络内的容器可以直接通过容器名进行相互的访问而无需使用 - -link 可以使用自定义网络模式实现不同集群应用的独立网络管理而互不影响而且在一个网络内可以直接利用容器名相互访问非常便利
自定义网实现
[rootcentos7 ~]# docker network --helpUsage: docker network COMMANDManage networksCommands:connect Connect a container to a networkcreate Create a networkdisconnect Disconnect a container from a networkinspect Display detailed information on one or more networksls List networksprune Remove all unused networksrm Remove one or more networksRun docker network COMMAND --help for more information on a command.# 创建自定义网络 注意mode不支持host和none
docker network create -d mode --subnet CIDR --gateway 网关 自定义网络名称# 查看自定义网络
docker network inspect 自定义网络名称或网络ID# 引用自定义网络
docker run --network 自定义网络名称 镜像名称# 删除自定义网络
docker network rm 自定义网络名称或网络IDDocker仓库管理
Docker仓库类似于yum仓库是用来保存镜像的仓库。为了方便的管理和使用docker镜像可以将镜像集中保存至Docker仓库中将制作好的镜像push到仓库集中保存在需要镜像时从仓库中pull镜像即可。 Docker仓库分为公有云仓库和私有云仓库 公有云仓库由互联网公司对外公开的仓库
官方阿里云等第三方仓库
私有云仓库组织内部搭建的仓库一般只为组织内部使用常使用下面软件搭建仓库
docekr registorydocker harbor
官方Docker仓库
https://hub.docker.com
# 用户登录 输入账号密码即可
docker login# 上传本地镜像前必须先给上传的镜像用docker tag命令打标签
# 标签格式 docker.io/用户账号/镜像名:TAG
docker tag alpine:3.11 docker.io/xchensir/alpine:3.11-v1# 上传本地镜像至官网
docker push docker.io/xchensir/alpine:3.11-v1私有云单机仓库Docker Registry
Docker Registry作为Docker的核心组件之一负责单主机的镜像内容的存储与分发客户端的docker pull以及push命令都将直接与registry进行交互最初版本的registry由python实现由于设计初期在安全性性能以及API的设计上有着诸多缺陷该版本在0.9之后停止开发由新项目distribution新的docker register被称为Distribution来重新设计并开发下一代registry新的项目由go语言开发所有的API底层存储方式系统架构都进行了全面的重新设计已解决上一代registry中存在的问题2016年4月registry2.0正式发布docker1.6版本开始支持registry2.0而八月份随着docker1.8发布docker hub正式启用2.1版本registry全面替代之前版本registry新版registry对镜像存储格式进行了重新设计和旧版不兼容docker1.5和之前的版本无法读取2.0的镜像另外Registry2.4版本之后支持了回收站机制也就是可以删除镜像在2.4版本之前是不支持删除镜像的所以最好使用大于Registry2.4版本 官方文档地址 https://docs.docker.com/registry/ 官方部署文档 https://github.com/docker/docker.github.io/blob/master/registry/deploying.md
搭建单机仓库
# 下载 docker registry 镜像
[rootcentos7 ~]# docker pull registry:2.7.1# 创建授权用户密码使用目录
[rootcentos7 ~]# mkdir -p /etc/docker/auth# 创建授权的registry用户和密码
# 创建registry用户 用于上传和下载镜像
[rootcentos7 ~]# yum install -y httpd
[rootcentos7 ~]# htpasswd -Bbn chensir 123456 /etc/docker/auth/registry
[rootcentos7 ~]# cat /etc/docker/auth/registry
chensir:$2y$05$KP9hiJW3W5ZvwfTeWUctEuak6vHxsHOdJpMRoHRfYQnIXfmEsceOS[rootcentos7 ~]# docker run -d -p 5000:5000 --restartalways --name registry -v /etc/docker/auth/:/auth -e REGISTRY_AUTHhtpasswd -e REGISTRY_AUTH_HTPASSWD_REALMRegistry Realm -e REGISTRY_AUTH_HTPASSWD_PATH/auth/registry registry:2.7.1
f2373f9e7c67bf628feb6222ff716cab115d63ffce9791179ef4797a00338145[rootcentos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2373f9e7c67 registry:2.7.1 /entrypoint.sh /etc… 47 seconds ago Up 46 seconds 0.0.0.0:5000-5000/tcp, :::5000-5000/tcp registry
[rootcentos7 ~]# docker port f23
5000/tcp - 0.0.0.0:5000
5000/tcp - :::5000# 登陆仓库
# docker login 默认使用https登录而docker registry为http所以默认登录失败
[rootcentos7 ~]# docker login 10.0.0.14:5000
Username: chensir
Password:
Error response from daemon: Get https://10.0.0.14:5000/v2/: http: server gave HTTP response to HTTPS client# 修改配置使docker login支持HTTP协议
[rootcentos7 ~]# vim /lib/systemd/system/docker.service
ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --insecure-registry 10.0.0.14:5000
[rootcentos7 ~]# systemctl daemon-reload
[rootcentos7 ~]# systemctl restart docker# 再次登录 验证成功
[rootcentos7 ~]# docker login 10.0.0.14:5000
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded# 打包并上传镜像
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v1 401a15cbac90 8 days ago 1.24MB
[rootcentos7 ~]# docker tag test:v1 10.0.0.14:5000/test:v1
[rootcentos7 ~]# docker push 10.0.0.14:5000/test:v1
The push refers to repository [10.0.0.14:5000/test]
084326605ab6: Pushed
v1: digest: sha256:c04ecf7d8a544273ae7b7d1cda2f6c123a9690fc56c705dd5e16a20c65bba555 size: 527# 下载镜像
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.7.1 b8604a3fe854 9 months ago 26.2MB
[rootcentos7 ~]# docker pull 10.0.0.14:5000/test:v1
v1: Pulling from test
50783e0dfb64: Pull complete
Digest: sha256:c04ecf7d8a544273ae7b7d1cda2f6c123a9690fc56c705dd5e16a20c65bba555
Status: Downloaded newer image for 10.0.0.14:5000/test:v1
10.0.0.14:5000/test:v1
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
10.0.0.14:5000/test v1 401a15cbac90 8 days ago 1.24MB
registry 2.7.1 b8604a3fe854 9 months ago 26.2MBDocker之分布式仓库Harbor
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器由VMware开源其通过添加一些企业必须的功能特性例如安全、标识和管理等扩展了开源Docker Distribution。作为一个企业级私有Registry服务器Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制镜像全部保存在私有Registry中确保数据和知识产权在公司内部网络中管控另外Harbor也提供了高级的安全特性诸如用户管理访问控制和活动审计等 vmware官方开源服务 https://vmware.github.io harbor官方github地址 https://github.com/goharbor/harbor harbor官方网址 https://goharbor.io harbor官方文档 https://goharbor.io/docs/
Harbor功能
基于角色的访问控制用户与Docker镜像仓库通过“项目”进行组织管理一个用户可以对多个镜像仓库在同一命名空间project里有不同的权限镜像复制镜像可在多个Registry实例中复制同步。尤其适合负载均衡高可用混合云和多云场景图形化用户界面用户可以通过浏览器来浏览检索当前Docker镜像仓库管理项目和命名空间AD/LDAP支Harbor可以集成企业内部已有的AD/LDAP用于鉴权认证管理国际化已拥有英文、中文、德文、日文和俄文的本地化版本RESTful API提供给管理员对于Harbor更多的操控使得其它管理软件集成变得更容易部署简单提供在线和离线两种安装工具也可以安装到vSphere平台OVA方式虚拟设备
Harbor组成 proxy对应启动组件Nginx。它是一个nginx反向代理代理Notary client镜像认证、Docker client镜像上传下载等和浏览器的访问请求Core Service给后端的各服务UICore Service对应启动组件harbor-ui。底层数据存储使用mysql数据库主要提供了四个子功能 UI一个Web管理页面APIHarbor暴露的API服务Auth用户认证服务decode后的token中的用户信息在这里进行认证auth后端可以接db、ldap、uaa三种认证实现Token服务负责根据用户在每个project中的role来为每一个docker push/pull命令发布一个token如果从docker client发送给registry的请求没带tokenregistry会重定向请求到token服务创建token Registry对应启动组件registry。负责存储镜像文件和处理镜像的pull/push命令。Harbor对镜像进行强制的访问控制Registry会将客户端的每个pull、push请求转发到token服务来获取有效的tokenAdmin Service对应启动组件harbor-adminserver。是系统的配置管理中心附带检查存储用量ui和job server启动时需要加载adminserver配置Job Service对应启动组件harbor-jobservice。负责镜像复制的工作他和registry通信从一个registry pull镜像然后push到另一个registry并记录job_logLog Collector对应启动组件harbor-log。日志汇总组件通过docker的log-drive把日志汇总到一起DB对应启动组件harbor-db负责存储project、user、role、replication、image_scan、access等的metadata数据
安装Harbor
下载地址https://github.com/vmware/harbor/releases 环境准备四台机器 两台harbor服务器两台harbor客户端上传和下载镜像
安装docker
rm -rf /etc/yum.repos.d/*# centos 7 安装docker依赖三个yum源BaseExtrasdocker-ce
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum clean all
yum install docker-ce -y
systemctl enable --now docker安装docker-compose
[rootcentos7 ~]# wget -O /usr/local/bin/docker-compose https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-linux-x86_64[rootcentos7 ~]# chmod x /usr/local/bin/docker-compose[rootcentos7 ~]# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose[rootcentos7 ~]# docker-compose --version下载Harbor安装包并解压缩安装启动
# 推荐下载离线完整版安装包[rootcentos7 ~]# wget https://github.com/goharbor/harbor/releases/download/v2.6.0/harbor-offline-installer-v2.6.0.tgz[rootcentos7 ~]# mkdir /apps[rootcentos7 ~]# tar xvf harbor-offline-installer-v2.6.0.tgz -C /apps/[rootcentos7 ~]# cp /apps/harbor/harbor.yml.tmpl /apps/harbor/harbor.yml[rootcentos7 ~]# vim /apps/harbor/harbor.ymlhostname: 10.0.0.16 # 修改此行指向当前主机IPharbor_admin_password: 123456 # 修改此行指定harbor登录用户admin的密码默认用户/密码 admin/Harbor12345# 安装docker 先安装python[rootcentos7 ~]# /apps/harbor/install.sh# 安装后会自动开启很多先关容器[rootcentos7 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES5a84db870a20 goharbor/nginx-photon:v2.6.0 nginx -g daemon of… 4 minutes ago Up 4 minutes (healthy) 0.0.0.0:80-8080/tcp, :::80-8080/tcp nginxc8ab9fcba25b goharbor/harbor-jobservice:v2.6.0 /harbor/entrypoint.… 4 minutes ago Up 4 minutes (healthy) harbor-jobservice7bb48de3447b goharbor/harbor-core:v2.6.0 /harbor/entrypoint.… 4 minutes ago Up 4 minutes (healthy) harbor-cored680480c0ef3 goharbor/redis-photon:v2.6.0 redis-server /etc/r… 4 minutes ago Up 4 minutes (healthy) redis09bbe5448ad2 goharbor/harbor-registryctl:v2.6.0 /home/harbor/start.… 4 minutes ago Up 4 minutes (healthy) registryctl88f5bcdd4c4b goharbor/harbor-portal:v2.6.0 nginx -g daemon of… 4 minutes ago Up 4 minutes (healthy) harbor-portal4e8d142ecb96 goharbor/registry-photon:v2.6.0 /home/harbor/entryp… 4 minutes ago Up 4 minutes (healthy) registry645b169ac0cf goharbor/harbor-db:v2.6.0 /docker-entrypoint.… 4 minutes ago Up 4 minutes (healthy) harbor-db7c9e23d67190 goharbor/harbor-log:v2.6.0 /bin/sh -c /usr/loc… 4 minutes ago Up 4 minutes (healthy) 127.0.0.1:1514-10514/tcp harbor-log# 实现开机自动启动harbor# 方式1通过service文件实现[rootcentos7 ~]# vim /lib/systemd/system/harbor.service[Unit]DescriptionHarborAfterdocker.service systemd-networked.service systemd-resolved.serviceRequiresdocker.serviceDocumentationhttp://github.com/vmware/harbor[Service]TypesimpleRestarton-failureRestartSec5ExecStart/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml upExecStop/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml down[Install]WantedBymulti-user.target# 方式2通过rc.local实现[rootcentos7 harbor]# cat /etc/rc.local#!/bin/bashcd /apps/harbor/usr/bin/docker-compose up[rootcentos7 harbor]# chmod x /etc/rc.local# 至此安装完毕 用浏览器访问 http://10.0.0.16# 用户名admin 密码前面harbor.yml指定的密码命令行登录harbor
[rootcentos7 ~]# vim /lib/systemd/system/docker.service
ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --insecure-registry 10.0.0.16 --insecure-registry 10.0.0.17
[rootcentos7 ~]# systemctl daemon-reload
[rootcentos7 ~]# systemctl restart docker
[rootcentos7 harbor]# docker login 10.0.0.16
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded# 查看进程是否添加上面的设置
[rootcentos7 ~]# ps aux |grep dockerd
root 7875 0.5 4.1 1777524 78544 ? Ssl 10:07 0:00 /usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --insecure-registry 10.0.0.16 --insecure-registry 10.0.0.17
root 9420 0.0 0.0 112680 984 pts/1 S 10:09 0:00 grep --colorauto dockerd本地镜像打标签上传至harbor
# 修改images的名称不修改成指定格式无法将镜像上传到harbor仓库
# 格式为 项目名需要登录Harbor管理页面去新建 如果不事先建立项目上传镜像失败
Harbor主机IP/项目名/image名字:版本# 例如
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox-chensir v1.0 71a52e0618a5 3 seconds ago 1.24MB
[rootcentos7 ~]# docker login 10.0.0.16
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
[rootcentos7 ~]# docker tag busybox-chensir:v1.0 10.0.0.16/chensir/busybox-chensir:v1.0
[rootcentos7 ~]# docker push 10.0.0.16/chensir/busybox-chensir:v1.0
The push refers to repository [10.0.0.16/chensir/busybox-chensir]
c1cf1676e7d0: Pushed
v1.0: digest: sha256:c501ccda169599fb77102ad0c2e2568336eaccf9ad83c94aec0d6f28fb55c0a0 size: 527下载harbor镜像
在10.0.0.15的centos7主机上无需登录即可下载镜像 注下载前需修改docker的service文件加入harbor服务器的地址才可以下载
[rootcentos7 ~]# docker pull 10.0.0.16/chensir/busybox-chensir:v1.0
Error response from daemon: Get https://10.0.0.16/v2/: dial tcp 10.0.0.16:443: connect: connection refused
[rootcentos7 ~]# vim /lib/systemd/system/docker.service
[rootcentos7 ~]# systemctl daemon-reload
[rootcentos7 ~]# systemctl restart docker
[rootcentos7 ~]# docker pull 10.0.0.16/chensir/busybox-chensir:v1.0
v1.0: Pulling from chensir/busybox-chensir
2c39bef88607: Pull complete
Digest: sha256:c501ccda169599fb77102ad0c2e2568336eaccf9ad83c94aec0d6f28fb55c0a0
Status: Downloaded newer image for 10.0.0.16/chensir/busybox-chensir:v1.0
10.0.0.16/chensir/busybox-chensir:v1.0
[rootcentos7 ~]# vim /lib/systemd/system/docker.service
[rootcentos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
10.0.0.16/chensir/busybox-chensir v1.0 71a52e0618a5 2 hours ago 1.24MB修改harbor配置
# 后期修改harbor配置比如修改IP地址等可执行以下步骤生效
# 方法1
[rootcentos7 ~]# cd /apps/harbor/
# 停止harbor相关容器
[rootcentos7 harbor]# docker-compose stop
# 修改配置
[rootcentos7 harbor]# vim harbor.yml
# 更新配置
[rootcentos7 harbor]# /apps/harbor/prepare
# 启动harbor
[rootcentos7 harbor]# docker-compose start# 方法2
[rootcentos7 harbor]# /apps/harbor/install.sh实现harbor高可用
Harbor支持基于策略的Docker镜像复制功能这类似于MySQL的主从同步其可以实现不同的数据中心不同的运行环境之间同步镜像并提供友好的管理界面大大简化了实际运维中的镜像管理工作已经有很多互联网公司使用harbor搭建内网docker仓库的案例并且还有实现了双向复制功能 多个harbor需要登录管理页面新建相同的项目然后在系统管理仓库管理新建目标系统管理复制管理新建规则 互相之前配置
Harbor安全配置https
harbor默认使用http为了安全可以使用https
# 生成私钥和证书[rootcentos7 ~]#[rootcentos7 ~]# touch /root/.rnd[rootcentos7 ~]# mkdir /apps/harbor/certs[rootcentos7 ~]# cd /apps/harbor/certs/# 生成CA证书[rootcentos7 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -subj /CNca.chensir.ink -days 365 -out ca.crtGenerating a 4096 bit RSA private key..................................................................................writing new private key to ca.key-----# 生成harbor主机的证书申请[rootcentos7 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -subj /CNca.chensir.ink -keyout harbor.chensir.ink.key -out harbor.chensir.ink.csrGenerating a 4096 bit RSA private key.............................................................................................................................................................................................................................................................................................................................................writing new private key to harbor.chensir.ink.key-----# 给harbor主机颁发证书[rootcentos7 certs]# openssl x509 -req -in harbor.chensir.ink.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out harbor.chensir.ink.crtSignature oksubject/CNca.chensir.inkGetting CA Private Key[rootcentos7 certs]# tree /apps/harbor/certs//apps/harbor/certs/├── ca.crt├── ca.key├── ca.srl├── harbor.chensir.ink.crt├── harbor.chensir.ink.csr└── harbor.chensir.ink.key0 directories, 6 files# 修改配置文件[rootcentos7 certs]# vim /apps/harbor/harbor.yml# https related confighttps:# https port for harbor, default is 443port: 443# The path of cert and key files for nginxcertificate: /apps/harbor/certs/harbor.chensir.ink.crtprivate_key: /apps/harbor/certs/harbor.chensir.ink.key# 更新配置[rootcentos7 harbor]# /apps/harbor/prepare# 启动harbor[rootcentos7 harbor]# docker-compose start在客户端下载CA的证书
# 直接登录和上传下载镜像会报错[rootcentos7 ~]# vim /etc/hosts10.0.0.16 harbor.chensir.ink[rootcentos7 ~]# docker login harbor.chensir.inkUsername: adminPassword:Error response from daemon: Get https://harbor.chensir.ink/v2/: x509: certificate has expired or is not yet valid: current time 2022-09-08T13:41:2808:00 is before 2022-09-08T06:20:55Z# 在客户端下载CA证书[rootcentos7 ~]# mkdir -pv /etc/docker/certs.d/harbor.chensir.org/[rootcentos7 ~]# scp -r harbor.chensir.ink:/apps/harbor/certs/ca.crt /etc/docker/certs.d/harbor.chensir.org/[rootcentos7 ~]# tree /etc/docker/certs.d//etc/docker/certs.d/└── harbor.chensir.org└── ca.crt1 directory, 1 file单机编排 Docker Compose
当在宿主机启动较多容器的时候如果都是手动操作会觉得比较麻烦而且容易出错此时推荐使用docker单机编排工具docker-compose docker-compose是docker容器的一种单机编排服务docker-compose是一个管理多个容器的工具比如可以解决容器之间的依赖关系就像启动一个nginx前端的时候会调用后端额Tomcat那就得先启动Tomcat但是启动Tomcat容器还需要依赖数据库那就还得启动数据库docker-compose可以用来解决这样的嵌套依赖关系并且可以替代docker命令对容器进行创建、启动和停止等手工的操作 因此如果说docker命令就像linux的命令docker-compose就像shell脚本可以自动的执行容器批量操作从而实现自动化的容器管理或者说docker命令相当于Ansible命令那么docker compose文件就相当于ansible-playbook的yaml文件 docker-compose 项目是Docker官方开源项目负责实现对Docker容器集群的快速编排docker-compose将所管理的容器分为三层分别是工程project服务service以及容器Container
命令格式
[rootcentos7 certs]# docker-compose --help
Usage: docker compose [OPTIONS] COMMAND# 选项说明
-f # 指定compose模板文件默认为docker-compose.yml
-p # 指定项目名称默认将使用当前所在目录名称作为项目名
--verbose # 显示更多输出信息
--log-level LEVEL # 定义日志级别 DEBUGINFOWARNINGERRORCRITICAL
--no-ansi # 不显示ANSI 控制字符
-v # 显示版本# 以下命令选项需要造docker-compose.yml 文件所在目录里执行
build # 构建镜像
bundle # 从当前docker compose 文件生成一个以当前目录为名称的json格式的Docker Bundle备份文件
config -q # 查看当前配置没有错误不输出任何信息
create # 创建服务较少使用
down # 停止和删除所有容器、网络、镜像和卷
events # 从容器接收实时事件可以指定json日志格式较少使用
exec # 进入指定容器进行操作
help # 显示帮助信息
images # 显示镜像信息较少使用
kill # 强制终止运行中的容器
logs # 查看容器的日志
pause # 暂停服务
port # 查看端口
ps # 列出容器较少使用
pull # 重新拉去镜像镜像发生变化后需要重新拉去镜像较少使用
push # 上传镜像
restart # 重启服务较少使用
rm # 删除已经停止的服务
run # 一次性运行容器
scale # 设置指定服务运行的容器个数
start # 启动服务较少使用
stop # 停止服务较少使用
top # 显示容器运行状态
unpause # 取消暂定
up # 床架并启动容器较少使用docker-compose文件格式
https://docs.docker.com/compose/compose-file/ docker-compose文件是一个yaml格式的文件所以注意行首的缩进很严格 默认docker-compose命令会调用当前目录下的docker-compose.yml文件因此一般执行docker-compose命令先进入docker-compose.yml文件所在目录
docker-compose启动单各容器
注意使用docker-compose之前先安装docker
创建docker-compose文件
docker-compose文件可以在任意目录没创建文件名为docker-compose.yml配置文件要注意前后的缩进
[rootcentos7 ~]# docker-compose --version
Docker Compose version v2.10.2
[rootcentos7 ~]# mkdir /data/docker-compose
[rootcentos7 ~]# cd /data/docker-compose/
[rootcentos7 docker-compose]# vim docker-compose.yml
services:service-nginx-web:image: nginxcontainer_name: nginx-webexpose:- 80- 443ports:- 80:80- 443:443
# 查看配置和检查格式
[rootcentos7 docker-compose]# docker-compose config
[rootcentos7 docker-compose]# docker-compose config -q启动/停止/删除/容器
注意必须要在docker-compose文件所在的目录执行
# 前台启动
[rootcentos7 docker-compose]# docker-compose up
# 后台启动
[rootcentos7 docker-compose]# docker-compose up -d
# 停止容器
[rootcentos7 docker-compose]# docker-compose stop
# 启动容器
[rootcentos7 docker-compose]# docker-compose start
# 重新启动
[rootcentos7 docker-compose]# docker-compose restart
# 只删除停止的容器
[rootcentos7 docker-compose]# docker-compose rm
# 停止并删除容器及镜像
[rootcentos7 docker-compose]# docker-compose down指定同时启动容器的数量
[rootcentos7 docker-compose]# vim docker-compose.yml
services:service-nginx-web:image: nginx
# container_name: nginx-web 同时启动多个同一镜像的容器不要指定容器名称否则会冲突expose:- 80- 443
# ports: 同时启动多个同一镜像不要指定端口号否则会冲突
# - 80:80
# - 443:443
[rootcentos7 docker-compose]# docker-compose up -d --scale service-nginx-web5docker-compose启动多个容器
# 编辑docker-compose文件并使用数据卷
# 注意同一个文件数据卷的优先级比镜像内的文件优先级高
[rootcentos7 docker-compose]# vim docker-compose.yml
services:service-nginx-web:image: nginxcontainer_name: nginx-webvolumes:- /data/nginx:/apps/nginx/html # 指定数据卷将宿主机/data/nginx挂载到容器/apps/nginx/htmlexpose:- 80- 443ports:- 80:80- 443:443service-tomcat-app1:image: tomcatexpose:- 8080ports:- 8081:8080
# 在宿主机准备nginx测试页面文件
[rootcentos7 docker-compose]# mkdir /data/nginx
[rootcentos7 docker-compose]# echo Docker compose test page /data/nginx/index.html
[rootcentos7 docker-compose]# docker-compose up -dDocker的资源限制
https://docs.docker.com/config/containers/resource_constraints/ 默认情况下容器没有资源的使用限制可以使用主机内核调度程序允许的尽可能多的资源 Docker提供了控制容器使用资源的方法可以限制容器使用多少内存或CPU等在docker run命令的运行时配置标志实现资源限制功能。 其中许多功能都要求宿主机的内核支持要检查是否支持这些功能可以使用docker info命令如果内核中的某项特性可能会在输出结尾处看到警告可参考 https://docs.docker.com/engine/install/linux-postinstall/#your-kernel-does-not-support-cgroup-swap-limit-capabilities 消除警告
OOMOut of Memory Exception
对于Linux主机如果没有足够的内存来执行其他重要的系统任务将会抛出OOM随后系统会开始杀死进程已释放内存凡是运行在宿主机的进程都有可能被kill包括Dockerd和其他的应用程序如果重要的系统进程被kill会导致和该进程相关的服务全部宕机。通常越消耗内存比较大的应用越容易被kill比如MySQL数据库java程序等 产生OOM异常时Dockerd尝试通过调整Docker守护程序上的OOM优先级来减轻这些风险以便它系统上的其他进程更不可能被杀死但是容器的OOM优先级未调整这使得单个容器被杀死的可能性比Docker守护程序或其他系统进程被杀死的可能性更大不推荐通过守护程序或容器上手动设置 oom-score-adj为极端负数或通过在容器上设置 oom-kill-disable来绕过这些安全措施 oom优先级机制 linux会为每个进程算一个分数最终将分数最高的kill
/proc/PID/oom_score_adj# 范围为 -1000 到 1000值越高越容易被宿主机kill掉如果将该值设置为-1000则进程永远不会被宿主机 kernel kill/proc/PID/oom_adj# 范围为 -17 到 15 取值越高越容易被干掉如果是 -17 则表示不能被 kill 该设置的存在是为了和旧版的linux内核兼容/proc/PID/oom_score# 这个值是系统综合进程的内存消耗量、CPU、时间utime 、存活时间uptime - start time和oom_adj计算出的进程得分消耗内存越多得分越高容易被宿主机 kernel强制杀死查看oom相关值
# docker服务进程的oom默认值[rootcentos7 docker-compose]# cat /proc/pidof dockerd/oom_adj-8[rootcentos7 docker-compose]# cat /proc/pidof dockerd/oom_score0[rootcentos7 docker-compose]# cat /proc/pidof dockerd/oom_score_adj-500容器的内存限制
Docker可以强制执行硬性内存限制即只允许容器使用给定的内存大小 Docker也可以执行非硬性内存限制即容器可以使用尽可能多的内存除非内核检测到主机上的内存不够用了
内存相关选项
https://docs.docker.com/config/containers/resource_constraints/ 以下设置大部分的选取正整数跟着一个后缀 b,k,m,g 表示字节千字节兆字节或千兆字节
选项描述-m容器可以使用的最大物理内存硬限制此选项最小允许值为 4m4MB常用–memory-swap允许此容器交换到磁盘的内存量必须先用 -m 对内存限制才可以使用详细说明如下–memory-swappiness设置容器使用交换分区的倾向性值越高表示越倾向于使用swap分区范围0-1000为能不用就不用100为能用就用–memory-reservation允许指定小于 –memory 的软限制当docker检测到主机上的争用或内存不足时会激活该限制如果使 –memory-reservation则必须将其设置为低于 –memory才能使其优先生效。因为它是软限制所以不能保证容器不超过限制–kernel-memory容器可以使用的最大内核内存量最小为4m由于内核内存与用户空间内存隔离因此无法与用户空间内存直接交换因此内核内存不足的容器可能会阻塞宿主机资源这会对主机和其他容器或者其他服务进程产生影响因此不建议设置内核内存大小–oom-kill-disable默认情况下如果发生内存不足OOM错误则内核将终止容器中的进程。要更改此行为请使用该 –oom-kill-disable选项。仅在设置了 -m选项的容器上禁用OOM。如果-m未设置该标志则主机可能会用完内存内核可能需要终止系统的进程以释放内存
# 示例
[rootcentos7 ~]# docker run -e MYSQL_ROOT_PASSWORD123456 -it --rm -m 1g --oom-kill-disable mysql:5.7.29
[rootcentos7 docker-compose]# sysctl -a |grep swappiness
sysctl: reading key net.ipv6.conf.all.stable_secret
sysctl: reading key net.ipv6.conf.default.stable_secret
sysctl: reading key net.ipv6.conf.docker0.stable_secret
sysctl: reading key net.ipv6.conf.eth0.stable_secret
sysctl: reading key net.ipv6.conf.lo.stable_secret
vm.swappiness 30swap限制
–memory-swap # 只有设置 --memory 后才会有意义。使用swap可以让容器将超出限制部分的内存置换到磁盘上WARNING经常将内存交换到磁盘的应用程序会降低性能 不同的 --memory-swap 设置会产生不同的效果
–memory-swap–memory功能正数S正数M容器可用内存总空间为S其中ram为Mswap为S-M若SM则无可用swap资源0正数M相当于未设置swapunsetunset正数M若主机Docker Host启用于swap则容器的可用swap为 2*M-1正数M若主机Docker Host启用了swap则容器可使用最大至主机上所有swap空间
--memory-swap # 值为正数那么--memory 和 --memory-swap都必须要设置--memory-swap表示你能使用的内存和swap分区大小的总和例如--memory300m--memory-swap1g那么该容器能够使用300m物理内存和700m swap即--memory是实际物理内存大小值不变而swap的实际计算方式为--memory-swap---memory 容器可用swap
--memory-swap # 如果设置为0则忽略该配置并将该值视为未设置即未设置交换分区
--memory-swap # 如果等于--memory的值并且--memory设置为正整数容器无权访问swap
--memory-swap # 如果未设置如果宿主机开启了swap则容器的swap值最大为2*--memory即两倍物理内存大小例如如果--memory300m与--memory-swap没有设置改哦让其可以使用300m总的内存和600m交换空间但是并不准确在容器使用free命令所看到的的swap空间并不精确毕竟每个容器都可以看到具体大小宿主机的swap是有上限的而且不是所有容器看到的累计大小
--memory-swap # 如果设置为-1如果宿主机开启了swap则容器可以使用主机上swap的最大空间注意在容器中执行free命令看到的是宿主机的内存和swap使用而非容器自身的swap使用情况
stress-ng压力测试工具
stress-ng是一个压力测试工具可以通过软件仓库进行安装也提供了docker版本容器
# centos
yum install -y stress-ng
# 容器方式安装
docker pull lorel/docker-stress-ng假如一个容器未做内存使用限制则该容器可以利用到系统内存最大空间默认创建的容器没有做内存资源限制
# 默认一个workers分配256M内存2个即占512M内存
[rootcentos7 ~]# docker run --name c1 -it --rm lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm# 上面命令是前台执行下面在另一个终端窗口执行可以看奥占用512M左右内存
[rootcentos7 ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a28df8e66a8b c1 197.23% 512.0MiB / 1.792GiB 28.02% 648B / 0B 0B / 0B 5# 指定内存最大值
[rootcentos7 ~]# docker run --name c1 -it --rm -m 300m lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm# 在另一窗口执行一次性查看资源使用情况
[rootcentos7 ~]# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c769402345f5 c1 163.55% 300MiB / 300MiB 100.00% 648B / 0B 6.75GB / 0B 5# 内存限制 200M
[rootcentos7 ~]# docker run -it --rm -m 200M lorel/docker-stress-ng --vm 2 --vm-bytes 256M
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm[rootcentos7 ~]# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c384505f559d hardcore_shtern 192.41% 199.9MiB / 200MiB 99.96% 648B / 0B 741MB / 0B 5# 查看基于 cgroup对容器进行资源的大小限制
[rootcentos7 ~]# cat /sys/fs/cgroup/memory/docker/c384505f559d799d9a20d0fbee95e131539778f3b0063829fdcf22226d435582/memory.limit_in_bytes
209715200# 动态修改内存限制
[rootcentos7 ~]# echo 300*1024*1024|bc
314572800
[rootcentos7 ~]# echo 314572800 /sys/fs/cgroup/memory/docker/c384505f559d799d9a20d0fbee95e131539778f3b0063829fdcf22226d435582/memory.limit_in_bytes
[rootcentos7 ~]# cat /sys/fs/cgroup/memory/docker/c384505f559d799d9a20d0fbee95e131539778f3b0063829fdcf22226d435582/memory.limit_in_bytes
314572800
[rootcentos7 ~]# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c384505f559d hardcore_shtern 181.25% 300MiB / 300MiB 100.00% 648B / 0B 10.7GB / 0B 5# 通过echo命令可以改内存限制的值但是可以在原基础上增大内存限制缩小内存限制会报错
# -bash: echo: 写错误: 无效的参数# 内存大小软限制
[rootcentos7 ~]# docker run -it --rm -m 256m --memory-reservation 128m --name c1 lorel/docker-stress-ng --vm 2 --vm-bytes 256m
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm[rootcentos7 ~]# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
9fd1ea32cc83 c1 178.48% 255.9MiB / 256MiB 99.96% 648B / 0B 1.44GB / 0B 5# 查看硬限制
[rootcentos7 ~]# cat /sys/fs/cgroup/memory/docker/9fd1ea32cc83788b3f223295d6976295fcb307b0adaf9b82ea883f1fba129c49/memory.limit_in_bytes
268435456# 查看软限制
[rootcentos7 ~]# cat /sys/fs/cgroup/memory/docker/9fd1ea32cc83788b3f223295d6976295fcb307b0adaf9b82ea883f1fba129c49/memory.soft_limit_in_bytes# 软限制不能高于硬限制# 关闭OOM机制
# 查看docker OOM机制默认值
[rootcentos7 ~]# cat /sys/fs/cgroup/memory/docker/memory.oom_control
oom_kill_disable 0
under_oom 0#启动容器时关闭OOM机制
[rootcentos7 ~]# docker run -it --rm -m 200m --oom-kill-disable lorel/docker-stress-ng --vm 2 --vm-bytes 256m
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm
[rootcentos7 ~]# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
b0bccc1c29f7 epic_edison 0.00% 185.1MiB / 200MiB 92.56% 648B / 0B 28.7kB / 0B 5
[rootcentos7 ~]# cat /sys/fs/cgroup/memory/docker/b0bccc1c29f7355073442a1d84270827a19dc38a9258eafb5b3f017e3378cae0/memory.oom_control
oom_kill_disable 1
under_oom 1交换分区限制
docker run -it --rm -m 256m --memory-swap 512m --name c1 centos bash
cat /sys/fs/cgroup/memory/docker/容器ID/memory.memsw.limit_in_bytes容器的CPU限制
一个宿主机有几十个核心的CPU但是宿主机上可以同时运行成百上千个不同的进程用已处理不同的任务多进程共用一个CPU的核心为可压缩资源即一个核心的 CPU可以通过调整而运行多个进程但是同一个单位时间内只能有一个进程在CPU上运行那这么多的进程怎么在CPU上执行可调度的呢 Linux kernel进程的调度基于CFSCompletely Fair Scheduler完全公平调度
服务器资源密集型
CPU密集型的场景优先级越低越好计算密集型任务的特点是要进行大量的计算消耗CPU资源比如计算圆周率、数据处理、对视频频进行高清解码等等全靠CPU的运算能力。IO密集型的场景优先级值高点设计到网络。磁盘IO的任务都是IO密集型任务这类任务的特点是CPU消耗很少任务的大部分时间都在等IO操作完成因为IO的速度远远低于CPU和内存的速度比如Web应用高并发数据量大的动态网站来说数据库应该为IO密集型
CFS原理 cfs定义了进程调度的新模型它给cfs_rqcfs的run queue中的每一个进程安排一个虚拟时钟vruntime。如果一个进程得以执行随着时间的增长其vruntime将不断增大。没有得到执行的进程vruntime不变而调度器总是选择vruntime跑得最慢的那个进程来执行。这就是所谓的“完全公平”。为了区别不同优先级的进程优先级高的进程vruntime增长得慢以至于它可能得到更多的运行机会。CFS的意义在于在一个混杂着打来年计算型进程和IO交互进程的系统中CFS调度器相对其它调度器在对待IO交互进程要更加友善和公平。
配置默认的CFS调度程序
默认情况下每个容器对主机的CPU周期的访问都是不受限制的。可以设置各种约束以限制给定容器对主机CPU周期的访问。大多数用户使用并配置默认的CFS调度程序。在Docker1.13及更高版本中还可以配置realtime scheduler CFS是用于常规Linux进程的Linux内核CPU调度程序。通过几个运行时标志可以配置对容器拥有的CPU资源的访问量。使用这些设置时Docker会在主机上修改容器cgroup的设置
选项描述–cpus指定一个容器可以使用多少个可用的CPU核心资源。例如如果主机有两个CPU如果设置了–cpus“1.5”则可以保证容器最多使用1.5个CPU如果是4核CPU那么还可以是4核心上每核用一点但是总计是1.5核心的CPU。这相当于设置–cpu-period100000和–cpu-quota“150000”。此设置可在Docker1.13及更高版本中可用目的是替代–cpu-period和–cpu-quota两个参数从而是配置更简单但是最大不能超过宿主机的CPU总核心数在操作系统看到的CPU超线程后的数值此项常用–cpu-period过时选项指定CPU CFS调度程序周期必须与cpu-quta一起使用。默认为100微秒。大多数用户不会更改默认设置。如果使用Docker1.13或更高版本请改用cpus–cpu-quota过时选项在容器上添加CPU CFS配额计算方式为cpu-quota/cpu-period的结果值docker1.13及以上版本通常使用cpus设置此值–cpuset-cpus用于指定容器运行的CPU编号也就是所谓的CPU绑定。如果一个或多个CPU则容器可以使用逗号分隔的列表或连字符分隔的CPU范围。第一个CPU编号为0.有效值可能是0-3使用第一第二第三和第四CPU或1,3使用第二和第四CPU–cpu-shares用于设置cfs中调度的相对最大比例权重cpu-share的值越高的容器将会分得更多的时间片宿主机多核CPU总数为100%假如容器A为1024容器B为2048那么容器B将最大是容器A的可用CPU的两倍默认的时间片1024最大262144.这是一个软限制。
使用stress-ng测试CPU配置
# 查看stress-n关于CPU的帮助
[rootcentos7 ~]# docker run -it --rm --name c1 lorel/docker-stress-ng |grep cpu-c N, --cpu N start N workers spinning on sqrt(rand())--cpu-ops N stop when N cpu bogo operations completed-l P, --cpu-load P load CPU by P %%, 0sleep, 100full load (see -c)--cpu-method m specify stress cpu method m, default is all
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s# 不限制容器CPU
# 占用4个CPU资源但只是平均的使用CPU资源
docker run -it --rm lorel/docker-stress-ng --cpu 4
# 限制使用CPU
docker run -it --rm --cpus 1.5 lorel/docker-stress-ng --cpu 4
# 绑定CPU
# 一般不建议绑在0号CPU上因0号CPU一般会较忙
docker run -it --rm --cpus 1.5 --cpuset-cpus 2,4-5 lorel/docker-stress-ng --cpu 4# 多个容器的CPU利用率比例
docker run -it --rm --name c1 --cpu-shares 1000 lorel/docker-stress-ng --cpu 4
docker run -it --rm --name c2 --spu-shares 500 lorel/docker-stress-ng --cpu 4# 查看c1容器的cpu利用比例
cat /sys/fs/cgroup/cpu,cpuacct/docker/c1容器ID/cpu.shares
# 查看c2容器的cpu利用比例
cat /sys/fs/cgroup/cpu,cpuacct/docker/c2容器ID/cpu.shares
# 再打开新的容器CPU分配比例会动态调整# 动态调整cpu shares值
echo 2000 /sys/fs/cgroup/cpu,cpuacct/docker/容器ID/cpu.shares可视化图形工具Portainer
Portainer是一个可视化的容器镜像的图形管理工具利用Portainer可以轻松构建管理和维护Docker环境。而且完全免费基于容器化的安装方式方便高效。 官方站点https://www.portainer.io
安装Portainer
[rootcentos7 ~]# docker search portainer |head -n 3
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
portainer/portainer This Repo is now deprecated, use portainer/p… 2262
portainer/portainer-ce Portainer CE - a lightweight service deliver… 1350# portainer项目废弃
# portainer-ce项目替代portainer
[rootcentos7 ~]# docker pull portainer/portainer-ce
Using default tag: latest
latest: Pulling from portainer/portainer-ce
772227786281: Pull complete
96fd13befc87: Pull complete
bc9eaab2cad1: Pull complete
6458f72e4747: Pull complete
Digest: sha256:444ade51d69d7fca889c7aa14525c459dba313a0e7ca79aee985e6c0749427de
Status: Downloaded newer image for portainer/portainer-ce:latest
docker.io/portainer/portainer-ce:latest
[rootcentos7 ~]# docker volume create portainer_data
portainer_data
[rootcentos7 ~]# docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restartalways -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
7d62ec92aaaca24218d44b13155fb47fb752847a596a1f732b90167687a986c3浏览器访问 http://ip:9000
docker命令总结
attach # 当前shell下attach连接指定运行镜像build # 通过Dockerfile定制镜像commit # 提交当前容器为新的镜像cp # 从容其中拷贝指定文件或者目录到宿主机中create # 创建一个新的容器同run 但不能启动diff # 查看dokcer 容器变化events # 从docker服务获取容器实时事件exec # 在已存在的容器上运行命令export # 导出容器的内容作为一个tar 归档文件[对应import]history # 展示一个镜像形成的历史images # 列出系统当前镜像import # 从tar包中的内容创建一个新的文件系统映像[对应export]info # 显示系统相关系统inspect # 查看容器详细信息kill # kill指定容器load # 从一个tar包中加载一个镜像[对应save]login # 注册或者登录一个docker源服务器logout # 从当前docker registry退出logs # 输出当前日志信息port # 查看映射端口对应的容器内部源端口pause # 暂停容器ps # 列出容器列表pull # 从docker镜像源服务器拉取指定镜像或者库镜像push # 推送指定镜像或者库镜像至docker源服务器restart # 重启运行的容器rm # 移除一个或多个容器rmi # 移除一个或多个镜像[无容器使用该镜像才可删除否则需要删除相关容器才可继续 或 -f 强制删除]run # 创建一个新的容器并运行一个命令save # 保存一个镜像为一个tar包[对应load]search # 在docker hub中搜索镜像start # 启动容器stop # 停止容器tag # 给源中镜像打标签top # 查看容器中运行的进程信息unpause # 取消暂停容器version # 查看docker版本号wait # 截取容器停止时的退出状态值
文章转载自: http://www.morning.jbctp.cn.gov.cn.jbctp.cn http://www.morning.rrqbm.cn.gov.cn.rrqbm.cn http://www.morning.gkmwx.cn.gov.cn.gkmwx.cn http://www.morning.qmmfr.cn.gov.cn.qmmfr.cn http://www.morning.qpnmd.cn.gov.cn.qpnmd.cn http://www.morning.rwfp.cn.gov.cn.rwfp.cn http://www.morning.niukaji.com.gov.cn.niukaji.com http://www.morning.ngpdk.cn.gov.cn.ngpdk.cn http://www.morning.mftdq.cn.gov.cn.mftdq.cn http://www.morning.ykswq.cn.gov.cn.ykswq.cn http://www.morning.pxspq.cn.gov.cn.pxspq.cn http://www.morning.qcdhg.cn.gov.cn.qcdhg.cn http://www.morning.whnps.cn.gov.cn.whnps.cn http://www.morning.dblgm.cn.gov.cn.dblgm.cn http://www.morning.ftsmg.com.gov.cn.ftsmg.com http://www.morning.tpnxj.cn.gov.cn.tpnxj.cn http://www.morning.qttg.cn.gov.cn.qttg.cn http://www.morning.tdmgs.cn.gov.cn.tdmgs.cn http://www.morning.grfhd.cn.gov.cn.grfhd.cn http://www.morning.bpmfl.cn.gov.cn.bpmfl.cn http://www.morning.yqndr.cn.gov.cn.yqndr.cn http://www.morning.symgk.cn.gov.cn.symgk.cn http://www.morning.jfbrt.cn.gov.cn.jfbrt.cn http://www.morning.hlrtzcj.cn.gov.cn.hlrtzcj.cn http://www.morning.srtw.cn.gov.cn.srtw.cn http://www.morning.qbfqb.cn.gov.cn.qbfqb.cn http://www.morning.fqpyj.cn.gov.cn.fqpyj.cn http://www.morning.tdwjj.cn.gov.cn.tdwjj.cn http://www.morning.tyklz.cn.gov.cn.tyklz.cn http://www.morning.ljglc.cn.gov.cn.ljglc.cn http://www.morning.hwljx.cn.gov.cn.hwljx.cn http://www.morning.kbfzp.cn.gov.cn.kbfzp.cn http://www.morning.sqmbb.cn.gov.cn.sqmbb.cn http://www.morning.lbjdx.cn.gov.cn.lbjdx.cn http://www.morning.pfnrj.cn.gov.cn.pfnrj.cn http://www.morning.ypfw.cn.gov.cn.ypfw.cn http://www.morning.qhvah.cn.gov.cn.qhvah.cn http://www.morning.gediba.com.gov.cn.gediba.com http://www.morning.cfhwn.cn.gov.cn.cfhwn.cn http://www.morning.xxiobql.cn.gov.cn.xxiobql.cn http://www.morning.mlgsc.com.gov.cn.mlgsc.com http://www.morning.tcfhs.cn.gov.cn.tcfhs.cn http://www.morning.tdzxy.cn.gov.cn.tdzxy.cn http://www.morning.zxybw.cn.gov.cn.zxybw.cn http://www.morning.bkgfp.cn.gov.cn.bkgfp.cn http://www.morning.qbxdt.cn.gov.cn.qbxdt.cn http://www.morning.wmfr.cn.gov.cn.wmfr.cn http://www.morning.tnhg.cn.gov.cn.tnhg.cn http://www.morning.pxlpt.cn.gov.cn.pxlpt.cn http://www.morning.ttdxn.cn.gov.cn.ttdxn.cn http://www.morning.xzqzd.cn.gov.cn.xzqzd.cn http://www.morning.haibuli.com.gov.cn.haibuli.com http://www.morning.fjmfq.cn.gov.cn.fjmfq.cn http://www.morning.xwlmg.cn.gov.cn.xwlmg.cn http://www.morning.ypcbm.cn.gov.cn.ypcbm.cn http://www.morning.xgbq.cn.gov.cn.xgbq.cn http://www.morning.srtw.cn.gov.cn.srtw.cn http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn http://www.morning.rdng.cn.gov.cn.rdng.cn http://www.morning.btypn.cn.gov.cn.btypn.cn http://www.morning.tpyjr.cn.gov.cn.tpyjr.cn http://www.morning.wlqbr.cn.gov.cn.wlqbr.cn http://www.morning.ymhjb.cn.gov.cn.ymhjb.cn http://www.morning.fdfsh.cn.gov.cn.fdfsh.cn http://www.morning.mcfjq.cn.gov.cn.mcfjq.cn http://www.morning.djwpd.cn.gov.cn.djwpd.cn http://www.morning.rnyhx.cn.gov.cn.rnyhx.cn http://www.morning.mkkcr.cn.gov.cn.mkkcr.cn http://www.morning.ccpnz.cn.gov.cn.ccpnz.cn http://www.morning.gjlst.cn.gov.cn.gjlst.cn http://www.morning.htsrm.cn.gov.cn.htsrm.cn http://www.morning.rttxx.cn.gov.cn.rttxx.cn http://www.morning.pqrhb.cn.gov.cn.pqrhb.cn http://www.morning.fwwkr.cn.gov.cn.fwwkr.cn http://www.morning.qnzgr.cn.gov.cn.qnzgr.cn http://www.morning.gqcd.cn.gov.cn.gqcd.cn http://www.morning.cgtfl.cn.gov.cn.cgtfl.cn http://www.morning.jcpq.cn.gov.cn.jcpq.cn http://www.morning.saletj.com.gov.cn.saletj.com http://www.morning.jgmdr.cn.gov.cn.jgmdr.cn