带你一文搞懂Docker
01Docker概述Docker简介
Docker是基于Go语言实现的云开源项目。
Docker的主要目标是:Build,ShipandRunAnyApp,Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP及其运行环境能做到一次镜像,处处运行。传统虚拟机和容器
传统虚拟机(virtualmachine):
传统虚拟机技术基于安装在主操作系统上的虚拟机管理系统(如VirtualBox、VMware等),创建虚拟机(虚拟出各种硬件),在虚拟机上安装从操作系统,在从操作系统中安装部署各种应用。
缺点:资源占用多、冗余步骤多、启动慢
Linux容器(LinuxContainer,简称LXC):
Linux容器是与系统其他部分分隔开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
对比:
特性
容器
虚拟机
启动
秒级
分钟级
大小
一般为Mb
一般为Gb
速度
接近原生
比较慢
系统支持数量
单机支持上千个容器
一般几十个Docker运行速度快的原因
Docker有比虚拟机更少的抽象层:
由于Docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在CPU、内存利用率上docker有明显优势。
Docker利用的是宿主机的内核,而不需要加载操作系统OS内核:
当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引寻、加载操作系统内核返回等比较耗时耗资源的过程。当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程是分钟级别的。而Docker由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟。
Docker容器的本质就是一个进程。Docker软件
Docker并非一个通用的容器工具,它依赖于已经存在并运行的Linux内核环境。(在Windows上安装Docker时需要依赖WLS,也即Windows下的Linux子系统)。
Docker实质上是在已经运行的Linux下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的Linux主机。
Docker的基本组成部分:镜像(image)容器(container)仓库(repository)Docker镜像
Docker镜像就是一个只读的模板。镜像可以用来创建Docker容器,一个镜像可以创建多个容器。Docker容器
Docker利用容器独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。Docker仓库
Docker仓库是集中存放镜像文件的场所。
仓库分为公开仓库和私有仓库两种。
最大的公开仓库是Docker官方的DockerHub:https:hub。docker。comDocker架构
Docker是一个CS(ClientServer)结构的系统,后端是一个松耦合架构,众多模块各司其职。
Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从容器接收命令并管理运行在主机上的容器。
〔外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(imgHp29jTNK1663229723141)(https:cdn。nlark。comyuque02022svg12911942165209333989720255a0ae98143e39e9e654b8da3b2c8。svg)〕
Docker运行的基本流程为:用户是使用DockerClient与DockerDaemon建立通信,并发送请求给后者DockerDaemon作为Docker架构的主体部分,首先提供DockerServer的功能使其可以接收DockerClient的请求DockerEngine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式存在Job的运行过程中,当需要容器镜像时,则从DockerRegistry中下载镜像,并通过镜像管理驱动GraphDriver将下载镜像以Graph的形式存储当需要为Docker创建网络环境时,通过网络管理驱动Networkdriver创建并配置Docker容器网络环境当需要限制Docker容器运行资源或执行用户指令等操作时,则通过Execdriver来完成Libcontainer是一项独立的容器管理包,Networkdriver以及Execdriver都是通过Libcontainer来实现具体对容器进行的操作
02Docker安装CentOS安装Docker
参考官网:https:docs。docker。comengineinstallcentos卸载旧版本
如果之前安装过Docker,需要先卸载旧版本:sudoyumremovedockerdockerclientdockerclientlatestdockercommondockerlatestdockerlatestlogrotatedockerlogrotatedockerengine
旧版本的Docker引擎包可能叫做:docker、dockerengine。
新版本的Docker引擎包叫做:dockerce配置yum资源库
安装yumconfigmanager:yumutil提供yumconfigmanager功能sudoyuminstallyyumutils
配置docker的资源库地址:
官方地址:(比较慢,不推荐)在yum资源库中添加docker资源库sudoyumconfigmanageraddrepohttps:download。docker。comlinuxcentosdockerce。repo
阿里云镜像地址:sudoyumconfigmanageraddrepohttps:mirrors。aliyun。comdockercelinuxcentosdockerce。repo
阿里云官网提供了很多资源镜像,镜像地址:https:mirrors。aliyun。com,进入之后可以选择自己需要的资源进行配置
创建缓存(可选):yummakecachefast安装Docker引擎
安装最新版本的Docker引擎、Docker客户端:dockerce是Docker引擎,dockercecli是客户端sudoyuminstalldockercedockerceclicontainerd。iodockercomposeplugin
此时,默认安装的docker引擎、客户端都是最新版本。
如果要安装指定版本:查询版本列表yumlistdockerceshowduplicatessortr指定版本安装17。09。0。ce版sudoyuminstalldockerceVERSIONSTRINGdockercecliVERSIONSTRINGcontainerd。iodockercomposepluginsudoyuminstalldockerce17。09。0。cedockercecli17。09。0。cecontainerd。iodockercomposeplugin启动docker引擎
如果没有启动Docker引擎,那么执行dockerversion查看版本号时,只能看到Client:DockerEngine(Docker引擎客户端)的版本号。
启动Docker引擎:新版本的Docker就是一个系统服务,可以直接使用启动系统服务方式启动systemctlstartdocker此时查看docker版本,可以看到Server:DockerEngine(Docker引擎)版本号dockerversion卸载Docker
卸载Docker步骤:关闭服务systemctlstopdocker使用yum删除docker引擎sudoyumremovedockercedockerceclicontainerd。io删除镜像、容器、卷、自定义配置等文件sudormrfvarlibdockersudormrfvarlibcontainerd运行HelloWorld测试
运行HelloWorld:dockerrunhelloworld03Docker下载加速
方式1:使用网易数帆、阿里云等容器镜像仓库进行下载。
例如,下载网易数帆镜像中的mysql。(网易数帆的地址为hub。c。163。com,网易数帆对dockerhub官方的镜像命名空间为library)。dockerpullhub。c。163。comlibrarymysql:latest
方式2:配置阿里云加速。
登录阿里云,进入工作台容器镜像服务镜像工具镜像加速器。
里面提供了一个加速器地址:https:xxxxx。mirror。aliyuncs。com,将该地址配置到docker中:cdetcdocker初次进来时没有etcdockerdaemon。json文件,直接创建该文件即可vietcdockerdaemon。json
在daemon。json中写入以下内容:(即加速器地址){registrymirrors:〔https:xxxxx。mirror。aliyuncs。com〕}
然后刷新配置、重启docker即可:centos6的命令sudochkconfigdaemonreloadsudoservicedockerrestartcentos7的命令sudosystemctldaemonreloadsudosystemctlrestartdocker
使用方式2可以直接下载官方的镜像,且镜像tag为官方tag,不需要加上云服务商的地址。
例如:dockerpullmysql:latest04Docker常用命令启动类命令
启动docker:systemctlstartdocker
停止Docker:systemctlstopdocker
重启Docker:systemctlrestartdocker
查看状态:systemctlstatusdocker
设置开机自启:systemctlenabledocker帮助类命令
查看Docker版本:dockerversion
查看Docker概要信息:dockerinfo
查看Docker总体帮助文档:dockerhelp
查看docker具体命令帮助文档:docker具体命令help镜像命令列出本地主机上的镜像dockerimages
参数:aqf在远程仓库中搜索镜像
(默认取dockerhub中搜索)dockersearch镜像名称
参数:flimit数量下载镜像dockerpull镜像名称〔:tag〕
不加tag时,默认下载最新的镜像(即tag为latest)。查看占据的空间
查看镜像容器数据卷所占的空间:dockersystemdf删除镜像dockerrmi镜像名称ID
可以使用空格分隔,删除多个镜像:dockerrmi镜像1镜像2镜像3
删除全部镜像:dockerrmif{dockerimagesqa}虚悬镜像
仓库名、标签都是的镜像,俗称虚悬镜像(danglingimage)。命令自动补全
docker支持命令自动补全功能,当输入镜像名前几位时,可以按tab键自动补全镜像名称、tag等。如果镜像中有ubuntu,查看输入ub按下tab是否可以补全dockerrunub
如果按下tab时没有自动补全,可以按以下步骤操作:检查是否安装了bashcompletion(命令补全增强包)检查有usrsharebashcompletionbashcompletion这个文件lsusrsharebashcompletionbashcompletion如果有usrsharebashcompletion目录,但是没有usrsharebashcompletionbashcompletion文件(centos6为etcbashcompletion文件),则需要安装bashcompletionyumyinstallbashcompletion检查是否安装了docker的自动补全检查usrsharebashcompletioncompletions文件夹下是否有docker开头的自动补全docker安装完后会在该文件夹下生成自动补全文件docker如果安装了dockercompose,则该文件夹下还会有dockercompose文件llusrsharebashcompletioncompletionsdocker如果已经安装了docker自动补全,使用source命令使其生效sourceusrsharebashcompletioncompletionsdocker再次使用tab查看是否可以自动补全如果镜像中有ubuntu,查看输入ub按下tab是否可以补全dockerrunub如果有报错,且报错中提示getcompwordsbyref:commandnotfound。说明bashcompletion的配置文件没有生效,需要source一下对于centos7,bashcompletion安装的是2。x版本,配置文件为usrsharebashcompletionbashcompletionsourceusrsharebashcompletionbashcompletion如果是centos6,自动安装的bashcompletion最新版为1。x版本,配置文件为etcbashcompletionbashetcbashcompletion再次使用tab查看是否可以自动补全如果镜像中有ubuntu,查看输入ub按下tab是否可以补全dockerrunub05容器命令新建启动容器dockerrun〔OPTIONS〕IMAGE〔COMMAND〕〔ARG。。。〕
常用的参数:name:为容器指定一个名称d:后台运行容器并返回容器ID,也即启动守护式容器i:以交互模式(interactive)运行容器,通常与t同时使用t:为容器重新分配一个伪输入终端(tty),通常与i同时使用。也即启动交互式容器(前台有伪终端,等待交互)e:为容器添加环境变量P:随机端口映射。将容器内暴露的所有端口映射到宿主机随机端口p:指定端口映射
p指定端口映射的几种不同形式:phostPort:containerPort:端口映射,例如p8080:80pip:hostPort:containerPort:配置监听地址,例如p10。0。0。1:8080:80pip::containerPort:随机分配端口,例如p10。0。0。1::80phostPort1:containerPort1phostPort2:containerPort2:指定多个端口映射,例如p8080:80p8888:3306启动交互式容器
以交互方式启动ubuntu镜像i交互模式t分配一个伪输入终端ttyubuntu镜像名称binbash(或者bash)shell交互的接口dockerrunitubuntubinbash
退出交互模式:
方式1:在交互shell中exit即可退回宿主机exit;
方式2:使用快捷键ctrlPQ
方式1退出后,容器会停止;
方式2退出后容器依然正在运行。启动守护式容器
大部分情况下,我们系统docker容器服务时在后台运行的,可以通过d指定容器的后台运行模式:dockerrund容器名
注意事项:
如果使用dockerrundubuntu尝试启动守护式的ubuntu,会发现容器启动后就自动退出了。
因为Docker容器如果在后台运行,就必须要有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(例如top、tail),就会自动退出。列出正在运行的容器
列出所有正在运行的容器:dockerps〔OPTIONS〕
常用参数:alnq容器其他启停操作启动已经停止的容器dockerstart容器ID或容器名重启容器dockerrestart容器ID或容器名停止容器dockerstop容器ID或容器名强制停止容器dockerkill容器ID或容器名删除容器
删除已经停止的容器:dockerrm容器ID或容器名
删除容器是dockerrm,删除镜像是dockerrmi,注意区分。
强制删除正在运行的容器:dockerrmf容器ID或容器名
一次删除多个容器实例:dockerrmf{dockerpsaq}或者dockerpsaqxargsdockerrm查看容器日志dockerlogs容器ID或容器名查看容器内运行的进程dockertop容器ID或容器名查看容器内部细节dockerinspect容器ID或容器名进入正在运行的容器
进入正在运行的容器,并以命令行交互:dockerexecit容器IDbashShell
重新进入:dockerattach容器ID
dockerexec和dockerattach区别:attach直接进入容器启动命令的终端,不会启动新的进程,用exit退出会导致容器的停止exec是在容器中打开新的终端,并且可以启动新的进程,用exit退出不会导致容器的停止
如果有多个终端,都对同一个容器执行了dockerattach,就会出现类似投屏显示的效果。一个终端中输入输出的内容,在其他终端上也会同步的显示。容器和宿主机文件拷贝
容器内文件拷贝到宿主机:dockercp容器ID:容器内路径目的主机路径
宿主机文件拷贝到容器中:dockercp主机路径容器ID:容器内路径导入和导出容器
export:导出容器的内容流作为一个tar归档文件(对应import命令);
import:从tar包中的内容创建一个新的文件系统再导入为镜像(对应export命令);
示例:导出dockerexport容器IDtar文件名dockerexportabcaaa。tar导入cattar文件dockerimport自定义镜像用户自定义镜像名:自定义镜像版本号dockeraaa。tardockerimporttestmytest:1。0。1将容器生成新镜像
dockercommit提交容器副本使之成为一个新的镜像。
docker启动一个镜像容器后,可以在里面执行一些命令操作,然后使用dockercommit将新的这个容器快照生成一个镜像。dockercommitm提交的描述信息a作者容器ID要创建的目标镜像名:〔tag〕
Docker挂载主机目录,可能会出现报错:cannotopendirectory。:Perissiondenied。
解决方案:在命令中加入参数privilegedtrue。
CentOS7安全模块比之前系统版本加强,不安全的会先禁止,目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了。如果要开启,一般使用privilegedtrue,扩大容器的权限解决挂载没有权限的问题。也即使用该参数,容器内的root才拥有真正的root权限,否则容器内的root只是外部的一个普通用户权限。容器数据卷
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过UnionFS,提供一些用于持续存储或共享数据。
特性:卷设计的目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
特点:数据卷可以在容器之间共享或重用数据卷中的更改可以直接实施生效数据卷中的更改不会包含在镜像的更新中数据卷的生命周期一直持续到没有容器使用它为止
运行一个带有容器卷存储功能的容器实例:dockerrunitprivilegedtruev宿主机绝对路径目录:容器内目录〔rwro〕镜像名
可以使用dockerinspect查看容器绑定的数据卷。
权限:rwro
容器卷的继承:启动一个容器dockerrunitprivilegedtruetmptest:tmpdockernameu1ubuntubinbash使用volumesfrom继承u1的容器卷映射配置dockerrunitprivilegedtruevolumesfromu1nameu2ubuntu所有命令示意图
06Docker镜像
镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好行程一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。Docker镜像加载原理联合文件系统
Docker中的文件存储驱动叫做storagedriver。
Docker最早支持的stotagedriver是AUFS,它实际上由一层一层的文件系统组成,这种层级的文件系统叫UnionFS。
联合文件系统(UnionFS):Union文件系统,是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(uniteserveraldirectoriesintoasinglevirtualfilesystem)。
Union文件系统是Docker镜像的基础。镜像可以通过分层来进行集成,基于基础镜像可以制作具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
后来出现的docker版本中,除了AUFS,还支持OverlayFS、Btrfs、DeviceMapper、VFS、ZFS等storagedriver。bootfs和rootfs
bootfs(bootfilesystem)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。
在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的LinuxUnix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已经由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(rootfilesystem),在bootfs之上,包含的就是典型Linux系统中的dev、proc、bin、etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu、CentOS等。
docker镜像底层层次:
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接使用Host的Kernel,自己只需要提供rootfs就可以。所以,对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,不同的发行版可以共用bootfs。
有差别的rootfs:
镜像分层
Docker支持扩展现有镜像,创建新的镜像。新镜像是从base镜像一层一层叠加生成的。
例如:Version:0。0。1FROMdebian直接在debainbase镜像上构建MAINTAINERmylinuxRUNaptgetupdateaptgetinstallyemacs安装emacsRUNaptgetinstallyapache2安装apache2CMD〔binbash〕容器启动时运行bash
镜像创建过程:
镜像分层的优势
镜像分层的一个最大好处就是共享资源,方便复制迁移,方便复用。
当容器启动时,一个新的可写层将被加载到镜像的顶部,这一层通常被称为容器层,容器层之下的都叫镜像层。
所有对容器的改动,无论添加、删除、还是修改文件都只会发生在容器层中。
只有容器层是可写的,容器层下面的所有镜像层都是只读的。
如图:
07nexus搭建docker私仓使用nexus创建docker私有仓库
Nexus的安装请参考该文档:https:www。yuque。comtmflpomuumrx2
Nexus配置Docker仓库步骤;nexus默认docker是失效的,需要在securityRealms,将docker配置成Active在Repository的BlobStore中创建一个用于存放docker镜像的存储。内网没有S3的话,把Type配置为file就行。
S3:SimpleStorageService,简单对象存储服务,即云存储。在Repository的Repositories中创建一个新的资源库,类型为dockerhosted。
创建的dockerhosted资源库的相关配置:Name:指定该资源库的名称,例如就叫dockerhostedOnline:默认勾选即可HTTP:与下面的HTTPS,至少需要勾选其中一个选择框,并配置一个和nexus不同的端口号,例如8881。将来docker客户端向镜像中心上传镜像时,需要向该端口号进行上传。HTTPS:如果服务器可以开启https服务,则也可以勾选HTTPS,然后配置一个端口号,接收docker客户端上传上来的镜像。Allowanonymousdockerpull:允许匿名上传,默认不勾选EnabledockerV1API:是否启用docker早期V1版本的API,默认不勾选,即只启用V2API:http:xxx。xxx。xxx。xxx:8881v2BlobStore:选择上面创建的docker镜像的存储DeploymentPolicy:是否允许重复上传同一个资源,默认允许
配置好之后,修改防火墙设置,开启刚刚配置的8881端口:vimetcsysconfigiptables
添加:AINPUTptcpmtcpdport8881jACCEPT
重启iptables:serviceiptablesrestartdocker客户端的镜像导出和导入
镜像下载和导出:下载镜像dockerpullmysql:8。0。28将镜像导出成本地tar文件dockersaveomysql8。0。28。tarmysql:8。0。28
镜像的导入:将本地文件导入到docker镜像中(docker会自动解析出文件中的tag,无需手动指定)dockerloadmysql8。0。28。tardocker客户端向私仓上传镜像配置docker允许接收http请求
docker默认只接收https请求,而我们的nexus私仓如果配置的是HTTP接口的话,docker直接连会报错:servergaveHTTPresponsetoHTTPSclient
需要配置docker允许连接我们私仓的http。vimusrlibsystemdsystemdocker。service
在其中的ExecStart选项后面,添加insecureregistry{docker私有镜像库IP}ipv6false。
例如:〔Service〕前面的H参数可能不同,不需要管,只需在最后面加上我们的私仓地址即可:insecureregistry192。168。x。xxx:8881ipv6falseExecStartusrbindockerdHtcp:0。0。0。0:2375Hunix:varrundocker。sockinsecureregistry192。168。x。xxx:8881ipv6false
然后重启docker:centos6的命令sudochkconfigdaemonreloadsudoservicedockerrestartcentos7的命令sudosystemctldaemonreloadsudosystemctlrestartdocker
也可以在etcdockerdaemon。json中进行配置:{insecurereigstries:〔192。168。xxx。xxx:8881〕}向私仓推送镜像如果私仓不允许匿名上传镜像,则需要先进行登陆。(一般私仓都不允许匿名上传,nexus默认匿名上传也没有勾选)username后面为nexus用户名,执行命令后会提示输入密码dockerloginusernameadminhttp:192。168。xxx。xxx:8881登录之后,会在HOME。dockerconfig。json中记录下登录的用户信息,之后便不需要再进行登陆操作如果要取消登录,则只需执行以下命令dockerlogouthttp:192。168。xxx。xxx:8881将要上传的镜像重新设置Tag。docker按照镜像名称区分上传的资源库。例如:mysql:8。0。28会被上传到docker官方dockerhub;tengyerhelloworld:lasted会被上传到dockerhub的tengyer命名空间中;registry。cnhangzhou。aliyuncs。com命名空间镜像名称:〔镜像版本号〕会上传到阿里云指定命名空间中;ccr。ccs。tencentyun。com命名空间helloworld:会上传到腾讯云指定命名空间中;hub。c。163。com命名空间helloworld:会上传到网易数帆指定命名空间中;所以,我们如果要上传到我们的私仓,需要将Tag修改为xxx。xxx。xxx。xxx:8881命名空间mysql:5。0。27格式:将mysql:8。0。28复制出一个私仓格式的Tag该操作在dockerimages中会多出一个复制出来的tag,但是ImageId和原始的相同加个official命名空间,方便区分这个镜像是从官方镜像下载下来的,不加命名空间也可以上传dockertag〔ImageId〕xxx。xxx。xxx。xxx:8881officialmysql:8。0。28将修改好Tag的镜像进行上传:dockerpushxxx。xxx。xxx。xxx:8881officialmysql:8。0。2808Registry搭建docker私仓DockerRegistry
DockerRegistry是官方提供的工具,用于构建私有镜像仓库。环境搭建
DockerRegistry也是DockerHub提供的一个镜像,可以直接拉取运行。
步骤:拉取镜像dockerpullregistry启动DockerRegistrydockerrundp5000:5000vappmyregistry:tmpregistryprivilegedtrueregistry验证(查看私服中的所有镜像)curlhttp:192。168。xxx。xxx:5000v2catalog
Registry会返回json格式的所有镜像目录向Registry私仓中上传镜像配置docker允许接收http请求
(配置方式和上传到nexus私仓相同)。
修改etcdockerdaemon。json,添加insecureregistries允许http:{registrymirros:〔https:xxxx。mirror。aliyuncs。com〕,insecureregistries:〔192。168。xxx。xxx:5000〕}
然后重启docker:(新版本的docker会立即生效)centos6的命令sudochkconfigdaemonreloadsudoservicedockerrestartcentos7的命令sudosystemctldaemonreloadsudosystemctlrestartdocker推送到私仓
步骤:添加一个对应私仓地址的tagdockertagleemyubuntu:1。0。1192。168。xxx。xxx:5000leemyubuntu:1。0。1push到私仓dockerpush192。168。xxx。xxx:5000leemyubuntu:1。0。1查看私仓中镜像目录验证curlhttp:192。168。xxx。xxx:5000v2catalog
拉取验证:dockerpull192。169。xxx。xxx:5000leemyubuntu:1。0。109Docker安装Mysql
以安装Mysql5。7为例:dockerpullmysql:5。7Mysql单机简单版Mysql5。7安装
简单的启动Mysql容器:需要使用e配置环境变量MYSQLROOTPASSWORD(mysqlroot用户的密码)dockerrunp3306:3306eMYSQLROOTPASSWORDrootdmysql:5。7
简单版的Mysql会存在以下问题:中文乱码没有容器卷映射
启动docker容器后,可以正常的连接、创建数据库,创建表,插入数据。但是插入中文则会报错。
例如:创建db01数据库createdatabasedb01;切换到db01;usedb01;创建表createtablet1(idint,namevarchar(20));插入英文可以正常插入insertintot1values(1,abc);插入中文报错insertintot1values(2,张三);
这是因为docker默认的字符集的问题,可以在mysql中使用以下命令查看数据库字符集:showvariableslikecharacter;
返回的字符集中,charactersetdatabase、charactersetserver等都为latin1字符集,所以会报错。
而且因为启动容器时没有配置容器卷映射,当容器意外被删时,数据无法找回。实际应用版Mysql5。7安装
启动Mysql容器,并配置容器卷映射:dockerrundp3306:3306privilegedtruevappmysqllog:varlogmysqlvappmysqldata:varlibmysqlvappmysqlconf:etcmysqlconf。deMYSQLROOTPASSWORDrootnamemysqlmysql:5。7参数说明:p3306:3306:将容器的3306端口映射到宿主机的3306端口。vappmysqllog:varlogmysql:将主机当前目录下的logs目录挂载到容器的logs。日志目录vappmysqldata:varlibmysql:将主机当前目录下的data目录挂载到容器的varlibmysql。数据目录vappmysqlconf:etcmysqlconf。d:将主机当前目录下的appmysqlconf挂载到容器的etcmysqlconf。d。配置目录eMYSQLROOTPASSWORDroot:初始化root用户的密码。
在appmysqlconf下新建my。cnf,通过容器卷同步给mysql实例,解决中文乱码问题:〔client〕defaultcharactersetutf8〔mysqld〕collationserverutf8generalcicharactersetserverutf8
重启mysql容器,使得容器重新加载配置文件:dockerrestartmysql
此时便解决了中文乱码(中文插入报错)问题。
而且因为启动时将容器做了容器卷映射,将mysql的配置(映射到appmysqlconf)、数据(映射到appmysqldata)、日志(映射到appmysqllog)都映射到了宿主机实际目录,所以即使删除了容器,也不会产生太大影响。只需要再执行一下启动Mysql容器命令,容器卷还按相同位置进行映射,所有的数据便都可以正常恢复。Mysql主从复制安装
安装主服务器容器实例(端口号3307):启动容器实例dockerrunp3307:3306namemysqlmasterprivilegedtruevappmysqlmasterlog:varlogmysqlvappmysqlmasterdata:varlibmysqlvappmysqlmasterconf:etcmysqleMYSQLROOTPASSWORDrootdmysql:5。7进入appmysqlmasterconf,新建my。cnf配置文件:〔mysqld〕设置serverid,同一个局域网中需要唯一serverid101指定不需要同步的数据库名称binlogignoredbmysql开启二进制日志功能logbinmallmysqlbin设置二进制日志使用内存大小(事务)binlogcachesize1M设置使用的二进制日志格式(mixed,statement,row)binlogformatmixed二进制日志过期清理时间。默认值为0,表示不自动清理expirelogsdays7跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致slaveskiperrors1062重启容器实例dockerrestartmysqlmaster进入容器实例内dockerexecitmysqlmasterbinbash登录mysql,创建数据同步用户首先使用mysqlurootp登录mysql创建数据同步用户createuserslaveidentifiedby123456;授权grantreplicationslave,replicationclienton。toslave;flushprivileges;
安装从服务器容器实例(端口号3308):启动容器服务:dockerrunp3308:3306namemysqlslaveprivilegedtruevappmysqlslavelog:varlogmysqlvappmysqlslavedata:varlibmysqlvappmysqlslaveconf:etcmysqleMYSQLROOTPASSWORDrootdmysql:5。7进入appmysqlslaveconf目录,创建my。cnf配置文件:〔mysqld〕设置serverid,同一个局域网内需要唯一serverid102指定不需要同步的数据库名称binlogignoredbmysql开启二进制日志功能,以备slave作为其它数据库实例的Master时使用logbinmallmysqlslave1bin设置二进制日志使用内存大小(事务)binlogcachesize1M设置使用的二进制日志格式(mixed,statement,row)binlogformatmixed二进制日志过期清理时间。默认值为0,表示不自动清理expirelogsdays7跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断如:1062错误是指一些主键重复,1032是因为主从数据库数据不一致slaveskiperrors1062relaylog配置中继日志relaylogmallmysqlrelaybinlogslaveupdates表示slave将复制事件写进自己的二进制日志logslaveupdates1slave设置只读(具有super权限的用户除外)readonly1修改完配置需要重启slave容器实例dockerrestartmysqlslave
在主数据库中查看主从同步状态:进入主数据库容器:dockerexecitmysqlmasterbinbash进入Mysqlmysqlurootp查看主从同步状态showmasterstatus;
主要查看返回结果的文件名File、当前位置Position
进入从数据库容器,配置主从复制:进入从数据库容器:dockerexecitmysqlslavebinbash进入数据库mysqlurootp配置从数据库所属的主数据库:格式:changemastertomasterhost宿主机ip,masteruser主数据库配置的主从复制用户名,masterpassword主数据库配置的主从复制用户密码,masterport宿主机主数据库端口,masterlogfile主数据库主从同步状态的文件名File,masterlogpos主数据库主从同步状态的Position,masterconnectretry连接失败重试时间间隔(秒);changemastertomasterhost192。168。xxx。xxx,masteruserslave,masterpassword123456,masterport3307,masterlogfilemallmysqlbin。000001,masterlogpos769,masterconnectretry30;查看主从同步状态:G可以将横向的结果集表格转换成纵向展示。slavestatus的字段比较多,纵向展示比友好showslavestatusG;
除了展示刚刚配置的主数据库信息外,主要关注SlaveIORunning、SlaveSQLRunning。目前两个值应该都为No,表示还没有开始。开启主从同步:startslave;再次查看主从同步状态,SlaveIORunning、SlaveSQLRunning都变为Yes。
主从复制测试:在主数据库上新建库、使用库、新建表、插入数据createdatabasedb01;usedb01;createtablet1(idint,namevarchar(20));insertintot1values(1,abc);在从数据库上使用库、查看记录showdatabases;usedb01;selectfromt1;10Docker安装Redis
以Redis6。0。8为例:dockerpullredis:6。0。8单机版安装简单版Redis
简单的启动Redis容器:dockerrunp6379:6379dredis:6。0。8
简单版没有配置容器卷映射,当容器被删除时数据无法恢复。实际应用版Redis
配置文件、数据文件都和容器卷进行映射。
步骤:宿主机创建目录appredis在appredisconf下创建文件redis。conf,主要修改以下几项配置开启密码验证(可选)requirepass123允许redis外地连接,需要注释掉绑定的IPbind127。0。0。1关闭保护模式(可选)protectedmodeno注释掉daemonizeyes,或者配置成daemonizeno。因为该配置和dockerrun中的d参数冲突,会导致容器一直启动失败daemonizeno开启redis数据持久化,(可选)appendonlyyesAOF文件比上次文件增长超过多少百分比则触发重写autoaofrewritepercentage100AOF文件体积最小多大以上才触发重写autoaofrewriteminsize64mb
即最后的配置文件为:启动docker容器:(因为要使用自定义的配置文件,所以需要指定容器运行的命令为redisserver容器内配置文件路径)dockerrunrestartalwayslogoptmaxsize100mlogoptmaxfile2dp6379:6379nameredisprivilegedtruevappredisconfredis。conf:etcredisredis。confvappredisdata:dataredis:6。0。8redisserveretcredisredis。conf11Docket部署Tomcat部署Tomcat搜索tomcat镜像dockersearchtomcat拉取tomcat镜像dockerpulltomcat创建容器,设置端口映射、目录映射在root目录下创建tomcat目录用于存储tomcat数据信息mkdirtomcatcdtomcatmkdirtest存放测试访问的静态文件dockerrunidnamectomcatp8080:8080vapptomcat:usrlocaltomcatwebappstomcat参数说明:p8080:8080:将容器的8080端口映射到主机的8080端口vapptomcat:usrlocaltomcatwebapps:将主机中当前目录挂载到容器的webapps使用外部机器访问tomcat
12Docker部署Nginx部署Nginx搜索nginx镜像dockersearchnginx拉取nginx镜像dockerpullnginx创建容器,设置端口映射、目录映射在root目录下创建nginx目录用于存储nginx数据信息mkdirnginxcdnginxmkdirhtml在该文件夹下放置一个静态网页用于访问mkdirconfcdconf在nginxconf下创建nginx。conf文件,粘贴下面内容vimnginx。confusernginx;workerprocesses1;errorlogvarlognginxerror。logwarn;pidvarrunnginx。pid;events{workerconnections1024;}http{includeetcnginxmime。types;defaulttypeapplicationoctetstream;logformatmainremoteaddrremoteuser〔timelocal〕requeststatusbodybytessenthttprefererhttpuseragenthttpxforwardedfor;accesslogvarlognginxaccess。logmain;sendfileon;tcpnopushon;keepalivetimeout65;gzipon;includeetcnginxconf。d。conf;}dockerrunidnamecnginxp80:80vappnginxconfnginx。conf:etcnginxnginx。confvappnginxlogs:varlognginxvappnginxhtml:usrsharenginxhtmlnginx参数说明:p80:80:将容器的80端口映射到宿主机的80端口。vappnginxconfnginx。conf:etcnginxnginx。conf:将主机当前目录下的confnginx。conf挂载到容器的:etcnginxnginx。conf。配置目录vappnginxlogs:varlognginx:将主机当前目录下的logs目录挂载到容器的varlognginx。日志目录使用外部机器访问nginx
反向代理端口号先复制对应的配置文件dockercpe00ecb2c204f:appnginxconfdefault。confetcnginxconf。ddefault。conf然后修改对应的配置文件,增加代理地址
locationnacos{proxypasshttp:43。138。107。173:8848nacos;}启动Nginx并访问dockerrunidnamenginxp80:80vappnginxconfnginx。conf:etcnginxnginx。confvappnginxconfdefault。conf:etcnginxconf。ddefault。confvappnginxlogs:varlognginxvappnginxhtml:usrsharenginxhtmlnginx
配置证书将证书文件放在指定目录下
编写配置文件server{SSL默认访问端口号为443listen443ssl;请填写绑定证书的域名servernamecoolpanda。tech;请填写证书文件的相对路径或绝对路径sslcertificateetcnginxsslcoolpanda。techbundle。crt;请填写私钥文件的相对路径或绝对路径sslcertificatekeyetcnginxsslcoolpanda。tech。key;sslsessiontimeout5m;请按照以下套件配置,配置加密套件,写法遵循openssl标准。sslciphersECDHERSAAES128GCMSHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;请按照以下协议配置sslprotocolsTLSv1。2TLSv1。3;sslpreferservercipherson;location{网站主页路径。此路径仅供参考,具体请您按照实际目录操作。例如,您的网站主页在Nginx服务器的etcwww目录下,则请修改root后面的html为etcwww。roothtml;indexindex。htmlindex。htm;}locationnacos{proxypasshttp:43。138。107。173:8848nacos;}locationfdfs{proxypasshttp:43。138。107。173:8888;}locationmq{proxypasshttp:43。138。107。173:15672;}}server{listen80;请填写绑定证书的域名servernamecoolpanda。tech;把http的域名请求转成httpsreturn301https:hostrequesturi;}启动Nginx并访问dockerrunidnamenginxp80:80p443:443vappnginxssl:etcnginxsslvappnginxconfnginx。conf:etcnginxnginx。confvappnginxconfdefault。conf:etcnginxconf。ddefault。confvappnginxlogs:varlognginxvappnginxhtml:usrsharenginxhtmlnginx:latest
13Dockerfile
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
构建步骤:dockerbuilddockerrun构建过程
Dockerfile编写:
Docker引擎执行Docker的大致流程:dockercommitDockerfile保留字Dockerfile
关键字
作用
备注
FROM
指定父镜像
指定dockerfile基于那个image构建
MAINTAINER
作者信息
用来标明这个dockerfile谁写的
LABEL
标签
用来标明dockerfile的标签可以使用Label代替Maintainer最终都是在dockerimage基本信息中可以查看
RUN
执行命令
执行一段命令默认是binsh格式:RUNcommand或者RUN〔command,param1,param2〕
CMD
容器启动命令
提供启动容器时候的默认命令和ENTRYPOINT配合使用。格式CMDcommandparam1param2或者CMD〔command,param1,param2〕
ENTRYPOINT
入口
一般在制作一些执行就关闭的容器中会使用
COPY
复制文件
build的时候复制文件到image中
ADD
添加文件
build的时候添加文件到image中不仅仅局限于当前build上下文可以来源于远程服务
ENV
环境变量
指定build时候的环境变量可以在启动的容器的时候通过e覆盖格式ENVnamevalue
ARG
构建参数
构建参数只在构建的时候使用的参数如果有ENV那么ENV的相同名字的值始终覆盖arg的参数
VOLUME
定义外部可以挂载的数据卷
指定build的image那些目录可以启动的时候挂载到文件系统中启动容器的时候使用v绑定格式VOLUME〔目录〕
EXPOSE
暴露端口
定义容器运行的时候监听的端口启动容器的使用p来绑定暴露端口格式:EXPOSE8080或者EXPOSE8080udp
WORKDIR
工作目录
指定容器内部的工作目录如果没有创建则自动创建如果指定使用的是绝对地址如果不是开头那么是在上一条workdir的路径的相对路径
USER
指定执行用户
指定build或者启动的时候用户在RUNCMDENTRYPONT执行的时候的用户
HEALTHCHECK
健康检查
指定监测当前容器的健康监测的命令基本上没用因为很多时候应用本身有健康监测机制
ONBUILD
触发器
当存在ONBUILD关键字的镜像作为基础镜像的时候当执行FROM完成之后会执行ONBUILD的命令但是不影响当前镜像用处也不怎么大
STOPSIGNAL
发送信号量到宿主机
该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL
指定执行脚本的shell
指定RUNCMDENTRYPOINT执行命令的时候使用的shell
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板。Dockerfile第一条必须是FROMFROM镜像名FROMhub。c。163。comlibrarytomcatMAINTAINER
镜像维护者的姓名和邮箱地址非必须MAINTAINERZhangSanzs163。com
容器构建时需要运行的命令。
有两种格式:shell格式等同于在终端操作的shell命令格式:RUN命令行命令RUNyumyinstallvimexec格式格式:RUN〔可执行文件,参数1,参数2〕RUN〔。test。php,dev,offline〕等价于RUN。test。phpdevoffline
RUN是在dockerbuild时运行
当前容器对外暴露出的端口。EXPOSE要暴露的端口EXPOSEport〔protocol〕。。。。EXPOSE330633060WORKDIR
指定在创建容器后,终端默认登录进来的工作目录。ENVCATALINAHOMEusrlocaltomcatWORKDIRCATALINAHOMEUSER
指定该镜像以什么样的用户去执行,如果不指定,默认是root。(一般不修改该配置)USERuser〔:group〕USERpatrick
用来在构建镜像过程中设置环境变量。
这个环境变量可以在后续的任何RUN指令或其他指令中使用格式ENV环境变量名环境变量值或者ENV环境变量名值ENVMYPATHusrmytest使用环境变量WORKDIRMYPATH
容器数据卷,用于数据保存和持久化工作。类似于dockerrun的v参数。VOLUME挂载点挂载点可以是一个路径,也可以是数组(数组中的每一项必须用双引号)VOLUMEvarlibmysql
将宿主机目录下(或远程文件)的文件拷贝进镜像,且会自动处理URL和解压tar压缩包。COPY
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中源路径的文件目录复制到新的一层镜像内的目标路径位置。COPYsrcdestCOPY〔src,dest〕src源路径:源文件或者源目录dest目标路径:容器内的指定路径,该路径不用事先建好。如果不存在会自动创建
指定容器启动后要干的事情。
有两种格式:shell格式CMD命令CMDechohelloworldexec格式CMD〔可执行文件,参数1,参数2。。。〕CMD〔catalina。sh,run〕参数列表格式CMD〔参数1,参数2。。。。〕,与ENTRYPOINT指令配合使用
Dockerfile中如果出现多个CMD指令,只有最后一个生效。CMD会被dockerrun之后的参数替换。
例如,对于tomcat镜像,执行以下命令会有不同的效果:因为tomcat的Dockerfile中指定了CMD〔catalina。sh,run〕所以直接dockerrun时,容器启动后会自动执行catalina。shrundockerrunitp8080:8080tomcat指定容器启动后执行binbash此时指定的binbash会覆盖掉Dockerfile中指定的CMD〔catalina。sh,run〕dockerrunitp8080:8080tomcatbinbash
CMD是在dockerrun时运行,而RUN是在dockerbuild时运行。ENTRYPOINT
用来指定一个容器启动时要运行的命令。
类似于CMD命令,但是ENTRYPOINT不会被dockerrun后面的命令覆盖,这些命令参数会被当做参数送给ENTRYPOINT指令指定的程序。
ENTRYPOINT可以和CMD一起用,一般是可变参数才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。
当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行期命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令,它们两个组合会变成。
例如:FROMnginxENTRYPOINT〔nginx,c〕定参CMD〔etcnginxnginx。conf〕变参
对于此Dockerfile,构建成镜像nginx:test后,如果执行;dockerrunnginxtest,则容器启动后,会执行nginxcetcnginxnginx。confdockerrunnginx:testappnginxnew。conf,则容器启动后,会执行nginxcappnginxnew。conf构建镜像
创建名称为Dockerfile的文件,示例:FROMubuntuMAINTAINERleeleexxx。comENVMYPATHusrlocalWORKDIRMYPATHRUNaptgetupdateRUNaptgetinstallnettoolsEXPOSE80CMDechoMYPATHCMDechoinstallifconfigcmdintoubuntusuccess。。。。。CMDbinbash
编写完成之后,将其构建成docker镜像。
命令:注意:定义的TAG后面有个空格,空格后面有个点dockerbuildt新镜像名字:TAG。dockerbuildtubuntu:1。0。1。虚悬镜像
虚悬镜像:仓库名、标签名都是的镜像,称为danglingimages(虚悬镜像)。
在构建或者删除镜像时可能由于一些错误导致出现虚悬镜像。
例如:构建时候没有镜像名、tagdockerbuild。
列出docker中的虚悬镜像:dockerimagelsfdanglingtrue
虚悬镜像一般是因为一些错误而出现的,没有存在价值,可以删除:删除所有的虚悬镜像dockerimageprune14Docker发布微服务发布微服务项目到Docker容器将项目jar包上传到服务器编写DockerfileFROMjava:8MAINTAINERlyqliuyanqiang98163。com在主机varlibdocker目录下创建一个临时文件,并链接到容器的tmpVOLUMEtmp将jar包添加到容器中,并命名为springbootdocker。jarADDspringboothello0。0。1SNAPSHOT。jarspringbootdocker。jar运行jar包RUNbashctouchspringbootdocker。jarENTRYPOINT〔java,jar,springbootdocker。jar〕SpringBoot项目配置的端口号为8080,需要将8080暴露出去EXPOSE8080构建镜像dockerbuildfspringbootdockerfiletspringbootdocker:1。0。启动容器:dockerrundp9000:8080namespringbootspringbootdocker:1。015Docker网络
docker安装并启动服务后,会在宿主机中添加一个虚拟网卡。
在Docker服务启动前,使用ifconfig或ipaddr查看网卡信息:ens33或eth0:本机网卡lo:本机回环网络网卡可能有virbr0(CentOS安装时如果选择的有相关虚拟化服务,就会多一个以网桥连接的私网地址的virbr0网卡,作用是为连接虚拟网卡提供NAT访问外网的功能。如果要移除该服务,可以使用yumremovelibvirtlibs。x8664)
使用systemctlstartdocker启动Docker服务后,会多出一个docker0网卡。
作用:容器间的互联和通信以及端口映射容器IP变动时候可以通过服务名直接网络通信而不受到影响
Docker容器的网络隔离,是通过Linux内核特性namespace和cgroup实现的。docker网络命令
查看Docker网络模式:dockernetworkls
如果没有修改过dockernetwork,则默认有3个网络模式:bridgehostnone
添加Docker网络:dockernetworkaddxxx
删除Docker网络:dockernetworkrmxxx
查看网络元数据:dockernetworkinspectxxx
删除所有无效的网络:dockernetworkpruneDocker网络模式
Docker的网络模式:
网络模式
简介
使用方式
bridge
为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,默认为该模式
networkbridge
host
容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口
networkhost
none
容器有独立的Networknamespace,但并没有对齐进行任何网络设置,如分配vethpari和网桥连接、IP等
networknone
container
新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等
networkcontainer:NAME或者容器ID
查看某个容器的网络模式:通过inspect获取容器信息,最后20行即为容器的网络模式信息dockerinspect容器IDtailn20docker0
Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥互相通信。
查看bridge网络的详细信息,并通过grep获取名称:dockernetworkinspectbridgegrepname
可以看到其名称为docker0。bridge模式
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为ContainerIP,同时Docker网桥是每个容器的默认网关。因为在同一个宿主机内的容器接入同一个网桥,这样容器之间就能够通过容器的ContainerIP直接通信。
dockerrun的时候,没有指定network的话,默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig就苦役看到docker0和自己create的network。
网桥docker0创建一对对等虚拟设备接口,一个叫veth,另一个叫eth0,成对匹配:
整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫做vethpair)。
每个容器实例内部也有一块网卡,容器内的网卡接口叫做eth0。
docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
例如:
启动tomcat容器,进入tomcat容器后,执行ipaddr,可以看到其网卡信息:1:lo。。。。。。。。。。。。。。。。。。容器内的网卡为eth0符号后面就是宿主机上对应的veth网卡的编号2827:eth0if28。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
在宿主机执行ipaddr查看宿主机网卡信息:每个veth都有个编号:vethXXXXXX符号后面对应就是容器内的eth0网卡编号2728:vethXXXXXXif27。。。。。。。。。。。。。。。。host模式
直接使用宿主机的IP地址与外界进行通信,不再需要额外进行NAT转换。
容器将不会获得一个独立的NetworkNamespace,而是和宿主机共用一个Networkspace。
容器将不会虚拟出自己的网卡,而是直接使用宿主机的IP和端口。
如果在dockerrun命令中同时使用了networkhost和p端口映射,例如:dockerrunp8082:8080networkhosttomcat
那么会出现一个警告:WARNING:Publishedportsarediscardedwhenusinghostnetworkmode
因为此时已经使用了host模式,本身就是直接使用的宿主机的IP和端口,此时的p端口映射就没有了意义,也不会生效,端口号还是会以主机端口号为主。
正确做法是:不再进行p端口映射,或者改用bridge模式none模式
禁用网络功能。
在none模式下,并不为docker容器进行任何网络配置。进入容器内,使用ipaddr查看网卡信息,只能看到lo(本地回环网络127。0。0。1网卡)。container模式
新建的容器和已经存在的一个容器共享网络IP配置,而不是和宿主机共享。
新创建的容器不会创建自己的网卡、IP,而是和一个指定的容器共享IP、端口范围。两个容器除了网络共享,其他的如文件系统、进程列表依然是隔离的。
示例:dockerrunitnamealpine1alpinebinsh指定和alpine1容器共享网络dockerrunitnetrowkcontainer:alpine1namealpine2alpinebinsh
此时使用ipaddr查看两台容器的网络,会发现两台容器的eth0网卡内的IP等信息完全相同。
如果关掉了alpine1容器,因为alpine2的网络使用的alpine1共享网络,所以关掉alpin1后,alpine2的eth0网卡也随之消失了。自定义网络
容器间的互联和通信以及端口映射。
容器IP变动时候可以通过服务名直接网络通信而不受影响。(类似Eureka,通过服务名直接互相通信,而不是写死IP地址)。
docker中还有一个link进行容器网络互联,但是已经被标记为过时的,可能会在将来的版本中移除这个功能。推荐使用自定义网络替换link。
自定义桥接网络(自定义网络默认使用的是桥接网络bridge):新建自定义网络dockernetworkcreatetomcatnetwork查看网络列表dockernetworkls创建容器时,指定加入我们自定义的网络中dockerrundp8081:8080networktomcatnetworknametomcat1tomcat:8。5jdk8correttodockerrundp8082:8080networktomcatnetworknametomcat2tomcat:8。5jdk8corretto此时进入tomcat1中,使用ping命令测试连接tomcat2容器名,发现可以正常连通安装ifconfig命令yuminstallynettools安装ipaddr命令yuminstallyiproute安装ping命令yuminstallyiputils直接ping容器名,不需要pingIP地址pingtomcat2link连接
示例:启动一台mysql容器name为容器指定一个别名dockerrunnamemysqlmatomop3308:3306eMYSQLROOTPASSWORDrootdmysql:8。0。28启动另一个容器,通过link连接到mysql容器link容器名称:本容器连接对方时的别名dockerrundp8888:80linkmysqlmatomo:dbnamematomomatomo:4。9。0此时,在matomo容器中,便可以通过db这个hostname连接到mysqlmatomo容器,而无须再通过ip连接地址:db:330616Dockercompose容器编排Dockercompose
DockerCompose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。
DockerCompose可以管理多个Docker容器组成一个应用。需要定义一个yaml格式的配置文件dockercompose。yml,配置好多个容器之间的调用关系,然后只需要一个命令就能同时启动关闭这些容器。
Docker建议我们每个容器中只运行一个服务,因为Docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来。但是如果我们需要同时部署多个服务,每个服务单独构建镜像构建容器就会比较麻烦。所以Docker官方推出了dockercompose多服务部署的工具。
Compose允许用户通过一个单独的dockercompose。yml模板文件来定义一组相关联的应用容器为一个项目(project)。可以很容易的用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。
核心概念:服务(service):一个个应用容器实例工程(project):由一组关联的应用容器组成的一个完整业务单元,在dockercompose。yml中定义
Compose使用的三个步骤:dockercompose。ymldockercomposeup安装DockerCompose
DockerCompose的版本需要和Docker引擎版本对应,可以参照官网上的对应关系。
安装Compose:例如从github下载2。5。0版本的dockercompose下载下来的文件放到usrlocalbin目录下,命名为dockercomposecurlLhttps:github。comdockercomposereleasesdownloadv2。5。0dockercompose(unames)(unamem)ousrlocalbindockercompose添加权限chmodxusrlocalbindockercompose验证dockercomposeversion
卸载Compose:直接删除usrlocalbindockercompose文件即可常用命令
执行命令时,需要在对应的dockercompose。yml文件所在目录下执行。
查看帮助:dockercomposeh
创建并启动dockercompose服务:(类似dockerrun)dockercomposeup后台运行dockercomposeupd
停止并删除容器、网络、卷、镜像:(类似dockerstopdockerrm)dockercomposedown
进入容器实例内部:dockercomposeexecyml里面的服务idbinbash
展示当前dockercompose编排过的运行的所有容器:dockercomposeps
展示当前dockercompose编排过的容器进程:dockercomposetop
查看容器输出日志:dockercomposelogyml里面的服务id
检查配置:dockercomposeconfig有问题才输出dockercomposeconfigq
重启服务:dockercomposerestart
启动服务:(类似dockerstart)dockercomposestart
停止服务:dockercomposestopcompose编排实例
示例:dockercompose文件版本号version:3配置各个容器服务services:microService:image:springbootdocker:1。0containername:ms01容器名称,如果不指定,会生成一个服务名加上前缀的容器名ports:6001:6001volumes:appmicroService:datanetworks:springbootnetworkdependson:配置该容器服务所依赖的容器服务redismysqlredis:image:redis:6。0。8ports:6379:6379volumes:appredisredis。conf:etcredisredis。confappredisdata:datanetworks:springbootnetworkcommand:redisserveretcredisredis。confmysql:image:mysql:5。7environment:MYSQLROOTPASSWORD:123456MYSQLALLOWEMPTYPASSWORD:noMYSQLDATABASE:dbspringbootMYSQLUSER:springbootMYSQLPASSWORD:springbootports:3306:3306volumes:appmysqldb:varlibmysqlappmysqlconfmy。cnf:etcmy。cnfappmysqlinit:dockerentrypointinitdb。dnetworks:springbootnetworkcommand:defaultauthenticationpluginmysqlnativepassword解决外部无法访问networks:创建springbootnetwork网桥网络springbootnetwork:
编写完成dockercompose。yml后,进行语法检查:进行语法检查dockercomposeconfigq
如果语法检查没有任何问题,进行创建、启动:dockercomposeupd17Portainer轻量级图形化监控Portainer:Docker轻量级可视化工具
Portainer是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。
Portainer分为开源社区版(CE版)和商用版(BE版EE版)。
Portainer也是一个Docker镜像,可以直接使用Docker运行。旧版镜像地址为portainerportainer,从2022年1月标记为过期新版镜像地址为portainerportainercerestartalways如果Docker引擎重启了,那么这个容器实例也会在Docker引擎重启后重启,类似开机自启dockerrundp8000:8000p9000:9000nameportainerrestartalwaysvvarrundocker。sock:varrundocker。sockvportainerdata:dataportainerportainerce:2。13。0alpine
启动之后,便可以在浏览器中进行访问:http:xxx。xxx。xxx。xxx:9000
首次进来时,需要创建admin的用户名(默认admin)、密码(必须满足校验规则,例如portainer。io123)。
选择local管理本地docker,即可看到本地Docker的详细信息,包括其中的镜像(images)、容器(containers)、网络(networks)、容器卷(volumes)、compose编排(stacks)等等。18CIG重量级监控
通过dockerstats命令可以很方便的查看当前宿主机上所有容器的CPU、内存、网络流量等数据,可以满足一些小型应用。
但是dockerstats统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有健康指标过线预警等功能。
CAdvisor(监控收集)InfluxDB(存储数据)Granfana(展示图表),合称CIG。
CAdvisor
CAdvisor是一个容器资源监控工具,包括容器的内存、CPU、网络IO、磁盘IO等监控,同时提供了一个Web页面用于查看容器的实时运行状态。
CAdvisor默认存储2分钟的数据,而且只是针对单物理机。不过CAdvisor提供了很多数据集成接口,支持InfluxDB、Redis、Kafka、Elasticsearch等集成,可以加上对应配置将监控数据发往这些数据库存储起来。
CAdvisor主要功能:展示Host和容器两个层次的监控数据展示历史变化数据InfluxDB
InfluxDB是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。
CAdvisor默认只在本机保存2分钟的数据,为了持久化存储数据和统一收集展示监控数据,需要将数据存储到InfluxDB中。InfluxDB是一个时序数据库,专门用于存储时序相关数据,很适合存储CAdvisor的数据。而且CAdvisor本身已经提供了InfluxDB的集成方法,在启动容器时指定配置即可。
InfluxDB主要功能:基于时间序列,支持与时间有关的相关函数(如最大、最小、求和等)可度量性,可以实时对大量数据进行计算基于事件,支持任意的事件数据Granfana
Grafana是一个开源的数据监控分析可视化平台,支持多种数据源配置(支持的数据源包括InfluxDB、MySQL、Elasticsearch、OpenTSDB、Graphite等)和丰富的插件及模板功能,支持图表权限控制和报警。
Granfana主要功能:灵活丰富的图形化选项可以混合多种风格支持白天和夜间模式多个数据源安装部署编写dockercompose。yml服务编排文件version:3。1volumes:grafanadata:{}services:influxdb:tutuminfluxdb相比influxdb多了web可视化视图。但是该镜像已被标记为已过时image:tutuminfluxdb:0。9restart:alwaysenvironment:PRECREATEDBcadvisorports:8083:8083数据库web可视化页面端口8086:8086数据库端口volumes:。datainfluxdb:datacadvisor:image:googlecadvisor:v0。32。0links:influxdb:influxsrvcommand:storagedriverinfluxdbstoragedriverdbcadvisorstoragedriverhostinfluxsrv:8086restart:alwaysports:8080:8080volumes::rootfs:rovarrun:varrun:rwsys:sys:rovarlibdocker:varlibdocker:rografana:image:grafanagrafana:8。5。2user:104restart:alwayslinks:influxdb:influxsrvports:3000:3000volumes:grafanadata:varlibgrafanaenvironment:HTTPUSERadminHTTPPASSadminINFLUXDBHOSTinfluxsrvINFLUXDBPORT8086检查语法dockercomposeconfigq创建并启动容器dockercomposeupd
容器启动之后:在浏览器打开InfluxDB数据库的页面:http:xxx。xxx。xxx。xxx:8083,使用命令查看当前数据库中的数据库实例:SHOWDATABASES
查看其中是否自动创建了我们在配置文件中配置的cadvisor数据库实例在浏览器打开CAdvisor页面:http:xxx。xxx。xxx。xxx8080,查看当前docker中的cpu、内存、网络IO等统计信息在浏览器打开Grafana页面:http:xxx。xxx。xxx。xxx:3000,默认用户名密码是:adminadmin。Grafana配置添加数据源
在Configuration(小齿轮)选项卡中,选择DataSources,添加一个InfluxDB数据源:InfluxDBInfluxQLhttp:influxdb:8086cadvisorrootroot
保存并测试,可以连通即可添加工作台在Create(加号)选项卡中,选择创建DashBoard工作台。右上角配置中可以配置创建出来的工作台的标题、文件夹等信息。在创建出来的工作台中,选择Addpanel中的Addanewpanel添加一个新的面板。Timeseriescpuusagetotalcontainernamecigcadvisor1
CAdvisor主要功能:展示Host和容器两个层次的监控数据展示历史变化数据InfluxDB
InfluxDB是用Go语言编写的一个开源分布式时序、事件和指标数据库,无需外部依赖。
CAdvisor默认只在本机保存2分钟的数据,为了持久化存储数据和统一收集展示监控数据,需要将数据存储到InfluxDB中。InfluxDB是一个时序数据库,专门用于存储时序相关数据,很适合存储CAdvisor的数据。而且CAdvisor本身已经提供了InfluxDB的集成方法,在启动容器时指定配置即可。
InfluxDB主要功能:基于时间序列,支持与时间有关的相关函数(如最大、最小、求和等)可度量性,可以实时对大量数据进行计算基于事件,支持任意的事件数据Granfana
Grafana是一个开源的数据监控分析可视化平台,支持多种数据源配置(支持的数据源包括InfluxDB、MySQL、Elasticsearch、OpenTSDB、Graphite等)和丰富的插件及模板功能,支持图表权限控制和报警。
Granfana主要功能:灵活丰富的图形化选项可以混合多种风格支持白天和夜间模式多个数据源安装部署编写dockercompose。yml服务编排文件version:3。1volumes:grafanadata:{}services:influxdb:tutuminfluxdb相比influxdb多了web可视化视图。但是该镜像已被标记为已过时image:tutuminfluxdb:0。9restart:alwaysenvironment:PRECREATEDBcadvisorports:8083:8083数据库web可视化页面端口8086:8086数据库端口volumes:。datainfluxdb:datacadvisor:image:googlecadvisor:v0。32。0links:influxdb:influxsrvcommand:storagedriverinfluxdbstoragedriverdbcadvisorstoragedriverhostinfluxsrv:8086restart:alwaysports:8080:8080volumes::rootfs:rovarrun:varrun:rwsys:sys:rovarlibdocker:varlibdocker:rografana:image:grafanagrafana:8。5。2user:104restart:alwayslinks:influxdb:influxsrvports:3000:3000volumes:grafanadata:varlibgrafanaenvironment:HTTPUSERadminHTTPPASSadminINFLUXDBHOSTinfluxsrvINFLUXDBPORT8086检查语法dockercomposeconfigq创建并启动容器dockercomposeupd
容器启动之后:在浏览器打开InfluxDB数据库的页面:http:xxx。xxx。xxx。xxx:8083,使用命令查看当前数据库中的数据库实例:SHOWDATABASES
查看其中是否自动创建了我们在配置文件中配置的cadvisor数据库实例在浏览器打开CAdvisor页面:http:xxx。xxx。xxx。xxx8080,查看当前docker中的cpu、内存、网络IO等统计信息在浏览器打开Grafana页面:http:xxx。xxx。xxx。xxx:3000,默认用户名密码是:adminadmin。Grafana配置添加数据源
在Configuration(小齿轮)选项卡中,选择DataSources,添加一个InfluxDB数据源:InfluxDBInfluxQLhttp:influxdb:8086cadvisorrootroot
保存并测试,可以连通即可添加工作台在Create(加号)选项卡中,选择创建DashBoard工作台。右上角配置中可以配置创建出来的工作台的标题、文件夹等信息。在创建出来的工作台中,选择Addpanel中的Addanewpanel添加一个新的面板。Timeseriescpuusagetotalcontainernamecigcadvisor1CPU使用情况汇总原文链接:https:blog。csdn。netweixin44684272articledetails126873963?utmsourcetuicoolutmmediumreferral