Docker基础学习笔记

Docker

Docker的概念

共享主机内核,轻量,隔离且高效,不想虚拟机需要完整的操作系统

上层是多个容器,每个容器独立运行一个应用

中间是Docker,负责管理这些容器

底层是主机操作系统HostOS和基础设施,为容器提供硬件和系统支持

容器核心理念

应用和环境被打包成不可变镜像

每次部署都使用相同的镜像

配置通过环境变量或配置文件注入

问题修复通过重新构建镜像而非修改运行中的容器

Docker的核心理念

镜像(Image)

镜像知识一个只读模块,包含运行应用所需内容:代码、运行、库文件、环境变量和配置文件

特点:

分层存储:镜像由多个层组成,每一层代表一次修改

只读性:镜像本身只读,不能直接修改

可复用:同一个镜像可创建多个容器

版本管理:通过tag进行版本管理

容器(Container)

容器时镜像运行的实例,是一个轻量级,可移植性的执行环境

隔离性:每个容器都有自己文件系统、网络和进程空间

临时性:容器可以被创建、启动、停止、删除

可写层:容器在镜像基础上添加一个可写层

进程级:容器内通常运行一个主进程

仓库(Repository)

仓库和存储和分发镜像的地方,可以包含一个镜像的多个版本

公共仓库:Docker Hub,任何人都可以使用

私有仓库:企业内部搭建,用于存储私有镜像

官方仓库:软件官方维护的镜像仓库

Docker与虚拟机的区别

架构区别

场景对比

|---|-------------|-------------------|
| | 虚拟机使用场景 | 容器使用场景 |
| | 需要完全隔离的环境 | 微服务架构 |
| | 运行不同操作系统的应用 | CI/CD流水线 |
| | 需要硬件级别的安全隔离 | 应用快速部署和扩展,开发环境标准化 |

Docker的架构组件

Docker Client

功能:

用户与Docker交互的主要方式

接收用户命令并发送Docker Daemon

可以远程Docker Daemon通信

Docker Daemon

Docker的核心服务进程

管理镜像、容器、网络和存储卷

监听Docker API请求并处理

Docker Registry

存储和分发Docker镜像

提供镜像的版本管理

支持公有和私有仓库

使用整体流程

Docker常用命令

镜像命令

