Docker学习路线
Docker概述
Docker安装
Docker命令
镜像命令
容器命令
操作命令
···
Docker镜像
容器数据卷
DockerFile
Docker网络原理
IDEA整合Docker
Docker Compose
Docker Swarm
Docker概述 Docker能干嘛 虚拟机技术缺点:
容器化技术:
不是模拟的一个完整的操作系统
传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件,而容器技术,是把应用直接运行在宿主机上,容器是没有自己的内核的,也没有虚拟硬件
每个容器之间相互隔离,每个容器之间都有属于自己的文件系统,互不影响。
Docker安装 Docker的基本组成
客户端-服务器-仓库
镜像(image) Docker镜像好比一个模板,可以通过这个模板来创建容器服务,比如Tomcat镜像=》run=》Tomcat容器。通过一个镜像可以创建多个容器,而最终的服务项目是运行在容器中的。
容器(container) Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建。容器可以启动,停止,删除等。目前可以把容器理解为一个简易的linux系统。
仓库(repository) Docker仓库就是存放镜像的地方,仓库分为共有仓库和私有仓库。Docker hub,阿里云···都有容器服务器(配置镜像加速)。
Docker底层原理 Docker是一个client-server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问。
DockerSever 接收到Docker–Client的指令,就会执行这个命令。
Docker的常用命令
帮助命令
1 2 3 docker version #显示docker的版本信息 docker info #显示docker的系统信息,包括容器和镜像的数量 docker 命令 --help #帮助命令
帮助文档的地址: https://docs.docker.com/engine/reference/ 右侧的command-line
镜像命令
docker images
查看所有本地主机上的镜像
1 2 3 #可选项: -a --all #列出所有的镜像 -q --quiet #只显示镜像的id
docker search
搜索镜像
1 2 #可选项,通过隐藏来过滤 --filter=STARS=3000 #搜索出来的镜像就是STARS大于3000的,也就是下载量比较高的镜像了
docker pull
下载镜像
1 2 3 4 5 docker pull 镜像名[:tag] 如果不加tag就是,默认下载最新版本,latest #指定版本下载: docker pull mysql:5.7 ---注意这个版本一定是docker hub里面写支持了,不是自己想写什么什么 #下载是分层下载,这是docker image的核心 联合文件系统
docker rmi
删除镜像 –这个i就是指的images,所以是删除镜像
1 2 #全部删除: docker rmi -f $(docker images -aq) #后面返回所有的images的ID
容器命令
说明:有了镜像才会有容器,以centos为例
新建容器并启动 1 2 3 4 5 6 7 8 9 10 11 12 docker run [可选参数] image #参数说明 --name='NAME' 容器名字 -d 后台方式运行 -P 指定容器的端口 -P ip:主机端口:容器端口 -P 主机端口:容器端口 容器端口 -p 随机制定端口 #测试 启动并进入容器 >docker run -it centos /bin/bash
列出所有运行的容器 1 2 3 4 docker ps -a #列出当前正在运行的所有容器+带出历史运行过的容器 -n=numbers #显示最近创建的几个容器 -q #只显示容器编号
退出容器 1 2 exit #容器停止并退出 Ctrl +P+Q #容器不停止退出
删除容器 1 2 3 4 docker rm #没有加i说明不是image,就是容器了 #只rm不能删除正在运行的容器,如果要删除正在运行的,需要: docker rm -f docker rm -f $(docker ps -aq)
启动/停止容器 1 2 3 4 docker start 容器ID #启动容器 docker stop 容器ID #停止当前正在运行的容器 docker restart 容器ID #重启容器 docker kill 容器ID #强制停止当前容器
常用其他命令
后台启动容器 1 2 3 4 5 #命令 docker run -d 镜像名 > docker run -d cnetos #问题 > docker ps的时候发现centos停止了 #常见的坑,docker容器使用后台运行的,需要有一个前台进程,而docker发现没有应用,就会自动停止 #比如启动nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有进程了
查看日志 1 2 3 4 docker logs -f -t --tail n 容器ID #显示日志 -tf #显示日志 --tail number #要显示的日志条数
查看容器中的进程信息
查看进程的元数据
进入当前正在进行的容器 1 2 3 4 5 6 7 8 #通常我们容器都是使用后台的方式运行的,有些时候我们需要进入容器,修改一些配置 #命令 docker exec -it 容器ID bashshell【例如/bin/bash】 #-it就是创建一个可交互的容器 docker attach 容器ID bashshell #进去之后就看到正在执行的命令 #二者的区别 docker exec #进入容器后,开启一个新的终端,可以在里面操作 docker attach #进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上 1 docker cp 容器ID:路径 目的的主机路径
Docker镜像详解
镜像是什么
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来
如何得到镜像:
远程仓库下载
别人拷贝
Dockerfile自己制作一个镜像
Docker镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同的目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会吧各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
镜像与容器 Docker镜像都是只读的,当容器启动之后,一个新的可写层被加载到镜像的顶部
这一层就是我们通常说的容器层,容器之下的都叫镜像层。我们创建一个镜像,然后run了之后在里面修改配置或者进行其他操作,这些操作都是基于容器层的,这个时候我们要把它发给其他人,需要把容器和镜像一起再重新打包。
commit镜像
1 2 docker commit 提交容器为一个新的副本 docker commit -m='提交的描述信息' -a='作者' 容器ID 目标镜像名:[TAG]
实战操作 1 2 3 4 5 6 7 #1.启动一个默认的Tomcat #2.发现默认的Tomcat是没有webapps引用的,这是镜像的原因,官方默认的webapps下面是没有文件的 #3.于是我们进入容器,自己拷贝进去了基本的文件 #4.将我们操作过的容器通过commit提交为一个新的镜像 #以后就可以直接使用我们修改过的镜像 docker commit -m='add webapps app' -a='psych' 镜像ID Tomcat01:1.0
容器数据卷
什么是容器数据卷
docker理念回顾:将应用和环境打包成一个镜像
但是如果数据都在容器中,那么我们将容器删除的时候里面的数据也会跟着丢失,所以需求是如何使数据可持久化。所以我们急需一个容器之间可以数据共享的技术,也就是容器数据卷 的技术
本质上就是目录的挂载技术,将容器内的目录挂载到Linux主机上
总结一句话:数据的持久化和同步操作
方式一:直接使用命令-v
挂载
1 docker run -it -v 主机目录:容器内目录 #和端口映射很类似
实战操作:MySQL安装配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #获取镜像 > docker pull mysql:5.7 #运行容器,需要做数据挂载;安装启动mysql,需要配置密码,这是要注意的点 #官方命令: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag #启动我们的: docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 #解释 -d #后台运行 -p #端口映射 -v #卷挂载 -e #环境配置,设置mysql登录密码 --name #设置容器名
具名和匿名挂载 1 2 3 4 5 6 7 8 9 10 11 12 13 #匿名挂载 -v 容器路径 docker run -d -p --name nginx -v /etc/nginx nginx #不指定主机名 #现在我们来查看所有的volume[卷]的情况 docker volume ls #就会显示很多匿名挂载,也就是我们在-v的时候只写了容器内的路径,没有写容器外的路径 #具名挂载 docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx nginx #然后我们再次查看volume的时候就会看到一个juming-nginx的卷,这个就是我们的具名挂载。 #然后我们要查看一个卷到底挂载到哪里了,就是用inspect查看详细数据就可以 > docker volume inspect juming-nginx
所有docker容器内的卷,没有指定容器外的路径的话,就会默认放在
/var/lib/docker/volumes/xxx/_data
这个路径下面。
挂载分类 1 2 3 -v 容器内路径 #匿名挂载 -v 卷名:容器内路径 #具名挂载 -v /宿主机路径:容器内路径 #指定路径挂载
方式二:利用Dockerfile来构建docker镜像
Dockerfile其实就是一个命令脚本,然后通过一个脚本来生成一个镜像,镜像是一层一层的,脚本是一行一行的命令,对应一层一层的镜像。
1 2 3 4 5 6 7 8 #Dockerfile内容编写 -> 指令 参数 #所有的指令都是大写 FROM centos VOLUME["volume01","volume02"] # 挂载卷,匿名挂载,通过docker inspect来查看路径 CMD echo"__end__" CMD /bin/bash
1 docker build -f Dockerfile -t psych-centos:1.0 .
Dockerfile
dockerfile是用来构建docker镜像的文件!命令参数脚本。
构建步骤:
编写一个Dockerfile文件
docker build 构建成为一个镜像
docker run 运行镜像
docker push 发布镜像(DockerHub、阿里云镜像仓库)
DOckerfile构建过程
基础知识 :
每个保留关键字(指令)必须都是大写字母
执行从上到下顺序执行
#
表示注释
每一个指令都会去创建提交一个新的镜像层
Dockerfile是面向开发的,Docker镜像已经逐渐称为企业交付的标准
Dockerfile:构建文件,定义了一切的步骤,源代码
DockerImage:通过Dockerfile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务的
Dockerfile指令
1 2 3 4 5 6 7 8 9 10 11 12 FROM #基础镜像,一切从这里开始构建 MAINTAINER #镜像是谁写的,姓名+邮箱 RUN #镜像构建的时候需要运行的命令 ADD #步骤:比如:Tomcat镜像,就需要在centos的基础镜像中添加Tomcat压缩包 WORKDIR #镜像的工作目录 VOLUME #挂载的目录 EXPOST #暴露端口 CMD #指定这个容器启动的时候要运行的命令,之后最后一个会生效,可被替代 ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD #当构建一个被继承的Dockerfile,这个时候就会触发ONBUILD。 COPY #类似ADD,将文件拷贝到镜像中 ENV #构建的时候设置环境变量
实战测试1
Docker HUb中99%的镜像都是从一个基础镜像过来的。FROM scratch
,然后设置需要的软件和其他的配置。
创建一个自己的centos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #Dockerfile FROM cnetos MAINTAINER psych<1836969156@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD ehco $MYPATH CMD echo '---end---' CMD /bin/bash
1 2 docker build -f /path·· -t mycentos:0.1 . #docker build -f dockerfile文件路径 -t 镜像名:[tag]
可以通过docker history 镜像ID
查看镜像构建过程(变更历史)
实战测试2
构建Tomcat镜像:
准备镜像文件:Tomcat压缩包,jdk压缩包
编写Dockerfile文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #Dockerfile FROM centos MAINTAINER psych<1836969156@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8ull-linux-x86.tar.gz /usr/local #ADD之后会自动解压 ADD apache-tomcat-9.0.22.tar.gz /usr/local RUN uym -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk.8.0_11 ENV CLASSPATH $JAVA_HOME/lib/dj.jar:$JAVA_HOME/lib/tools.jar ENV CATALINE_HOME /usr/local/apache-tomcat-9.0.22 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
1 2 3 4 5 6 #构建镜像 docker build -t name . #启动镜像 docker run -d -p 8888:8080 --name psychtomcat -v /home/psych/build/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test 容器name #进入容器 docker exec -it 容器ID /bin/bash
Docker网络
Docker0
1 2 3 4 5 ip addr #查看ip地址 出现三个地址 l0: 127.0.0.1 #本机回环地址 eth0: 172.17.90.138 #服务器公网地址 docker0: 172.18.0.1/16 #Docker帮我们生成的网卡地址
1 2 3 4 5 6 7 8 9 10 #问题:docker是如何处理网络访问的? #我们随便启动一个容器,查看其ip地址,并尝试主机ping一下 docker run -d -P tomcat docker exec -it tomcat ip addr #不进入容器,直接执行命令 #发现了两个网卡: l0: 127.0.0.1/8 eth0@if162: 172.18.0.2/16 #docker分配的。 #主机尝试ping ping 172.18.0.2 #发现主机可以ping通docker容器内部
原理
我们每启动一个docker容器,docker就会给容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术是veth-pair技术
启动一个容器,主机ip addr就会多一对网卡。veth-pair就是一对的虚拟设备接口,都是成对出现,一端连着协议,另一端彼此相连
不同的容器和容器之间也是可以互相ping通的,因为docker0就想一个路由器一样,让各个容器之间能够ping
docker中所有的网络接口都是虚拟的,虚拟的转发效率高。