Docker 学习笔记

本文详细介绍了Docker的基础知识,包括Docker的作用、安装、常用命令、镜像加载原理、容器数据卷以及网络设置。重点阐述了Docker与虚拟机的区别,强调其轻量级和快速启动的优势。此外,还提供了DockerFile的使用示例和实战部署Redis集群的教程,适合后端开发者学习Docker使用。

文章目录

Docker 概述

常用网址

Docker 是基于 Go 语言开发的 开源项目。
官网:https://www.docker.com/

文档地址:https://docs.docker.com/ Docker文档非常详细!

仓库地址:https://hub.docker.com/

作用

虚拟机技术

在这里插入图片描述
虚拟机技术缺点:

  1. 资源占用大
  2. 冗余步骤多
  3. 启动缓慢

容器化技术

容器化技术不是模拟的一个完整操作系统
在这里插入图片描述

Docker与虚拟机技术的不同:

  • 传统虚拟机,虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
  • 容器内的应用直接运行在 宿主机的内核,容器是没有自己的内核的,也没有虚拟硬件,所以轻便
  • 每个容器间是互相隔离的,每个容器内部都有一个属于自己的文件系统,互不影响

DevOps (开发、运维)

应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像发布测试,一键运行
更便捷的升级和扩缩容
使用了Docker后,部署应用就和搭积木一样,很简便
项目打包为一个镜像,扩展 服务器A,服务器B
更简单的系统运维
在容器化开发后,开发和测试环境都是高度一致的!
更搞笑的计算资源利用
Docker 是内核级的虚拟化,可以在一个物理机上运行很多的容器实例!服务器的性能可以被压榨到极致

Docker安装

Docker的基本组成

在这里插入图片描述
镜像(Image)
docker镜像好比是一个模板,可以通过这个模块来创建容器服务,可以通过这个镜像创建多个容器(最终服务运行或者项目运行就是在容器中的)
容器(container)
Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的
启动,停止,删除,基本命令
目前可以把这个容器理解为就是一个简易的linux系统
仓库(repository)
仓库就是存放镜像的地方
仓库分为公有仓库和私有仓库
Docker Hub(默认是国外的)
可以通过阿里云等容器父亲(配置镜像加速访问)

安装Docker

环境准备

  1. 首先需要会一些Linux基础
  2. 我使用的是CentOS7的Linux系统
  3. 使用了FinalShell远程连接服务器

环境查看

# 系统内核 3.10 以上
[root@VM-8-9-centos ~]# uname -r
3.10.0-1160.31.1.el7.x86_64
# 系统版本
[root@VM-8-9-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"

安装

帮助文档https://docs.docker.com/engine/install/centos/
在这里插入图片描述

# 1. 卸载旧版本
 yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
# 2. 安装新版本
yum install -y yum-utils
# 3. 设置镜像的仓库
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo #默认是国外的!
    # 咱们使用阿里云镜像 国内镜像较快!
yum-config-manager \
    --add-repo \
    http: / /mirrors.aliyun.com/docker-ce/7inux/centos /docker-ce.repo

# 4. 安装docker相关内容 docker-ce 社区 docker-ee 企业版
yum makecache fast # 更新一下索引
yum install docker-ce docker-ce-cli containerd.io

# 5. 启动docker
systemctl start docker

# 6. 使用docker version查看是否安装成功
docker version

# 7. 测试运行 hello-world
docker run hello-world

# 8. docker images 查看镜像
docker images

卸载

# 1. 卸载依赖
yun remove docker-ce docker-ce-cli containerd.io

# 2。 删除资源 
rm -rf /var/lib/docker  # docker的默认工作路径

阿里云镜像加速

  1. 登录阿里云 找到 容器镜像服务

  2. 选择 镜像加速器
    在这里插入图片描述

  3. 配置使用

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://vnvb02sv.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

回顾HelloWorld流程

在这里插入图片描述
run 运行流程图
run运行图

底层原理

Docker工作方式

Docker是一个 Client-Server 结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问。
Docker-Server 接收到 Docker-Client 的指令,就会去执行这个指令。
在这里插入图片描述

Docker为什么比 虚拟机 快呢?

  1. Docker有着比虚拟机更少的抽象层。

  2. Docker 使用的是宿主机的内核!而虚拟机是需要模拟一个内核!
    在这里插入图片描述
    创建一个新的容器时,docker不需要重新加载一个操作系统内核, 避免一些引导性操作。虚拟机需要加载Guest OS,分钟级别,比较慢,而docker利用宿主机操作系统,省略该过程,秒级启动!

Docker常用命令及工具

帮助命令

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

官方文档命令

镜像命令

查看本机镜像 docker images

># docker image
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE 
hello-world   latest    d1165f221234   4 months ago   13.3kB

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

#OPTIONS
-a,--a;        #列出所有的镜像
-q,--quiet    #只显示镜像的id

搜索镜像 docker search

># docker search mysql
NAME                             DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                            MySQL is a widely used, open-source relation…   12234     [OK]       
mariadb                          MariaDB Server is a high performing open sou…   4699      [OK]       
mysql/mysql-server               Optimized MySQL Server Docker images. Create…   907                  [OK]

# 可选项 通过搜索来过滤 
--filter=STARS=3000  #搜索出来的镜像是STARS大于3000的

拉取镜像 docker pull

在这里插入图片描述

docker pull 镜像名 [:tag]
#下载镜像
># docker pull mysql  
Using default tag: latest	#不写tag,默认下载最新版
latest: Pulling from library/mysql
b4d181a07f80: Pull complete  #采用分层下载 docker image的核心!! 联合文件系统
a462b60610f5: Pull complete 
578fafb77ab8: Pull complete 
524046006037: Pull complete 
d0cbe54c8855: Pull complete 
aa18e05cc46d: Pull complete 
32ca814c833f: Pull complete 
9ecc8abdb7f5: Pull complete 
ad042b682e0f: Pull complete 
71d327c6bb78: Pull complete 
165d1d10a3fa: Pull complete 
2f40c47d0626: Pull complete 
Digest: sha256:52b8406e4c32b8cf0557f1b74517e14c5393aff5cf0384eff62d9e81f4985d4b	#签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest    #真实地址

#等价命令
># docker pull mysql
># docker.io/library/mysql:latest

#指定下载版本
># docker pull mysql:5.7
b4d181a07f80: Already exists  #分层,只下载不同的内容,联合文件系统
a462b60610f5: Already exists 
578fafb77ab8: Already exists 
524046006037: Already exists 
d0cbe54c8855: Already exists 
aa18e05cc46d: Already exists 
32ca814c833f: Already exists 
52645b4af634: Pull complete 
bca6a5b14385: Pull complete 
309f36297c75: Pull complete 
7d75cacde0f8: Pull complete 
Digest: sha256:1a2f9cd257e75cc80e9118b303d1648366bc2049101449bf2c8d82b022ea86b7
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

删除镜像 docker rmi

># docker rmi -f 5c62e459e087 #删除指定容器
#结果
Untagged: mysql:latest
Untagged: mysql@sha256:52b8406e4c32b8cf0557f1b74517e14c5393aff5cf0384eff62d9e81f4985d4b
Deleted: sha256:5c62e459e087e3bd3d963092b58e50ae2af881076b43c29e38e2b5db253e0287
Deleted: sha256:b92a81bddd621ceee73e48583ed5c4f0d34392a5c60adf37c0d7acc98177e414
Deleted: sha256:265829a9fa8318ae1224f46ab7bc0a10d12ebb90d5f65d71701567f014685a9e
Deleted: sha256:2b9144b43d615572cb4a8fb486dfad0f78d1748241e49adab91f6072183644e9
Deleted: sha256:944ffc10a452573e587652116c3217cf571a32c45a031b79fed518524c21fd4f
Deleted: sha256:b9108f19e3abf550470778a9d91959ce812731d3268d7224e328b0f7d8a73d26


># docker rmi -f $(docker images -qa)  #删除所有镜像

删除指定的容器:docker rmi -f <ID>
删除多个容器:docker rmi -f <ID1> <ID2> ...
删除所有容器:docker rmi -f $(docker images -qa)

提交镜像 docker commit

docker commit #提交容器称为一个新的副本
docker commit -m="提交的描述" -a="作者" 容器id 目标镜像名:[TAG]

容器命令

有了镜像才可以创建容器,linux,下载一个centos镜像来测试学习
docker pull centos
新建容器并启动

运行容器 docker run
#docker run [OPTIONS] image
#参数说明
--name="Name"   #容器名字 
,tomcat02 用来区分容器
-d				#后台运行方式
-it				#使用交互方式运行,进入容器查看内容
-p				#指定容器的端口 -p 8080:8080
        -p ip:主机端口:容器端口
        -p 主机端口:容器端口(常用)
        -p 容器端口
        容器端口
-P(大写P)		#随机指定端口
前台启动并进入容器
#启动并进入容器
[root@VM-8-9-centos ~]# docker run -it centos /bin/bash 
[root@851eb2068038 /]# ls #基础版本,很多命令都不是很完善
bin  etc   lib      lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@851eb2068038 /]# exit   #退出centos容器到主机
exit

