目录
前言1. Docker介绍1.1 Docker的安装1.2 Docker的卸载2. 配置阿里云镜像加速3. Docker原理3. docker常用命令3.1 镜像命令3.2 容器命令3.3 其他命令3.4 总结4. 部署nginx5. 部署tomcat6. 部署ES+Kibana7. Portaniner可视化面板8. Docker镜像讲解8.1 Docker镜像加载原理8.2 分层理解8.3 提交镜像9. 容器数据卷9.1 安装mysql实战9.2 匿名挂载和具名挂载10. DockerFile10.1 DockerFile常用命令10.2 DockerFile构建过程10.3 实战centos镜像测试10.4 实战tomcat镜像测试10.5 发布自已的镜像10.6 Docker流程小结11. Docker网络11.1 理解Docker011.1 容器互联--link11.2 自定义网络11.3 网络联通12. 容器命令大总结前言
博文学习视频主要是来自狂神
【狂神说Java】Docker最新超详细版教程通俗易懂
了解docker的安装、命令、镜像
集群管理compose、swarm等
虚拟机和docker都是虚拟化,两者对比
虚拟机占资源,冗余,启动慢,较笨重docker容器间相互隔离互不影响,可运行多个docker,轻巧镜像比较小,直接运行在宿主机中,没有自已的内核。docker通过镜像隔离,将其一一打包装箱,互相隔离。将环境也打包成一个镜像,防止端口冲突基于go语言框架。
docker没有虚拟化硬件,也没有自已的内核。每个容器都相互隔离,有自已的文件系统
容器化带来的好处:
打包镜像发布的测试,可以通过一键运行,和传统不一样便捷的升级和扩缩容内核级别的虚拟化,可以在一个物理机上运行很多容器实例
docker为什么比vm块?
docker有着比虚拟机更少的抽象层docker利用的宿主主机内核,而vm需要的是guest os
1. Docker介绍
基本组成:客户端、服务器、仓库
镜像:可通过镜像创建多个容器
容器:独立运行多个应用,可以通过镜像创建。类似于linux的轻巧系统,启动停止删除的一些基本命令
仓库:存放镜像的地方(类似app的商店),分为公有私有
1.1 Docker的安装
查看官网文档,博主在ubuntu下安装
docker官网文档
通过官网具体配置的安装命令
配置文件之官网
安装的过程步骤
查看系统版本号uname -r
查看系统配置cat /etc/os-release
卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
更新源,下载所需要的安装包
sudo apt-get update
sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg \ lsb-release
增加docker的密钥
url -fsSL /linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
更新源,安装相关配置(ce是社区版,ee是企业版)
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
测试是否成功安装
sudo docker run hello-world
查看下载的镜像docker images
1.2 Docker的卸载
删除依赖
sudo apt-get purge docker-ce docker-ce-cli containerd.io
删除资源文件
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
2. 配置阿里云镜像加速
通过阿里云官网找到弹性计算中的容器服务
找到其ubuntu中的配置
执行分别是这四条命令
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'{"registry-mirrors": ["https://axvfsf7e."]}EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3. Docker原理
涉及原理,我们先探讨一下在run中,容器是如何工作的
本机中寻找镜像如果没有,则在镜像仓库中下载再找不到,则返回错误
比如
root@gaokaoli:/home/gaokaoli/docker# sudo docker run hello-worldUnable to find image 'hello-world:latest' locallylatest: Pulling from library/hello-worldb8dfde127a29: Pull complete Digest: sha256:7d91b69e04a9029b99f3585aaaccae2baa80bcf318f4a5d2165a9898cd2dc0a1Status: Downloaded newer image for hello-world:latestHello from Docker!
而docker的底层原理中
守护进程运行在主机上,通过socker从客户端进行访问,docker服务器接收到命令,就会执行这个命令
3. docker常用命令
docker version
#查看docker的版本信息docker info
#查看docker的系统信息,包括镜像、服务器地址和容器的数量docker 命令 --help
#帮助命令(可查看可选的参数),比如docker COMMAND --help3.1 镜像命令
docker images
查看所有的镜像地址和仓库地址#可选参数
-a/–all 列出所有镜像
-q/–quiet 只显示镜像的id
具体这个命令的解释
REPOSITORY
镜像的仓库源TAG
镜像的标签IMAGE ID
镜像的idCREATED
镜像的创建时间SIZE
镜像的大小docker search
搜索镜像
比如
查询到其参数为
root@gaokaoli:/home/gaokaoli# docker search --helpUsage: docker search [OPTIONS] TERMSearch the Docker Hub for imagesOptions:-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)--no-trunc Don't truncate output
故我们使用filter这个参数docker search mysql --filter=STARS=3000
docker pull 镜像名[:tag]
下载镜像
如果不写tag默认是最新版本
下载的时候是分层下载,docker image的核心-联合文件系统
使用这个命令docker pull mysql
等价于docker pull docker.io/library/mysql:latest
也可以指定版本下载比如docker pull mysql:5.7
docker rmi
删除镜像
docker rmi -f 容器id
docker rmi -f 容器id 容器id 容器id
docker rmi -f $(docker images -aq)
递归遍历删除所有的镜像
3.2 容器命令
通过镜像下载一个容器
比如下载一个centos容器
docker pull centos
docker run [可选参数] image
运行容器
这个是后台进入
具体参数的说明
#参数说明--name="名字" 指定容器名字-d 后台方式运行-i -t使用交互方式运行,进入容器查看内容-p 指定容器的端口(-p ip:主机端口:容器端口 配置主机端口映射到容器端口-p 主机端口:容器端口-p 容器端口)-P 随机指定端口(大写的P)
docker run -it centos /bin/bash
进入容器
这种方式的进入,退出后,查看其运行过的容器,找不到
退出容器
exit
停止并退出容器(后台方式运行则仅退出)
Ctrl+P+Q
不停止容器退出
docker ps
列出运行过的容器
具体参数说明
-a # 列出所有容器的运行记录-n=? # 显示最近创建的n个容器-q # 只显示容器的编号
删除容器
docker rm 容器id
#删除指定的容器,不能删除正在运行的容器,强制删除使用rm -f
,加多一个参数-f
docker rmi -f $(docker ps -aq)
#删除所有的容器、
删除完成后再查看容器,发现都没了
docker ps -a -q|xargs docker rm
#删除所有的容器
该命令中涉及的xargs可看我之前的文章
linux之xargs用法详细分析
删除容器的时候docker images 是查看容器名docker ps 查看其使用过的容器id之后通过docker 进行删除id 而不是删除容器名
启动和停止容器
docker start 容器id
#启动容器
docker restart 容器id
#重启容器
docker stop 容器id
#停止当前运行的容器
docker kill 容器id
#强制停止当前容器
3.3 其他命令
后台启动容器docker run -d 镜像名
结果docker ps发现停止了找不到
主要原因是docker启动的时候必须要有一个前台进程,docker发现没有应用会自动停止
docker logs --help
查看日志
参数:
-t 日志加时间
-f 保留打印窗口,持续打印
–tail [数字] 显示最后多少行
docker logs -tf 容器id
查看全部日志
docker logs --tail number 容器id
num为要显示的日志条数
具体代码演练
输入docker 一段脚本启动一个容器
docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
查看其容器是否启动成功
之后用日志查看,每隔一秒打印一次,ctrl+c终止进行
docker logs -tf --tail 10 ead985c4bb37
docker top 进程id
查看容器中进程信息
docker inspect 容器id
查看容器的元数据
内部包含多个文件配置信息,文后会讲解
进入当前正在运行的容器,通常容器都是使用后台方式来运行的,有时候需要容器修改配置
docker exec -it 容器id /bin/bash
进入当前容器内部,进入容器开启新的终端
ps -ef
查看进程号
docker attach -it 容器id
,进入容器终端,不会启动新的进程
会一行一行打印输出
拷贝命令
将容器内部的文件拷贝到主机上
docker cp 容器id:容器内路径 目的主机路径
通过在容器中建立文件,在回主机拷贝容器的文件
具体代码演示可以通过如下
3.4 总结
此处区分两个命令,这个命令之前博主也有点疑问
run和exec的区别:
docker run:根据镜像创建一个容器并运行一个命令,操作的对象是镜像;docker exec:在运行的容器中执行命令,操作的对象是容器。
4. 部署nginx
在涉及nginx中,如果对这部分知识不懂可查看我之前的文章
Nginx从入门到精通(全)
搜索docker search nginx
下载docker pull nginx
查看其镜像是否存在docker images
运行测试其容器docker run -d --name nginx01 -p 3334:80 nginx
-d 后台运行
–name 给容器命名
-p 3334:80 将宿主机的端口3334映射到该容器的80端口访问测试curl localhost:3334
截图如下
访问测试截图
此处的ip地址是linux的地址而不是容器中的ip地址
补充说明
如果想修改其配置的文件
可进入容器中修改
进入容器docker exec -it nginx01 /bin/bash
查看其nginx的位置whereis nginx
进入具体位置修改即可cd /etc/nginx
然而每次改动nginx配置文件,都要进入到容器内部。后期的数据卷可以为我们解决这种麻烦
5. 部署tomcat
在涉及tomcat中,如果对这部分知识不懂可查看我之前的文章
Tomcat详细配置(全)
和部署nginx步骤类似
搜索docker search tomcat
下载docker pull tomcat
查看其镜像是否存在docker images
运行测试其容器docker run -d --name tomcat01 -p 3355:8080 tomcat
访问测试curl localhost:3355
部分截图如图所示
在本地的主机进行访问的时候却不能访问
究其原因是因为容器中命令行少了,而且也没有webapps中的文件,该容器比较小,镜像中很多没必要的都被删除掉了
需要在配置中进行配置复制一份文件即可
重新打开网址即可加载
6. 部署ES+Kibana
es是elasticsearch
下载启动一步到位
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
非常耗内存,启动之后linux虚拟机会很卡
docker stats
查看cpu当前的状态
测试es是否测试成功curl localhost:9200
为了防止启动的时候这么卡,可以增加内存的限制,修改配置文件
加上-e
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx512m" elasticsearch:7.6.2
7. Portaniner可视化面板
-v是挂载
外网8088
内网是9000
具体完整的代码突入所示
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
本机测试访问curl localhost:8088
登录之后的页面是
8. Docker镜像讲解
独立的软件包,包含所有的内容,包含代码、运行时环境,库文件等
8.1 Docker镜像加载原理
UnionF5(联合文件系统):分层轻量级的高性能文件系统,支持文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
在内核中加一层一层镜像系统
bootfs系统启动需要的引导加载rootfs启动之后的不同操作系统版本
这个rootfs可以很小,只要包含基本的命令即可,使用底层主机host,提供rootfs即可。再开机的时候,bootfs是一样的,之后的操作系统版本就不一样,每个操作系统都可以共用bootfs
8.2 分层理解
所有的docker镜像都起始于一个基础的镜像层,当进行修改或者增加新的内容,会在当前镜像层上面增加新的镜像层
下载的时候一层一层下载,如果每一层有单独的文件更新,也只是更新这个版本,其他的层面文件还是可以复用
Docker镜像都是只读,当容器启动,一个新的可写层被加载到镜像的顶部,这一个层就是容器层,容器之下的是镜像层
通过docker image inspect nginx
查看内部信息,其内部配置也是分层的界面
即使用pull下载的时候,也是一层一层下载
8.3 提交镜像
docker commit
提交容器成为一个新的版本
docker commit -m=“提交的描述信息” -a="作者" 容器id 目标镜像名:[TAG]
9. 容器数据卷
容器之间有一个数据共享
容器中产生的内容,可以同步到本地,也就是卷技术
目录的挂载,将容器内的目录挂载到linux上
容器的持久化和同步操作,容器之间也可以数据共享
方式一:
可以通过使用命令进行挂载
docker run -it -v 主机内目录:容器内目录 镜像名 /bin/bash
启动后,在主机内(不是在容器内)可以通过docker inspect id
查看内部数据的源地址以及目的地址
source为源地址,destination 为目的地址
挂载成功后,在主机内部目录和容器内部目录中的一方添加数据,另一方也会同时添加数据等操作,是双向绑定操作
即使容器退出,在主机内部添加数据,登录容器后,数据也会显示
9.1 安装mysql实战
具体这部分内容可看我之前的文章
docker启动mysql配置实战过程(全)
再连接的时候可能会出现如下问题
MySql连接出现1251Client does not support authentication protocol requested by server解决方法navicat:-Lost connection to MySQL server at ‘reading initial communication packet解决方法cmd:发生系统错误 5。拒绝访问解决方法
如果没有出现问题,且正常连接启动了即可成功
9.2 匿名挂载和具名挂载
匿名挂载 -v 后面只写容器内的路径而没有写容器外的路径
具名挂载 -v 后面多了个卷名
具体代码规则
匿名挂载:-v 容器内路径
具名挂载:-v 卷名:容器内路径
指定路径挂载:-v /宿主主机路径:容器内路径
此处补充一条命令docker volume ls
查询容器
还可以通过docker colume --help
查看其它参数规则
root@gaokaoli:/home/gaokaoli/mysql# docker volume --helpUsage: docker volume COMMANDManage volumesCommands:createCreate a volumeinspectDisplay detailed information on one or more volumeslsList volumesprune Remove all unused local volumesrmRemove one or more volumesRun 'docker volume COMMAND --help' for more information on a command.
下面也会重点讲解inspect这个参数,记住
具体代码实战
匿名挂载:docker run -d --name nginx01 -v /etc/nginx nginx
具名挂载:docker run -d --name nginx02 -v 02nginx:/etc/nginx nginx
补充:在挂载中的容器路径后还可以跟其他参数
ro:只读(容器外对容器内只能读)rw:可读可写
比如下面这种情况docker run -d --name nginx02 -v 02nginx:/etc/nginx:ro nginx
而且挂载之后还可以通过命令查询其参数
通过dockerinspect id
在没有指定目录的情况下,其目录大多情况都在/var/lib/docker/volumes/卷名/_data
,可通过具名挂载可以方便的找到卷,因此广泛使用这种方式进行挂载
10. DockerFile
功能:用来构建docker镜像的文件
构建步骤:
编写一个dockerfile文件docker build
构建成为一个镜像docker run
运行镜像docker push
发布镜像
10.1 DockerFile常用命令
具体讲解个别命令的区别
CMD和ENTRYPOINT:
在创建镜像的过程中,内部的文件为
FROM centosCMD ["ls","-a"]
最后生成该文件通过build
启动该文件使用run,会显示ls -a
的命令格式
如果使用docker run id镜像 -l
,此处是将-l代替前面的命令,这个命令会出错
如果编写的文件为
FROM centosENTRYPOINT ["ls","-a"]
最后生成该文件通过build
启动该文件使用run,会显示ls -a
的命令格式
如果使用docker run id镜像 -l
,这个意思代表显示的命令是追加,最后显示ls -la
的命令格式
讲解add命令
这个命令主要是压缩压缩包
add 压缩包 压缩最后的路径
10.2 DockerFile构建过程
每个保留关键字都必须是大写字母
执行从上到下执行
每个指令都会创建提交一个新的镜像层
具体执行步骤:开发部署运维
开发:dockerfile用来构建文件定义一切步骤的源代码部署:通过dockerimages来构建生成dockerfile生成的镜像,最终发布和运行产品运维:docker容器是镜像运行起来提供的服务器
10.3 实战centos镜像测试
编写文件,通过vim或者vi或者gedit打开文件或者touch创建文件FROM centosMAINTAINER manongyanjiuseng ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum install -y vimEXPOSE 80CMD echo $MYPATHCMD echo "--end--"CMD /bin/bash
mypath 本地目录
工作目录 就是键值与对
此处在ubuntu或者centos中的其他版本系统中,都是通过yum来安装,在原始的centos还未有apt-get安装命令,通过这个镜像搭建其他的命令版本
构建文件docker build -f 镜像名 -t 最后生成的镜像文件名:版本号 .
具体参数讲解:
-f 文件名-t 目标文件镜像:版本号. docker build 最后的 . 号,其实是在指定镜像构建过程中的上下文环境的目录,这个点不能漏掉
使用的执行命令为:docker build -f centos-myself -t mycentos:0.1 .
测试文件docker images
进入容器docker run it 目标文件镜像
安装完成之后的镜像通过pwd,直接显示的是工作目录
且通过yum安装的vim命令也可以直接使用这个命令行
通过原先centos的镜像,添加相应的命令变成自身的镜像
也可以通过各个容器版本的构建过程
通过docker history 容器id
10.4 实战tomcat镜像测试
编写Dockerfile文件,如果命令的是这种格式,可以不用加-f,-f会自动帮你查询该目录下的Dockerfile
文件内容具体为
FROM centosMAINTAINER manongyanjiusengADD apache-tomcat-9.0.52.tar.gz /usr/localADD jdk-16.0.2_linux-x64_bin.tar.gz /usr/localRUN yum -y install vimENV MYPATH /usr/localWORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk-16.0.2ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.52ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.52ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.52/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.52/bin/logs/catalina.out
通过文件内容可以看到我们的cmd有解压两个文件
这两个解压的文件可以提前下载好并且放置于同一个目录下,如果不是同一个目录下需要使用绝对路径
两个文件分别为jdk和tomcat的压缩包,具体版本也要和文件一一对应进行配置
之后开始docker build -t diytomcat01 .
查询其镜像
通过run启动其镜像docker run -d -p 8080:8080 --name manongyanjiuseng diytomcat
,这里的参数可以适当添加-v参数,之后访问tomcat的时候,可以添加一些网页从而进行访问
如果想要进入其容器,可通过docker ps
查询其容器id,在通过docker exec
进入容器内部
在镜像外测试是否可以访问
访问其具体网址
如果想要访问网址的时候,变成自已想要的网页,可以通过-v添加参数挂载其相关的网页,之后进行同步的访问即可
10.5 发布自已的镜像
关于这部分内容可看我之前比较详细的文章:
Docker镜像推送到远程服务器
10.6 Docker流程小结
11. Docker网络
11.1 理解Docker0
理解网络Docker0
清空所有环境,方便理解
移除所有的镜像docker rm -f $(docker ps -aq)
移除所有的容器docker rmi -f $(docker images -aq)
ip addr
显示网卡信息,以及本地的ip地址等
具体由回环地址、阿里云内网地址和docker地址
docker如何处理容器地址的访问?
通过一个实例进行测试
创建一个tomcat的容器
docker run -d -P --name tomcat01 tomcat
docker exec -it tomcat01 /bin/bash
接着ip addr 得到一个eth0的ip地址,这是docker分配的,linux可以ping容器内部
以下是启动了两个容器,分别都是一对的网卡信息
每启动一个docker容器,都会分配一个ip,而且会给予容器一个网卡,使用的是桥接方式,使用的是evth-pair技术,容器内部都在同一个网段。
evth-pair技术是一对对的,一对的虚拟设备接口,一段链接协议,一段彼此连接
容器之间可以ping通
具体的网络模型大致如下
主要是共用的docker0作为一个路由器,主要是使用linux的桥接的网桥
所有的网络接口都是虚拟的,通过内网传递比较快,而且只要容器删除,对应的网桥就会没
而且在相互ping的时候
发现是按顺序分配其ip地址,跨越地址会ping不通
1为路由地址,而2和3为容器地址
再者也可以通过其docker network ls
查看其docker network inspect brige的网卡id
11.1 容器互联–link
为了通过容器ping通容器,而不是ping通ip地址
即改了ip地址,但是项目名没变化,也不用重新启动容器。只需要ping项目即可。省去了麻烦的操作,才可以实现高可用
加一个参数--link 服务器
即可,反向连接不可以
通过docker run -d -P --name tomcat03 --link tomcat02 tomcat
在使用docker exec -it tomcat03 ping tomcat02
但是反过来却不能ping通
具体可以通过docker exec -it tomcat03 cat /etc/hosts
查看其hosts文件配置
–link 也就是在hosts中配置一个映射文件
docker0不支持容器名连接访问,所以现在多数都是自定义网络
11.2 自定义网络
显示所有网卡docker network ls
移除网卡docker network remove 网卡名字
具体可以通过docker network ls
查看配置信息
网络模式具体有
bridge为桥接none不配置网络host为和宿主机共享网络container 为容器网络连通(局限性很大)
在查看其网卡详细配置
docker network inspect 容器id地址
在最开始的时候,配置的命令为
docker run -d -P --name tomcat01 tomcat
其实默认是--net bridge
参数省略了
docker run -d -P --name tomcat01 --net bridge tomcat
doker0网络默认是不能直接访问域名,而且–link才可以打通网络访问
要使用自定义网络
docker network create
加一些参数
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
具体参数讲解
subnet为子网地址gateway为网关地址
自定义网络默认是可以直接ping通域名(不使用–link),而且已经维护好了对应好的关系
如果要使用自已的自定义网络
只需要这样定义即可,在run参数中加入--net mynet
docker run -d -P --name tomcat01 --net mynet tomcat
11.3 网络联通
不同网段的容器,(使用了不同的docker网络)要想打通
必须通过docker network connect (network container )
也就是后面加一个容器 -网络
而且可以通过docker inspect 容器id
,发现其加入了相对应的网卡