写在前面笔记内容:由理论和具体docker常用操作构成。 你拥有青春的时候,就要感受它,不要虚掷你的黄金时代,不要去倾听枯燥乏味的东西,不要设法挽留无望的失败,不要把你的生命献给无知,平庸和低俗。王尔德一、docker原理docker是什么? Docker是完整的一套容器管理系统,所以想要搞懂Docker的概念,我们必须先从容器开始说 起。什么是容器?容器是用来装东西的(类似运行的启动盘),Linux里面的容器是用来装应用的;容器就是将软件打包成标准化单元,以用于开发、交付和部署;容器技术已经成为应用程序封装和交付的核心技术;容器原理 容器技术的核心,由以下几个内核技术组成:Cgroups(ControlGroups)资源管理SELinux安全(是针对于文件系统,文件的管理措施)NameSpace命名空间是指可以对系统资源空间进行分割隔离的技术,例如:创建一个虚拟机,在虚拟机里的所有操 作,都不会对真实机造成影响。命名空间分为六大类,可以从各个方面来对系统资源空间进行隔离;Linux的NameSpaceUTS:主机名命名空间,作用:分割主机名,即在容器内修改主机名,不会对宿主机的系统造成影响,实现主机名的隔离;NETWORK:网络命名空间,作用:分割网络,即容器内的网络配置和宿主机相互之间不受干扰的;例如在真实机器上的网卡名为eth0,IP地址为192。168。1。1024;而在容器内的网卡名可以为ens33,ip地址为10。10。10。1024;MOUNT:挂载命名空间,作用:隔离文件系统,在容器内挂载的光盘或nfs共享目录,宿主机是无法看到里面的内 容的;例如:在linux系统上,创建一个虚拟机,在真机的varlibftp中挂载了一个光盘文件,但是在虚拟机的varlibftp中是没有光盘内容的,这就是MOUNT隔离;USER:用户命名空间,作用:隔离用户,即容器内创建的用户不能用于登录宿主机,真机机里创建的用户也不能 作用于容器;PID:进程命名空间,作用:为了防止容器和宿主机中的进程冲突;例如:在真实机中,有一个服务:nfs,PID为2250;在容器内,也有一个服务:chrony,PID为2250;真实机中用户,杀死(kill)PID号为2250的进程时,并不会对容器内的进程2250产生影响;而容器内的用户,杀死(kill)PID号为2250的进程时,也并不会对真实机内的进程2250产生影响;IPC:信号向量命名空间,作用:通常和PID一起使用;用户杀死一个进程时,实际上是向进程发送一个信号(IPC),进程接收到这个信号后会执行对应的操作;docker的特性docker的优缺点优点:相比于传统的虚拟化技术,容器更加简洁高效,传统虚拟机需要给每个VM安装操作系统,容器使用的共享公共库和程序缺点:容器的隔离性没有虚拟机强共用Linux内核,安全性有先天缺陷。docker的特点docker与传统虚拟化的对比:虚拟化:例如:虚拟机的使用,每一个虚拟机都要安装独立的操作系统;将一台服务器转变为多台服务器的物理硬件的抽象。系统管理程序允许多个VM在单台计算机上运行。每个VM包含操作系统,应用程序,必要的二进制文件和库的完整副本占用数十GB。VM也可能启动缓慢。容器:不需要安装独立的操作系统,只有一个Docker进程,和宿主机共享操作系统;容器没有操作系统,启动容器就跟开启一个进程一样,简单高效;是应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行,并与其他容器共享OS内核,每个容器在用户空间中作为隔离的进程运行。容器占用的空间少于VM(容器映像的大小通常为几十MB),可以处理更多的应用程序,并且需要的VM和操作系统更少。运行区别(容器的高效性):启动虚拟机中的应用程序,需要先启动虚拟机的操作系统,然后再启动应用程序;启动容器内的应用程序,直接启动应用程序即可;二、docker安装部署docker安装安装条件需要64位操作系统,至少RHEL6。5以上的版本,强烈推荐RHEL7docker安装时,内核要求在3。0以上,RHEL7的内核默认在3。0以上,不满足可以单独升级系统内核。 查看linux系统的内核版本,【unamer】也可以关闭防火墙(不是必须):firewalld【RHEL7使用】,Iptables【RHEL6使用】,Docker安装时,会自动的接管防火墙,并向防火墙里添加配置,如果防火墙存在,会产生冲突。源配置配置yum源在物理机的http目录下创建文件夹extras:mkdirvarwwwhtmlextras把光盘挂到这个目录下:mounttiso9660oro,loopRHEL70OSPextras。isovarwwwhtmlextrasdocker安装卸载防火墙yumremoveyfirewalld安装软件包yuminstalldocker开启路由转发etcsysctl。confnet。ipv4。ipforward1使用sysctlp让配置立刻生效(否则需要重新虚拟机)docker是通过虚拟交互机来进行通讯的,需要开启路由转发的功能。软件的BUG:iptablesnLFORWARD版本大于1。12时会设置FORWARD的默认规则,被设置为DROP,对于有些docker的版本中,FORWARD链的规则被设置成了DROP,会造成容器和宿主机之间无法通讯。 解决办法:修改libsystemdsystemdocker。server重载配置文件,重启服务systemctldaemonreloadsystemctlrestartdocker〔rootliruilong〕systemctldaemonreload〔rootliruilong〕systemctlrestartdocker三、获取镜像镜像、容器、仓库什么是镜像 镜像是启动容器的核心,在Docker中容器是基于镜像启动的,镜像采用分层设计,使用COW技术容器本身是没有操作系统,和宿主机共用一个操作系统;容器是docker(容器的管理工具)使用镜像文件来启动的;镜像是启动容器的模板,镜像中存放的是应用程序(服务软件),例如:有一个http的镜像文件,在这个镜像中就存放的是http的所有文件和变量;用户使用镜像启动容器时,会生成一个独立于镜像的容器层,并不会对镜像层产生任何影响;而且容器采用了cow(写时复制)的技术,用户可以使用一个镜像文件创建多个容器,互不干扰;镜像采用分层技术:用户可以根据自己的需求来制作镜像,例如:在镜像的第一层定义应用程序的变量,在镜像的第二层修改配置文件,在镜像的第三层进行应用软件的部署;分层做好镜像后,用户使用镜像启动容器时,可以选择根据镜像的哪一层来启动,类似快照还原;容器使用镜像启动 镜像是怎么来的? 镜像可以从官方镜像仓库下载,也可以自己制作官方镜像仓库:https:hub。docker。com查看本机镜像dockerimagesREPOSITORY镜像名称TAG镜像标签IMAGEID镜像ID号CREATED镜像创建时间SIZE镜像大小获取镜像查找镜像:dockersearch关键字dockersearchjdk INDEX索引名称,即网站域名NAME镜像的名称DESCRIPTION镜像的描述信息STARS镜像被下载的次数OFFICIAL是否是docker官方开发的AUTOMATED是否自动构建镜像下载镜像dockerpull镜像名称:标签:dockerpulldocker。iobusybox镜像的备份与恢复备份镜像(导出镜像):dockersave镜像名称:镜像标签o备份文件夹(tar格式)镜像busybox,需要指定名字和标签,导出到root目录下,名称为busybox。tar〔rootkubenode1〕dockersavedocker。iobusybox:latestorootbusybox。tar拷贝备份镜像到其他机器上〔rootkubenode1〕scprootbusybox。tar192。168。1。22:root恢复镜像(导入镜像)dockerloadi备份文件名称dockerloadibusybox。tar四、第一个容器运行容器dockerrun命令dockerrun参数镜像名称:镜像标签启动命令镜像名称:镜像标签这种形式,可以指定唯一的镜像,防止镜像名相同,内容不同的情况,latest为默认标签,创建镜像时,不指定标签,则为此默认标签 run创建启动进入,dockerrun命令:运行过程中,会先根据镜像来创建容器,然后会启动容器,最后进入容器帮助文档:查看run的参数:dockerhelprunmandockerrun参数:i交互式,t终端,d后台运行,name容器名字:dockerrunitdocker。iocentos:lasestbinbash(binbash为容器内的命令,容器内存在,才可以使用)五、docker镜像管理镜像管理命令查看镜像:dockerimages查找镜像dockersearch删除镜像dockerrmi镜像名称:镜像标签dockerimagermfd1c5f7b6816下载镜像dockerpull镜像名称:镜像标签上传镜像dockerpush要上传的镜像名称:镜像标签备份镜像dockersave镜像名称:镜像标签o备份文件名称恢复镜像dockerloadi备份文件名称查看镜像的制作历史dockerhistory镜像名称:镜像标签查看镜像的信息dockerinspect镜像名称:镜像标签镜像的新名称和标签dockertag镜像名称:镜像标签新镜像名称:新的标签六、docker容器管理常用容器管理命令启动容器dockerrun参数镜像名称:镜像标签启动命令查看容器dockerps〔a所有容器id〕〔q只显示容器id〕删除容器dockerrm容器id、容器管理启动dockerstart容器id容器管理停止dockerstop容器id容器管理重启dockerrestart容器id查看容器进程dockertop容器id查看容器信息dockerinspect容器id连接容器启动进程dockerattach容器idattach以上帝进程的身份,进入容器内部,使用attach进入容器,是上帝进程的身份进入容器的,当执行exit退出容器时,会结束整个容器,查看进程树,systemd就是上帝进程,即:系统服务的最初进程,所有的进程都是在上帝进程下创建的;当systemd进程被结束时,整个系统也就会崩溃通常用于在测试时,查看报错信息;连接容器,启动新进程dockerexecit容器id命令在对容器的使用过程中,都是使用exec,新开一个进程的方式进入容器,进行编辑的;而attach往往应用于调试,终端输出的情况;七,自定义镜像commit自定义镜像 自定义镜像原理:镜像采用分层设计:1,创建读写层2,修改配置3,重新打包 使用镜像启动容器,在该容器基础上修改,另存为一个新镜像dockerrunitdocker。iocentos:latestbinbash配置yum,安装软件,系统配置dockercommit容器id新镜像名称:新镜像标签创建一个centos的容器,在kubenode1上操作查看所有的镜像〔rootkubenode1〕dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEbusyboxtest6858809bf6695weeksago1。232MBdocker。iobusyboxlatest6858809bf6695weeksago1。232MBdocker。ioredislatest82629e941a3821monthsago4。98MBdocker。ionginxlatest42b4762643dc21monthsago109。2MBdocker。ioubuntulatest20bb25d3275821monthsago87。47MBdocker。iocentoslatest76d6bc25b8a52yearsago199。7MBit以交互式终端的方式,根据centos镜像启动一个容器binbash为容器内的命令,容器内存在,才可以使用〔rootkubenode1〕dockerrunitdocker。iocentos:latestbinbashh容器内安装yum,在kubenode1上操作清除网络yum文件,配置本地yum〔rootd76e8f39e026〕rmrfetcyum。repos。d〔rootd76e8f39e026〕vietcyum。repos。dcentos7。repo〔centos〕namecentos7。5baseurlhttp:192。168。1。100centos1804enabled1gpgcheck0清空缓存,重新加载配置〔rootd76e8f39e026〕yumcleanall〔rootd76e8f39e026〕yumrepolist。。。。。。。。Determiningfastestmirrorscentos3。6kB00:00(12):centosgroupgz166kB00:00(22):centosprimarydb5。9MB00:00repoidreponamestatuscentoscentos7。59911repolist:9911容器内安装基础工具软件包,在kubenode1上操作安装基础工具软件包〔rootd76e8f39e026〕yumyinstallnettoolspsmisciproutevimbashcompletiontree清除yum缓存,减小容器大小,用于镜像制作〔rootd76e8f39e026〕yumcleanall退出容器,主机名就是容器的ID号〔rootd76e8f39e026〕exitcommit自定义镜像,在kubenode1上操作commit提交容器,生成新的镜像;此ID为容器的ID号〔rootkubenode1〕dockercommitd76e8f39e026myos:latestsha256:10a665c54e587d47756a00058abef86ef6b329b44937aaea34376482c9410878myos镜像,就是新生成的镜像〔rootkubenode1〕dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEmyoslatest10a665c54e58Aboutaminuteago317。8MB。。。。。。。。使用dockerrun验证新的镜像验证新的镜像,在kubenode1上操作查看历史镜像,多出一个镜像层〔rootkubenode1〕dockerhistorymyos:latestIMAGECREATEDCREATEDBYSIZECOMMENT10a665c54e583minutesagobinbash118。1MB。。。。。。。使用新的镜像生成一个容器,容器的yum已经部署,验证成功〔rootkubenode1〕dockerrunitmyos:latestbinbash〔root5dbc2153d039〕yumrepolistLoadedplugins:fastestmirror,ovlLoadingmirrorspeedsfromcachedhostfilerepoidreponamestatuscentoscentos7。59911repolist:9911Dockerfile自定义镜像 语法FROM:基础镜像RUN:制作镜像时执行的命令,可以有多个ADD:复制文件到镜像,自动解压(文件类型为:tar。gz或tar。bz2)COPY:复制文件到镜像,不解压MAINTAINER:镜像创建者信息EXPOSE:开放的端口ENV:设置变量WORKDIR:定义容器默认工作目录CMD:容器启动时执行的命令,仅可以有一条CMD。ENTRYPOINT:类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一具单独的可执行程序 与CMD不同的是,由ENTRYPOINT启动的程序不会被dockerrun命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。不过,dockerrun命令的entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序Dockerfile案例1 配置yum、安装软件FROMdocker。iocentos:latestRUNrmfetcyum。repos。dCOPYlocal。repoetcyum。repos。dlocal。repoRUNyuminstallybashcompletionnettoolsiproutepsmisc创建镜像 使用Dockerfile工作流程,根据Dockerfile生成新的镜像,build创建新的镜像;t指定新镜像的名字和标签;。指定Dockerfile文件所在的目录mkdirbuildcdbuild编写Dockerfile获取制作镜像的历史命令,在kubenode1上操作利用myos镜像,创建一个容器,可以查看之前制作镜像的历史命令〔rootkubenode1〕dockerrunitmyos:latestdockerbuildtimagenameDockerfile所在目录〔root096875f0df8d〕history1rmrfetcyum。repos。d2vietcyum。repos。dcentos7。repo3yumcleanall4yumrepolist5yumyinstallnettoolspsmiscvimiproutevimbashcompletionotree6exit7historyexit退出,并关闭容器〔root096875f0df8d〕exit制作Dockerfile自动创建镜像脚本,在kubenode1上操作创建一个目录,名称任意定义〔rootkubenode1〕mkdiraa进入到aa目录下〔rootkubenode1〕cdaa创建Dockerfile文件,文件名不能改变〔rootkubenode1〕touchDockerfile复制repo文件到aa目录下,用户Dockerfile中的文件复制〔rootkubenode1aa〕cpetcyum。repos。dcentos7。repo。编写Dockerfile文件,文件名不能改变Dockerfile中所有的指令,必须是大写的(例如:FROM,RUN,COPY等)FROM指定基础镜像,Dockerfile会对基础镜像进行编辑,生成新的镜像RUN指定制作命令,一条RUN,就代表一条要在容器内执行的命令COPY复制,即把当前目录下的文件,拷贝到容器内〔rootkubenode1aa〕vimDockerfileFROMdocker。iocentos:latestRUNrmrfetcyum。repos。dCOPYcentos7。repoetcyum。repos。dcentos7。repoRUNyumyinstallnettoolspsmiscvimiproutevimbashcompletionotreeyumcleanalldockerbuildtimagenameDockerfile所在目录根据Dockerfile生成新的镜像,在kubenode1上操作build创建新的镜像;t指定新镜像的名字和标签;。指定Dockerfile文件所在的目录〔rootkubenode1aa〕dockerbuildtnewos:latest。SendingbuildcontexttoDockerdaemon3。072kBStep1:FROMdocker。iocentos:latest76d6bc25b8a5Step2:RUNrmrfetcyum。repos。dRunninginade538eaf11ca934f7feea65Removingintermediatecontainerade538eaf11cStep3:COPYcentos7。repoetcyum。repos。dcentos7。repobd5e3914cda6Removingintermediatecontainer80ea3d53088eStep4:RUNyumyinstallnettoolspsmiscvimiproutevimbashcompletionotreeyumcleanall。。。。。。。。查看本地仓库镜像,newos创建成功〔rootkubenode1〕dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEnewoslatestfb3d8579650433minutesago280。8MBmyoslatest10a665c54e5858minutesago317。8MB。。。。。。。八,Dockerfile入门Dockerfile创建服务镜像Dockerfile创建Apache服务案例 Dockfile中,不指定CMD时,则使用默认的启动命令;如果没有使用CMD指定启动命令,则会继承上一个镜像的默认启动命令;CMD容器的默认启动命令,有且只能有一条;FROMmyos:latestMAINTAINERJacobredhat163。comRUNyumyinstallhttpdENVLANGCWORKDIRvarwwwhtmlEXPOSE80443CMD〔httpd,DFOREGROUND〕WORKDIR在Dockerfile中用于定义容器默认工作目录使用ssh远程执行以下三条命令,f1和f2文件,最终都是创建在root目录下因为每次ssh连接都是代表不同的连接,无法保持上次连接时,命令的执行状态〔rootlocalhost〕sshhost1touchf1〔rootlocalhost〕sshhost1cdtmp〔rootlocalhost〕sshhost1touchf2Dockerfile和ssh类似,所以要使用WORKDIR容器默认工作目录的指定在容器内安装并启动apache服务使用myos镜像创建一个容器,在kubenode1上操作查看本地仓库镜像,myos镜像已经部署好了yum和基本软件包〔rootkubenode1〕dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEmyoslatest10a665c54e5858minutesago317。8MB。。。。。。。it以交互式终端的方式,根据centos镜像启动一个容器binbash为容器内的命令,容器内存在,才可以使用,不指定则会选择默认容器命令〔rootkubenode1〕dockerrunitmyos:latestbinbash〔roota670096c60ad〕部署并启动apache服务,在kubenode1上操作安装apache的服务软件httpd〔roota670096c60ad〕yumyinstallhttpd因为容器内并没有systemd的服务,无法使用systemctl来启动httpd的服务查看httpd的服务文件,获取环境变量文件和服务启动命令〔roota670096c60ad〕catlibsystemdsystemhttpd。service。。。。。。。。〔Service〕。。。。。。。。环境变量文件EnvironmentFileetcsysconfighttpd启动命令,OPTIONS此环境变量为空,可以不用写ExecStartusrsbinhttpdOPTIONSDFOREGROUND。。。。。。。。从环境变量文件中,获取环境变量〔roota670096c60ad〕vimetcsysconfighttpd。。。。。。LANGC设置环境变量〔roota670096c60ad〕LANGC启动httpd服务,OPTIONS此环境变量为空,可以不用写CtrlC退出〔root54cb8bfa063d〕usrsbinhttpdDFOREGROUNDAH00558:httpd:Couldnotreliablydeterminetheserversfullyqualifieddomainname,using172。17。0。2。SettheServerNamedirectivegloballytosuppressthismessage编写http的Dockerfile文件制作Dockerfile自动创建镜像脚本,在kubenode1上操作创建一个目录,名称任意定义〔rootkubenode1〕mkdirbb进入到aa目录下〔rootkubenode1〕cdbb创建Dockerfile文件,文件名不能改变〔rootkubenode1〕touchDockerfileDockerfile中所有的指令,必须是大写的(例如:FROM,RUN,COPY等)FROM指定基础镜像,Dockerfile会对基础镜像进行编辑,生成新的镜像MAINTAINER指定创建镜像者的信息RUN指定制作命令,一条RUN,就代表一条要在容器内执行的命令ENV指定环境变量EXPOSE开启httpd服务要使用的端口,80和443WORKDIR指定启动容器后的,默认工作目录ADD指拷贝,Dockerfile目录下的文件,拷贝到容器内(tar。gz,tar。bz2格式会自动解压)CMD指定默认启动命令,格式示例:lsla则:CMD〔ls,l,a〕〔rootkubenode1bb〕vimDockerfileFROMmyos:latestMAINTAINERtarenaRUNyumyinstallhttpdENVLANGCEXPOSE80443WORKDIRvarwwwhtmlADDindex。htmlvarwwwhtmlindex。htmlCMD〔usrsbinhttpd,DFOREGROUND〕创建apache的默认访问页面,在kubenode1上操作〔rootkubenode1bb〕echohelloworldindex。html运行容器 创建服务镜像:dockerbuildtmyos:httpd使用Dockerfile文件,创建新的镜像,在kubenode1上操作build创建新的镜像;t指定新镜像的名字和标签;。指定Dockerfile文件所在的目录〔rootkubenode1bb〕dockerbuildtmyos:httpd。SendingbuildcontexttoDockerdaemon3。072kBStep1:FROMmyos:latest10a665c54e58Step2:RUNyumyinstallhttpdRunninginb3226773e826。。。。。。。 运行容器验证服务dockeerrunitdmyos:httpddockerinspect容器idcurlhttp:ip。xx。xx。xx验证结果验证查看镜像,在kubenode1上操作查看镜像,myos:httpd镜像创建成功〔rootkubenode1〕dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEmyoshttpd019f5b48a5a0Aboutaminuteago372。4MB。。。。。。使用myos:httpd镜像,创建一个容器〔rootkubenode1〕dockerrunitdmyos:httpd800b21aa9736bd68a521e7d5667835710b24829a136c5a0baa3e24cc319d3b70查看正在使用的容器〔rootkubenode1〕dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES800b21aa9736myos:httpdusrsbinhttpdDFOAboutaminuteagoUpAboutaminute80tcp,443tcpreverentthompson查看容器的详细信息〔rootkubenode1〕dockerinspect800b21aa9736。。。。。。。。。。。。。。。。ENV中,PATH指定可执行文件的搜索路径,为命令的默认查找路径如果没有指定PATH,则执行所有命令,都需要指定绝对路径Env:〔PATHusrlocalsbin:usrlocalbin:usrsbin:usrbin:sbin:bin,LANGC〕,Cmd默认的启动命令,即:启动容器时,默认的启动命令Cmd:〔binsh,c,(nop),CMD〔usrsbinhttpdDFOREGROUND〕〕,。。。。。。。。。。。。。。。。Networks:{bridge:{IPAMConfig:null,Links:null,Aliases:null,NetworkID:b0cf7b16b65e272fa685ac975bce1f13647379beb8e22191d6623e30817829bc,EndpointID:f010d043874446d28892fa52903165f7370cccbc7cf449d325ad07c1c58fe6c4,容器的网关和IP地址Gateway:172。17。0。1,IPAddress:172。17。0。2,IPPrefixLen:16,IPv6Gateway:,GlobalIPv6Address:,GlobalIPv6PrefixLen:0,MacAddress:02:42:ac:11:00:02。。。。。。。。。。。。。。。。根据容器的IP地址,访问容器内的httpd服务,在kubenode1上操作访问容器内的apache服务〔rootkubenode1〕curlhttp:172。17。0。2helloworld九、私有仓库安装部署私有仓库创建私有仓库 搭建私有仓库安装私有仓库(服务端)yuminstalldockerdistribution启动私有仓库,并设置开机自启动:systemctlstartdockerdistributionsystemctlenabledockerdistribution私有仓库的配置:仓库配置文件etcdockerdistributionregistryconfig。yml数据存储路径:varlibregistry默认端口号:5000 我们可以通过curl命令访问仓库curlhttp:仓库ip:5000v2使用私有仓库 docker主机修改配置文件etcsysconfigdocker允许非加密方式访问仓库INSECUREREGISTRYinsecureregistry仓库IP:5000docker仓库地址ADDREGISTRYaddregistry仓库IP:5000 重启docker服务systemctlrestartdocker十、外部存储卷卷的用途 Docker容器不保持任何数据,重要数据请使用外部卷存储(数据持久化),容器可以挂在真实机目录或共享存储为卷首先,Docker是一个进程(随着机器的启动而运行,随着机器的停止而消失);然后,所以Docker容器内不适合存放任何的数据,容易丢失;最后,需要对Docker进行数据解耦(把Docker应用和数据存放进行分离);主机卷的映射 将真实机目录挂载到容器中提供持久化存储,目录不存在就自动创建,目录存在就直接覆盖掉,多个容器可以映射同一个目录,来达到数据共享的目的 启动容器时,使用v参数映射卷dockerrunitv真实目录:容器内目录docker。iocentos:latest多主机共享目录 有多台docker主机的情况下,我们也可以使用共享存储,来作为docker的卷服务,可以实现多主机之间多容器的共享卷服务 十一,发布docker服务怎么访问docker服务 默认容器可以访问宿主机,但外部网络的主机不可以访问容器内的资源,解决这个问题的最佳方法是端口绑定,容器可以与宿主机的端口进行绑定,从而把宿主机变成对应的服务。宿主机和容器内部的服务端口绑定以后,用户在访问宿主机的服务端口时,就是在访问容器内部的服务发布docker服务 我们使用p参数把容器端口和宿主机端口绑定p宿主机端口:容器端口 例如:把宿主机变成httpddockerrunitdp80:80docker。iomyos:httpd 例如:把宿主机变成nginxdockerrunitdp80:80docker。ionginx:latest十二,Podman(podmanager): 是一个功能齐全的容器引擎,它是一个简单的无需守护的用来管理镜像、容器的工具。Podman提供了一个与DockerCLI兼容的操作方式,简单地说:aliasdockerpodman。大多数Podman命令都可以普通用户运行,而无需其他额外的权限。 图片容器(Container): 指的是针对应用所需的运行环境资源(依赖库目录网络用户等)进行整体封装的技术。封装好的镜像相比虚拟机的粒度要更细,可移植性强。每个容器采用沙箱机制,相互隔离。 传统虚拟化与容器技术对比: 图片 仓库》镜像》容器的关系:仓库:用来提供存放镜像,有官方仓库(比如红帽的registry。redhat。io、刀客的docker。io),或自建私有仓库。镜像:针对某个虚拟机或某个应用封装的独立环境,作为容器的模板。容器:基于某个镜像启动的在内存中运行的实例。 图片一、安装环境yummoduleinstallycontainertools安装容器工具及其模块配置yuminstallypodmandocker安装docker兼容包(可选)二、访问仓库 1)设置默认的仓库地址(全局配置) 可以使用官方仓库(比如registry。access。redhat。com)、第三方仓库(比如docker。io),或者私有仓库(比如registry。lab。example。com)。vimetccontainersregistries。conf〔registries。search〕registries〔registry。lab。example。com〕设置搜索镜像的默认仓库地址。。。。〔registries。insecure〕registries〔registry。lab。example。com〕允许访问不安全的仓库(比如HTTPS证书无效或过期等情况)。。。。 2)登录仓库(如果需要的话,比如push上传镜像时)podmanloginregistry。lab。example。comUsername:adminPassword:LoginSucceeded! 3)搜索仓库中的镜像(比如nginx)podmansearchnginxINDEXNAMEDESCRIPTIONSTARSOFFICIALAUTOMATEDexample。comregistry。lab。example。comlibrarynginx三、管理镜像 1)下载镜像到本地podmanpullregistry。lab。example。comlibrarynginx。。。。容器存储默认工作目录varlibcontainers 2)查看镜像podmanimages列出本地镜像REPOSITORYTAGIMAGEIDCREATEDSIZEregistry。lab。example。comnginxlatest4bb46517cac33monthsago137MBpodmanimageinspect4bb4查看xxxx镜像的详细配置信息。。。。 3)导出备份镜像podmansavenginxrootnginx。tar 4)导入镜像podmanloadirootnginx。tarnginxnew:latest 5)删除镜像podmanrmixxxx删除ID为xxxx的镜像podmanrmia删除所有镜像四、管理容器1。启动容器1)在后台启动一个容器(d后台运行)podmanrundregistry。lab。example。comlibrarynginx80b22e7bd4d789773223f5afc85808ea472e82ec72f162903cd658ed6d98091cpodmanps列出启用中的容器(结合a选项可以列出所有)。。。。podmancontainerinspect4bb4查看xxxx容器的详细信息。。。。2)新启动一个容器并执行其中的命令catetcosrelease,然后删除此容器podmanrunrmregistry。lab。example。comlibrarynginxcatetcosreleasePRETTYNAMEDebianGNULinux10(buster)NAMEDebianGNULinux。。。。3)启动一个容器,并进入容器内的binbash命令行环境(i允许交互,t开启终端)podmanrunitregistry。lab。example。comlibrarynginxbinbashroot840b592a6d3f:nginxv检查nginx版本nginxversion:nginx1。19。2root840b592a6d3f:lsusrsharenginxhtml检查网页目录50x。htmlindex。htmlroot840b592a6d3f:exit退出容器exit4)在后台启动一个nginx容器,添加端口映射(p本地端口:容器端口)〔rootred〕podmanrundp8000:80nginx2b9ef8c0864149e2cf7860e903e36ba9deaa1717863f172b2bf2e5c5f3f6600c〔rootred〕podmanps列出活动中的容器CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES2b9ef8c08641registry。lab。example。comlibrarynginx:latestnginxgdaemono。。。2minutesagoUp2minutesago0。0。0。0:800080tcpecstaticmaxwell。。。。〔rootred〕curlhttp:127。0。0。1:8000通过主机端口访问容器中的web站点!DOCTYPEhtmlhtmlheadtitleWelcometonginx!title。。。。5)在后台启动一个nginx容器,将主机的optwebroot映射为此nginx容器的web目录(v本地目录:容器内目录)【持久存储】mkdiroptwebroot准备网页目录echoPodmanTestoptwebrootindex。html准备默认测试网页podmanrundp8001:80voptwebroot:usrsharenginxhtmlnginxba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8cacurlhttp:127。0。0。1:8001测试结果PodmanTest2。访问运行中的容器1)连接到ID值以ba64开头的(或者以l表示最近一个容器)容器的命令行〔rootred〕podmanexecitba64bashrootba64a15abdce:servicenginxstatus〔ok〕nginxisrunning。rootba64a15abdce:exitexit〔rootred〕2)检查容器的IP地址〔rootred〕podmaninspectba64grepIPAddress。。。。SecondaryIPAddresses:null,IPAddress:10。88。0。6,。。。。3)从主机向ID值为ba64的(或者以l表示最近一个容器)容器传输文件〔rootred〕echoAAAAroota。html建立测试网页〔rootred〕podmancproota。htmlba64:usrsharenginxhtmla。html复制文件到容器〔rootred〕curlhttp:127。0。0。1:8001a。html确认结果AAAA4)通过映射端口访问容器中的Web服务〔rootred〕curlhttp:localhost:8001浏览8001端口访问目标容器首页PodmanTest〔rootred〕curlhttp:localhost:8001a。html浏览指定页面AAAA3。关闭杀死容器1)关闭杀死ID值为ba64的容器〔rootred〕podmanstopba64若要杀容器改用killba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca〔rootred〕podmanpsagrepba64检查容器状态ba64a15abdceregistry。lab。example。comlibrarynginx:latestnginxgdaemono。。。47minutesagoExited(0)25secondsago0。0。0。0:800180tcpdreamyswirles2)重新启动被关闭的ID值为ba64的容器〔rootred〕podmanstartba64启用已关闭的xx容器ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca〔rootred〕podmanpsagrepba64检查容器状态ba64a15abdceregistry。lab。example。comlibrarynginx:latestnginxgdaemono。。。48minutesagoUp2secondsago0。0。0。0:800180tcpdreamyswirles3)强制删除ID值为ba64的容器〔rootred〕podmanrmfba64删除已关闭的xx容器(如果不加f,则需要先stop此容器)ba64a15abdce1dbd4ed834ad061efde2f7ea421a862076468cbbd694c587f8ca〔rootred〕podmanpsagrepba64检查删除结果(无输出)〔rootred〕五、为容器设置systemd服务1)启动一个容器,命名为myweb〔rootred〕podmanrunnamemywebdp80:80voptwebroot:usrsharenginxhtmlnginx52e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b182)为名称为myweb的容器创建对应的systemd服务配置〔rootred〕cdetcsystemdsystem进入服务配置目录〔rootredsystem〕podmangeneratesystemdnmywebfilesetcsystemdsystemcontainermyweb。service3)更新systemd服务配置〔rootredsystem〕systemctldaemonreload 4)配置congtainermyweb服务开机自启〔rootredsystem〕systemctlenablecontainermywebCreatedsymlinketcsystemdsystemmultiuser。target。wantscontainermyweb。serviceetcsystemdsystemcontainermyweb。service。 5)关闭当前运行的容器〔rootredsystem〕podmanstop52e652e6996bef86c501731115216c84a2f48d1a03f8c1a2cad70d27e281bd642b18 6)重启主机后,检查是否可以访问此web〔rootredsystem〕reboot。。。。〔rootserver1〕curlhttp:172。25。0。26PodmanTest六、使用无根(rootless)环境 通过rootless无根模式,非特权用户也可以很方便的运行容器(允许开启1024以上端口),以提高服务管理的安全性。 !!!确认非特权用户的起始可用端口(需要时可更改)catprocsysnetipv4ipunprivilegedportstart1024 使用systemctluser会话时,注意要直接以普通用户SSH或console控制台登录,不要使用su或sudo的方式执行。1)配置仓库 可参考mancontainersregistries。conf手册, 如果已经在etccontainersregistries。conf文件全局设置过,这里可以不做。〔zaniured〕mkdirp。configcontainers〔zaniured〕vim。configcontainersregistries。confunqualifiedsearchregistries〔registry。lab。example。com〕〔〔registry〕〕locationregistry。lab。example。cominsecuretrue允许访问不安全的仓库(全局配置中也需要添加仓库地址)blockedfalse2)下载(或导入)镜像〔zaniured〕podmanloginregistry。lab。example。com登录仓库(如果仓库要求的话)Username:adminPassword:LoginSucceeded!〔zaniured〕podmanpullregistry。lab。example。comlibrarynginx下载镜像到本地。。。。用户容器存储默认工作目录。localsharecontainers〔zaniured〕podmanimages检查本地镜像REPOSITORYTAGIMAGEIDCREATEDSIZEregistry。lab。example。comlibrarynginxlatest4bb46517cac33monthsago137MB 2)启动一个名为xxnginx的容器(如果SELinux要求启用的话,可以通过:Z传递安全标签)〔zaniured〕mkdirhomezaniuhtml〔zaniured〕echozaniuhomezaniuhtmlindex。html〔zaniured〕podmanrunnamexxnginxdp8080:80vhomezaniuhtml:usrsharenginxhtml:Znginx8fa1bc2ccd14ddc57e187ffe8e0035b6bfb1c3189460b3470b3935365f5d9a85〔zaniured〕curlhttp:127。0。0。1:8080zaniu3)创建containerxxnginx服务配置〔zaniured〕mkdirp。configsystemduser创建用户服务配置目录〔zaniured〕cd。configsystemduser进入用户服务配置目录〔zaniureduser〕podmangeneratesystemdnamexxnginxfiles生成containerxxnginx服务配置homezaniu。configsystemdusercontainerxxnginx。service4)更新用户服务配置,设置开机自启动〔zaniureduser〕systemctluserdaemonreload更新用户服务配置〔zaniureduser〕systemctluserenablecontainerxxnginx。service配置自启动Createdsymlinkhomezaniu。configsystemdusermultiuser。target。wantscontainerxxnginx。servicehomezaniu。configsystemdusercontainerxxnginx。service。〔zaniureduser〕loginctlenablelinger允许为未登录的用户启动保持后台服务如果linger方式无效,也可以通过用户计划任务实现开机自启动〔zhsanreduser〕crontaberebootsystemctluserstartcontainerxxnginx。service5)测试用户服务控制〔zaniureduser〕podmanstopxxnginx停止原来手动运行的容器〔zaniureduser〕systemctluserstartcontainerxxnginx。service启动容器服务〔zaniureduser〕systemctluserstatuscontainerxxnginx。service检查容器状态〔zaniureduser〕systemctluserstopcontainerxxnginx。service停止容器服务6)重启主机后,确认仍然可以访问web〔rootredsystem〕reboot。。。。〔rootserver1〕curlhttp:172。25。0。26:8080