【Docker】笔记小结

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 【Docker】笔记小结

一、快速入门

1. 安装

# 1.查看系统内核(3.10以上才可以)
uname -r

[root@VM-24-12-centos ~]# uname -r
3.10.0-1160.45.1.el7.x86_64

# 2.查看系统环境
cat /etc/os-release

[root@VM-24-12-centos ~]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

# 3.卸载本机docker
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 4.设置仓库
yum install -y yum-utils
## 设置国内阿里云仓库,速度快
 yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 5.更新yum包索引
yum makecache fast

# 5.安装docker(ce 社区版  ee 企业版)
yum install docker-ce docker-ce-cli containerd.io

# 6.启动docker
systemctl start docker

# 7.检查docker版本
docker version

[root@VM-24-12-centos ~]# docker version
Client: Docker Engine - Community
 Version:           20.10.14
 API version:       1.41
 Go version:        go1.16.15
 Git commit:        a224086
 Built:             Thu Mar 24 01:49:57 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.14
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.15
  Git commit:       87a90dc
  Built:            Thu Mar 24 01:48:24 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.5.11
  GitCommit:        3df54a852345ae127d1fa3092b95168e4a88e2f8
 runc:
  Version:          1.0.3
  GitCommit:        v1.0.3-0-gf46b6ba
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

# 8.测试docker
docker run hello-world

# 9.查看docker镜像
docker images