[root@VM-8-9-centos ~]:~# docker ps  #查看当前正在运行的容器
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

后台启动容器
# 后台启动容器 docker run -d [镜像名]
[root@VM-8-9-centos ~]# docker run -d centos
599b658a7b67644cbefb08c37cffc8fd03ed0788079aabddd262b2ceccc168df
# 发现centos这个容器是停止的!
[root@VM-8-9-centos ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 注意:docker 容器使用后台运行,就必须要有一个前台进程

注意:docker 容器使用后台运行,就必须要有一个前台进程

查看运行的容器 docker ps
# docker ps 参数
	    	#列出当前正在与运行的容器
	-a		#列出当前正在运行的容器,并列出历史运行过的容器
	-n=?	#显示最近创建的容器
	-q		#显示容器的编号

[root@VM-8-9-centos ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@VM-8-9-centos ~]# docker ps -a
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS                     PORTS     NAMES
851eb2068038   centos                    "/bin/bash"              7 minutes ago   Exited (0) 4 minutes ago             bold_kepler
9c3a5dae7bf4   hello-world               "/hello"                 2 weeks ago     Exited (0) 2 weeks ago               gifted_kapitsa
d600d6322ff7   redislabs/rejson:latest   "docker-entrypoint.s…"   2 weeks ago     Exited (137) 13 days ago             redis-redisjson
c35ca3ead5d8   redislabs/rejson:latest   "docker-entrypoint.s…"   2 weeks ago     Exited (0) 13 days ago               great_dhawan
[root@VM-8-9-centos ~]# docker ps -aq
851eb2068038
9c3a5dae7bf4
d600d6322ff7
c35ca3ead5d8
退出容器
  1. exit 退出容器并退出
  2. 按下Ctrl+p+q 容器不停止,退出
删除容器 docker rm
# 不能删除正在运行的容器若需要则-rf
docker rm 容器id						#删除指定容器
docker rm 容器id -rf					#删除指定容器(强制)
docker rm -f $(docker ps -aq)		#删除所有容器
docker ps -a -q | xargs docker rm	#删除所有容器
启动和停止的操作
docker start 容器id		#启动过容器
docker restart 容器id	#重启容器
docker stop  容器id		#停止当前正在运行的容器
docker kill 容器id		#强制停止当前容器

其他常用命令

查看日志 docker logs

帮助文档

Usage:  docker logs [OPTIONS] CONTAINER
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m
                       for 42 minutes)
  -n, --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:37Z) or relative (e.g.
                       42m for 42 minutes)

示例

