docker学习至docker-compose

    技术2022-07-13  78

    docker安装

    #系统内核 3.10 [fengge@localhost ~]$ uname -r 3.10.0-957.el7.x86_64 #系统版本 [fengge@localhost ~]$ cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"

    ​ 安装

    #1、卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine #2、安装工具包 sudo yum install -y yum-utils #3、配置docker阿里云镜像仓库加速 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo #这个是国外的镜像,速度慢 sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #推荐使用阿里云镜像 yum makecache fast #更新缓存(更新yum软件包) #4、 安装docker docker-ce 社区 ee 企业版(收费) yum install docker-ce docker-ce-cli containor.io #一路选择y(两个)安装成功后 #5、启动docker systemctl start docker #6、查看docker版本信息 docker version #7、运行hello-world镜像 docker run hello-world #出现问题?什么鬼 docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http:///var/run/docker.sock/v1.35/containers/create: dial unix /var/run/docker.sock: connect: permission denied.See 'docker run --help'. #非root用户身份运行docker,则需要将其添加到docker组 $sudo groupadd docker $sudo usermod -aG docker $USER #再次运行hello-world docker run hello-world #出现错误 Unable to find image 'hello-world:latest' locally docker: Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: Get https://auth.docker.io/token?scope=repository:library/hello-world:pull&service=registry.docker.io: net/http: request canceled (Client.Timeout exceeded while awaiting headers). See 'docker run --help'. #如果在虚拟机上进行测试,可能需要重新启动虚拟机以使更改生效。在桌面Linux环境(如X Windows)中,完全注销会话,然后再重新登录。在Linux上,还可以运行以下命令来激活对组的更改 #解决办法 newgrp docker #再次运行 docker run hello-world #出现错误 Unable to find image 'hello-world:latest' locally docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout. See 'docker run --help'. #解决办法 sudo mkdir /etc/docker/daemon.json <<-'EOF' sudo tee /etc/docker/daemon.json { "registry-mirrors":"https://docker.mirrors.ustc.edu.cn"] } #也可以添加多个国内镜像 { "registry-mirrors": ["http://hub-mirror.c.163.com", "https://registry.docker-cn.com"] } # { "registry-mirrors": ["https://registry.docker-cn.com", "http://hub-mirror.c.163.com", "https://kfwkfulq.mirror.aliyuncs.com" ] } #然后重启服务 systemctl daemon-reload systemctl restart docker #出现下面问题 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running #肯定是daemonl.json 没写对 #拉取hello-world docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. ###大功告成 #Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? #解决方法 https://blog.csdn.net/keineahnung2345/article/details/84814677 sudo service docker start

    docker常用命令

    帮助命令

    docker version #显示docker版本信息 docker info #docker系统信息,包括镜像容器熟练 docker 命令 --help #帮助命令

    镜像命令

    docker images

    [fengge@localhost ~]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest bf756fb1ae65 5 months ago 13.3kB # 解释 REPOSITORY 镜像仓库源 TAG 镜像标签 IMAGE ID 镜像id CREATED 镜像创建时间 SIZE 镜像大小 #可选项 -a, --all 列出所有镜像 -q, --quiet 只显示id

    ​ docker search 镜像 #搜索命令

    [fengge@localhost ~]$ docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 9616 [OK] mariadb MariaDB is a community-developed fork of MyS… 3494 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 702 [OK] #可选项 可通过搜索来过滤 --filter=STARS=3000 #搜索出来的镜像是stars大于3000的 [fengge@localhost ~]$ docker search mysql --filter=STARS=3000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 9616 [OK] mariadb MariaDB is a community-developed fork of MyS… 3494 [OK]

    docker pull 下载镜像

    #下载镜像docker pull 镜像名称[:tag] [fengge@localhost ~]$ docker pull mysql Using default tag: latest #不写TAG默认下载latest latest: Pulling from library/mysql 8559a31e96f4: Pull complete #分层下载, docker image的核心,联合文件系统 d51ce1c2e575: Pull complete c2344adc4858: Pull complete fcf3ceff18fc: Pull complete 16da0c38dc5b: Pull complete b905d1797e97: Pull complete 4b50d1c6b05c: Pull complete c75914a65ca2: Pull complete 1ae8042bdd09: Pull complete 453ac13c00a3: Pull complete 9e680cd72f08: Pull complete a6b5dc864b6c: Pull complete Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6 #签名 Status: Downloaded newer image for mysql:latest docker.io/library/mysql:latest #真实地址 #等价 docker pull mysql docker pull docker.io/libray/mysql:latest #指定版本下载 [fengge@localhost ~]$ docker pull mysql:5.7 5.7: Pulling from library/mysql 8559a31e96f4: Already exists #分层下载,前面已经下载就不下载 d51ce1c2e575: Already exists c2344adc4858: Already exists fcf3ceff18fc: Already exists 16da0c38dc5b: Already exists b905d1797e97: Already exists 4b50d1c6b05c: Already exists d85174a87144: Pull complete a4ad33703fa8: Pull complete f7a5433ce20d: Pull complete 3dcd2a278b4a: Pull complete Digest: sha256:32f9d9a069f7a735e28fd44ea944d53c61f990ba71460c5c183e610854ca4854 Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7

    docker rmi 删除镜像

    [fengge@localhost ~]$ docker rmi -f 容器id #删除指定容器 [fengge@localhost ~]$ docker rmi -f 容器id 容器id 容器id #多个删除 [fengge@localhost ~]$ docker rmi -f @(docker images -aq) #删除全部容器

    容器命令

    有了镜像才可以创建容器

    docker run [可选参数] image #可选参数 --name="nginx-lb" #为容器指定一个名称 -d #后台运行容器,并返回容器ID -it # 以交互模式运行容器 -P #随机端口映射,容器内部端口随机映射到主机的高端口 -p #指定端口映射,格式为:主机(宿主)端口:容器端口 -p 8080:8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 容器端口 #来启动一个容器并进入容器 [fengge@localhost ~]$ docker run -it centos /bin/bash [root@067ad7cdef5a /]# ls #产看容器内的centos 基础版本,很多命令不完善 bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usr #从容器中退回主机 [root@067ad7cdef5a /]# exit exit

    列出所有运行中的容器

    docker ps [可选项目] #显示当前正在运行的容器 -a #列出正在运行的容器+历史运行过的容器 -n=#显示最近创建过的容器 -q #只显示容器编号 [fengge@localhost ~]$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 067ad7cdef5a centos "/bin/bash" 6 minutes ago Exited (0) 2 minutes ago zen_ganguly 17b2f180b2d1 bf756fb1ae65 "/hello" 2 hours ago Exited (0) 2 hours ago determined_liskov 6819267c282f bf756fb1ae65 "/bin/sh" 6 hours ago Created peaceful_yonath e35ef64c711d hello-world "/hello" 6 hours ago Exited (0) 6 hours ago charming_montalcini 88e1e126c685 hello-world "/hello" 7 hours ago Exited (0) 7 hours ago funny_vaughan [fengge@localhost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    退出容器

    exit #停止容器并退出 Ctrl+P+Q #容器不停止退出

    删除容器

    docker rm 容器id #删除指定容器,不能删除在运行中的容器,如要强制删除 rm -f docker rm -f $(docker images -aq) #删除全部容器 docker ps -a -q|xargs docker rm #删除所有容器

    停止和启动容器

    docker start 容器id #启动容器 docker restart 容器id #重启容器 docker stop 容器id #停止当前正在运行的容器 docker kill 容器id #强制停止当前容器

    其他常用命令

    后台启动容器

    #命令 docker run -d 镜像名! [fengge@localhost ~]$ docker run -d centos #问题docker ps 发现centos停止了 #常见的坑 容器后台运行,就必须要有一个前台进行,docker发现没有应用会自动停止 #nginx,容器启动后,发i西安自己没有提供服务,就会立即停止,就是没有程序了

    查看日志

    docker logs -t -f --tail num 容器 #num数字 #编写shell脚本记录日志 [fengge@localhost ~]$ docker run -d centos /bin/bash -c "while true;do echo fengge;sleep 1;done" #[fengge@localhost ~]$ docker ps CONTAINER ID IMAGE ab04bca60168 centos #显示日志 -tf 显示日志 --tail number #显示日志的条数 [fengge@localhost ~]$ docker logs -tf --tail 10 ab04bca60168 2020-06-12T12:13:27.162777064Z fengge 2020-06-12T12:13:28.171253330Z fengge 2020-06-12T12:13:29.177486249Z fengge 2020-06-12T12:13:30.188136700Z fengge 2020-06-12T12:13:31.196537899Z fengge 2020-06-12T12:13:32.199776685Z fengge 2020-06-12T12:13:33.208004111Z fengge 2020-06-12T12:13:34.215576626Z fengge

    查看容器中的进程信息

    #docker top 容器id [fengge@localhost ~]$ docker top 871b3fce0ce4 UID PID PPID C STIME TTY TIME CMD root 9172 9156 0 20:22 ? 00:00:00 /bin/bash -c while true;do echo fengge;sleep 1;done root 9261 9172 0 20:23 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

    查看镜像的元数据

    #命令 docker inspect 容器id [fengge@localhost ~]$ docker inspect 860c4eec8397d4 [ { "Id": "860c4eec8397d4f5106b18de298ad8ff545a1dc6c96e995da7649bb8fd59f5c3", "Created": "2020-06-12T12:25:07.469617008Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "exited", "Running": false, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 0, "ExitCode": 0, "Error": "", "StartedAt": "2020-06-12T12:25:07.812952732Z", "FinishedAt": "2020-06-12T12:25:07.811107996Z" }, "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee", "ResolvConfPath": "/var/lib/docker/containers/860c4eec8397d4f5106b18de298ad8ff545a1dc6c96e995da7649bb8fd59f5c3/resolv.conf", "HostnamePath": "/var/lib/docker/containers/860c4eec8397d4f5106b18de298ad8ff545a1dc6c96e995da7649bb8fd59f5c3/hostname", "HostsPath": "/var/lib/docker/containers/860c4eec8397d4f5106b18de298ad8ff545a1dc6c96e995da7649bb8fd59f5c3/hosts", "LogPath": "/var/lib/docker/containers/860c4eec8397d4f5106b18de298ad8ff545a1dc6c96e995da7649bb8fd59f5c3/860c4eec8397d4f5106b18de298ad8ff545a1dc6c96e995da7649bb8fd59f5c3-json.log", "Name": "/modest_lalande", "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, "Capabilities": null, "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/68abc5f20300a1a3422fb828420f96c57269535b63cb20053a429c2f1e85d1b9-init/diff:/var/lib/docker/overlay2/9ebcf313255a7fda28c85d474fed278fc9edc7faf990dbf890ba016623cde851/diff", "MergedDir": "/var/lib/docker/overlay2/68abc5f20300a1a3422fb828420f96c57269535b63cb20053a429c2f1e85d1b9/merged", "UpperDir": "/var/lib/docker/overlay2/68abc5f20300a1a3422fb828420f96c57269535b63cb20053a429c2f1e85d1b9/diff", "WorkDir": "/var/lib/docker/overlay2/68abc5f20300a1a3422fb828420f96c57269535b63cb20053a429c2f1e85d1b9/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "860c4eec8397", "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/bash" ], "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20200114", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS", "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00", "org.opencontainers.image.licenses": "GPL-2.0-only", "org.opencontainers.image.title": "CentOS Base Image", "org.opencontainers.image.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "c5ce5f4f977c025c9e5d7317b26769fcc7b16e15e7a99eb5ec2774a479bfccc1", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/c5ce5f4f977c", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "465851a3863f25ecf8251af0d4739ad81b3bedd65597cc1010963bd77b16aeeb", "EndpointID": "", "Gateway": "", "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "", "DriverOpts": null } } } } ] ###太长了--00---

    进入正在运行的容器

    #通常容器都是使用后台方式运行的,需要进入容器 ,修改一些配置 #命令 docker exec -it 容器id bashshell #测试 [fengge@localhost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9d950b1eea12 centos "/bin/bash -c 'while…" 40 seconds ago Up 39 seconds naughty_pare [fengge@localhost ~]$ docker exec -it 9d950b1eea12 /bin/bash [root@9d950b1eea12 /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 12:48 ? 00:00:00 /bin/bash -c while true;do echo fengg root 164 0 0 12:50 pts/0 00:00:00 /bin/bash root 182 1 0 12:51 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-s root 183 164 0 12:51 pts/0 00:00:00 ps -ef #方式二 docker attach 容器id #测试 [fengge@localhost ~]$ docker exec 470671670cac 正在执行当前代码…………………… #docker exec #进入容器后开启一个新的终端,可以在里面操作--常用 #docker attach #进入容器正在执行的终端,不会开启新的进程

    从容器内拷贝文件到主机上

    sudo docker cp 容器id:容器内路径 目的的主机路径 #当前主机目录下 [fengge@localhost home]$ ll 总用量 4 -rw-r--r-- 1 root root 0 6月 12 21:04 ailuoli.go drwx------. 15 fengge fengge 4096 6月 12 21:02 fengge #进入docker容器内部进行 [fengge@localhost home]$ docker attach d199938e24e5 [root@d199938e24e5 /]# cd /home [root@d199938e24e5 home]# ls #在容器内部新建一个文件 [root@d199938e24e5 home]# touch test.go [root@d199938e24e5 home]# exit exit [fengge@localhost home]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [fengge@localhost home]$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d199938e24e5 centos "/bin/bash" 10 minutes ago Exited (127) 35 seconds ago pensive_bassi 9d950b1eea12 centos "/bin/bash -c 'while…" 21 minutes ago Exited (137) 13 minutes ago naughty_pare #将文件拷贝到主机上 [fengge@localhost home]$ sudo docker cp d199938e24e5:/home/test.go /home [sudo] fengge 的密码: [fengge@localhost home]$ ll 总用量 4 -rw-r--r-- 1 root root 0 6月 12 21:04 ailuoli.go drwx------. 15 fengge fengge 4096 6月 12 21:02 fengge -rw-r--r-- 1 root root 0 6月 12 21:08 test.go #拷贝是一个手动操作,容器卷是自动操作

    小结

    attach 进入运行中的容器, 显示该容器的控制台界面。注意, 从该指令退出会导致容器关闭 build 根据 Dockerfile 文件构建镜像 commit 提交容器所做的改为为一个新的镜像 cp 在容器和宿主机之间复制文件 create 根据镜像生成一个新的容器 diff 展示容器相对于构建它的镜像内容所做的改变 events 实时打印服务端执行的事件 exec 在已运行的容器中执行命令 export 导出容器到本地快照文件 history 显示镜像每层的变更内容 images 列出本地所有镜像 import 导入本地容器快照文件为镜像 info 显示 Docker 详细的系统信息 inspect 查看容器或镜像的配置信息, 默认为json数据 kill -s 选项向容器发送信号, 默认为SIGKILL信号(强制关闭) load 导入镜像压缩包 login 登录第三方仓库 logout 退出第三方仓库 logs 打印容器的控制台输出内容 pause 暂停容器 port 容器端口映射列表 ps 列出正在运行的容器, -a 选项显示所有容器 pull 从镜像仓库拉取镜像 push 将镜像推送到镜像仓库 rename 重命名容器名 restart 重启容器 rm 删除已停止的容器, -f 选项可强制删除正在运行的容器 rmi 删除镜像(必须先删除该镜像构建的所有容器) run 根据镜像生成并进入一个新的容器 save 打包本地镜像, 使用压缩包来完成迁移 search 查找镜像 start 启动关闭的容器 stats 显示容器对资源的使用情况(内存、CPU、磁盘等) stop 关闭正在运行的容器 tag 修改镜像tag top 显示容器中正在运行的进程(相当于容器内执行 ps -ef 命令) unpause 恢复暂停的容器 update 更新容器的硬件资源限制(内存、CPU等) version 显示docker客户端和服务端版本信息 wait 阻塞当前命令直到对应的容器被关闭, 容器关闭后打印结束代码 daemon 这个子命令已过期, 将在Docker 17.12之后的版本中移出, 直接使用dockerd ### 此命令集合来自 https://www.cnblogs.com/jpfss/p/10937575.html

    dockerfile是核心,掌握了dockerfile就掌握了docker

    ##写完上面才查看到一个详细的文档

    ##–>https://www.cnblogs.com/ZhuChangwu/p/11985742.html

    nginx部署

    #拉取nginx镜像 [fengge@localhost home]$ docker pull nginx Using default tag: latest latest: Pulling from library/nginx #只贴部分剩下脑子补…………………… #查看nginx镜像 [fengge@localhost home]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 2622e6cca7eb 2 days ago 132MB #运行nginx -d 后台运行 --name 容器命名 -p 宿主端口:容器内部端口 镜像 [fengge@localhost home]$ docker run -d --name nginx01 -p 5566:80 nginx 0879519cd7eae32cc18fee66acd5b4da1358ad87214d1ef65cf2b6851aaaab22 #查看运行的nginx容器 [fengge@localhost home]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0879519cd7ea nginx "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:5566->80/tcp nginx01 [fengge@localhost home]$ curl localhost:5566 <!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> #只贴部分剩下脑子补……………………

    Dockers镜像

    镜像为何

    镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量以及配置文件等.

    Docker镜像加载原理

    UnionFs 联合文件系统

    UnionFs(联合文件系统):union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件下。

    Union文件系统是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等标准目录和文件,rootfs就是各种不同操作系统的发行版,比如Ubuntu,Centos等等。

    对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序就可以了,因为底层直接用宿主机的内核,自己只需要提供rootfs就可以了,因此可见,对于不用的Linux发行版,bootfs基本是一致的,而rootfs会有差别,因此不同的发行版可以公用bootfs。

    Docker镜像分层

    共享资源:多个镜像从相同的父镜像构建而来,那么宿主机只需在磁盘上保存一份父镜像,同时内存中也只需加载一份父镜像就可以为所有容器服务了,并且镜像的每一层都可以被共享。

    Docker镜像特点

    1、Docker镜像只读 ,容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们通常所说的容器层

    2、当镜像实例为容器后,只有最外层是可写的。也就是说镜像为只读层,容器为读写层

    容器数据卷

    数据卷

    [fengge@localhost ~]$ docker run -it -v /myDataVolume:/dataVolumeContainer centos /bin/bash #容器中 [root@b0bd1eda363f /]# ls bin dev home lib64 media opt root sbin sys usr dataVolumeContainer etc lib lost+found mnt proc run srv tmp var #宿主机 [fengge@localhost /]$ ll 总用量 32 lrwxrwxrwx. 1 root root 7 4月 18 08:26 bin -> usr/bin dr-xr-xr-x. 5 root root 4096 6月 12 09:02 boot drwxr-xr-x 20 root root 3300 6月 14 08:53 dev drwxr-xr-x. 146 root root 8192 6月 14 08:53 etc drwxr-xr-x. 3 root root 53 6月 12 21:11 home lrwxrwxrwx. 1 root root 7 4月 18 08:26 lib -> usr/lib lrwxrwxrwx. 1 root root 9 4月 18 08:26 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 6 4月 11 2018 media drwxr-xr-x. 3 root root 18 6月 12 08:58 mnt drwxr-xr-x 2 root root 6 6月 14 10:23 myDataVolume drwxr-xr-x. 4 root root 34 6月 12 09:35 opt dr-xr-xr-x 225 root root 0 6月 14 08:52 proc dr-xr-x---. 5 root root 278 6月 12 11:56 root drwxr-xr-x 45 root root 1340 6月 14 08:57 run lrwxrwxrwx. 1 root root 8 4月 18 08:26 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 4月 11 2018 srv dr-xr-xr-x 13 root root 0 6月 14 08:52 sys drwxrwxrwt. 57 root root 8192 6月 14 10:23 tmp drwxr-xr-x. 13 root root 155 4月 18 08:26 usr drwxr-xr-x. 21 root root 4096 6月 12 09:00 var #容器 [root@b0bd1eda363f /]# cd dataVolumeContainer [root@b0bd1eda363f dataVolumeContainer]# ls [root@b0bd1eda363f dataVolumeContainer]# touch fengge.go [root@b0bd1eda363f dataVolumeContainer]# ls fengge.go [root@b0bd1eda363f dataVolumeContainer]# vi fengge.go #写入 container write [root@b0bd1eda363f dataVolumeContainer]# cat fengge.go container write #宿主机 [fengge@localhost /]$ cat myDataVolume/fengge.go container write [fengge@localhost /]$ sudo vi myDataVolume/fengge.go #宿主机写入host write [fengge@localhost /]$ cat myDataVolume/fengge.go container write host write #容器 修改 [root@b0bd1eda363f dataVolumeContainer]# cat fengge.go container write host write [root@b0bd1eda363f dataVolumeContainer]# vi fengge.go [root@b0bd1eda363f dataVolumeContainer]# cat fengge.go container update host write #宿主机修改 [fengge@localhost /]$ sudo vi myDataVolume/fengge.go [fengge@localhost /]$ cat myDataVolume/fengge.go container update host update #容器 [root@b0bd1eda363f dataVolumeContainer]# cat fengge.go container update host update #主机 [fengge@localhost /]$ sudo touch myDataVolume/test.go [fengge@localhost /]$ ls myDataVolume/ fengge.go test.go #容器 [root@b0bd1eda363f dataVolumeContainer]# ls fengge.go test.go [root@b0bd1eda363f dataVolumeContainer]# rm -f test.go [root@b0bd1eda363f dataVolumeContainer]# ls fengge.go [root@b0bd1eda363f dataVolumeContainer]# touch gege.go [root@b0bd1eda363f dataVolumeContainer]# ls fengge.go gege.go #宿主机 [fengge@localhost /]$ ls myDataVolume/ fengge.go gege.go #退出宿主机后 [fengge@localhost /]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [fengge@localhost /]$ ls myDataVolume/ fengge.go gege.go

    数据卷容器

    命名的容器挂载数据卷,其他容器通过挂载这个父容器实现数据共享,挂载数据卷的容器称为数据卷容器

    #启动dc01容器: docker run -it --name dc01 imageName #dc02继承自dc01: docker run -it --name dc02 --volumes-from dc01 imageName #volumes-from [fengge@localhost /]$ docker run -it --name dc01 -v /myDataVolume:/dataVolumeContainer centos /bin/bash [root@80b11609e899 /]# ls bin dev home lib64 media opt root sbin sys usr dataVolumeContainer etc lib lost+found mnt proc run srv tmp var [root@80b11609e899 /]# touch /dataVolumeContainer/dc01.go [root@80b11609e899 /]# ls /dataVolumeContainer/ fengge.go gege.go dc01.go #创建dc02继承dc01 volumes-from [fengge@localhost ~]$ docker run -it --name dc02 --volumes-from dc01 centos [root@f380c8ea9e45 /]# ls bin dev home lib64 media opt root sbin sys usr dataVolumeContainer etc lib lost+found mnt proc run srv tmp var [root@f380c8ea9e45 /]# touch /dataVolumeContainer/dc02.go [root@f380c8ea9e45 /]# ls /dataVolumeContainer fengge.go gege.go dc01.go dc02.go #创建dc03继承dc02 volumes-from [fengge@localhost ~]$ docker run -it --name dc03 --volumes-from dc02 centos [root@2a72db9ca175 /]# ls /dataVolumeContainer fengge.go gege.go dc01.go dc02.go [root@2a72db9ca175 /]# touch /dataVolumeContainer/dc03.go [root@2a72db9ca175 /]# ls /dataVolumeContainer/ fengge.go gege.go dc01.go dc02.go dc03.go #宿主机 [fengge@localhost ~]$ ls /myDataVolume/ fengge.go gege.go dc01.go dc02.go dc03.go #容器dc01 删除文件 [root@80b11609e899 /]# rm /dataVolumeContainer/gege.go #三个容器执行 ls /dataVolumeContainer/ 相同的结果 [root@80b11609e899 /]# fengge.go dc01.go dc02.go dc03.go #宿主机 [fengge@localhost ~]$ ls /myDataVolume/ fengge.go dc01.go dc02.go dc03.go #现在把容器dc01删除 dc02继承dc01 dc03继承于dc02 [fengge@localhost ~]$ docker rm -f dc01 dc01 [fengge@localhost ~]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b0b958899aa8 centos "/bin/bash" 33 minutes ago Up 33 minutes dc003 3ac41d743abf centos "/bin/bash" 35 minutes ago Up 35 minutes dc002 #查看dc02 dc03中的数据卷的情况 [root@f380c8ea9e45 /]# ls /dataVolumeContainer/ fengge.go dc01.go dc02.go dc03.go # [root@f380c8ea9e45 /]# touch /dataVolumeContainer/dc03_update.txt [root@2a72db9ca175 /]# touch /dataVolumeContainer/dc02_update.txt #容器中 [root@2a72db9ca175 /]# ls /dataVolumeContainer/ dc01.go dc02.go dc02_update.txt dc03.go dc03_update.txt fengge.go [root@2a72db9ca175 /]# ls /dataVolumeContainer/ dc01.go dc02.go dc02_update.txt dc03.go dc03_update.txt fengge.go #主机中 [fengge@localhost ~]$ ls /myDataVolume/ dc01.go dc02.go dc02_update.txt dc03.go dc03_update.txt fengge.go

    我们讲容器删除后,发现挂载到本地的数据卷没有丢失,这就实现了容器数据的持久化功能

    具名和匿名挂载

    #匿名挂载 -v 容器内路径 docker run -d -P --name nginx02 -v /etc/nginx nginx #查看你所有的volume 情况 [fengge@localhost ~]$ docker run -d -P --name nginx02 -v /etc/nginx nginx 7090527fec247065d1b9c95bc6cf383fc62b24b94fbf4ee24f0f63ad51d38f61 [fengge@localhost ~]$ docker volume list DRIVER VOLUME NAME local 6f603e9a0350063cf10e7e3822b4768b47a99088df6f7e15e1ee1ec530353582 local c134e8f9d79e6cb1de5cbc05a679c08b58480febb70e874c6e7a256fb1b182e8 local fd15bdfbcf5146c1308b4090a0ee74285e4b731155942d017b1457e688fd571b #剧名挂载 jintian-nginx前面没有加/ 不是绝对路径 只是普通配置 [fengge@localhost ~]$ docker run -d -P --name nginx03 -v jintian-nginx:/etc/nginx nginx cae2be4518e2ebd4ddb0ce12645eef794495a60bd80f1035ba641c5917a5fc60 [fengge@localhost ~]$ docker volume ls DRIVER VOLUME NAME local 6f603e9a0350063cf10e7e3822b4768b47a99088df6f7e15e1ee1ec530353582 local c134e8f9d79e6cb1de5cbc05a679c08b58480febb70e874c6e7a256fb1b182e8 local fd15bdfbcf5146c1308b4090a0ee74285e4b731155942d017b1457e688fd571b local jintian-nginx #通过 -v 卷名:容器内路径 #查看一下这个卷的信息 [fengge@localhost ~]$ docker volume inspect jintian-nginx [ { "CreatedAt": "2020-06-14T14:06:05+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/jintian-nginx/_data", "Name": "jintian-nginx", "Options": null, "Scope": "local" } ]

    所有docker容器内的卷,没有指定目录的情况下都是在var/lib/docker/volumes/xxx/_data

    通过具名挂载可以很方便的找到我们的一个卷,大多数情况在使用 具名挂载

    #如何确定是具名挂载还是匿名挂载,还是指定路径挂载 -v 容器内路径 #匿名挂载 -v 卷名:容器内路径 #具名挂载 -v /宿主机路径:容器内路径 #指定路径挂载 #通过 -v 容器内路径:ro rw 改变读写权限 ro readonly #只读 rw readwrite #读写 #一旦确定这个设置容器权限,容器对我们挂载出来的内容就有限定了 docker run -d -P --name nginx02 -v /etc/nginx:ro nginx docker run -d -P --name nginx02 -v /etc/nginx:rw nginx #ro 只要看到ro 就说明了这个路径只能通过宿主机来操作,容器内部是无法操作的

    dockerfile

    dockerfile原则

    #更小的Docker镜像大小 #更少的Docker镜像层 #充分利用镜像缓存 #增加Dockerfile可读性 #让Docker容器使用起来更简单

    FROM

    FROM <image> [AS <name>] FROM <image>[:tag] [AS name] #基础镜像,当前的镜像是基于哪个镜像的 FROM centos:7

    MAINTAINER

    MAINTAINER <name> #维护者信息 MAINTAINER fengge MAINTAINER fengge@163.com MAINTAINER fengge <jack@163.com>

    ENV

    #设置环境变量 ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>... ENV VERSION=1.0 DEBUG=on \ NAME="HappyFeet" ENV NODE_VERSION 7.2.0 ENV env_var_name=$NAME

    WORKDIR

    # WORKDIR 指定在创建容器后,终端默认登陆的进来工作的目录,一个落脚点 WORKDIR /path/to/workdir #该WORKDIR指令集的工作目录对任何RUN,CMD, ENTRYPOINT,COPY和ADD有效。如果WORKDIR不存在,即使它未在任何后续Dockerfile指令中使用,也将创建它。 #该WORKDIR指令可以在Dockerfile多次使用。如果提供了相对路径,则它将相对于前一条WORKDIR指令的路径 WORKDIR /home WORKDIR fengge WORKDIR gege RUN pwd #pwd命令最终输入dockerfile是 /home/fengge/gege

    RUN

    #RUN 构建容器时需要运行的命令 RUN (shell形式)(常用) RUN [“executable”, “param1”, “param2”](exec形式) #exec形式被解析为JSON数组,这意味着必须使用双引号(“),而不是单引号(') #RUN指令将在当前镜像之上的新层中执行任何命令并提交结果。生成的镜像用于下一步Dockerfile #tip 将多个RUN指令合并为一个,减少镜像形成,因为每一个RUN都会形成一个镜像。基础镜像的标签不要用latest。每个RUN指令后要删除多余的文件。 #使用\将多个RUN指令合成一个,可以有效减少容器层数以及镜像大小。当我们更新了apt-get源,下载安装了一些软件包,它们都保存在/var/lib/apt/lists/目录中。但是,运行应用时Docker镜像中并不需要这些文件。最好将它们删除,因为这会使Docker镜像变大。 RUN yum makecache && \ yum -y install gcc gcc-c++\ autoconf wget \ psmisc \ openssl openssl-devel \ gperftools-devel \ tar \ passwd \ openssh-server \ openssh-clients \ initscripts \ unzip pcre pcre-devel zlib zlib-devel git \ libxml2 libxml2-devel curl curl-devel \ libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel \ python-setuptools dos2unix gperf \ libevent libevent-devel bzip2-devel ncurses-devel \ boost libtool boost-devel* libuuid-devel python-sphinx.noarch &&\ yum clean all &&\ rm -rf /var/lib/apt/lists/* &&\ rm -rf /var/cache/yum

    EXPOSE

    #EXPOSE 当前容器用来对外暴露端口 EXPOSE <port> [<port>/<protocol>...] EXPOSE 80/tcp EXPOSE 80/udp #测试 docker run -p 80:80/tcp -p 80:80/udp ...

    LABEL

    #LABEL 用来给镜像添加元素据 LABEL <key>=<value> <key>=<value> <key>=<value> ... #示例: LABEL version="1.0" description="测试" #使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像

    ADD

    # ADD 讲宿主机目录下的文件拷贝进镜像切ADD命令会自动处理URL和解压tar压缩包。可以访问网络资源,类似wget #目的位置不存在,Docker会自动创建所需要的目录结 #格式: ADD <src>... <dest> ADD ["<src>",... "<dest>"] 用于支持包含空格的路径 #示例: ADD hom* /mydir/ # 添加所有以"hom"开头的文件 ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt" ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/ ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/ #注意:需要复制的本地文件一定要放在Dockerfile文件的同级目录下 #原因:因为构建环境将会先上传到Docker守护进程,而复制是在Docker守护进程中进行的。任何位于构建环境之外的东西都是不可用的。ADD指令的目的的位置则必须是容器内部的一个绝对路径。

    WOLUME

    #WOLUME 添加数据卷,用于持久化目录 VOLUME ["/path/to/dir"] #例子 VOLUME ["/myVolumeContainer"] VOLUME ["/var/www", "/etc/nginx", "/etc/apache2","/var/log/mysql"] #注: 一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能: #1 卷可以容器间共享和重用 #2 容器并不一定要和其它容器共享卷 #3 修改卷后会立即生效 #4 对卷的修改不会对镜像产生影响 #5 卷会一直存在,直到没有任何容器在使用它

    ENTRYPOINT

    #配置容器,使其可执行化。配合CMD可省去"application",只使用参数 ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先) ENTRYPOINT command param1 param2 (shell内部命令) #入口程序是容器启动时执行的程序,docker run中最后的命令将作为参数传递给入口程序 #入口程序有两种格式:exec、shell,其中shell使用/bin/sh -c运行入口程序,此时入口程序不能接收信号量 #当Dockerfile有多条ENTRYPOINT时只有最后的ENTRYPOINT指令生效 #如果使用脚本作为入口程序,需要保证脚本的最后一个程序能够接收信号量,可以在脚本最后使用exec或gosu启动传入脚本的命令 #注意:通过shell方式启动入口程序时,会忽略CMD指令和docker run中的参数 为了保证容器能够接受docker stop发送的信号量,需要通过exec启动程序;如果没有加入exec命令,则在启动容器时容器会出现两个进程,并且使用docker stop命令容器无法正常退出(无法接受SIGTERM信号),超时后docker stop发送SIGKILL,强制停止容器 FROM ubuntu <换行> ENTRYPOINT exec top -b

    CMD

    #类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者的运行时间点不同RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖,在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效 CMD <command> 或 CMD [<executable>”, “<param1>”, “<param2>] 或 CMD ["<param1>","<param2>"] #如果启动竟像是有其他的命令会把最后一个命令替换掉

    docker build

    -t (坑:不能以/开头)

    docker网络

    #linux 容器是否可以ping docker容器

    每docker启动一个docker容器,docker就会给docker容器分配一个ip,只要我们安装了docker,就会有一个docker0桥接模式,使用的是veth-pair技术!

    [root@localhost test]# 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 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:27:b8:9f brd ff:ff:ff:ff:ff:ff ##----其他 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:7b:c1:ed brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever ##----其他 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:7b:c1:ed brd ff:ff:ff:ff:ff:ff ##------这里就是docker0地址 5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:af:8b:21:4b 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:afff:fe8b:214b/64 scope link valid_lft forever preferred_lft forever 52: br-880f47423aa7: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:84:3f:58:90 brd ff:ff:ff:ff:ff:ff inet 192.168.0.1/16 brd 192.168.255.255 scope global br-880f47423aa7 valid_lft forever preferred_lft forever

    网络模式

    bridge :桥接 --docker默认模式

    none:不配置网络

    host:和主机共享网络

    container:容器网络联通 --使用少局限大

    测试

    #我们直接启动一个命令 --net bridge 使用的事docker0 docker run -d -p --name nginx01 nginx docker run -d -P --name nginx01 --net bridge nginx #docker0特点 默认 域名不能访问,--link可以大同连接 #可以自定义一个自定义网络 #帮助文档 [root@localhost ~]# docker network create --help Usage: docker network create [OPTIONS] NETWORK Create a network Options: --attachable Enable manual container attachment --aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[]) --config-from string The network from which copying the configuration --config-only Create a configuration only network -d, --driver string Driver to manage the Network (default "bridge") --gateway strings IPv4 or IPv6 Gateway for the master subnet --ingress Create swarm routing-mesh network --internal Restrict external access to the network --ip-range strings Allocate container ip from a sub-range --ipam-driver string IP Address Management Driver (default "default") --ipam-opt map Set IPAM driver specific options (default map[]) --ipv6 Enable IPv6 networking --label list Set metadata on a network -o, --opt map Set driver specific options (default map[]) --scope string Control the network's scope --subnet strings Subnet in CIDR format that represents a network segment #创建自定义网络 #--driver bridge #--subnet 192.168.0.2/16 192.168.2 192.168.255.255(最大) [root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 501da386b2a5701b47b7dd6581be7f4b217398f823c2d872a282441647e07065 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 4f17b7242743 bridge bridge local 5644bd8f7125 host host local 501da386b2a5 mynet bridge local 2736b9202743 none [root@localhost ~]# docker network inspect 501da386b2a5 [ { "Name": "mynet", "Id": "501da386b2a5701b47b7dd6581be7f4b217398f823c2d872a282441647e07065", "Created": "2020-06-18T12:12:01.856734467+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": {} } ] #docker使用自定义网络实现容器互联 [root@localhost ~]# docker run -d -P --name nginx-mynet-91 --net mynet nginx 76cb080ebaa8ac5efd276eb027d559cc0e6b82298cb4d2acca82a8c4750d61f1 [root@localhost ~]# docker run -d -P --name nginx-mynet-81 --net mynet nginx 89f80f2d918683e5f513c2dc5a4c5c5446748205a5278f133835da99484aef5e [root@localhost ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "501da386b2a5701b47b7dd6581be7f4b217398f823c2d872a282441647e07065", "Created": "2020-06-18T12:12:01.856734467+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": { "76cb080ebaa8ac5efd276eb027d559cc0e6b82298cb4d2acca82a8c4750d61f1": { "Name": "nginx-mynet-91", "EndpointID": "52f6555a4d2fb93bd352be09bc2a676ecea154e077ee0042191a1927223f1b7d", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "89f80f2d918683e5f513c2dc5a4c5c5446748205a5278f133835da99484aef5e": { "Name": "nginx-mynet-81", "EndpointID": "69435fe3db2d9b67bef1fb672d2d44c775abb12bf853f3ad05b0d2713c8ce343", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] [root@localhost ~]#docker exec -it nginx-mynet-91 ping 192.168.0.3

    docker-composer

    安装

    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”: { “76cb080ebaa8ac5efd276eb027d559cc0e6b82298cb4d2acca82a8c4750d61f1”: { “Name”: “nginx-mynet-91”, “EndpointID”: “52f6555a4d2fb93bd352be09bc2a676ecea154e077ee0042191a1927223f1b7d”, “MacAddress”: “02:42:c0:a8:00:02”, “IPv4Address”: “192.168.0.2/16”, “IPv6Address”: “” }, “89f80f2d918683e5f513c2dc5a4c5c5446748205a5278f133835da99484aef5e”: { “Name”: “nginx-mynet-81”, “EndpointID”: “69435fe3db2d9b67bef1fb672d2d44c775abb12bf853f3ad05b0d2713c8ce343”, “MacAddress”: “02:42:c0:a8:00:03”, “IPv4Address”: “192.168.0.3/16”, “IPv6Address”: “” } }, “Options”: {}, “Labels”: {} } ] [root@localhost ~]#docker exec -it nginx-mynet-91 ping 192.168.0.3

    # docker-composer ## 安装 安装错误可以看这篇文章 https://blog.csdn.net/jiangbenchu/article/details/82744824
    Processed: 0.015, SQL: 9