Docker 从入门到精通
Docker 从入门到精通
docker学习视频 B站:遇见狂神说
知道的越多,不知道的就越多!!!
1.Docker 概述
产品开发到上线,会有两套环境:开发环境、应用环境(应用配置)
开发即运维:项目的发布包括:jar包+配置环境
Docker 通过隔离机制,可以将服务器运行到极致!
vm:linux centos原生镜像 隔离,需要开启多个虚拟机 几个G 分钟级启动 docker:隔离 镜像(核心环境 4m+jdk+mysql)小巧 只运行镜像就可以 几个M 妙级启动
Docker是基于Go语言开发的开源项目
Docker官网地址:https://www.docker.com/
Docker文档地址:https://docs.docker.com/
Docker的仓库地址:https://hub.docker.com/
2.Docker安装
基本组件
镜像(image):
镜像就是一个模板,通过镜像来创建容器,镜像==》 run =》容器
容器(container):
Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建
启动,停止,删除,基本命令!
仓库(repository):
存放镜像的地方
安装docker
帮助文档:
#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 #阿里云的镜像 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #4、安装docker相关 docker-ce 社区版 ee 企业版 #更新软件包索引 yum makecache fase #安装相关 yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin #5、启动docker systemctl start docker #6、使用docker version 查看对应 docker version #7、验证hello-world docker run hello-world
#8、查看镜像 docker images #输出: #REPOSITORY TAG IMAGE ID CREATED SIZE #hello-world latest feb5d9fea6a5 23 months ago 13.3kB
了解卸载docekr
#卸载依赖 yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras #删除资源 rm -rf /var/lib/docker rm -rf /var/lib/containerd #/var/lib/docker docker的默认工作路径
阿里云镜像加速
网址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://7dawuuwc.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
底层原理
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
DockerServer 接收到Docker-Client的指令,就会执行这个命令!
Docker 为什么比VM快
- Docker的抽象层更少
- docker用的是宿主机的内核,vm需要是Guest OS
3.Docker的常用命令
帮助文档:https://docs.docker.com/reference/
帮助命令
docker version #显示docker的版本信息 docker info #显示docker的详细信息 docker 命令 --help #万用命令
镜像命令
1.查看镜像 images
docker images #[root@localhost ~]# docker images #REPOSITORY TAG IMAGE ID CREATED SIZE #hello-world latest feb5d9fea6a5 23 months ago 13.3kB #镜像的仓库源 镜像的标签 镜像的id 镜像的创建时间 镜像的大小 #可选项 -a, --all Show all images (default hides intermediate images) #列出所有镜像 -q, --quiet Only show image IDs #只显示镜像的id
2.搜索镜像 search
docker search #[root@localhost ~]# docker search mysql #NAME DESCRIPTION STARS OFFICIAL AUTOMATED #mysql MySQL is a widely used, open-source relation… 14384 [OK] #mariadb MariaDB Server is a high performing open sou… 5491 [OK] #可选项 -f, --filter filter Filter output based on conditions provided #过滤选项
3.下载镜像 pull
docker pull #[root@localhost ~]# docker pull mysql #Using default tag: latest #如果不写tag ,默认就是latest #latest: Pulling from library/mysql #72a69066d2fe: Pull complete #分层下载,docker images的核心, 联合文件系统 #93619dbc5b36: Pull complete #99da31dd6142: Pull complete #626033c43d70: Pull complete #37d5d7efb64e: Pull complete #ac563158d721: Pull complete #d2ba16033dad: Pull complete #688ba7d5c01a: Pull complete #00e060b6d11d: Pull complete #1c04857f594f: Pull complete #4d7cfa90e6ea: Pull complete #e0431212d27d: Pull complete #Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 #签名 #Status: Downloaded newer image for mysql:latest #docker.io/library/mysql:latest #真实地址 #两个命令是等价的 docker pull mysql docker pull docker.io/library/mysql:latest #指定版本下载 docker pull mysql:5.7 #[root@localhost ~]# docker pull mysql:5.7 #5.7: Pulling from library/mysql #72a69066d2fe: Already exists #联合文件系统的体现 共用资源 #93619dbc5b36: Already exists #99da31dd6142: Already exists #626033c43d70: Already exists #37d5d7efb64e: Already exists #ac563158d721: Already exists #d2ba16033dad: Already exists #0ceb82207cd7: Pull complete #37f2405cae96: Pull complete #e2482e017e53: Pull complete #70deed891d42: Pull complete #Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94 #Status: Downloaded newer image for mysql:5.7 #docker.io/library/mysql:5.7
4.删除镜像 rmi
docker rmi #[root@localhost ~]# docker rmi -f c20987f18b13 #Untagged: mysql:5.7 #Untagged: mysql@sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94 #Deleted: sha256:c20987f18b130f9d144c9828df630417e2a9523148930dc3963e9d0dab302a76 #Deleted: sha256:6567396b065ee734fb2dbb80c8923324a778426dfd01969f091f1ab2d52c7989 #Deleted: sha256:0910f12649d514b471f1583a16f672ab67e3d29d9833a15dc2df50dd5536e40f #Deleted: sha256:6682af2fb40555c448b84711c7302d0f86fc716bbe9c7dc7dbd739ef9d757150 #Deleted: sha256:5c062c3ac20f576d24454e74781511a5f96739f289edaadf2de934d06e910b92 #删除单个镜像 docker rmi -f 镜像id #删除多个镜像 docker rmi -f 镜像id 镜像id 镜像id 镜像id #删除全部的镜像 docker rmi -f $(docker images -aq)
容器命令
有了镜像之后才可以创建容器,通过下载centos镜像来测试
1.新建容器并启动 run
docker run [可选参数] image #参数说明 --name=“Name” 容器名字 用于区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器的端口 -p 8080:8080 4种方式 -p ip:主机端口:容器端口 -p 主机端口:容器端口 (常用) -p 容器端口 容器端口 -P(大写) 随机指定端口 #启动并进入容器 [root@localhost ~]# docker run -it centos /bin/bash [root@d20d35c75c5d /]# #从容器中退回到主机 exit [root@d20d35c75c5d /]# exit exit [root@localhost ~]#
2.退出容器 两种方式
#容器停止并退出 exit #容器不停止退出 Ctrl+P+Q
3.查看容器 ps
docker ps #列出当前在运行的容器 docker ps -a #列出当前在运行的容器+历史运行过的容器 docker ps -n=[] #显示最新创建的容器,个数 docker ps -q #只显示容器的编号 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d20d35c75c5d centos "/bin/bash" 19 minutes ago Exited (130) 8 seconds ago hungry_hertz e2e1924b8d54 feb5d9fea6a5 "/hello" 2 hours ago Exited (0) 2 hours ago mystifying_diffie
4.删除容器 rm
docker rm docker rm 容器id #删除指定的容器,不能删除在运行的容器,强制删除 rm -f docker rm -f $(docker ps -aq) #删除所有容器 docker ps -a -q | xargs docker rm #删除所有容器
5.启动和停止容器 start/restart/stop/kill
docker start 容器id #启动容器 docker restart 容器id #重启容器 docker stop 容器id #停止当前正在运行的容器 docker kill 容器id #强制停止当前容器
常用其他命令
1.后台启动容器 run -d
docker run -d 镜像名 [root@localhost ~]# docker run -d centos 7d93f91682b07e621cf565247a24c8bf7e3e25290a793e9e9961840776c52ce4 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES #问题:docker ps 时发现centos停止了 #常见的坑:docker容器使用后台运行,就必须有一个前台进程,docker发现没有应用,就会自动停止
2.查看日志 logs
docker logs 容器id #可选项 --details Show extra details provided to logs -f, --follow Follow log output --since string Show logs since timestamp (e.g. "2013-01-02T13:23:37Z") or relative (e.g. "42m" for 42 minutes) -n, --tail string Number of lines to show from the end of the logs (default "all") -t, --timestamps Show timestamps --until string Show logs before a timestamp (e.g. "2013-01-02T13:23:37Z") or relative (e.g. "42m" for 42 minutes) #显示最近10行 docker logs -tf --tail 10 容器
3.查看容器中进程信息 top
docker top 容器id [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 07059ea597cc centos "/bin/bash" 12 seconds ago Up 11 seconds stupefied_proskuriakova [root@localhost ~]# docker top 07059ea597cc UID PID PPID C STIME TTY TIME CMD root 4853 4833 0 22:28 pts/0 00:00:00 /bin/bash
4.查看镜像的元数据 inspect
docker inspect 容器id [root@localhost ~]# docker inspect 07059ea597cc [ { "Id": "07059ea597cc748afb87369a811e7f922f77a6f12f34148534967024a1276353", "Created": "2023-08-15T14:28:56.47618888Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 4853, "ExitCode": 0, "Error": "", "StartedAt": "2023-08-15T14:28:56.793337001Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6", "ResolvConfPath": "/var/lib/docker/containers/07059ea597cc748afb87369a811e7f922f77a6f12f34148534967024a1276353/resolv.conf", "HostnamePath": "/var/lib/docker/containers/07059ea597cc748afb87369a811e7f922f77a6f12f34148534967024a1276353/hostname", "HostsPath": "/var/lib/docker/containers/07059ea597cc748afb87369a811e7f922f77a6f12f34148534967024a1276353/hosts", "LogPath": "/var/lib/docker/containers/07059ea597cc748afb87369a811e7f922f77a6f12f34148534967024a1276353/07059ea597cc748afb87369a811e7f922f77a6f12f34148534967024a1276353-json.log", "Name": "/stupefied_proskuriakova", "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, "ConsoleSize": [ 42, 156 ], "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", "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": [], "BlkioDeviceWriteBps": [], "BlkioDeviceReadIOps": [], "BlkioDeviceWriteIOps": [], "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "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/8016f194e83a30d435c5198f2390a54f55a88afdc286f7fe23aa8599f5f4f8b8-init/diff:/var/lib/docker/overlay2/6b85255aee5f5ba8af05120724b86ddc99eb38125083580b88395e10d60c8c48/diff", "MergedDir": "/var/lib/docker/overlay2/8016f194e83a30d435c5198f2390a54f55a88afdc286f7fe23aa8599f5f4f8b8/merged", "UpperDir": "/var/lib/docker/overlay2/8016f194e83a30d435c5198f2390a54f55a88afdc286f7fe23aa8599f5f4f8b8/diff", "WorkDir": "/var/lib/docker/overlay2/8016f194e83a30d435c5198f2390a54f55a88afdc286f7fe23aa8599f5f4f8b8/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "07059ea597cc", "Domainname": "", "User": "", "AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Tty": true, "OpenStdin": true, "StdinOnce": true, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20210915", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "3aeaa502f85b75e9ee4fd2a3752747eb34709dce12bced7d1ad2a47be5a8eb3e", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/3aeaa502f85b", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "40ecb64fe767f67a07256010f47614403293554a2d6845520a95abc2cc6c436d", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "99a6c87d54159c287cb731088a4297dca4655987eb9a5a14cfefbff6dc7f8ee3", "EndpointID": "40ecb64fe767f67a07256010f47614403293554a2d6845520a95abc2cc6c436d", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ]
5. 进入当前运行的容器 exec/attach
#方式1:开始一个新的终端 docker exec -it 容器id /bin/bash #方式2,进入正在运行的命令行 docker attach 容器id
6.从容器内拷贝文件到主机 cp
docker cp 容器id:/home /home #拷贝是一个手动的过程,未来使用-v 卷的技术,实现自动同步
4.案例实战
1.部署Nginx
ngnix是一个高性能的HTTP和反向代理web服务器,主要功能包括:HTTP服务器、FTP服务器、反向代理、负载均衡。
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。
#Docker 安装Nginx #1.搜索镜像 docker search nginx #2.拉取镜像 docker pull nginx #3.启动镜像 docker run -d --name nginx01 -p 3344:80 nginx -d 后台运行 --name 给容器命名 -p 暴露端口 宿主机端口:容器端口 #4.查看容器 docker ps [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b7ac4311bf45 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01 #5.通过curl访问 curl localhost:3344 [root@localhost ~]# curl localhost:3344 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> #6.进入容器 docker exec -it b7ac4311bf45 /bin/bash [root@localhost ~]# docker exec -it b7ac4311bf45 /bin/bash root@b7ac4311bf45:/#
2.部署Tomcat
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP (java server pages)程序的首选。
#官方的使用方法 docker run -it --rm tomcat:9.0 -it 前端运行 --rm 用完之后,即删除容器 #1.拉取镜像 docker pull tomcat:9.0 #2.运行镜像 docker run -d -p 3355:8080 --name tomcat01 tomcat #测试访问没有问题 192.168.32.6:3355 #3.查看容器 docker ps [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ad94afba89a tomcat "catalina.sh run" 45 seconds ago Up 44 seconds 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01 #4.进入容器 [root@localhost ~]# docker exec -it tomcat01 /bin/bash #发现问题:1.linux命令少了 2.没有webapps。 阿里云镜像的原因,默认是最小的镜像,所以不必要的都要剔除掉。 #保证最小可运行的命令
3.部署ES+Kibana 包括 docker stats 查看CPU的状态
Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。
Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。
#es 暴露的端口很多 #es 十分的耗内存 #es 的数据一般需要放置到安全目录!挂载 # --net somenetwork 网络配置 #1.下载并启动 docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 #启动后发现,虚拟机非常卡 #es十分耗费内存 #查看CPU状态 docker stats 容器id #测试一下es是否成功 [root@localhost ~]# curl localhost:9200 { "name" : "f15ff08f7f6e", "cluster_name" : "docker-cluster", "cluster_uuid" : "X9A7tOWDToqSVEOYGPCrug", "version" : { "number" : "7.6.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f", "build_date" : "2020-03-26T06:34:37.794943Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } #增加内存限制,通过修改配置 -e 环境配置修改 -e ES_JAVA_OPTS="-Xms64m -Xms512m"
使用Kibana连接 ES 通过网络才能连接过去
5.可视化管理工具
- portainer
docker图形化界面管理工具!提供后台面板供我们操作!
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer #访问测试 http://ip:8088/
- Rancher(做CI/DI)
6.Docker镜像
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
如何得到镜像:
- 从远程仓库下载 - 朋友拷贝 - 自己制作一个镜像 DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
联合文件系统(Union File System,Unionfs)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
docker 的镜像实际上有一层一层的文件系统组成,这种层级的文件系统是UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system),在bootfs之上。包含的就是典型Linux.系统中的/dev, /proc, /bin, /etc等标准目录和文件。roots就是各种不同的操作系统发行版,比如Ubuntu ,Centos等等。
分层理解
#[root@localhost ~]# docker pull mysql #Using default tag: latest #如果不写tag ,默认就是latest #latest: Pulling from library/mysql #72a69066d2fe: Pull complete #分层下载,docker images的核心, 联合文件系统 #93619dbc5b36: Pull complete #99da31dd6142: Pull complete #626033c43d70: Pull complete #37d5d7efb64e: Pull complete #ac563158d721: Pull complete #d2ba16033dad: Pull complete #688ba7d5c01a: Pull complete #00e060b6d11d: Pull complete #1c04857f594f: Pull complete #4d7cfa90e6ea: Pull complete #e0431212d27d: Pull complete #Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 #签名 #Status: Downloaded newer image for mysql:latest #docker.io/library/mysql:latest #真实地址
特点
Docker镜像都是只读的,当容器启动时,一个新的可写成被加载到镜像的顶部!
这一层就是我们常说的容器层,容器之下的都叫镜像层!
提交镜像 commit
docker commit 提交容器成为一个新的副本 #命令和git原理类似 docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
#启动一个默认的tomcat docker run tomcat -p 3355:8080 -it /bin/bash #发现这个默认的tomcat是没有webapps应用的 #自己拷贝进去基本文件 cp -r webapps.dist/* webapps #退出容器 exit #提交做好的容器,就变成我们自己的镜像了 docker commit -m="add webapps app" -a="ssl" 3ad94afba89a tomcat02:1.0 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat02 1.0 aeb8fc0772c0 44 seconds ago 684MB
7.容器数据卷
什么是容器数据卷
满足数据的持久化,容器之间可以有一个数据共享的技术,docker容器中产生的数据,同步到本地!
卷技术:目录的挂载,将容器内的目录挂载到linux上。
总结:容器的持久化和同步操作!容器间也是可以共享数据的!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 本地目录:容器内目录 #Mount 挂载 #启动起来时候,我们可以通过docker inspect 容器id 来查看
修改只需要在本地修改即可,容器内会自动同步!
实战:安装MySQL
#1.查找镜像 docker search mysql #2.拉取镜像 docker pull mysql:5.7 #注意:安装启动mysql是需要配置密码的!!! -e MYSQL_ROOT_PASSWORD= #3.运行容器,需要做数据挂载 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=123456 --name mysql01 mysql:5.7 #虚拟机别忘记开放端口firewall-cmd --permanent --add-port=3310/tcp #重启防火墙firewall-cmd --reload #查款端口开放情况 firewall-cmd --list-all #关闭防火墙 systemctl stop firewalld.service #查看防火前状态 systemctl status firewalld.service #5.7版本的mysql 可能会连接不上 可以下载最新版 用navicat进行连接 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=123456 --name mysql01 mysql
具名挂载和匿名挂载(docker volume inspect juming-nginx)
#匿名挂载 -v 容器内路径! docker run -d -P --name nginx01 -v /etc/nginx nginx #查看所有volume的情况 [root@localhost conf]# docker volume ls DRIVER VOLUME NAME local 6a5a5bee778cc035359622b5565ea7b279b0e2f246e55e977700cadee70858f3 local 7f295bb8f25ab495cd9ceb9cf26d2ec937799eb96a0c0d1b1feea6f75fad27c5 local bf14cab87c46f8bc8eb33a3f56f15a0c387e4caa5fa7263ad2c65566204842c4 #这种及时匿名挂载的 #具名挂载 #通过-v 卷名:容器内路径 docker run -d -P --name nginx02 -v jvming-nginx:/etc/nginx nginx [root@localhost conf]# docker volume ls DRIVER VOLUME NAME local jvming-nginx #查看一下当前卷 docker volume inspect juming-nginx [root@localhost conf]# docker volume inspect jvming-nginx [ { "CreatedAt": "2023-08-16T21:37:57+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/jvming-nginx/_data", "Name": "jvming-nginx", "Options": null, "Scope": "local" } ]
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumnes/xxxxx/_
通过具名挂载可以方便找到我们的一个卷,大多数情况下使用具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载! -v 容器内路径 #匿名挂载 -v 卷名:容器内目录 #具名挂载 -v /宿主机路径:容器内路径 #路径挂载
拓展:
#通过 -v 容器内路径:ro rw 改变读写权限 ro readonly #只读 rw readwrite #可读可写 docker run -d -P --name nginx02 -v jv:/etc/nginx:ro nginx # 只能通过宿主机来操作 docker run -d -P --name nginx02 -v jv:/etc/nginx:rw nginx
初识Dockerfile (docker build)
方式二:在构建容器的时候进行数据卷挂载
Dockerfile就是用来构建docker镜像的构建文件!命令脚本
通过脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层
#创建一个docekrfile文件,名字可以随机,建议Dockerfile #文件中的内容 指令(大写) 参数 FROM centos VOLUME ["volume01","volume02"] CMD echo "---end---" CMD /bin/bash #这里的每个命令都是镜像的一层
#通过dockerfile构建镜像 [root@localhost docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t ssl/centos:1.0 . [+] Building 0.0s (5/5) FINISHED docker:default => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from dockerfile1 0.0s => => transferring dockerfile: 177B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:139235ade34847ff60bb087950d6bfc135d69865c42012862ca936647598ae1e 0.0s => => naming to docker.io/ssl/centos:1.0 0.0s #查看镜像 [root@localhost docker-test-volume]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ssl/centos 1.0 139235ade348 23 months ago 231MB #启动一下自己写的容器 [root@localhost docker-test-volume]# docker run -it 139235ade348 /bin/bash [root@2d361c9080ac /]# ls -l total 60 lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x. 5 root root 360 Aug 17 02:41 dev drwxr-xr-x. 1 root root 4096 Aug 17 02:41 etc drwxr-xr-x. 2 root root 4096 Nov 3 2020 home lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------. 2 root root 4096 Sep 15 2021 lost+found drwxr-xr-x. 2 root root 4096 Nov 3 2020 media drwxr-xr-x. 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x. 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x. 227 root root 0 Aug 17 02:41 proc dr-xr-x---. 2 root root 4096 Sep 15 2021 root drwxr-xr-x. 11 root root 4096 Sep 15 2021 run lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x. 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x. 13 root root 0 Aug 17 02:13 sys drwxrwxrwt. 7 root root 4096 Sep 15 2021 tmp drwxr-xr-x. 12 root root 4096 Sep 15 2021 usr drwxr-xr-x. 20 root root 4096 Sep 15 2021 var drwxr-xr-x. 2 root root 4096 Aug 17 02:41 volume01 #这两个目录就是我们生成镜像的时候自动挂载的 drwxr-xr-x. 2 root root 4096 Aug 17 02:41 volume02 #这个卷和外部一定有一个同步的目录! #VOLUME ["volume01","volume02"] #这种写作方式是匿名挂载 #查看容器 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3a724e015c08 139235ade348 "/bin/bash" 2 minutes ago Up 2 minutes vigorous_bell #查看容器信息 [root@localhost ~]# docker inspect 3a724e015c08 [ { "Id": "3a724e015c0866b7ae1ca89eda0b3e4e67ecbd6f2d55b66d497cd5c8a267a190", "Created": "2023-08-17T02:45:00.946167469Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 2405, "ExitCode": 0, "Error": "", "StartedAt": "2023-08-17T02:45:01.80904947Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:139235ade34847ff60bb087950d6bfc135d69865c42012862ca936647598ae1e", "ResolvConfPath": "/var/lib/docker/containers/3a724e015c0866b7ae1ca89eda0b3e4e67ecbd6f2d55b66d497cd5c8a267a190/resolv.conf", "HostnamePath": "/var/lib/docker/containers/3a724e015c0866b7ae1ca89eda0b3e4e67ecbd6f2d55b66d497cd5c8a267a190/hostname", "HostsPath": "/var/lib/docker/containers/3a724e015c0866b7ae1ca89eda0b3e4e67ecbd6f2d55b66d497cd5c8a267a190/hosts", "LogPath": "/var/lib/docker/containers/3a724e015c0866b7ae1ca89eda0b3e4e67ecbd6f2d55b66d497cd5c8a267a190/3a724e015c0866b7ae1ca89eda0b3e4e67ecbd6f2d55b66d497cd5c8a267a190-json.log", "Name": "/vigorous_bell", "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, "ConsoleSize": [ 42, 156 ], "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", "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": [], "BlkioDeviceWriteBps": [], "BlkioDeviceReadIOps": [], "BlkioDeviceWriteIOps": [], "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "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/849f489cc93a2d6c05d52e52fb9eb3f4751a99fc417db66166d66deca70c7c16-init/diff:/var/lib/docker/overlay2/6b85255aee5f5ba8af05120724b86ddc99eb38125083580b88395e10d60c8c48/diff", "MergedDir": "/var/lib/docker/overlay2/849f489cc93a2d6c05d52e52fb9eb3f4751a99fc417db66166d66deca70c7c16/merged", "UpperDir": "/var/lib/docker/overlay2/849f489cc93a2d6c05d52e52fb9eb3f4751a99fc417db66166d66deca70c7c16/diff", "WorkDir": "/var/lib/docker/overlay2/849f489cc93a2d6c05d52e52fb9eb3f4751a99fc417db66166d66deca70c7c16/work" }, "Name": "overlay2" }, "Mounts": [ { "Type": "volume", "Name": "fc3c449184d5bc6bd0ca68b4ece7d38b464c92a13bf960c62d3125266a95ee4e", "Source": "/var/lib/docker/volumes/fc3c449184d5bc6bd0ca68b4ece7d38b464c92a13bf960c62d3125266a95ee4e/_data", "Destination": "volume02", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "19dd50051fb5581c42917af92a59691a8be25ded67c9b777d98678b631c65c6a", "Source": "/var/lib/docker/volumes/19dd50051fb5581c42917af92a59691a8be25ded67c9b777d98678b631c65c6a/_data", "Destination": "volume01", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], "Config": { "Hostname": "3a724e015c08", "Domainname": "", "User": "", "AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Tty": true, "OpenStdin": true, "StdinOnce": true, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "Image": "139235ade348", "Volumes": { "volume01": {}, "volume02": {} }, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20210915", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "8d0824dec434c40cb51f22f7da3e4c8df490989bdeff608220778c51bf4bb187", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/8d0824dec434", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "240bccf433e7293060264c980b58e523cafc809978c2c4b2525ad4ec57ccd1db", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "7eb718801946dc33be130c0eff359ae7559c8308352109bdfd22da49f3e72ac9", "EndpointID": "240bccf433e7293060264c980b58e523cafc809978c2c4b2525ad4ec57ccd1db", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ]
数据卷容器
实现容器之间的数据共享
--volume-from 容器名
# 启动三个容器 [root@localhost /]# docker run -it --name docker01 139235ade348 [root@2311e2c7fae5 /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02 #容器卷挂载 [root@localhost /]# docker run -it --name docker02 --volumes-from docker01 139235ade348 [root@79d0de7f27e5 /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02 #进入容器 docker01 并创建 docker01文件 [root@localhost docker-test-volume]# docker attach docker01 [root@2311e2c7fae5 /]# cd /volume01 [root@2311e2c7fae5 volume01]# ls [root@2311e2c7fae5 volume01]# touch docker01 #在docker02中查看 [root@79d0de7f27e5 /]# cd volume01 [root@79d0de7f27e5 volume01]# ls docker01 #创建一个docker03,并查看 [root@localhost /]# docker run -it --name docker03 --volumes-from docker01 139235ade348 [root@ae845087ca4c /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02 [root@ae845087ca4c /]# cd volume01 [root@ae845087ca4c volume01]# ls docker01
多个mysql之间实现数据共享
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=123456 --name mysql01 mysql docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql #这个时候就可以实现两个容器数据同步!
结论:
- 容器之间配置信息的传递,数据卷容器的生命周期会一直持续到没有容器使用为止。但是一旦持久化到了本地,这个时候,本地的数据是不会删除的!
8.DockerFile
DockerFile介绍
dockerfile 是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库)
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下顺序执行
3、# 表示注释
4、每一个指令都会创建提交一个新的镜像层并提交!
dockerfile是面向开发的,我们以后要发布项目,作镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准,必须要掌握!
步骤:开发、部署、运维
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布出去
Docker容器:容器就是镜像运行起来提供服务器
DockerFile的指令
FROM #基础镜像 centos ubuntu 一切从这里开始构建 MAINTAINER #此命令已经过时了,维护者信息:姓名+邮箱 LABEL RUN #镜像构建的时候需要运行的命令 ADD #添加内容 步骤:假设构建tomcat镜像,这个tomcat的压缩包添加进去 WORKDIR #镜像的工作目录 VOLUME #挂载的目录 EXPOSE #暴露端口配置 CMD #指定这个容器启动时要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT #entrypoint 指定这个容器启动时要运行的命令,可以追加命令 ONBUILD #触发指令 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令。 #ONBUILD是一个特殊的指令它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的 时候才会被执行 COPY #类似ADD,将文件拷贝到镜像中 ENV #构建的时候设置环境变量!-e
实战测试(docker history)
Docker Hub中 99%镜像都是从这个基础镜像过来的 FROM scratch
创建自己的centos
#编写配置文件 FROM centos MAINTAINER ssl<ssl@qq.com> ENV MYPATH /user/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 #镜像存在问题 FROM centos MAINTAINER ssl<ssl@qq.com> ENV MYPATH /user/local WORKDIR $MYPATH RUN cd /etc/yum.repos.d/ RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* RUN yum makecache RUN yum update -y RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "----end----" CMD /bin/bash #创建镜像 [root@localhost dockerfile]# docker build -f mydockerfile -t mycentos:0.1 . [+] Building 52.6s (13/13) FINISHED docker:default => [internal] load build definition from mydockerfile 0.0s => => transferring dockerfile: 537B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => [1/9] FROM docker.io/library/centos 0.0s => CACHED [2/9] WORKDIR /user/local 0.0s => [3/9] RUN cd /etc/yum.repos.d/ 0.3s => [4/9] RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* 0.3s => [5/9] RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* 0.3s => [6/9] RUN yum makecache 8.9s => [7/9] RUN yum update -y 31.6s => [8/9] RUN yum -y install vim 6.1s => [9/9] RUN yum -y install net-tools 2.0s => exporting to image 3.0s => => exporting layers 3.0s => => writing image sha256:5f83b634a5bae4ee1720477d4ec7a76245a032c84354f3942c3affa405b47d48 0.0s => => naming to docker.io/library/mycentos:0.1 0.0s
#查看构建历史 docker history 镜像id [root@localhost dockerfile]# docker history 5f83b634a5ba IMAGE CREATED CREATED BY SIZE COMMENT 5f83b634a5ba 4 minutes ago CMD ["/bin/sh" "-c" "/bin/bash"] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago CMD ["/bin/sh" "-c" "echo \"----end----\""] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago CMD ["/bin/sh" "-c" "echo $MYPATH"] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago RUN /bin/sh -c yum -y install net-tools # bu… 28.8MB buildkit.dockerfile.v0 <missing> 4 minutes ago RUN /bin/sh -c yum -y install vim # buildkit 67.3MB buildkit.dockerfile.v0 <missing> 4 minutes ago RUN /bin/sh -c yum update -y # buildkit 276MB buildkit.dockerfile.v0 <missing> 5 minutes ago RUN /bin/sh -c yum makecache # buildkit 27.4MB buildkit.dockerfile.v0 <missing> 5 minutes ago RUN /bin/sh -c sed -i 's|#baseurl=http://mir… 8.8kB buildkit.dockerfile.v0 <missing> 5 minutes ago RUN /bin/sh -c sed -i 's/mirrorlist/#mirrorl… 8.82kB buildkit.dockerfile.v0 <missing> 5 minutes ago RUN /bin/sh -c cd /etc/yum.repos.d/ # buildk… 0B buildkit.dockerfile.v0 <missing> 8 minutes ago WORKDIR /user/local 0B buildkit.dockerfile.v0 <missing> 8 minutes ago ENV MYPATH=/user/local 0B buildkit.dockerfile.v0 <missing> 8 minutes ago MAINTAINER ssl<ssl@qq.com> 0B buildkit.dockerfile.v0 <missing> 23 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 23 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 23 months ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0… 231MB
CMD 和 ENTRYPOINT 的区别
CMD #指定这个容器启动时要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT #entrypoint 指定这个容器启动时要运行的命令,可以追加命令
测试CMD
#构建dockerfile文件 [root@localhost dockerfile]# vim dockerfile_cmd_test [root@localhost dockerfile]# cat dockerfile_cmd_test FROM centos CMD ["ls","-a"] #构建镜像 [root@localhost dockerfile]# docker build -f dockerfile_cmd_test -t cmdtest . [+] Building 0.2s (5/5) FINISHED docker:default => [internal] load build definition from dockerfile_cmd_test 0.0s => => transferring dockerfile: 134B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => CACHED [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:7d202bdf002be182b794b7f2b4c90c4fe3560c3ac4f8cebc27f1c8a94ab10a9a 0.0s => => naming to docker.io/library/cmdtest 0.0s [root@localhost dockerfile]# #run 发现ls -a 命令生效 [root@localhost dockerfile]# docker run 7d202bdf002b . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var # 想追加一个命令 -l ==》 ls -al [root@localhost dockerfile]# docker run 7d202bdf002b -l docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown. ERRO[0000] error waiting for container: #cmd的清理下 -l 替代了CMD ["ls","-a"]命令,-l 不是命令所以报错 #正确运行 [root@localhost dockerfile]# docker run 7d202bdf002b ls -al total 60 drwxr-xr-x. 1 root root 4096 Aug 17 06:56 . drwxr-xr-x. 1 root root 4096 Aug 17 06:56 .. -rwxr-xr-x. 1 root root 0 Aug 17 06:56 .dockerenv lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x. 5 root root 340 Aug 17 06:56 dev drwxr-xr-x. 1 root root 4096 Aug 17 06:56 etc drwxr-xr-x. 2 root root 4096 Nov 3 2020 home lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------. 2 root root 4096 Sep 15 2021 lost+found drwxr-xr-x. 2 root root 4096 Nov 3 2020 media drwxr-xr-x. 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x. 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x. 243 root root 0 Aug 17 06:56 proc dr-xr-x---. 2 root root 4096 Sep 15 2021 root drwxr-xr-x. 11 root root 4096 Sep 15 2021 run lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x. 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x. 13 root root 0 Aug 17 02:13 sys drwxrwxrwt. 7 root root 4096 Sep 15 2021 tmp drwxr-xr-x. 12 root root 4096 Sep 15 2021 usr drwxr-xr-x. 20 root root 4096 Sep 15 2021 var
测试ENTRYPOINT
#构建dockerfile [root@localhost dockerfile]# vim dockerfile-entrypoint-test [root@localhost dockerfile]# cat dockerfile-entrypoint-test FROM centos ENTRYPOINT ["ls","-a"] #构建镜像 [root@localhost dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint . [+] Building 0.1s (5/5) FINISHED docker:default => [internal] load build definition from dockerfile-entrypoint-test 0.0s => => transferring dockerfile: 148B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => CACHED [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:b325f5b972337e763ad3b2c0f1a720eb2d5b11a39b3d88008cc5a0e42393b617 0.0s => => naming to docker.io/library/entrypoint 0.0s [root@localhost dockerfile]# #运行 [root@localhost dockerfile]# docker run entrypoint . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var #追加运行,直接生效 [root@localhost dockerfile]# docker run entrypoint -l total 60 drwxr-xr-x. 1 root root 4096 Aug 17 07:03 . drwxr-xr-x. 1 root root 4096 Aug 17 07:03 .. -rwxr-xr-x. 1 root root 0 Aug 17 07:03 .dockerenv lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x. 5 root root 340 Aug 17 07:03 dev drwxr-xr-x. 1 root root 4096 Aug 17 07:03 etc drwxr-xr-x. 2 root root 4096 Nov 3 2020 home lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64 drwx------. 2 root root 4096 Sep 15 2021 lost+found drwxr-xr-x. 2 root root 4096 Nov 3 2020 media drwxr-xr-x. 2 root root 4096 Nov 3 2020 mnt drwxr-xr-x. 2 root root 4096 Nov 3 2020 opt dr-xr-xr-x. 238 root root 0 Aug 17 07:03 proc dr-xr-x---. 2 root root 4096 Sep 15 2021 root drwxr-xr-x. 11 root root 4096 Sep 15 2021 run lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin drwxr-xr-x. 2 root root 4096 Nov 3 2020 srv dr-xr-xr-x. 13 root root 0 Aug 17 02:13 sys drwxrwxrwt. 7 root root 4096 Sep 15 2021 tmp drwxr-xr-x. 12 root root 4096 Sep 15 2021 usr drwxr-xr-x. 20 root root 4096 Sep 15 2021 var
实战:Tomcat镜像(有问题)
1、 准备镜像文件 tomcat压缩包,jdk的压缩包
#下载jdk wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz
2、编写dockerfile文件,官方命名Dockerfile
,build会自动寻找这个文件,不需要-f 指定
#Dockerfile 文件 FROM centos MAINTAINER ssl<ssl@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u131-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.79.tar.gz /usr/local/ RUN cd /etc/yum.repos.d/ RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* RUN yum makecache RUN yum update -y RUN yum -y install vim RUN yum -y install net-tools ENV MYPATH /usr/local WORK $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_131 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.79 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.79 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.79/bin/startup.sh && tail -F /url/localapache-tomcat-9.0.79/bin/catalina.out
3、构建镜像
[root@localhost tomcat]# docker build -t diytomcat . [+] Building 64.2s (17/17) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 984B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => CACHED [ 1/12] FROM docker.io/library/centos 0.0s => [internal] load build context 1.1s => => transferring context: 197.28MB 1.1s => [ 2/12] COPY readme.txt /usr/local/readme.txt 0.1s => [ 3/12] ADD jdk-8u131-linux-x64.tar.gz /usr/local/ 2.8s => [ 4/12] ADD apache-tomcat-9.0.79.tar.gz /usr/local/ 0.2s => [ 5/12] RUN cd /etc/yum.repos.d/ 0.3s => [ 6/12] RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* 0.3s => [ 7/12] RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* 0.3s => [ 8/12] RUN yum makecache 11.9s => [ 9/12] RUN yum update -y 35.8s => [10/12] RUN yum -y install vim 6.2s => [11/12] RUN yum -y install net-tools 1.8s => [12/12] WORKDIR /usr/local 0.0s => exporting to image 3.1s => => exporting layers 3.1s => => writing image sha256:c2a8685d07c6e92939d41c19f99f777caeb774852b8d5d305cfdf113762cb3eb 0.0s => => naming to docker.io/library/diytomcat #查看镜像 [root@localhost tomcat]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE diytomcat latest c2a8685d07c6 46 seconds ago 1.02GB
4、启动镜像,运行tomcat
#运行镜像 docker run -d -p 9090:8080 --name ssltamcat -v /home/ssl/build/tomcat/test:/usr/local/apache-tomcat-9.0.79/webapps/test -v /home/ssl/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.79/logs diytomcat #在linux上访问 curl localhost:9090
5、访问测试
6、发布项目
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.5"> </web-app> #第二种 <?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/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.0" metadata-complete="true"> <display-name>Router for Tomcat</display-name> <error-page> <error-code>404</error-code> <location>/index.html</location> </error-page> </web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello ssl</title> </head> <body> Hello World! <br/> <% System.out.println("--------my test web logs---------"); %> </body> </html>
这两个文件可能有问题!!! 没有调通.....
发布镜像 (docker login/logout、docker push、docker tag)
DockerHub
1、地址 https://hub.docker.com/ 注册自己的账号
2、确定这个账号可以登录
3、在我们服务器上提交自己的镜像
[root@localhost ~]# docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username #登录 docekr login -u sslgogogo -p xxxxx [root@localhost ~]# docker login -u sslgogogo -p xxxx WARNING! Using --password via the CLI is insecure. Use --password-stdin. WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
4、登录成功之后,就可以提交镜像了 docker push
docker tag 镜像id 新名字 [root@localhost ~]# docker tag c2a8685d07c6 ssl/tomcat:1.0 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ssl/tomcat 1.0 c2a8685d07c6 2 hours ago 1.02GB #这样就可以push上去了 [root@localhost ~]# docker push ssl/tomcat:1.0 The push refers to repository [docker.io/ssl/tomcat] 5f70bf18a086: Preparing 11e0495cb651: Preparing 6739317a3c45: Preparing 5eb8a0e3085c: Preparing 142625a35063: Preparing 13b009d6135a: Waiting 6272ae3d80c5: Waiting 7eba5634d3a1: Waiting 9f69748d6fe8: Waiting #需要设置好docker仓库
提交也是按照层级提交!!!
阿里云镜像服务 https://cr.console.aliyun.com/cn-hangzhou/instance/repositories
1、登陆阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建镜像仓库
5、登录阿里云
6、push
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/ssl_study/ssl-test:[镜像版本号] docker push registry.cn-hangzhou.aliyuncs.com/ssl_study/ssl-test:[镜像版本号] [root@localhost ~]# docker push registry.cn-hangzhou.aliyuncs.com/ssl_study/ssl-test:1.0 The push refers to repository [registry.cn-hangzhou.aliyuncs.com/ssl_study/ssl-test] 74ddd0ec08fa: Pushed 1.0: digest: sha256:40fb8d8b173aae6f0cfb57b9ab5485f63af1f65b2e0fc84f699efd563591e5fd size: 529
小结 (docker save,docker load)
docker save 镜像id #打包压缩包 docker load 镜像id #加载压缩包
9.Docker网络
理解docker0
测试
[root@localhost ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:46:2c:6d brd ff:ff:ff:ff:ff:ff inet 192.168.32.6/24 brd 192.168.32.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::ecdb:1808:fe2d:6090/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:08:d4:33:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:8ff:fed4:3305/64 scope link valid_lft forever preferred_lft forever # lo 本机回环地址 # ens33 内网地址 # docker0 地址
发现有三个网络
#问题:docker 是如何处理容器访问的? #[root@localhost ~]# docker run -d -P --name tomcat01 tomcat #查看容器的内部网络地址 ip addr #发现没有找ip addr 命令 #查看系统版本 root@27a0ad90c575:/usr/local/tomcat# cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" NAME="Debian GNU/Linux" VERSION_ID="11" VERSION="11 (bullseye)" VERSION_CODENAME=bullseye ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" #在debian系统中的操作 # 进入配置文件 cd /etc/apt # 查看目录信息 ls cat sources.list # 备份 mkdir cat sources.list.backup cp sources.list ./sources.list.backup cd ../ # 以覆盖+追加的方式替换掉sources.list文件 echo 'deb https://mirrors.aliyun.com/debian bullseye main'>sources.list echo 'deb https://mirrors.aliyun.com/debian-security bullseye-security main'>>sources.list echo 'deb https://mirrors.aliyun.com/debian bullseye-updates main'>>sources.list # 执行一下更新命令: apt-get update -y # 执行下载 iproute2命令: apt install -y iproute2 #继续查看容器的内部网络地址 ip addr [root@localhost ~]# docker exec -it tomcat01 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 66: eth0@if67: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever #发现容器启动的时候,就会得到一个 eth0@XX 的ip地址,这个地址是有docker分配的。 #思考。linux能不能 ping 通容器内部? #如果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.088 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.075 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.041 ms 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.139 ms # linux 可以ping 通 docker 容器内部
★ Linux系统分为两种:
1.RedHat系列:Redhat、Centos、Fedora等
2.Debian系列:Debian、Ubuntu等
- RedHat系列的包管理工具是yum
- Debian系列的包管理工具是apt-get
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0 桥接模式,使用的技术是 evth-pair 技术!
#发现多了一对网卡 容器 66:67 主机 67:66 [root@localhost ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:46:2c:6d brd ff:ff:ff:ff:ff:ff inet 192.168.32.6/24 brd 192.168.32.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::ecdb:1808:fe2d:6090/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:08:d4:33:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:8ff:fed4:3305/64 scope link valid_lft forever preferred_lft forever 67: vethfeea82d@if66: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 2a:e6:ee:f6:f6:e3 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::28e6:eeff:fef6:f6e3/64 scope link valid_lft forever preferred_lft forever
# 我们发现容器带来的网卡,都是一对对的 # evth-pair 就是一对的虚拟设备接口,都是成对出现的,一段连着协议,一段彼此相连 # 正是因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的 # OpenStac、Docker容器之间的连接,OVS的连接,都是使用 evth-pair 技术
2、再启动一个容器
#发现又多了一对网卡 [root@localhost ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:46:2c:6d brd ff:ff:ff:ff:ff:ff inet 192.168.32.6/24 brd 192.168.32.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::ecdb:1808:fe2d:6090/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:08:d4:33:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:8ff:fed4:3305/64 scope link valid_lft forever preferred_lft forever 67: vethfeea82d@if66: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 2a:e6:ee:f6:f6:e3 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::28e6:eeff:fef6:f6e3/64 scope link valid_lft forever preferred_lft forever 69: veth4fed851@if68: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 26:ee:49:35:c1:d9 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::24ee:49ff:fe35:c1d9/64 scope link valid_lft forever preferred_lft forever #发现又多了一对网卡
3、测试 tomcat01 和 tomcat02 是否可以ping通?
# 安装ping命令 apt-get install inetutils-ping #容器和容器之间是可以互相ping通的!!! [root@localhost ~]# docker exec -it tomcat01 ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@localhost ~]# docker exec -it tomcat02 ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@localhost ~]# docker exec -it tomcat01 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.073 ms 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.096 ms ^C--- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.073/0.084/0.096/0.000 ms
结论:tomcat01和tomcat02是共用一个路由器,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可以用IP
#ipv4地址分类 #A类IP地址 #一个A类IP地址由1字节的网络地址和3字节主机地址组成,它主要为大型网络而设计的,网络地址的最高位必须是“0”, 地址范围从1.0.0.0 到127.0.0.0)。可用的A类网络有127个,每个网络能容纳16777214个主机。其中127.0.0.1是一个特殊的IP地址,表示主机本身,用于本地机器的测试。 #注 A:0-127,其中0代表任何地址,127为回环测试地址,因此,A类ip地址的实际范围是1-126. #默认子网掩码为255.0.0.0 #B类IP地址 #一个B类IP地址由2个字节的网络地址和2个字节的主机地址组成,网络地址的最高位必须是“10”,地址范围从128.0.0.0到191.255.255.255。可用的B类网络有16382个,每个网络能容纳6万多个主机 。 #注:B:128-191,其中128.0.0.0和191.255.0.0为保留ip,实际范围是128.1.0.0--191.254.0.0。 #C类IP地址 #一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址的最高位必须是“110”。范围从192.0.0.0到223.255.255.255。C类网络可达209万余个,每个网络能容纳254个主机。 #注:C:192-223,其中192.0.0.0和223.255.255.0为保留ip,实际范围是192.0.1.0--223.255.254.0 #D类IP地址 #用于多点广播(Multicast)。 D类IP地址第一个字节以“lll0”开始,它是一个专门保留的地址。它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。224.0.0.0到239.255.255.255用于多点广播 。 #E类IP地址 #以“llll0”开始,为将来使用保留。240.0.0.0到255.255.255.254,255.255.255.255用于广播地址。 #全零(“0.0.0.0”)地址对应于当前主机。全“1”的IP地址(“255.255.255.255”)是当前子网的广播地址。
255.255.0.1/24 24代表一个域! 个人理解是网络分类 24位网络地址,即C类。
16代表 255*255
24代表 255
小结
Docker 使用的是Linux的桥接,宿主机中是一个Docker容器的网桥 docker0
容器互联 --link (docker network) 仅理解即可!!不推荐使用
思考一个场景,我们编写了一个微服务,database url=ip: ,项目库ip换掉了,我们希望可以处理这个问题,可以通过名字来访问容器?
#通过服务名来访问,发现ping不通 [root@localhost ~]# docker exec -it tomcat01 ping tomcat02 ping: unknown host #如何解决这个问题? 通过--link [root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat 21c13b1b39fb15ea755bd82ab1f0ebd6f953716bab43b908d57d7cd89b46f87f [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 21c13b1b39fb tomcat "catalina.sh run" 10 seconds ago Up 8 seconds 0.0.0.0:32770->8080/tcp, :::32770->8080/tcp tomcat03 ad22a445a44d tomcat "catalina.sh run" 13 days ago Up 50 minutes 0.0.0.0:32768->8080/tcp, :::32768->8080/tcp tomcat02 27a0ad90c575 tomcat "catalina.sh run" 13 days ago Up 50 minutes 0.0.0.0:32769->8080/tcp, :::32769->8080/tcp tomcat01 #用tomcat03去ping tomcat02 [root@localhost ~]# docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.099 ms 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.078 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.072 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.060 ms ^C64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.060 ms --- tomcat02 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.060/0.074/0.099/0.000 ms #发现通过 --link 可以ping通 #反向ping 发现不行 [root@localhost ~]# docker exec -it tomcat02 ping tomcat03 ping: unknown host #在tomcat03文件里面看一下连接 etc/hosts 配置本地绑定 root@21c13b1b39fb:/etc# cat 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.2 tomcat02 ad22a445a44d 172.17.0.4 21c13b1b39fb #本质是在hosts内部添加了一个配置 #目前docker已经不推荐 --link了! #docker0问题:不支持容器名连接访问!
用help命令查看docker network
[root@localhost ~]# docker network --help Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network create Create a network disconnect Disconnect a container from a network inspect Display detailed information on one or more networks ls List networks prune Remove all unused networks rm Remove one or more networks Run 'docker network COMMAND --help' for more information on a command.
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 09e87aa34a91 bridge bridge local 44a8849d5290 host host local 91ca0d160a16 none null local [root@localhost ~]# docker network inspect 09e87aa34a91 [ { "Name": "bridge", "Id": "09e87aa34a91d94c840d86d72b923a35830b7b0772bbb9422cad64e52d6e7635", "Created": "2023-09-01T09:36:05.332778927+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" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "21c13b1b39fb15ea755bd82ab1f0ebd6f953716bab43b908d57d7cd89b46f87f": { "Name": "tomcat03", "EndpointID": "373265c0597c9d7e5f8660723098719b32ff9c26b7a4a01d292064889e0186fd", "MacAddress": "02:42:ac:11:00:04", "IPv4Address": "172.17.0.4/16", "IPv6Address": "" }, "27a0ad90c575ebfb2404ae8ccd4517855f259fe7aca14cc55576411ed479fe99": { "Name": "tomcat01", "EndpointID": "861b4c02df7f3f3ccc127d1fd5d92c54b20f651da827970f6723e6b62225ce93", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "ad22a445a44d047d36d7503bff17abf03052279c300f4482160500f567e89a01": { "Name": "tomcat02", "EndpointID": "f6f9a874df9f7fec599d031dfccbb4beb18c738777feb7e8f69960de2cf1fe2c", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "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": {} } ]
自定义网络(推荐)
查看所有的docker网络
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 09e87aa34a91 bridge bridge local 44a8849d5290 host host local 91ca0d160a16 none null local
网络模式
bridge :桥接 docker(默认,我们自定义网络也是用桥接模式)
none :不配置网络
host :和宿主机共享网络
container:容器内网络连通!(用的少!局限性很大)
测试
#我们直接启动的命令 --net bridge,这个就是docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat # docker0特点:默认,域名不能访问, --link可以打通连接! # 我们可以自定义一个网络! # --driver bridge 网络模式 # --subnet 子网地址 # --gateway 网关 [root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 716af3b0bbf3dde7c541620031cd93bc2df4525e2c408e2edf3b0d4bc45e7702 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 09e87aa34a91 bridge bridge local 44a8849d5290 host host local 716af3b0bbf3 mynet bridge local 91ca0d160a16 none null local # 查看自己的网络配置 [root@localhost ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "716af3b0bbf3dde7c541620031cd93bc2df4525e2c408e2edf3b0d4bc45e7702", "Created": "2023-09-01T11:14:54.756372535+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
在自定义网络下创建容器
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat01 1.0 71d1587d961f 15 minutes ago 705MB [root@localhost ~]# docker run -d -P --name tomcat01 --net mynet tomcat01:1.0 83c958c64e0271a58057a57a5415c82aa5f2bd2da0a501cd8162ccf5156525e2 [root@localhost ~]# docker run -d -P --name tomcat02 --net mynet tomcat01:1.0 7d1ee5eba40e6d6c37163ee500765c21f6d844bf679325e4227cd566d53a06d0 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7d1ee5eba40e tomcat01:1.0 "catalina.sh run" 4 seconds ago Up 3 seconds 0.0.0.0:32772->8080/tcp, :::32772->8080/tcp tomcat02 83c958c64e02 tomcat01:1.0 "catalina.sh run" 12 seconds ago Up 10 seconds 0.0.0.0:32771->8080/tcp, :::32771->8080/tcp tomcat01 #查看网络mynet的配置 [root@localhost ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "716af3b0bbf3dde7c541620031cd93bc2df4525e2c408e2edf3b0d4bc45e7702", "Created": "2023-09-01T11:14:54.756372535+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "7d1ee5eba40e6d6c37163ee500765c21f6d844bf679325e4227cd566d53a06d0": { "Name": "tomcat02", "EndpointID": "fd37938ce12b81019d34839ce4989d70fcf5b2ceb7ec93da1bebe8800b572c41", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" }, "83c958c64e0271a58057a57a5415c82aa5f2bd2da0a501cd8162ccf5156525e2": { "Name": "tomcat01", "EndpointID": "07b157e8a0398b731f5ff0b64a9e03b896bd259ed5710c7532baec23eb200644", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] #发现已经配置成功 #测试 [root@localhost ~]# docker exec -it tomcat01 ping tomcat02 PING tomcat02 (192.168.0.3): 56 data bytes 64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.127 ms 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.136 ms ^C--- tomcat02 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.127/0.132/0.136/0.000 ms [root@localhost ~]# docker exec -it tomcat02 ping tomcat01 PING tomcat01 (192.168.0.2): 56 data bytes 64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.106 ms 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.063 ms ^C--- tomcat01 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.063/0.084/0.106/0.000 ms #发现tomcat01和tomcat02之间可以相互ping通
自定义网络docker已经帮我们维护好了对应的关系,推荐使用。
好处:
- redis-不同的集群使用不同的网络,保证集群是安全和健康的
- mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络连通(docker network connect)
[root@localhost ~]# docker run -d -P --name tomcat03 tomcat01:1.0 2fae795e1151fafc492ea763b5576387a403a2eb34a9afc61edfea09e1832f9c [root@localhost ~]# docker run -d -P --name tomcat04 tomcat01:1.0 0b8d2c7971f0e988c0f220b8495360ec8e924fb08aacd271f975349b16590b0a [root@localhost ~]# [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0b8d2c7971f0 tomcat01:1.0 "catalina.sh run" 11 seconds ago Up 10 seconds 0.0.0.0:32774->8080/tcp, :::32774->8080/tcp tomcat04 2fae795e1151 tomcat01:1.0 "catalina.sh run" 18 seconds ago Up 17 seconds 0.0.0.0:32773->8080/tcp, :::32773->8080/tcp tomcat03 7d1ee5eba40e tomcat01:1.0 "catalina.sh run" 9 minutes ago Up 9 minutes 0.0.0.0:32772->8080/tcp, :::32772->8080/tcp tomcat02 83c958c64e02 tomcat01:1.0 "catalina.sh run" 9 minutes ago Up 9 minutes 0.0.0.0:32771->8080/tcp, :::32771->8080/tcp tomcat01 #tomcat01和tomcat02在mynet网络中 #tomcat03和tomcat04在docker0网络中 #发现tomcat03不能ping通tomcat01 [root@localhost ~]# docker exec -it tomcat03 ping tomcat01 ping: unknown host #需要做的是容器tomcat03打通连接到网络mynet #docker network connect 网络名 容器名 [root@localhost ~]# docker network connect mynet tomcat03 [root@localhost ~]# docker exec -it tomcat03 ping tomcat01 PING tomcat01 (192.168.0.2): 56 data bytes 64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.320 ms 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.100 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.079 ms ^C--- tomcat01 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.079/0.166/0.320/0.109 ms [root@localhost ~]# docker exec -it tomcat01 ping tomcat03 PING tomcat03 (192.168.0.4): 56 data bytes 64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=0.086 ms 64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=0.108 ms ^C--- tomcat03 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.086/0.097/0.108/0.000 ms #发现 tomcat01和tomcat03可以使用容器名互相ping通 #查看mynet [root@localhost ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "716af3b0bbf3dde7c541620031cd93bc2df4525e2c408e2edf3b0d4bc45e7702", "Created": "2023-09-01T11:14:54.756372535+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "2fae795e1151fafc492ea763b5576387a403a2eb34a9afc61edfea09e1832f9c": { "Name": "tomcat03", "EndpointID": "df0fa9e402c8092fc429b421f8f84ed3197103a9946249221ab82dcdb73aa139", "MacAddress": "02:42:c0:a8:00:04", "IPv4Address": "192.168.0.4/16", "IPv6Address": "" }, "7d1ee5eba40e6d6c37163ee500765c21f6d844bf679325e4227cd566d53a06d0": { "Name": "tomcat02", "EndpointID": "fd37938ce12b81019d34839ce4989d70fcf5b2ceb7ec93da1bebe8800b572c41", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" }, "83c958c64e0271a58057a57a5415c82aa5f2bd2da0a501cd8162ccf5156525e2": { "Name": "tomcat01", "EndpointID": "07b157e8a0398b731f5ff0b64a9e03b896bd259ed5710c7532baec23eb200644", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] #发现tomcat03被加入进来了 #一个容器两个ip地址: 公网ip 私网ip
实战:部署redis集群
#1. 创建一个redis网络 [root@localhost ~]# docker network create redis --subnet 172.38.0.0/16 90e8d1481b2084d7f105c94c6388e07f57e8bf737a90d7bf6b3291705e4935f0 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 09e87aa34a91 bridge bridge local 44a8849d5290 host host local 716af3b0bbf3 mynet bridge local 91ca0d160a16 none null local 90e8d1481b20 redis bridge local #2.通过脚本创建六个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 #3.启动 docker run -p 6371:6379 -p 16371:16379 --name redis-1 \ -v /mydata/redis/node-1/data:/data \ -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6372:6379 -p 16372:16379 --name redis-2 \ -v /mydata/redis/node-2/data:/data \ -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6373:6379 -p 16373:16379 --name redis-3 \ -v /mydata/redis/node-3/data:/data \ -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6374:6379 -p 16374:16379 --name redis-4 \ -v /mydata/redis/node-4/data:/data \ -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6375:6379 -p 16375:16379 --name redis-5 \ -v /mydata/redis/node-5/data:/data \ -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf docker run -p 6376:6379 -p 16376:16379 --name redis-6 \ -v /mydata/redis/node-6/data:/data \ -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf [root@localhost redis]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 40063f9f502f redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6 0d5e9dcd6284 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5 0e7cf72ac9b6 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4 e1ea97d47b18 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 8 seconds ago Up 7 seconds 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-3 21edcd7a6326 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 9 seconds ago Up 8 seconds 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2 50deeb13a4f6 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1 #4.进入容器 [root@localhost redis]# docker exec -it redis-1 /bin/sh #5.构建集群 /data # 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 #完成三主三从的构建 #6.测试 /data # redis-cli -c 127.0.0.1:6379> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:263 cluster_stats_messages_pong_sent:260 cluster_stats_messages_sent:523 cluster_stats_messages_ping_received:255 cluster_stats_messages_pong_received:263 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:523 127.0.0.1:6379> cluster nodes 17c9f991189e6d17e15f4c92034d40dab77d9972 172.38.0.14:6379@16379 slave d31db3ade0a007bb95b1fff9d501f14ffdebbae5 0 1693551753540 4 connected a95ebfd004ef2c86c1a75364d5e04f80f2d3153a 172.38.0.16:6379@16379 slave ec7a1eed25da560a2cd9f8f6be60b0e037cb5a2b 0 1693551755000 6 connected ec7a1eed25da560a2cd9f8f6be60b0e037cb5a2b 172.38.0.12:6379@16379 master - 0 1693551754000 2 connected 5461-10922 9ecfef68f143fa75dbccfc3bd696417b2f80f9b0 172.38.0.11:6379@16379 myself,master - 0 1693551754000 1 connected 0-5460 d31db3ade0a007bb95b1fff9d501f14ffdebbae5 172.38.0.13:6379@16379 master - 0 1693551755382 3 connected 10923-16383 46bfdaa6484ac4a082f6acc9b6146fe123cd1026 172.38.0.15:6379@16379 slave 9ecfef68f143fa75dbccfc3bd696417b2f80f9b0 0 1693551755586 5 connected
SpringBoot微服务打包Docker镜像
1、构建springboot项目
2、打包应用
3、编写dockerfile
4、构建镜像
5、发布运行
#待学习springboot
企业实战:compose 容器编排 swarm集群部署 CI/CD之Jenkins
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人