docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]
docker学习大纲
docker概述
docker安装
docker命令
镜像命令
容器命令
操作命令
…
docker镜像
容器数据卷
dockerfile
docker网络原理
IDEA整合docker
docker compose
docker swarm
CI\CD Jenkins
1.docker概述
docker为什么会出现?
一款产品: 开发–上线 两套环境! 应用环境,应用配置
开发----运维 (我在我的电脑上可以运行)
环境配置麻烦,每一台机器要部署环境(集群redis,es,hadoop…)!费时费力
发布一个项目(jar + (redis mysql es)),项目+环境一起打包!
传统 : 开发jar包,运维来做
现在 : 开发打包部署上线,一套流程完成,不需要运维!
java —apk ----发布 (应用商店)—下载安装即可用
java —jar(环境) —打包项目带上环境(镜像) —docker仓库 : 商店 下载镜像—直接运行
docker总体上就是避免了环境造成的影响
docker思想来自于集装箱!
jre —多个应用(端口冲突) —原来都是交叉的!
隔离 : docker核心思想!打包装箱!每个箱子是互相隔离的! docker通过隔离机制,可以将服务器利用到极致!
docker的官方地址:https://www.docker.com/ 文档 : https://docs.docker.com/
docker仓库地址: https://hub.docker.com/
2.docker能干什么
之前的虚拟机技术
虚拟机技术缺点:
- 资源占用多
- 冗余步骤多
- 启动很慢
容器化技术:
容器化技术不是模拟的一个完成的操作系统!
比较docker和虚拟机技术的不同:
- 传统虚拟机,虚拟出一条硬件,运行一个完成的操作系统,然后再这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机上的内核上,容器是没有自己的内核的,也没有虚拟硬件,所以也就轻便
- 每个容器间都是互相隔离的,每个容器内都有一个属于自己的文件系统,互不影响
DevOps (开发,运维)
更快速的交付和部署
传统 : 一堆帮助文件 , 安装程序
docker : 打包镜像,发布测试,一键运行
更便捷的升级和扩缩容
使用docker之后,我们部署应用就和搭积木一样!
项目打包为一个镜像,扩展服务器A 服务器B (水平扩展,负载均衡)
更简单的系统运维
在容器化后,我们开发,测试都是高度一致的.
更高效的计算资源利用
docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例!服务器的性能可以被压榨到极致.
3.docker安装
3.1docker的基本组成
镜像(image) :
docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像===>run===>tomcat01容器(提供服务)
,通过一个镜像可以创建多个容器(最终服务运行或者项目运行在容器中)
容器(container):
docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建容器
启动,停止,删除,基本命令
容器就是一个简易的linux系统
仓库(repository):
仓库就是存放镜像的地方!仓库分为共有仓库和私有仓库
docker hub
阿里云 配置国内镜像加速
3.2安装命令
环境查看
# 系统内核
[root@localhost /]# uname -r
3.10.0-862.el7.x86_64
# 系统版本
[root@localhost /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
安装 官方文档: https://docs.docker.com/engine/install/centos/
# 1.卸载以前的版本
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine# 2.需要的安装包
yum install -y yum-utils# 3.设置镜像仓库
yum-config-manager \--add-repo \# https://download.docker.com/linux/centos/docker-ce.repo 国外http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 阿里云# 更新软件包索引
yum makecache fast # 清空缓存 更新# 4.安装最新docker docker - ce 是社区办 ee 企业版
yum install docker-ce docker-ce-cli containerd.io# 5.启动docker
systemctl start docker# 6.查看
docker version
# 7.测试
docker run hello-world # 一般是没有当前镜像
# 8.卸载docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker # docker默认的工作资源路径
rm -rf /var/lib/containerd
3.3配置阿里云镜像加速
mkdir -p /etc/dockervim /etc/docker/daemon.json
{"registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com"]
}systemctl daemon-reload
systemctl restart docker
docker run 的运行原理图
docker底层原理
docker是如何工作的?
docker是一个client-server结构的系统,docker的守护进程运行在主机上,通过Socket从客户端访问!dockerserver 接收到docker-client的指令,就会执行这个命令.
docker为什么比虚拟机快?
- docker有比虚拟机更少的抽象层
- docker利用的是宿主机的内核,vm需要guest os.
所以说,新建一个容器时,docker不需要像虚拟机一样重新加载一个操作系统内核.vm是分钟级别的,docker是利用宿主机的操作系统,省略这一过程,docker是秒级的.
3.3镜像命令
帮助命令
docker version
docker info #显示docker的系统信息,镜像和容器信息
docker --help / docker 命令 --help #当前命令的细节使用,万能命令# 如
[root@localhost ~]# docker images --helpUsage: docker images [OPTIONS] [REPOSITORY[:TAG]]List imagesOptions:-a, --all Show all images (default hides intermediate images)--digests Show digests-f, --filter filter Filter output based on conditions provided--format string Pretty-print images using a Go template--no-trunc Don't truncate output-q, --quiet Only show image IDs
帮助文档地址: 进入官网,找doc找reference
镜像命令
docker images #查看所有本机镜像docker search #搜索镜像
docker search mysql
docker search --filter=stars=3000 # 3000以上(stars,收藏数)docker pull #下载镜像
docker pull mysql # 默认最新的版本,分层下载,docker images的核心 联合文件系统:实际中,下载过的就不 会重复下载,极大的节省内存
docker pull 镜像名[:tag] # docker pull mysql:5.7docker rmi #删除镜像
docker rmi 镜像id/镜像名称 # docker rmi -f(全删)
docker rmi $(docker images -aq) # 删除所有镜像
容器命令
说明: 我们有了镜像才可以创建容器
启动镜像
docker run # 启动镜像# 参数说明
--name="name" 容器名称
-d 后台运行
-it 交互方式运行,进入容器查看内容
-p 指定容器端口,主机映射 -p ip:主机端口:容器端口-p 主机端口:容器端口-p 容器端口容器端口
-P 随机指定端口
3.4容器命令
查看容器
docker ps # 运行中的容器
docker ps -a # 所有容器
docker ps -n=? # 显示最近创建的容器 ?是个数
docker ps -q # 只显示容器的编号 -aq就是所有
退出容器
exit # 容器停止退出
Ctrl + p + q # 容器不停止退出
删除容器
docker rm 容器id # 删除指定容器,不能删除正在运行的容器,强制删除 加 -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -a -q|xargs docker rm # 删除所有的容器
启动,停止和重启容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id # 强制停止当前容器 stop报错时用
例如
docker run -it centos /bin/bash # 交互启动,并进入容器控制台
exit # 退出容器
3.5常用其他命令
后台启动容器
# 命令 docker run -d 镜像名/id 后台运行容器# 问题docker ps 时发现当前容器停止了# docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# 如nginx,容器启动后,发现自己没有提供服务,就会立即停止(自杀)
查看日志
docker logs -f -t [--tail 日志条数] [容器id] # 容器,没有日志docker run -d [容器名称/id] -c "while true;do echo kuangshen;sleep 1;done"显示日志
-tf # 显示日志
--tail number # 显示多少条日志
查看容器的进程信息
docker top 容器id
查看镜像的元数据
# docker inspect 容器id[root@localhost ~]# docker inspect dea069283958
[{"Id": "dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f","Created": "2022-03-14T02:28:55.599139597Z","Path": "-c","Args": ["while true;do echo lipengg;sleep 1;done"],"State": {"Status": "created","Running": false,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 0,"ExitCode": 127,"Error": "OCI runtime create failed: container_linux.go:380: starting container process caused: exec: \"-c\": executable file not found in $PATH: unknown","StartedAt": "0001-01-01T00:00:00Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412","ResolvConfPath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/resolv.conf","HostnamePath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/hostname","HostsPath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/hosts","LogPath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f-json.log","Name": "/vigilant_engelbart","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24-init/diff:/var/lib/docker/overlay2/7be1ddf0bbc549ea7f722c77e9ae046ea9a317d8f41061cea21d6a567c8ca9cd/diff","MergedDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24/merged","UpperDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24/diff","WorkDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24/work"},"Name": "overlay2"},"Mounts": [], # 挂载,就是做数据卷映射的时候的一些信息"Config": {"Hostname": "dea069283958","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["-c","while true;do echo lipengg;sleep 1;done"],"Image": "feb5d9fea6a5","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {}},"NetworkSettings": {"Bridge": "","SandboxID": "a4a3e343b2a2d696266f046afb3ffae1543b51a5ff85148b0fa4219e28b54600","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/a4a3e343b2a2","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "","Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","MacAddress": "","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "82e66b0d7cbbba16fc6e02714ea5f315bb2a9e2d9a2cbc5f4177f17cd8f1ce99","EndpointID": "","Gateway": "","IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "","DriverOpts": null}}}}
]
进入当前正在运行的容器
# 我们通常容器都是采用后台方法运行的,需要进入容器,修改一些配置
docker exec -it 容器id [/bin/bash]# docker
docker ps -it #docker attach 容器id# docker exec # 进入容器开启个新的终端,可以在里面进行操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程.
3.6从容器内拷贝文件到主机上
# 命令 docker cp 容器id:容器内路径 目的路径
# 进入docker容器内部
docker attach b12343556# 新建之后,退出容器
touch test.javadocker cp b12343556:/home/test.java /home# 拷贝是一个手动的过程,使用数据卷 -v ,实现自动cp
3.7导入导出镜像
# 将pull下来的镜像打包成压缩包文件docker save 镜像id -o /home/local_centos.tar docker export 容器id -o /home/local_centos.tar
# 将本地镜像加载到dockerdocker load 镜像压缩包 # 和 save共用docker import 镜像压缩包 # 和 export共有特别注意:两种方法不可混用。如果使用 import 导入 save 产生的文件,虽然导入不提示错误,但是启动容器时会提示失败,会出现类似"docker: Error response from daemon: Container command not found or does not exist"的错误。1,文件大小不同
export 导出的镜像文件体积小于 save 保存的镜像2,是否可以对镜像重命名
docker import 可以为镜像指定新名称
docker load 不能对载入的镜像重命名3,是否可以同时将多个镜像打包到一个文件中
docker export 不支持
docker save 支持4,是否包含镜像历史
export 导出(import 导入)是根据容器拿到的镜像,再导入时会丢失镜像所有的历史记录和元数据信息(即仅保存容器当时的快照状态),所以无法进行回滚操作。
而 save 保存(load 加载)的镜像,没有丢失镜像的历史,可以回滚到之前的层(layer)。5,应用场景不同
docker export 的应用场景:主要用来制作基础镜像,比如我们从一个 ubuntu 镜像启动一个容器,然后安装一些软件和进行一些设置后,使用 docker export 保存为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。
docker save 的应用场景:如果我们的应用是使用 docker-compose.yml 编排的多个镜像组合,但我们要部署的客户服务器并不能连外网。这时就可以使用 docker save 将用到的镜像打个包,然后拷贝到客户服务器上使用 docker load 载入。详细见
https://www.cnblogs.com/cj1698/p/15534197.html
练习
一.docker 安装 nginx
1.搜索镜像
docker search nginx
2.下载镜像
docker pull nginx
3.运行启动镜像
docker run -d --name nginx -p 3344:80 nginx/nginx的id
4.本地测试
curl localhost:33445.进入nginx
docker exec -it nginx /bin/bash
6.查看位置
whereis nginx
思考问题: 我们每次改动nginx配置文件,都需要进入容器内部,十分麻烦,我要是可以在容器外部提供一个映射路径,达到在容器外修改配置文件,就可以在文件内部自动修改 ? 因此,有了数据卷!
二.安装 tomcat
# 官方文档
docker run -it --rm tomcat:9.0
# 我们之前启动都是后台,停止了容器之后,容器依然存在, docker run -it --rm,一般用来测试,用完就删除.# ...下载镜像# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat
# 测试访问
404
# 进入容器
docker exec -it tomcat01 /bin/bash
# 发现问题.1.linux命令少了.2.没有webapps,阿里云镜像的原因,默认是最小的镜像,所有不必要的都已经剔除.
# 保证最小可运行环境
三.安装 es+kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录!挂载
# --net somenetwork ? 网络配置# 启动 elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 # 启动了 linux就卡住了 docker status 查看cpu的状态#一般启动es之前增加内存限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_java_opts="-Xms64m --Xmx512m" elasticsearch:7.6.2
kibana + es
3.7可视化
- portainer(先用)
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
- rancher(CI/CD时用)
什么是portainer?
docker图形界面管理工具!提供一个后台面板供我们操作!
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
访问测试 :
4.docker镜像
特点 : docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器层之下都叫镜像层!
如何提交一个自己的镜像?
4.1commit镜像
docker commit 提交容器成为一个新的副本# 命令和git原理相同docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[tag(版本)]
实战操作
#启动一个默认的tomcat
docker run -it -p 8080:8080
#发现这个默认的tomcat 是没有webapps应用,镜像的原因,官方的镜像默认webapps下是没有内容的!
#自己需要cp文件到webapps
cp webapps.dict/* webapps
#将修改后的容器,通过commit提交为一个新的镜像,这样以后我们使用这个新镜像就避免可上述操作
docker commit -m="add webapps app" -a="lpg" 容器id tomcat02:1.0
如此就相当于保存了当前容器的状态,获得一个镜像
就好比虚拟机的快照!
容器数据卷,dockerfile,Docker网络才是docker的精髓所在
5.容器数据卷
5.1什么是容器数据卷?
数据?如果在容器当中,那么容器被删除,数据也就会丢失 ! 需求 : 数据可以持久化
mysql,容器删了,删库跑路 ! 需求 : mysql数据可以存储在本地 !
所以需要,容器之间可以有一个数据共享的技术 ! docker容器中产生的数据 , 同步到本地 !
如此,便是卷技术 ! 目录的挂载 ,将我们容器内的目录挂载到linux上面
好处 : 我们以后修改只需要在本地修改即可,因为容器内会自动同步
总结 : 卷,就是容器的持久化和同步操作 ! 容器间也是可以数据共享的(多个容器映射一个目录)
5.2使用数据卷
方式一 : 直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
docker run -it -v /home/test:/home/test centos /bin/bash# 查看容器的详细信息
docker inspect 容器id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dSFW00UQ-1655110483997)(D:\后端养成记\笔记\docker\docker_images\image-20220318104320617.png)]
5.3实战,安装mysql
思考:mysql的数据持久化问题?
# 拉取mysql5.7版本的镜像
docker pull mysql:5.7
# 启动运行加数据卷 -v 映射多个 配置 数据 , -e表示环境配置
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 mysql5.7
# 将容器删除,我们宿主机的数据还在,数据并没有丢失,这就是mysql的数据持久化功能!
docker rm -f mysql01
5.4具名挂载和匿名挂载
# 匿名挂载 -P 随机指定端口
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx# 查看所有的 volume 的情况
docker volume ls
local 53484a4631971e8cc46af7217d046a63eae7105d2a572dcfffc7c6107aa3ae77
# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!# 具名挂载
-v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
docker volume lslocal juming-nginx
# 通过 -v 卷名:容器内路径
所有docker容器内的卷,没有指定目录的情况下都在 /var/lib/docker/volumes/xxxx/_data
我们通过具名挂载可以方便的找到一个卷,大多数情况都使用具名挂载
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v 宿主机路径:容器内路径 #指定路径挂载
拓展
# 通过 -v 容器内路径:ro 或 rw 改变读写权限
# ro readOnly 只读 只能通过宿主机改变,容器内部无法改变内容
# rw readWrite 可读可写 默认# 一旦设置了容器权限,容器对我们挂载出的内容即有了限制!
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
5.5初始dockerfile
dockerfile 就是用来构建 docker 镜像的构建文件 ! 本质就是一个命令脚本 !
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,所以,一个命令就是一层!
# 在/home/下建立一个新的文件
touch dockerfile1
# vi 进入文件编辑脚本 指令都是大写!
FROM tomcat8.0
VOLUME ["volume01","volume02"] # 在生成镜像时就挂自动载 匿名挂载
CMD echo "---end---"
CMD /bin/bash
# 运行生成新镜像 -f dockerfile的路径 -t生成镜像的名称和版本 最后的空格 + 点 表示在当前目录下生成
docker build -f /home/dockerfile1 -t lipengg-tomcat:1.0 .
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uuxpXCbC-1655110483999)(D:\后端养成记\笔记\docker\docker_images\image-20220318163803251.png)]
总结 : 这种方式我们未来使用的十分多,因为我们通常会构造自己的镜像 !
假设构建镜像时没有挂载卷,则需要手动镜像挂载 -v 卷名:容器内路径
5.5数据卷容器
容器间的数据共享
例如 , 两个或多个mysql同步数据 !
# 启动三个容器,测试是否同步 使用镜像id好一点,用name在volumes-from时还是有问题
docker run -it --name docker01 lipengg-tomcat:01 # 交互式进入,此时可以使用ctrl+p+q退出
docker run -it --name docker02 --volumes-from docker01 lipengg-tomcat:01
docker run -it --name docker03 --volumes-from docker01 lipengg-tomcat:01
利用指针指向,docker02和docker03都指向了宿主机的地址,所以删除了docker1也没有问题.
此时,在没有docker01的情况下,docker02和docker03之间还是数据同步的
用docker inspect检查三个容器会发现其实都映射到了宿主机的相同目录
用docker inspect检查三个容器会发现其实都映射到了宿主机的相同目录
多个mysql实现数据共享
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/con.f -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7docker run -d -p 3311:3306 -v /home/mysql/conf:/etc/mysql/con.f -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7# 匿名
docker run -d -p 3310:3306 -v /etc/mysql/con.f -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
结论 :
容器之间配置信息的传递 , 数据卷容器的生命周期一致持续到没有容器使用为止 !
但是一旦你持久化到本地, -v到本地 ,就算容器都没有了,数据依然存在 !
6.dockerfile
6.1dockerfile介绍
dockerfile是用来构建docker镜像的命令 ! 命令参数脚本 !
构建步骤 :
1.编写一个dockerfile文件
2.docker build构建成为一个镜像
3.docker run运行生成的镜像
4.docker push发布镜像(dockerHub , 阿里云镜像仓库)
很多官方镜像都是基础包 , 很多功能没有,我们通常会自己搭建自己的镜像 !
6.2dockerfile的构建过程
基础知识:
- 每个保留字(指令)都必须是大写
- 从上到下执行
- “#” 表示注释
- 每一个命令都会创建提交一个新的镜像 , 并提交 !
dockerfile是面向开发的 , 我们以后发布项目 , 做镜像 , 就需要编写dockerfile文件 !
docker镜像逐渐成为企业交付的标准 , 必须掌握 !
dockerfile : 构建文件 , 定义了一切的步骤 , 源代码.
dockerImages : 通过dockerfile 构建生成镜像 , 最终发布和运行的产品 !
dockerContainer : 容器就是镜像运行起来提供的服务器 !
6.3dockerfile的指令
6.4实战测试
docker hub 中99%的镜像都是FROM scratch镜像来的
创建一个自己的centos镜像
touch mydockerfile-centos
# 1.编写dockerfile文件
FROM centos
MAINTAINER lipengg<12345678@qq.com>ENV MYPATH /usr/local
WORKDIR $MYPATH # 工作目录# 加运行的命令
RUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo MYPATH # 输出
CMD echo "---end---"
CMD /bin/bash # 最终进入/bin/bash# 2.通过文件构建镜像
# docker build -f 文件路径+文件 -t 镜像名:版本 .是当前目录下生成
docker build -f mydockerfile-centos -t mycentos:0.1 .# 3.测试
docker run -it mycentos:0.1 # 直接进入工作目录,且vim和ipconfig命令也可以用# 4.查看镜像的构建历史
docker history 镜像id
CMD和ENTRYPOINT的区别
CMD # 指定这个容器启动时候要运行的命令,只有最后一个会生效(run成功后,打印出来),可被替代
ENTRYPOINT # 指定这个容器启动时候要运行的命令,可以追加命令
# 构建cmd测试文件
touch centos-cmd-testFROM centos
CMD ["ls","-a"]# build镜像
# run执行
docker run 镜像
成功,打印出ls -a的信息
# 想追加一个命令
docker run 镜像 -l # 预想是执行ls -al 显示详细信息,实际报错
# 原因 : cmd的最后一个命令是l,l不是命令
# 构建entrypoint测试文件,追加命令
touch centos-entrypoint-testFROM centos
ENTRYPOINT ["ls","-a"]# build镜像
# run执行
docker run 镜像
成功,打印出ls -a的信息
# 想追加一个命令
docker run 镜像 -l
执行成功 # 实际是执行了ls -al,追加了命令
6.5实战 : Tomcat镜像
1.准备镜像文件tomcat , jdk 压缩包
2.编写Dockerfile文件,官方命令Dockerfile,build命令会自动寻找这个文件 , 也就不需要 -f 进行指定了 !
FROM centos
MAINTAINER lipengg<12345678@qq.com>COPY readme.txt /usr/local/readme.txtADD apache-tomcat-8.5.70.tar.gz /usr/local/ # ADD 命令会自动解压
ADD jdk-8u152-linux-x64.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/local4
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.0_152
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar # 冒号就是将两个路径隔开
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.70
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.70
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_HOME/libEXPOSE 8080CMD /usr/local/apache-tomcat-8.5.70/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.70/bin/logs/catalina.out
3.构建镜像
docker build -t diytomcat .
4.启动镜像
docker run -d -p 9090:8080 --name lipenggtomcat -v /home/tomcat/test:/usr/local/apache-tomcat-8.5.70/webapps/test -v /home/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.5.70/logs diytomcat
5.访问测试
curl localhost:9090
6.发布项目 (做了卷挂载,我们直接在本地编写项目就可以发布)
# 我们的tomcat挂载到了/home/tomcat/test 目录
# 进入到该目录
mkdir WEB-INF
cd WEB-INF
vim web.xml # 写入下面的web.xml文件内容<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"></web-app># cd 到test目录
vim index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>首页</title>
</head>
<body>
<%
System.out.println("-----hello world------");
%>
</body>
</html>
6.6 发布自己的镜像
再议
docker小结
7.docker网络
铺垫,容器编排,集群部署!
7.1理解docker0
# 问 : docker是如何处理网络访问的 ?
# 例如 ,tomcat如何连接到mysql# 先启动一个tomcat
docker run -d -P --name mytomcat01 tomcat
# 查看容器内部的网络
docker exec -it mytomcat01 ip addr
# 思考 ,linux本地能否ping通容器内部 ?
[root@localhost ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.220 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.085 ms
原理
- 我们每启动一个docker容器,docker就会给docker容器分配一个ip ,我们只要安装了docker ,就会有一个网卡docker0
而docker0使用的是桥接模式 ,桥接模式使用的技术就是evth-pair技术 !
当启动容器之后 ip addr
43: veth4ae83a6@if42: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 56:8b:84:25:86:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0inet6 fe80::548b:84ff:fe25:864f/64 scope link valid_lft forever preferred_lft forever
- 在启动一个容器之后,就会再增加一个
而且 ,本地ip addr和容器内部ip addr后会发现
本地 : 43: veth4ae83a6@if42
容器内部 : 42: eth0@if43
二者是成对出现的
再启动一个容器后 ,就会是44和45
本地 : 45: veth995d510@if44:
容器内部 : 44: eth0@if45:
# evth-pair 技术 ,就是网卡的出现都是成对的
# 一对网卡就是一对虚拟设备接口 ,它们都是成对出现的 ,一端连接协议 ,一端彼此相连.
# 正因为有这个特性 ,evth-pair充当一个桥梁 ,连接各种虚拟网络设备
# openStac ,docker容器之间的连接 ,ovs的连接 ,都是使用evth-pair技术
问 : 此时容器之间是否可以相互ping通 ?
[root@localhost ~]# docker exec -it mytomcat01 ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.571 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.133 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.131 ms[root@localhost ~]# docker exec -it mytomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.126 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.128 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.133 ms
结论 : 容器与容器之间是可以ping通的
注意 : 容器之间实际通信并不是直连的
docker中所有的网络接口都是虚拟的 ,虚拟的转发效率高 ! (内网传递文件 !)
只要容器删除 ,对应的evth-pair网桥对就消失
思考 : 我们编写一个微服务 ,datavaseUrl = ip:端口 ,如果用docker启动 , 每次ip发生变化 ,则此url失效
此时 , 我们应该如何去处理 ?
参考微服务springCloud , feign的存在 , 帮助我们使用服务名去访问 !
docker提供了–link
7.2容器互联–link
# 在原来的基础行 ,我们改用容器名ping
[root@localhost ~]# docker exec -it mytomcat01 ping mytomcat02
ping: unknown host# 使用link去连接mytomcat02容器
[root@localhost ~]# docker run -d -P --name mytomcat03 --link mytomcat02 b8dfe9ade316
[root@localhost ~]# docker exec -it mytomcat03 ping mytomcat02
PING mytomcat02 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.109 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.130 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.131 ms
[root@localhost ~]# docker exec -it mytomcat02 ping mytomcat03
ping: unknown host# 此时我们发现通过--link进行绑定的容器名和ip,并不是双向的 !
探究docker网络
# docker当前网络
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e7a83f201666 bridge bridge local
c289a29e595b host host local
3bdca47b627d none null local
# inspectdocker0的网络信息 ,bridge
[root@localhost ~]# docker network inspect e7a83f201666
[{"Name": "bridge","Id": "e7a83f201666cc2db85a133e2fe857369c8b9a44fb67c82ad3190272818d5032","Created": "2022-03-25T15:08:34.025252475+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.17.0.0/16", # 子网"Gateway": "172.17.0.1" # docker0 路由}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"02b08f62e4aa41d12cef3cac005316144b6926d95c96197d4cafedb815ef3403": {"Name": "mytomcat03","EndpointID": "09c706a5e4b5800c0e80b1029514b0e5095780671cf18f6cf9e5d64bffb41b5a","MacAddress": "02:42:ac:11:00:04","IPv4Address": "172.17.0.4/16", # docker0自动分配"IPv6Address": ""},"1cdbd7eb3cdf3e92e4dac9404a813fc3190534d570f4a78c8f5d711a5030b001": {"Name": "mytomcat02","EndpointID": "5bab48d6b1e30bb03e6b18d5d43d19f045c639c4fb48ea8a8b4e8b18d4961e1c","MacAddress": "02:42:ac:11:00:03","IPv4Address": "172.17.0.3/16", # docker0自动分配"IPv6Address": ""},"95d4c2a7ca777c58483ecdd05c69f555ca01bf6503200b1b11dff4233e0ac04d": {"Name": "mytomcat01","EndpointID": "6d98c0d3cfa15e95f94f12818e825b3cbbdb2e5737712e452b2cc5de7ebfefd9","MacAddress": "02:42:ac:11:00:02","IPv4Address": "172.17.0.2/16", # docker0自动分配"IPv6Address": ""}},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}}
]# 进入tomcat02/03 查看host配置
[root@localhost ~]# docker exec -it mytomcat03 /bin/bash
root@02b08f62e4aa:/# cat /etc/hosts 也可以一步 docker exec -it mytomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 mytomcat02 1cdbd7eb3cdf # 发现在tomcat03中增加了tomcat02的映射配置
172.17.0.4 02b08f62e4aa
在docker中已经不建议使用 --link !
自定义网络 ! 不适用docker0 !
docker0问题 : 不支持容器名访问 !
7.3自定义网络(重点)
查看所有的docker网络
网络模式
bridge : 桥接 docker(默认)
none : 不配置网络
host : 和宿主机共享网络
container : 容器内网络连通 (用的少 ! 局限性很大 !)
测试
# 我们直接启动的命令 --net bridge默认就有 ,不需要手动加 ,而这个就是我们的docker0叫bridge
docker run -d -P --name tomcat01 [--net bridge] tomcat# docker0特点 : 默认 ,不能通过名称访问 . 但可以用 --link可以打通连接# 我们可以自定义一个网络
# --driver bridge 网络模式 (不指定默认是bridge)
# --subnet 192.168.0.0/16 子网
# --gateway 192.168.0.1 网关(路由)
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
7607be71142d4724944a6b9dd114006b6e96a2fe58b3cb384449e87d2f245f0e
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e7a83f201666 bridge bridge local
c289a29e595b host host local
7607be71142d mynet bridge local
3bdca47b627d none null local
在自己的网络中启动容器
[root@localhost ~]# docker run -d -P --name tomcat-mynet-01 --network mynet b8dfe9ade316
3d5eb9483fc3bdf1bfe4ceff313034084ac98ec14c1f68fc66732b0d8adf7587
[root@localhost ~]# docker run -d -P --name tomcat-mynet-02 --network mynet b8dfe9ade316
3c7b8235eab8888a33b39e76fb2dbf8be9deab8e5d424368618d61e1dc662128
[root@localhost ~]# docker network inspect mynet
...
"Containers": {"3c7b8235eab8888a33b39e76fb2dbf8be9deab8e5d424368618d61e1dc662128": {"Name": "tomcat-mynet-02","EndpointID": "d1cc522577f52f8183ee0866711447edb5ceabd6a50a45fd3449110e69499beb","MacAddress": "02:42:c0:a8:00:03","IPv4Address": "192.168.0.3/16","IPv6Address": ""},"3d5eb9483fc3bdf1bfe4ceff313034084ac98ec14c1f68fc66732b0d8adf7587": {"Name": "tomcat-mynet-01","EndpointID": "6f403d72f49a6ca88c9594cb0437963920eb3c0305c5f663df2c2adbd5f58c57","MacAddress": "02:42:c0:a8:00:02","IPv4Address": "192.168.0.2/16","IPv6Address": ""}},...# 此时测试能够ping通
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.182 ms
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.135 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.091 ms
^C--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.091/0.136/0.182/0.037 ms
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping tomcat-mynet-02
PING tomcat-mynet-02 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.052 ms
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.223 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.133 ms# 发现,在自定义网络中,不仅可以通过ip ping,而且 ,在没有--link的情况下 ,也可以通过容器名称 ping
结论 : 我们自定义网络docker都已经帮我们维护好了对应的关系 ,推荐使用自定义网络 !
好处 : 当我们在搭建redis,mysql集群时,使用自定义网络,因为都有不同的子网,保证了集群的安全与健康
7.4网络连通
如何在docker中连通两个在不同网段的容器
问 : tomcat01如何可以ping通tomcat-mynet-01 ?
# docker network的connect命令
[root@localhost ~]# docker network --help
Commands:connect Connect a container to a network#将tomcat01加入到mynet网络中
[root@localhost ~]# docker network connect mynet tomcat01
[root@localhost ~]# docker network inspect mynet
..."b6bc62f9fbcd8e469e1de9473438035eadb9ab1f68bf09d29df8562c5e01141e": {"Name": "tomcat01","EndpointID": "ede2eea516ffa923ea1eafc52be3180e735c95419c9822c05426e22dc79ed263","MacAddress": "02:42:c0:a8:00:04","IPv4Address": "192.168.0.4/16","IPv6Address": ""
...# 此时去ping ,双向都通
[root@localhost ~]# docker exec -it tomcat01 ping tomcat-mynet-01
PING tomcat-mynet-01 (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.705 ms
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.117 ms
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping tomcat01
PING tomcat01 (192.168.0.4): 56 data bytes
64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=0.114 ms
64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=0.133 ms# 连通之后就是将tomcat01放到了mynet网络中
# 一个容器两个ip地址 !
# 阿里云服务 ,一个公网, 一个私网 !# 此时02依旧连不通 ,和网络不同的是 ,并不会自动暴露 !
# 实际网络应该是,主机ip注册到路由,互联的路由之间通过某种方式进行路由表的交换 !
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping tomcat02
ping: unknown host
一个容器两个ip
想要在docker中跨网络操作别人 ,就需要使用docker network connect 连通 !
7.5实战 : 部署redis集群
# 建立redis网络
docker network create redis-net --subnet 172.38.0.0/16# 通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done# 启动redis服务
docker run -d -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/redis.conf:/etc/redis/redis.conf \
--net redis-net --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf# 一次启动(可以试试,不用6次)
docker run -d -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/redis.conf:/etc/redis/redis.conf \
--net redis-net --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;\# 随便进入一个redis(没有bash)
docker exec -it redis-1 /bin/sh
# 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1# 连接集群
redis-cli -c # -c才是连接集群,要不然就是单机
cluster info # 集群信息
cluster nodes # redis集群节点
8.springboot微服务打包docker镜像
1.构建springboot项目
2.打包应用 打包成jar包
3.编写dockerfile文件
FROM java:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java","-jar","/app.jar"]
4.构建镜像 docker build -t xxx .
5.启动运行 启动docker镜像
企业实战
docker compose
docker swarm
CI/CD jenkins 流水线
ata/redis/node-port/conf/redis.confcat<<EOF>/mydata/redis/node−{port}/conf/redis.conf cat << EOF >/mydata/redis/node-port/conf/redis.confcat<<EOF>/mydata/redis/node−{port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
启动redis服务
docker run -d -p 6371:6379 -p 16371:16379 --name redis-1
-v /mydata/redis/node-1/data:/data
-v /mydata/redis/node-1/redis.conf:/etc/redis/redis.conf
–net redis-net --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
一次启动(可以试试,不用6次)
docker run -d -p 637port:6379−p1637{port}:6379 -p 1637port:6379−p1637{port}:16379 --name redis-KaTeX parse error: Undefined control sequence: \ at position 8: {port} \̲ ̲-v /mydata/redi…{port}/data:/data
-v /mydata/redis/node-KaTeX parse error: Undefined control sequence: \ at position 41: …dis/redis.conf \̲ ̲--net redis-net…{port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;\
随便进入一个redis(没有bash)
docker exec -it redis-1 /bin/sh
创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
连接集群
redis-cli -c # -c才是连接集群,要不然就是单机
cluster info # 集群信息
cluster nodes # redis集群节点
## 8.springboot微服务打包docker镜像1.构建springboot项目2.打包应用 ==打包成jar包==3.编写dockerfile文件```dockerfile
FROM java:8COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java","-jar","/app.jar"]
4.构建镜像 docker build -t xxx .
5.启动运行 启动docker镜像
企业实战
docker compose
docker swarm
CI/CD jenkins 流水线
docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]相关推荐
- Docker入门知识|基本命令|数据卷|dockerfile|发布镜像|基本概念
文章目录 Docker 一.概述 二.安装 基本安装 阿里云镜像加速 三.基本 1.镜像启动流程 2.工作原理 3.帮助命令 4.镜像命令 5.容器命令 6.其它常用命令 7.Portainer可视化 ...
- Docker基础篇 - (六)Docker 网络Spring Boot微服务打包Docker镜像
⑦ Docker 网络 7.1 理解Docker0 清空下前面的docker 镜像.容器 # 删除全部容器 [root@cVzhanshi tomcat-diy]# docker rm -f $(do ...
- Docker(三) 使用容器数据卷实现数据持久化与容器数据共享
一,什么是容器数据卷 出现背景:我们在运行的容器中所产生的数据都生成在容器中,如果容器后期被我们删除,那么在容器中的文件数据都将彻底丢失.为了获得容器中的数据,只能通过 docker cp 命令将容器 ...
- docker入门实践之数据卷管理
在实际使用docker过程中,有时需要查看容器内应用产生的数据,或需要把容器内的数据进行备份,甚至是多个容器间需要共享数据,这势必涉及到数据管理,那么docker的数据怎么管理呢? 容器中数据管理主要 ...
- SpringBoot 入坑(八)Docker 暴露端口 容器数据卷 基本使用
Docker端口+数据卷 1).暴露端口 2).容器数据卷使用 1).暴露端口 1.在不暴露端口的情况下启动tomcat docker run -d --name mTM01 tomcat 通过宿主机 ...
- nginx作用_实战文档:彻底搞懂SpringBoot+微服务+Nginx+Docker+Tomcat
前言 微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦.你可以将其看作是在架构层次而非获取服务的类上应用很多S ...
- Docker基础讲解狂神笔记:容器数据卷,docker compose,docker swarm(2/2)未修订版欢迎留言补漏
L06 容器数据卷 相对于01-05难度加大 什么是容器数据卷 Docker理念:将应用和环境打包成一个镜像! 程序要保存数据,数据并不能放在容器里面,因为一旦数据放在容器,误操作删除掉容器,数据也随 ...
- Docker 使用容器数据卷 实现宿主机与容器共享数据 容器数据持久化
容器数据卷:可以实现宿主机与容器进行共享.容器数据持久化,容器与容器共享数据.可以在run镜像时使用-v参数指定宿主机与容器进行挂载的目录,也可以使用dockerfile的volume指定容器中容器数 ...
- Docker容器数据卷详解
文章目录 1. 数据卷介绍 2. 简单使用 3. MySQL容器建立数据卷同步数据 4. 常用命令 5. 具名挂载和匿名挂载 5.1 匿名挂载 5.2 具名挂载 6. Dockerfile中设置数据卷 ...
最新文章
- RxJava 操作符 do
- 新建arcgis api for android 项目失败
- win32 GDI 画图 防止闪烁
- Android NDK学习笔记4:JNI访问Java构造函数
- Linux sed命令完全攻略(超级详细)
- 容器编排技术 -- Kubernetes kubectl create service loadbalancer 命令详解
- 本地正常,部署放在IIS服务器上面偶尔会出现 列不属于表Table,因为多客户并发造成那个的问题
- 深入浅出数据分析:寻找最大值Solver
- 微信公众号开发相关流程及功能介绍
- 计算机如何格式化和重装系统,怎样格式化c盘重新安装系统_重装系统时如何格式化C盘...
- 【转】Java技能清单
- 口语语汇单词篇(7)
- 揽月摘星 | 第 13 届金鼠标数字营销大赛得奖名单出炉,知家斩获 5 项大奖
- oracle ora00940,ORA-32773问题的解决方法。
- 已知三角形的三边长a,b,c,利用海伦公式求三角形面积
- 【庖丁解牛】从零实现FCOS(终):CenterSample的重要性
- 论文笔记-Reliable Supervision from Transformations for Unsupervised Optical Flow Estimation
- otn与stn网络_全光网络:OTN与超长距离传输
- 职场必学的10个常用网站-活动策划
- ACM/ICPC 金牌进阶之路
热门文章
- 实战项目:医院挂号网(ui组件开发)
- lodop属性及方法介绍
- 实时查询引擎 - Apache Drill 介绍与应用
- 论文翻译:2020_DTLN:Dual-Signal Transformation LSTM Network for Real-Time Noise Suppression
- #今日论文推荐# 光子神经网络登上nature,图像识别速度降至1纳秒
- 转‘ROS学习心得——安装篇——ROS安装’
- 基于 Kafka 和 ZooKeeper 的分布式消息队列原理
- JAVA解决经典兔子问题(递归)
- 【蓝桥杯选拔赛真题58】Scratch打气球游戏 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析
- wmm开启和关闭的区别_一次搞懂VV阀、BDV阀、RFV阀的区别与用途