bash 复制代码
# 例出所有镜像
[root@node1 ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    feb5d9fea6a5   3 years ago   13.3kB
centos        latest    5d0da3dc9764   3 years ago   231MB

#例如所有镜像id
[root@node1 ~]# docker images -aq
feb5d9fea6a5
5d0da3dc9764

#下载MySQL镜像
[root@node1 ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete  # 分层下载docker image的核心联合文件索引
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   #真实地址

# 删除镜像命令
[root@node1 ~]# docker rmi -f $(docker images -aq) #删除所有镜像

容器命令

新建容器启动
bash 复制代码
docker run [可选参数] image
# 参数说明
--name="Name"      容器名字
-d                 后台方式运行
-it                使用快捷交互方式运行,进入容器查看内容
-p                 指定容器端口 -p 8080:8080  (主机端口:容器端口)
-P                随机指定端口

# 启动并进入容器
[root@node1 ~]# docker run -it centos  /bin/bash
# 退出容器命令
[root@fc56051b6477 /]# exit  #退出即停止
exit
Ctr + P +Q #容器退出但不会停止
# 例出当前正在运行的容器
[root@node1 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 删除容器
[root@node1 ~]# docker rm 容器id
# 批量删除容器
[root@node1 ~]# docker rm -f `docker ps -aq`
启动和停止容器操作
bash 复制代码
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id    
查看容器进程信息
bash 复制代码
docker top 容器id

# 查看镜像详细数据
docker inspect 容器id

[
    {
        "Id": "fc56051b6477f2db3b796126127823658c3fcf9bf95c646ca904ffa5f43b59ee",
        "Created": "2025-07-28T02:50:06.533466786Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2025-07-28T02:50:06.870607508Z",
            "FinishedAt": "2025-07-28T02:51:17.154604984Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/fc56051b6477f2db3b796126127823658c3fcf9bf95c646ca904ffa5f43b59ee/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/fc56051b6477f2db3b796126127823658c3fcf9bf95c646ca904ffa5f43b59ee/hostname",
        "HostsPath": "/var/lib/docker/containers/fc56051b6477f2db3b796126127823658c3fcf9bf95c646ca904ffa5f43b59ee/hosts",
        "LogPath": "/var/lib/docker/containers/fc56051b6477f2db3b796126127823658c3fcf9bf95c646ca904ffa5f43b59ee/fc56051b6477f2db3b796126127823658c3fcf9bf95c646ca904ffa5f43b59ee-json.log",
        "Name": "/silly_mclean",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "bridge",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "ConsoleSize": [
                35,
                175
            ],
            "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": [],
            "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",
                "/sys/devices/virtual/powercap"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/aa5451ca535227500eb778bf36c500db3d1f01f9ecfb0279cd1199ad8eb9fdbd-init/diff:/var/lib/docker/overlay2/d30db0dc5cce265d7c9d91dd409290eb73f490f968c329e0094a6670f2643e9a/diff",
                "MergedDir": "/var/lib/docker/overlay2/aa5451ca535227500eb778bf36c500db3d1f01f9ecfb0279cd1199ad8eb9fdbd/merged",
                "UpperDir": "/var/lib/docker/overlay2/aa5451ca535227500eb778bf36c500db3d1f01f9ecfb0279cd1199ad8eb9fdbd/diff",
                "WorkDir": "/var/lib/docker/overlay2/aa5451ca535227500eb778bf36c500db3d1f01f9ecfb0279cd1199ad8eb9fdbd/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "fc56051b6477",
            "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": "fc190f97102d538f89d0c337450ae64043e1b0787e4b306b5fc4ac32b08f49e3",
            "SandboxKey": "/var/run/docker/netns/fc190f97102d",
            "Ports": {},
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "",
                    "NetworkID": "2812d36c28f0fd892fb5124a66324466c92176c1b5274a84898dbf0504d139d6",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null,
                    "DNSNames": null
                }
            }
        }
    }
]
进入当前正在运行的容器
bash 复制代码
# 方式一
docker exec -it 容器id /bin/bash

方式二
docker attach -it 容器id 

# 区别,方式一进入容器后开启一个新的终端,可在里面操作,退出后容器也不会停止
#  方式二进入正在执行的终端后,不会启动新的进程。生产环境不建议使用

部署启动tomcat