# 启动docker,执行shell脚本打印"guokun"
[root@VM-8-9-centos ~]# docker run -d centos /bin/sh -c "while true;do echo guokun;sleep 1;done"
cc5f796c45d3eb66f7744dff504b9ff5ebd0325319d3dd25c921dd5df2621b30
# docker ps 找到执行的容器id
[root@VM-8-9-centos ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
cc5f796c45d3   centos    "/bin/sh -c 'while t…"   5 seconds ago   Up 4 seconds             beautiful_carver
489bfb086173   centos    "/bin/bash"              6 minutes ago   Up 6 minutes             affectionate_thompson
# 查看5条日志
[root@VM-8-9-centos ~]# docker logs -tf --tail 5 cc5f796c45d3 
2022-03-28T02:07:12.255984892Z guokun
2022-03-28T02:07:13.258016459Z guokun
2022-03-28T02:07:14.260114633Z guokun
2022-03-28T02:07:15.262239508Z guokun
2022-03-28T02:07:16.264209183Z guokun

查看容器中进程信息 docker top
[root@VM-8-9-centos ~]# docker top cc5f796c45d3
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                21597               29164               0                   11:28               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root                29164               29144               0                   10:05               ?                   00:00:01            /bin/sh -c while true;do echo guokun;sleep 1;done
[root@VM-8-9-centos ~]# docker top 489bfb086173
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                19708               19689               0                   09:59               pts/0               00:00:00            /bin/bash

查看镜像元数据

docker inspect [OPTIONS] NAME|ID [NAME|ID…]

[root@VM-8-9-centos ~]# docker inspect 489bfb086173
[
    {
        "Id": "489bfb086173521b043695aa0094f0f89889408b7cc03215145403db566c6ffd",
        "Created": "2022-03-28T01:59:22.236726649Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 19708,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-03-28T01:59:22.571708887Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/www/server/docker/containers/489bfb086173521b043695aa0094f0f89889408b7cc03215145403db566c6ffd/resolv.conf",
        "HostnamePath": "/www/server/docker/containers/489bfb086173521b043695aa0094f0f89889408b7cc03215145403db566c6ffd/hostname",
        "HostsPath": "/www/server/docker/containers/489bfb086173521b043695aa0094f0f89889408b7cc03215145403db566c6ffd/hosts",
        "LogPath": "/www/server/docker/containers/489bfb086173521b043695aa0094f0f89889408b7cc03215145403db566c6ffd/489bfb086173521b043695aa0094f0f89889408b7cc03215145403db566c6ffd-json.log",
        "Name": "/affectionate_thompson",
        "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": "/www/server/docker/overlay2/a9c70067bedfcc1199c6ea2c8e1a50713348f717d011d8647dfa3b74c47c831d-init/diff:/www/server/docker/overlay2/b412c7d43b93ea32d8470c628ba67660872e7b01fb2c0945e4f31d60aeee2ff3/diff",
                "MergedDir": "/www/server/docker/overlay2/a9c70067bedfcc1199c6ea2c8e1a50713348f717d011d8647dfa3b74c47c831d/merged",
                "UpperDir": "/www/server/docker/overlay2/a9c70067bedfcc1199c6ea2c8e1a50713348f717d011d8647dfa3b74c47c831d/diff",
                "WorkDir": "/www/server/docker/overlay2/a9c70067bedfcc1199c6ea2c8e1a50713348f717d011d8647dfa3b74c47c831d/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "489bfb086173",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "e59008a27fe795f237d174bf0e5331760da9adcaf9275022334f8e715975eb25",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/e59008a27fe7",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "96e3d95740c486b3252edbd642e393e953ba8763a00a6597fdfd9242dfa307cc",
            "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": "33a695f4e66396b2e0b27cc62df6520da25ed083e0ed62daa7bfd19ec98eb193",
                    "EndpointID": "96e3d95740c486b3252edbd642e393e953ba8763a00a6597fdfd9242dfa307cc",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前正在运行的容器
打开新的终端 docker exec

文档

  -d, --detach               Detached mode: run command in the background
      --detach-keys string   Override the key sequence for detaching a container
  -e, --env list             Set environment variables
      --env-file list        Read in a file of environment variables
  -i, --interactive          Keep STDIN open even if not attached
      --privileged           Give extended privileges to the command
  -t, --tty                  Allocate a pseudo-TTY
  -u, --user string          Username or UID (format: <name|uid>[:<group|gid>])
  -w, --workdir string       Working directory inside the container

实操

[root@VM-8-9-centos ~]# docker exec -it 489bfb086173 /bin/bash
[root@489bfb086173 /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@489bfb086173 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 01:59 pts/0    00:00:00 /bin/bash
root        16     0  0 03:36 pts/1    00:00:00 /bin/bash
root        31    16  0 03:36 pts/1    00:00:00 ps -ef

进入正在执行的终端 docker attach

参数

Usage:  docker attach [OPTIONS] CONTAINER

Attach local standard input, output, and error streams to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)

测试

[root@VM-8-9-centos ~]# docker attach 489bfb086173
[root@489bfb086173 /]# ls
bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
[root@489bfb086173 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 01:59 pts/0    00:00:00 /bin/bash
root        33     1  0 03:40 pts/0    00:00:00 ps -ef

docker exec 进入容器开启一个新的终端(常用)
docker attach 进入容器正在执行的终端,不会启动新的进程!

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

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

# 进入容器
[root@VM-8-9-centos ~]# docker attach 489bfb086173
# 容器中
[root@489bfb086173 /]# cd home
[root@489bfb086173 home]# ls
# 创建file文件
[root@489bfb086173 home]# touch file
[root@489bfb086173 home]# ls
file
[root@489bfb086173 home]# exit
exit
# 在主机中输入 docker cp 将历史镜像容器中的文件复制到主机
docker cp 489bfb086173:/home/file ./
[root@VM-8-9-centos ~]# ls
app  bili  dump  Enviroment  fan  file  jar  linux1

拷贝是一个手动过程,未来可以使用 -v 卷的技术,可以实习自动同步

docker常用命令总结

请添加图片描述
输入 docker --help 即可获取

  attach      # 当前shell下attach连接指定运行镜像,不创建新的进程
  build       # 通过Dockerfile定制镜像
  commit      # 提交当前镜像为新的镜像
  cp          # 从容器中拷贝指定文件或者目录到宿主机中
  create      # 创建一个新的容器,同run,但是不启动容器
  diff        # 查看docker容器变化
  events      # 从docker服务中获取容器实时事件
  exec        # 在已存在的容器上,通过新的终端运行命令
  export      # 到处容器的内容流出作为一个tar归档文件[对应 import]
  history     # 展示一个镜像形成历史
  images      # 列出系统当前镜像列表
  import      # 从tar包中的内容创建一个新的文件系统映像[对应 export]
  info        # 显示系统相关信息
  inspect     # 查看容器详细信息
  kill        # kill指定的docker容器
  load        # 从一个tar包中加载一个镜像[对应 save]
  login       # 注册或登录一个docker源服务器
  logout      # 从当前Docker registry退出
  logs        # 输出当前容器日志信息
  pause       # 暂停容器
  port        # 查看映射端口对应的容器内部源端口
  ps          # 列出容器列表
  pull        # 从docker镜像源服务器拉区指定镜像
  push        # 推送指定镜像或者库镜像至docker源服务器
  rename      # 给指定容器重命名
  restart     # 重启运行的容器
  rm          # 移除一个或多个容器
  rmi         # 移除一个或多个镜[无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或 -f 强制删除]
  run         # 创建一个容器并运行容器
  save        # 保存一个镜像为一个tar包[对应 load]
  search      # 在Docker hub中搜索镜像
  start       # 启动容器
  stats       # 显示容器资源使用统计的实况流
  stop        # 停止容器
  tag         # 给原中镜像打标签
  top         # 查看容器中运行的进程信息
  unpause     # 取消暂停容器
  update      # 更新一个或多个容器的配置
  version     # 查看docker版本号
  wait        # 截取容器停止时的退出状态值

练习

docker安装nginx
  1. 搜索镜像 search (网上查看)
[root@VM-8-9-centos ~]# docker search nginx
NAME                                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                                             Official build of Nginx.                        16523     [OK]       
bitnami/nginx                                     Bitnami nginx Docker Image                      120                  [OK]
ubuntu/nginx                                      Nginx, a high-performance reverse proxy & we…   37                   
bitnami/nginx-ingress-controller                  Bitnami Docker Image for NGINX Ingress Contr…   17                   [OK]
rancher/nginx-ingress-controller                                                                  10                   
ibmcom/nginx-ingress-controller                   Docker Image for IBM Cloud Private-CE (Commu…   4                    
bitnami/nginx-ldap-auth-daemon                                                                    3                    
bitnami/nginx-exporter                                                                            2                    
rancher/nginx-ingress-controller-defaultbackend                                                   2                    
circleci/nginx                                    This image is for internal use                  2                    
vmware/nginx                                                                                      2                    
vmware/nginx-photon                                                                               1                    
rancher/nginx                                                                                     1                    
bitnami/nginx-intel                                                                               1                    
wallarm/nginx-ingress-controller                  Kubernetes Ingress Controller with Wallarm e…   0                    
rancher/nginx-conf                                                                                0                    
rancher/nginx-ssl                                                                                 0                    
continuumio/nginx-ingress-ws                                                                      0                    
ibmcom/nginx-ppc64le                              Docker image for nginx-ppc64le                  0                    
rancher/nginx-ingress-controller-amd64                                                            0                    
ibmcom/nginx-ingress-controller-ppc64le           Docker Image for IBM Cloud Private-CE (Commu…   0                    
rancher/nginx-proxy                                                                               0                    
kasmweb/nginx                                     An Nginx image based off nginx:alpine and in…   0                    
wallarm/nginx-ingress-controller-amd64            Kubernetes Ingress Controller with Wallarm e…   0                    
ibmcom/nginx-ingress-controller-s390x  
  1. 下载镜像
[root@VM-8-9-centos ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete 
a9edb18cadd1: Pull complete 
589b7251471a: Pull complete 
186b1aaa4aa6: Pull complete 
b4df32aa5a72: Pull complete 
a0bcbecc962e: Pull complete 
Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@VM-8-9-centos ~]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED        SIZE
redislabs/rejson   latest    29c809f8fc00   4 weeks ago    231MB
nginx              latest    605c77e624dd   2 months ago   141MB
mysql              5.7       c20987f18b13   3 months ago   448MB
hello-world        latest    feb5d9fea6a5   6 months ago   13.3kB
centos             latest    5d0da3dc9764   6 months ago   231MB

  1. 启动容器
[root@VM-8-9-centos ~]# docker run -d --name nginx01 -p:3344:80 nginx
eb349d0df0be791548a70ff6ef0c7bc86fd89dc0ed4c8eda352810acc84d93ef
[root@VM-8-9-centos ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
eb349d0df0be   nginx     "/docker-entrypoint.…"   15 seconds ago   Up 14 seconds   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01


  1. 测试访问
[root@VM-8-9-centos ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
端口暴露

请添加图片描述
问题:每次改动nginx配置文件,都需要进入容器内部,非常麻烦。可以在容器外部通过一个映射路径达到在容器外修改容器内文件。-v 数据卷

docker安装Tomcat

测试容器 使用后自动删除容器!docker ps -a 找不到

#官方命令,容器启动后删掉用来测试,用完就删除容器
docker run -it --rm tomcat:9.0  

# 1.获取镜像
docker pull tomcat
# 2.启动容器
docker run -d -p 8686:8080 --name tomcat01 tomcat
# 3.进入容器
docker exec -it tomcat01 /bin/bash

问题:

  1. 可执行的linux命令有限
  2. 没有webapps
    阿里云镜像默认使用最小镜像,所有不必要的都剔除了,保证最小的运行环境

可视化工具

  1. portainer
    docker run -d -p 8689:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  2. Rancher

portainer

Docker图形化界面管理工具,提供一个后台面板方便操作

启动代码(中间一段为端口和权限设置)
docker run -d -p 8689:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
简化:
docker run -d portainer/portainer

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

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

Docker镜像讲解

镜像是什么?

镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的索引内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接可以打包成docker镜像,然后直接运行!
获取镜像:

  • 从远程仓库获取
  • 拷贝获取
  • 自己制作镜像 DockerFile

Docker镜像加载原理

UnionFSB(联合文件系统)

UnionFS:Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来继承,基于基础镜像(无父镜像),可以制作各种具体的应用镜像。

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

镜像加载原理

docker的镜像实际上由一层层的文件系统组成,这种蹭吃的文件系统UnionFS。
BootFS主要包含BootLoader和kernel,BootLoader主要是引导加载kernel,Linux刚启动时会加载BootFS文件系统,在Docker镜像的最底层是BootFS。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由BootFS转交给内核,此时系统也会卸载BootFS。

RootFS,在BootFS之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。RootFS就是各种不同的操作系统发行版,比如Ubuntu,CentOS等。请添加图片描述
对于一个精简的操作系统,RootFS可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接使用主机的内核,自己只需要提供RootFS即可。由此可见对于不同的Linux发行版,BootFS基本是一致的,RootFS会有差别,因此不同的发行版可以公用BootFS。

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

分层理解

"RootFS": {
            "Type": "layers",
            # Layers 每一层就是一个文件记录
            "Layers": [
                "sha256:11936051f93baf5a4fb090a8fa0999309b8173556f7826598e235e8a82127bce",
                "sha256:31892cc314cb1993ba1b8eb5f3002c4e9f099a9237af0d03d1893c6fcc559aab",
                "sha256:8bf42db0de72f74f4ef0c1d1743f5d54efc3491ee38f4af6d914a6032148b78e",
                "sha256:26a504e63be4c63395f216d70b1b8af52263a5289908df8e96a0e7c840813adc",
                "sha256:f9e18e59a5651609a1503ac17dcfc05856b5bea21e41595828471f02ad56a225",
                "sha256:832e177bb5008934e2f5ed723247c04e1dd220d59a90ce32000b7c22bd9d9b54",
                "sha256:3bb5258f46d2a511ddca2a4ec8f9091d676a116830a7f336815f02c4b34dbb23",
                "sha256:59c516e5b6fafa2e6b63d76492702371ca008ade6e37d931089fe368385041a0",
                "sha256:bd2befca2f7ef51f03b757caab549cc040a36143f3b7e3dab94fb308322f2953",
                "sha256:3e2ed6847c7a081bd90ab8805efcb39a2933a807627eb7a4016728f881430f5f"
            ]
        }

理解:
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
例如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示。请添加图片描述
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要!下图举例一个简单例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。请添加图片描述
下图展示一个稍微复杂一点的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
请添加图片描述
这种情况下,上层镜像中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

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

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

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

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
请添加图片描述

特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
在这里插入图片描述
如何提交一个自己的镜像?

提交镜像 commit

提交方式

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

docker commit -m="提交的描述信息" -a="作者" (目标镜像名):[TAG]

实战测试

# 1.启动一个默认的tomcat
docker run -d --name tomcat01 -p 8687:8080 tomcat
docker exec -it tomcat01 /bin/bash
# 2.发现这个默认的tomcat没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的!
root@b508e8e14a23:/usr/local/tomcat# ls webapps

# 3.自己拷贝webapps的基本文件
root@b508e8e14a23:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@b508e8e14a23:/usr/local/tomcat# cd webapps
root@b508e8e14a23:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
# 4.将我们操作过的容器通过commit提交成为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己的镜像。

如果想保存当前容器的状态,可以通过commit来提交,获得一个镜像
好比VM中的快照

Docker 容器数据卷

什么是Docker容器数据卷?

当我们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在我们关闭docker容器时是会消失的,但是其中产生的部分内容我们是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,我们希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。

​ 通俗地来说,docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。

特点:

  1. 数据卷可以在容器之间共享或重用数据
  2. 数据卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

在这里插入图片描述

容器的持久化和同步操作,容器间也是可以数据同步的!

使用容器数据卷

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

[root@VM-8-9-centos centos]# docker run -it -v /root/data/centos/home:/home centos /bin/bash
[root@334f4a042e05 /]# cd home
[root@334f4a042e05 home]# ls
[root@334f4a042e05 home]# touch newFile
[root@334f4a042e05 home]# ls
newFile

# 到主机中对应目录中查看
[root@VM-8-9-centos centos]# ls /root/data/centos/home
newFile

通过docker inspect 334f4a042e05查看信息可以找到对应容器卷绑定信息
在这里插入图片描述

绑定同步之后,无论容器是否启动。对主机文件上的操作都会同步到容器中,同样容器中的文件操作也会同步到主机

优点:
绑定后,只需要在本地修改文件即可,容器内会自动同步

数据卷命令文档

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

实战:安装MySQL

# 1. 获取镜像
docker pull mysql:5.7
# 2. 运行mysql并且挂载数据卷 配置mysql密码
# 官方配置: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# -d 后台运行
# -p 端口映射 
# -v 卷挂载
# -e 环境配置
# --name 容器名字
[root@VM-8-9-centos home]# docker run -d -p 8688:3306 -v /root/data/mysql/conf:/etc/mysql/conf.d -v /root/data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

远程连接到8688端口数据库 连接成功!
在这里插入图片描述
远程测试创建一个数据库,检查文件是否同步
在这里插入图片描述
在这里插入图片描述
当我们删除mysql01容器

[root@VM-8-9-centos centos]# docker rm -f mysql01
mysql01
[root@VM-8-9-centos centos]# ls /root/data/mysql/data
auto.cnf    client-cert.pem  ibdata1      ibtmp1              private_key.pem  server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql               public_key.pem   sys
ca.pem      ib_buffer_pool   ib_logfile1  performance_schema  server-cert.pem  test

可以发现挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!

具名和匿名挂载

匿名挂载

-v (容器内路径)

# 匿名挂载 
[root@VM-8-9-centos centos]# docker run -d -P --name nginx01 -v /etc/nginx nginx
5e103cdc1ddfb63622cda5a28979a559724367ac193d7c6d530f46b613acc0ba
[root@VM-8-9-centos centos]# docker volume ls
DRIVER    VOLUME NAME
local     26febf097831005c5fb23037107dbdb5aa47ee47a5491993376e37451bb8d110
local     525d9edea1301e8e0971593de6e03eee7f0c699fbe0a3691c32153a81f3a4934
local     782bcd18b72c2fa03470cdd6251d48ee57919c2f54140516e1489b012ae78e04
local     7665d7edd2d832de44ee136d7c726df9802c00a122776a0315cf5b067bb5e070
local     e523c503043e88d48da3f70fe774e784e8c0eab0ee1c2d5295a0e2bcf29339ac

具名挂载

-v (卷名:容器内路径)

# 具名挂载
[root@VM-8-9-centos centos]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
bd427e82fb38b02f1d15ea4d6f7e2644860b307fd61913591f2b313a0d0447cc

[root@VM-8-9-centos centos]# docker volume ls
DRIVER    VOLUME NAME
local     26febf097831005c5fb23037107dbdb5aa47ee47a5491993376e37451bb8d110
local     525d9edea1301e8e0971593de6e03eee7f0c699fbe0a3691c32153a81f3a4934
local     782bcd18b72c2fa03470cdd6251d48ee57919c2f54140516e1489b012ae78e04
local     7665d7edd2d832de44ee136d7c726df9802c00a122776a0315cf5b067bb5e070
local     e523c503043e88d48da3f70fe774e784e8c0eab0ee1c2d5295a0e2bcf29339ac
local     juming-nginx	# 卷名被指定了名称

# 查看卷 获取挂载的地址
[root@VM-8-9-centos centos]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2022-03-29T16:10:27+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/www/server/docker/volumes/juming-nginx/_data",	# 挂载地址
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

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

通过具名挂载可以方便的找到卷,大多数情况下使用具名挂载

Dockerfile

通过dockerfile脚本生成镜像

  1. 创建一个dockerfile文件 testDockerfile:

    # 指令(大写) + 参数
    FROM centos
    
    VOLUME ["volume01","volume02"]
    
    CMD echo "--end--"
    CMD /bin/bash
    
    # dockerfile的每一个指令相当于镜像的一层
    
  2. 创建自定义镜像

    [root@VM-8-9-centos dockerfile]# docker build -f /root/data/dockerfile/testDockerfile -t test-centos:1.0 .
    Sending build context to Docker daemon  2.048kB
    Step 1/4 : FROM centos
     ---> 5d0da3dc9764
    Step 2/4 : VOLUME ["volume01","volume02"]
     ---> Running in ed981029fea2
    Removing intermediate container ed981029fea2
     ---> 62bae0da3650
    Step 3/4 : CMD echo "--end--"
     ---> Running in bf7b91a0baed
    Removing intermediate container bf7b91a0baed
     ---> 0c0aac1db8ff
    Step 4/4 : CMD /bin/bash
     ---> Running in b7ae17322dda
    Removing intermediate container b7ae17322dda
     ---> 53663a8f3bb9
    Successfully built 53663a8f3bb9
    Successfully tagged test-centos:1.0
    
    
  3. 启动容器
    在这里插入图片描述
    这两个卷一定和外部一一对应!同步!

    [root@da0d8959333d /]# cd volume01
    [root@da0d8959333d volume01]# touch newFile
    

    docker inspect 容器id 查看卷地址在这里插入图片描述

    到对应卷地址查看文件列表,可以看见文件已经同步

    [root@VM-8-9-centos _data]# cd /www/server/docker/volumes/01fd1ce93a70a0af363dd9a9e85cf8b33bb085e17c83bdb5ae4a3ee7e49dc4bd/_data
    [root@VM-8-9-centos _data]# ls
    newFile
    
    

    这种方式比较常用,假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径

数据卷容器

除了宿主机与容器数据共享之外
还可以通过--volumes-from实现多个容器之间的数据共享!!
请添加图片描述

  1. 启动有容器卷的容器docker01(上一栏中自定义的test-centos镜像)
    docker run -it --name docker01 test-centos:1.0
  2. 启动新的容器docker02并同步docker01的数据卷!
    docker run -it --name docker02 --volumes-from docker01 test-centos:1.0
  3. 在docker02中的同步卷volume01中创建文件docker02-file
    touch volume01/docker2-file
  4. 发现在docker01中的同步卷volume01中也出现了docker02-file
    # docker01
    [root@6a158f5971c8 /]# ls volume01 
    docker2-file 
    

只要通过 --volumes-from可以实现容器间共享数据

  • 同步的多个容器间相互影响!可以共享数据卷
  • 停止的容器扔会同步数据卷
  • 删除容器,其他的同步卷数据不会丢失!

实践:实现多个mysql数据共享

# 运行第一个mysql容器
[root@VM-8-9-centos home]# docker run -d -p 8688:3306 -v /root/data/mysql/conf:/etc/mysql/conf.d -v /root/data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 运行第二个mysql容器并同步mysql01的数据卷!实现数据共享!
[root@VM-8-9-centos home]# docker run -d -p 8687:3306 -v /root/data/mysql/conf:/etc/mysql/conf.d -v /root/data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

扩展

如何确定是具名挂载还是匿名挂载还是指定路径挂载呢?

  • -v (容器内路径) 匿名挂载
  • -v (卷名:容器内路径) 具名挂载
  • -v (/宿主机路径:容器内路径) 指定路径挂载

RO与RW

可以通过ro与rw变更读写权限(默认rw)

  • ro readonly # 只读
  • rw readwrite # 可读可写

一旦设置了容器权限,容器对挂载的内容就会有限制!
若权限为ro,说明这个路径只能通过宿主机来操作,容器内部是无法操作的!

DockerFile

DockerFIle 介绍

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

构建步骤:

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

查看一下官方制作centos过程
在这里插入图片描述

FROM scratch
ADD centos-7-x86_64-docker.tar.xz /

LABEL \
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

CMD ["/bin/bash"]

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

DockerFile 构建

基础知识:

  1. 每个保留关键字(指令)都必须是大写字母
  2. 执行顺序 从上至下
  3. 注释使用 #
  4. 每一个指令都会创建提交一个新的镜像层,并提交请添加图片描述

dockerfile是面向开发的,以后要发布项目,可以做成镜像,编写dockerfile文件。

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

DockerFIle:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务

DockerFile 指令

  • FROM
    基础镜像,一切从这里开始构建
  • MAINTAINER
    镜像作者 姓名+邮箱
  • RUN
    镜像构建的时候需要运行的命令
  • ADD
    添加内容 (例如添加JDK)
  • WORKDIR
    镜像的工作目录
  • VOLUME
    挂载的目录
  • EXPOSE
    暴露端口配置
  • CMD
    指定容器启动时需要运行的命令
    不可以追加命令,追加的命令会覆盖原本的命令
  • ENTRYPOINT
    指定容器启动时需要运行的命令
    可以追加命令
  • ONBUILD
    当构建一个被继承DockerFile时,就会运行ONBUILD的指令。触发指令
  • COPY
    类似于ADD,将文件拷贝到镜像中
  • ENV
    构建的时候设置环境变量

CMD 和 ENTRYPOINT 区别

CMD 覆盖

# 通过编写dockerfile构建执行CMD命令的centos镜像
[root@VM-8-9-centos dockerfile]# vim dockerfile-cmd-CMD
[root@VM-8-9-centos dockerfile]# docker build -f dockerfile-cmd-CMD -t cmd .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
 ---> Running in 4c65fb8ed3f3
Removing intermediate container 4c65fb8ed3f3
 ---> e47175d50707
Successfully built e47175d50707
Successfully tagged cmd:latest
# 正常运行容器
[root@VM-8-9-centos dockerfile]# docker run cmd
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 追加命令参数 -l,想构成 ls -al 发现覆盖原本的命令导致无法运行!
[root@VM-8-9-centos dockerfile]# docker run cmd -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不是命令所以报错!!!

ENTRYPOINT 直接追加

[root@VM-8-9-centos dockerfile]# vim dockerfile-cmd-ENTRYPOINT
[root@VM-8-9-centos dockerfile]# docker build -f dockerfile-cmd-ENTRYPOINT -t entrypoint .
Sending build context to Docker daemon  6.656kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in 49f2896ea2d2
Removing intermediate container 49f2896ea2d2
 ---> 03b0900b826a
Successfully built 03b0900b826a
Successfully tagged entrypoint:latest
# 常规运行容器
[root@VM-8-9-centos dockerfile]# docker run entrypoint
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 追加参数-l 运行容器 发现可以按照目的运行!拼接为 ls -al
[root@VM-8-9-centos dockerfile]# docker run entrypoint -l
total 56
drwxr-xr-x   1 root root 4096 Mar 29 16:04 .
drwxr-xr-x   1 root root 4096 Mar 29 16:04 ..
-rwxr-xr-x   1 root root    0 Mar 29 16:04 .dockerenv
lrwxrwxrwx   1 root root    7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x   5 root root  340 Mar 29 16:04 dev
drwxr-xr-x   1 root root 4096 Mar 29 16:04 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 164 root root    0 Mar 29 16:04 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 Mar 29 08:45 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

实操写DockerFile

Docker Hub 中 99% 镜像都是从基础镜像 scratch 继承过来的,然后配置需要的软件和配置来进行的构建

创建一个centos

  1. 编写dockerfile文件

    FROM centos
    MAINTAINER guokun<317557750@qq.com>
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    RUN yum -y install vim
    RUN yum -y install net-tools
    
    EXPOSE 80
    
    CMD echo $MYPATH
    CMD echo "---end---"
    CMD /bin/bash
    
    
  2. 构建镜像
    docker build -f (dockerfile文件路径) -t (镜像名[:标记]) .

    注意不要忘了最后的.

    Successfully built 8d972e1413c6
    Successfully tagged mycentos:0.1
    

    在构建过程中踩坑:

    最新版本centos存在问题,使用centos7镜像解决无法装配vim等功能的bug

    https://blog.csdn.net/Ctrl_kun/article/details/123835198

  3. 测试运行

前后对比

  • 原生centos
    在这里插入图片描述

  • 添加了自定义功能后的自定义镜像mycentos
    在这里插入图片描述

可以通过docker history (镜像名[:标签] | 镜像id) 查看它是如何制作的

[root@VM-8-9-centos dockerfile]# docker history mysql:5.7
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
c20987f18b13   3 months ago   /bin/sh -c #(nop)  CMD ["mysqld"]               0B        
<missing>      3 months ago   /bin/sh -c #(nop)  EXPOSE 3306 33060            0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B        
<missing>      3 months ago   /bin/sh -c ln -s usr/local/bin/docker-entryp…   34B       
<missing>      3 months ago   /bin/sh -c #(nop) COPY file:345a22fe55d3e678…   14.5kB    
<missing>      3 months ago   /bin/sh -c #(nop)  VOLUME [/var/lib/mysql]      0B        
<missing>      3 months ago   /bin/sh -c {   echo mysql-community-server m…   313MB     
<missing>      3 months ago   /bin/sh -c echo 'deb http://repo.mysql.com/a…   55B       
<missing>      3 months ago   /bin/sh -c #(nop)  ENV MYSQL_VERSION=5.7.36-…   0B        
<missing>      3 months ago   /bin/sh -c #(nop)  ENV MYSQL_MAJOR=5.7          0B        
<missing>      3 months ago   /bin/sh -c set -ex;  key='A4A9406876FCBD3C45…   1.84kB    
<missing>      3 months ago   /bin/sh -c apt-get update && apt-get install…   52.2MB    
<missing>      3 months ago   /bin/sh -c mkdir /docker-entrypoint-initdb.d    0B        
<missing>      3 months ago   /bin/sh -c set -eux;  savedAptMark="$(apt-ma…   4.17MB    
<missing>      3 months ago   /bin/sh -c #(nop)  ENV GOSU_VERSION=1.12        0B        
<missing>      3 months ago   /bin/sh -c apt-get update && apt-get install…   9.34MB    
<missing>      3 months ago   /bin/sh -c groupadd -r mysql && useradd -r -…   329kB     
<missing>      3 months ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      3 months ago   /bin/sh -c #(nop) ADD file:bd5c9e0e0145fe33b…   69.3MB

构建一个Tomcat镜像

遇到的坑!

  1. 下载的压缩包缺失数据(传输或下载出了问题)
  2. 下载的压缩包搞成了32位的
  3. usr写成url
  4. 最后一个CMD启动日志写错路径
  1. 准备镜像文件 tomcat 压缩包,jdk 压缩包
    tomcat-9:
    官网地址(很慢)https://downloads.apache.org/tomcat/tomcat-9/v9.0.60/bin/apache-tomcat-9.0.60.tar.gz
    国内镜像地址(不能通过url下载302,可以浏览器下载)
    https://mirrors.cnnic.cn/apache/tomcat/tomcat-9/v9.0.60/bin/apache-tomcat-9.0.60.tar.gz

    jdk-1.8:https://download.oracle.com/otn/java/jdk/8u311-b11/4d5417147a92418ea8b615e228bb6935/jdk-8u311-linux-x64.tar.gz

  2. 编写dockerfile文件(官方命名 Dockerfile build 会自动寻找这个文件,不用-f指定路径)

    FROM centos:centos7
    MAINTAINER guokun<317557750@qq.com>
    
    # 拷贝当前目录中的readme.txt到容器中的/usr/local/readme.txt
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u311-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.60.tar.gz /usr/local/
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_311
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.60
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.60
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-9.0.60/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.60/bin/logs/catalina.out
    
    
  3. 构建镜像

    [root@VM-8-9-centos tomcat]# docker build -t diy-tomca .
    
    Successfully built 2d88ade4566c
    Successfully tagged diy-tomca:latest
    
  4. 启动容器

    docker run -d -p 8688:8080 --name diy-tomcat01 -v /root/data/tomcat/webapps/test:/usr/local/apache-tomcat-9.0.60/webapps/test -v /root/data/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.60/logs diy-tomcat
    
  5. 访问测试
    太不容易了,搞了一个下午…在这里插入图片描述

  6. 发布项目
    由于做了卷挂载,直接在本地编写项目即可
    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             metadata-complete="true">
    </web-app>
    

    index.jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset="utf-8">
    		<titile>diy-tomcat</title>
    	</head>
    	<body>
    		<%
    			String text = "访问者IP : " + request.getRemoteAddr();
    			out.println(text);
    			System.out.println(text);
    		%>
    	</body>
    </html>
    

    项目部署成功,可以访问
    在这里插入图片描述

发布自己的镜像

DockerHub

  1. 注册自己的DockerHub账号

  2. docker登录到DockerHub

    [root@VM-8-9-centos tomcat]# 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
    
    
    [root@VM-8-9-centos tomcat]# docker login -u guokun0docker
    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
    
    
  3. 提交镜像 docker push

    直接push会被拒绝请求

    [root@VM-8-9-centos tomcat]# docker push diy-tomcat
    Using default tag: latest
    The push refers to repository [docker.io/library/diy-tomcat]
    0951f1121a0f: Preparing 
    82d2adf3ac4a: Preparing 
    a67bb5adf0bf: Preparing 
    d8bad9df986b: Preparing 
    174f56854903: Preparing 
    denied: requested access to the resource is denied
    
    

    tag必须在前面加上自己的dockerhub的username,然后再push就可以了

    [root@VM-8-9-centos tomcat]# docker tag diy-tomcat:latest guokun0docker/tomcat:1.0
    

    提交时也是安装镜像层级进行提交的

    The push refers to repository [docker.io/guokun0docker/tomcat]
    0951f1121a0f: Pushing  54.16MB/215.7MB
    82d2adf3ac4a: Pushed 
    a67bb5adf0bf: Pushing  6.093MB/365.3MB
    d8bad9df986b: Pushed 
    174f56854903: Pushing  31.03MB/203.9MB
    

阿里云镜像服务

  1. 注册阿里云账号

  2. 找到容器服务

  3. 创建命名空间
    在这里插入图片描述

  4. 创建容器镜像仓库
    在这里插入图片描述

  5. 操作步骤文档
    在这里插入图片描述

  6. 根据文档上传镜像

上传后的镜像会显示在版本列表中在这里插入图片描述

请添加图片描述

Docker网络

docker 是如何处理容器网络访问的?

Docker0

删除影响实验结果的容器

先删除所有容器 docker rm -f $(docker ps -aq)

查看主机网卡信息

查看网卡信息 ip addr
网卡地址
可以发现有一个 docker0网卡信息

给原生tomcat容器添加iproute2组件并提交成自定义镜像ip-tomcat

原生的tomcat没有网络控制功能,因此需要自己安装iproute2net-toolsiputils-ping,然后提交为自定义镜像tomcat容器ip-tomcat

# 运行一个原生tomcat容器
centos> docker run -it --name tomcat01 tomcat /bin/bash
# 安装iproute2
tomcat> apt update && apt install -y iproute2 && apt install -y net-tools && apt install -y iputils-ping
# ..... 安装中
tomcat> exit
# 提交为自定义镜像 ip-tomcat
centos> docker commit tomcat01 ip-tomcat 
# 删除tomcat01容器 
centos> docker rm -f tomcat01

使用ip-tomcat镜像 创建容器并用ip addr查看网卡信息

tomcat01

[root@VM-8-9-centos ~]# docker exec -it tomcat01 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
261: eth0@if262: <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

主机

[root@VM-8-9-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:f9:05:3c brd ff:ff:ff:ff:ff:ff
    inet 10.0.8.9/22 brd 10.0.11.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fef9:53c/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:43:1f:f2:f4 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:43ff:fe1f:f2f4/64 scope link 
       valid_lft forever preferred_lft forever
262: veth7e25f43@if261: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 1a:21:ef:cc:9b:91 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::1821:efff:fecc:9b91/64 scope link 
       valid_lft forever preferred_lft forever

可以发现tomcat01容器和主机生成了一对数字相差1的网卡

其中tomcat01中的eth0@if163是由docker分配的!

测试主机与容器间网卡是否能够ping通

[root@VM-8-9-centos ~]# 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.076 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.041 ms

发现linux主机可以ping通docker容器!

容器与容器之间也是可以相互ping通

创建新的ip-tomcat容器tomcat02尝试ping通tomcat01

[root@VM-8-9-centos ~]# docker run -d --name tomcat02 ip-tomcat
[root@VM-8-9-centos ~]# 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.100 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.076 ms

发现是可以ping通的。

原理

每次启动一个docker容器,docker就会给docker容器分配一个ip,只要安装了docker就会有一个网卡docker0桥接模式,使用evth-pair技术!

例如上一个例子中创建tomcat01容器时除了tomcat01生成的网卡162::eth0@if163,主机也生成了一个对应的网卡163:veth7e25f43@if162,形成一个evth-pair

evth-pair 是一堆虚拟设备接口,成对出现,一段连接协议,一段彼此相连

evth-pair 充当一个桥梁,连接各种虚拟网络设备

请添加图片描述
所有容器在不指定网络的情况下,都是由 docker0 路由的, docker 会给容器分配一个默认的可用IP

小结

Docker 使用的是 Linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0
请添加图片描述
Docker中的所有网络接口都是虚拟的。虚拟的转发效率非常高。(内网传递数据)

若容器被暂停或删除,对应的网桥对就会消失。(仅在运行时存在,每次运行重新生成!)

–link

高可用 -> 容器ip地址更换项目仍然能够定位到指定微服务(通过唯一名字定位)

直接尝试两个容器间ping是无法ping通的

[root@VM-8-9-centos ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

使用--link参数可以将两个容器连接,之后便可以直接通过容器名字(或容器ID)ping通

[root@VM-8-9-centos ~]# docker run -d --name tomcat03 --link tomcat02 ip-tomcat
ad53d25fe3ceaef901d7c16ea819d54c7a3bf29c211be5d9e12fb4aa3eaa8225
[root@VM-8-9-centos ~]# 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.111 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.073 ms

注意:
通过link连接的是单向ping通,不能反向ping通,两个容器都需要link才可以实现双向ping通!!!

[root@VM-8-9-centos ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

查看docker网络信息 docker network
帮助文档

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

docker network ls

[root@VM-8-9-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
b31f3de3e5ff   bridge    bridge    local
93cde78e2b58   host      host      local
0dec21c5d6a8   none      null      local

docker network inspect (网络ID)

[root@VM-8-9-centos ~]# docker network inspect b31f3de3e5ff
[
    {
        "Name": "bridge",
        "Id": "b31f3de3e5ff0549da27a9a25f0accc96d207ba28a46a37c79985e8bd1cf2da6",
        "Created": "2022-03-29T23:11:54.436421179+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": {
            "25318c1306be0deedaab5ebc9b2bc0134383eb0f304af7d7cb02fe7caad06d27": {
                "Name": "tomcat02",
                "EndpointID": "24dcc29f5a58d960608916fc416cfb6380ea2a57e144e8a170c509ebcc981661",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "aadfe9d280298887a4b4971801f360d78578eaf32337a6625d713b8dc04f95a2": {
                "Name": "tomcat01",
                "EndpointID": "c19611d2471c532f551d4a42cf440e678d18136465ddf53ba8c8c532fec923f6",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "ad53d25fe3ceaef901d7c16ea819d54c7a3bf29c211be5d9e12fb4aa3eaa8225": {
                "Name": "tomcat03",
                "EndpointID": "5c398ff94f5cf5e96eb9313a3e61b472b3829f99605be21903d005d255ba4859",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

原理:在本地/etc/hosts中配置了映射关系

其实就上述tomcat03就是在本地配置了tomcat02的IP映射关系

[root@VM-8-9-centos ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3      tomcat02 25318c1306be
172.17.0.4      ad53d25fe3ce

本质:--link 就是在hosts配置中添加了一个 172.17.0.3 tomcat02 25318c1306be

现在不建议使用 --link !!
一般自定义网络,不使用 docker0docker0 不支持容器名连接访问!

自定义网络

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

网络模式

模式解释
bridge桥接 docker (默认)
none不配置网络
host和宿主机共享网络
container容器网络连通(用得少)

默认带有参数 --net bridge

docker run -d --name tomcat01 ip-tomcat
docker run -d --name tomcat01 --net ip-tomcat

默认使用的 docker0,域名不能访问!可以通过 --link 连通。

创建网络

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver
                             (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment

创建一个简单的网络 mynet

  • -- driver bridge 网络模式
  • --subnet 192.168.0.0/16 子网地址 -> (192.168.0.2 ~ 192.168.255.255)
  • --gateway 192.168.0.1 网关
[root@VM-8-9-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
dc3360444237c65c301416861b9c8a04c500354d2a5bfa715ccf86d01a07fc32

[root@VM-8-9-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
b31f3de3e5ff   bridge    bridge    local
93cde78e2b58   host      host      local
dc3360444237   mynet     bridge    local
0dec21c5d6a8   none      null      local

[root@VM-8-9-centos ~]# docker network inspect mynet 
[
    {
        "Name": "mynet",
        "Id": "dc3360444237c65c301416861b9c8a04c500354d2a5bfa715ccf86d01a07fc32",
        "Created": "2022-03-31T17:31:17.128610062+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": {}
    }
]

启动一个容器,设置网络为mynet

[root@VM-8-9-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
dc3360444237c65c301416861b9c8a04c500354d2a5bfa715ccf86d01a07fc32

[root@VM-8-9-centos ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "dc3360444237c65c301416861b9c8a04c500354d2a5bfa715ccf86d01a07fc32",
        "Created": "2022-03-31T17:31:17.128610062+08:00",
        "Scope": "local",
        "Driver": "bridge",
        .....
        "ConfigOnly": false,
        "Containers": {
            "cbc91c79cb279e4192452ea5c0cf5f37f21c77c9272bd4c0b98bf7861263e04a": {
                "Name": "tomcat-net-01",
                "EndpointID": "8c8ac809cd39021a82fe350a1d7c5898dcdf05dc925272fc0c7bad03b0212de0",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

使用自定义创建的网络docker,可以通过容器名或容器ID相互ping通!
所以推荐使用自定义网络!!!

[root@VM-8-9-centos ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.078 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.071 ms
[root@VM-8-9-centos ~]# docker exec -it tomcat-net-02 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.076 ms

好处:不同的集群使用不同的网络,保证集群是安全和健康的。

网络连通 docker network connect

不同网络中容器无法通过名字连通

开启一个docker0网络的镜像tomcat01 和 一个 mynet 网络的镜像 tomcat-net-01

尝试相互ping,发现都无法ping通~

[root@VM-8-9-centos ~]# docker exec -it tomcat01 ping tomcat-net-01 
ping: tomcat-net-01: Name or service not known
[root@VM-8-9-centos ~]# docker exec -it tomcat-net-01 ping tomcat01
ping: tomcat01: Name or service not known

docker network connect 将一个容器连接到一个网络中

Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      driver options for the network
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container

测试

[root@VM-8-9-centos ~]# docker network connect mynet tomcat01

输入docker network inspect mynet 可以发现mynet下也有tomcat01容器了,原理是给它再分配了一个网络IP
在这里插入图片描述
输入docker exec -it tomcat01 ip addr 可以发现多了一个192.168.0.3IP,这就是由mynet分配的网络IP
在这里插入图片描述
尝试相互ping,发现都可以ping通了。 而且此时tomcat01是和整个mynet网络所有容器都连通了!!

[root@VM-8-9-centos ~]# docker exec -it tomcat01 ping tomcat-net-01 
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.081 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.073 ms

[root@VM-8-9-centos ~]# docker exec -it tomcat01 ping tomcat-net-01 
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.084 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.084 ms

实战部署 Redis集群

创建一个 redis 专用网络

docker network create redis --subnet 172.38.0.0/16

创建6个redis容器并挂载数据卷

for id in $(seq 1 6); \
do \
docker run --name redis-${id} \
-v /root/data/redis/node-${id}/data/:/data/ \
-v /root/data/redis/node-${id}/conf/:/etc/redis/conf \
-d --net redis --ip 172.38.0.1${id} redis 
done

创建6个redis配置

for id in $(seq 1 6); \
do \
mkdir -p /root/data/redis/node-${id}/conf
touch /root/data/redis/node-${id}/conf/redis.conf
cat << EOF >/root/data/redis/node-${id}/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${id}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

启动6个redis服务

for id in $(seq 1 6); \
do \
docker run --name redis-${id} \
-v /root/data/redis/node-${id}/data/:/data/ \
-v /root/data/redis/node-${id}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${id} redis redis-server /etc/redis/redis.conf; 
done

搭建集群

docker exec -it redis-1 \
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
[root@VM-8-9-centos data]# docker exec -it redis-1 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: 1ac333a27b8d3aecdcd3b14d90428869fde4ed98 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: fe99d242067af86f124bcc691a682b25345e209c 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 8cf43330c5eac644e5b94c608d26902097760dc1 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 174b8a5fddbf7741aa517af5ae465960ee9fb7c9 172.38.0.14:6379
   replicates 8cf43330c5eac644e5b94c608d26902097760dc1
S: 0015c60ff195dfd1a723a96ea327cec6f7fc0413 172.38.0.15:6379
   replicates 1ac333a27b8d3aecdcd3b14d90428869fde4ed98
S: 92f2bdb68cc3ff268397e4af37ece72be11009df 172.38.0.16:6379
   replicates fe99d242067af86f124bcc691a682b25345e209c
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: 1ac333a27b8d3aecdcd3b14d90428869fde4ed98 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 0015c60ff195dfd1a723a96ea327cec6f7fc0413 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 1ac333a27b8d3aecdcd3b14d90428869fde4ed98
S: 174b8a5fddbf7741aa517af5ae465960ee9fb7c9 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 8cf43330c5eac644e5b94c608d26902097760dc1
M: 8cf43330c5eac644e5b94c608d26902097760dc1 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 92f2bdb68cc3ff268397e4af37ece72be11009df 172.38.0.16:6379
   slots: (0 slots) slave
   replicates fe99d242067af86f124bcc691a682b25345e209c
M: fe99d242067af86f124bcc691a682b25345e209c 172.38.0.12:6379
   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.

查看集群信息 cluster info

root@7593134c0dcb:/data# redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:279
cluster_stats_messages_pong_sent:287
cluster_stats_messages_sent:566
cluster_stats_messages_ping_received:282
cluster_stats_messages_pong_received:279
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:566

执行一次操作,设置一个值 (工作被集群分配)

127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
# 在redis-1上操作,redis集群分配给redis-3来做

关闭redis-3,在redis-1上尝试获取刚刚设置的键值对

[root@VM-8-9-centos ~]# docker stop redis-3

发现可以获取到值,是从redis-4上获取的

127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"

SpringBoot微服务打包Docker镜像

  1. 构建SpringBoot项目
    提供一个接口在这里插入图片描述

  2. 打包应用
    在这里插入图片描述

  3. 编写DockerFile
    在这里插入图片描述

  4. 上传文件到Linux服务器

    [root@VM-8-9-centos idea]# ls
    Dockerfile  docker-helloword-0.0.1-SNAPSHOT.jar
    
  5. 构建镜像

    [root@VM-8-9-centos idea]# docker build -t hello-world .
    Sending build context to Docker daemon  16.57MB
    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
     ---> 7e9f8828aabf
    Step 3/5 : CMD ["--server.port=8080"]
     ---> Running in bd687d1d5906
    Removing intermediate container bd687d1d5906
     ---> 9be40d171a2d
    Step 4/5 : EXPOSE 8080
     ---> Running in aa4d5a1dae1e
    Removing intermediate container aa4d5a1dae1e
     ---> 93af34491a63
    Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
     ---> Running in 4d3a39d54159
    Removing intermediate container 4d3a39d54159
     ---> fb1f931c9420
    Successfully built fb1f931c9420
    Successfully tagged hello-world:latest
    
  6. 发布运行

    [root@VM-8-9-centos idea]# docker run -d -p 8688:8080 hello-world --name hello01
    e3e9b325660cee49b231e8799567934ed5accdc3f4b2dd237456595916404c38
    [root@VM-8-9-centos idea]# curl localhost:8688
    Hello world!
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值