Docker

安装

CenterOS 7 以上,内核版本 3.10以上

各部分安装命令:

-------------------------------------
//先关闭防火墙
//关闭
systemctl stop firewalld
//禁止开机启动
systemctl disable firewalld
----------------------------
//下载必要的环境
yum -y install gcc
yum -y install gcc-c++
------------------------------
//正式下载
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
//更新一下缓存
yum makecache fast
//下载Docker
yum install docker-ce docker-ce-cli containerd.io
------------------------------
//启动Docker,没有返回就是正常启动
systemctl start docker

ps -ef|grep docker

-------------------------------
//查看版本,以及服务是否启动成功
docker version
// 测试命令,helloWorld
docker run hello-world

初级篇

一、常用命令

1、帮助启动类

image-20220909205913463

基础的启动命令,以及一些帮助文档,不做详细介绍

2、镜像命令

docker images

列出本地主机上的全部镜像

[root@master docker]# docker  images

//表头含义:
仓库         |标签版本号 |唯一镜像id    |创建时间        |大小
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB

Docker_第1张图片

docker search xxx

查询 xxx 镜像是否在远程仓库

[root@master docker]# docker search hello-world
//表头含义:
|名称                                      |描述                                           |点赞数   |官方认证   |是否是自动构建的

NAME                                       DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
hello-world                                Hello World! (an example of minimal Dockeriz…   1840      [OK]       
kitematic/hello-world-nginx                A light-weight nginx container that demonstr…   152                  
tutum/hello-world                          Image to test docker deployments. Has Apache…   89                   [OK]
dockercloud/hello-world                    Hello World!                                    19                   [OK]
crccheck/hello-world                       Hello World web server in under 2.5 MB          15                   [OK]
vad1mo/hello-world-rest                    A simple REST Service that echoes back all t…   5                    [OK]
rancher/hello-world                                                                        4                    
ppc64le/hello-world                        Hello World! (an example of minimal Dockeriz…   2                    [OK]
armswdev/c-hello-world                     Simple hello-world C program on Alpine Linux…   0                    
                                                           0                    
tacc/hello-world                                                                           0                    
garystafford/hello-world                   Simple hello-world Spring Boot service for t…   0                    [OK]
                                                      0                    
okteto/hello-world                                                                         0                    
strimzi/hello-world-consumer     

docker pull xxx :TAG

从远程仓库拉取 xxx 镜像,可以指定版本号进行拉取,如果不指定,就拉取最新版本

---------------------------------------------------------------------------
[root@master docker]# docker pull ubuntu

Using default tag: latest
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete 
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

---------------------------------------------------------------------------
[root@master docker]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        latest    ba6acccedd29   10 months ago   72.8MB
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB


docker system df

查看 镜像/容器/数据卷 所占的空间

[root@master docker]# docker system df
//表头含义
|类型           |总数     |活动中的  |大小     |可伸缩性 

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          2         1         72.79MB   72.78MB (99%)
Containers      2         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B


[root@master docker]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        latest    ba6acccedd29   10 months ago   72.8MB
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB

docker rmi xxx

删除 xxx 镜像, 使用镜像名称或者镜像id都可以

docker rmi xxx 可能会报错提示有进程正在使用不允许删除,替换成 docker rim -f xxx 即可正常删除

[root@master docker]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
ubuntu        latest    ba6acccedd29   10 months ago   72.8MB
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB


[root@master docker]# docker rmi ubuntu
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Deleted: sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1
Deleted: sha256:9f54eef412758095c8079ac465d494a2872e02e90bf1fb5f12a1641c0d1bb78b

[root@master docker]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB


拓展

Docker_第2张图片

扩展:什么是 虚悬镜像?

仓库名、标签都是 none 的镜像,不知道是做什么用的,但是确实占用空间

这种镜像建议删除

Docker_第3张图片

3、容器命令

有镜像才能创建容器,成功下载镜像是创建容器的大前提;

镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。

① docker run -it XXX

以交互模式创建并启动一个容器实例

参数:

-it 以交互模式启动

–name 指定容器的名称

-d 以后台进程的模式启动容器并返回容器id,也就是启动守护式容器(后台运行)

-P 随机端口映射 ,大写P

-p 指定端口映射 ,小写p

Docker_第4张图片

exit 退出终端也就是停止了容器的运行

crtl + p +q 退出终端但是不停止容器的运行

② docker ps

列出当前所有正在运行中的容器实例

参数:

-a 列出当前所有正在运行的容器 + 历史运行过的容器

-l 显示最近创建的容器

-n 显示最近n个创建的容器

-q 静默模式,只显示当前所有正在运行的容器编号

[root@master /]# docker ps
//表头含义
|容器id       |镜像名称   |命令        |创建时间        |状态          |对外暴漏端口 |容器名称,未自定义就随机

CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
b00ad6e687cd   ubuntu    "/bin/bash"   5 minutes ago   Up 5 minutes             amazing_ritchie

[root@master /]# docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                  PORTS     NAMES
b00ad6e687cd   ubuntu        "/bin/bash"   16 minutes ago   Up 16 minutes                     amazing_ritchie
8d665b1966dc   hello-world   "/hello"      5 days ago       Exited (0) 5 days ago             infallible_stonebraker
5883d1e27338   hello-world   "/hello"      5 days ago       Exited (0) 5 days ago             reverent_blackburn

[root@master /]# docker ps -l
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
b00ad6e687cd   ubuntu    "/bin/bash"   17 minutes ago   Up 17 minutes             amazing_ritchie

[root@master /]# docker ps -n 2
CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                  PORTS     NAMES
b00ad6e687cd   ubuntu        "/bin/bash"   21 minutes ago   Up 21 minutes                     amazing_ritchie
8d665b1966dc   hello-world   "/hello"      5 days ago       Exited (0) 5 days ago             infallible_stonebraker

[root@master /]# docker ps -q
b00ad6e687cd


③ docker start 容器id/容器名称

启动已经停止的容器

[root@master ~]# docker ps -a    //查看历史容器
CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                     PORTS     NAMES
b00ad6e687cd   ubuntu        "/bin/bash"   30 minutes ago   Exited (0) 7 minutes ago             amazing_ritchie
8d665b1966dc   hello-world   "/hello"      5 days ago       Exited (0) 5 days ago                infallible_stonebraker
5883d1e27338   hello-world   "/hello"      5 days ago       Exited (0) 5 days ago                reverent_blackburn
[root@master ~]# docker ps       //检查是否有运行的
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@master ~]# docker start b00ad6e687cd   //根据容器id,启动已经停止的容器
b00ad6e687cd
[root@master ~]# docker ps    //检查是否有运行的
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
b00ad6e687cd   ubuntu    "/bin/bash"   30 minutes ago   Up 4 seconds             amazing_ritchie

④ docker restart 容器id/容器名称

重启容器

⑤ docker stop 容器id/容器名

停止容器的运行

⑥ docker kill 容器id/容器名

强制停止容器

⑦ docker rm 容器id/容器名

删除已经停止运行的容器

未停止的容器无法删除 需要增加参数 -f docker rm -f 不管是否运行,强制删除

[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
b00ad6e687cd   ubuntu    "/bin/bash"   30 minutes ago   Up 4 seconds             amazing_ritchie

[root@master ~]# docker rm b00ad6e687cd //尝试删除未停止的容器
Error response from daemon: You cannot remove a running container b00ad6e687cda5623cd17dd763a6a8ae3617954c11d7601d718192165813c6dc. Stop the container before attempting removal or force remove

[root@master ~]# docker stop b00ad6e687cd   //停止该容器的运行
b00ad6e687cd
[root@master ~]# docker rm b00ad6e687cd    //再次删除
b00ad6e687cd
[root@master ~]# docker ps   //删除成功
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES


容器删除后,就不再存在了,无法再次通过 docker start 容器id/容器名 来启动,需要再次创建并启动容器 docker run XXX 才行

4.重点命令操作

1.后台运行容器 docker run -d 镜像名

大多数场景下,我们都希望docker的服务是在后台运行的,我们可以通过 -d 指定容器的后台运行模式

**注意:**有些容器是不能以后台模式启动的,比如web容器、系统级容器

Docker_第5张图片

因此,我们选用能够后台运行的容器来进行测试,这里用redis来举例

a.前台交互模式运行
[root@master ~]# docker run -it redis   //以前台交互模式启动redis
1:C 14 Sep 2022 13:47:25.853 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 14 Sep 2022 13:47:25.853 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 14 Sep 2022 13:47:25.853 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 14 Sep 2022 13:47:25.853 * monotonic clock: POSIX clock_gettime
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 6.2.6 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                  
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 1
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           https://redis.io       
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

1:M 14 Sep 2022 13:47:25.854 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 14 Sep 2022 13:47:25.854 # Server initialized
1:M 14 Sep 2022 13:47:25.854 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 14 Sep 2022 13:47:25.854 * Ready to accept connections

这种模式下,如果输入任何错误命令,比如无意义的 ctrl+c 就会关闭这个容器

b.后台进行模式运行
[root@master ~]# docker run -d --name=redis redis   //以后台进行模式启动,取名为 redis
6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710
[root@master ~]# docker ps                          //检查状态
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS      NAMES
6e7a1aa6ed74   redis     "docker-entrypoint.s…"   4 seconds ago   Up 4 seconds   6379/tcp   redis

这种模式,相当于后台运行,不会被错误命令给停止了

2.查看容器的运行日志

docker logs 容器id/容器名

[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS      NAMES
6e7a1aa6ed74   redis     "docker-entrypoint.s…"   4 seconds ago   Up 4 seconds   6379/tcp   redis

[root@master ~]# docker logs 6e7a1aa6ed74     //根据容器id,查看容器运行日志
1:C 14 Sep 2022 13:51:45.590 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 14 Sep 2022 13:51:45.590 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 14 Sep 2022 13:51:45.590 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 14 Sep 2022 13:51:45.591 * monotonic clock: POSIX clock_gettime
1:M 14 Sep 2022 13:51:45.592 * Running mode=standalone, port=6379.
1:M 14 Sep 2022 13:51:45.592 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 14 Sep 2022 13:51:45.592 # Server initialized
1:M 14 Sep 2022 13:51:45.592 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:M 14 Sep 2022 13:51:45.592 * Ready to accept connections

后面会学习容器化日志可视化软件 Portainer,这里先做了解;

3.查看容器内的进程

docker top 容器id/容器名

[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS      NAMES
6e7a1aa6ed74   redis     "docker-entrypoint.s…"   14 minutes ago   Up 14 minutes   6379/tcp   redis

[root@master ~]# docker top 6e7a1aa6ed74        //查看redis中的进行
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
polkitd             2913                2894                0                   21:51               ?                   00:00:01            redis-server *:6379

4.查看容器内部细节

docker inspect 容器id

因为每个容器都相当于一个微小的linux内核,因此它内部有很多细节可供查看

[root@master ~]# docker inspect 6e7a1aa6ed74
[
    {
        "Id": "6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710",
        "Created": "2022-09-14T13:51:45.244026708Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "redis-server"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 2913,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-09-14T13:51:45.579736569Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:7614ae9453d1d87e740a2056257a6de7135c84037c367e1fffa92ae922784631",
        "ResolvConfPath": "/var/lib/docker/containers/6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710/hostname",
        "HostsPath": "/var/lib/docker/containers/6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710/hosts",
        "LogPath": "/var/lib/docker/containers/6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710/6e7a1aa6ed74224859c7a2c235fb6452a5fe19e22cfd5180957807b1c53b9710-json.log",
        "Name": "/redis",
        "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/bc440a30a4f173fab3ab718dbdacc1e78341ff9c39254e06172a80a3a8667f63-init/diff:/var/lib/docker/overlay2/b35a5d9a97281838583753ec5be30cbfdab2880a93b3c6cdc210f5e9d8d20747/diff:/var/lib/docker/overlay2/1370d3c5691e6bb35222ec6963ecf03cef060dca7840d296b694749fded03263/diff:/var/lib/docker/overlay2/8832362c568516bde142242f2285b8753f9de0a554abbae5d1cc487048a4bc97/diff:/var/lib/docker/overlay2/f4296cf92df3d8de24ea3c323254ea10ccaff21f42dedc5603122156a6cb3683/diff:/var/lib/docker/overlay2/d3aa144c0377c27592ae9f2724e35c93554c56780d976f011c2ab95ee5f40f40/diff:/var/lib/docker/overlay2/d085e690e68cb33a7be887dadf82ef5702c181769c76303036d9855e55d732e2/diff",
                "MergedDir": "/var/lib/docker/overlay2/bc440a30a4f173fab3ab718dbdacc1e78341ff9c39254e06172a80a3a8667f63/merged",
                "UpperDir": "/var/lib/docker/overlay2/bc440a30a4f173fab3ab718dbdacc1e78341ff9c39254e06172a80a3a8667f63/diff",
                "WorkDir": "/var/lib/docker/overlay2/bc440a30a4f173fab3ab718dbdacc1e78341ff9c39254e06172a80a3a8667f63/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "6cc58bd44bde866ae1bbb72a93d9250bb3d9ebfba4027e6cb5c4ab37aa3a42f6",
                "Source": "/var/lib/docker/volumes/6cc58bd44bde866ae1bbb72a93d9250bb3d9ebfba4027e6cb5c4ab37aa3a42f6/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "6e7a1aa6ed74",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "6379/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.12",
                "REDIS_VERSION=6.2.6",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.2.6.tar.gz",
                "REDIS_DOWNLOAD_SHA=5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab"
            ],
            "Cmd": [
                "redis-server"
            ],
            "Image": "redis",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "ac698e718f239c3ffe31e3a7721ed2c40aafb993cd703e8172bdfb3bfefdda76",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "6379/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/ac698e718f23",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "91a38bc7bb5a3b1744ecf0969ea81fea8b9de9d2af01650c829afe1328d30044",
            "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": "a1afba55ca7d118eccecf18231c3da6a7e75a48c137a24fd3ec199469423caae",
                    "EndpointID": "91a38bc7bb5a3b1744ecf0969ea81fea8b9de9d2af01650c829afe1328d30044",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

内部细节涉及很多,这里先做了解,后面再详细学习

5.进入正在运行的容器以进行命令行交互

有两个命令可以进入命令行交互

docker exec -it 容器id /bin/bash

docker attach 容器id

两个命令的区别:

Docker_第6张图片

工作中推荐使用 exec 因为直接 exit 退出不会影响容器运行

[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS      NAMES
6e7a1aa6ed74   redis     "docker-entrypoint.s…"   32 minutes ago   Up 32 minutes   6379/tcp   redis

[root@master ~]# docker exec -it 6e7a1aa6ed74 /bin/bash    //进入正在运行的redis  进行命令行交互
root@6e7a1aa6ed74:/data# redis-cli -p 6379  //测试连接
127.0.0.1:6379> ping
PONG

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

将容器内的文件,复制拷贝到宿主机上

docker cp 容器id:容器内路径 目的主机路径

Docker_第7张图片

7.导入和导出容器

导出: export 导出容器的内容流作为一个tar归档文件 【对应import命令】

​ docker export 容器id > 文件名.tar

导出: import 从tar包中的内容创建一个新的文件系统再导入为镜像【对应export】

​ cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

//导出
[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED             STATUS             PORTS      NAMES
6e7a1aa6ed74   redis     "docker-entrypoint.s…"   About an hour ago   Up About an hour   6379/tcp   redis

[root@master ~]# docker export 6e7a1aa6ed74 > abc.tar  导出到当前目录下,生成 abc.tar 文件

如图,确实生成了

Docker_第8张图片

//导入
[root@master ~]# docker rm -f 6e7a1aa6ed74     //强制删除掉刚才导出的容器
6e7a1aa6ed74
[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@master ~]# cat abc.tar | docker import - mypack/redis:1.1   //导入tar包,创建成镜像  镜像用户+镜像名+版本号,都是自己自定义的,无特殊意义
sha256:4e342e735102b9f203fc68bcfc9cf793ecffbfcbcfc82976cbe73679404aeb7c

[root@master ~]# docker images                  //检查全部镜像,发现多了一个刚才导入的镜像
REPOSITORY     TAG       IMAGE ID       CREATED              SIZE
mypack/redis   1.1       4e342e735102   About a minute ago   109MB
redis          latest    7614ae9453d1   8 months ago         113MB
ubuntu         latest    ba6acccedd29   11 months ago        72.8MB
hello-world    latest    feb5d9fea6a5   11 months ago        13.3kB


导出相当于一种制作镜像的方法,将镜像启动成容器,与原本的容器完全一致

二、Docker 镜像讲解

1.定义

Docker_第9张图片

可以发现,在远程仓库拉取镜像时,是一个文件一个文件的分步拉取,其实这每个“文件”,就是一层;也就是说,镜像其实是由不同的层组成的

Docker_第10张图片

分层下载

2.镜像的分层组成

镜像的分层,其实是 UnionFS (联合文件系统) 的体现

UnionFS 联合文件系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSnpsnzU-1666522669132)(https://gitee.com/chenchong123456/picture/raw/master/typora/Docker/image-20220918095752026.png)]

镜像加载原理

Docker 镜像由一层一层的文件系统组成,也就是联合文件系统UnionFS;

因为每个镜像容器其实就是一个微小的linux系统,应用程序运行在这个微小的系统上,这个微小的系统包含两个部分,bootfs与rootfs

  • 先加载linux内核

**bootfs:**主要包含boot加载器(bootloader)和内核(kernel),boot加载器主要是为了引导加载内核,docker镜像刚启动时,会加载整个引导文件系统 bootfs,

boot加载器开始引导,加载引导完成后,内核就存在与内存中了,这时内存的使用权交到内核,并且系统会卸载bootfs引导文件系统,到此,Linux内核加载完成

  • 然后发行版操作系统

**rootfs:**rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等,rootfs记载完成,则整个微小版的Linux操作系统就创建完成,等待容器的应用程序记载

Docker_第11张图片

到这里,都被称为 镜像层;

启动后,应用程序被称为 容器层,容器层是可写的,镜像层只可读

Docker_第12张图片

3.commit 提交自己的镜像

docker commit -m=“提交的描述信息” -a=“作者” 容器id 要创建的目标镜像名:【标签名】

# 一、 进入ubuntu系统,检查,确定不存在 vim编辑器
[root@master ~]# docker run -it ubuntu /bin/bash   
root@8d2d878ae434:/# vim a.txt
bash: vim: command not found

#二、安装vim
#更新包管理工具
root@8d2d878ae434:/# apt-get update
#安装vim
root@8d2d878ae434:/# apt-get -y install vim

# 系统中已经存在vim编辑器了
root@8d2d878ae434:/# vim a.txt
root@8d2d878ae434:/# 
root@8d2d878ae434:/# cat a.txt
this is docker
root@8d2d878ae434:/# 

#三、commit 提交为我们自己的新镜像 
# 1.先检查存在那些镜像,运行了那些容器实例
[root@master /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
8d2d878ae434   ubuntu    "/bin/bash"   8 minutes ago   Up 8 minutes             xenodochial_leavitt
[root@master /]# docker images
REPOSITORY     TAG       IMAGE ID       CREATED         SIZE
mypack/redis   1.1       4e342e735102   3 days ago      109MB
tomcat         latest    fb5657adc892   8 months ago    680MB
redis          latest    7614ae9453d1   9 months ago    113MB
ubuntu         latest    ba6acccedd29   11 months ago   72.8MB
hello-world    latest    feb5d9fea6a5   11 months ago   13.3kB
# 提交镜像  容器id为想要提交的容器id 后面是要创建的镜像名
[root@master /]# docker commit -m="add vim ok" -a="chenchong" 8d2d878ae434 mypack/myubuntu:1.2
sha256:4bf46269abe8f605f0cf5e73e52291e1863149ef6b20f66665369f55ad3f4e70 #创建成功

#可以看到,新镜像已经提交生成了
[root@master /]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED              SIZE
mypack/myubuntu   1.2       4bf46269abe8   About a minute ago   179MB
mypack/redis      1.1       4e342e735102   3 days ago           109MB
tomcat            latest    fb5657adc892   8 months ago         680MB
redis             latest    7614ae9453d1   9 months ago         113MB
ubuntu            latest    ba6acccedd29   11 months ago        72.8MB
hello-world       latest    feb5d9fea6a5   11 months ago        13.3kB

#四、启动新的镜像,发现已经内置了vim 编辑器
[root@master /]# docker run -it mypack/myubuntu:1.2 /bin/bash
root@d60c686200d6:/# vim a.txt

可看见,新的镜像的文件大小变大了,这是因为我们引入了新的功能 vim,这就相当于给容器层新增加了一层,也就是说,新的ubuntu与旧的ubuntu其实底层都是一样的,只不过新的推加了一层vim,这也就是文件联合分层系统的优点所在

Docker_第13张图片

小总结

Docker_第14张图片

4.镜像发布到阿里云

上面的提交镜像,是把自己添加好功能的容器,交给docker来生成镜像,而如果想要让别人也能够拉取这个镜像,需要将其发布到云,这里用阿里云来介绍:

Docker_第15张图片

进入镜像仓库

Docker_第16张图片

先创建命名空间

Docker_第17张图片

在命名空间下创建仓库

Docker_第18张图片

点击 管理 即可获取到自动生成的阿里云仓库 拉取、发布等一系列命令语句

Docker_第19张图片

设置密码

Docker_第20张图片

到这里,阿里镜像仓库算是创建完成了,接下来,开始向仓库发布上传镜像

上传镜像到仓库

docker login --username=努力的陈皮 registry.cn-hangzhou.aliyuncs.com

docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:[镜像版本号]

docker push registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:[镜像版本号]

# 检查镜像
[root@master ~]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
mypack/myubuntu   1.2       4bf46269abe8   4 hours ago     179MB
mypack/redis      1.1       4e342e735102   3 days ago      109MB
tomcat            latest    fb5657adc892   8 months ago    680MB
redis             latest    7614ae9453d1   9 months ago    113MB
ubuntu            latest    ba6acccedd29   11 months ago   72.8MB
hello-world       latest    feb5d9fea6a5   11 months ago   13.3kB

#先登录到仓库,这里的密码是刚刚设置的仓库密码
[root@master ~]# docker login --username=努力的陈皮 registry.cn-hangzhou.aliyuncs.com
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 开始上传发布,分两步,都直接粘贴生成的命令即可,记得替换镜像id+版本号
[root@master ~]# docker tag 4bf46269abe8 registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:1.2
[root@master ~]# docker push registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:1.2
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker]
0b3b5401d7e3: Pushed 
9f54eef41275: Pushed 
1.2: digest: sha256:507b357761bf83e46d3076b2dcb3067d7e14368b4b24b59c0bf3630c7357d028 size: 741

#上传成功

在阿里云控制台即可看到

Docker_第21张图片

从仓库拉取下来

docker pull registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:[镜像版本号]

# 检查本地 全部镜像
[root@master ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
tomcat       latest    fb5657adc892   8 months ago    680MB
redis        latest    7614ae9453d1   9 months ago    113MB
ubuntu       latest    ba6acccedd29   11 months ago   72.8MB

#拉取镜像
[root@master ~]# docker pull registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:1.2
1.2: Pulling from docker_chenchong/mydocker
7b1a6ab2e44d: Already exists 
4e1f464b9aab: Already exists 
Digest: sha256:507b357761bf83e46d3076b2dcb3067d7e14368b4b24b59c0bf3630c7357d028
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:1.2
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker:1.2

#再次检查,发现已经有了
[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   4 hours ago     179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB
redis                                                         latest    7614ae9453d1   9 months ago    113MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

#启动起来,同样拥有 新加上的 vim编辑器

至此,创建阿里云仓库、上传、拉取都已完成

5.发布镜像到私服仓库

在本地创建私服

① 将私服的镜像拉取到本地

# 本地私服,也需要将私服的镜像拉取下来再启动
[root@master ~]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
79e9f2f55bf5: Pull complete 
0d96da54f60b: Pull complete 
5b27040df4a2: Pull complete 
e2ead8259a04: Pull complete 
3790aef225b9: Pull complete 
Digest: sha256:169211e20e2f2d5d115674681eb79d21a217b296b43374b8e39f97fcf866b375
Status: Downloaded newer image for registry:latest
docker.io/library/registry:latest
[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   4 hours ago     179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB
redis                                                         latest    7614ae9453d1   9 months ago    113MB
registry                                                      latest    b8604a3fe854   10 months ago   26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

② 运行私有库 registry,相当于本地有个私有的镜像仓库

image-20220918153239410

-v 后面的参数解释

冒号前面的是该文件存在于宿主机上面的位置,冒号后面的是在容器里面的位置

image-20220918171722133

③ 发送请求,验证私服库是否畅通

Docker_第22张图片

④ 将镜像修改为符合规范的 TAG

Docker_第23张图片

⑤ 上传

Docker_第24张图片

再次验证,就发现私服已经有镜像了

Docker_第25张图片

⑥ 拉取镜像到本地

Docker_第26张图片

6.容器数据卷

开启容器卷,需要在语句中加一个参数: –privileged=true

Docker_第27张图片

作用,映射目录后,完成重要数据的持久化备份功能,实时备份

命令: docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名

Docker_第28张图片

image-20220918172238810

Docker_第29张图片

运行一个带数据卷的容器

[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 查看全部镜像
[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   7 hours ago     179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB
redis                                                         latest    7614ae9453d1   9 months ago    113MB
registry                                                      latest    b8604a3fe854   10 months ago   26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

# 以数据卷挂载的方式启动容器
[root@master ~]# docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data  ubuntu

#进入挂载的容器内的该文件夹,并创建一个 dockerin.txt 的文件
root@7ddc9a79c5a9:/# cd /tmp/docker_data
root@7ddc9a79c5a9:/tmp/docker_data# ls
root@7ddc9a79c5a9:/tmp/docker_data# touch dockerin.txt
root@7ddc9a79c5a9:/tmp/docker_data# ls
dockerin.txt



可以看到,宿主机立马就有了备份

Docker_第30张图片

接着,在宿主机上,创建一个文件 hostin.txt

Docker_第31张图片

root@7ddc9a79c5a9:/tmp/docker_data# touch dockerin.txt
root@7ddc9a79c5a9:/tmp/docker_data# ls
dockerin.txt

# docker 容器中也立马有了这个文件
root@7ddc9a79c5a9:/tmp/docker_data# ls
dockerin.txt  hostin.txt
root@7ddc9a79c5a9:/tmp/docker_data# ^C

至此,挂载绑定成功

tips:如何查看挂载的信息呢?

一.4.4 节谈到过,查看容器内部细节的命令 docker inspect 容器id

      ## Mounts 该项就是挂载的详细信息
      "Mounts": [
            {
                "Type": "bind",
                "Source": "/tmp/host_data",  # 宿主机
                "Destination": "/tmp/docker_data", # 容器内
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

小总结

1.docker 修改,宿主机同步获得

2.宿主机修改,docker也会同步获得

3.docker容器停掉 stop,主机修改,docker容器重启后依旧能够同步最新数据

修改读写规则

上述挂载,可以互相通讯,这是因为,挂载默认的读写规则就是 支持 互相读写

也就是完整的命令语句是: docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名

有个 rw 参数,表明支持读和写

如果想要限制容器内,让他只能读,不能写,就把参数改为 ro 即可

docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

Docker_第32张图片

容器之间,卷的继承

image-20220918182717261

继承的前提,是已经有一个容器,他已经启动并配置好了映射挂载规则,新的容器想要完整的复刻该容器的挂载规则,则可以使用继承

按照以上命令,挂载启动后,就相当于该容器已经跟父容器之间挂载规则完全一致,也可以理解为共享宿主挂载规则,文件共享

tips:该命令只是方便的以父容器的挂载规则来启动容器,启动完成后就跟父容器没有关系了,也就是说父容器就算停掉,子容器挂载规则不受影响;

三、Docker上常用软件的安装

1.安装软件的总体步骤概述

Docker_第33张图片

2.安装常用软件

Tomcat

# 拉取到本地镜像
[root@master ~]#  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@master ~]# docker images 
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   8 hours ago     179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB #成功拉取
redis                                                         latest    7614ae9453d1   9 months ago    113MB
registry                                                      latest    b8604a3fe854   10 months ago   26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

然后是使用镜像创建容器实例(也叫启动运行镜像)

Docker_第34张图片

[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   8 hours ago     179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB
redis                                                         latest    7614ae9453d1   9 months ago    113MB
registry                                                      latest    b8604a3fe854   10 months ago   26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

# 映射本地宿主机端口 8080 
[root@master ~]# docker run -d -p 8080:8080 --name=tom1 tomcat
9099302dc01a15061d5b6c5810442e819d153b50234349f46e2432490ddbf87e

# 检查成功启动
[root@master ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
9099302dc01a   tomcat    "catalina.sh run"   5 seconds ago   Up 4 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   tom1

检查是否能够访问首页: 宿主机ip:8080 能够出现首页即为访问成功

Docker_第35张图片

原因是新版需要修改一些配置,首先,进入tomcat容器交互命令

# 进入交互行
[root@master ~]# docker exec -it 9099302dc01a /bin/bash

#可以看出,交互行是在tomcat的根目录下的
root@9099302dc01a:/usr/local/tomcat# pwd
/usr/local/tomcat
#检查根目录都有那些文件
root@9099302dc01a:/usr/local/tomcat# ls -l
total 132
-rw-r--r--. 1 root root 18994 Dec  2  2021 BUILDING.txt
-rw-r--r--. 1 root root  6210 Dec  2  2021 CONTRIBUTING.md
-rw-r--r--. 1 root root 60269 Dec  2  2021 LICENSE
-rw-r--r--. 1 root root  2333 Dec  2  2021 NOTICE
-rw-r--r--. 1 root root  3378 Dec  2  2021 README.md
-rw-r--r--. 1 root root  6905 Dec  2  2021 RELEASE-NOTES
-rw-r--r--. 1 root root 16517 Dec  2  2021 RUNNING.txt
drwxr-xr-x. 2 root root  4096 Dec 22  2021 bin
drwxr-xr-x. 1 root root    22 Sep 18 10:52 conf
drwxr-xr-x. 2 root root  4096 Dec 22  2021 lib
drwxrwxrwx. 1 root root    80 Sep 18 10:52 logs
drwxr-xr-x. 2 root root   159 Dec 22  2021 native-jni-lib
drwxrwxrwx. 2 root root    30 Dec 22  2021 temp
drwxr-xr-x. 2 root root     6 Dec 22  2021 webapps
drwxr-xr-x. 7 root root    81 Dec  2  2021 webapps.dist
drwxrwxrwx. 2 root root     6 Dec  2  2021 work


需要将webapps文件夹删除,并将webapps.dist文件夹改名为 webapps

root@9099302dc01a:/usr/local/tomcat# rm -r webapps
root@9099302dc01a:/usr/local/tomcat# mv webapps.dist webapps
root@9099302dc01a:/usr/local/tomcat# ls -l
total 132
-rw-r--r--. 1 root root 18994 Dec  2  2021 BUILDING.txt
-rw-r--r--. 1 root root  6210 Dec  2  2021 CONTRIBUTING.md
-rw-r--r--. 1 root root 60269 Dec  2  2021 LICENSE
-rw-r--r--. 1 root root  2333 Dec  2  2021 NOTICE
-rw-r--r--. 1 root root  3378 Dec  2  2021 README.md
-rw-r--r--. 1 root root  6905 Dec  2  2021 RELEASE-NOTES
-rw-r--r--. 1 root root 16517 Dec  2  2021 RUNNING.txt
drwxr-xr-x. 2 root root  4096 Dec 22  2021 bin
drwxr-xr-x. 1 root root    22 Sep 18 10:52 conf
drwxr-xr-x. 2 root root  4096 Dec 22  2021 lib
drwxrwxrwx. 1 root root    80 Sep 18 10:52 logs
drwxr-xr-x. 2 root root   159 Dec 22  2021 native-jni-lib
drwxrwxrwx. 2 root root    30 Dec 22  2021 temp
drwxr-xr-x. 7 root root    81 Dec  2  2021 webapps # 已成功改名
drwxrwxrwx. 2 root root     6 Dec  2  2021 work

这样即可正常访问

Docker_第36张图片

tips:或者拉取这个版本的tomcat,就不用上述的修改

image-20220918213204874

MySql

# 检查本地镜像
[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   11 hours ago    179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB
redis                                                         latest    7614ae9453d1   9 months ago    113MB
mysql                                                         5.7       c20987f18b13   9 months ago    448MB
registry                                                      latest    b8604a3fe854   10 months ago   26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

#启动镜像  -e 指定环境  MYSQL_ROOT_PASSWORD=root 设置密码
[root@master ~]# docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
e113906fc741e24c65571ae26a66408c93363ea734d595d36b6ff53603652d2c

#检查是否正常启动
[root@master ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
e113906fc741   mysql:5.7   "docker-entrypoint.s…"   4 seconds ago   Up 4 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   beautiful_lamport  #正常启动


进入命令行操作

# 进入命令行
[root@master ~]# docker exec -it e113906fc741 /bin/bash
root@e113906fc741:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  #  正常进入

mysql> create database db01;  # 创建数据库
Query OK, 1 row affected (0.00 sec)

mysql> use db01; #使用数据库
Database changed

mysql> create table t1(id int,name varchar(20));# 创建表
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(1,'chenchong'); # 插入数据
Query OK, 1 row affected (0.01 sec)

mysql> select * from t1; # 查询
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | chenchong |
+------+-----------+
1 row in set (0.00 sec)


使用可视化工具也一样可以连接上

Docker_第37张图片

这种虽然起来了服务,但是有两个问题:

① docker mysql数据库默认字符编码的问题,不能插入中文

Docker_第38张图片

Docker_第39张图片

② 容器没有挂载容器卷,停止后就会数据消失

如何解决?

第一步:使用如下的语句启动MySQL服务

docker run -d -p 3306:3306 --privileged=true
#开始挂载,多个挂载
-v /usr/mysql/log:/var/log/mysql   # 日志
-v /usr/mysql/data:/var/lib/mysql  #数据
-v /usr/mysql/conf:/etc/mysql/conf.d  #配置

-e MYSQL_ROOT_PASSWORD=root #密码
--name mysql  mysql:5.7

[root@master ~]# docker run -d -p 3306:3306 --privileged=true -v /usr/mysql/log:/var/log/mysql -v /usr/mysql/data:/var/lib/mysql -v /usr/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --name mysql  mysql:5.7
cc34c635dc81323a25cc38e236a2f783a48080b8a441fe333a4f8cd9031c4936

#检查是否启动成功
[root@master ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
cc34c635dc81   mysql:5.7   "docker-entrypoint.s…"   4 seconds ago   Up 3 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql

第二步:/usr/mysql/conf 目录下,新建配置文件my.cnf,解决中文乱码问题

my.cnf 文件内容:

[client]
default_character_set=utf-8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8

重启容器才生效

#检查配置文件内容
[root@master conf]# cat my.cnf
[client]
default_character_set=utf-8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8[root@master conf]# 

#重启mysql容器
[root@master conf]# docker restart mysql
mysql

#检查是否启动成功
[root@master conf]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
cc34c635dc81   mysql:5.7   "docker-entrypoint.s…"   7 minutes ago   Up 3 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql

已经可以插入中文字符了

Docker_第40张图片

问题①解决

image-20220918222739593

接着我们查看容器卷挂载到宿主机的文件夹啊

Docker_第41张图片

Docker_第42张图片

可以看到,宿主机文件夹都有备份的数据,接下来,我们删除容器,并再次启动


[root@master conf]# docker rm -f mysql
mysql

[root@master conf]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

#再次启动
。。。
[root@master conf]# docker run -d -p 3306:3306 --privileged=true -v /usr/mysql/log:/var/log/mysql -v /usr/mysql/data:/var/lib/mysql -v /usr/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --name mysql  mysql:5.7
e005746486607605ee2793eb02567afd4a977f6ee6b89cc8976aa7946860917f
[root@master conf]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
e00574648660   mysql:5.7   "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql

接着查看数据是否还存在

[root@master conf]# docker exec -it mysql /bin/bash
root@e00574648660:/# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> use db01;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from t1;
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | chenchong |
|    1 | 陈冲      |
+------+-----------+
2 rows in set (0.00 sec)

mysql> 

数据都还在,问题②解决;

Redis

#检查镜像
[root@master conf]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   12 hours ago    179MB
tomcat                                                        latest    fb5657adc892   8 months ago    680MB
redis                                                         latest    7614ae9453d1   9 months ago    113MB
mysql                                                         5.7       c20987f18b13   9 months ago    448MB
registry                                                      latest    b8604a3fe854   10 months ago   26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago   72.8MB

#启动redis
[root@master conf]# docker run -d -p 6379:6379 redis
c3a1f178efb0571a17fa2895c5782df0205da1ace6fc1b380cfe84e12bf51cc0

#检查正常启动
[root@master conf]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                       NAMES
c3a1f178efb0   redis     "docker-entrypoint.s…"   25 seconds ago   Up 23 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   silly_matsumoto

#进入命令行
[root@master conf]# docker exec -it c3a1f178efb0 /bin/bash
root@c3a1f178efb0:/data# redis-cli
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"


这样的还是不满足实战,因此需要做一些修改

① 挂载目录下新增 自己的 redis.conf 文件(可以从别的redis处复制)

②修改内容

Docker_第43张图片

image-20220918224801003

然后再用挂载的方式启动

docker run  -p 6379:6379 --name=myredis  --privileged=true
#开始挂载,多个挂载
-v /usr/redis/redis.conf:/etc/redis/redis.conf   # 配置
-v /usr/redis/data:/data  #数据

-d redis:6.0.8 redis-server /etc/redis/redis.conf  #指定启动时读取那个配置文件

至此,完成了数据挂载,配置文件修改

高级篇

一、MySQL主从复制搭建

1.启动主数据库

## 启动主数据库
[root@master ~]# docker run -d -p 3307:3306 --privileged=true -v /usr/mysql-master/log:/var/log/mysql -v /usr/mysql-master/data:/var/lib/mysql -v /usr/mysql-master/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql-master  mysql:5.7
e21b214ecc5475fd7510c72fc9be7212faace3c35d3349292c43eb6b75cafd5f
[root@master ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
e21b214ecc54   mysql:5.7   "docker-entrypoint.s…"   3 seconds ago   Up 3 seconds   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master

2.创建配置文件

创建配置文件 进入 /usr/mysql-master/conf 文件夹创建文件 my.cnf

[mysqld]
## 设置server_id  同一局域网中需要唯一
server_id=101
##指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size-1M
## 设置使用的二进制日志格式 (mixed,statement,row)
binlog_format=mixed
## 二进制日志过去清理时间,默认值为0:表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的全部错误或者指定类型的错误,避免slave端复制中断
## 如,1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

3.重启docker,生效

[root@master ~]# docker restart mysql-master
mysql-master
[root@master ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS         PORTS                                                  NAMES
e21b214ecc54   mysql:5.7   "docker-entrypoint.s…"   11 minutes ago   Up 3 seconds   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master

4.进入命令行

[root@master ~]# docker exec -it mysql-master /bin/bash
root@e21b214ecc54:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

## 成功进入命令行
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

5.设置从机授权用户

## 创建一个从机用户,并开启权限
create USER 'salve'@'%'IDENTIFIED BY '123456';

GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'salve'@'%';

-----主机设置完成-----

6.启动从数据库

## 启动从数据库
[root@master ~]# docker run -d -p 3308:3306 --privileged=true -v /usr/mysql-salve/log:/var/log/mysql -v /usr/mysql-salve/data:/var/lib/mysql -v /usr/mysql-salve/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql-salve  mysql:5.7
df014e4888ee23d63faf179afbce4d85da4de5857f51c149db13c8afb013df10
[root@master ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
df014e4888ee   mysql:5.7   "docker-entrypoint.s…"   3 seconds ago    Up 2 seconds    33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp   mysql-salve
e21b214ecc54   mysql:5.7   "docker-entrypoint.s…"   24 minutes ago   Up 13 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master

7.创建从数据库配置文件,进入 /usr/mysql-slave/conf 文件夹创建文件 my.cnf

创建从数据库配置文件,进入 /usr/mysql-slave/conf 文件夹创建文件 my.cnf

[mysqld]
## 设置server_id  同一局域网中需要唯一
server_id=102
##指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备slave作为其它数据库实例的mstaer时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式 (mixed,statement,row)
binlog_format=mixed
## 二进制日志过去清理时间,默认值为0:表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的全部错误或者指定类型的错误,避免slave端复制中断
## 如,1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1

8.重启从机

[root@master ~]# docker restart mysql-salve
mysql-salve
[root@master ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
df014e4888ee   mysql:5.7   "docker-entrypoint.s…"   7 minutes ago    Up 12 seconds   33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp   mysql-salve
e21b214ecc54   mysql:5.7   "docker-entrypoint.s…"   32 minutes ago   Up 3 seconds    33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master
[root@master ~]# 

9.进入主机查看,主从同步状态

mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000001 |      154 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

10.进入从机

[root@master ~]# docker exec -it mysql-salve /bin/bash
root@df014e4888ee:/# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'databashes' at line 1
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> 

11.在从机配置主从复制

Docker_第44张图片

change master to master_host='192.168.220.133', ## 主机ip
master_user='slave', ## 从机要使用的账号
master_password='123456', ## 密码
master_port=3307, ##  主机端口
master_log_file='mall-mysql-bin.000001', ## 主机上面获得的参数
master_log_pos=154, ## 主机上面获得的参数
master_connect_retry=30; ## 失败重试次数

change master to master_host='192.168.220.133', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=154, master_connect_retry=30;

12.在从机配置查看主从复制状态

##查看 主从复制状态
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.220.133
                  Master_User: slave
                  Master_Port: 3307
                Connect_Retry: 30
              Master_Log_File: mall-mysql-bin.000001
          Read_Master_Log_Pos: 154
               Relay_Log_File: mall-mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mall-mysql-bin.000001
             Slave_IO_Running: No   ## 这里显示还没有开启
            Slave_SQL_Running: No   ## 这里显示还没有开启
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 154
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)


13.在从机开启主从复制

mysql>  start slave;
Query OK, 0 rows affected (0.01 sec)

再次检查主从复制状态

##查看 主从复制状态
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.220.133
                  Master_User: slave
                  Master_Port: 3307
                Connect_Retry: 30
              Master_Log_File: mall-mysql-bin.000001
          Read_Master_Log_Pos: 154
               Relay_Log_File: mall-mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mall-mysql-bin.000001
             Slave_IO_Running: Yes   ## 这里显示已经开启
            Slave_SQL_Running: Yes   ## 这里显示已经开启
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 154
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)


最后,检查主从复制是否能够同步数据

## 主库

# 创库
mysql> create database db01;
Query OK, 1 row affected (0.01 sec)

mysql> use db01;
Database changed
# 建表
mysql> create table t1 (id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
# 插入数据
mysql> insert into t1 values(1,'z3');
Query OK, 1 row affected (0.02 sec)
# 查询,表明成功插入
mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | z3   |
+------+------+
1 row in set (0.00 sec)

## 从库
# 使用库,提示是从库同步的
mysql> use db01;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
# 查询数据,成功,证明主从同步成功了
mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | z3   |
+------+------+
1 row in set (0.00 sec)

mysql> 

二、redis 三主三从集群配置

0.哈希槽分配算法

image-20220925171957793

1.启动六个redis服务

命令解析

docker run -d  ## 后台运行
--name redis-node-1 ## 命名
--net host ## 网络配置,暂时先不必理解。后面网络篇会详解 (使用宿主机的ip和地址)
--privileged=true ## 开启权限
-v /data/redis/share/redis-node-1:/data ## 挂载
redis:6.0.8 ## 镜像名
--cluster-enabled yes ## 是否集群启动,这里选择 yes
--appendonly yes ##开启持久化 默认选择即可 
--port 6381## 端口

开启六个不同的容器redis

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6381

docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6382

docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6383

docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6384

docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6385

docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6386
## 开启六个,第一个省略不展示了
[root@master ~]# docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6382
:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6386a3defc6b6cd08b5af9163169d535583c40eadae1b1cb439c376e5e966955ba78
[root@master ~]# 
[root@master ~]# docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6383
ef8715a7a9f24ea32faa9dcb99aa3b326afe29b7832678bfade52f0497775ded
[root@master ~]# 
[root@master ~]# docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6384
dfbd2c6d6635b2ec822aa19feb386b48b43aef713543bf0cfac7d9aa323b212b
[root@master ~]# 
[root@master ~]# docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6385
55fc9c544eaae8a63dd0ed3dec6d64059fa0250880ae49dc4d3929fcab9a0b2a
[root@master ~]# 
[root@master ~]# docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6386
9c9e4b3b83b1b6be2841ba4f45ddb1a4d9822ff6b6ef03231378c55893aad4b7
[root@master ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS     NAMES
9c9e4b3b83b1   redis:6.0.8   "docker-entrypoint.s…"   4 seconds ago    Up 3 seconds              redis-node-6
55fc9c544eaa   redis:6.0.8   "docker-entrypoint.s…"   9 seconds ago    Up 8 seconds              redis-node-5
dfbd2c6d6635   redis:6.0.8   "docker-entrypoint.s…"   9 seconds ago    Up 8 seconds              redis-node-4
ef8715a7a9f2   redis:6.0.8   "docker-entrypoint.s…"   9 seconds ago    Up 9 seconds              redis-node-3
a3defc6b6cd0   redis:6.0.8   "docker-entrypoint.s…"   9 seconds ago    Up 9 seconds              redis-node-2
8d329735de57   redis:6.0.8   "docker-entrypoint.s…"   54 seconds ago   Up 53 seconds             redis-node-1

2.构建主从关系

1.先进入其中一个redis的命令行,执行以下命令

redis-cli --cluster create  ## 创建集群命令
192.168.220.133:6381 ## 指定六个redis的IP地址与端口  
192.168.220.133:6382 ## 指定六个redis的IP地址与端口 
192.168.220.133:6383 ## 指定六个redis的IP地址与端口 
192.168.220.133:6384 ## 指定六个redis的IP地址与端口 
192.168.220.133:6385 ## 指定六个redis的IP地址与端口 
192.168.220.133:6386 ## 指定六个redis的IP地址与端口 
--cluster-replicas 1 ## 表示为每个master创建一个slave节点

2.开始执行

## 进入命令行
[root@master ~]# docker exec -it redis-node-1 /bin/bash
root@master:/data# redis-cli --cluster create 192.168.220.133:6381 192.168.220.133:6382 192.168.220.133:6383 192.168.220.133:6384 192.168.220.133:6385 192.168.220.133:6386 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
## 为三个主机分配哈希槽
Master[0] -> Slots 0 - 5460  ## 为三个主机分配哈希槽
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
## 展示主从如何分配
Adding replica 192.168.220.133:6385 to 192.168.220.133:6381 ## 展示主从如何分配
Adding replica 192.168.220.133:6386 to 192.168.220.133:6382
Adding replica 192.168.220.133:6384 to 192.168.220.133:6383
>>> Trying to optimize slaves allocation for anti-affinity ## 翻译: 尝试智能化的进行主从分配
[WARNING] Some slaves are in the same host as their master
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381 ## 分配的策略
   slots:[0-5460] (5461 slots) master
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[5461-10922] (5462 slots) master
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[10923-16383] (5461 slots) master
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
## 询问是否同意上述配置
Can I set the above configuration? (type 'yes' to accept): yes ##输入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 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.  ## 16384个槽已经分配完成,看见这个就说明分配成功


3.查看主从状态

以其中一个容器redis为切入点,进入命令行查看

## 进入,并连接上
[root@master ~]# docker exec -it redis-node-1 /bin/bash
root@master:/data# redis-cli -p 6381

## 查看集群信息
127.0.0.1:6381> cluster info  ## 查看集群信息
cluster_state:ok #状态 ok
cluster_slots_assigned:16384 #一共多少个槽
cluster_slots_ok:16384#已经分配掉多少槽
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 #已经的redis节点
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:448
cluster_stats_messages_pong_sent:477
cluster_stats_messages_sent:925
cluster_stats_messages_ping_received:472
cluster_stats_messages_pong_received:448
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:925

##查看有那些节点
127.0.0.1:6381> cluster nodes
10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381@16381 myself,master - 0 1664098267000 1 connected 0-5460
b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382@16382 master - 0 1664098269000 2 connected 5461-10922
fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383@16383 master - 0 1664098269857 3 connected 10923-16383

3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384@16384 slave fc11fd3e22a5e8942d73b9938100335256dd8b38 0 1664098267813 3 connected  ## 能够看出是挂在 容器id为fc11fd3e22a5e8942d73b9938100335256dd8b38的主机上
3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386@16386 slave b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 0 1664098267000 2 connected
4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385@16385 slave 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 0 1664098268832 1 connected


从上面也可以看出,主从分配的结构如下

M主    S从
1      5
2      6
3      4

每次重启,分配的结构都不一样;

4.测试redis主从

写入错误问题

因为主从用的是哈希槽算法,因此每个键key应该存入哪个主机redis已经是固定的,因此如果自己在随便一个主机redis上进行插入,可能会报错

127.0.0.1:6381> keys *
(empty array)
127.0.0.1:6381> set k1 v1  ## 在6381 存入,就报错了,提示说应该在6383主机进行插入
(error) MOVED 12706 192.168.220.133:6383

因此,既然我们搭建了集群,那就得以集群的方式连接上redis集群,然后再录入键值对

## 连接语句,最后加上一个参数 -c
root@master:/data# redis-cli -p 6381 -c
## 再次尝试存入键值对
127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.220.133:6383 ## 提示,根据算法,分配到了 6383 端口的redis上
OK
192.168.220.133:6383>    ## 然后可以发现,命令行也跳转到了 6383 
192.168.220.133:6383>  set k2 v2   # 根据key值的不同,来计算应该放入哪个主机
-> Redirected to slot [449] located at 192.168.220.133:6381
OK
192.168.220.133:6381> 


查看集群信息

redis-cli --cluster check IP地址:端口

redis-cli --cluster check 192.168.220.133:6381
root@master:/data# redis-cli --cluster check 192.168.220.133:6381

192.168.220.133:6381 (10c9c5f1...) -> 1 keys | 5461 slots | 1 slaves.
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 5461 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 2 keys in 3 masters. ## 表示现在一共 2个key在3个主机上
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
root@master:/data# 

tips:只要是存入了集群中的其中一个主机,那么在任意的主机的命令行中,都可以获取到这个key

## 可以看出,6383 并没有存入键,但是可以获取到
root@master:/data# redis-cli -p 6383
127.0.0.1:6383> get k1
"v1"
127.0.0.1:6383> 

- 测试主机宕机,从机上位

主从结构如下:

M主    S从
1      5
2      6
3      4

如果1号主机宕机,5号主机应该能够顺利上位才行

开始测试

① 把一号主机停掉

## 检查
[root@master ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED       STATUS       PORTS     NAMES
9c9e4b3b83b1   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-6
55fc9c544eaa   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-5
dfbd2c6d6635   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-4
ef8715a7a9f2   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-3
a3defc6b6cd0   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-2
8d329735de57   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-1
##停掉1号主机
[root@master ~]# docker stop redis-node-1
redis-node-1
[root@master ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED       STATUS       PORTS     NAMES
9c9e4b3b83b1   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-6
55fc9c544eaa   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-5
dfbd2c6d6635   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-4
ef8715a7a9f2   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-3
a3defc6b6cd0   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-2

②查看状态

## 进入二号机命令行
[root@master ~]# docker exec -it redis-node-2 /bin/bash
root@master:/data# redis-cli -p 6382 -c
#检查节点信息
127.0.0.1:6382> cluster nodes
b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382@16382 myself,master - 0 1664107426000 2 connected 5461-10922
fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383@16383 master - 0 1664107426553 3 connected 10923-16383
3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384@16384 slave fc11fd3e22a5e8942d73b9938100335256dd8b38 0 1664107428000 3 connected
#5号主机顺利成为了msater主机
4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385@16385 master - 0 1664107428593 7 connected 0-5460
# 可以看到,一号主机显示 fail 表示已经宕机
10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381@16381 master,fail - 1664107300918 1664107297860 1 disconnected
3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386@16386 slave b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 0 1664107427578 2 connected

- 主机重新开启,查看主从切换问题

## 检查
[root@master ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED       STATUS       PORTS     NAMES
9c9e4b3b83b1   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-6
55fc9c544eaa   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-5
dfbd2c6d6635   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-4
ef8715a7a9f2   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-3
a3defc6b6cd0   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours             redis-node-2
## 重新启动一号机
[root@master ~]# docker start redis-node-1
redis-node-1
[root@master ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED       STATUS         PORTS     NAMES
9c9e4b3b83b1   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours               redis-node-6
55fc9c544eaa   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours               redis-node-5
dfbd2c6d6635   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours               redis-node-4
ef8715a7a9f2   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours               redis-node-3
a3defc6b6cd0   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 3 hours               redis-node-2
8d329735de57   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago   Up 2 seconds             redis-node-1
## 进入命令行
[root@master ~]# docker exec -it redis-node-2 /bin/bash
root@master:/data# redis-cli -p 6381 -c
## 检查状态
127.0.0.1:6381> cluster nodes
#发现一号机虽然起来了,但是因为从机已经上位为主机,因此一号机就只能变为从机
10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381@16381 myself,slave 4bbfd41f437411e751b314832aa8941c27e14490 0 1664108056000 7 connected
4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385@16385 master - 0 1664108058735 7 connected 0-5460
fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383@16383 master - 0 1664108057000 3 connected 10923-16383
3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386@16386 slave b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 0 1664108057715 2 connected
3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384@16384 slave fc11fd3e22a5e8942d73b9938100335256dd8b38 0 1664108057000 3 connected
b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382@16382 master - 0 1664108057000 2 connected 5461-10922

5.主从扩容

先增加两个节点

docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6388

启动新节点,并加入集群

[root@master ~]# docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6387
-node-8:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6388735eb9d6daf41e35e79d64d0b15d885a3312bf1a928f883405a7f11579996315
[root@master ~]# docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes  --appendonly yes --port 6388
b54fc7402f49798660a8db15f20a0da2905cb20001b162e8ae7960bb705252a5
[root@master ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS          PORTS     NAMES
b54fc7402f49   redis:6.0.8   "docker-entrypoint.s…"   3 seconds ago   Up 3 seconds              redis-node-8
735eb9d6daf4   redis:6.0.8   "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds              redis-node-7
9c9e4b3b83b1   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago     Up 3 hours                redis-node-6
55fc9c544eaa   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago     Up 4 minutes              redis-node-5
dfbd2c6d6635   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago     Up 3 hours                redis-node-4
ef8715a7a9f2   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago     Up 3 hours                redis-node-3
a3defc6b6cd0   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago     Up 3 hours                redis-node-2
8d329735de57   redis:6.0.8   "docker-entrypoint.s…"   3 hours ago     Up 16 minutes             redis-node-1

新的两个只是启动了,并没有跟集群产生关系,接下来让他们产生关系

①新加入作为主节点

Docker_第45张图片

## 进入命令行
[root@master ~]# docker exec -it redis-node-7 /bin/bash
## 将新节点中的一个,作为主机加入集群
root@master:/data# redis-cli --cluster add-node 192.168.220.133:6387 192.168.220.133:6381
>>> Adding node 192.168.220.133:6387 to cluster 192.168.220.133:6381
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.220.133:6387 to make it join the cluster.
[OK] New node added correctly. ## 提示新节点已经成功加入了


③ 检查节点信息

root@master:/data# redis-cli --cluster check 192.168.220.133:6381
192.168.220.133:6381 (10c9c5f1...) -> 1 keys | 5461 slots | 1 slaves.
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 5461 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 5462 slots | 1 slaves.
192.168.220.133:6387 (730add61...) -> 0 keys | 0 slots | 0 slaves. ## 表示新加入的没有槽位,也没有从机
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
root@master:/data# 

重新分配槽号

Docker_第46张图片

##重新分配槽位的命令
root@master:/data# redis-cli --cluster reshard 192.168.220.133:6381
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
 # 需要键入,要分配多少个槽位给新节点,需要使用 总槽位/全部主节点得出  也就是16384/4=4096
How many slots do you want to move (from 1 to 16384)? 4096 
## 键入要分配给那个节点,输入节点的容器id :30add61f9baaa3f5d943f9d05e0621420c2153a
What is the receiving node ID? 730add61f9baaa3f5d943f9d05e0621420c2153a
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots. # 使用全部的存在的节点作为槽位的来源
  Type 'done' once you entered all the source nodes IDs. #指定一个容器作为槽位的来源
  ## 输入all即可,表示全部分配
  all

## 再次询问是否继续  yes即可
Do you want to proceed with the proposed reshard plan (yes/no)? 

检查集群信息:

root@master:/data# redis-cli --cluster check 192.168.220.133:6381
192.168.220.133:6381 (10c9c5f1...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 4096 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6387 (730add61...) -> 1 keys | 4096 slots | 0 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master  ## 可以看出,已经分配好了,其他的也都相应的减去槽位了
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

槽位分配规则

新加入的主节点的槽位,是从之前的所有主节点,每个都匀一些出来,从而组成的。这样的好处是这样能够提高性能

image-20220925205309605

给主节点分配新从节点

Docker_第47张图片

redis-cli --cluster add-node IP地址:子节点端口 IP地址:主节点端口 --cluster-slave --cluster-master-id 新主机节点ID

##分配子节点的命令
root@master:/data# redis-cli --cluster add-node 192.168.220.133:6388 192.168.220.133:6387 --cluster-slave --cluster-master-id 730add61f9baaa3f5d943f9d05e0621420c2153a
>>> Adding node 192.168.220.133:6388 to cluster 192.168.220.133:6387
>>> Performing Cluster Check (using node 192.168.220.133:6387)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.220.133:6388 to make it join the cluster.
Waiting for the cluster to join

>>> Configure node as replica of 192.168.220.133:6387.
[OK] New node added correctly. # 提示新节点加入集群成功

## 检查节点,发现新的主节点已经有了从节点
root@master:/data# redis-cli --cluster check 192.168.220.133:6381
192.168.220.133:6381 (10c9c5f1...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 4096 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6387 (730add61...) -> 1 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: ae4e4392e985b003ba7cdb9582349f5e7a52f707 192.168.220.133:6388
   slots: (0 slots) slave
   replicates 730add61f9baaa3f5d943f9d05e0621420c2153a
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

6.主从缩容

先删除主从的从节点

redis-cli --cluster del-node IP地址:从节点端口 从节点容器id

## 删除节点的命令
root@master:/data# redis-cli --cluster del-node 192.168.220.133:6388 ae4e4392e985b003ba7cdb9582349f5e7a52f707
>>> Removing node ae4e4392e985b003ba7cdb9582349f5e7a52f707 from cluster 192.168.220.133:6388
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.

##检查节点信息
root@master:/data# redis-cli --cluster check 192.168.220.133:6381
192.168.220.133:6381 (10c9c5f1...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 4096 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6387 (730add61...) -> 1 keys | 4096 slots | 0 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master  ## 可以发现已经成功删除
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

将主从的槽位全部清空,并赋值给另外一个主节点

分配节点的操作与之前扩容的时候一样,只不过是选择槽位来源的时候需要变动一下

root@master:/data# redis-cli --cluster reshard 192.168.220.133:6381
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID? 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1: 730add61f9baaa3f5d943f9d05e0621420c2153a #指定之前扩容的新主节点作为槽位的来源
Source node #2: done

分配完成后,检查集群信息

root@master:/data# redis-cli --cluster check 192.168.220.133:6381
192.168.220.133:6381 (10c9c5f1...) -> 1 keys | 8192 slots | 1 slaves. # 一号主节点,拥有了缩容的全部槽位
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 4096 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 4096 slots | 1 slaves.
192.168.220.133:6387 (730add61...) -> 0 keys | 0 slots | 0 slaves.  # 之前扩容的新节点,已经没有槽位了
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-6826],[10923-12287] (8192 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 730add61f9baaa3f5d943f9d05e0621420c2153a 192.168.220.133:6387
   slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

删除主从的主节点

跟删除从节点一样

##删除主节点
root@master:/data# redis-cli --cluster del-node 192.168.220.133:6387 730add61f9baaa3f5d943f9d05e0621420c2153a
>>> Removing node 730add61f9baaa3f5d943f9d05e0621420c2153a from cluster 192.168.220.133:6387
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.

再次检查集群信息

root@master:/data# redis-cli --cluster check 192.168.220.133:6381
192.168.220.133:6381 (10c9c5f1...) -> 1 keys | 8192 slots | 1 slaves.
192.168.220.133:6383 (fc11fd3e...) -> 1 keys | 4096 slots | 1 slaves.
192.168.220.133:6382 (b8c3e7f7...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.220.133:6381)
M: 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8 192.168.220.133:6381
   slots:[0-6826],[10923-12287] (8192 slots) master
   1 additional replica(s)
S: 4bbfd41f437411e751b314832aa8941c27e14490 192.168.220.133:6385
   slots: (0 slots) slave
   replicates 10c9c5f1364cb593da90ec4fb2f1e10a9a8156e8
M: fc11fd3e22a5e8942d73b9938100335256dd8b38 192.168.220.133:6383
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
S: 3143a394d45547a6b4ef9aa72434c4dc48abe145 192.168.220.133:6386
   slots: (0 slots) slave
   replicates b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f
S: 3e400672e9b5a617a11ebabce3298e40af668766 192.168.220.133:6384
   slots: (0 slots) slave
   replicates fc11fd3e22a5e8942d73b9938100335256dd8b38
M: b8c3e7f70b1b3c4861b33f1c3f1e52c1fd35443f 192.168.220.133:6382
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

三、Dockerfile

1.dockerfile文件内容讲解

① dockerfile基础关键知识

  • 每条关键字指令都必须是大写字母,且后面至少跟一个参数
  • 指令按照从上到下,顺序执行
  • ‘#’ 号,表示注释
  • 每条指令都会创建一个镜像层,并且提交,就是每次指令都在联合文件系统加了一层功能

② Docker执行dockerfile 的大致流程

1.docker加载基础镜像,然后从基础镜像运行一个容器

2.读取dockerfile,并执行一条指令,并对容器做出修改

3.执行类似于docker commit 的操作提交一个新的容器层

4.docker 再基于刚提交的镜像运行一个新容器

5.接着执行dickerfile的下一条指令直到全部指令执行完成

③ 容器生态,各部分含义的小总结

Docker_第48张图片

**Dockerfile:**容器化的第一步就是需要定义一个dockerfile,它就相当于整个容器生态的配置文件,dockerfile定义了进程需要的一切东西,它涉及到的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程等等;

**Docker镜像:**在成功用dockerfile定义好了配置文件后,docker build 时会产生一个Docker镜像,当运行Docker镜像时会真正开始提供服务;

**Docker容器:**容器就是镜像运行之后的状态,容器是直接提供服务的。

④ 保留字

这里以 tomcat 在Dockerhub上面发布的Dockerfile为讲解案例,讲解保留字的使用

FROM amazoncorretto:8-al2-jdk   # 指出当前镜像是基于那个镜像的

ENV CATALINA_HOME /usr/local/tomcat  # 用来在构建镜像的过程中,设置环境变量 (这里就是指定了CATALINA_HOME变量)
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME  # 指定在容器创建成功后,终端登录进来之后的默认文件夹,相当于根工作目录

# let "Tomcat Native" live somewhere isolated
ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib
ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR

# see https://www.apache.org/dist/tomcat/tomcat-10/KEYS
# see also "versions.sh" (https://github.com/docker-library/tomcat/blob/master/versions.sh)
ENV GPG_KEYS A9C5DF4D22E99998D9875A5110C01C5A2F6059E7

ENV TOMCAT_MAJOR 10
ENV TOMCAT_VERSION 10.0.26
ENV TOMCAT_SHA512 dad742b2962f73a23ebbe7aecd674246e25d83cde04bd20126f10e9a9abbac6fd025cd9ffd829c8e3152b6cbe07ff839f48383b64f81a5b0ac020f8d8c7f054f

RUN set -eux; \
	\
# http://yum.baseurl.org/wiki/YumDB.html
	if ! command -v yumdb > /dev/null; then \
		yum install -y --setopt=skip_missing_names_on_install=False yum-utils; \
		yumdb set reason dep yum-utils; \
	fi; \
	
/// 。 。 。 。 。 。 。///	
/// 中间省略具体的 run  ///
/// 。 。 。 。 。 。 。///


# verify Tomcat Native is working properly
RUN set -eux; \
	nativeLines="$(catalina.sh configtest 2>&1)"; \
	nativeLines="$(echo "$nativeLines" | grep 'Apache Tomcat Native')"; \
	nativeLines="$(echo "$nativeLines" | sort -u)"; \
	if ! echo "$nativeLines" | grep -E 'INFO: Loaded( APR based)? Apache Tomcat Native library' >&2; then \
		echo >&2 "$nativeLines"; \
		exit 1; \
	fi

EXPOSE 8080 # 当前容器对外暴漏的端口
CMD ["catalina.sh", "run"]
FROM

指出当前镜像是基于那个镜像的,需要指定一个已经存在的镜像作为模板,dockerfile文件的第一条必须是 from

MAINTAINER

表明作者的姓名邮箱等

RUN

容器构建时,具体执行的指令,在docker bulid 的时候,会执行 以 run 关键字修饰的语句

它有两种格式:shell格式 和 exec格式

shell格式

跟实际在命令行运行的指令一样

Docker_第49张图片

exec格式

类似于组合的字符串一样的东西

Docker_第50张图片

EXPOSE

当前容器对外暴漏的端口

WORKDIR

指定在容器创建成功后,终端登录进来之后的默认文件夹,相当于根工作目录

就是使用 -it 命令,进入命令行操作时,默认的文件夹地址

USER

指定该镜像以什么样的用户去执行,如果不指定,默认就是 root

一般都不指定,使用默认的

ENV

用来在构建镜像的过程中,设置环境变量

就如同在命令前制定了环境变量一样,定义的环境变量可以在后续的任何指令中使用,包括run指令和其他指令

ENV CATALINA_HOME /usr/local/tomcat  // 用来在构建镜像的过程中,设置环境变量 (这里就是指定了CATALINA_HOME变量)

WORKDIR $CATALINA_HOME  //使用的时候, $+变量名
COPY

拷贝宿主机的文件和目录到镜像中

:将宿主机上下文目录中 <源路径>的文件或者目录复制到新的一层的镜像内的<目标路径>位置

COPY [“src”,“desc”]

src:源文件或者目录

desc:目标文件或者目录,该路径如果不存在,会自动创建

ADD

跟COPY类似,都是将宿主机文件拷贝进镜像中,不同的是,ADD多了自动处理URL和解压tar压缩包的步骤

VOLUME

容器数据卷,用于数据保存和持久化工作

CMD

指定容器启动后要做的事情

Docker_第51张图片

查看 tomcat 容器的最后一行 CMD [“catalina.sh”, “run”]

所以,容器启动后,就运行了这个指令,如下

Docker_第52张图片

tips:

1.一个dockerfile文件中,允许有多条 CMD 命令,每条都会执行,但是如果两条语句进行不同的操作,前一条操作会被后面的覆盖

2.CMD 会被 docker run 最后的参数替换,比如 启动容器命令最后加上了 /bin/bash ,那么,CMD的指令就会变成

CMD[“/bin/bash”],而不是 CMD [“catalina.sh”, “run”]

ENTRYPOINT

Docker_第53张图片

Docker_第54张图片

2. 案例 - 编写dockerfile

①.下载运行最原始的 centos 镜像容器

检查内容

##
[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED         SIZE
centos                                                        latest    5d0da3dc9764   12 months ago   231MB
# 命令行运行
[root@master ~]# docker run -it 5d0da3dc9764 /bin/bash
[root@6b0123858955 /]# 
[root@6b0123858955 /]# vim a.txt # 没有vim
bash: vim: command not found
[root@6b0123858955 /]# 
[root@6b0123858955 /]# ifconfig  #没有ifconfig
bash: ifconfig: command not found
[root@6b0123858955 /]# java -version #没有Java环境
bash: java: command not found
[root@6b0123858955 /]# 

现在要做的就是创建一个拥有 vim+ifconfig+Java8环境 的新镜像;

②.编写Dockerfile文件

注意,文件名一定要是 大写的 Dockerfile 才可以

内容:

FROM centos:7 #指定源镜像,这里需要指定版本,要不然会报错
MAINTAINER chen #作者名称,邮箱地址

ENV MYPATH /usr/local # 环境变量
WORKDIR $MYPATH # 进入命令行后的默认工作目录

#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令以查看网络IP
RUN yum -y install net-tools
#安装java8 及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java  #创建文件夹
#ADD是相对路径,把jdk从宿主机添加到容器中,安装包必须于Dockerfile文件在同一位置
ADD jdk-8u311-linux-x64.tar.gz /usr/local/java/
#配置Java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_311
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

EXPOSE 80

CMD ecno $MYPATH  # 打印 MYPATH 的值
CMD ecno "success---------------ok"  # 打印
CMD /bin/bash #进入命令行的语句

另外,因为需要从宿主机引入Java8,因此需要将压缩包放在Dockerfile同一目录下

[root@master /]# cd /myfile   #进入存放的文件夹
[root@master myfile]# ll
总用量 143364
-rw-r--r--. 1 root root       885 930 16:40 Dockerfile  # dockerfile 文件,不带后缀
-rw-r--r--. 1 root root 146799982 930 16:12 jdk-8u311-linux-x64.tar.gz #需要引入的压缩包
[root@master myfile]# 

至此,准备完成,开始进行新镜像的构建

③构建镜像 - docker build

docker build -t 新镜像名称:TAG .

注意,TAG后面有个空格,还有个点

## 进入到Dockerfile 同级的文件夹下操作
[root@master myfile]# pwd
/myfile
[root@master myfile]# ll
总用量 143364
-rw-r--r--. 1 root root       544 930 16:56 Dockerfile
-rw-r--r--. 1 root root 146799982 930 16:12 jdk-8u311-linux-x64.tar.gz
[root@master myfile]# docker build -t centosjava8:1.5 .

///。。。。。。

 ---> e01305f31a65
Step 12/17 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
 ---> Running in f9d5ffab2239
Removing intermediate container f9d5ffab2239
 ---> 6728f98dd135
Step 13/17 : ENV PATH $JAVA_HOME/bin:$PATH
 ---> Running in 63df7eee8a80
Removing intermediate container 63df7eee8a80
 ---> 759674c31609
Step 14/17 : EXPOSE 80
 ---> Running in 0ff62bdd047d
Removing intermediate container 0ff62bdd047d
 ---> c3f3ee3c73a0
Step 15/17 : CMD ecno $MYPATH
 ---> Running in 8cace90ddbd9
Removing intermediate container 8cace90ddbd9
 ---> 197b50b42efb
Step 16/17 : CMD ecno "success---------------ok" ## 成功输出标志
 ---> Running in 226cb372a61b
Removing intermediate container 226cb372a61b
 ---> 02b17bf6e896
Step 17/17 : CMD /bin/bash ## 命令行也成功进入
 ---> Running in 6e493404220f
Removing intermediate container 6e493404220f
 ---> c291091d48f5
Successfully built c291091d48f5
Successfully tagged centosjava8:1.5

检查是否成功生成镜像

[root@master myfile]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED          SIZE
centosjava8                                                   1.5       c291091d48f5   3 minutes ago    1.21GB
centos                                                        latest    5d0da3dc9764   12 months ago    231MB

可以看到,已经成功的创建出来镜像了

接下来,就可以将这个镜像运行起来,成为容器,查看它是否拥有打进去的哪些功能

④ 运行镜像,使之成为容器

## ----  查看镜像  ---- ##
[root@master myfile]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED          SIZE
centosjava8                                                   1.5       c291091d48f5   3 minutes ago    1.21GB
centos   
## ----  将镜像运行起来  ---- ##
[root@master myfile]# docker run -it c291091d48f5 /bin/bash
## ----  查看是否成功设置默认工作路径 MYPATH  ---- ##
[root@0de30ac75a71 local]# pwd
/usr/local
## ----  查看ifconfig功能  ---- ##
[root@0de30ac75a71 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 656 (656.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
## ----  查看vim编辑器功能  ---- ##
[root@0de30ac75a71 local]# vim a.txt
## ----  查看Java环境  ---- ##
[root@0de30ac75a71 local]# java -version
java version "1.8.0_311"
Java(TM) SE Runtime Environment (build 1.8.0_311-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.311-b11, mixed mode)
[root@0de30ac75a71 local]# 

可以看出,都成功的将功能创建到镜像中去了

至此,使用Dockerfile进行镜像的构建已经完成

tips:虚悬镜像

[root@master ~]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED          SIZE
centosjava8                                                   1.5       c291091d48f5   14 minutes ago   1.21GB
## 出现了错误,出现了这种 没有名称,没有标签,的镜像,就是虚悬镜像,建议删除
<none>                                                        <none>    433ec4a712ee   26 minutes ago   231MB
registry.cn-hangzhou.aliyuncs.com/docker_chenchong/mydocker   1.2       4bf46269abe8   12 days ago      179MB
tomcat                                                        latest    fb5657adc892   9 months ago     680MB
redis                                                         latest    7614ae9453d1   9 months ago     113MB
mysql                                                         5.7       c20987f18b13   9 months ago     448MB
registry                                                      latest    b8604a3fe854   10 months ago    26.2MB
ubuntu                                                        latest    ba6acccedd29   11 months ago    72.8MB
centos                                                        7         eeb6ee3f44bd   12 months ago    204MB
centos                                                        latest    5d0da3dc9764   12 months ago    231MB
redis                                                         6.0.8     16ecd2772934   23 months ago    104MB
##  ----- 查看虚悬镜像的命令 -----  ##
[root@master ~]# docker image ls -f dangling=true
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
<none>       <none>    433ec4a712ee   40 minutes ago   231MB
[root@master ~]# 
##  ----- 删除全部虚悬镜像的命令 -----  ##
[root@master ~]# docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y

四、Docker微服务实战

1.将微服务打成jar包,并上传到服务器

image-20221020153600749

tips:如果是微服务的单模块打包,需要在该模块中的 pom.xml 文件中增加以下插件配置,否则否则打包后文件依赖文件没有一起打包,然后镜像内没有可以运行的程序文件,会导致程序运行不起来

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                
                <executions>
                    <execution>
                        <goals>
                            <goal>repackagegoal>
                        goals>
                    execution>
                executions>
                <configuration>
                    <includeSystemScope>trueincludeSystemScope>
                configuration>
            plugin>
        plugins>
    build>

2.编写 DockerFile 文件

FROM java:8
# 作者 
MAINTAINER chen
# 容器数据卷,用于数据保存和持久化工作,在主机安装地址 /var/lib/docker 目录下创建一个临时文件并连接到容器的 /tmp文件夹
VOLUME /tmp
# 将同目录下的jar包添加到容器中并改名为 chen_docker.jar
ADD spring-boot-docker.jar chen_docker.jar
# 运行 jar 包
RUN bash -c 'touch /chen_docker.jar'
ENTRYPOINT ["java","-jar","chen_docker.jar"]
# 暴漏7020端口作为微服务端口
EXPOSE 7020

放在跟jar包同目录下

Docker_第55张图片

3.构建镜像

使用命令,会自动根据本目录下的 Dockerfile 文件来构建镜像

docker build -t chen_docker:1.1 . 这里可以指定版本

Docker_第56张图片

检查本地 镜像

[root@master mydocker]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED          SIZE
## 镜像创建成功
chen_docker                                                   1.1       fd457c751076   56 seconds ago   643MB
centosjava8                                                   1.5       c291091d48f5   2 weeks ago      1.21GB
redis                                                         6.0.8     16ecd2772934   24 months ago    104MB
java                                                          8         d23bdf5b1b1b   5 years ago      643MB

4.运行容器

交互式启动 :docker run -it -p 暴漏端口:程序的端口 镜像id

后台启动:docker run -d -p 暴漏端口:程序的端口 镜像id

停止程序 : docker stop 容器id

## 检查,并没有启动的程序
[root@master mydocker]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
## 查看程序的镜像
[root@master mydocker]# docker images
REPOSITORY                                                    TAG       IMAGE ID       CREATED          SIZE
chen_docker                                                   1.2       6d5e2a4f33c9   7 minutes ago    684MB
redis                                                         6.0.8     16ecd2772934   24 months ago    104MB
java                                                          8         d23bdf5b1b1b   5 years ago      643MB
## 后台启动程序
[root@master mydocker]# docker run -d -p 7020:7020 6d5e2a4f33c9
e9a84f25bbb1dc12daeea3d4e5de8f8fafa1a5e21c3b17deb88684088d59f179
## 检查,程序已经启动
[root@master mydocker]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                       NAMES
e9a84f25bbb1   6d5e2a4f33c9   "java -jar chen_dock…"   3 seconds ago   Up 2 seconds   0.0.0.0:7020->7020/tcp, :::7020->7020/tcp   optimistic_gould

5.连接程序,测试程序

① 命令行测试访问

curl 本机IP地址:暴漏的端口/接口url

## 访问接口
[root@master mydocker]# curl 127.0.0.1:7020/dockerDemo/hello
你好,docker 
[root@master mydocker]# 

② 网页测试访问

Docker_第57张图片

至此,单体不连接数据库等外部中间件的程序已启动

tip:交互式启动的jar,可以实时看见程序运行日志

Docker_第58张图片

五、Docker 网络 - docker_network

1.三大网络模式

docker启动后,可以在Linux系统中看见一个网络桥接

ifconfig

Docker_第59张图片

安装docker会同步创建三个网络模式:查看网络模式的命令 : docker network ls

[root@master mydocker]# docker network ls
##网络id       |名称     |驱动名    |范围
NETWORK ID     NAME      DRIVER    SCOPE
c738b8c0a715   bridge    bridge    local
4576f1b38dbb   host      host      local
c24554a5a598   none      null      local

2.常见命令

[root@master mydocker]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network ## 连接
  create      Create a network ##创建
  disconnect  Disconnect a container from a network ##终断
  inspect     Display detailed information on one or more networks ##查看
  ls          List networks ##网络列表
  prune       Remove all unused networks ## 删除全部无效不再用的网络
  rm          Remove one or more networks ## 删除一个或多个网络

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

使用:

## 创建一个新的网络
[root@master mydocker]# docker network create chen_net
593a55ec1cd5680f6f13902aa8f3ec6bef25dcb05184aa625a279693f1ec9c58
## 列表查看全部网络
[root@master mydocker]# docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
c738b8c0a715   bridge     bridge    local
593a55ec1cd5   chen_net   bridge    local
4576f1b38dbb   host       host      local
c24554a5a598   none       null      local
## 删除一个网络
[root@master mydocker]# docker network rm chen_net
chen_net
##列表查看全部网络
[root@master mydocker]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
c738b8c0a715   bridge    bridge    local
4576f1b38dbb   host      host      local
c24554a5a598   none      null      local
## 查看详细信息
[root@master mydocker]# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "c738b8c0a715ea47e7bb031f35fb5b63d819d0fa01970daf3c8549ae2b03d017",
        "Created": "2022-10-20T14:51:04.809473857+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": {},
        "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": {}
    }
]

3.docker_network 的用处

  1. 容器间的互联和通信以及端口映射
  2. 容器IP变动时可以通过服务名直接网络通信而不受影响

实现原理:

​ 每个docker容器启动都会有一个默认的网络模式,默认的就是bridge,而启动后,查看容器的详细信息,比如下图

Docker_第60张图片

相同的网络模式下,他们也是通过网关转发,每个容器有自己的IP地址(IPAddress),也共有一个网关地址(Gateway),各容器之间通过服务名既可以互相访问了,就算容器重启导致自己的IP地址发生变化,也不影响互相通信.

4.各个网络模式介绍

常见的有三种,最常用的是第一种

Docker_第61张图片

还有一种不常见的:

image-20221020193112335

下面是详细介绍

bridge

Docker_第62张图片

Docker_第63张图片

host

Docker_第64张图片

用host模式的时候,端口映射没有意义,不用再设置端口映射;端口号会以主机端口为主,重复时则递增。

none

了解即可,几乎不会用

container

Docker_第65张图片

被共享的容器一旦关闭,借用端口的容器也会同步关闭;

自定义

创建一个自定义名称的网络,默认的驱动还是bridge,只不过名称可以自己决定。这样做的原因是能够使用容器名来互相ping通、互相调用

启动容器时,命令中多加一些命令即可让容器在自定义网络下启动。

image-20221020234431638

总结:

Docker_第66张图片

所以能够通过容器服务名来ping通;

六、Docker 编排 - Compose

1.是什么,能干什么

image-20221021102627114

Docker_第67张图片

2.下载安装

安装参考链接 : Install on Linux | Docker Documentation

## 指定目录,下载安装
[root@master ~]# DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
[root@master ~]#  mkdir -p $DOCKER_CONFIG/cli-plugins
[root@master ~]#  curl -SL https://github.com/docker/compose/releases/download/v2.12.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 42.8M  100 42.8M    0     0  10.6M      0  0:00:04  0:00:04 --:--:-- 17.0M
## 赋予可执行权限
[root@master ~]# chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
## 检查是否安装成功
[root@master ~]# docker compose version
Docker Compose version v2.12.0

3.核心概念

核心是:一文件,二要素

Docker_第68张图片

组成示意图:

Docker_第69张图片

总结来说就是:一个文件(docker-compose.yml)多个服务(redis\mysql\微服务)编排汇聚成一个工程(docker工程)

4.compose 常用命令

Docker_第70张图片

5.微服务实战

① 创建简单微服务

需要连接redis、MySql,都连接docker容器中的数据库。

启动redis命令:

docker run  -p 6379:6379 --name=myredis  --privileged=true  -v /usr/redis/redis.conf:/etc/redis/redis.conf -v /usr/redis/data:/data 
-d redis:6.0.8 redis-server /etc/redis/redis.conf 

启动mysql命令:

docker run -d -p 3306:3306 --privileged=true -v /usr/mysql/log:/var/log/mysql -v /usr/mysql/data:/var/lib/mysql  #数据
-v /usr/mysql/conf:/etc/mysql/conf.d  #配置

-e MYSQL_ROOT_PASSWORD=root #密码
--name mysql  mysql:5.7

微服务代码:

 /**
     * 获取用户信息 !
     *
     * @return
     */
    @GetMapping("/getUserInfo")
    public UserInfo getUserInfo() {
        String key ="userInfo";
        UserInfo userInfo=null;
        Boolean aBoolean = redisTemplate.hasKey(key);
        if (Boolean.TRUE.equals(aBoolean)){
            log.info("redis中存在,查询缓存数据");
            String s = redisTemplate.opsForValue().get(key);
            userInfo = JSONObject.parseObject(s, UserInfo.class);
        }else {
            log.info("查询数据库,并缓存数据");
            userInfo = userInfoService.getOne(Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getUserName, "陈冲"));
            redisTemplate.opsForValue().set(key, JSON.toJSONString(userInfo));
        }
        return userInfo;
    }

如果不用编排的方式启动的话,需要先后启动redis、Mysql、各个微服务,需要相当多个 Run 命令,异常麻烦,下面使用编排的方式进行启动

② 编写docker-compose.yml 文件

编排方式只是把多个启动命令放在一个文件里面进行,相当于启动jar包的 cmd 文件,因此各个服务的镜像还是需要提前生成的,生成镜像没有捷径。

下面是本案例的编排文件(注意不能有tab空格必须手敲)

version: "3"

services:
   ##  第一个容器服务
	mymodule:
		image: chen_docker:2.1 # 指定从哪个镜像启动
		container_name: bootdocker01 #启动后的容器名称
		ports:
			- "7020:7020" # 端口映射
		volumes:
			- /app/microService:/data # 数据挂载
		networks:
			- chen_mynet # 使用的网络
		depends_on: # 指定它依赖于那几个容器,依赖的容器会在它之前启动,且IP地址变动不影响
			- redis
			- mysql
			
	redis:
		image: redis:6.0.8  # 指定从哪个镜像启动
		ports:
			- "6379:6379" # 端口映射
		volumes:
			- /app/redis/redis.conf:/etc/redis/redis.conf
			- /app/redis/data:/data  # 数据挂载
		networks:
			- chen_mynet  # 使用的网络
		command: redis-server /etc/redis/redis.conf # 命令,跟单个启动redis的命令一样
		
	mysql:
		image: mysql:5.7  # 指定从哪个镜像启动
		environment:
			MYSQL_ROOT_PASSWORD: 'root' # 根
			MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
			MYSQL_DATABASE: 'db01' #指定数据库
			MYSQL_USER: 'root01' #新创建个用户密码
			MYSQL_PASSWORD: 'root01'
		ports:
			- "3306:3306" # 端口映射
		volumes:
			- /app/mysql/db:/var/lib/mysql
			- /app/mysql/conf/my.cnf:/etc/my.cnf
			- /app/mysql/init:/docker-entrypoint-initdb.d   # 数据挂载
		networks:
			- chen_mynet  # 使用的网络
		command: --default-authentication-plugin=mysql_native_password  # 解决外部无法访问,默认加上即可
		
networks:
	chen_mynet:  # 创建一个自己的网络,让整个编排中的全部容器都引用该网络,这样就会处于同一个网段
			
			
			

③ 微服务配置文件修改

需要将原本的IP地址修改为 容器服务名

spring:
  datasource:
    # 需要将原本的IP地址改成编排文件中的 容器服务名
    url: jdbc:mysql://mysql:3306/db01?serverTimezone=GMT%2B8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  profiles:
    active: dev
    #服务名
  application:
    name: service-docker
  redis:
    # 需要将原本的IP地址改成编排文件中的 容器服务名
    host: redis
    port: 6379
    database: 1

④ 打包微服务,上传并利用 dockerfile 生成镜像

dockerfile 文件不用修改,直接按照上面的步骤进行新镜像的创建

⑤ 用编排的方式启动容器

需要进入到编排文件同目录下进行命令操作

1.先检查语法有没有错误

docker-compose config -q

如果没有输出,就表示语法是正确的

[root@master mydocker]# docker compose config -q
[root@master mydocker]# 

2.运行编排文件,启动容器

运行命令要在跟编排文件同文件夹下进行

## 确认没有容器运行
[root@master mydocker]# docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
## 运行编排文件的命令
[root@master mydocker]# docker compose up -d
[+] Running 4/4
 ⠿ Network mydocker_chen_mynet  Created                                                                                                                                                                                                                      0.0s
 ⠿ Container mydocker-mysql-1   Started                                                                                                                                                                                                                      0.7s
 ⠿ Container mydocker-redis-1   Started                                                                                                                                                                                                                      0.6s
 ⠿ Container bootdocker01       Started                                                                                                                                                                                                                      1.0s
## 检查容器是否成功启动
[root@master mydocker]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
622d2001b50e   chen_docker:2.1   "java -jar chen_dock…"   6 seconds ago   Up 5 seconds   0.0.0.0:7020->7020/tcp, :::7020->7020/tcp              bootdocker01
5614db683b7b   redis:6.0.8       "docker-entrypoint.s…"   6 seconds ago   Up 6 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              mydocker-redis-1
8d31360141ba   mysql:5.7         "docker-entrypoint.s…"   6 seconds ago   Up 6 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mydocker-mysql-1


3.验证程序

正常访问程序

tips:问题待解决:Java代码向mysql中插入中文字段会出现乱码,猜测可能是mysql版本不对,未解决

5.关闭程序

[root@master mydocker]# docker compose stop
[+] Running 3/3
 ⠿ Container bootdocker01      Stopped                                                                                                                                                                                                                       0.2s
 ⠿ Container mydocker-redis-1  Stopped                                                                                                                                                                                                                       0.2s
 ⠿ Container mydocker-mysql-1  Stopped                                                                                                                                                                                                                       3.5s
[root@master mydocker]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

七、可视化工具 Portainer

1.下载安装启动

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

## 直接运行语句进行下载并启动
[root@master mydocker]# 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
Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete 
49d59ee0881a: Pull complete 
a2300fd28637: Pull complete 
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
c28263826a5a1f2c2f0f542bd7baa3ce4c25d354a9cb3dc5fdcf4e4822438579
## 看到已经启动
[root@master mydocker]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED             STATUS          PORTS                                                                                  NAMES
c28263826a5a   portainer/portainer   "/portainer"             12 minutes ago      Up 2 minutes    0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp   portainer
76ab042d3ef3   chen_docker:3.2       "java -jar chen_dock…"   24 minutes ago      Up 24 minutes   0.0.0.0:7020->7020/tcp, :::7020->7020/tcp                                              bootdocker01
5614db683b7b   redis:6.0.8           "docker-entrypoint.s…"   About an hour ago   Up 24 minutes   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp                                              mydocker-redis-1
8d31360141ba   mysql:5.7             "docker-entrypoint.s…"   About an hour ago   Up 24 minutes   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                   mydocker-mysql-1
[root@master mydocker]# 

2.访问页面

在服务器上启动后,可以通过 服务器IP地址+9000 网页访问到

Docker_第71张图片

第一次登陆需要创建用户,有默认用户名 admin 自己输入八位密码,然后创建用户

登录上去后,选择 Local 查看本地的容器情况:

Docker_第72张图片

点进去查看详细信息:

Docker_第73张图片

3.常规操作

① 查看容器日志、细节、命令行

Docker_第74张图片

② 网页完成拉取镜像、运行为容器

Docker_第75张图片

Docker_第76张图片

启动后可以看见,网页上正常启动了

Docker_第77张图片

并且也能够看到正常拉下来了镜像

Docker_第78张图片

访问nginx也能得到正常反馈

Docker_第79张图片

八、CIG 重量级容器监控

1.docker 原生监控 - docker stats

docker 原生也有支持动态监控容器各项参数的命令

docker stats

[root@master mydocker]# docker stats

##  一直动态打印容器状态信息。。。
CONTAINER ID   NAME               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
c28263826a5a   portainer          0.19%     15.41MiB / 1.917GiB   0.78%     250kB / 396kB   44MB / 492kB     11
76ab042d3ef3   bootdocker01       5.68%     346.8MiB / 1.917GiB   17.66%    926B / 0B       232MB / 0B       32
5614db683b7b   mydocker-redis-1   0.07%     9.656MiB / 1.917GiB   0.49%     1.1kB / 0B      39.5MB / 0B      5
8d31360141ba   mydocker-mysql-1   0.30%     191MiB / 1.917GiB     9.73%     1.1kB / 0B      113MB / 25.4MB   27

CONTAINER ID   NAME               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
c28263826a5a   portainer          0.19%     15.41MiB / 1.917GiB   0.78%     250kB / 396kB   44MB / 492kB     11
76ab042d3ef3   bootdocker01       5.68%     346.8MiB / 1.917GiB   17.66%    926B / 0B       232MB / 0B       32
5614db683b7b   mydocker-redis-1   0.07%     9.656MiB / 1.917GiB   0.49%     1.1kB / 0B      39.5MB / 0B      5
8d31360141ba   mydocker-mysql-1   0.30%     191MiB / 1.917GiB     9.73%     1.1kB / 0B      113MB / 25.4MB   27
CONTAINER ID   NAME               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O        PIDS
c28263826a5a   portainer          0.00%     15.41MiB / 1.917GiB   0.78%     252kB / 397kB   44MB / 492kB     11
76ab042d3ef3   bootdocker01       0.17%     346.8MiB / 1.917GiB   17.66%    926B / 0B       232MB / 0B       32
5614db683b7b   mydocker-redis-1   0.13%     9.656MiB / 1.917GiB   0.49%     1.1kB / 0B      39.5MB / 0B      5
8d31360141ba   mydocker-mysql-1   0.17%     191MiB / 1.917GiB     9.73%     1.1kB / 0B      113MB / 25.4MB   27
^C  # 键盘输入 ctrl+c 退出展示
[root@master mydocker]# 

参数含义:

Docker_第80张图片

问题:

Docker_第81张图片

2.CIG 重量级监控三剑客

CIC 是一个统称,包含三部分

image-20221022113129542

CAdvisor

Docker_第82张图片

InfluxDB

Docker_第83张图片

Grafana

Docker_第84张图片

总结:

Docker_第85张图片

3.使用compose将CIG编排,一键启动 CIG

① 编写 docker-compose 文件

version: '3.1'
volumes:
 grafana_data: {} # 数据的挂载
services: # run的服务清单
 influxdb: # 1.influxdb ======================
  image: tutum/influxdb:0.9
  restart: always
  environment:
   - PRE_CREATE_DB=cadvisor # 启动influxdb前先创建一个名叫cadvisor的数据库
  ports:
   - "8083:8083"
   - "8086:8086"
  volumes:
   - ./data/influxdb:/data # 容器数据卷的关联
 cadvisor: # 2.cadvisor ======================
  image: google/cadvisor # 指定镜像
  links: 
   -influxdb:influxsrv # 指定连接数据库
  command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086 # 指定连接数据库
  restart: always
  ports:
   - "8080:8080" # 端口
  volumes:
   - /:/rootfs:ro
   - /var/run:/var/run:rw
   - /sys:/sys:ro
   - /var/lib/docker/:/var/lib/docker:ro
 grafana: # 2.cadvisor ======================
  user: "104"
  image: grafana/grafana
  user: "104"
  restart: always
  links:
   - influxdb:influxsrv # 指定展现数据的来源
  pors:
   - "3000:3000"
  volumes:
   - grafana_data:/var/lib/grafana
  environment:
   - HTTP_USER=admin
   - HTTP_PASS=admin
   - INFLUXDB_HOST=influxsrv
   - INFLUXDB_PORT=8086

经检查未发现语法错误

② 一键启动 CIG

进入到 CIG 的编排文件的同目录下

Docker_第86张图片

[root@master cig]# ll
总用量 4
-rw-r--r--. 1 root root 1231 1022 12:08 docker-compose.yml
[root@master cig]# docker compose config -q
[root@master cig]# docker compose up -d
# // 省略拉取启动过程。。。
# // 省略拉取启动过程。。。
[root@master cig]# docker ps  # 检查已经启动
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                                                  NAMES
1709d8ed9fcb   google/cadvisor       "/usr/bin/cadvisor -…"   23 seconds ago   Up 21 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp                                              cig-cadvisor-1
9803fd2828b9   grafana/grafana       "/run.sh"                23 seconds ago   Up 21 seconds   0.0.0.0:3000->3000/tcp, :::3000->3000/tcp                                              cig-grafana-1
487e1a38ce97   tutum/influxdb:0.9    "/run.sh"                23 seconds ago   Up 22 seconds   0.0.0.0:8083->8083/tcp, :::8083->8083/tcp, 0.0.0.0:8086->8086/tcp, :::8086->8086/tcp   cig-influxdb-1


可视化页面也能看到启动成功:

Docker_第87张图片

③ 测试页面能否正常访问

CAdvisor - 收集

http://IP地址:8080/

页面如下:

Docker_第88张图片

Docker_第89张图片

Influxdb - 存储

http://IP地址:8083/

页面如下:

Docker_第90张图片

在命令导航栏,选中,回车即可

Grafana - 展现

http://IP地址:3000/

页面如下:

Docker_第91张图片

使用配置的账号密码 admin admin

Docker_第92张图片

⑤ 配置使用 - 配置数据源

页面能够正常访问,但是 Grafana 需要配置数据源才能够正常显示监控数据

Docker_第93张图片

Docker_第94张图片

image-20221022123344061

Docker_第95张图片

点击save保存,配置完成

⑥ 配置使用 - 配置面板

Docker_第96张图片

Docker_第97张图片

配置名称

Docker_第98张图片

数据面板出来了:

Docker_第99张图片

⑦ 配置使用 - 业务规则配置

Docker_第100张图片

配置完成即可展示

九、win10使用可视化工具创建容器

1.安装Docker Desktop

2.安装常用软件

① MySQL - 主从复制

主服务器

一主两从

setp1:下载镜像

安装后,windows的命令行就可以直接使用docker命令

直接搜索并下载镜像

Docker_第101张图片

setp2:先创建挂载目录,配置目录

Docker_第102张图片

conf 目录下先创建 配置文件 my.cnf

[client]
default_character_set=utf-8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
# 服务器唯一id,默认值1
server-id=1
# 设置日志格式,默认值ROW
binlog_format=STATEMENT

setp3:运行镜像,生成容器

命令:

docker run -p 3307:3306  # 因为本地已有3306,因此需要避开3306端口
--privileged=true 
--name mysql   # 取名
-v E:/Docker/mysql/log:/var/log/mysql   ## 挂载日志目录
-v E:/Docker/mysql/data:/var/lib/mysql    ## 挂载数据持久化目录
-v E:/Docker/mysql/conf:/etc/mysql/conf.d    ## 挂载配置文件
-e MYSQL_ROOT_PASSWORD=root  -d mysql    ## 配置密码并指定镜像

docker run -p 3307:3306 --privileged=true --name mysql-master -v //e/Docker/mysql/log:/var/log/mysql -v //e/Docker/mysql/data:/var/lib/mysql -v //e/Docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root  -d mysql

启动成功,并使用可视化工具连接

Docker_第103张图片

进入到命令行,将密码编码方式修改一下,否则无法使用连接工具连接上,如下的错误:

Docker_第104张图片

使用如下命令:

# mysql -uroot -proot
mysql: [Warning] World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
## 更改密码编码
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
Query OK, 0 rows affected (0.00 sec)

可以成功连接

Docker_第105张图片

连接成功,主机可以正常使用;

setp4:主机中创建从机用户

-- 创建slave用户
CREATE USER 'chen_slave'@'%';
-- 设置密码
ALTER USER 'chen_slave'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'chen_slave'@'%' ;
-- 刷新权限
FLUSH PRIVILEGES;
  • step5:主机中查询master状态:

执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化

SHOW MASTER STATUS;

记下FilePosition的值。执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。

mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 |     1347 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
从服务器

setp1:准备

从服务器的目录、挂载、配置文件、启动命令、修改密码方式都一样。按照上述进行即可

my.cnf

[client]
default_character_set=utf-8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=2
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin

启动命令

docker run -p 3308:3306 --privileged=true --name mysql-slave1 -v //e/Docker/mysql-slave1/log:/var/log/mysql -v //e/Docker/mysql-slave1/data:/var/lib/mysql -v //e/Docker/mysql-slave1/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root  -d mysql

setp2:配置主从关系

进入从机命令行

# 这里使用主机创建的 从机账号密码来配置
CHANGE MASTER TO MASTER_HOST='172.27.48.1', 
MASTER_USER='chen_slave',MASTER_PASSWORD='root', MASTER_PORT=3307,
# 这里是主机显示的内容
MASTER_LOG_FILE='binlog.000002',MASTER_LOG_POS=1347; 


CHANGE MASTER TO MASTER_HOST='172.27.48.1', MASTER_USER='chen_slave',MASTER_PASSWORD='root', MASTER_PORT=3307,MASTER_LOG_FILE='binlog.000002',MASTER_LOG_POS=1347; 

-- 启动
START SLAVE;
-- 查看状态(不需要分号)
SHOW SLAVE STATUS\G

**两个关键进程:**下面两个参数都是Yes,则说明主从配置成功!

Docker_第106张图片

常见问题

如果没有全部yes,可以删除掉配置关系从新配置

stop slave;  #停止主从配置
reset slave;  #删除原本的主从配置


# 问题一,连接不上主机,原因:docker上挂载的配置文件没有生效,两个都用的同一个服务id,出错
# 解决办法,每次手动修改服务id
 show variables like 'server_id'; ## 查看当前服务的id
 SET GLOBAL server_id=2; # 修改当前服务的id
 SHOW MASTER STATUS;
 # 问题二 同一个主机,要用   IPv4 地址 . . . . . . . . . . . . : 172.27.48.1
 其他的ip不可以

注意:创建第一个数据库时候需要指定编码格式为 utf-8 否则会导致插入中文数据报错

② redis

– 完结 –

你可能感兴趣的:(docker,java)