该笔记是学习b站up主的视频所得: 狂神说java 链接:https://www.bilibili.com/video/BV1og4y1q7M4?from=search&seid=15489208779599341642
简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
docker与虚拟机技术有什么不同
- 传统虚拟机,虚拟出一套完整的硬件,在这个硬件中安装和运行软件
- 容器化的应用直接运行在宿主机中,容器没有属于自己的内核,也没有虚拟自己的硬件,所以比较轻便
- 每个容器之间相互隔离,每个容器都有自己文件系统,互不影响
docker运行流程

底层原理
docker是一个client-servie结构的系统,docker的守护进程运行在主机上,通过socket从客户端访问
dockerservice接收dockerclient的指令,就会执行这个命令

docke为什么比虚拟机快
1.docker有着比虚拟机更少的抽象层
2.docker利用的是宿主机的内核,vm使用的是guest os

所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导操作,虚拟机是加载Guest OS,分钟级别的,而docker是利用宿主机的操作系统,省略了这个复杂的步骤,秒级别
docker 常用命令
帮助命令
# 查看版本
docker version
# 版本信息
docker info
# 帮助命令
docker --help
镜像命令
# 查看本机上所有镜像
docker images
# 列出所有的镜像
docker images -a
# 只显示镜像id
docker images -q
# 搜索镜像
docker search 镜像名
例如: docker search mysql
# 搜索帮助命令
docker search --help
# 下载镜像
docker pull 镜像名[:tag]
例如: docker pull mysql:5.7
不写tag默认是最新
# 删除指定tag镜像
docker rmi -f 镜像id
# 全部删除
docker rmi -f $(docker images -aq)
# 删除多个指定版本id的镜像
docker rmi -f 镜像id 镜像id 镜像id
容器命令
有了镜像才可以使用容器
docker pull centos
新建容器并启动
docker run [可选参数] image
# 测试并进入容器
docker run -it centos /bin/bash
# 退出容器并停止
exit
# 退出容器不停止
Ctrl+p+q
# 停止正在运行的容器
docker stop 容器id
# 查看运行的容器
docker ps
# 查看运行过的容器
docker ps -a
# 删除容器 不可以删除正在运行的容器,想要强制删除的话 需要加 -f
docker rm 容器id
# 删除所有的容器
docker rm $(docker ps -aq)
# 删除所有容器
dokcer ps -a -q|xargs docker rm
# 启动容器
docker start 容器id
# 删除容器
docker kill 容器id
容器的其他命令
# 后台启动容器
docker run -d 容器名
docker run -d centos #启动发现停止了
# 常见的问题:docker 容器启动后需要有个前台进程,docker发现没有应用,就会自动停止
# 查看日志
docker -logs -tf --tail 条数 容器
docker -logs -tf 容器
# 查看容器中进程信息
docker top 容器id
# 查看容器元数据
docker inspect 容器id
# 进入当前正在运行容器
# 方式一:
docker exec -it 容器id /bin/bash
#方式二:
docker attach 容器id
区别:
exec: 进入容器后开启一个新的终端
attach: 进入容器后进入正在执行的终端,不会新开终端
# 从容器内拷贝文件到主机上
docker cp 容器id:目标路径 目的地主机路径
# 新建文件
touch 文件名
# 新建文件夹
mkdir 文件夹名
docker端口映射图解

