容器数据卷:将容器数据与主机数据共享
DockerFile:自行编写,构建Docker镜像 。发布自己镜像
企业实战
Docker Compose
Dokcer Swarm
CI/CD Jenkins流水线!
什么是容器数据卷?
数据 不应该放在容器中,因为容器一旦删除,数据就会丢失! 数据卷就相当于数据可持久化。
比如 Mysql容器删除了 数据就丢失了 如何解决?
这个时候就是需要容器数据卷,使docker容器产生的数据 挂载在Linux主系统上。
能解决什么? 容器的持久化和同步操作,容器回见也是可以数据共享的!
使用数据卷
# 命令格式
docker run -it -v 主机目录:容器内目录 镜像 /bin/bash
# 示例
docker run -it -v /home/ceshi:/home centos /bin/bash
#查看当前容器状态
docker inspect 镜像容器
数据卷特点:
- 容器删除后 数据依旧保留在宿主机中
- 以后修改配置文件 就可以使用本地修改即可,可以理解是共享文件夹。
实战Mysql 数据文件挂载到宿主机
(建议去dockerHub看看)
docker run -d -p3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql --name mysql001 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# -v 容器配置文件 指定同步到本地配置文件
# -v 容器数据数据 指定同步到本地的数据
# -e 配置环境 指定参数 密码123456 不配置mysql启动不了
即便容器停止、销毁,数据卷依旧停留在本地文件中!
# 找到容器的挂载情况,去Mounts 里面找
docker inspect 容器id
测试:
编写Dockerfile
FROM centos
Volume ["volume1","volume2"]
CMD echo "-end-"
CMD /bin/bash
通过一个脚本生成镜像
docker build -f Dockerfile kun/centos:1.0 .
# 格式 docker build -f Dockerfile文件 -t 镜像名:版本号 . 注意 . 不能少!!!
镜像是一层一层的,脚本就是一个个命令,每个命令都是一层
注意:不加targ 就会默认找最新的,由于刚才是使用制定了targs 所以就必须加上,才算能启动
正常启动(我们自己镜像的文件夹 volume01 02 也都在了)
docker inspect mycentos
只要使用 --volumes-from 名字或者容器id 就可以共享文件了
如果删除任意一个 共享文件夹会依旧存在
即 数据共享 不会随着容器删除而消失,只在最后一个使用该数据的容器删除后,才删除。
总结论:
容器之间配置信息传递,数据卷容器的生命周期一直持续到没有容器使用为止
但是数据卷同步到本地,不会随着容器删除而删除。
文件挂载
什么是挂载?
同步镜像文件到宿主机
挂载到哪里?
挂载到宿主机的
cd /var/lib/docker/volumes
具名、匿名、指定路径挂载
# 匿名挂载一个nginx
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 具名挂载一个nginx
docker run -d -P --name nginx02 -v Nginx02:/etc/nginx nginx
# 指定路径挂载一个nginx
docker run -d -P --name nginx03 -v /etc/localNginx:/etc/nginx/logs:rw nginx
# docker run -d -P --name nginx03 -v /etc/localNginx:/etc/nginx:rw nginx 此命令无法启动,虽然是指定路径挂载,但是:引发的思考:可能是将主机的localNginx映射给了容器的nginx文件夹,因为没有localNginx是空的,就导致Nginx文件为空,进而导致nginx无法正常运行!不信,可以去尝试 run出一个容器,用docker logs 容器名 查看。
# 查看docker数据卷 帮助
docker volume --help
查看所有卷的情况 (volume叫做数据卷)
#查看所有卷的情况 指定路径挂载无法查看!
docker volume ls
看似乱码的Volume Name的话 就是匿名挂载
查看某个挂载情况
docekr volume inspect [VolumeName]
# 匿名挂载,还是比较难受的,名字太长
# 注意 VolumeName 区分大小写,不能用缩写
如何确定是具名挂载 还是匿名挂载 还是指定路径挂载?
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载 不指定宿主机路径,在/var/lib/docker/volumes/卷名 里面
-v /宿主机路径:/容器内路径 #指定路径挂载
Docker容器内的卷 没有指定目录的情况都是在/var/lib/docker/volumes/ 文件夹下 即匿名挂载、具名挂载的数据卷都在这个路径里面
宿主机绝对路径都是/开头的 所以区别是否是指定路径挂载 可以通过 -v后面第一个是不是‘/’来区别
使用聚名挂载可以很快确定卷的位置,不用担心看到,匿名挂载的卷名时混乱的一串字符串
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
ro 代表ReadOnly 容器 只读
rw 代表ReadWrite 容器 可读写 默认是rw
问题多个Mysql如何同步数据?
使用命令 --volumes-from 名字或者容器id
初始DockerFile
什么是DockerFile?
Dockerfile就是构建Docker镜像的构建文件、命令脚本
DockerFIle的意义:
- 步骤 : 开发 部署 运维 。。。缺一不可!
- Dockerfile 是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件
- Docker镜像 逐渐成为了一个企业交付的标准,必须要掌握!
- DockerFile 构建文件 定义了一切的步骤,源代码
- DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品
- Docker容器:容器就是为镜像运行起来提供服务
构建步骤
- 1 编写一个dockerfile 文件
- 2 docker bulid images #构建成为一个镜像
- 3 docker run images #启动镜像
- 4 docker push images(dockerhub)
例如:我们pull的所有镜像 都是dockerfile
很多官方镜像都是基础包,很多功能没有,我们需要自定义
官方可以制作镜像,我们也可以制作我们自己的Docker FIle
DockerFile制作过程基础知识:
- 每个保留关键字(指令)都是大写字母
- 执行顺序从上到下
- #表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交!
DockerFile的指令
- FROM # 基础的镜像
- MAINTAINER # 作者:镜像是谁写的,国际标准格式:姓名+邮箱
- RUN # Docker镜像构建时候需要运行的命令
- ADD # 提那件会自动解压
- WORKDIR # 镜像工作的目录
- VOLUME # 文件挂载的目录
- EXPOSE # 暴露端口配置 和run的时候-p是相同的
- CMD # 指定这个容器启动的时候运行的命令,只有最后一个会生效,可被替代
- ENTRYPOINT # 指定这个容器启动的时候运行的命令,可以追加命令
- ONBUILD # 当构建一个被继承DockerFile 这个时候 就会运行ONBUILD 的指令。是一个触发指令
- COPY # 将文件拷贝到镜像中
- ENV # 构建的时候设置环境变量
创建一个自己的CentOS
2021年7月21日 文件追加了新注释 内容如下:
FROM centos
MAINTAINER zanglikun<740969606@qq.com>
ENV MYPATH /usr/local # MYPATH是变量名 /usr/local是变量值 最后意思:run后默认进入的文件位置
# 可以参考Windows环境变量添加的 JAVA_HOME
WORKDIR $MYPATH # 镜像工作的目录
RUN yum -y install vim # 给centos镜像添加vim命令
RUN yum -y install net-tools # 给centos镜像添加ipconfig命令
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
开始构建自己的镜像 build
# 将dockerfile 编译为镜像,这里需要指定镜像名与tag
docker build -f 文件路径 -t 镜像名:tag .
# 例如:
docker build -f Dockerfile -t myapplication:1.0 .
#编译完成,就需要去查看当前docker 是否有镜像了 如果出现
成功的是这样的:
启动一下自己的docker 测试 发现vim、ifconfig命令就可以用了。完成
CMD参数的使用 ,切记多个CMD 只有最后一个生效!如果run的时候 追加了命令,所有的CMD 都不生效
# 让对应镜像的容器启动后执行,ls -a 切记 每个逗号 相当于一个空格
CMD ["ls","-a"]
ENTRYPOINT的使用 :比CMD 要好用,不会被覆盖,永远会执行!
ENTRYPOINT ["ls","-a"]
实战:制作Tomcat镜像
先写dockerfile
vim Dockerfile
实战:发布自己的镜像到 DockerHub
想要发布,需要在DockerHub创建自己的账号:https://hub.docker.com/
账号:740969606 密码:*******
想要发布,切记一点,一定要在dockerhub验证自己的邮箱。否则,你即便用docker 命令发布成功,你依旧无法在dockerhub的网页上查看到自己。
登录
# 登录 需要输入密码
docker login -u 账号
想看自己受否登录成功
docker info
修改容器名字(跟发布镜像没关系)
# newname 只能是A-Z 0-9
docker rename 容器id newname
修改镜像名称
docker tag 镜像id dockerhub账号/新名字:版本号
例如:docker tag 300 740969606/mycentos:1.0.1
上传镜像(到国外服务器)
docker push 740969606/mycentos:1.0.1
阿里云容器镜像,自行百度即可
Docker 网络: Docker0
查看宿主机的网卡,(每次启动一个容器,都会多一个虚拟网卡!)
ip addr
- lo 本机ip
- docker0 docker网卡地址 相当与网关!桥接到真实的宿主机上
注意 Linux可以 ping 通docker 容器内部:每次启动容器,docker就会给容器分配一个与docker0虚拟网卡同段的地址。所以主机就可以用docker虚拟网卡docker0 来访问容器了。切记,是成对出现,(容器有一个公网,一个内网) :通过 veth-pair 技术,充当桥梁。所以多个容器之间可以进行通信!
多个容器之间如何互通 --link
run 命令的时候,加上参数 :--link 容器ID/Name
他是如何生效的呢?我们都知道/etc/hosts 文件的作用!因为他们都在一个docker0的域中,追加hosts 就可以直接进行通讯了
docker run -d -it --name tomcat001 tomcat
docker run -d -it --name tomcat002 --link tomcat001 tomcat
docker exec -it tomcat002 /bin/bash
ping tomcat001
# 注意tomcat002 link命令了tomcat001 所以tomcat2 可以连通tomcat1,反之则tomcat001单独使用ping tomcat002 行不通哦
cat /etc/hosts
我们 inspect tomcat002 看下情况
docker inspect tomcat002
目前,已经不建议使用--link了!
最后想要查看网卡情况,请使用:
# 查看网卡情况
docker host ls
主机的网络模式
- bridge:桥接模式,是docker0
- host:是宿主机的共享网络
- none:没有配置的网络
- containner:容器网络联通,局限性大,用的少
Docker 自定义网络 代替 --link
docker network --help
docker0的特点:默认的网卡,域名不能访问,所以我们要自己搞docker网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 分析
--driver bridge # 默认是这个网络模式
--subnet 192.168.0.0/16 # 就是允许192.168.0.1 -- 192.168.255.255
--gateway 192.168.0.1 # 网关位置
mynet # 网络名称,自定义
查看所有的docker network 列表
docker network ls
【示例】# docker network ls
NETWORK ID NAME DRIVER SCOPE
1454252ea763 bridge bridge local
e89b113c65ec elk bridge local
eb8f7f510ac1 host host local
33b4fa3fdb89 none null local
查看自己网络配置(可以看到网络连接模式、有哪些容器加入了此网络)
# 查看网络的信息
docker network inspect 网络名称
#例如
docker network inspect mynet
[root@VM-4-14-centos filebeat]# docker network inspect e89b [ { "Name": "elk", 我们的网络名称在这 "Id": "e89b113c65ecb261350305d3141980fa18084ddd4a13a4d8ba5241a5032b764e", "Created": "2022-12-08T21:47:04.389868901+08:00", "Scope": "local", "Driver": "bridge", 主机的网络模式 "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { 此网络有哪些连接的容器 "3242a4379f77b4c7da11ded812fdb02d8b54b868dfc6c4a293cd1501c4b98105": { "Name": "elasticsearch", "EndpointID": "fb3be5999aded3adf3458465fe05d3e6372e7b2bd0643e643d4308ecfe58f9fe", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "3e627fabc22262e283d23efa94dec2e74128f7826f13a3b4aee67f3e9cb04e89": { "Name": "logstash", "EndpointID": "6947080c6049325a810470a8cf2c6feb28ca07b1177f3f7cc6f7e80ae3a42c19", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", "IPv6Address": "" }, "9e8520d2f2c4a5b50e00aec15d84db84940d09c60f7f089a9b121034fc1f5881": { "Name": "kibana", "EndpointID": "e6820de38592c2a41772c2521c081a8f766b4beb1f58de68c041c9445bd11e3e", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" }, "ae2ddb1103e7e1f71a87a229e0cdec842007c86940c35ca70849f7d7a126e748": { "Name": "filebeat", "EndpointID": "08d710430cea4690fc59687a137becbfa72b150d320d1b5ff9ff2b4099bb9556", "MacAddress": "02:42:ac:12:00:05", "IPv4Address": "172.18.0.5/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
以后想让容器之间互相ping通,就需要使用使用--net 即可!
# 启动2个docker 并使用mynet网络
docker run -dit -P --name tomcat004 --net mynet tomcat
docker run -dit -P --name tomcat005 --net mynet tomcat
# 测试通讯
docker exec -it tomcat005 ping tomcat004
docker exec -it tomcat004 ping tomcat005
讲了这么多,自定义网络有啥用的?就是代替docker0 无法通过容器名进行通信,现在就可以了。不在需要依赖于--link了,更加优秀的是:不需要创建容器就开始指定相关的--link信息了。毕竟--link 得先有容器。而自定义无需担心,不需要提前创建容器。
网络联通
主动让已经存在的容器加入某个网络
docker network connect 网络名 容器名
让自定义网卡与docker0 联通
我们先看一下mynet的容器详情
docker network inspect mynet
让docker0下的tomcat001 连接到mynet中
docker network connect 网络名称 容器Id/Name
例如: 注意:tomcat001 未启动,不会看到mynet,tomcat001的内容。当tomcat001启动时,就能够看到正常了信息了!
docker network connect mynet tomcat001
就让一个tomcat001 有了俩个ip 一个docker0下的ip 一个mynet下的ip,你可通过docker inspect 容器ID 来查看
我们试一下是否联通:
docker exec -it tomcat005 ping tomcat001
完成。
实战 Redis集群(尚未补全)
分片 + 高可用 + 负载均衡
建立myredis网卡
docker network create --driver bridge --subnet 172.38.0.0/16 --gateway 172.38.0.1 myreids
等价于
docker network create --subnet 172.38.0.0/16 myredis
# 尝试删除 myredis网卡 自己测测两个创建网卡命令
docker network rm myredis
SpringBoot微服务打包Docker Dockerfile镜像
安装idea的docker高亮插件:高级版本idea自带
编写自己的Dockerfile :在IDEA中直接命名为:Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
我还见ENTRYPOINT在dockerfile的写法
ENTRYPOINT exec java -jar -Djava.net.preferIPv4Stack=true -Duser.timezone=GMT+08 -server -Xms512m -Xmx700m -Xmn512m -XX:MetaspaceSize=128m -XX:+UseConcMarkSweepGC -XX:MaxMetaspaceSize=320m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./logs/java_heapdump.hprof -XX:-UseLargePages -Xloggc:./logs/ic_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M ./XXXXX.jar
将自己的jar包搞成 改名app 放到同级文件夹
构建自己的镜像
docker build -t myapplication:1.0 .
启动吧
docker run -P --name myapplication myapplication:1.0
Docker Compose
Docker Compose可以基于Composr文件帮我们快速部署分布式应用,无需手动配置一个个创建、运行容器
compose本质是一个文本文件,通过定义指令实现集群部署。
需要安装Docker Compose,自行下载 https://github.com/docker/compose/releases
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤
评论(0)