bash 复制代码
[root@node1 ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
0e29546d541c: Pull complete 
9b829c73b52b: Pull complete 
cb5b7ae36172: Pull complete 
6494e4811622: Pull complete 
668f6fcc5fa5: Pull complete 
dc120c3e0290: Pull complete 
8f7c0eebb7b1: Pull complete 
77b694f83996: Pull complete 
0f611256ec3a: Pull complete 
4f25def12f23: Pull complete 
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
[root@node1 ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
nginx         latest    605c77e624dd   3 years ago   141MB
tomcat        latest    fb5657adc892   3 years ago   680MB
mysql         latest    3218b38490ce   3 years ago   516MB
hello-world   latest    feb5d9fea6a5   3 years ago   13.3kB
centos        latest    5d0da3dc9764   3 years ago   231MB
[root@node1 ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
8f9ed2d2a12e4a4e7d5b28d8d88b8caf6dfe099a32c74e9ab775e30bfeffdce2

部署es+kibana

bash 复制代码
# 自动拉取镜像并下载然后启动elasticsearch
[root@node1 ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch
# 限制内存大小启动
[root@node1 ~]# docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="Xms64m -Xmx512m" elasticsearch
# 查看占用的CPU状态
[root@node1 ~]# docker stats
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT    MEM %     NET I/O     BLOCK I/O   PIDS
8f9ed2d2a12e   tomcat01   0.10%     50.1MiB / 1.715GiB   2.85%     656B / 0B   0B / 0B     18
# 访问服务器地址加9200端口即可

commit镜像

bash 复制代码
docker commit 提交容器成为一个新的副本
docker commit -m="提交信息描述" -a="作者" 容器id 目标镜像名:[TAG]

# 1,进入tomcat容器,然后将webapps.dist下文件拷贝到webapps里面
# 2,将自己操作过的容器镜像通过commit提交为一个镜像,我们以后就使用修改过的镜像即可
root@8f9ed2d2a12e:/usr/local/tomcat# cp -r webapps.dist/*   webapps
root@8f9ed2d2a12e:/usr/local/tomcat# cd webapps
root@8f9ed2d2a12e:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
# 将操作过的容器通过commit提交为一个镜像,使用修改过的镜像即可,用镜像查看命令看是否提交成功
[root@node1 ~]# docker commit -a="Tian" -m="add webapps app" 8f9ed2d2a12e tomcat02:1.0
[root@node1 ~]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED       SIZE
tomcat02        1.0       76b40495db7f   2 weeks ago   684MB
nginx           latest    605c77e624dd   3 years ago   141MB
tomcat          latest    fb5657adc892   3 years ago   680MB
mysql           latest    3218b38490ce   3 years ago   516MB
hello-world     latest    feb5d9fea6a5   3 years ago   13.3kB
centos          latest    5d0da3dc9764   3 years ago   231MB
elasticsearch   latest    5acf0e8da90b   6 years ago   486MB

容器数据卷

数据卷介绍

容器持久化同步操作,容器间也可以数据共享

使用数据卷

bash 复制代码
1,方式一
docker run -it -v 主机目录:容器目录

# 测试文件同步,使用数据卷挂载
[root@node1 ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
# 虚拟机中查看容器详情
[root@node1 ~]# docker inspect 64a2718f6a19
"Mounts": [
            {
                "Type": "bind",
                "Source": "/home/ceshi",   # 主机地址
                "Destination": "/home",    # docker容器内的地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
# 容器内容创建文件后,主机中也会同步
[root@64a2718f6a19 home]# touch 1.text
[root@64a2718f6a19 home]# ls
1.text

数据库数据持久化

bash 复制代码
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@node1 ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql

然后用本地的mysql连接到服务器创建的mysql就可以实现数据持久化

具名挂载和匿名挂载

bash 复制代码
# 匿名挂载
[root@node1 ~]# docker run -d -P nginx01 -v /etc/nginx nginx
# 查看所有的volume的情况
[root@node1 ~]# docker volume ls

DRIVER    VOLUME NAME
local     5f3f53d2389544f4c93cedec84b769563b1b01e7b5220f4e34fa339f54321b85
local     7948c0be61687d167efa25ec7113d82bd3cde4a640dab8e845d295362c62227f
local     41534caaabfced3bc4a68a6935d2be9c8c80bc64d536094bfef97f82a42ce30b

# 具名挂载
[root@node1 ~]# docker run -d -P --name nginx02 -v detail-nginx:/etc/nginx nginx
[root@node1 ~]# docker volume ls
DRIVER    VOLUME NAME
local     5f3f53d2389544f4c93cedec84b769563b1b01e7b5220f4e34fa339f54321b85
local     7948c0be61687d167efa25ec7113d82bd3cde4a640dab8e845d295362c62227f
local     41534caaabfced3bc4a68a6935d2be9c8c80bc64d536094bfef97f82a42ce30b
local     detail-nginx

默认挂载路径在/var/lib/volumes/***下

2,方式二
# 编写dockerfile文件内容
[root@node1 docker-test]# vim dockerfile1
[root@node1 docker-test]# cat dockerfile1
FROM centos
VOLUME ["volume01", "volume02"]
CMD echo "---end---"
CMD /bin/bash 
# 构建镜像
[root@node1 docker-test]# docker build -f dockerfile1 -t  tian/centos .
[root@node1 docker-test]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED       SIZE
tian/centos     latest    2771b5374df0   3 years ago   231MB
# 启动自己容器镜像
[root@node1 docker-test]# docker run -it 2771b5374df0 /bin/bash
# 可以查看到自己挂载的volume1和volume2
[root@cdd6785e8626 /]# ls -l
drwxr-xr-x  20 root root 4096 Sep 15  2021 var
drwxr-xr-x   2 root root 4096 Aug 13 07:38 volume01
drwxr-xr-x   2 root root 4096 Aug 13 07:38 volume02

数据卷容器

bash 复制代码
# 容器数据间之间继承
docker run -it --name 子容器 --volumes-from 父容器 镜像名

# 启动docker01容器
[root@node1 ~]# docker run -it --name docker01 tian/centos

# 启动docker02并继承docker01数据卷
[root@node1 ~]# docker run -it --name docker02 --volumes-from docker01 tian/centos

# 在docker01中创建docker01文件,docker02容器中也会有
[root@82922241b4a1 /]# cd volume01
[root@82922241b4a1 volume01]# ls
[root@82922241b4a1 volume01]# touch docker01.txt
# docker02中查看
[root@eb45c1458930 volume01]# ls
docker01.txt

结论:容器之间配置信息传递,数据卷容器的生命周期一直持续到没有容器使用为止

一旦持久化到本地,则本地数据不会删除

Dockerfile

概念

是用来构建docker镜像的文件,命令参数脚本

构建步骤

1,编写dockerfile文件

2,docker build构建成一个镜像

3,docker run 运行镜像

4,docker push发布镜像(DockerHub、阿里云镜像仓库等)

指令

bash 复制代码
FROM:指定基础镜像
MAINTAINER:镜像名+邮箱,知道镜像作者
RUN:在镜像中执行命令
ADD/COPY:添加内容(ADD可以自动解压,url等COPY只能复制本地文件,一般用COPY)
WORKDIR:镜像的工作目录
VOLUME:挂载的目录
CMD:指定容器启动时默认执行的命令,只有最后一个会生效,会被docker run命令参数覆盖
ENTRYPOINT:指定容器启动时默认执行的命令,可以追加命令
EXPOSE:暴露容器端口
ENV:设置环境变量

发布自己镜像

1,注册自己账号

2,在服务器提交自己镜像

bash 复制代码
# 登录dockerhub账号
[root@node1 ~]# docker login -u
# 镜像发布
[root@node1 ~]# docker tag 82922241b4a1 tian/mytomcat:1.0
[root@node1 ~]# docker push tian/mytomcat:1.0

阿里云镜像发布

1,登录阿里云

2,找到容器服务

3,创建命名空间

4,创建后参考阿里云官方文档

bash 复制代码
1,[root@node1 ~]# docker login -阿里云镜像名
2,[root@node1 ~]# docker push tian/mytomcat:1.0

Docker网络

bash 复制代码
# 产看容器网络
[root@node1 ~]# docker exec -it tomcat01 ip addr
# ping容器网络
[root@node1 ~]# ping  172.17.0.2
PING 172.17.0.2 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.042 ms

原理

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

2,veth-pair技术。是一对虚拟设备接口,成对出现,一端连接协议,一端彼此相连。每当创建一个容器后,会发现会成对网卡会成对。如63和62

bash 复制代码
[root@node1 ~]# ip addr
63: veth97ae6d5@if62: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether c2:32:12:50:67:19 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c032:12ff:fe50:6719/64 scope link 

3,容器之间可以进行通信

bash 复制代码
[root@node1 ~]# docker exec -it tomcat02 ping 172.17.0.2

网络模型

所有容器在不指定网络情况下,都是docker0路由的,docker会给我们容器分配默认的可用ip。docker所有网络接口都是虚拟的,虚拟的转发效率高。

自定义网络

docker网络模式

bash 复制代码
# bridge为桥接模式
# none 不配置网络
# host 和宿主机共享网络
[root@node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2812d36c28f0   bridge    bridge    local
dc2de3ca0a28   host      host      local
b2881497f8dc   none      null      local


# 自定义网络
# --driver bridge  模式
# --subnet 192.168.0.0/16 子网掩码
# --gateway 192.168.0.1   网关
[root@node1 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
8b893895d220e75481baa19bdc299edf7ce08bb8c9694840a2b9d042b9575f18
[root@node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
8b893895d220   mynet     bridge    local
# 启动容器
[root@node1 ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat
fee2e32bf773af3959d14cbbd8ce8370d55938210863acd5b873bc370d487155
[root@node1 ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat
4ca35984edef567b95ffd457d1aba87fd0d75695b9ee34fdff7fe33e49dc5e2a
# 查看该网络中自己容器
[root@node1 ~]# docker network inspect mynet
   "4ca35984edef567b95ffd457d1aba87fd0d75695b9ee34fdff7fe33e49dc5e2a": {
                "Name": "tomcat-net02",
                "EndpointID": "ec8ac64a0e798fb7cec075cf2132ea14a75b9e1f89d2504666cd1b1bbc6087e1",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "fee2e32bf773af3959d14cbbd8ce8370d55938210863acd5b873bc370d487155": {
                "Name": "tomcat-net01",
                "EndpointID": "185603b16ae9e9fbcfd7f51c50186bd87ef38c597fb538efa7d3d5b7790ac553",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
# 容器1可以ping容器2的网络,修复了docker0网络中不能ping容器名的bug
[root@node1 ~]# docker exec -it tomcat-net01 ping tomcat-net02               

网络连接

bash 复制代码
# 创建网络与tomcat01连接
# 一个容器两个ip地址
[root@node1 ~]# docker network connect mynet tomcat01

部署Redis集群

bash 复制代码
1,# 创建Redis集群网络
[root@node1 ~]# docker network create redis --subnet 172.38.0.0/16 
204e78bce60280e035f11d4531f5dfea2a60a62fcc0f87b95198836250baac58
[root@node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2812d36c28f0   bridge    bridge    local
dc2de3ca0a28   host      host      local
204e78bce602   redis     bridge    local
2,# shell脚本,创建六个docker容器
[root@node1 ~]# 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-enable 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
#说明
# cluster-enable yes 启用Redis集群模式
# cluster-config-file nodes.conf  指定用于保存集群节点配置的文件名
# cluster-node-timeout 5000  节点超时时间,超过次响应时间则认为该节点失效
# cluster-announce-ip 172.38.0.1${port}  ip地址
# cluster-announce-port 6379   端口     
# cluster-announce-bus-port 16379  集群总线端口
# appendonly yes  启用AOF作为持久化方式

3,# 启动所有redis节点
# 循环启动6个Redis容器节点
for port in $(seq 1 6);
do
  docker run -d -p 637${port}:6379 -p 1637${port}:16379 \
    --name redis-${port} \
    --net redis \
    --ip 172.38.0.1${port} \
    -v /mydata/redis/node-${port}/data:/data \
    -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
    redis:6.2.6 redis-server /etc/redis/redis.conf
done
# 查看启动的容器
docker ps | grep redis
4, # 创建集群
[root@node1 ~]# docker exec it redis-6379 env REDISCLI_AUTH==1234 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 \
--cluster-yes
5,验证集群状态
[root@node1 ~]# docker exec -it redis-6379 redis-cli -h 172.38.0.11 -p 6379 -a "1234" cluster nodes

Docker Compose

安装

1,下载安装

bash 复制代码
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

2,赋予执行权限

bash 复制代码
sudo chmod +x /usr/local/bin/docker-compose

3,查看版本

bash 复制代码
docker-compose --version

实战

docker compose启动Wordpress

bash 复制代码
1,创建一个docker-compose.yaml文件
2,yaml文件内容
name:myblog
version :'3'
services:
  mysql:
    container_name: mysql
    image: mysql:8.0
    build:
      context:./mysql
    ports:
      -"3306:3306"
    volumes:
      -mysql-data:/var/lib/mysql
      -./app/myconf:/etc/mysql/conf.d
    environment:
      MYSQL_DATABASE:'root'
      MYSQL_ROOT_PASSWORD:'123456'
    restart: always
    networls:
        -blog
   Wordpress:
    image: wordpress
    ports:
      -"8080:80"
    environment:
      WORDPRESS_DB_HOST:mysql
      WORDPRESS_DB_USER:root
      WORDPRESS_DB_PASSWORD:'123456'
      WORDPRESS_DB_NAME:wordpress
    volumes:
      - wordpress:/var/www/html
    restart:always
    networks:
      - blog
    depends_on:
       -mysql  
       
volumes:
   mysql-data:
   wordpress:
network:
   blog:    
3,使用docker-compose up创建启动即可                

yaml文件详情

bash 复制代码
1,version
指定本 yml 依从的 compose 哪个版本制定的。
2,build
指定为构建镜像上下文路径
3,command
覆盖容器启动的默认命令。
4,container_name
指定自定义容器名称,而不是生成的默认名称。
5,depends_on
设置依赖关系
例如
 web:
    build: .
    depends_on:
      - db
      - redis
docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web
6,deploy
指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
7,environment
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False
8,networks
配置容器连接的网络,引用顶级 networks 下的条目 
9,restart
no:是默认的重启策略,在任何情况下都不会重启容器。
always:容器总是重新启动
10,volumes
将主机的数据卷或者文件挂载到容器里。

Docker Swarm

概念

swarm manager:负责整个集群的管理工作包括集群配置、服务管理等所有集群有关工作

work node:主要负责运行相应的服务来执行任务

示例图:

命令

bash 复制代码
[root@localhost ~]# docker swarm --help

Usage:	docker swarm COMMAND

Manage Swarm

Commands:
  ca          Display and rotate the root CA
  init        Initialize a swarm
  join        Join a swarm as a node and/or manager
  join-token  Manage join tokens
  leave       Leave the swarm
  unlock      Unlock swarm
  unlock-key  Manage the unlock key
  update      Update the swarm

Run 'docker swarm COMMAND --help' for more information on a command.

# 初始化命令
[root@localhost ~]# docker swarm init --help

Usage:	docker swarm init [OPTIONS]

Initialize a swarm

Options:
      --advertise-addr string                  Advertised address (format: <ip|interface>[:port])
      --autolock                               Enable manager autolocking (requiring an unlock key to start a stopped manager)
      --availability string                    Availability of the node ("active"|"pause"|"drain") (default "active")
      --cert-expiry duration                   Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
      --data-path-addr string                  Address or interface to use for data path traffic (format: <ip|interface>)
      --data-path-port uint32                  Port number to use for data path traffic (1024 - 49151). If no value is set or is set to 0, the default port (4789) is used.
      --default-addr-pool ipNetSlice           default address pool in CIDR format (default [])
      --default-addr-pool-mask-length uint32   default address pool subnet mask length (default 24)
      --dispatcher-heartbeat duration          Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
      --external-ca external-ca                Specifications of one or more certificate signing endpoints
      --force-new-cluster                      Force create a new cluster from current state
      --listen-addr node-addr                  Listen address (format: <ip|interface>[:port]) (default 0.0.0.0:2377)
      --max-snapshots uint                     Number of additional Raft snapshots to retain
      --snapshot-interval uint                 Number of log entries between Raft snapshots (default 10000)
      --task-history-limit int                 Task history retention limit (default 5)

Raft协议

保证大多数节点存活才可以(至少>2)

bash 复制代码
1,初始化swarm集群,生成主节点
[root@localhost ~]# docker swarm init --advertise-addr 192.168.0.250
Swarm initialized: current node (xa4tcvtx0ss80pu7zsy975xf1) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-2nz7pe5u74to8kkyqam343fa1ldkwbui5o5ang480nxcl55wvq-2o0qo4iazn44s0h4akqo00su5 192.168.0.250:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2,添加节点令牌并加入节点
# 管理节点令牌
docker swarm join-token manager
# 工作节点令牌
docker swarm join-token worker
[root@localhost ~]# docker swarm join --token SWMTKN-1-2nz7pe5u74to8kkyqam343fa1ldkwbui5o5ang480nxcl55wvq-2o0qo4iazn44s0h4akqo00su5 192.168.0.250:2377
This node joined a swarm as a worker.

3,启动两个manager节点和两个worker节点, 查看当前节点状态
[root@localhost ~]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4detbmr2ziwikj91j9x6lsbhs     localhost.localdomain   Ready               Active                                  19.03.13
7j34gp7d1xrijkwxy2nprmp89     localhost.localdomain   Ready               Active              Reachable           19.03.13
tgvu8ep05zohd6x5h7ab9n8c6     localhost.localdomain   Ready               Active                                  19.03.13
xa4tcvtx0ss80pu7zsy975xf1 *   localhost.localdomain   Ready               Active              Leader              19.03.13

4,将主节点1停止测试
[root@localhost ~]# systemctl stop docker
Warning: Stopping docker.service, but it can still be activated by:
  docker.socket

5,在给一个manager节点查看状态(剩余一个主节点, 集群不能工作)
[root@localhost ~]# docker node ls
Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded
[root@localhost ~]# docker node ls
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.

6,重新启动主节点1, 重新查看节点状态
[root@localhost ~]# systemctl start docker
[root@localhost ~]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4detbmr2ziwikj91j9x6lsbhs     localhost.localdomain   Ready               Active                                  19.03.13
7j34gp7d1xrijkwxy2nprmp89     localhost.localdomain   Ready               Active              Leader              19.03.13
tgvu8ep05zohd6x5h7ab9n8c6     localhost.localdomain   Ready               Active                                  19.03.13
xa4tcvtx0ss80pu7zsy975xf1 *   localhost.localdomain   Ready               Active 

7,把其中一个worker离开集群
[root@localhost ~]# docker swarm leave
Node left the swarm.
[root@localhost ~]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4detbmr2ziwikj91j9x6lsbhs     localhost.localdomain   Ready               Active                                  19.03.13
7j34gp7d1xrijkwxy2nprmp89     localhost.localdomain   Ready               Active              Leader              19.03.13
tgvu8ep05zohd6x5h7ab9n8c6     localhost.localdomain   Down                Active                                  19.03.13
xa4tcvtx0ss80pu7zsy975xf1 *   localhost.localdomain   Ready               Active              Reachable           19.03.13

8,重新作为manager加入集群
[root@localhost ~]# docker swarm join --token SWMTKN-1-2nz7pe5u74to8kkyqam343fa1ldkwbui5o5ang480nxcl55wvq-boj74lujjljzvyvtlprh0fqpa 192.168.0.250:2377
This node joined a swarm as a manager.
[root@localhost ~]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4detbmr2ziwikj91j9x6lsbhs     localhost.localdomain   Ready               Active                                  19.03.13
7j34gp7d1xrijkwxy2nprmp89     localhost.localdomain   Ready               Active              Leader              19.03.13
msrkboug93zfzmf1s3koxtyx0     localhost.localdomain   Ready               Active              Reachable           19.03.13
tgvu8ep05zohd6x5h7ab9n8c6     localhost.localdomain   Down                Active                                  19.03.13
xa4tcvtx0ss80pu7zsy975xf1 *   localhost.localdomain   Ready               Active              Reachable           19.03.13

9, 再次停止一个主节点, 查看状态 (剩余两个主节点, 集群正常工作)
[root@localhost ~]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
4detbmr2ziwikj91j9x6lsbhs     localhost.localdomain   Ready               Active                                  19.03.13
7j34gp7d1xrijkwxy2nprmp89 *   localhost.localdomain   Ready               Active              Leader              19.03.13
msrkboug93zfzmf1s3koxtyx0     localhost.localdomain   Ready               Active              Reachable           19.03.13
tgvu8ep05zohd6x5h7ab9n8c6     localhost.localdomain   Down                Active                                  19.03.13
xa4tcvtx0ss80pu7zsy975xf1     localhost.localdomain   Ready               Active              Unreachable         19.03.13

弹性扩缩容

单机: 启动一个项目: docker-compose up

集群: swarm, docker service(服务启动,具备扩缩容器,滚动更新)

灰度发布:金丝雀发布(滚动发布)

bash 复制代码
1,创建nginx服务
[root@localhost ~]# docker service create -p 8888:80 --name mynginx nginx
pqn9zyf0dvrrxwh8mwo66hwth
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged
2,扩容增加3个服务
[root@localhost ~]# docker service update --replicas 3 mynginx
mynginx
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 
3,打开浏览器访问其中一台机器 (集群中任意节点都可以访问服务)
4,回滚容器(减少)
[root@localhost ~]# docker service update --replicas 1 mynginx
mynginx
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 
# 查看状态
[root@localhost ~]# docker service ps mynginx
ID                  NAME                IMAGE               NODE                    DESIRED STATE       CURRENT STATE            ERROR               PORTS
tjr17l8ryj6e        mynginx.1           nginx:latest        localhost.localdomain   Running             Running 18 minutes ago  
5,scale命令扩缩容 (等于update)
[root@localhost ~]# docker service scale mynginx=5
mynginx scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   [==================================================>] 
2/5: running   [==================================================>] 
3/5: running   [==================================================>] 
4/5: running   [==================================================>] 
5/5: running   [==================================================>] 
verify: Service converged

实战

bash 复制代码
1,创建swarm集群管理节点,该节点为manager
[root@node1 ~]# docker-machine create -d virtualbox swarm-manager
2,初始化swarm集群,进行初始化这台机器,就是集群的管理节点
[root@node1 ~]# docker-machine ssh swarm-manager
[root@node1 ~]# docker swarm init --addvertise-addr 172.38.1.1
3,创建swarm集群工作节点,该节点为worker
[root@node1 ~]# docker-machine create -d virtualbox swarm-work1
[root@node1 ~]# docker-machine create -d virtualbox swarm-work2
[root@node1 ~]# docker-machine ssh worker1
docker@swarm-worker1:~$ docker swarm join --token SWMTKN-1-4oogo9qziq768dma0uh3j0z0m5twlm10iynvz7ixza96k6jh9p-ajkb6w7qd06y1e33yrgko64sk 172.38.1.2:2377
4,查看集群信息
[root@node1 ~]# docker info
5,部署服务到集群中,创建一个hello的服务在工作节点上
docker@swarm-manager:~$ docker service create --replicas 1 --name helloalpine ping docker.com
6,查看helloworld服务运行在哪个节点上
docker@swarm-manager:~$ docker service ps helloworld
7,扩展集群服务,爱你过helloworld服务扩展到两个节点
docker@swarm-manager:~$ docker service scale helloworld=2
8,删除服务
docker@swarm-manager:~$ docker service rm helloworld
9,创建一个 3.0.6 版本的 redis
docker@swarm-manager:~$ docker service create --replicas 1 --name redis --update-delay 10s redis:3.0.6
10,滚动升级 redis 
docker@swarm-manager:~$ docker service update --image redis:3.0.7 redis
相关推荐
豆芽脚脚9 分钟前
docker compose再阿里云上无法使用的问题
阿里云·docker·容器
yuxb7334 分钟前
Ansible 学习笔记:变量事实管理、任务控制与文件部署
linux·运维·笔记
鸢栀w1 小时前
前端css学习笔记7:各种居中布局&空白问题
前端·css·笔记·学习·尚硅谷网课
Hero_11271 小时前
学习Stm32 的第一天
stm32·嵌入式硬件·学习
之歆1 小时前
大模型微调分布式训练-大模型压缩训练(知识蒸馏)-大模型推理部署(分布式推理与量化部署)-大模型评估测试(OpenCompass)
人工智能·笔记·python
冷崖6 小时前
MySQL异步连接池的学习(五)
学习·mysql
知识分享小能手7 小时前
Vue3 学习教程,从入门到精通,Axios 在 Vue 3 中的使用指南(37)
前端·javascript·vue.js·学习·typescript·vue·vue3
所愿ღ8 小时前
JavaWeb-Servlet基础
笔记·servlet
岑梓铭8 小时前
考研408《计算机组成原理》复习笔记,第五章(2)——CPU指令执行过程
笔记·考研·408·计算机组成原理·计组