《三体》弱小和无知不是生存的障碍,傲慢才是。
授人以渔!学习我的思想!--狂神
即使再小的帆也能远航。--狂神
只要学不死,就往死里学!--狂神
多看官网学习
单独的容器没什么意义,有意义的是容器编排!
Dockerfilebuildrun手动操作,单个容器!
微服务:管理维护100个微服务!依赖关系
DockerCompose来轻松高效的管理容器。定义、运行多个容器。
定义、运行多个容器。
YAML文件
命令有哪些?
作用:批量容器编排
Compose是Docker官方的开源项目。需要单独安装!
Dockerfile让程序可以在任何地方运行。Web服务,redis,mysql,nginx....多个容器,挨个手动去启动管理太麻烦了!!
Compose的重要的概念:
Linux需要单独安装,windows安装dockerdesktop之后自带
1下载
chmod+x/usr/local/bin/docker-compose3测试安装成功
python应用,计数器
1应用
2Dockerfile应用打包为镜像
3Docker-composeyaml文件(定义整个服务,需要的环境。web,redis)完整的上线服务!
4启动项目compose(docker-composeup)
UsingComposeisbasicallyathree-stepprocess:
Defineyourapp’senvironmentwithaDockerfilesoitcanbereproducedanywhere.
Dockerfile保证我们的项目可以在任何地方运行。
Definetheservicesthatmakeupyourappindocker-compose.ymlsotheycanberuntogetherinanisolatedenvironment.
service--什么是服务
Rundocker-composeupandComposestartsandrunsyourentireapp.
启动项目
Adocker-compose.ymllookslikethis:
version:"3.9"#optionalsincev1.27.0services:web:build:.ports:-"5000:5000"volumes:-.:/code-logvolume01:/var/loglinks:-redisredis:image:redisvolumes:logvolume01:{}DockerSwarm集群的方式部署,购买4台阿里云服务器
点击”创建实例“
在Dockerfile文件第二行加入国内镜像
一款产品:开发–-上线两套环境!应用环境,应用配置!
开发----运维。问题:我在我的电脑上可以运行!版本更新,导致服务不可用!对于运维来说。考验十分大?
开发即运维!
环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop…)!费事费力。
发布一个项目(jar+(RedisMySQLJDKES)),项目能不能带上环境安装打包!
之前在服务器配置一个应用的环境RedisMySQLJDKESHadoop配置超麻烦了,不能够跨平台。
开发环境Windows,最后发布到Linux!
传统:开发jar,运维来做!
现在:开发打包部署上线,一套流程做完!
安卓流程:java—apk—-----------发布(应用商店)-----------------------------------------------------张三使用apk------------安装即可用!
docker流程:java-----jar(环境)----打包项目帯上环境(镜像)--(Docker仓库:商店)-----下载我们发布的镜像--直接运行即可!
Docker给以上的问题,提出了解决方案!
JRE–多个应用(端口冲突)–原来都是交叉的!
隔离:Docker核心思想!打包装箱!每个箱子是互相隔离的。
Docker通过隔离机制,可以将服务器利用到极致!
本质:所有的技术都是因为出现了一些问题,我们需要去解决,才去学习!
了解一项技术的历史才是真的了解了这项技术,跟别人才有的聊。
2010年,几个搞IT的年轻人,就在美国成立了一家公司dotcloud
做一些pass的云计算服务!LXC(LinuxContainer容器)有关的容器技术!
LinuxContainer容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
他们将自己的技术(容器化技术)命名就是Docker。
Docker刚刚延生的时候,没有引起行业的注意!dotCloud,就活不下去!
开源
开放源代码!
2013年,Docker开源!
越来越多的人发现docker的优点!火了。Docker每个月都会更新一个版本!
2014年4月9日,Docker1.0发布!
docker为什么这么火?十分的轻巧!
在容器技术出来之前,我们都是使用虚拟机技术!
虚拟机:在window中装一个VMware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重!
虚拟机也属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!
vm:linuxcentos原生镜像(一个电脑!)隔离、需要开启多个虚拟机!几个G几分钟docker:隔离,镜像(最核心的环境4MB+jdk+mysql)十分的小巧,运行镜像就可以了!小巧!几个M秒级启动!到现在,所有开发人员都必须要会Docker!
聊聊Docker
Docker基于Go语言开发的!开源项目!
了解一项技术的途径:
官网
百度百科
它产生的历史
之前的虚拟机技术
虚拟机技术的缺点:
1、资源占用十分多
2、冗余步骤多
3、启动很慢!
容器化技术
容器和技术不是模拟一个完整的系统
比较Docker和虚拟机技术的不同:
传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
每个容器间是互相隔离的,每个容器内都有一个属于自己的文件系统,互不影响
传统:一堆帮助文档,安装程序。
Docker:打包镜像,发布测试,一键运行。
使用了Docker之后,我们部署应用就和搭积木一样!
项目打包为一个镜像,扩展服务器A!服务器B
在容器化之后,我们的开发、测试环境都是高度一致的。
Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
百度:Docker的架构图
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像=>run=>tomcat01容器(提供服务的),
通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的。
启动,停止,删除,基本命令!
目前就可以把这个容器理解为就是一个简易的Linux系统。
仓库就是存放镜像的地方!
仓库分为公有仓库和私有仓库。(很类似git)
DockerHub是国外的。(默认是国外的)
阿里云…都有容器服务器(配置镜像加速!)
1、需要一点点的Linux的基础
2、CentOS7
3、我们使用Xshell连接远程服务器进行操作
Linux要求内核3.10以上
系统版本
2、找到镜像加速器
3、配置使用
Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
Docker-Server接收到Docker-Client的指令,就会执行这个命令!
1、docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在
docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
2、docker利用的是宿主机的内核,而不需要GuestOS。GuestOS:VM(虚拟机)里的的系统(OS);
HostOS:物理机里的系统(OS);
因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。然而避免引导、加载操作系统内核是个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。
而docker直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟。
之后学习完毕所有的命令,再回过头来看这段理论,就会很清晰!
dockercp容器id:容器内路径主机目的路径#这里拷贝是一个手动过程,未来我们使用-v数据卷的技术,可以实现,自动同步/home/home学习方式:将所有笔记敲一遍,自己记录笔记!
#1.搜索镜像search建议大家去docker搜索,可以看到帮助文档#2.拉取镜像pull#3.运行测试#-d后台运行#--name给容器命名#-p宿主机端口:容器内部端口~dockerrun-d--namenginx00-p3344:80nginx75943663c116f5ed006a0042c42f78e9a1a6a52eba66311666eee12e1c8a4502~dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES75943663c116nginx"nginx-g'daemonof…"41secondsagoUp40seconds0.0.0.0:3344->80/tcpnginx00~curllocalhost:3344#测试,,,,端口暴露示意图
思考问题:我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?-v数据卷!
#官方的使用dockerrun-it--rmtomcat:9.0#之前的启动都是后台,停止了容器,容器还是可以查到#dockerrun-it--rmimage一般是用来测试,用完就删除(暂时不建议)--rmAutomaticallyremovethecontainerwhenitexits#下载dockerpulltomcat#启动运行dockerrun-d-p8080:8080--nametomcat01tomcat#测试访问有没有问题curllocalhost:8080#进入容器~dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESdb09851cf82etomcat"catalina.shrun"28secondsagoUp27seconds0.0.0.0:8080->8080/tcptomcat01~dockerexec-itdb09851cf82e/bin/bashroot@db09851cf82e:/usr/local/tomcat##发现问题:1、linux命令少了。2.没有webapps#阿里云镜像(阉割版),它为保证最小镜像,将不必要的都剔除了→保证最小可运行环境!思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?要是可以在容器外部提供一个映射路径,webapps,我们在外部放置项目,就自动同步到内部就好了!
~curllocalhost:9200{"name":"b72c9847ec48","cluster_name":"docker-cluster","cluster_uuid":"yNAK0EORSvq3Wtaqe2QqAg","version":{"number":"7.6.2","build_flavor":"default","build_type":"docker","build_hash":"ef48eb35cf30adf4db14086e8aabd07ef6fb113f","build_date":"2020-03-26T06:34:37.794943Z","build_snapshot":false,"lucene_version":"8.4.0","minimum_wire_compatibility_version":"6.8.0","minimum_index_compatibility_version":"6.0.0-beta1"},"tagline":"YouKnow,forSearch"}
作业:使用kibana连接es?思考网络如何才能连接。
portainer(先用这个)
Rancher(CI/CD再用)
Docker图形化界面管理工具!提供一个后台面板供我们操作!
通过portainer来访问:
镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
将所有的应用和环境,直接打包为docker镜像,就可以直接运行。
如何得到镜像?
我们下载的时候看到一层层的下载就是这个。
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(uniteseveraldirectoriesintoasinglevirtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。boots(bootfilesystem)主要包含bootloader和Kernel,bootloader主要是引导加kernel,Linux刚启动时会加bootfs文件系统,在Docker镜像的最底层是boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
黑屏--(加载)--开机进入系统
rootfs(rootfilesystem),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版,boots基本是一致的,rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!
2.分层理解我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载。
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过dockerimageinspect命令
举一个简单的例子,假如基于UbuntuLinux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,
就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引撃有AUFS、Overlay2、DeviceMapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的。
件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1]。
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。
Docker镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
dockercommit提交容器成为一个新的副本#命令和git原理类似dockercommit-m="描述信息"-a="作者"容器id目标镜像名:[TAG]实战测试
#1、启动一个默认的tomcatdockerrun-d-p8080:8080tomcat#2、发现这个默认的tomcat是没有webapps应用,官方的镜像默认webapps下面是没有文件的!dockerexec-it容器id#3、我自己拷贝文件进去cp-rwebapps.dis/*webapps#4、将操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像。dockercommit-m="描述信息"-a="作者"容器id目标镜像名:[TAG]dockercommit-a="kuangshen"-m="addwebappsapp"容器idtomcat02:1.0
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我使用虚拟机的时候,快照!
学习方式说明:先理解概念,但是一定要实践,最后实践和理论相结合,一次搞定这个知识。
学到这里,才算是入门docker!!
入门成功!!!!
Docker的精髓:容器数据卷,DockerFile,Docker网络
企业实践:Dockercompose,Dockerswarm
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
方式一:直接使用命令挂载-v
-v,--volumelistBindmountavolumedockerrun-it-v主机目录:容器内目录-p主机端口:容器内端口~dockerrun-it-v/home/ceshi:/homecentos/bin/bash#启动起来之后,通过dockerinspect容器id查看
测试文件的同步
再来测试!
1、停止容器
2、宿主机修改文件
3、启动容器
4、容器内的数据依旧是同步的
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
#获取mysql镜像~dockerpullmysql:5.7#运行容器,需要做数据挂载#安装启动mysql,需要配置密码的,这是要注意点!#参考官网hubdockerrun--namesome-mysql-eMYSQL_ROOT_PASSWORD=my-secret-pw-dmysql:tag#启动我们得-d后台运行-p端口映射-v卷挂载-e环境配置--name容器名字~dockerrun-d-p3306:3306-v/home/mysql/conf:/etc/mysql/conf.d-v/home/mysql/data:/var/lib/mysql-eMYSQL_ROOT_PASSWORD=123456--namemysql01mysql:5.7#启动成功之后,我们在本地使用sqlyog来测试一下#sqlyog-连接到服务器的3306--和容器内的3306映射#在本地测试创建一个数据库,查看一下我们映射的路径是否ok!假设我们将容器删除:
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!
#匿名挂载-v容器内路径!dockerrun-d-P--namenginx01-v/etc/nginxnginx#查看所有的volume的情况~dockervolumelsDRIVERVOLUMENAMElocal33ae588fae6d34f511a769948f0d3d123c9d45c442ac7728cb85599c2657e50d#这里发现,这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径!#具名挂载~dockerrun-d-P--namenginx02-vjuming-nginx:/etc/nginxnginx~dockervolumelsDRIVERVOLUMENAMElocaljuming-nginx#通过-v卷名:容器内路径#查看一下这个卷
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data下
如果指定了目录,dockervolumels是查看不到的。
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况都使用具名挂载。
如何确定是具名挂载还是匿名挂载,指定路径挂载?
#三种挂载:匿名挂载、具名挂载、指定路径挂载-v容器内路径 #匿名挂载-v卷名:容器内路径 #具名挂载-v/宿主机路径:容器内路径#指定路径挂载dockervolumels是查看不到的。#注意/表明是一个路径,如果不写/,就是卷名拓展:
#通过-v容器内路径:rorw改变读写权限ro#readonly只读rw#readwrite可读可写dockerrun-d-P--namenginx05-vjuming:/etc/nginx:ronginxdockerrun-d-P--namenginx05-vjuming:/etc/nginx:rwnginx#ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!5.初识Dockerfile--起到了commit命令的作用Dockerfile就是用来构建docker镜像的构建文件!命令脚本!先体验一下!通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个命令,一个命令就是一层。
注意:
镜像名的部分不能有/(把/kuangshen/centos改成kuangshen/centos)
不要漏写当前目录的.
启动自己写的镜像
这个卷和外部一定有一个同步的目录。
查看一下卷挂载。dockerinspect容器id,查看Mounts
测试一下刚才的文件是否同步出去了!
这种方式使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载-v卷名:容器内路径!
多个MySQL同步数据!命名的容器挂载数据卷!
数据卷容器是一个容器,但是他是提供数据的,给别的容器提供数据共享。也叫他父容器。
#启动3个容器,通过我们刚才自己写的镜像启动。
测试:可以删除docker01,查看一下docker02和docker03是否可以访问这个文件
测试结果:测试依旧可以访问
双向拷贝
多个mysql实现数据共享
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用它为止。
但是一旦你持久化到了本地(也就是第一个父容器通过-v挂到了本地的文件系统),这个时候,本地的数据是不会删除的!
-v:具名挂载匿名挂载
dockerfile:在生成镜像的时候直接挂载
容器数据卷直接的挂载--实现数据共享和同步
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、编写一个dockerfile文件
2、dockerbuild构建称为一个镜像
3、dockerrun运行镜像
4、dockerpush发布镜像(DockerHub、阿里云仓库)
但是很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
查看一下官方是怎么做的,官方既然可以制作镜像,那我们也可以!
自己学习的方法:百度Dockerfile命令(图片)
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成企业交付的标准,必须要掌握!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。---传统是用jar包,war包
Docker容器:容器就是镜像运行起来提供服务。
步骤:开发,部署,运维缺一不可!
#1.编写Dockerfile文件vimmydockerfile-centos或者catmydockerfile-centosFROMcentosMAINTAINERcheng<1204598429@qq.com>ENVMYPATH/usr/localWORKDIR$MYPATHRUNyum-yinstallvimRUNyum-yinstallnet-toolsEXPOSE80CMDecho$MYPATHCMDecho"-----end----"CMD/bin/bash#2、通过这个文件构建镜像#命令dockerbuild-f文件路径-t镜像名:[tag].dockerbuild-fmydockerfile-centos-tmycentos:0.1.#3、测试运行3、测试运行
直接就进入了工作目录
ENVMYPATH/usr/localWORKDIR$MYPATH
对比:之前原生的
我们增加之后的镜像
我们平时拿到一个镜像,可以研究一下它是怎么做出来的了!
#编写dockerfile文件$vimdockerfile-test-cmdFROMcentosCMD["ls","-a"]#构建镜像$dockerbuild-fdockerfile-test-cmd-tcmd-test:0.1.#运行镜像$dockerruncmd-test:0.1....dockerenvbindev#想追加一个命令-l成为ls-al$dockerruncmd-test:0.1-ldocker:Errorresponsefromdaemon:OCIruntimecreatefailed:container_linux.go:349:startingcontainerprocesscaused"exec:\"-l\":executablefilenotfoundin$PATH":unknown.ERRO[0000]errorwaitingforcontainer:contextcanceled#cmd的情况下-l替换了CMD["ls","-l"]。-l不是命令,所以报错!
#编写dockerfile文件$vimdockerfile-test-entrypointFROMcentosENTRYPOINT["ls","-a"]$dockerrunentrypoint-test:0.1#在这里没看到与CMD的任何区别....dockerenvbindevetchomeliblib64lost+found...#我们的追加命令,是直接拼接在我们得ENTRYPOINT命令后面的$dockerrunentrypoint-test:0.1-ltotal56drwxr-xr-x1rootroot4096May1606:32.drwxr-xr-x1rootroot4096May1606:32..-rwxr-xr-x1rootroot0May1606:32.dockerenvlrwxrwxrwx1rootroot7May112019bin->usr/bindrwxr-xr-x5rootroot340May1606:32devdrwxr-xr-x1rootroot4096May1606:32etcdrwxr-xr-x2rootroot4096May112019homelrwxrwxrwx1rootroot7May112019lib->usr/liblrwxrwxrwx1rootroot9May112019lib64->usr/lib64....自己学习:Dockerfile中很多命令都十分的相似,我们需要了解它们的细微区别,我们最好的学习就是对比他们然后测试效果!
1、准备镜像文件--tomcat的压缩包和jdk的压缩包
准备tomcat和jdk到当前目录,编写好README。
2、编写dockerfile,官方命名是Dockerfile,build的时候会自动寻找这个文件,就不需要-f去指定了!
FROMcentos#MAINTAINERcheng<1204598429@qq.com>COPYREADME/usr/local/README#复制文件到/usr/local/ADDjdk-8u231-linux-x64.tar.gz/usr/local/#复制解压,ADD会自动帮我们解压ADDapache-tomcat-9.0.35.tar.gz/usr/local/#复制解压RUNyum-yinstallvimENVMYPATH/usr/local#设置环境变量(key,value)WORKDIR$MYPATH#设置工作目录ENVJAVA_HOME/usr/local/jdk1.8.0_231#设置环境变量ENVCLASSPATH$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENVCATALINA_HOME/usr/local/apache-tomcat-9.0.35#设置环境变量ENVCATALINA_BASH/usr/local/apache-tomcat-9.0.35#设置环境变量ENVPATH$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib#设置环境变量分隔符是一个冒号:EXPOSE8080#设置暴露的端口CMD/usr/local/apache-tomcat-9.0.35/bin/startup.sh&&tail-F/usr/local/apache-tomcat-9.0.35/logs/catalina.out#设置默认命令#多个命令用&&符号拼接3、构建镜像
#因为dockerfile命名使用默认命名因此不用使用-f指定文件$dockerbuild-tmytomcat:0.1.4、启动镜像
$dockerrun-d-p8080:8080--nametomcat01-v/home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test-v/home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logsmytomcat:0.15、访问测试
6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
发现:项目部署成功,可以直接访问!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
3、我们的服务器上提交自己镜像
自己发布的镜像,尽量带上版本号
提交的时候也是按照层级来进行提交的!
参考阿里云容器镜像的官方文档
自己的操作:
您可以在访问凭证页面修改凭证密码。
$sudodockerpullregistry.cn-beijing.aliyuncs.com/vivian_test/vivian_repos:[镜像版本号]3.将镜像推送到Registry$sudodockerlogin--username=wulakuer01registry.cn-beijing.aliyuncs.com$sudodockertag[ImageId]registry.cn-beijing.aliyuncs.com/vivian_test/vivian_repos:[镜像版本号]$sudodockerpushregistry.cn-beijing.aliyuncs.com/vivian_test/vivian_repos:[镜像版本号]请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。
从ECS推送镜像时,可以选择使用镜像仓库内网地址。推送速度将得到提升并且将不会损耗您的公网流量。
使用"dockertag"命令重命名镜像,并将它通过专有网络地址推送至Registry。
$sudodockerimagesREPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZEregistry.aliyuncs.com/acs/agent0.7-dfb681637bb9c63c8b27daysago37.89MB$sudodockertag37bb9c63c8b2registry-vpc.cn-beijing.aliyuncs.com/acs/agent:0.7-dfb6816使用"dockerpush"命令将该镜像推送至远程。
$sudodockerpushregistry-vpc.cn-beijing.aliyuncs.com/acs/agent:0.7-dfb68166.小结
清空所有镜像和容器,方便理解
三个网络
#启动一个容器dockerrun-d-P--nametomcat01tomcat#查看容器的内部网络地址ipaddr,发现容器启动的时候会得到一个ip地址eth0@if77,docker分配的!dockerexec-ittomcat01ipaddr[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat01ipaddr1:lo:
192.168.0.1路由器IP
192.168.0.2手机的IP
同一个网段,可以互相ping通
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip。
我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术是veth-pair技术
2、再启动一个容器测试,发现又多了一对网络
我们发现这个容器带来的网卡,都是一对对的。
veth-pair就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连。
正因为有这个特性veth-pair充当一个桥梁,连接各种虚拟网络设备的
OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
3、我们来测试下tomcat01和tomcat02是否可以ping通
结论是可以!
[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES05e0879325bbtomcat"catalina.shrun"3hoursagoUp3hours0.0.0.0:49155->8080/tcptomcat02fcf026993acdtomcat"catalina.shrun"3hoursagoUp3hours0.0.0.0:49154->8080/tcptomcat01[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat01ipaddr1:lo:
结论:tomcat01,tomcat02共同使用了一个路由器,也就是docker0。
所有的docker容器不指定网络的情况下,都是docker0路由的。docker会给我们的容器分配一个默认的可用IP。
0~255??
ABC类
255.255.0.1/16
00000000.00000000.00000000.00000000
表示255.255.xxx.xxx是一个网
共有多少个IP地址?
255255减去0.0.0.0和255.255.255.255这两个
也就是255255--1-1=65535个
255.255.0.1/24
表示表示255.255.255.xxx是一个网络
又例如:
192.168.1.0/24给出了IP地址和子网掩码的位数,
24个1即11111111.11111111.11111111.00000000转为10进制是255.255.255.0,
如果改用新的子网掩码255.255.255.224转为二进制是11111111.11111111.11111111.1110000第四个段有三位是1,2的3次方是8:即问题中的可划分为子网数是8
第四个段剩5个零,子网内主机数是2的5次方减2(减2是因为减去全零的网络地址和全1的广播地址):即每个有效子网主机数是30
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥,也就是docker0
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的一对veth网卡就没了!
思考一个场景:
我们编写了一个微服务,databaseurl=ip:,项目不重启,数据库ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器或服务?
服务名不变,但是每次重启之后IP都会变。怎么能通过名字来访问服务?不通过pingip地址,而是通过ping容器名
实现高可用!
可以使用--link
[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat02pingtomcat01ping:tomcat01:Nameorservicenotknown#tomcat02直接pingtomcat01会不成功#如果tomcat03--linktomcat01之后,就可以pingtomcat01成功。通过--link解决网络连通问题。[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerrun-d-P--nametomcat03--linktomcat01tomcat387ccb1f9e462193e955f0448923690341a7e9b8f391db1d89af2a8281f48bce[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat03/bin/bashroot@387ccb1f9e46:/usr/local/tomcat#pingtomcat01PINGtomcat01(172.17.0.2)56(84)bytesofdata.64bytesfromtomcat01(172.17.0.2):icmp_seq=1ttl=64time=0.080ms64bytesfromtomcat01(172.17.0.2):icmp_seq=2ttl=64time=0.059ms#反向可以ping通吗?不能[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat01pingtomcat03ping:tomcat03:Nameorservicenotknown探究:
dockernetworkinspect网络id网段相同
dockerinspecttomcat03
其实这个tomcat03就是在本地配置了tomcat01的配置
查看tomcat03里面的/etc/hosts发现有tomcat01的配置
/etc/hosts是配置绑定的例如127.0.0.1www.baidu.com[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat03cat/etc/hosts127.0.0.1localhost::1localhostip6-localhostip6-loopbackfe00::0ip6-localnetff00::0ip6-mcastprefixff02::1ip6-allnodesff02::2ip6-allrouters172.17.0.2tomcat01fcf026993acd172.17.0.4387ccb1f9e46本质探究:-–link本质就是在hosts配置中添加一个映射172.17.0.2tomcat01fcf026993acd
之前是pingIP地址172.17.0.2,现在pingtomcat01就会转化成pingIP地址172.17.0.2
tomcat01就没有使用--link去做类似的配置,所以在tomcat01中无法直接使用pingtomcat03。
现在玩Docker已经不建议使用–link了!
自定义网络,不使用docker0!
docker0问题:不支持容器名连接访问!
查看所有的docker网络
bridge:桥接docker(默认模式,自己创建也是用bridge模式)0.2--0.1--0.3
none:不配置网络,一般不用
host:和所主机共享网络
container:容器网络连通(用得少!局限很大)
#这里再测试ping连接[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat-net01ping192.168.0.3PING192.168.0.3(192.168.0.3)56(84)bytesofdata.64bytesfrom192.168.0.3:icmp_seq=1ttl=64time=0.091ms#现在不使用--link也可以ping通名字了[root@iZ2ze15y2yl9b6nhbq5lz9Z~]#dockerexec-ittomcat-net01pingtomcat-net02PINGtomcat-net02(192.168.0.3)56(84)bytesofdata.64bytesfromtomcat-net02.mynet(192.168.0.3):icmp_seq=1ttl=64time=0.066ms在自定义的网络下,服务可以互相ping通,不必使用-–link
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis-不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
我们使用docker之后,所有的技术都会慢慢变得简单起来!
1、构建SpringBoot项目
2、打包运行
3、编写dockerfile
4、构建镜像
5、发布运行
以后我们使用了Docker之后,给别人交付就是一个镜像即可!
Docker定义:Docker是一个开源的应用容器引擎,它可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制(沙箱是一个虚拟系统程序,沙箱提供的环境相对于每一个运行的程序都是独立的,而且不会对现有的系统产生影响),相互之间不会有任何接口,更重要的是容器性能开销极低。
Docker的优点
Docker应用场景
Web应用的自动化打包和发布。
自动化测试和持续集成、发布。
在服务型环境中部署和调整数据库或其他的后台应用。
从头编译或者扩展现有的OpenShift或CloudFoundry平台来搭建自己的PaaS环境。
我们用的传统虚拟机如VMware之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。
而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。
容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。
Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的Linux容器解决方案。
Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了Docker,就不用担心环境问题。
Docker的几个重要概念,如下图所示:
镜像就类似于在创建虚拟机前需要下载的系统镜像文件,比如iso文件、img文件等一些镜像文件。
容器可以类比于正在运行中的虚拟机。
你可以将你的镜像save为一个tar文件,别人就可以通过load来获取你的镜像。
仓库中则保存了很多公共的常用的镜像,比如常用的JDK镜像、MySQL镜像、tomcat镜像、Ubuntu镜像、ngnix镜像等等。你可以通过pull来拉取获得这些镜像,你也可以自定义一些镜像通过push推送到仓库中。
Dockerfile就是一个build镜像的文件,它描述并指定了应该如何构建一个镜像。
启动容器查看容器
启动已经停止的容器后台运行
停止一个容器进入容器
退出容器导出容器导入容器容器快照删除容器
清理掉所有处于终止状态的容器
以端口5000开启端口关闭web应用
重启web应用移除web应用
获取镜像
构建镜像
step1:添加Docker的maven的插件,配置Dockerfile的path;
step2:在配置的Dockerfile的path处添加Dockerfile文件;
Step3:文件中添加配置:
Step4:mvncleanpackage-Dmaven.test.skip=true(表示不执行测试用例,也不编译测试用例类。)
step5:mvnpackagedocker:build打镜像
step6:dockerimages查看镜像
step7:dockerrun-p8081:8081-tspringboot/web-app-template运行
step9:dockerpush
自己学习:所有的都去官网学习
docker容器内无法联网问题解决,本人centos8
firewall-cmd--zone=public--add-masquerade--permanentfirewall-cmd--reloadsystemctlrestartdocker
顾名思义,veth-pair就是一对的虚拟设备接口,和tap/tun设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。如下图所示:
正因为有这个特性,它常常充当着一个桥梁,连接着各种虚拟网络设备,典型的例子像“两个namespace之间的连接”,“Bridge、OVS之间的连接”,“Docker容器之间的连接”等等,以此构建出非常复杂的虚拟网络结构,比如OpenStackNeutron。
我们给上图中的veth0和veth1分别配上IP:10.1.1.2和10.1.1.3,然后从veth0ping一下veth1。理论上它们处于同网段,是能ping通的,但结果却是ping不通。
抓个包看看,tcpdump-nnt-iveth0
Copyroot@ubuntu:~#tcpdump-nnt-iveth0tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonveth0,link-typeEN10MB(Ethernet),capturesize262144bytesARP,Requestwho-has10.1.1.3tell10.1.1.2,length28ARP,Requestwho-has10.1.1.3tell10.1.1.2,length28可以看到,由于veth0和veth1处于同一个网段,且是第一次连接,所以会事先发ARP包,但veth1并没有响应ARP包。
Copyecho1>/proc/sys/net/ipv4/conf/veth1/accept_localecho1>/proc/sys/net/ipv4/conf/veth0/accept_localecho0>/proc/sys/net/ipv4/conf/all/rp_filterecho0>/proc/sys/net/ipv4/conf/veth0/rp_filterecho0>/proc/sys/net/ipv4/conf/veth1/rp_filter完了再ping就行了。
Copyroot@ubuntu:~#ping-Iveth010.1.1.3-c2PING10.1.1.3(10.1.1.3)from10.1.1.2veth0:56(84)bytesofdata.64bytesfrom10.1.1.3:icmp_seq=1ttl=64time=0.047ms64bytesfrom10.1.1.3:icmp_seq=2ttl=64time=0.064ms---10.1.1.3pingstatistics---2packetstransmitted,2received,0%packetloss,time3008msrttmin/avg/max/mdev=0.047/0.072/0.113/0.025ms我们对这个通信过程比较感兴趣,可以抓包看看。
对于veth0口:
Copyroot@ubuntu:~#tcpdump-nnt-iveth0tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonveth0,link-typeEN10MB(Ethernet),capturesize262144bytesARP,Requestwho-has10.1.1.3tell10.1.1.2,length28ARP,Reply10.1.1.3is-at5a:07:76:8e:fb:cd,length28IP10.1.1.2>10.1.1.3:ICMPechorequest,id2189,seq1,length64IP10.1.1.2>10.1.1.3:ICMPechorequest,id2189,seq2,length64IP10.1.1.2>10.1.1.3:ICMPechorequest,id2189,seq3,length64IP10.1.1.2>10.1.1.3:ICMPechorequest,id2244,seq1,length64对于veth1口:
Copyroot@ubuntu:~#tcpdump-nnt-iveth1tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonveth1,link-typeEN10MB(Ethernet),capturesize262144bytesARP,Requestwho-has10.1.1.3tell10.1.1.2,length28ARP,Reply10.1.1.3is-at5a:07:76:8e:fb:cd,length28IP10.1.1.2>10.1.1.3:ICMPechorequest,id2189,seq1,length64IP10.1.1.2>10.1.1.3:ICMPechorequest,id2189,seq2,length64IP10.1.1.2>10.1.1.3:ICMPechorequest,id2189,seq3,length64IP10.1.1.2>10.1.1.3:ICMPechorequest,id2244,seq1,length64奇怪,我们并没有看到ICMP的echoreply包,那它是怎么ping通的?
其实这里echoreply走的是localback口,不信抓个包看看:
Copyroot@ubuntu:~#tcpdump-nnt-ilotcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecodelisteningonlo,link-typeEN10MB(Ethernet),capturesize262144bytesIP10.1.1.3>10.1.1.2:ICMPechoreply,id2244,seq1,length64IP10.1.1.3>10.1.1.2:ICMPechoreply,id2244,seq2,length64IP10.1.1.3>10.1.1.2:ICMPechoreply,id2244,seq3,length64IP10.1.1.3>10.1.1.2:ICMPechoreply,id2244,seq4,length64为什么?
我们看下整个通信流程就明白了。
整个过程如下图所示:
namespace是Linux2.6.x内核版本之后支持的特性,主要用于资源的隔离。有了namespace,一个Linux系统就可以抽象出多个网络子系统,各子系统间都有自己的网络设备,协议栈等,彼此之间互不影响。
如果各个namespace之间需要通信,怎么办呢,答案就是用veth-pair来做桥梁。
根据连接的方式和规模,可以分为“直接相连”,“通过Bridge相连”和“通过OVS相连”。
直接相连是最简单的方式,如下图,一对veth-pair直接将两个namespace连接在一起。
给veth-pair配置IP,测试连通性:
如下图,两对veth-pair分别将两个namespace连到Bridge上。
同样给veth-pair配置IP,测试其连通性:
如下图所示:
同样测试两个namespace之间的连通性:
veth-pair的三个经典实验,直接相连、通过Bridge相连和通过OVS相连。
syntaxerrornearunexpectedtoken`docker
dockerbuild-t镜像名镜像名要用小写
dockerbuildxxxx.最后要加一个.,代表当前目录
FROMubuntu:18.04MAINTAINERdan.yang@ibe.cnRUNapt-getupdate\#加上update这一句&&apt-getinstall-yvimENVMYPATH/usr/localWORKDIR$MYPATHEXPOSE80CMD$MYPATHCMDecho"-----end----"CMD/bin/bashmkdirjavaJDKmkdir-pjavaJDK/sortmkdir-pjavaJDK/installtar-zxvfjdk-8u271-linux-x64.tar.gz-C/javaJDK/install/vim/etc/profile.d/java.shexportJAVA_HOME=/javaJDK/install/jdk1.8.0_271exportPATH=$PATH:$JAVA_HOME/binsource/etc/profilejava-versionwhereisjavaapt-getinstall-yopenjdk-8-jdk\
&&apt-getinstall-ybuild-essentialcmakewgetlibzip-devlibgl1-mesa-dev\
&&apt-getinstall-ypython3.8\
&&apt-getinstall-ypython3-pip
&&pip3installpytest
FROMubuntu:18.04MAINTAINERdan.yang@ibe.cnRUNapt-getupdate\&&apt-getinstall-yopenjdk-8-jdk\&&apt-getinstall-ypython3.8\&&apt-getinstall-ypython3-pipRUNpip3installpytest\#再用一个RUN,否则requests,pyyaml安装不成功。&&pip3installrequests\&&pip3installpyyamlENVMYPATH/usr/localWORKDIR$MYPATHEXPOSE80CMD$MYPATHCMDecho"-----end----"CMD/bin/bashdockerrun-it-v/home/yundao/buildpythonimage/automation:/usr/localmyubut:6.0
如果有官方镜像,就用官方的镜像。但是怎么选择版本?
如果没有官方镜像,比如pytest,需要我自己build一个镜像pipinstall
安装python
为啥要设置软连接?不需要设置在PATH中python路径吗?
ln-s/usr/bin/python3.8/usr/bin/pythonyum
wget
python3.6??我不确定会不会有问题
没找到pytest模块?明明之前安装过了
经过小测试,pytest是可用的
直接输入pytest是可以的,pythonmain_test.py就不行,具体原因不清楚。