docker上安装Nginx
docker search nginx
docker pull nginx
docker run -d -p 80:80 nginx
docker上安装tomcat
docker pull tomcat
docker run -d -p 8080:8080 tomcat
docker仓库下载的是阉割版的,没有默认的其他页面和项目
需要自己在Tomcat中添加webapps
这解决方案:
可以进入Tomcat容器中将webapps.dist中的所有文件拷贝到webapps文件夹下
cp -r webapps.dist/* webapps
docker安装elasticsearch
docker run -d --name elasticsearch -p 9200:9200 9300:9300 -e "discovery.type=single-node" -ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
可视化
portainer
docker可视化界面管理工具
docker run -d -p 8088:9090 \ --restart=always -v /vat/run/docker.sock:/vat/run/docker.sock --privileged=true portainer/portainer
访问测试:
http://ip:8088
commit
提交自己的的镜像
docker commit -a="作者" -m="描述" tagid 新名称:版本号
# 例如:
docker commit -a="zhm" -m="add webapps file" a1abbe416846 tomcat02:1.0
容器数据卷
容器之间可以有一个数据共享技术,docker容器中产生的数据,同步到本地
可以实现数据的持久化和同步操作,容器之间也是可以数据共享
使用数据卷
方式一: 直接使用命令来挂载 -v
docker run -it -v 主机目录地址:容器内目录
# 例如:
docker run -it -v /home/ceshi:/home centos /bin/bash
使用查看元数据命令
docker inspect 容器id

这样的挂载是双向绑定的,只有在对应的目录中进行了操作的话,挂载的目录中也会有相应的同步操作
安装启动mysql
-d : 后台启动
-p : 配置端口
-v : 配置挂载
-e : 设置配置
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7
匿名和具名挂载
# 匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/nginx nginx
# 查看所有的volume情况
docker volume ls
# 这种匿名挂载,在-v 后面只写了容器内的路径,容器外的路径不用写
# 具名挂载
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx nginx
如何区分匿名和具名还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器路径 # 指定路径挂载
扩展
# 通过-v 容器内路径,ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 读写
一旦这个设置了容器权限的话,容器对我们挂载出来的内容就有了限定
docker run -d -p --name nginx02 -v juming:/etc/nginx:ro nginx
docker run -d -p --name nginx02 -v juming:/etc/nginx:rw nginx
# 设置了ro的话,只能通过宿主机操作,容器内部无法操作
# 默认设置的是rw
dockerfile
dockerfile是用来构建docker镜像的构造文件的命令脚本
通过这个脚本可以生产镜像,镜像是一层一层的,每个命令都是一层
# 创建一个dokcerfile文件
# 文件中的内容:指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
#这里的每个命令都是镜像的一层
启动脚本文件
docker build -f 路径 -t 名称:版本号
# 例如:
docker build -f /home/docekr-test-volume/dockerfilel -t centos:1.0
数卷容器
多个容器实现数据共享
# 启动一个父容器 (被挂载的容器称为父容器)
docker run -it --name docker01 centos:1.0
# 启动docker02并挂载docker01
docker run -it --name docker02 --volumes-from docker01 centos:1.0
数据共享不会因为删除了其中一个容器而丢失数据
实现多个mysql数据共享
# 启动一个mysql容器
docker run -d -p 3306:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7
# 启动第二个mysql容器并挂载第一个启动的mysql容器
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root --name mysql02 --volumes from mysql01 mysql:5.7
总结:
容器之间配置信息传递,数据卷容器的生命周期一直持续到没有容器使用为止
一旦持久化到本地后,本地的数据是不会被删除
可以理解为一种备份拷贝机制
DockerFile
dockerfile是用来构建docker镜像的文件,命令参数脚本
构建步骤:
- 编写一个dockerfile文件
- docker build 构建成一个镜像
- docker run 运行镜像
- docker push 发布镜像
dockerfile构建过程
基础知识
- 每个保留字(指令)都必须是大写
- 执行顺序是从上到下
- "#"表示注释
- 每一个指令都会创建一个镜像层并提交
DockerFile : 构建文件,定义了一切的步骤,源代码
DockerImages : 通过DockerFile 构建生成的镜像,最终发布和运行的产品
Docker容器 : 容器是镜像运行起来服务器


创建一个自己的centos
# 编写DockerFile文件
vim mydocker-centos
cat mydocker-centos
# dockerfile 内容:
FROM centos
MAINTAINER kuangshen<222222@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
# 构建文件
docker build -f mydocker-centos -t mycentos:0.1 .
CMD和ENTPYPOINT区别
CMD #指定容器启动时要运行的命令,只有最后一个生效,可被代替
ENTPYPOINT #指定容器启动时要运行的命令.可被追加
制作Tomcat镜像
-
准备好Tomcat压缩包,jdk安装包

-
编写dockerfile文件,官方命名:
Dockerfile
FROM centos
MAINTAINER zhm<8888888@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.27.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_181
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME usr/local/apache-tomcat-8.5.27
ENV CATALINA_BASH usr/local/apache-tomcat-8.5.27
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.27/bin/startup.sh && -F /usr/local/apache-tomcat-8.5.27/bin/logs/catalina.out
- 构建镜像
docker build -t divtomcat .
# 由于是官方命名,所以不用-f
- 运行
docker run -d -p 8080:8080 --name zhmtomcat -v /home/kuang/tomcat/test:/usr/local/apache-tomcat-8.5.27/webapps/test -v /home/kuang/tomcat/tomcatlogs:/
usr/local/apache-tomcat-8.5.27/logs diytomcat
发布镜像到DockerHub
- 地址 https://hub.docker.com/ 注册账号
- 在服务器上提交自己的镜像
docker login -u 用户名 -p 密码
- 登录成功后就可以提交
docker push 作者名/镜像名:版本号
发布镜像到阿里云
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间(防止冲突)
- 创建容器镜像
- 在基本信息中可以看到详细的操作步骤
docker流程

Docker网络

linux服务器可以ping通自己的容器
原理
- 每启动一个docker容器,docker就会给容器分配一个ip,我们只要安装了docker,就会一个网卡 docker0 桥接模式,使用的技术是evth-pair技术
- 再次启动一个网卡的话,就会发现又多了一对网卡
容器网卡都是成对出现的,一端连着协议,一端彼此相连,这就是 evth-pair技术
正因为有了这个技术,我们可以用这个技术充当桥梁,连接各种虚拟设备
- 容器和容器之间是可以ping通的

结论: Tomcat01和Tomcat02是公用了一个路由器:docker0
所有的容器在不指定网络的情况下,都是有docker0路由的,docker0会给我们分配一个默认可用的ip
小结
Docker使用的是linux的桥接,宿主机中是一个Docker容器的网桥,dicker0

docker中所有的网络接口都是虚拟的,以为虚拟的转发效率高(内网传递比较快)
只要容器删除,对应的网桥就没有了
–link
思考一个问题:
我们编写了一个微服务,database url=ip; 项目不重启,数据库ip换掉了,我们希望使用名字进行访问容器
直接 docker exec -it tomcat02 ping tomcat01是不通的
需要使用 --link 命令
docker run -d -p --name tomcat03 --link tomcat01
docker exec -it tomcat03 ping tomcat01
# 这样就可以ping通了
# 这是这样配置的话只是单向连接的
查看容器中的hosts 文件中就会发现 --link 就是在我们的hosts配置中增加了一个 ip 域名 容器id 这样一个关系
例如: 172.18.0.3 tomcat03 213432ee1q
自定义网络
查看所有网络
docker network ls
网络模式
bridge : 桥接模式
none : 不配置网络
host : 和宿主机共享网络
container : 容器内网络连通
docker0特点 : 默认的,域名不可以访问 --link可以打通连接
创建自定义网络命令:
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
在自己配置的网络里面进行创建容器
docker run -d -p --name tomcat-net-01 --net mynet tomcat
自定义网络优点:
- 可以使容器之间可以直接ping通
- 不同的集群使用不同的网络,保证了集群是健康和安全的
网络连通
将一个容器连接到一个网络

连接命令
# mynet 是我们上面自定义的网络
# tomcat01 是我们新起的容器
docker network connect mynet tomcat01
# 查看网络元数据
docker network inspect mynet
# 连通之后就是讲tomcat01 放到了mynet网络下
# 官方称为: 一个容器两个ip
# 就好比一个服务器有一个公网ip和一个私网ip
SpringBoot微服务服务打包Docker镜像
- 构建springboot项目
- 打包应用
- 可以idea下载docker插件,然后编写dockerfile文件时候显示高亮
- 编写对应的dockerfile
FROM java:8
COPY *.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
- 构建镜像
将jar包和dockerfile都放在服务器上
然后使用命令进行构建 - 发布运行
本文深入探讨Docker的基础概念及核心应用,包括容器与虚拟机的区别、Docker的工作原理、常用命令详解,以及如何构建和发布自定义镜像。同时介绍了Docker在微服务部署中的实践案例。
2074

被折叠的 条评论
为什么被折叠?



