docker笔记
有不懂的或者建议可以加我q来骚扰:1006551298
docker学习笔记
安装docker
docker网址:https://www.docker.com/
1.卸载旧的
yum remove docker \
dlient \
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 \
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 -y
设置开机启动
systemctl enable docker
5.启动docker
systemctl start docker
6.使用docker version是否安装成功
7.hello world
8.查看下载的这个hello-world镜像
[root@localhost local]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 4 months ago 13.3kB
centos latest 300e315adb2f 7 months ago 209MB
[root@localhost local]#
底层原理
docker 是怎么工作的?
docker是一个client-server结构的系统,docker的守护运行在主机上,通过socket从客户端访问.
DockerServer接受到Docker-Client的指令,就会执行这个命令!
docker run 运行原理
Docker的常用命令
帮助命令
docker verison #显示docker版本
docker info #显示docker的系统信息,包括镜像和容器数量
docker --help #万能命令
镜像命令
docker images 查看所有本地上主机上的镜像 #可选项 -a, --all #列出所有镜像 -q, --quiet #只显示镜像id
docker search 搜索镜像
[root@localhost ~]# docker search mysqlNAME DESCRIPTION STARS OFFICIAL AUTOMATEDmysql MySQL is a widely used, open-source relation… 11113 [OK] mariadb MariaDB Server is a high performing open sou… 4213 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 825 [OK]#可选项,通过收藏来过滤 --filter=STARS=3000 #搜索的镜像就是STARS大于3000 [root@localhost ~]# docker search mysql --filter=STARS=3000NAME DESCRIPTION STARS OFFICIAL AUTOMATEDmysql MySQL is a widely used, open-source relation… 11113 [OK] mariadb MariaDB Server is a high performing open sou… 4213 [OK]
docker pull 下载镜像
docker pull 下载镜像
#下载镜像 docker pull 镜像名 [:tag]
[root@localhost ~]# docker pull mysql
Using default tag: latest #如果不写tag,默认是latest
latest: Pulling from library/mysql
b4d181a07f80: Pull complete #分层下载,docker images的核心 联合文件系统
a462b60610f5: Pull complete
578fafb77ab8: Pull complete
524046006037: Pull complete
d0cbe54c8855: Pull complete
aa18e05cc46d: Pull complete
32ca814c833f: Pull complete
9ecc8abdb7f5: Pull complete
ad042b682e0f: Pull complete
71d327c6bb78: Pull complete
165d1d10a3fa: Pull complete
2f40c47d0626: Pull complete
Digest: sha256:52b8406e4c32b8cf0557f1b74517e14c5393aff5cf0384eff62d9e81f4985d4b #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实下载地址
docker pull mysql 等价于
docker pull docker.io/library/mysql:latest
#指定版本下载
[root@localhost ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
b4d181a07f80: Already exists
a462b60610f5: Already exists
578fafb77ab8: Already exists
524046006037: Already exists
d0cbe54c8855: Already exists
aa18e05cc46d: Already exists
32ca814c833f: Already exists
52645b4af634: Pull complete
bca6a5b14385: Pull complete
309f36297c75: Pull complete
7d75cacde0f8: Pull complete
Digest: sha256:1a2f9cd257e75cc80e9118b303d1648366bc2049101449bf2c8d82b022ea86b7
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
docker rmi -f 镜像id #删除指定镜像 (-f 强制删除镜像)
docker rmi -f 镜像id 镜像id 镜像id $()
docker rmi -f $(docker images -aq) #删除全部的镜像
容器命令
说明:我们有了镜像才可以创建容器,Linux ,下载一个
centos镜像来测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image#参数说明--name="Name" 容器名字 Tomcat1-d 后台方式运行-it 使用交互方式运行,进入容器查看内容-p(小写) 指定容器的端口 -p 8080:80808 -p ip:主机端口:容器端口 -p 主机端口:容器端口(映射) -p 容器端口 容器端口-P |随机指定端口#测试。启动并进入容器[root@localhost ~]# docker run -it centos /bin/bash[root@f415d69469e6 /]# lsbin etc lib lost+found mnt proc run srv tmp vardev home lib64 media opt root sbin sys usr# 从容器中退回主机[root@f415d69469e6 /]# exitexit[root@localhost ~]#
列出所有的运行的容器
#docker ps 命令 #列出当前正在运行的容器-a #列出当前正在运行的容器+带出历史运行过的容器-n=? #显示最近创建的容器-q #只显示容器的编号[root@localhost ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES[root@localhost ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf415d69469e6 centos "/bin/bash" 4 minutes ago Exited (130) About a minute ago peaceful_vaughan95007aeb54ec centos "/bin/bash" 13 minutes ago Exited (0) 13 minutes ago hardcore_snyder63256adfc0eb d1165f221234 "/hello" 16 hours ago Exited (0) 16 hours ago adoring_lichterman
退出容器
exit #退出容器 停止并退出Ctrl+P+Q #容器不停止并退出
删除容器
docker rm 容器id #删除指定容器,不能删除正在运行的容器,如果要强制删除 rm -fdocker rm -f $(docker ps -aq) #删除所有容器docker ps -a -q|xargs docker rm #删除所有容器
启动和停止容器的操作
docker start 容器id #启动容器docker restart 容器id #重启容器docker stop 容器id #停止当前正在运行的容器 docker kill 容器id #强制停止当前的容器
常用的其他命令
后台启动容器
#命令 docker run -d 镜像名[root@localhost ~]# docker run -d centos# 问题 docker ps,发现centos 停止了#常见的坑,docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止#Nginx 容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志
docker logs -ft --tail 容器,没有日志 #自己编写一段shell脚本[root@localhost ~]# docker run -d centos /bin/sh -c "while true;do echo asd;sleep 2;done" # [root@localhost ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESc94a833e8e13 centos "/bin/sh -c 'while t…" About a minute ago Up About a minute sweet_yalow #显示日志 -tf #显示日志--tail #要显示日志的条数[root@localhost ~]# docker logs -f -t --tail 5 c94a833e8e13
查看容器中进程信息ps
#命令 docker top 容器id[root@localhost ~]# [root@localhost ~]# docker top c94a833e8e13 UID PID PPID C STIME root 20167 20147 0 17:33 root 20853 20167 0 17:47
查看镜像的元数据
#docker inspect 容器id
#测试
[root@localhost ~]# docker inspect c94a833e8e13
[
{
"Id": "c94a833e8e13d021a43e814b2735f7daafe07f8c54502135409b38ce898636de",
"Created": "2021-07-15T09:33:04.25856399Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo asd;sleep 2;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 20167,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-07-15T09:33:04.67862489Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
"ResolvConfPath": "/var/lib/docker/containers/c94a833e8e13d021a43e814b2735f7daafe07f8c54502135409b38ce898636de/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/c94a833e8e13d021a43e814b2735f7daafe07f8c54502135409b38ce898636de/hostname",
"HostsPath": "/var/lib/docker/containers/c94a833e8e13d021a43e814b2735f7daafe07f8c54502135409b38ce898636de/hosts",
"LogPath": "/var/lib/docker/containers/c94a833e8e13d021a43e814b2735f7daafe07f8c54502135409b38ce898636de/c94a833e8e13d021a43e814b2735f7daafe07f8c54502135409b38ce898636de-json.log",
"Name": "/sweet_yalow",
"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/f46a0cd282d1b96dbb0ffdc077269efd593ba697bc0e4c4ff92d1d25559391d8-init/diff:/var/lib/docker/overlay2/e9f512d2244dc084c66764230a9ad26183a22b55659d24ab6ce7752057ea4b8c/diff",
"MergedDir": "/var/lib/docker/overlay2/f46a0cd282d1b96dbb0ffdc077269efd593ba697bc0e4c4ff92d1d25559391d8/merged",
"UpperDir": "/var/lib/docker/overlay2/f46a0cd282d1b96dbb0ffdc077269efd593ba697bc0e4c4ff92d1d25559391d8/diff",
"WorkDir": "/var/lib/docker/overlay2/f46a0cd282d1b96dbb0ffdc077269efd593ba697bc0e4c4ff92d1d25559391d8/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "c94a833e8e13",
"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": [
"/bin/sh",
"-c",
"while true;do echo asd;sleep 2;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20201204",
"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": "cba7c0b019a1c65128c377ac9cdff9fad1c6b59b9b3ccb52ee737fd9bffd11aa",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/cba7c0b019a1",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c67ea30db515806bfe9f4741783493fa808422fe1f0d4e18c0d4e87c5e917cb3",
"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": "b7309a0ec3024481586faf163ed9036b86a93413675c335b4bf4262daf049480",
"EndpointID": "c67ea30db515806bfe9f4741783493fa808422fe1f0d4e18c0d4e87c5e917cb3",
"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
}
}
}
}
]
进入当前正在运行的容器
#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置#命令docker exec -it 容器id /bin/bash#测试[root@localhost ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESe44ec56343f6 centos "/bin/bash" 8 minutes ago Up 8 minutes ecstatic_fermi[root@localhost ~]# docker exec -it e44ec56343f6 /bin/bash[root@e44ec56343f6 /]# lsbin etc lib lost+found mnt proc run srv tmp vardev home lib64 media opt root sbin sys usr#方式二docker attach 容器id#测试[root@localhost ~]# docker attach e44ec56343f6进入第一个终端#docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)#docker attach# 进入容器第一个终端
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的主机路径docker cp e44ec56343f6:/home/123 /home/
小结
作业练习
docker 安装nginx
#1.搜索镜像 search 建议去docker hub#2.下载镜像 pull#3.运行测试# -d 后台运行#--name 给容器命名#-p 宿主机端口,容器内部端口[root@localhost ~]# docker run -d --name nginx01 -p 3000:80 nginx4a1ba0d48c4579efb374f18d6dd558c372ceadb832cd68fd44fe3c42543925ba[root@localhost ~]# curl localhost:3000<!DOCTYPE html><html><head><title>Welcome to nginx!</title><style> 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>#进入容器[root@localhost ~]# docker exec -it nginx01 /bin/bashroot@4a1ba0d48c45:/# root@4a1ba0d48c45:/# whereis nginxnginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
作业
docker安装tomcat
#官方的使用docker run -it --rm tomcat:9.0#我们之前的启动都是后台,停止容器后,容器还是可以查到 docker run -it --rm ,一般用来测试,用完就删除#下载在启动docker pull tomcat#启动运行docker run -d -p 3333:8080 --name tomcat01 tomcat#测试访问没问题#进入容器[root@localhost ~]# docker exec -it tomcat01 /bin/bash#发现问题:1.Linux命令少了 2.没有webapps。阿里云镜像的原因。默认是最小的镜像,所有不必要的都删除掉。#保障最小可运行的环境ROOT docs examples host-manager managerroot@f0984f7f9933:/usr/local/tomcat/webapps.dist# pwd/usr/local/tomcat/webapps.distroot@f0984f7f9933:/usr/local/tomcat/webapps.dist# cd ..root@f0984f7f9933:/usr/local/tomcat# cp -r webapps.dist/* webappsroot@f0984f7f9933:/usr/local/tomcat#
作业ES+KIbana
#es暴露的端口很多!#es十分的耗内存#es的数据一般需要放置到安全目录!挂载#--net somenetwork ?网络配置#启动 elasticsearchdocker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2#启动Linux就卡住了 docker stats 查看cpu状态#查看docker stats#测试一下es是否成功了[root@localhost ~]# curl localhost:9200{ "name" : "1d10ca8c4e9d", "cluster_name" : "docker-cluster", "cluster_uuid" : "yL_tEWWJQhOV0eLNeoWJyA", "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 环境配置修改#docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx600m" elasticsearch:7.6.2[root@localhost ~]# docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx600m" elasticsearch:7.6.2^C[root@localhost ~]# [root@localhost ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1edd9547230f elasticsearch:7.6.2 "/usr/local/bin/dock…" 7 minutes ago Up 7 minutes 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch02[root@localhost ~]# curl localhost:9200{ "name" : "1edd9547230f", "cluster_name" : "docker-cluster", "cluster_uuid" : "bmJG6zUNQqS8t-z81SvSLg", "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"}
作业:使用kibana连接es
可视化
portainer(先用这个)
#拉取portainer-ce镜像(portainer/portainer/portainer已被抛弃)docker pull portainer/portainer-ce#创建一个数据卷docker volume create portainer_data启动portainer容器docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
commit镜像
docker commit 提交容器成为一个新的副本#命令和git 原理类似docker commit -m="提交的描述信息" -a="作者名字" 容器id 目标镜像名:[TAG]
实战测试
#启动一个默认的Tomcat#发现这个默认的Tomcat是没有webapps应用,镜像原因,官方的镜像默认webapps下面是没有文件的!#拷贝进去最基本的文件#将我们操作过的容器通过commit提交为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像
#docker inspect tomcat02:1.0{ "Id": "sha256:8e7a46d137886b7df32d212ccd1448ea555d02464bb8a63660cce4b901f20323", "RepoTags": [ "tomcat02:1.0" ], "RepoDigests": [], "Parent": "sha256:36ef696ea43d360827271a0d69475cb11fde0029d26fda66ea3204c116908597", "Comment": "add basic webapps/*", "Created": "2021-07-22T03:31:29.961539759Z", "Container": "42e7c7ba4cae811400a4fe0bf82951fd14f91525a022e024c7e1270b7f46dbcf", "ContainerConfig": { "Hostname": "42e7c7ba4cae", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "8080/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "JAVA_HOME=/usr/local/openjdk-11", "LANG=C.UTF-8", "JAVA_VERSION=11.0.11+9", "CATALINA_HOME=/usr/local/tomcat", "TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib", "LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib", "GPG_KEYS=48F8E69F6390C9F25CFEDCD268248959359E722B A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243", "TOMCAT_MAJOR=9", "TOMCAT_VERSION=9.0.50", "TOMCAT_SHA512=06cd51abbeebba9385f594ed092bd30e510b6314c90c421f4be5d8bec596c6a177785efc2ce27363813f6822af89fc88a2072d7b051960e5387130faf69c447b" ], "Cmd": [ "catalina.sh", "run" ], "Image": "tomcat", "Volumes": null, "WorkingDir": "/usr/local/tomcat", "Entrypoint": null, "OnBuild": null, "Labels": {} }, "DockerVersion": "20.10.7", "Author": "jianle", "Config": { "Hostname": "42e7c7ba4cae", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "8080/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "JAVA_HOME=/usr/local/openjdk-11", "LANG=C.UTF-8", "JAVA_VERSION=11.0.11+9", "CATALINA_HOME=/usr/local/tomcat", "TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib", "LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib", "GPG_KEYS=48F8E69F6390C9F25CFEDCD268248959359E722B A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243", "TOMCAT_MAJOR=9", "TOMCAT_VERSION=9.0.50", "TOMCAT_SHA512=06cd51abbeebba9385f594ed092bd30e510b6314c90c421f4be5d8bec596c6a177785efc2ce27363813f6822af89fc88a2072d7b051960e5387130faf69c447b" ], "Cmd": [ "catalina.sh", "run" ], "Image": "tomcat", "Volumes": null, "WorkingDir": "/usr/local/tomcat", "Entrypoint": null, "OnBuild": null, "Labels": {} }, "Architecture": "amd64", "Os": "linux", "Size": 672350910, "VirtualSize": 672350910, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/862e773aa0d7de26234015733684394de347adca181bdf36c1df40f935966f16/diff:/var/lib/docker/overlay2/b54bf8610651ea9b8a8a6de40d74c4cbc8a5c0c6e9f1cb31be937c6d9c4de1a4/diff:/var/lib/docker/overlay2/17a09fd607d88fdd6b75317cb8997be774b278c8a7cd0c8c84cd7ecdf583991e/diff:/var/lib/docker/overlay2/5a066f46e9134c76e16192c325f79d2418f49684e71c38032fbdb2cd26e393c7/diff:/var/lib/docker/overlay2/1245c2a79f653cef1045a6791f133c782cc698113a5866f243a2cdad085565af/diff:/var/lib/docker/overlay2/b5a9cfa266d9c31b15dfb3b6efb20c2444bf2fce30ec0bca7d0d455e588adde2/diff:/var/lib/docker/overlay2/cef685391d7fc3d7fbee3d849ca34f5757236da261dbe89622af9211e9dd3b34/diff:/var/lib/docker/overlay2/fa6355bd8e4bf63310c98781ea27db5a1fe815adef216fcddb5c3d3037eaef48/diff:/var/lib/docker/overlay2/9bfb8dbcdb61ab32f6571808172d6b96cee2a292f705a7f2be9a1883f4b0b794/diff:/var/lib/docker/overlay2/5b4f915615be6420c94a71bcfd9275d94e68b3e972be6198071c5e32d049cda8/diff", "MergedDir": "/var/lib/docker/overlay2/e15a0bb5c9b2cc7a85664d0dbc183cce0abdec306784c125bf7f54f8ce0757c4/merged", "UpperDir": "/var/lib/docker/overlay2/e15a0bb5c9b2cc7a85664d0dbc183cce0abdec306784c125bf7f54f8ce0757c4/diff", "WorkDir": "/var/lib/docker/overlay2/e15a0bb5c9b2cc7a85664d0dbc183cce0abdec306784c125bf7f54f8ce0757c4/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:4e006334a6fdea37622f72b21eb75fe1484fc4f20ce8b8526187d6f7bd90a6fe", "sha256:e4d0e810d54a9c47e3dface412b0b88045d156b18809a2e0bbfb0fc8a45d8127", "sha256:fe6a4fdbedc0cbc560437fa700b3b034114e31a264f0818d0d32ed2ee6cbe7a3", "sha256:7095af798ace32173839a61cbf101048434e1065185c0f29cc888e67158d990b", "sha256:79c550eb7bd278d360284d86c39e05852c2026b64232267a43947300bcf54a2c", "sha256:c0848348e2f7a56acbdaa24e3ee321b5c85651fce0317aa47ada385a4f9a4e85", "sha256:6ea995e9b7d379dd368b12fcde9b116035765cd2a58a72fd0e2dab4ea01392b7", "sha256:b59bec8e923057ad30f9bacd026af8f91aa3faad3bcf084ebeb7ecb22eb479a6", "sha256:d4f9607ef3baf7ac2a0ce80aaf4442011eb987cea8daef4eac767a7b664191f2", "sha256:7aa976df10c03de778d66c21799669f63f34a0b9d5c328109ec28506422a9efc", "sha256:ab07b3fa8e8b47bf7e7593153636e47f2e2af3b2bce37f3f3973f57190231114" ] }, "Metadata": { "LastTagTime": "2021-07-22T11:31:29.965237669+08:00" }}
容器数据卷
什么是容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
mysql,容器删了,删库跑路!需求:mysql数据可以存储在本地!
容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地!这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录,容器内目录#测试[root@localhost 123]# docker run -it -v /home/ceshi:/home/ tomcat /bin/bash#启动起得来之后我们可以通过docker inspect 容器id查看挂载
实战:安装mysql
思考:mysql的数据持久化的问题!
#获取镜像 docker pull mysql:5.7#运行容器,需要做数据挂载! #安装启动mysql,需要配置密码的,这是要注意的!#官方安装测试: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag #启动我们的 -d 后台运行 -p 端口映射 -v卷挂载 -e环境配置 --name容器名字docker run -d -p 3000: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#启动成功之后,我们在本地使用sqlyog来测试一下#sqlyog-连接到服务器的3000 ----3000和容器内的3306映射,这个时候我们就可以连接上了!#在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
假设我们将容器删除,发现挂载在本地的数据没有丢失,这就实现了容器数据持久化功能
具名和匿名挂载
#匿名挂载
-v 容器内路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有的 volume的情况
[root@localhost conf]# docker volume lsDRIVER VOLUME NAMElocal ea90a0ea8ff505e7c1988178fa007589742df7377c4f426dcb956088f4f91a03#这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!#具名挂载[root@localhost conf]# docker run -d -P --name nginx02 -v juming:/etc/nginx nginx8c80930a53654ccb8005b4763d5a4bf593ff860e9d925624aeb0c83a3044e328[root@localhost conf]# docker volume lsDRIVER VOLUME NAMElocal juming#通过 -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:/etc/nginx:ro nginxdocker run -d -P --name nginx02 -v juming:/etc/nginx:rw nginx#ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的!
初识dockerfile
dockerfile 就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
通过脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
#创建一个dockerfile文件,,名字可以随机,建议 Dockerfile#文件中的内容 指令(大写) 参数FROM centosVOLUME ["volume01","volume02"]CMD echo"-----end------"CMD /bin/bash# 这里的每个命令,就是镜像的一层![root@localhost /]# docker build -f dockerfile01 -t home/centos .
#启动自己的容器
这个卷和外部一定有一个同步的目录!
查看一下卷挂载的路径
测试一下刚才的文件是否同步
这种方式我们未来使用十分多,因为我们通常会构建自己的镜像!
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内的路径!
数据卷容器
两个mysql同步数据
#启动3个容器,通过我们刚才自己写的镜像启动
#启动第一个
#启动第二个 并挂载数据卷
docker run -it --name docker02 --volumes-from docker01 jianle /bin/bash
#启动第三个
docker run -it --name docker03 --volumes-from docker01 jianle /bin/bash
通过 --volumes-from可以容器间的共享
#测试,可以删除docker01,查看一下docker02和docker03是否还可以访问这个文件
#测试依旧可以访问
多个mysql实现数据共享
#docker run -d -p 3000:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql:5.7#docker run -d -p 3100:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=mysql02 --volume-from mysql01 mysql:5.7#这个时候,可以实现两个容器数据同步!
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
dockerfile
dockerfile的介绍
dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
构建步骤:
1.编写一个dockerfile文件
2.docker build构建成为一个镜像
3.docker run 运行镜像
4.docker push发布镜像(dockerHub、阿里云镜像仓库!)
查看一下官方是怎么做的?
很多官方镜都是基础包,很多功能都没有,我们通常会搭建自己的镜像!
官方既然可以制作镜像,那我们也可以!
Dockerfile构建过程
基础知识:
1.每个保留关键字(指令)都必须是大写字母
-
指令从上到下顺序执行
-
#表示注解
-
每一个指令都会创建提交一个新的镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
docker镜像逐渐成为企业交付的标准,必须掌握!
dockerfile:构建文件,定义了一切的步骤,必须要掌握!
dockerfile:构建文件,定义了一切的步骤,源代码
dockerimages:通过Dockerfile构建的镜像,最终发布和运行的产品!
docker容器:容器就是镜像运行起来提供服务器
dockerfile的指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤,tomcat镜像,这个Tomcat压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被代替
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承Dockerfile 这个时候就会运行ONBUILD的指令。触发指令。
COPY #类似ADD,将我们文件拷贝到镜像中
ENV #构建的时候设置环境变量!
实战测试
Docker Hub中99%镜像都是从这个基础镜像过来的FROM search,然后配置需要的软件和配置进行的构建
创建一个自己的centos
#编写dockerfile的文件FROM centosMAINTAINER jianle<1006551298@qq.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH CMD echo "---end----"CMD /bin/bash#2.通过这个文件构建镜像#命令 docker build -f dockerfile文件路径 -t 镜像名[tag]Successfully built e1e5d920d5acSuccessfully tagged mycentos:latest#3.测试运行
对比:之前的原生centos
我们增加之后的镜像
我们可以列出本地进行的变更历史
我们平时拿到一个镜像,可以研究一下它是怎么做的?
CMD和ENTRYPOINT区别
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被代替ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
#编写dockerfile文件 [root@localhost ~]# vim dockerfile/dockerfile-cmd-test FROM centosCMD ["ls","-a"]
#构建镜像docker build -f dockerfile-cmd-test -t docker-cmd .#run运行[root@localhost ~]# docker run docker-cmd ....dockerenvbindevetchomeliblib64lost+foundmediamnt#想追加一个命令 -l[root@localhost ~]# docker run docker-cmd -ldocker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.ERRO[0000] error waiting for container: context canceled #cmd的清理下 -l 替换了CMD ["ls","-a"]命令,-l不是命令,所以报错!
测试ENTRYPOINT entrypoint
#编写dockerfile文件 docker-entrypoint dockerfile-cmd-test [root@localhost dockerfile]# cat docker-entrypoint FROM centosENTRYPOINT ["ls","-a"]#构建镜像[root@localhost dockerfile]# docker build -f docker-entrypoint -t en-test .#我们的追加一个命令 是直接拼接在我们的ENTRYPOINT后面的[root@localhost dockerfile]# docker run en-test -ltotal 0drwxr-xr-x. 1 root root 6 Jul 28 06:16 .drwxr-xr-x. 1 root root 6 Jul 28 06:16 ..-rwxr-xr-x. 1 root root 0 Jul 28 06:16 .dockerenvlrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bindrwxr-xr-x. 5 root root 340 Jul 28 06:16 devdrwxr-xr-x. 1 root root 66 Jul 28 06:16 etcdrwxr-xr-x. 2 root root 6 Nov 3 2020 homelrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/liblrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64drwx------. 2 root root 6 Dec 4 2020 lost+founddrwxr-xr-x. 2 root root 6 Nov 3 2020 mediadrwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
实战:tomcat镜像
镜像排错 docker logs
1.准备镜像文件tomcat压缩包,jdk的压缩包
2.编写dockerfile文件,官方命名 dockerfile ,build会自动寻找这个文件,就不需要-f指定了。
FROM centosMAINTAINER jianle<1006551298@qq.com>COPY readme.txt /usr/local/readme.txtADD apache-tomcat-9.0.22.tar.gz /usr/local/ADD jdk-8u11-linux-x64.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/localWORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_11ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22ENV PASH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/logs/catalina.out
-
构建镜像
#docker build -t diytomcat .
4.启动镜像
docker run -d -p 9090:8080 --name diytomcat -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.22/logs diytomcat
5.访问测试
6发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
test/WEB-INF/web.xml
(===<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>db</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>===)不可用<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" version="3.1"></web-app>
test/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="utf-8"><title>hello,world</title></head><body>Hello World!<br/><%System.out.println("----my test web logs----- " );%></body></html>
发现,项目部署成功,可以直接访问ok!
发布自己的镜像
docker上
1.地址https://hub.docker.com/注册自己的账号!
2.确定账号可以登录
3.在我们服务器提交我们自己的镜像
[root@localhost ~]# docker login --helpUsage: docker login [OPTIONS] [SERVER]Log in to a Docker 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 [root@localhost ~]# docker login -u renjianlePassword: WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
4.登录完毕后tag规范镜像,之后就可以提交镜像了
[root@localhost ~]# docker tag hello-world renjianle/hello:1.0 docker tag 本地有的镜像 用户名/生成的镜像名:[tag] #docker push 上去即可!自己发布的镜像尽量带上版本号[root@localhost ~]# docker push renjianle/hello:1.0The push refers to repository [docker.io/renjianle/hello]f22b99068db9: Mounted from library/hello-world 1.0: digest: sha256:1b26826f602946860c279fce658f31050cff2c596583af237d971f4629b57792 size: 525
提交的时候也是按照镜像的层级来进行提交的!
阿里云镜像服务上
1.登录阿里云
2.找到容器镜像服务
3.实例列表 -创建个人实例-创建命名空间
4.创建容器镜像
5.浏览阿里云
阿里云容器镜像就参考官方地址!
小结:docker全流程
Docker网络
测试:
三个网络
#问题,docker是如何处理容器网络访问的?
[root@jianle ~]# docker run -d -P --name tomcat01 tomcat#查看容器内部网络地址 ip addr ,发现容器启动的时候回得到一个eth0@if9 ip地址,地址docker分配的![root@jianle ~]# docker exec -it e9b2e996a1e1 ip addr1: 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 forever8: eth0@if9: <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 思考,Linux能不能ping通容器内部![root@jianle ~]# ping 172.17.0.2PING 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.062 ms64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.067 ms^X64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.062 ms可以ping通docker容器内部
1 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术!
再次测试ip addr
2.再启动一个容器测试,发现又多了一对网卡
#我们发现这个容器带来网卡,都是一对对的#evth—pair就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此连接#正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的#OpenStack,docker容器之间的连接,ovs的连接,都是使用evth-pair技术
3我们来测试tomcat01和tomcat02是否可以ping通!
docker exec -it tomcat02 ping 172.18.0.2
#结论:容器和容器之间是可以互相ping通的
绘制一个网路模型图:
结论:tomcat01和tomcat02是公用的一个路由器,docker0.
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip
小结
docker总所有的网络接口都是虚拟的。虚拟的转发效率高!
只要容器删除,对应网桥一对就没了!
--link
思考一个场景,我们编写了一个微服务,database url=ip;项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以名字来进行访问容器?
[root@jianle ~]# docker exec -it tomcat02 ping tomcat01ping: tomcat01: Name or service not known
#如何可以解决呢?
[root@jianle ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat db8257361d7762525264b5f3ac9f68bbb10251af7162ab76ab72efc0c2ae71b1[root@jianle ~]# docker exec -it tomcat03 ping tomcat02PING tomcat02 (172.17.0.3) 56(84) bytes of data.64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.153 ms64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.070 ms#反向可以ping通吗?[root@jianle ~]# docker exec -it tomcat02 ping tomcat03 ping: tomcat03: Name or service not known
探究:inspect
[root@jianle ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
71379641dbd0 bridge bridge local
ec1d8272f26e host host local
16682bf93b18 none null local
[root@jianle ~]# docker network inspect 71379641dbd0
[
{
"Name": "bridge",
"Id": "71379641dbd0f0d09596fd6ca39a93cfcc5b0a3ed5890c1cf01c2a61bf087ab8",
"Created": "2021-08-02T16:31:13.736611638+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": {
"8375b468dc2f738bb83d5f8a4938dfbde2d1a8118f2abe807c0ba44d25de8bc5": {
"Name": "tomcat02",
"EndpointID": "91d496a20b2a7b6097314334e65b1ee0642d948ebb430d44e7ffa569ec123cd5",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"db8257361d7762525264b5f3ac9f68bbb10251af7162ab76ab72efc0c2ae71b1": {
"Name": "tomcat03",
"EndpointID": "25d5d0a02c49e2fe4df0aa48079ee3c3ee1ee1c8a3f42b0c3dc7efc5b9a41c9d",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"e9b2e996a1e1a14dba1921db8a74da39980426a096e9fdb39273e5ce042918b2": {
"Name": "tomcat01",
"EndpointID": "a89c7c747ebe23b4f996dbab2a9ffa14b851e21918be6836f4664dd70cd927c5",
"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": {}
}
]
其实这个tomcat03就是本地配置了tomcat02的配置
#查看hosts配置,在这里原理发现![root@jianle ~]# docker exec -it db8257361d77 cat /etc/hosts127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopbackfe00::0 ip6-localnetff00::0 ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters172.17.0.3 tomcat02 8375b468dc2f172.17.0.4 db8257361d77
本质探究--link就是我们在hosts配置中增加了一个地址
真实我们现在玩docker已经不建议使用--link!
自定义网络!不适用docker0!
docker0网络:他不支持容器名连接访问!
自定义网络
查看所有的docker网络
网络模式
bridge:桥接docker(默认,自己创建也使用bridge模式)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通!(用的少!局限性很大)
测试
#我们直接启动的命令 --net bridge ,而这个就是docker0docker run -d -P --name tomcat01 tomcatdocker run -d -P --name tomcat01 --net bridge tomcat#docker0特点,默认,域名不能访问 --link可以打通连接 #我们可以自定义一个网络!#--driver bridge#--subnet 192.168.0.0/24 #--gateway 192.168.0.1[root@jianle ~]# docker network create --driver bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 mynet4cbe715d7b5795aec944e05ec8360d747103e71d496e93d867f895087d913163[root@jianle ~]# docker network lsNETWORK ID NAME DRIVER SCOPE71379641dbd0 bridge bridge localec1d8272f26e host host local4cbe715d7b57 mynet bridge local16682bf93b18 none null local[root@jianle ~]#
我们自己的网络就创建好了
#再次测试ping连接[root@jianle ~]# docker run -d -P --name tomcat01 --net mynet tomcatfa691e64ef0605cb9cb9f99c5567e75a4aca75b6b5888d3e3ce820eaa24d897c[root@jianle ~]# docker run -d -P --name tomcat02 --net mynet tomcat 3a17908d6a590ac3d4402dd20a614211ec17a423ddddc73272b9d7120f509456#现在不使用--link也可以ping名字了![root@jianle ~]# docker exec -it tomcat01 ping tomcat02PING tomcat02 (192.168.0.3) 56(84) bytes of data.64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.078 ms64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.084 ms
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保障集群是安全和健康的
mysql -不同的集群使用不同的网络,保障集群是安全和健康的
网络连通
#测试打通tomcat01 -mynet
[root@jianle ~]# docker network connect mynet tomcat01
#连通之后就是将tomcat01放到了mynet网络下
#一个容器两个ip地址 !
#01连通ok
[root@jianle ~]# docker exec -it tomcat01 ping tomcat001
PING tomcat001 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat001.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.078 ms
64 bytes from tomcat001.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.085 ms
#02是依旧打不通的
[root@jianle ~]# docker exec -it tomcat02 ping tomcat001
ping: tomcat001: Name or service not known
结论:假设要跨网络操作别人,就需要使用docker network连通!
实战:部署Redis集群
#创建网卡
docker network create redis --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
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf \
done
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
#创建集群的配置
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
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 86ddc1a103aaa290654078744c84157563bd2f58 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 1a681a5b449895d2c357d349b3a7f2e9f846b05b 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: b9ef03ef2257cde6f656bb7e756517f9b3a85c75 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: b39fc2ef559f418640262255a3ae73102bf11a33 172.38.0.14:6379
replicates b9ef03ef2257cde6f656bb7e756517f9b3a85c75
S: d903d44d10793ef61c152b4732b594c7a97c66a0 172.38.0.15:6379
replicates 86ddc1a103aaa290654078744c84157563bd2f58
S: e250cd396339e8bb726088e4ac38a684c3f74769 172.38.0.16:6379
replicates 1a681a5b449895d2c357d349b3a7f2e9f846b05b
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 86ddc1a103aaa290654078744c84157563bd2f58 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: e250cd396339e8bb726088e4ac38a684c3f74769 172.38.0.16:6379
slots: (0 slots) slave
replicates 1a681a5b449895d2c357d349b3a7f2e9f846b05b
S: b39fc2ef559f418640262255a3ae73102bf11a33 172.38.0.14:6379
slots: (0 slots) slave
replicates b9ef03ef2257cde6f656bb7e756517f9b3a85c75
M: 1a681a5b449895d2c357d349b3a7f2e9f846b05b 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: b9ef03ef2257cde6f656bb7e756517f9b3a85c75 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: d903d44d10793ef61c152b4732b594c7a97c66a0 172.38.0.15:6379
slots: (0 slots) slave
replicates 86ddc1a103aaa290654078744c84157563bd2f58
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
docker搭建 redis集群完成!
SpringBoot微服务打包docker镜像
-
构建springboot
-
打包应用
-
编写dockerfile
-
构建镜像
-
发布运行!
通过阿里云服务器公网访问正常运行!
正好看到了dos的视频 ,随手记一下
window下cmd操作
#文件操作
md 创建文件夹
cd>文件 创建文件
del 删除文件
rd 删除文件夹
cd /d 切换目录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)