[root@VM-24-12-centos ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   6 months ago   13.3kB

# 10.卸载docker
## 10.1 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
##10.2 删除资源
rm -rf /var/lib/docker   (docker默认工作路径)
rm -rf /var/lib/containerd

2.配置镜像加速

以阿里云镜像为例:

  1. 阿里云容器镜像服务-镜像加速器

在这里插入图片描述
在这里插入图片描述

  1. 配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["xxxxx"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

二、常用命令

0. 预备

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

帮助文档地址:https://docs.docker.com/reference/

在这里插入图片描述

1.镜像命令

1.1 查看所有本地主机的镜像

# 查看所有本地主机的镜像
docker images  

REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   6 months ago   13.3kB

# 解释:
REPOSITORY    镜像的仓库源
TAG           镜像的标签
IMAGE ID    镜像的标签
CREATED        镜像的创建时间
SIZE        镜像的大小

# 可选项
Options:
  -a, --all         Show all images (default hides intermediate images) #列出所有镜像
  -q, --quiet       Only show numeric IDs # 只显示镜像的id

1.2 搜索镜像

# 搜索镜像
docker search

[root@VM-24-12-centos ~]# docker search mysql
NAME                             DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                            MySQL is a widely used, open-source relation…   12413     [OK]       
mariadb                          MariaDB Server is a high performing open sou…   4782      [OK]       
mysql/mysql-server               Optimized MySQL Server Docker images. Create…   918                  [OK]
percona                          Percona Server is a fork of the MySQL relati…   575       [OK]       


## 可选项:
Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output

# --filter=STARS=3000 #过滤,搜索出来的镜像收藏STARS数量大于3000的
[root@VM-24-12-centos ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   12413     [OK]       
mariadb   MariaDB Server is a high performing open sou…   4782      [OK]       

搜索镜像【也可以在docker hub上找下载,比较麻烦,没有命令用起来舒服】


1.3 下载镜像

# 下载镜像
docker pull 镜像名[:tag]

[root@VM-24-12-centos ~]# docker pull tomcat:8
8: Pulling from library/tomcat #如果不写tag,默认就是latest
90fe46dd8199: Already exists   #分层下载: docker image 的核心 联合文件系统(之前下载过的会,不用下载,共用)
35a4f1977689: Already exists 
bbc37f14aded: Already exists 
74e27dc593d4: Already exists 
93a01fbfad7f: Already exists 
1478df405869: Pull complete 
64f0dd11682b: Pull complete 
68ff4e050d11: Pull complete 
f576086003cf: Pull complete 
3b72593ce10e: Pull complete 
Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df # 签名防伪
Status: Downloaded newer image for tomcat:8
docker.io/library/tomcat:8 #真实地址

#等价于
docker pull tomcat:8
docker pull docker.io/library/tomcat:8

1.4 删除镜像

# 删除镜像
docker rmi -f 镜像id #删除指定id的镜像
docker rmi -f 容器id 容器id ... # 删除多个容器
docker rmi -f $(docker images -aq) # 删除全部的容器

2.容器命令

说明:有了镜像才可以创建容器

以centos镜像为例:

#docker中下载centos
docker pull centos
#查看镜像
docker images
#测试启动,bash启动
docker run -it centos /bin/bash

[root@VM-24-12-centos ~]# docker run -it centos /bin/bash
[root@0687c291327c /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 退回主机
exit   # 直接容器停止并推出
Ctrl + P + Q # 容器不停止退出

2.1 启动容器:

docker run [可选参数] image | docker container run [可选参数] image 
#参书说明
--name="Name"        #容器名字 tomcat01 tomcat02 用来区分容器
-d                    #后台方式运行
-it                 #使用交互方式运行,进入容器查看内容
-p                    #指定容器的端口 -p 8080(宿主机):8080(容器)
        -p ip:主机端口:容器端口
        -p 主机端口:容器端口(常用)
        -p 容器端口
        容器端口
-P(大写)             # 随机指定端口

2.2 查看容器:

docker ps    # 列出所有的运行的容器
docker ps -a # 列出所有的运行的容器 + 最近运行过的容器
docker ps -a -n=?  # 列出所有的运行的容器 + 最近运行过的容器 ?个
docker ps -q # 只显示容器的编号
docker ps -aq # 只显示容器的编号


[root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@VM-24-12-centos ~]# docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                      PORTS     NAMES
0687c291327c   centos        "/bin/bash"   4 minutes ago    Exited (0) 3 minutes ago              peaceful_stonebraker
6f0823b20328   hello-world   "/hello"      57 minutes ago   Exited (0) 57 minutes ago             inspiring_engelbart

[root@VM-24-12-centos ~]# docker ps -a -n=1
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
0687c291327c   centos    "/bin/bash"   4 minutes ago   Exited (0) 3 minutes ago             peaceful_stonebraker

2.3 删除容器:

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

2.4 启动和停止容器:

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

3.其他命令

3.1 后台启动:

# 命令 docker run -d 镜像名

[root@VM-24-12-centos ~]# docker run -d centos
a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c

[root@VM-24-12-centos ~]# docker ps    
CONTAINER ID      IMAGE       COMMAND    CREATED     STATUS   PORTS    NAMES
# 问题docker ps. 发现centos 停止了
# 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

3.2 查看日志:

docker logs --help
Options:
      --details        Show extra details provided to logs 
*  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
*      --tail string    Number of lines to show from the end of the logs (default "all")
*  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)


docker run -d centos /bin/sh -c "while true;do echo 666;sleep 1;done" #模拟日志      
#显示日志
-tf        #显示日志信息(一直更新)
--tail number #需要显示日志条数
docker logs -t --tail n 容器id #查看n行日志
docker logs -ft 容器id #跟着日志

3.3 查看容器中的进程信息:

# 命令 docker top 容器id

[root@VM-24-12-centos ~]# docker top 9865999fe479
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12852               12833               0                   22:46               ?                   00:00:00            /bin/sh -c while true;do echo 666;sleep 1;done
root                17867               12852               0                   22:49               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

3.4 查看镜像的元数据:

docker inspect 容器id

[root@VM-24-12-centos ~]# docker inspect 9865999fe479
[
    {
        "Id": "9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e",
        "Created": "2022-04-15T14:46:44.445308293Z",
        "Path": "/bin/sh",
        "Args": [
            "-c",
            "while true;do echo 666;sleep 1;done"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 12852,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-04-15T14:46:44.722755109Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/hostname",
        "HostsPath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/hosts",
        "LogPath": "/var/lib/docker/containers/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e/9865999fe4792a12af884bd8e6bc4ad008ae47b962ba5e310fdf5477d06e1f4e-json.log",
        "Name": "/zen_taussig",
        "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/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088-init/diff:/var/lib/docker/overlay2/9123fd3ce2d692e8f29431878cfad8dc26c3b37973ab99176f479f3f9fe3f15a/diff",
                "MergedDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088/merged",
                "UpperDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088/diff",
                "WorkDir": "/var/lib/docker/overlay2/a576bc4c3377d3992efc6b80ba3a93d2690562265e311a152885e0ed025b2088/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "9865999fe479",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "while true;do echo 666;sleep 1;done"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4c98fe4130129a2c6f7eb38578c8a2032a9756328060dd026c37fce231bf51e8",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/4c98fe413012",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "aa0e4a6dab7e4b283423df17e1bbb65e54458447959a3c0e13acbbb6abb47446",
            "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": "e4fba822dc97104a9a319b745f7b00e87a04eaccd49cae3d366aa4cb47a553de",
                    "EndpointID": "aa0e4a6dab7e4b283423df17e1bbb65e54458447959a3c0e13acbbb6abb47446",
                    "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
                }
            }
        }
    }
]

3.5 进入当前正在运行的容器

# 方式一:

docker exec -it 容器id bashShell

[root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
9865999fe479   centos    "/bin/sh -c 'while t…"   14 minutes ago   Up 14 minutes             zen_taussig
[root@VM-24-12-centos ~]# docker exec -it 9865999fe479 /bin/bash
[root@9865999fe479 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@9865999fe479 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 14:46 ?        00:00:00 /bin/sh -c while true;do echo 666;sleep 1;done
root       901     0  0 15:01 pts/0    00:00:00 /bin/bash
root       925     1  0 15:01 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root       926   901  0 15:01 pts/0    00:00:00 ps -ef

# 方式二:
docker attach 容器id
正在执行的代码.....

# 比较:
# docker exec          # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach     # 进入容器正在执行的终端,不会启动新的进程!

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

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

[root@VM-24-12-centos ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         5.7       c20987f18b13   3 months ago   448MB
hello-world   latest    feb5d9fea6a5   6 months ago   13.3kB
centos        latest    5d0da3dc9764   7 months ago   231MB
## 进入docker容器内
[root@VM-24-12-centos home]# docker attach a0aa07d62a3e
[root@a0aa07d62a3e /]# cd /home
[root@a0aa07d62a3e home]# ls
## 在容器内新建一个test.java文件
[root@a0aa07d62a3e home]# touch test.java
[root@a0aa07d62a3e home]# exit
exit
## 将这个文件拷贝到主机上
[root@VM-24-12-centos home]# docker cp a0aa07d62a3e:/home/test.java /home
[root@VM-24-12-centos home]# ls
lighthouse  test.java  www

小结:

在这里插入图片描述

命令大全:

  attach      Attach local standard input, output, and error streams to a running container
  #当前shell下 attach连接指定运行的镜像
  build       Build an image from a Dockerfile # 通过Dockerfile定制镜像
  commit      Create a new image from a container's changes #提交当前容器为新的镜像
  cp          Copy files/folders between a container and the local filesystem #拷贝文件
  create      Create a new container #创建一个新的容器
  diff        Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
  events      Get real time events from the server # 从服务获取容器实时时间
  exec        Run a command in a running container # 在运行中的容器上运行命令
  export      Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
  history     Show the history of an image # 展示一个镜像形成历史
  images      List images #列出系统当前的镜像
  import      Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
  info        Display system-wide information # 显示全系统信息
  inspect     Return low-level information on Docker objects #查看容器详细信息
  kill        Kill one or more running containers # kill指定docker容器
  load        Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
  login       Log in to a Docker registry #
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

4.练习

4.1 部署Nginx

# 1.搜索镜像,建议去dockerhub上搜索,可以看到帮助文档
docker search nginx
# 2.下载镜像
docker pull nginx
# 3.启动
docker run -d --name nginx01 -p 6666:80 nginx
# 4.查看运行状态
docker ps
# 5.测试
curl localhost:6666

4.2 部署Tomcat

# 官方的使用(用完即删,一般用来做测试)
docker run -it --rm tomcat:9.0
# 1.下载镜像
docker pull tomcat:9.0
# 2.启动运行
docker run -d -p 6667:8080 --name tomcat01 tomcat:9.0
#测试访问有没有问题
curl localhost:6667

# 发现问题:1、linux命令少了。 2.webapps目录为空 
# 原因:阿里云镜像的原因,阿里云默认是最小的镜像,所以不必要的都剔除掉
# 保证最小可运行的环境!
# 解决方案:
# 将webapps.dist下的文件都拷贝到webapps下即可

# 进入容器
docker exec -it tomcat01 /bin/bash
# 拷贝webapps.dist 内容给webapps
cp -r webapps.dist/* webapps 

4.3 部署 es + kibana

# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置的安全目录 ! 挂载
# 1.启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
# 2.测试
curl localhost:9200
{
  "name" : "d73ad2f22dd3",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "atFKgANxS8CzgIyCB8PGxA",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
# 2.查看内存消耗
docker stats
# 3.停止

# 1.增加内存限制启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
# 2.查看内存消耗
docker stats 容器id

三、可视化工具

Docker图形化界面管理工具!提供一个后台面板供我们操作!

1. portainer

docker run -d -p 8088:9000 \
> --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

内网测试
curl localhost:8088

外网测试
在这里插入图片描述
可能遇到的错误:
在这里插入图片描述
在portainer容器启动五分钟后,还没有创建管理员账号,portainer容器就会自动关闭。重新启动就好了。

在这里插入图片描述
在这里插入图片描述

2. Rancher(CI/CD)

四、Docker镜像

1. 镜像是什么?

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

所有应用,直接打包docker镜像,就可以直接跑起来!

如何得到镜像

  • 从远程仓库下载
  • 别人拷贝给你
  • 自己制作一个镜像 DockerFile

2. Docker镜像加载原理

2.1 UnionFs (联合文件系统)

UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

2.2 Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。
在这里插入图片描述
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?

在这里插入图片描述
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs.

虚拟机是分钟级别,容器是秒级!

3.分层理解

分层的镜像

我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载

在这里插入图片描述

思考:为什么Docker镜像要采用这种分层的结构呢?

最大的好处,我觉得莫过于==资源共享==了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

查看镜像分层的方式可以通过docker image inspect 命令

docker image inspect redis          

[
    {
        "Id": "sha256:f9b9909726890b00d2098081642edf32e5211b7ab53563929a47f250bcdc1d7c",
        "RepoTags": [
            "redis:latest"
        ],
        "RepoDigests": [
            "redis@sha256:399a9b17b8522e24fbe2fd3b42474d4bb668d3994153c4b5d38c3dafd5903e32"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2020-05-02T01:40:19.112130797Z",
        "Container": "d30c0bcea88561bc5139821227d2199bb027eeba9083f90c701891b4affce3bc",
        "ContainerConfig": {
            "Hostname": "d30c0bcea885",
            "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.0.1",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz",
                "REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"redis-server\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "18.09.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "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.0.1",
                "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.1.tar.gz",
                "REDIS_DOWNLOAD_SHA=b8756e430479edc162ba9c44dc89ac394316cd482f2dc6b91bcd5fe12593f273"
            ],
            "Cmd": [
                "redis-server"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:704c602fa36f41a6d2d08e49bd2319ccd6915418f545c838416318b3c29811e0",
            "Volumes": {
                "/data": {}
            },
            "WorkingDir": "/data",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 104101893,
        "VirtualSize": 104101893,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/adea96bbe6518657dc2d4c6331a807eea70567144abda686588ef6c3bb0d778a/diff:/var/lib/docker/overlay2/66abd822d34dc6446e6bebe73721dfd1dc497c2c8063c43ffb8cf8140e2caeb6/diff:/var/lib/docker/overlay2/d19d24fb6a24801c5fa639c1d979d19f3f17196b3c6dde96d3b69cd2ad07ba8a/diff:/var/lib/docker/overlay2/a1e95aae5e09ca6df4f71b542c86c677b884f5280c1d3e3a1111b13644b221f9/diff:/var/lib/docker/overlay2/cd90f7a9cd0227c1db29ea992e889e4e6af057d9ab2835dd18a67a019c18bab4/diff",
                "MergedDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/merged",
                "UpperDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/diff",
                "WorkDir": "/var/lib/docker/overlay2/afa1de233453b60686a3847854624ef191d7bc317fb01e015b4f06671139fb11/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:c2adabaecedbda0af72b153c6499a0555f3a769d52370469d8f6bd6328af9b13",
                "sha256:744315296a49be711c312dfa1b3a80516116f78c437367ff0bc678da1123e990",
                "sha256:379ef5d5cb402a5538413d7285b21aa58a560882d15f1f553f7868dc4b66afa8",
                "sha256:d00fd460effb7b066760f97447c071492d471c5176d05b8af1751806a1f905f8",
                "sha256:4d0c196331523cfed7bf5bafd616ecb3855256838d850b6f3d5fba911f6c4123",
                "sha256:98b4a6242af2536383425ba2d6de033a510e049d9ca07ff501b95052da76e894"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

理解:

所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点.

在这里插入图片描述

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

在这里插入图片描述
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。

在这里插入图片描述

这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统

Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的文件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。

Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。

下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。

在这里插入图片描述

特点

Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层!

在这里插入图片描述

4. commit镜像

# 提交容器成为一个新的副本
docker commit 

# 命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]

实战测试:

  1. 启动一个默认tomcat
  2. 默认tomcat没有webapps应用
  3. 自己拷贝了基本的文件
# 1、启动一个默认的tomcat
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker run -d -p 8080:8080 tomcat
de57d0ace5716d27d0e3a7341503d07ed4695ffc266aef78e0a855b270c4064e

# 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的!
#docker exec -it 容器id /bin/bash
[root@iz2zeak7sgj6i7hrb2g862z ~]# docker exec -it de57d0ace571 /bin/bash
root@de57d0ace571:/usr/local/tomcat# 

# 3、从webapps.dist拷贝文件进去webapp
root@de57d0ace571:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@de57d0ace571:/usr/local/tomcat# cd webapps
root@de57d0ace571:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

# 4、将操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,而不需要每次都重新拷贝webapps.dist下的文件到webapps了,这就是我们自己的一个修改的镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="xiaohang" -m="add webapps app" 容器id tomcat02:1.0

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker commit -a="csp提交的" -m="add webapps app" de57d0ace571 tomcat02.1.0
sha256:d5f28a0bb0d0b6522fdcb56f100d11298377b2b7c51b9a9e621379b01cf1487e

[root@iz2zeak7sgj6i7hrb2g862z ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
tomcat02.1.0          latest              d5f28a0bb0d0        14 seconds ago      652MB
tomcat                latest              1b6b1fe7261e        5 days ago          647MB
nginx                 latest              9beeba249f3e        5 days ago          127MB
mysql                 5.7                 b84d68d0a7db        5 days ago          448MB
elasticsearch         7.6.2               f29a1ee41030        8 weeks ago         791MB
portainer/portainer   latest              2869fc110bf7        2 months ago        78.6MB
centos                latest              470671670cac        4 months ago        237MB
hello-world           latest              bf756fb1ae65        4 months ago        13.3kB

五、容器数据卷

1. 什么是容器数据卷?

将应用和环境打包成一个镜像!

数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!

需求:==数据可以持久化==

MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!

容器之间可以有一个==数据共享==的技术!Docker容器中产生的数据,==同步==到本地!

这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!

总结一句话:==容器的持久化和同步操作!容器间也是可以数据共享的!==

2. 使用容器数据卷

1.方式一:直接使用命令来挂载 -v

docker run -it -v 主机目录:容器内目录

测试:
[root@VM-24-12-centos ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@756b8fb5faa6 /]# [root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND             CREATED          STATUS          PORTS                                       NAMES
756b8fb5faa6   centos                "/bin/bash"         29 seconds ago   Up 28 seconds                                               modest_elbakyan
7cf1763a18b1   portainer/portainer   "/portainer"        26 hours ago     Up 26 hours     0.0.0.0:8088->9000/tcp, :::8088->9000/tcp   adoring_knuth
797b64907651   tomcat:9.0            "catalina.sh run"   2 days ago       Up 42 minutes   0.0.0.0:80->8080/tcp, :::80->8080/tcp       tomcat03
[root@VM-24-12-centos ~]# docker inspect 756b8fb5faa6
"Mounts": [
            {
                "Type": "bind",
                "Source": "/home/ceshi",    # 主机内地址
                "Destination": "/home",     # docker容器内地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

测试文件的同步

在这里插入图片描述

再来测试!

1、停止容器

2、宿主机修改文件

3、启动容器

4、容器内的数据依旧是同步的

在这里插入图片描述

好处:我们以后修改只需要在本地修改即可,容器内会自动同步!

3. 实战:安装MySQL

[root@VM-24-12-centos ~]# docker pull mysql:5.7

-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@VM-24-12-centos ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql03 mysql:5.7

测试连接(别忘了开放安全组)

假设我们将包含mysql的容器删除时,发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能。

4. 具名和匿名挂载

4.1 匿名挂载

# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有的volume的情况
docker volume ls


[root@VM-24-12-centos data]# docker volume ls
DRIVER    VOLUME NAME
local     5e138dd9c45a0042eda0968e4c1392eeff7ff95b9045a2ddcd84a9bf034113f4
local     e157c4fe4cf611bc35ea7f71025d0bc1c59b11d09887a2a6c30e5d90d5c43922


# 这里发现,我们在 -v 只写的容器内的路径,没有写容器外的路径!那么究竟挂载到哪个地方呢?

4.2 具名挂载(推荐)

# 具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

[root@VM-24-12-centos data]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx

通过 -v 卷名:容器内路径


查看一下,挂载的地方:
[root@VM-24-12-centos data]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2022-04-21T09:20:48+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]
得出结论
所有的docker容器内的卷,没有指定目录的情况下都是在 
/var/lib/docker/volumes/xxx/_data

我们进入对应的目录:
[root@VM-24-12-centos data]# cd /var/lib/docker/volumes/
[root@VM-24-12-centos volumes]# ls
5e138dd9c45a0042eda0968e4c1392eeff7ff95b9045a2ddcd84a9bf034113f4  backingFsBlockDev  e157c4fe4cf611bc35ea7f71025d0bc1c59b11d09887a2a6c30e5d90d5c43922  juming-nginx  metadata.db

=> 我们通过具名挂载可以方便的找到我们的一个卷,大多数情况推荐使用:具名挂载

# 如何确定是具名挂载、匿名挂载、指定路径挂载!
-v 容器内路径                   # 匿名挂载
-v 卷名:容器内路径                # 具名挂载
-v /宿主机路径:容器内路径        # 指定路径挂载

拓展:

通过 -v 容器内路径:ro/rw  改变读写权限
ro read only     # 只读(只有宿主机可操作)
rw readwrite     # 可读可写

docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx:ro nginx

5. 初识Dockerfile

Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层!

# 新建测试目录
[root@VM-24-12-centos ~]# cd /home
[root@VM-24-12-centos home]# mkdir /home/docker-test-volume
[root@VM-24-12-centos home]# cd docker-test-volume/
[root@VM-24-12-centos docker-test-volume]# pwd
/home/docker-test-volume
## 创建一个dockerfile文件,名字可以随机
[root@VM-24-12-centos docker-test-volume]# vim dockerfile1

## 文件中的内容
    FROM centos                     # 当前这个镜像是以centos为基础的

    VOLUME ["volume01","volume02"]     # 挂载卷的卷目录列表(多个目录)

    CMD echo "-----end-----"        # 输出一下用于测试
    CMD /bin/bash                    # 默认走bash控制台
##
# 这里的每个命令,就是镜像的一层!


# 构建出这个镜像 
-f dockerfile1             # f代表file,指这个当前文件的地址(这里是当前目录下的dockerfile1)
-t xiaohang/centos     # t就代表target,指目标目录(注意xiaohang镜像名前不能加斜杠‘/’)
.                         # 表示生成在当前目录下
docker build -f dockerfile1 -t xiaohang/centos .

# 生成自己的镜像
[root@VM-24-12-centos docker-test-volume]# docker build -f dockerfile1 -t xiaohang/centos .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in 5e1b9b47c35a
Removing intermediate container 5e1b9b47c35a
 ---> 8f41c19d3c3f
Step 3/4 : CMD echo "----end-----"
 ---> Running in f6e32a9e0fbe
Removing intermediate container f6e32a9e0fbe
 ---> 06d3158c96d5
Step 4/4 : CMD /bin/bash
 ---> Running in 6909b1600a15
Removing intermediate container 6909b1600a15
 ---> f36fc725be93
Successfully built f36fc725be93
Successfully tagged xiaohang/centos:latest

## 查看自己生成的镜像
[root@VM-24-12-centos docker-test-volume]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
xiaohang/centos       latest    f36fc725be93   52 seconds ago   231MB

## 启动自己写的镜像
[root@VM-24-12-centos docker-test-volume]# docker run -it f36fc725be93 /bin/bash
[root@66ad7f7b420b /]# ll    (注意ll没有)
bash: ll: command not found
[root@66ad7f7b420b /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  360 Apr 21 07:13 dev
drwxr-xr-x   1 root root 4096 Apr 21 07:13 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15  2021 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 139 root root    0 Apr 21 07:13 proc
dr-xr-x---   2 root root 4096 Sep 15  2021 root
drwxr-xr-x  11 root root 4096 Sep 15  2021 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Apr 21 07:13 sys
drwxrwxrwt   7 root root 4096 Sep 15  2021 tmp
drwxr-xr-x  12 root root 4096 Sep 15  2021 usr
drwxr-xr-x  20 root root 4096 Sep 15  2021 var
drwxr-xr-x   2 root root 4096 Apr 21 07:13 volume01
drwxr-xr-x   2 root root 4096 Apr 21 07:13 volume02
## 最后这两个目录就是我们生成镜像的时候自动挂载的,数据卷目录

思考: 这个卷和外部一定有一个同步的目录!!!

匿名挂载:

## 文件中的内容
    ...
    VOLUME ["volume01","volume02"]     # 挂载卷的卷目录列表(多个目录)
    ...
##

## 查看一下卷挂载的路径:
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS         PORTS                                                  NAMES
fb03c0ac928e   f36fc725be93          "/bin/bash"              10 seconds ago   Up 9 seconds                                                          agitated_napier
48094937fd09   mysql:5.7             "docker-entrypoint.s…"   15 hours ago     Up 15 hours    33060/tcp, 0.0.0.0:3310->3306/tcp, :::3310->3306/tcp   mysql03
7cf1763a18b1   portainer/portainer   "/portainer"             3 days ago       Up 3 days      0.0.0.0:8088->9000/tcp, :::8088->9000/tcp              adoring_knuth
[root@VM-24-12-centos ~]# docker inspect fb03c0ac928e


"Mounts": [
            {
                "Type": "volume",
                "Name": "9fe1401672d9c3e97cdf28147fa6164da59bcf08a762de24a323180ced0de948",
                "Source": "/var/lib/docker/volumes/9fe1401672d9c3e97cdf28147fa6164da59bcf08a762de24a323180ced0de948/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "7c33e40060a3b2ae4e02f9748c46d011d5454ce7d6d109b47edc997b89069e94",
                "Source": "/var/lib/docker/volumes/7c33e40060a3b2ae4e02f9748c46d011d5454ce7d6d109b47edc997b89069e94/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

## 不难得出:这是匿名挂载

## 最后,我们测试一下刚才的文件是否同步出去:

### 容器内:
[root@fb03c0ac928e /]# cd /
.dockerenv  dev/        home/       lib64/      media/      opt/        root/       sbin/       sys/        usr/        volume01/   
bin/        etc/        lib/        lost+found/ mnt/        proc/       run/        srv/        tmp/        var/        volume02/ 
[root@fb03c0ac928e /]# cd /volume01
[root@fb03c0ac928e volume01]# touch container.txt

### 容器外:
[root@VM-24-12-centos ~]# cd /var/lib/docker/volumes/9fe1401672d9c3e97cdf28147fa6164da59bcf08a762de24a323180ced0de948/_data
[root@VM-24-12-centos _data]# ls
container.txt

## 同步成功!

6. 数据卷容器

在这里插入图片描述

# 启动三个容器测试
[root@VM-24-12-centos ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
xiaohang/centos       latest    f36fc725be93   20 hours ago    231MB

# 启动第一个容器:
[root@VM-24-12-centos ~]# docker run -it --name docker01 xiaohang/centos
[root@fe47b170c766 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02

Ctrl + P + Q(退出不结束)
[root@fe47b170c766 /]# [root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED              STATUS              PORTS     NAMES
fe47b170c766   xiaohang/centos   "/bin/sh -c /bin/bash"   About a minute ago   Up About a minute             docker01

# 启动第二个容器
[root@VM-24-12-centos ~]#  docker run -it --name docker02 --volumes-from docker01 xiaohang/centos
[root@280b39ca806f /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02

# 启动第二个容器
[root@VM-24-12-centos ~]#  docker run -it --name docker03 --volumes-from docker01 xiaohang/centos
[root@280b39ca806f /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02


# 进入容器一,创建docker01.txt
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS     NAMES
280b39ca806f   xiaohang/centos   "/bin/sh -c /bin/bash"   11 minutes ago   Up 11 minutes             docker02
fe47b170c766   xiaohang/centos   "/bin/sh -c /bin/bash"   15 minutes ago   Up 15 minutes             docker01
[root@VM-24-12-centos ~]# docker exec -it fe47b170c766 /bin/bash
[root@fe47b170c766 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02
[root@fe47b170c766 /]# cd volume01
[root@fe47b170c766 volume01]# ls
[root@fe47b170c766 volume01]# touch docker01.txt
[root@fe47b170c766 volume01]# ls
docker01.txt

# 进入容器二,查看是否有docker02.txt
[root@280b39ca806f /]# ls     
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01  volume02
[root@280b39ca806f /]# cd volume01
[root@280b39ca806f volume01]# ls
docker01.txt

## 测试删除docker01,docker02,docker03还可以继续访问。

在这里插入图片描述
多个MySQL实现数据共享:

$ docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

$ docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01  mysql:5.7

# 这个时候,可以实现两个容器数据同步!

结论:

  • 容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
  • 但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

7. Dockerfile

Dockerfile是用来构建docker镜像的文件!(命令参数脚本)

7.1 构建步骤

  1. 编写一个dockerfile文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云仓库)

在这里插入图片描述
在这里插入图片描述

很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!

官方既然可以制作镜像,那我们也可以!

7.2 Dockerfile构建过程

7.2.1 基础知识:

1、每个保留关键字(指令)都是必须是大写字母

2、执行从上到下顺序

3、#表示注释

4、每一个指令都会创建提交一个新的镜像曾,并提交!

在这里插入图片描述
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

Docker镜像逐渐成企业交付的标准,必须要掌握!

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。

Docker容器:容器就是镜像运行起来提供服务。

7.2.2 Dockerfile的指令

FROM                # from:基础镜像,一切从这里开始构建
MAINTAINER            # maintainer:镜像是谁写的, 姓名+邮箱
RUN                    # run:镜像构建的时候需要运行的命令
ADD                    # add:步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR                # workdir:镜像的工作目录
VOLUME                # volume:挂载的目录
EXPOSE                # expose:保留端口配置
CMD                    # cmd:指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT            # entrypoint:指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD                # onbuild:当构建一个被继承DockerFile这个时候就会运行onbuild的指令,触发指令
COPY                # copy:类似ADD,将我们文件拷贝到镜像中
ENV                    # env:构建的时候设置环境变量!

在这里插入图片描述
以前的话我们就是使用别人的,现在我们知道了这些指令后,我们来练习自己写一个镜像!

7.2.3 实战测试

创建自己的一个centos
# 1./home下新建dockerfile目录
$ mkdir dockerfile

# 2. dockerfile目录下新建mydockerfile-centos文件
$ vim mydockerfile-centos

# 3.编写Dockerfile配置文件
FROM centos                            # 基础镜像是官方原生的centos
MAINTAINER xiaohang<1531137510@qq.com>     # 作者

ENV MYPATH /usr/local                # 配置环境变量的目录 
WORKDIR $MYPATH                        # 将工作目录设置为 MYPATH

RUN yum -y install vim                # 给官方原生的centos 增加 vim指令
RUN yum -y install net-tools        # 给官方原生的centos 增加 ifconfig命令

EXPOSE 80                            # 暴露端口号为80

CMD echo $MYPATH                    # 输出下 MYPATH 路径
CMD echo "-----end----"                
CMD /bin/bash                        # 启动后进入 /bin/bash

# 4.通过这个文件构建镜像
# 命令: docker build -f 文件路径 -t 镜像名:[tag] .
$ docker build -f mydockerfile-centos -t mycentos:0.1 .

# 5.出现下图后则构建成功

在这里插入图片描述

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mycentos            0.1                 cbf5110a646d        2 minutes ago       311MB

# 6.测试运行
$ docker run -it mycentos:0.1         # 注意带上版本号,否则每次都回去找最新版latest

$ pwd    
/usr/local                            # 与Dockerfile文件中 WORKDIR 设置的 MYPATH 一致
$ vim                                # vim 指令可以使用
$ ifconfig                             # ifconfig 指令可以使用

# docker history 镜像id 查看镜像构建历史步骤
$ docker history 镜像id

[root@VM-24-12-centos dockerfile]# docker history 605c77e624dd
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
605c77e624dd   3 months ago   /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B        
<missing>      3 months ago   /bin/sh -c #(nop)  STOPSIGNAL SIGQUIT           0B        
<missing>      3 months ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["/docker-entr…   0B        
<missing>      3 months ago   /bin/sh -c #(nop) COPY file:09a214a3e07c919a…   4.61kB    
<missing>      3 months ago   /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7…   1.04kB    
<missing>      3 months ago   /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0…   1.96kB    
<missing>      3 months ago   /bin/sh -c #(nop) COPY file:65504f71f5855ca0…   1.2kB     
<missing>      3 months ago   /bin/sh -c set -x     && addgroup --system -…   61.1MB    
<missing>      3 months ago   /bin/sh -c #(nop)  ENV PKG_RELEASE=1~bullseye   0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENV NJS_VERSION=0.7.1        0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENV NGINX_VERSION=1.21.5     0B        
<missing>      4 months ago   /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B        
<missing>      4 months ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      4 months ago   /bin/sh -c #(nop) ADD file:09675d11695f65c55…   80.4MB 


我们平时拿到一个镜像,可以用 “docker history 镜像id” 研究一下是什么做的

7.2.4 CMD 和 ENTRYPOINT

CMD          # 指定这个容器启动的时候要运行的命令,只有最后一个生效,可被替代
ENTRYPOINT     # 指定这个容器启动的时候要运行的命令,可以追加命令

测试CMD:

[root@VM-24-12-centos dockerfile]# vim dockerfile-cmd-test

FROM centos
CMD ["ls","-a"]

[root@VM-24-12-centos dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:0.1 .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
 ---> Running in 064c77f9e8b2
Removing intermediate container 064c77f9e8b2
 ---> 3594071968fc
Successfully built 3594071968fc
Successfully tagged cmdtest:0.1

# 运行镜像
$ docker run cmd-test:0.1        # 由结果可得,运行后就执行了 ls -a 命令
.
..
.dockerenv
bin
dev
etc
home

## 想追加一个命令 -l    执行ls -al命令
[root@VM-24-12-centos dockerfile]# docker run 279bb7d5f91f -l
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 

## cmd情况下, -l 替换了CMD["ls","-a"]命令,-l不是命令,所以报错!

[root@VM-24-12-centos dockerfile]# docker run 279bb7d5f91f ls -al
total 56
drwxr-xr-x   1 root root 4096 Apr 23 06:18 .
drwxr-xr-x   1 root root 4096 Apr 23 06:18 ..
-rwxr-xr-x   1 root root    0 Apr 23 06:18 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Apr 23 06:18 dev
drwxr-xr-x   1 root root 4096 Apr 23 06:18 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
drwx------   2 root root 4096 Sep 15  2021 lost+found
drwxr-xr-x   2 root root 4096 Nov  3  2020 media
drwxr-xr-x   2 root root 4096 Nov  3  2020 mnt
drwxr-xr-x   2 root root 4096 Nov  3  2020 opt
dr-xr-xr-x 136 root root    0 Apr 23 06:18 proc
dr-xr-x---   2 root root 4096 Sep 15  2021 root
drwxr-xr-x  11 root root 4096 Sep 15  2021 run
lrwxrwxrwx   1 root root    8 Nov  3  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3  2020 srv
dr-xr-xr-x  13 root root    0 Apr 21 07:13 sys
drwxrwxrwt   7 root root 4096 Sep 15  2021 tmp
drwxr-xr-x  12 root root 4096 Sep 15  2021 usr
drwxr-xr-x  20 root root 4096 Sep 15  2021 var

测试Entrypoint:

[root@VM-24-12-centos dockerfile]# vim dockerfile-entrypoint-test

FROM centos
ENTRYPOINT ["ls","-a"]

[root@VM-24-12-centos dockerfile]# docker build -f dockerfile-entrypoint-test -t entrypoint-test .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in b4677105ef8d
Removing intermediate container b4677105ef8d
 ---> f8b8ec376712
Successfully built f8b8ec376712
Successfully tagged entrypoint-test:latest
[root@VM-24-12-centos dockerfile]# docker run f8b8ec376712
.
..
.dockerenv
bin
dev
etc
home
lib
...
[root@VM-24-12-centos dockerfile]# docker run f8b8ec376712 -l
total 56
drwxr-xr-x   1 root root 4096 Apr 23 06:28 .
drwxr-xr-x   1 root root 4096 Apr 23 06:28 ..
-rwxr-xr-x   1 root root    0 Apr 23 06:28 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Apr 23 06:28 dev
drwxr-xr-x   1 root root 4096 Apr 23 06:28 etc
drwxr-xr-x   2 root root 4096 Nov  3  2020 home
lrwxrwxrwx   1 root root    7 Nov  3  2020 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3  2020 lib64 -> usr/lib64
...

7.2.5 实战-Tomcat镜像

1、准备镜像文件 tomcat压缩包,jdk的压缩包!

在这里插入图片描述
2、编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,就不需要-f指定了!

FROM centos:7      # 基础镜像centos:7
MAINTAINER xiaohang<1531137510@qq.com>   # 作者信息

COPY readme.txt /usr/local/readme.txt   

ADD jdk-8u271-linux-x64.tar.gz /usr/local/    # 添加JDK,ADD会自动解压
ADD apache-tomcat-9.0.62.tar.gz /usr/local/  # 添加Tomcat

RUN yum -y install vim   # 安装VIM命令

ENV MYPATH /usr/local    # 环境变量设置 工作目录
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_271   # JAVA_HOME 环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.62  # Tomcat 环境变量
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.62

# 设置环境变量,分隔符为:
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:CATALINA_HOME/bin

EXPOSE 8080  # 设置暴露的端口

CMD /usr/local/apache-tomcat-9.0.62/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.62/bin/logs/catalina.out

可能会遇到的错:

CentOS Linux 8 - AppStream                      1.6  B/s |  38  B     00:24    
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
The command '/bin/sh -c yum -y install vim' returned a non-zero code: 1


请指定Centos版本7

3、构建镜像

# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件
docker build -t diytomcat .

4、启动镜像

# -d:后台运行 -p:暴露端口 --name:别名 -v:绑定路径 
docker run -d -p 8080:8080 --name tomcat01 
-v /home/tomcat/test:/usr/local/apache-tomcat-9.0.62/webapps/test 
-v /home/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.62/logs mytomcat:0.1

5、访问测试

$ docker exec -it 自定义容器的id /bin/bash

$ cul localhost:8080

6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)

发现:项目部署成功,可以直接访问!

我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!

7.2.6 发布自己的镜像

DockerHub

1、地址 https://hub.docker.com/

2、确定这个账号可以登录

3、登录

$ docker login --help
Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

$ docker login -u 你的用户名 -p 你的密码

4、提交 push镜像

docker push mytomcat

# 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library
# 解决方法:
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t xiaohang/mytomcat:0.1 .

# 第二种 使用docker tag #然后再次push
$ docker tag 容器id xiaohang/mytomcat:1.0 #然后再次push
$ docker push xiaohang/mytomcat:1.0

7.2.7 发布到阿里云镜像服务上

  1. 登录阿里云,找到容器镜像服务(https://cr.console.aliyun.com/cn-hangzhou/instance/repositories
  2. 找到命名空间

在这里插入图片描述

  1. 创建镜像仓库

在这里插入图片描述
在这里插入图片描述
4.看文档

docker logout  退出当前登录的账号

8. Docker小结:

在这里插入图片描述

六、Docker网络

1、理解Docker0

清空所有容器
docker rm -f $(docker ps -aq)
清空所有镜像
docker rmi -f $(docker images -aq)

测试:

[root@VM-24-12-centos ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 52:54:00:49:d1:3b brd ff:ff:ff:ff:ff:ff
    inet 10.0.24.12/22 brd 10.0.27.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe49:d13b/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:0e:e5:eb:26 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:eff:fee5:eb26/64 scope link 
       valid_lft forever preferred_lft forever

在这里插入图片描述
三个网络:

问题:Docker是如何处理容器网络访问的?
在这里插入图片描述
# 测试  运行一个tomcat
$ docker run -d -P --name tomcat01 tomcat

# 查看容器内部网络地址
$ docker exec -it 容器id ip addr

# 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker分配!
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

       
# 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
$ ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.074 ms
原理

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

关于veth-pair的介绍,你需要了解这些!

再次测试 ip addr

在这里插入图片描述
2 、再启动一个容器测试,发现又多了一对网络

在这里插入图片描述

# 我们发现这个容器带来网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术

3、我们来测试下tomcat01和tomcat02是否可以ping通

# 获取tomcat01的ip 172.17.0.2
$ docker-tomcat docker exec -it tomcat01 ip addr  
550: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
       
# 让tomcat02 ping tomcat01       
$ docker-tomcat docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms

# 结论:容器和容器之间是可以互相ping通
网络模型图

在这里插入图片描述
结论:tomcat01和tomcat02公用一个路由器,docker0。

所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。

小结

Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
在这里插入图片描述
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只要容器删除,对应的网桥一对就没了!

思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?

2、- - Link

思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
$ docker exec -it tomcat02 ping tomca01   # ping不通
ping: tomca01: Name or service not known

# 运行一个tomcat03 --link tomcat02 
$ docker run -d -P --name tomcat03 --link tomcat02 tomcat
5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef

# 3连接2
# 用tomcat03 ping tomcat02 可以ping通
$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms

# 2连接3
# 用tomcat02 ping tomcat03 ping不通

探究:

docker network inspect 网络id 网段相同
在这里插入图片描述
docker inspect tomcat03
在这里插入图片描述

查看tomcat03里面的/etc/hosts发现有tomcat02的配置

在这里插入图片描述
–link 本质就是在hosts配置中添加映射

现在使用Docker已经不建议使用–link了!

自定义网络,不适用docker0!

docker0问题:不支持容器名连接访问!

3、自定义网络

查看所有的docker网络

[root@VM-24-12-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
000f0b7bb122   bridge    bridge    local
46dc3c551551   host      host      local
2dea6558d00c   none      null      local

网络模式:

  • bridge:桥接docker(默认,自己创建也使用这个)
  • none:不配置网络
  • host:和宿主机共享网络
  • container:容器网络连通!(用的少!)
## 我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 -net bridge tomcat

## docker0特点:默认,域名不能访问,--link可以打通连接!

## 我们可以自定义一个网络:(想想自己家里的路由器)
## --driver bridge
## --subnet 192.168.0.0/16
## --gateway 192.168.0.1
[root@VM-24-12-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
00496e0f79c1a09cd4f632e010d1d572a3c5eb77400e6e14c6dc671824337287
[root@VM-24-12-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
000f0b7bb122   bridge    bridge    local
46dc3c551551   host      host      local
00496e0f79c1   mynet     bridge    local

## 查看自己定义的网络
[root@VM-24-12-centos ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "00496e0f79c1a09cd4f632e010d1d572a3c5eb77400e6e14c6dc671824337287",
        "Created": "2022-04-27T20:58:09.144161755+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

## 用自己的网络启动
[root@VM-24-12-centos ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
39a25939ca7d17005c6a3a840fc20f671ae73138d6899617dd08b7b6fba354b8
[root@VM-24-12-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
b9a6da9e634209752e9dee02b3bd9a83beda040ffc420a23f7e02b401fd633be

## 再次查看自定义网络
[root@VM-24-12-centos ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "00496e0f79c1a09cd4f632e010d1d572a3c5eb77400e6e14c6dc671824337287",
        "Created": "2022-04-27T20:58:09.144161755+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "39a25939ca7d17005c6a3a840fc20f671ae73138d6899617dd08b7b6fba354b8": {
                "Name": "tomcat-net-01",
                "EndpointID": "4b6d064f9b6b0f56bc0224c4c9d71ec53864e1c66ca88e7f31af04535c9aae78",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "b9a6da9e634209752e9dee02b3bd9a83beda040ffc420a23f7e02b401fd633be": {
                "Name": "tomcat-net-02",
                "EndpointID": "b3b0ecb8e8b143f2160bd044ac9d362f4dfccef517dac727bf02021f74cdc449",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
在自定义的网络下,服务可以互相ping通,不用使用–link

在这里插入图片描述

好处:

  • redis -不同的集群使用不同的网络,保证集群是安全和健康的
  • mysql-不同的集群使用不同的网络,保证集群是安全和健康的

在这里插入图片描述

4、部署Redis集群

在这里插入图片描述

# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个redis配置
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >> /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

# 创建结点1
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
 
#创建结点2
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点3
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点4
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 查看镜像
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                                                                                      NAMES
869a6ce9f6b0   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   2 seconds ago    Up 1 second     0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
2ead11d175ce   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 seconds ago    Up 9 seconds    0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
349c9d30b905   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   16 seconds ago   Up 16 seconds   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
e534ebf30369   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   23 seconds ago   Up 23 seconds   0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
847746759c29   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   31 seconds ago   Up 30 seconds   0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
b08ea8b5184e   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   48 seconds ago   Up 48 seconds   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1

#创建集群
[root@VM-24-12-centos ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379
   replicates 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7
S: f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379
   replicates 7b7f474f5deb841ed789af0d2cd3a7294c1bac98
S: 4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379
   replicates 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 7b7f474f5deb841ed789af0d2cd3a7294c1bac98
S: 32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7
S: 4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379
   slots: (0 slots) slave
   replicates 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

# docker 搭建redis集群完成
/data # redis-cli -c
172.38.0.13:6379> set a b
OK
172.38.0.13:6379> get a
"b"
172.38.0.13:6379> cluster nodes
32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379@16379 slave 8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 0 1651130873827 4 connected
4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379@16379 master - 0 1651130875530 2 connected 5461-10922
f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379@16379 slave 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 0 1651130875530 5 connected
8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379@16379 myself,master - 0 1651130874000 3 connected 10923-16383
4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379@16379 slave 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 0 1651130875830 6 connected
7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379@16379 master - 0 1651130874528 1 connected 0-5460

# 现在我们模拟宕机,挂掉当前的master
[root@VM-24-12-centos ~]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED         STATUS         PORTS                                                                                      NAMES
869a6ce9f6b0   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes   0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
2ead11d175ce   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 minutes ago   Up 9 minutes   0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
349c9d30b905   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 minutes ago   Up 9 minutes   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
e534ebf30369   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 minutes ago   Up 9 minutes   0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp   redis-3
847746759c29   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 minutes ago   Up 9 minutes   0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
b08ea8b5184e   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   9 minutes ago   Up 9 minutes   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1
[root@VM-24-12-centos ~]# docker stop redis-3
redis-3
# 当前容器成功挂掉
172.38.0.13:6379> get a
^C
# 重新获取 get a
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379> cluster nodes
8c1aa2186c3cd0e4122766a77b13f7cc7c91aaf7 172.38.0.13:6379@16379 master,fail - 1651131226581 1651131225780 3 connected
32b72ace218af7196f8a1761a3676efc5642a03b 172.38.0.14:6379@16379 myself,master - 0 1651131291000 7 connected 10923-16383
4f108a64c4db7b5d274a5de1d9b6292dac9a371c 172.38.0.16:6379@16379 slave 4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 0 1651131291892 6 connected
f8337c9e18eafbc183b60738ea3410de5f0c55fd 172.38.0.15:6379@16379 slave 7b7f474f5deb841ed789af0d2cd3a7294c1bac98 0 1651131290590 5 connected
4dbe130bd240fb1d4ca9023b3e32d22e2b379c40 172.38.0.12:6379@16379 master - 0 1651131291592 2 connected 5461-10922
7b7f474f5deb841ed789af0d2cd3a7294c1bac98 172.38.0.11:6379@16379 master - 0 1651131291000 1 connected 0-5460

七、SpringBoot微服务打包Docker镜像

  1. 构建SpringBoot项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 编写Dockerfile
FROM java:8
 
COPY *.jar /app.jar
 
CMD ["--server.port=8080"]
 
EXPOSE 8080
 
ENTRYPOINT ["java", "-jar", "/app.jar"]
  1. 构建镜像
# 把打好的jar包和Dockerfile上传到linux
[root@VM-24-12-centos ceshi]# ll
总用量 17136
-rw-r--r-- 1 root root 17542922 4月  28 16:39 demo-0.0.1-SNAPSHOT.jar
-rw-r--r-- 1 root root      124 4月  28 16:38 Dockerfile

# 构建镜像,不要忘了最后有一个点
[root@VM-24-12-centos ceshi]# docker build -t xiaohang .
Sending build context to Docker daemon  17.55MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete 
fce5728aad85: Pull complete 
76610ec20bf5: Pull complete 
60170fec2151: Pull complete 
e98f73de8f0d: Pull complete 
11f7af24ed9c: Pull complete 
49e2d6393f32: Pull complete 
bb9cdec9c7f3: Pull complete 
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> 18cfc3f88a7f
Step 3/5 : CMD ["--server.port=8080"]
 ---> Running in 429a00e60898
Removing intermediate container 429a00e60898
 ---> ccd6f998893a
Step 4/5 : EXPOSE 8080
 ---> Running in 9f6841a10f25
Removing intermediate container 9f6841a10f25
 ---> 3050a62735ad
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
 ---> Running in 5b4c19329c96
Removing intermediate container 5b4c19329c96
 ---> e3f233220c0c
Successfully built e3f233220c0c
Successfully tagged xiaohang:latest
[root@VM-24-12-centos ceshi]# docker images
REPOSITORY   TAG                IMAGE ID       CREATED          SIZE
xiaohang     latest             e3f233220c0c   43 seconds ago   661MB
redis        5.0.9-alpine3.11   3661c84ee9d0   2 years ago      29.8MB
java         8                  d23bdf5b1b1b   5 years ago      643MB
[root@VM-24-12-centos ceshi]# docker run -d -P --name xiaohang-web xiaohang
9d433ae3ba3290438bac32065071b6360e3db9d58af5df0187dd9c07cedd8832
[root@VM-24-12-centos ceshi]# docker ps
CONTAINER ID   IMAGE                    COMMAND                  CREATED             STATUS             PORTS                                                                                      NAMES
9d433ae3ba32   xiaohang                 "java -jar /app.jar …"   5 seconds ago       Up 4 seconds       0.0.0.0:49157->8080/tcp, :::49157->8080/tcp                                                xiaohang-web
869a6ce9f6b0   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp   redis-6
2ead11d175ce   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp   redis-5
349c9d30b905   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp   redis-4
847746759c29   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp   redis-2
b08ea8b5184e   redis:5.0.9-alpine3.11   "docker-entrypoint.s…"   About an hour ago   Up About an hour   0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp   redis-1
[root@VM-24-12-centos ceshi]# curl localhost:8080
hello xiaohang!
  1. 发布运行

八、DockerCompose

1、简介

之前我们是:DockerFile -> build -> run 手动操作,单个容器!

现在我们有很多微服务,使用Docker Compose来轻松高效的管理容器,定义多个容器。

官方介绍
  • 定义、运行多个容器。
  • YAML file 配置文件
  • single command 命令有哪些?

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

  • 所有环境都可以使用 Compose。

Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.

  • 三步骤:

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
  • Dockerfile保证我们的项目在任何地方运行
  1. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  • services 什么服务。
  • docker-compose.yml 这个文件怎么写?
  1. Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.
  • 启动项目

作用:批量容器编排

个人理解

Compose是Docker官方开源的项目,需要安装!
Compose:

version: "3.9"  # optional since v1.27.0
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

重要的概念:

  • 服务:Services
  • 项目:project 一组关联的容器

2、安装

# 1、下载
# 国内地址
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
 
# 2、授权
sudo chmod +x /usr/local/bin/docker-compose
 
# 3、检查是否安装成功
docker-compose version

3、体验

官网示例

补充:(官网的例子无法通过测试)


app.py

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

requirements.txt

flask
redis

Dockerfile

FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
 
# 官网的用来flask框架,我们这里不用它
# 这告诉Docker
# 从python3.7开始构建镜像
# 将当前目录添加到/code印像中的路径中
# 将工作目录设置为/code
# 安装Python依赖项
# 将容器的默认命令设置为python app.py

docker-compose.yml

version: '3.8'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
  redis:
    image: "redis:alpine"

启动:

docker-compose up

流程:

  1. 创建网络
  2. 执行Docker-compose.yaml
  3. 启动服务

Docker小结:

  1. Docker镜像。 run => 容器
  2. DockerFile 构建镜像(服务打包)
  3. docker-compose 启动项目(编排、多个微服务/环境)
  4. Docker网络

4、yaml规则

docker-compose.yaml 核心!

官方文档

# 3层
version: '' # 版本
services: # 服务
    服务1: web
        # 服务配置
        images
        build
        network
        ......
    服务2: redis
        .....
    服务3: mysql
        .....
# 其他配置 网络/卷 全局规则
volumes:
networks:
configs

在这里插入图片描述

5、实战开源项目

一键搭建WordPress博客

官方示例

docker-compose up  启动
docker-compose down  停止

6、实战

1.初始化SpringBoot项目
在这里插入图片描述
配置文件:

在这里插入图片描述
2.编写Dockerfile文件构建镜像

在这里插入图片描述

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

3.docker-compose.yml编排项目

在这里插入图片描述

version: '3.8'
services:
  demoapp:
    build: .
    image: demoapp
    depends_on:
      - redis
    ports:
      - "8080:8080"
  redis:
    image: "library/redis:alpine"

4.丢到服务器,docker-compose up 编排启动

打包jar包
在这里插入图片描述
一定要检查一下jar包是否打包正确,4KB的那种,是因为maven没有配置插件,没把依赖打包进来。

紧接着,我们上传到服务器中:
在这里插入图片描述

[root@VM-24-12-centos home]# mkdir demoDcoker
[root@VM-24-12-centos home]# cd demoDcoker/
[root@VM-24-12-centos demoDcoker]# ls
[root@VM-24-12-centos demoDcoker]# ls
demo-0.0.1-SNAPSHOT.jar  docker-compose.yml  Dockerfile
[root@VM-24-12-centos demoDcoker]# docker-compose up
Creating network "demodcoker_default" with the default driver
Building demoapp
Step 1/5 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> 9642ca5cf204
Step 3/5 : CMD ["--server.port=8080"]
 ---> Running in d5c3d7311cb4
Removing intermediate container d5c3d7311cb4
 ---> c9e8a80cc852
Step 4/5 : EXPOSE 8080
 ---> Running in 7cd3844db211
Removing intermediate container 7cd3844db211
 ---> 8fadaa095ba1
Step 5/5 : ENTRYPOINT ["java", "-jar", "/app.jar"]
 ---> Running in ca5f1648bc5a
Removing intermediate container ca5f1648bc5a
 ---> d3d778d2f33f

Successfully built d3d778d2f33f
Successfully tagged demoapp:latest
WARNING: Image for service demoapp was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating demodcoker_redis_1 ... done
Creating demodcoker_demoapp_1 ... done
Attaching to demodcoker_redis_1, demodcoker_demoapp_1
redis_1    | 1:C 21 Jun 2022 03:35:13.790 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1    | 1:C 21 Jun 2022 03:35:13.790 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1    | 1:C 21 Jun 2022 03:35:13.790 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1    | 1:M 21 Jun 2022 03:35:13.791 * monotonic clock: POSIX clock_gettime
redis_1    | 1:M 21 Jun 2022 03:35:13.791 * Running mode=standalone, port=6379.
redis_1    | 1:M 21 Jun 2022 03:35:13.791 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1    | 1:M 21 Jun 2022 03:35:13.791 # Server initialized
redis_1    | 1:M 21 Jun 2022 03:35:13.791 # 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.
redis_1    | 1:M 21 Jun 2022 03:35:13.791 * Ready to accept connections
demoapp_1  | 
demoapp_1  |   .   ____          _            __ _ _
demoapp_1  |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
demoapp_1  | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
demoapp_1  |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
demoapp_1  |   '  |____| .__|_| |_|_| |_\__, | / / / /
demoapp_1  |  =========|_|==============|___/=/_/_/_/
demoapp_1  |  :: Spring Boot ::                (v2.4.1)
demoapp_1  | 
demoapp_1  | 2022-06-21 03:35:17.486  INFO 1 --- [           main] com.dockerdemo.DemoApplication           : Starting DemoApplication using Java 1.8.0_111 on da5653278dec with PID 1 (/app.jar started by root in /)
demoapp_1  | 2022-06-21 03:35:17.489  INFO 1 --- [           main] com.dockerdemo.DemoApplication           : No active profile set, falling back to default profiles: default
demoapp_1  | 2022-06-21 03:35:18.556  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
demoapp_1  | 2022-06-21 03:35:18.558  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
demoapp_1  | 2022-06-21 03:35:18.577  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
demoapp_1  | 2022-06-21 03:35:19.188  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
demoapp_1  | 2022-06-21 03:35:19.225  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
demoapp_1  | 2022-06-21 03:35:19.225  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.41]
demoapp_1  | 2022-06-21 03:35:19.291  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
demoapp_1  | 2022-06-21 03:35:19.291  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1666 ms
demoapp_1  | 2022-06-21 03:35:20.278  INFO 1 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
demoapp_1  | 2022-06-21 03:35:20.638  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
demoapp_1  | 2022-06-21 03:35:20.651  INFO 1 --- [           main] com.dockerdemo.DemoApplication           : Started DemoApplication in 4.093 seconds (JVM running for 6.056)

测试:
在这里插入图片描述
重新构建项目:

docker-compose up --build   # 重新部署!

总结:

  • 工程
  • 服务
  • 容器

九、DockerSwarm

1、集群

购买服务器(四台) => 搭建双主双从

工作机制:
在这里插入图片描述
官网直达

docker swarm init --help
 
ip addr # 获取自己的ip(用内网的不要流量)
 
[root@iZ2ze58v8acnlxsnjoulk5Z ~]# docker swarm init --advertise-addr 172.16.250.97
Swarm initialized: current node (otdyxbk2ffbogdqq1kigysj1d) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-3vovnwb5pkkno2i3u2a42yrxc1dk51zxvto5hrm4asgn37syfn-0xkrprkuyyhrx7cidg381pdir 172.16.250.97:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

初始化结点docker swarm init
docker swarm join 加入一个结点!

# 获取令牌
docker swarm join-token manager
docker swarm join-token worker

2、Raft协议

保证大多数节点存活才可以用。 至少要保证三个主节点

3、体会

弹性、扩缩容

容器 => 服务

灰度发布:金丝雀发布!

docker run  容器启动! 不具有扩缩容器
docker service  服务! 具有扩缩容器,滚动更新!

4、概念总结

1.swarm
集群的管理和编号,docker可以初始化一个swarm集群,其他节点可以加入。(身份:管理员、工作者)

2.Node
就是一个docker节点,多个节点组成了网络集群。

3.Service
任务,可以在管理节点或者工作节点来运行核心。

4.Task
容器内的命令,细节任务!

在这里插入图片描述

逻辑是不变的!

命令 -> 管理 -> API -> 调度 -> 工作节点(创建Task容器维护创建)

十、Docker Stack

十一、Docker Secret

十二、Docker Config

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
6月前
|
测试技术 网络安全 数据安全/隐私保护
【Docker项目实战】使用Docker部署Mininote轻量级笔记工具
【4月更文挑战第7天】使用Docker部署Mininote轻量级笔记工具
258 2
|
Linux Docker 索引
CentOS7安装Docker遇到的问题笔记
CentOS7安装Docker遇到的问题笔记
207 0
|
Linux 应用服务中间件 nginx
[笔记]docker入门《二》之 docker介绍(一)
[笔记]docker入门《二》之 docker介绍
|
API Docker 容器
Docker学习研究笔记(二)
Docker学习研究笔记(二)
|
Java 测试技术 Docker
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
486 0
|
Ubuntu Linux Docker
[笔记]Centos/Ubuntu/Windows/Docker 安装使用Aria2及Aria2基本使用
[笔记]Centos/Ubuntu/Windows/Docker 安装使用Aria2及Aria2基本使用
511 0
|
6月前
|
运维 Linux Docker
Docker笔记(个人向) 简述,最新高频Linux运维面试题目分享
Docker笔记(个人向) 简述,最新高频Linux运维面试题目分享
|
5月前
|
测试技术 Linux 数据库
【Docker项目实战】使用Docker部署Xnote轻量级笔记系统
【6月更文挑战第19天】使用Docker部署Xnote轻量级笔记系统
93 4
|
6月前
|
Linux Docker 容器
【微服务系列笔记】Docker
docker是一种容器技术,它主要是用来解决软件跨环境迁移的问题和同一环境下依赖冲突问题。 Docker可以运行在Mac, Windows, linux等操作系统上,常用于适用于构建和部署分布式应用、微服务架构。
84 0
【微服务系列笔记】Docker
|
6月前
|
监控 数据可视化 虚拟化
Docker容器常用命令笔记分享
Docker容器常用命令笔记分享
90 2