Docker笔记

1.Docker 入门

1.1.Docker概述

Docker为什么出现?

  • 一款产品: 开发–上线 两套环境 应用环境 应用配置!

  • 开发 — 运维 问题:我在我的电脑上可以运行

  • 版本更新 导致服务不可用 对于运维来说考验十分大

  • 环境配置是十分的麻烦 每一个及其都要部署环境(集群Redis、ES、Hadoop…) 费事费力

  • 发布一个项目( jar + (Redis MySQL JDK ES) ) 项目能不能带上环境安装打包

  • 服务器配置一个应用的环境 Redis MySQL JDK ES Hadoop 配置超麻烦了 不能够跨平台

  • 开发环境Windows 最后发布到Linux

  • 传统:开发jar 运维来做

  • 现在:开发打包部署上线 一套流程做完

  • 安卓流程:java — apk —发布(应用商店)一 张三使用apk一安装即可用!

  • docker流程: java-jar(环境) — 打包项目帯上环境(镜像) — ( Docker仓库:商店)

  • Docker给以上的问题,提出了解决方案

image

Docker的思想就来自于集装箱

  • JRE – 多个应用(端口冲突) – 原来都是交叉的隔离

  • Docker核心思想 打包装箱 每个箱子是互相隔离的

  • Docker通过隔离机制 可以将服务器利用到极致

  • 本质:所有的技术都是因为出现了一些问题 我们需要去解决 才去学习

1.2.Docker历史

  • 2010年 几个的年轻人 就在美国成立了一家公司 dotcloud

  • 做一些pass的云计算服务!LXC(Linux Container容器)有关的容器技术

  • Linux Container容器是一种内核虚拟化技术 可以提供轻量级的虚拟化 以便隔离进程和资源

  • 他们将自己的技术(容器化技术)命名就是 Docker

  • Docker刚刚延生的时候 没有引起行业的注意 dotCloud 就活不下去 所以就开源

开源

  • 2013年 Docker开源
  • 越来越多的人发现docker的优点 火了
  • Docker每个月都会更新一个版本
  • 2014年4月9日,Docker1.0发布

docker为什么这么火

  • 十分的轻巧

  • 在容器技术出来之前 我们都是使用虚拟机技术

  • 虚拟机:在window中装一个VMware 通过这个软件我们可以虚拟出来一台或者多台电脑 笨重

  • 虚拟机也属于虚拟化技术 Docker容器技术 也是一种虚拟化技术

VMware : linux centos 原生镜像(一个电脑!) 隔离、需要开启多个虚拟机! 几个G 几分钟
docker: 隔离,镜像(最核心的环境 4m + jdk + mysql)十分的小巧,运行镜像就可以了!小巧! 几个M 秒级启动!

聊聊Docker

Docker基于Go语言开发的!开源项目!

docker官网:https://www.docker.com/

文档:https://docs.docker.com/ Docker的文档是超级详细的

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

1.3.Docker能干嘛

之前的虚拟机技术

image

虚拟机技术缺点

  1. 资源占用十分多

  2. 冗余步骤多

  3. 3启动很慢

容器化技术

容器化技术不是模拟一个完整的操作系统

image

比较Docker和虚拟机技术的不同:

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

DevOps(开发、运维)

应用更快速的交付和部署

  • 传统:一对帮助文档 安装程序。

  • Docker:打包镜像发布测试一键运行

更便捷的升级和扩缩容

  • 使用了 Docker之后 我们部署应用就和搭积木一样

  • 项目打包为一个镜像 扩展服务器A 服务器B更简单的系统运维

  • 在容器化之后,我们的开发 测试环境都是高度一致的

更高效的计算资源利用

Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。

2.Docker安装

2.1.Docker的基本组成

image

镜像(image):

  • docker镜像就好比是一个目标,可以通过这个目标来创建容器服务,tomcat镜像>run>容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)

容器(container):

  • Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的

  • 启动,停止,删除,基本命令

  • 目前就可以把这个容器理解为就是一个简易的 Linux系统

仓库(repository):

  • 仓库就是存放镜像的地方

  • 仓库分为公有仓库和私有仓库 (很类似git)

  • Docker Hub是国外的

  • 阿里云…都有容器服务器(配置镜像加速!)

2.2.安装Docker

环境准备

1.Linux要求内核3.0以上

2.CentOS 7

# 系统内核
[root@localhost /]# uname -r
3.10.0-1160.76.1.el7.x86_64	# 要求3.0以上
# 系统版本
[root@localhost /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

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

安装Docker

帮助文档:https://docs.docker.com/engine/install/
卸载与安装

#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 \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
#更新yum软件包索引
yum makecache fast

#4.安装docker相关的 docker-ce 社区版 docker-ee 企业版
    yum install docker-ce docker-ce-cli containerd.io # 这里我们使用社区版即可

#5.启动docker
systemctl start docker

#6. 使用docker version查看是否按照成功
docker version

image

#7. 测试
docker run hello-world

image

#8.查看已经下载的镜像(从这里可以查看已有镜像的id)
[root@localhost /]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB

卸载docker

#1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2. 删除资源
rm -rf /var/lib/docker
# /var/lib/docker 是docker的默认工作路径!

2.3.阿里云镜像加速

1.1.登录阿里云找到容器服务

image

1.2.找到镜像加速器

image

1.3.配置使用

#1.创建一个目录
sudo mkdir -p /etc/docker

#2.编写配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://oltiqh2r.mirror.aliyuncs.com"]
}
EOF

#3.重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker

2.4.回顾HelloWorld流程

image

docker run 流程图

image

底层原理

Docker是怎么工作的

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!

Docker-Server接收到Docker-Client的指令,就会执行这个命令!

image

为什么Docker比Vm快

1.docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
2.docker利用的是宿主机的内核,而不需要Guest OS。

GuestOS: VM(虚拟机)里的的系统(OS)

HostOS:物理机里的系统(OS)

image

因此,当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引导、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟。

image

3.Docker的常用命令

3.1.帮助命令

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

帮助文档的地址:https://docs.docker.com/engine/reference/commandline/build/

3.2.镜像命令

docker images #查看所有本地主机上的镜像 可以使用docker image ls代替

docker search #搜索镜像

docker pull #下载镜像 docker image pull

docker rmi #删除镜像 docker image rm

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

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


# 解释
#REPOSITORY			# 镜像的仓库源
#TAG				# 镜像的标签(版本)		---lastest 表示最新版本
#IMAGE ID			# 镜像的id
#CREATED			# 镜像的创建时间
#SIZE				# 镜像的大小

# 可选项
Options:
  -a, --all        # 列出所有镜像
  -q, --quiet      # 只显示镜像的id
  
# 列出所有镜像详细信息
[root@localhost ~]# docker images -a
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB

# docker images -aq #列出所有镜像的id
[root@localhost ~]# docker images -q
feb5d9fea6a5

docker search 搜索镜像

image

[root@localhost ~]# docker search mysql
NAME                            DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                           MySQL is a widely used, open-source relation…   13123     [OK]       
mariadb                         MariaDB Server is a high performing open sou…   5017      [OK]       
phpmyadmin                      phpMyAdmin - A web interface for MySQL and M…   621       [OK]       
percona                         Percona Server is a fork of the MySQL relati…   584       [OK]
     
# 可选项 docker search --help
[root@localhost ~]# docker search --help
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
      
# 过滤 搜索出来的镜像收藏STARS数量大于9000的 docker search mysql --filter=STARS=9000
[root@localhost ~]# docker search mysql --filter=STARS=9000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   13123     [OK]  

docker pull 下载镜像

# 下载镜像 docker pull 镜像名[:tag(版本)]
[root@localhost ~]# docker pull mysql
Using default tag: latest # 如果不写tag(版本) 默认就是latest(最新的)
latest: Pulling from library/mysql
72a69066d2fe: Pull complete # 分层下载:docker image 的核心 联合文件系统
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

#等价于
docker pull mysql
docker pull docker.io/library/mysql:latest

# 指定版本下载
[root@localhost ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists # 以前下载过了 可以共用的
93619dbc5b36: Already exists 
99da31dd6142: Already exists 
d2ba16033dad: Already exists 
0ceb82207cd7: Pull complete 
e2482e017e53: Pull complete 
70deed891d42: Pull complete 
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

image

docker rmi 删除镜像

# docker rmi 批量删除镜像 根据id指定删除镜像
[root@localhost ~]# docker rmi -f  c20987f18b13 镜像id 删除指定的镜像
 
docker rmi -f $(docker images -aq) # $(docker images -aq) 查出所有的镜像id 然后根据镜像id批量删除
[root@localhost~]# docker stop $(docker ps -a -q)

3.3.容器命令

说明:我们有了镜像才可以创建容器 Linux 下载centos镜像来学习

镜像下载
# docker中下载centos
docker pull centos
docker run 镜像id # 新建容器并启动

docker ps 列出所有运行的容器 docker container list

docker rm      容器id # 删除指定容器
docker start   容器id	# 启动容器
docker restart 容器id	# 重启容器
docker stop    容器id	# 停止当前正在运行的容器
docker kill    容器id	# 强制停止当前容器
[root@localhost~]# docker container list  #h和docker ps相同

image

新建容器并启动
docker run [可选参数] image | docker container run [可选参数] image 
#参书说明
--name ="Name" # 给容器赋值名字 用来区分
-d  		   # 后台方式运行 跟nohup相似
-i		       # 使用交互方式运行
-t   		   # 进入容器查看内容
-p			   # 指定容器的端口 -p 8080(宿主机):8080(容器)
		-p ip:主机端口:容器端口
		-p 主机端口:容器端口(常用)
		-p 容器端口
		容器端口
-P(大写) 				随机指定端口

# 测试、启动并进入容器   主机名称有区别就可以看出进没进容器 主机名字就是镜像Id
[root@localhost /]# docker run -it centos /bin/bash # 后面的/bin/bash的作用是表示载入容器后运行bash
													# docker中必须要保持一个进程的运行
													# 要不然整个容器启动后就会马上kill itself
													# 这样当你使用docker ps 查看启动的容器时
													# 就会发现你刚刚创建的那个容器并不在已启动的容器队列中
													# 这个/bin/bash就表示启动容器后启动bash

[root@e3e1a08cff7a /]# ls 查看容器内的Centos 基础版本 很多命令都是不完善的
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@e3e1a08cff7a /]# exit #从容器退回主机
exit

image

列出所有运行的容器
docker ps 命令  		# 列出当前正在运行的容器
  -a, --all     	 # 列出当前正在运行的容器 + 带出历史运行过的容器
  -n=?, --last int   # 列出最近创建的?个容器 ?为1则只列出最近创建的一个容器,为2则列出2个
  -q, --quiet        # 只列出容器的编号

image

image

退出容器
exit 		# 容器直接退出
ctrl +P +Q  # 容器不停止退出 	---注意:这个很有用的操作
删除容器
docker rm 容器id   				# 删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -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	# 强制停止当前容器

3.4.常用其他命令

后台启动命令
# 命令 docker run -d 镜像名
[root@localhost~]# docker run -d centos
a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c

[root@localhost ~]# docker ps    
CONTAINER ID      IMAGE       COMMAND    CREATED     STATUS   PORTS    NAMES
# 问题docker ps. 发现centos 停止了
# 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志
# 查看关于日志的信息以及怎么使用
docker logs --help 

# 自己编写一个小脚本让他有日志信息否则运行时没有日志信息
docker run -d centos /bin/sh -c "while true;do echo 6666;sleep 1;done" #模拟日志      

# 显示日志
-tf --tail number	# 显示日志信息 -t是显示时间 -f持续更新显示 --tail number 显示number条日志

# 查看n行日志
docker logs -t --tail n 容器id 

# 显示全部日志信息 并且持续更新
docker logs -tf 容器id

image

查看容器中进程信息ps
# 命令 docker top 容器id 查看容器中的进程
docker top 2e01b3333cbc

image

查看镜像的元数据(容器的内部信息)
# 命令
docker inspect 容器id

#测试
docker inspect 55321bcae33d
[root@localhost ~]# docker inspect c109c4603669
[
    {
        "Id": "c109c4603669d78a269a0fea6f0e4f5333e6067ec64a7120b0e6990f4e2bd9db", # 容器id
        "Created": "2022-09-05T14:20:09.367362185Z",
        "Path": "/bin/sh", # 开启一个shell终端 
        "Args": [
            "-c", # 容器执行脚本
            "while true;do echo 6666;sleep 1;done"
        ],
        "State": {
            "Status": "running", # 容器的状态
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 76269,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-09-05T14:20:09.607130704Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/c109c4603669d78a269a0fea6f0e4f5333e6067ec64a7120b0e6990f4e2bd9db/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/c109c4603669d78a269a0fea6f0e4f5333e6067ec64a7120b0e6990f4e2bd9db/hostname",
        "HostsPath": "/var/lib/docker/containers/c109c4603669d78a269a0fea6f0e4f5333e6067ec64a7120b0e6990f4e2bd9db/hosts",
        "LogPath": "/var/lib/docker/containers/c109c4603669d78a269a0fea6f0e4f5333e6067ec64a7120b0e6990f4e2bd9db/c109c4603669d78a269a0fea6f0e4f5333e6067ec64a7120b0e6990f4e2bd9db-json.log",
        "Name": "/amazing_swartz",
        "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/dc5afe1a107eb52814a2aa197dab799b3520fadf45c5c325840524658b816412-init/diff:/var/lib/docker/overlay2/1df4d2ed45f644912e8bbb015da6068ce2dc4f149d0ce20c44586acc773fc61a/diff",
                "MergedDir": "/var/lib/docker/overlay2/dc5afe1a107eb52814a2aa197dab799b3520fadf45c5c325840524658b816412/merged",
                "UpperDir": "/var/lib/docker/overlay2/dc5afe1a107eb52814a2aa197dab799b3520fadf45c5c325840524658b816412/diff",
                "WorkDir": "/var/lib/docker/overlay2/dc5afe1a107eb52814a2aa197dab799b3520fadf45c5c325840524658b816412/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "c109c4603669",
            "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 6666;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": "662462c192e051bb49eb3df2b13fc33a0429f288ab2bb44df5ad3e1b33c7426f",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/662462c192e0",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "234ee1328ec1c365cb6b7f0171c49bf40f8457a1eb517436cc4fff2caae51e74",
            "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": "6057227c558119251707b6c0db6330684e5a254cf2946c6f8b2924c7776200c7",
                    "EndpointID": "234ee1328ec1c365cb6b7f0171c49bf40f8457a1eb517436cc4fff2caae51e74",
                    "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
                }
            }
        }
    }
]
进入当前正在运行的容器
# 我们通常容器都是在后台运行,需要进入容器,修改一些配置

# 方式一 开启一个新的bash或shell终端窗口
# 命令
docker exec -it 容器id bashshell

[sh-4.4# ~]# docker ps
[sh-4.4# ~]# ps -ef

image

# 方式二 不开启新的终端窗口 
dcoker attach 容器id
# 测试
[root@localhost ~]# docker attach dce7bshk8oou7
正在执行当前的代码...

# 区别
docker exec #进入容器后开启一个新的终端
docker attach # 进入容器正在执行的终端,不会启动新的进程

image

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

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

# 运行容器并且进入交互模式
[root@localhost /]# docker run -it centos /bin/bash
[root@a9525c9c9393 /]# cd home
[root@a9525c9c9393 home]# ls

# 在容器内部进行创建文件
[root@a9525c9c9393 home]# touch test.java
[root@a9525c9c9393 home]# ls     
test.java

# 退出容器并且不结束容器运行 查看正在运行的容器id
[root@a9525c9c9393 home]# [root@localhost /]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
a9525c9c9393   centos    "/bin/bash"   30 seconds ago   Up 29 seconds             beautiful_ritchie

# 进入容器
[root@localhost /]# docker attach a9525c9c9393

# 退出容器并且结束容器
[root@a9525c9c9393 home]# exit
exit

# 从容器中拷贝到本机
[root@localhost /]# docker cp a9525c9c9393:/home/test.java /home
[root@localhost /]# cd home

# 查看是否拷贝成功
[root@localhost home]# ls
test.java
[root@localhost home]# 
# 拷贝是一个手动过程,未来我们可以使用-v卷的技术,可以实现自动同步 /home /home

image

3.5.小结

docker中镜像和容器的区别:

1.镜像是包含了各种环境或者服务的一个模板 而容器是镜像的一个实例

2.镜像是不能运行的 是静态的 而容器是可以运行的 是动态的

image

命令大全

attach    Attach to a running container  				 # 当前shell下attach连接指定运行镜像
build     Build an image from a Dockerfile  			 # 通过Dockerfile定制镜像
commit    Create a new image from a containers changes   # 提交当前容器为新的镜像
cp    	  Copy files/folders from a container to a HOSTDIR or to STDOUT  # 从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container  						 # 创建一个新的容器,同run 但不启动容器
diff      Inspect changes on a containers filesystem  	 # 查看docker容器变化
events    Get real time events from the server			 # 从docker服务获取容器实时事件
exec      Run a command in a running container		     # 在已存在的容器上运行命令
export    Export a containers 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包中的内容创建一个新的文件系统映像(对应export)
info      Display system-wide information  									# 显示系统相关信息
inspect   Return low-level information on a container or image  			# 查看容器详细信息
kill      Kill a running container  					 # kill指定docker容器
load      Load an image from a tar archive or STDIN  	 # 从一个tar包中加载一个镜像(对应save)
login     Register or log in to a Docker registry		 # 注册或者登陆一个docker源服务器
logout    Log out from a Docker registry  				 # 从当前Docker registry退出
logs      Fetch the logs of a container  				 # 输出当前容器日志信息
pause     Pause all processes within a container		 # 暂停容器
port      List port mappings or a specific mapping for the CONTAINER  		# 查看映射端口对应的容器内部源端口
ps        List containers  								 # 列出容器列表
pull      Pull an image or a repository from a registry  # 从docker镜像源服务器拉取指定镜像或者库镜像
push      Push an image or a repository to a registry  	 # 推送指定镜像或者库镜像至docker源服务器
rename    Rename a container  												# 重命名容器
restart   Restart a running container  										# 重启运行的容器
rm        Remove one or more containers  									# 移除一个或者多个容器
rmi       Remove one or more images  # 移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run       Run a command in a new container  								# 创建一个新的容器并运行一个命令
save      Save an image(s) to a tar archive									# 保存一个镜像为一个tar包(对应load)
search    Search the Docker Hub for images  								# 在docker
hub中搜索镜像
start     Start one or more stopped containers								# 启动容器
stats     Display a live stream of container(s) resource usage statistics  	# 统计容器使用资源
stop      Stop a running container  										# 停止容器
tag       Tag an image into a repository  									# 给源中镜像打标签
top       Display the running processes of a container 						# 查看容器中运行的进程信息
unpause   Unpause all processes within a container  						# 取消暂停容器
version   Show the Docker version information								# 查看容器版本号
wait      Block until a container stops, then print its exit code  			# 截取容器停止时的退出状态值

3.6.作业练习(安装)

作业一:Docker 安装Nginx

# 1.搜索镜像
[root@localhost ~]# docker search nginx

image

# 2.拉取镜像
[root@localhost ~]# docker pull nginx

image

# 3.查看镜像
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
nginx         latest    605c77e624dd   8 months ago    141MB
mysql         latest    3218b38490ce   8 months ago    516MB
hello-world   latest    feb5d9fea6a5   11 months ago   13.3kB
centos        latest    5d0da3dc9764   11 months ago   231MB

image

# 4.启动运行
[root@localhost ~]# docker run -d --name nginx01 -p 3344:80 nginx
66f84ea1a1679cc5f062e4c7aab26f051d30df710e23e7685597257933eb7d61
# -d 后台运行
# --name 给容器起名字
# -p 宿主机端口:容器内部端口

image

# 5.查看运行情况
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
d320470acea6   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01

image

# 6.本机自测运行情况
[root@localhost ~]# 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>
# 成功访问nginx80 端口

image

外部也可以访问到

image

# 7.进入容器,修改配置
[root@localhost ~]# docker exec -it nginx01 /bin/bash
root@d320470acea6:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@d320470acea6:/# cd /etc/nginx
root@d320470acea6:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@d320470acea6:/etc/nginx# 

image

端口暴露的概念

image

思考问题:我们每次都需要改动nginx配置,都需要进入容器内部?十分的麻烦,我们要是可以在容器外部提供一个映射路径,达到可以在容器外部修改文件名,容器内部就可以进行自动修改?-数据卷

作业二:用docker 来装一个tomcat

# 1.搜索镜像
[root@localhost ~]# docker search tomcat

image

# 2.拉取镜像
[root@localhost ~]# docker pull tomcat

image

# 3.查看镜像
[root@localhost ~]# docker images

image

# 4.启动运行
[root@localhost ~]# docker run -d --name tomcat01 -p 3355:8080 tomcat
360c1575e51593850917c7835c6b3e9b02d5cb54f3630f4c493dcb1d108b8581
# -d 后台运行
# --name 给容器起名字
# -p 宿主机端口:容器内部端口

image

# 5.测试访问没有问题

image

# 5.1.发现问题
# 但是我们发现了一个问题 这个tomcat不完整
# linux命令少了 webapps目录为空 
# 原因:阿里云镜像默认是最小的 把所有不必要的都剔除掉
# 保证最小可运行的环境

image

# 5.2.解决方法
# 方式一:将webapps.dist下的文件都拷贝到webapps下即可
# 方式二:将webapps.dist改名成webapps即可
# 这样docker部署tomcat就可以访问了

image

# 扩展
# 下载 tomcat9.0
# 之前的启动都是后台,停止了容器,容器还是可以查到, docker run -it --rm 镜像名 一般是用来测试,用完就删除
[root@localhost ~]# docker run -it --rm tomcat:9.0

image

# 扩展
# 已经运行了tomcat 我们把它停止看一下是否删除了    并没有已经删除了

image

问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?要是可以在容器外部提供一个映射路径,比如webapps,我们在外部放置项目,就自动同步内部就好了!

作业三:部署elasticsearch+kibana

# Elasticsearch 暴露的端口很多
# Elasticsearch 十分耗内存
# Elasticsearch 的数据一般需要放置到安全目录!挂载
# --net somenetwork ? 网络配置

# 启动Elasticsearch
[root@localhost ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

# 测试一下启动Elasticsearch是否成功启动
[root@localhost ~]# curl localhost:9200
{
  "name" : "f93e12029746",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "TQ35zd5tRaKE7tYkcQXm3w",
  "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"
}

# 测试成功就关掉Elasticsearch 防止耗内存
[root@localhost ~]# docker stop f93e12029746
f93e12029746

# 查看docker容器使用内存情况
[root@localhost ~]# docker stats  

image

# 测试成功就关掉Elasticsearch 增加内存的限制 修改配置文件 -e 环境配置修改               
[root@localhost ~]#docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

# 查看状态
docker stats 3553281f0124

image

# 访问成功
[root@localhost ~]# curl localhost:9200
{
  "name" : "3553281f0124",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "ADbhVlrORX-900UonZqA_w",
  "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"
}

image

作业三:使用kibana连接es (elasticSearch)?思考网络如何才能连接

image

Portainer 可视化面板安装

  • portainer(先用这个)
docker run -d -p 8080:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • Rancher(CI/CD再用)
    什么是portainer?

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

# 安装命令
[root@localhost home]# docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete 
49d59ee0881a: Pull complete 
a2300fd28637: Pull complete 
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
b7213da870de3fb291a30d24471b689306b0109faf5b28aca19d697f01c6cf7f

image

  • 设置密码登录上去选择本地

    image

  • 进入之后的面板

    image

4.镜像原理之联合文件系统

4.1.镜像是什么

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

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

如何得到镜像:

  • 从远处仓库下载
  • 朋友拷贝给你
  • 自己制作一个镜像DockerFile

4.2.Docker镜像加载原理

  1. UnionFS(联合文件系统)

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

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

  1. 镜像加载原理

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

rootfs (root file system),在bootfs之上。包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

平时我们安装虚拟机的centos都是好几个G,为什么Docker这里才200M?

image

对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

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

4.3.分层的镜像

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

image

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

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

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

[root@localhost ~]# docker image inspect redis:latest

"RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:7e718b9c0c8c2e6420fe9c4d1d551088e314fe923dce4b2caf75891d82fb227d",
                "sha256:89ce1a07a7e4574d724ea605b4877f8a73542cf6abd3c8cbbd2668d911fa5353",
                "sha256:9eef6e3cc2937e452b2325b227ca28120a70481be25404ed9aad27fa81219fd0",
                "sha256:ee748697d275b904f1d5604345d70b647a8c145b9f05aeb5ca667e1f256e43d8",
                "sha256:f1f7964d40afa49c6ef63ab11af91044e518a2539f567783ce997d3cea9ce8f6",
                "sha256:3d9fda8ff875e549d54e9d7504ce17d27423fe27dafbb92127c603dddad7fa13"
            ]
        },

理解

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

举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。

该镜像当前已经包含 3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
image

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

image

上图中的镜像层和之前的图中略有区别,主要目的是便于展示文件

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层的文件7是文件5的一个更新版

image

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。 Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系統。 Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

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

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

image

特点

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

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

image

4.4.commit镜像

docker commit	  # 提交容器成为一个新的副本 
docker commit -m  # "提交的描述信息" -a="作者" 容器id 目标镜像名:[tag] 命令和git原理类似

实战测试

# 1.启动一个默认的tomcat

# 2.发现这个默认的tomcat是没有webapps应用的 镜像的原因:官方镜像默认webapps下面没有文件的

# 3.我自己拷贝进去了基本的文件

image

# 4.将我们自己操作过后的容器通过commit提交为一个镜像 我们以后就可以使用自己修改过的镜像 这就是我们自己的一个修改过的镜像
[root@localhost ~]# docker commit -a="xiao" -m="add webapps app" a0d539971acd tomcat02:1.0
sha256:ab7aa3ba7a164203e1f9a5bd8d8f633a64a2e184cdd82301c3ee6a6e49cb8f3a 

image

# 5.查看我们提交的镜像
docker images

image

如果你想要保存当前的状态 就通过commit提交 获得一个镜像 就好比我们以前学习VM时候 快照

5. 容器数据卷

5.1.什么是容器数据卷

docker的理念回顾

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

  • 数据问题 如果数据都在容器中 那么我们容器删除 数据就会丢失 需求:数据可以持久化

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

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

这就是卷技术,目录的挂载,将容器内的目录挂载在Linux上面

image

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

5.2.使用命令来挂载

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

# 测试
[root@localhost home]#  docker run -it -v /home/ceshi:/home centos /bin/bash

# 容器启动的时候我们可以通过docker inspect 容器id 去查看容器相信信息

image

测试文件的同步

image

再来测试

  1. 停止容器

  2. 宿主机上修改文件

  3. 启动容器

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

image

优点:我们以后修改只需要在本地进行修改即可 容器内部会自动进行同步

实战:安装MySQL

# 获取镜像
[root@localhost ~]# docker pull mysql:5.7

# 运行容器,需要做数据挂载 安装MySQL需要配置密码 下面是官方命令
[root@localhost ~]#docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

# 启动我们的-d后台运行 -p端口映射 -v数据卷挂载 -e环境配置 --name容器名字
[root@localhost /]# 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=123.com --name mysql01 mysql

image

# 启动成功后 我们在本地使用Navict来测试连接一下
# Navict连接到服务器3310后 3310和容器内部的3306进行映射 这个时候就可以连接上了

# 本地测试新建数据库 查看映射的路径是否可以同步数据

image

假设我们把容器删除

image

5.3.具名和匿名挂载

# 匿名挂载 -v只指定了容器内的路径 没有指定容器外的路径
[root@localhost /]# docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有的volume的情况
[root@localhost /]# docker volume ls

image

# 具名挂载 -v指定了容器外的路径 也指定卷名  # -v /juming-nginx 这个是指定路径 juming-nginx 这个是卷名
[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx  


# 查看所有的volume的情况
[root@localhost /]# docker volume ls

image

# 通过查看volume就可以看到 卷名:容器内路径
[root@localhost /]# docker volume inspect juming-nginx

image

# 进入这个路径 查看一下
[root@localhost /]# cd /var/lib/docker/volumes/juming-nginx/_data/

# 查看一下是否有nginx的配置文件
[root@localhost _data]# ls
# 看到了nginx的配置文件 证明拿到了nginx的配置文件 没有错

image

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

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

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

拓展

# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写

# 一旦设置了这个容器权限 容器对我们挂载出来的内容就有了限制了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v /etc/nginx:ro nginx

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
docker run -d -P --name nginx02 -v /etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作 容器内部是无法进行操作的

5.4.初识DockerFile

DockerFile就是用来构建docker镜像的构建文件 命令脚本 先体验一下

通过这个脚本可以生成一个镜像 镜像是一层层的 所以脚本是一个个的命令

# 文件中的内容 命令(大写) 
# 参数:
#    FROM centos 						# 当前构建这个镜像 以centos为基础
# 	 VOLUME ["volume01","volume02"] 	# 生成的时候就挂载卷
#  	 CMD echo "---end---" 				# 构建成功之后输出end
#	 CMD /bin/bash 						# 构建成功后默认走的是bash控制台
# 	 这里的每个命令就是镜像的一层

image

# 创建一个dockerfile文件 名字可以随机 建议Dockerfile
[root@localhost docker-test-volume]docker build -f /home/docker-test-volume/dockerfile1 -t xiao/centos:1.0 .
# build 		# 构建一个镜像
# -f 			# 通过-f指定的文件来构建镜像
# -t			# 生成(name)镜像
# .				# 当前目录下

image

# 查看一下是否构建镜像成功
docker images 

image

# 启动一下自己写的容器

image

这个卷和外部一定有一个同步的目录

image

查看一下卷挂载的路径

[root@localhost data]# docker inspect fca535846c94

image

# 测试一下文件是否已经被同步出去了
[root@localhost _data]# cd /var/lib/docker/volumes/a15fa5acea56bd53fae7fc7b71a328cf26a6a2eb5c38b76ee7cdf5bf917dbe1e/_data
[root@localhost _data]# ls

image

这种方式未来的使用非常多 因为我们自己通常会构建自己的镜像

假设构建镜像的时候没有挂载 需要自己手动挂载镜像 -v 卷名:容器内路径

5.5.数据卷容器

多个MySQL同步数据

image

启动3个容器 通过我们刚在自己写的镜像启动

启动第一个容器

image

启动第二个容器

image

docker01的数据同步到了docker02

image

image

启动第三个容器并且也挂载docker01

image

# 测试 :可以删除容器dcoker01,查看docker02和docker03时候还可以访问这个文件

image

# 测试结果是依然可以访问到

image

image

多个MySQL实现数据共享

# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=338218 --name mysql01 mysql:5.7
# docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=338218 --name mysql02 --volumes-from mysql01 mysql:5.7# # 这个时候可以实现两个容器数据同步

结论:

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

但是一旦持久化到了本地 这个时候 本地的数据不会被删除

6.DockerFile

6.1.DockerFile介绍

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

构建步骤:

  1. 编写一个dockerfile文件

  2. docker build构建为一个镜像

  3. docker run 运行镜像

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

查看一下官方是怎么做的

image

image

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

官方可以制作镜像 那我们也可以

6.2.DockerFile镜像的构建

基础知识:

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

  2. 执行从上到下顺序执行

  3. 表示注释

  4. 每一个指令都会创建提交一个新的镜像层,并提交

image

  • dockerfile是面向开发的 我们以后要发布项目 做镜像 就需要编写dockerfile文件 这个文件十分简单

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

  • 步骤:开发 部署,运维…缺一不可

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

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

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

6.3.Docker指令

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

image

6.4.实战训练

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

image

创建一个自己的centos

# 1、编写Dockerfile文件[root@localhost dockerfile]# cat mydockerfile-centos FROM centosMAINTAINER eric<doctor_eric@163.com>ENV MYPATH /usr/localWORKDIR $MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD echo "----end----"CMD /bin/bash# 2、通过这个文件构建镜像# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]Successfully built dc4556607d09Successfully tagged mycentos:0.1# 3、测试运行

对比:之前原生的centos

image

# 1.编写 Dockerfile文件
[root@localhost dockerfile]# vim myDockerfile
[root@localhost dockerfile]# cat myDockerfile 
FROM centos:7
MAINTAINER xiao<1559567258@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

image

# 2.通过这个myDockerfile文件构建镜像
[root@localhost dockerfile]# docker build -f myDockerfile -t mycentos:0.1 .
Sending build context to Docker daemon  2.048kB
Step 1/11 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/11 : MAINTAINER xiao<1559567258@qq.com>
 ---> Using cache
 ---> 3bce5ca94a90
Step 3/11 : ENV MYPATH /usr/local
 ---> Using cache
 ---> d7b10d43dfd9
Step 4/11 : WORKDIR $MYPATH
 ---> Using cache
 ---> 2798b9857343
Step 5/11 : RUN yum install vim
 ---> Running in f9c8c6aa2670
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.huaweicloud.com
 * extras: mirrors.neusoft.edu.cn
 * updates: mirrors.neusoft.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package vim-enhanced.x86_64 2:7.4.629-8.el7_9 will be installed
--> Processing Dependency: vim-common = 2:7.4.629-8.el7_9 for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: which for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: perl(:MODULE_COMPAT_5.16.3) for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: libperl.so()(64bit) for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: libgpm.so.2()(64bit) for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Running transaction check
---> Package gpm-libs.x86_64 0:1.20.7-6.el7 will be installed
---> Package perl.x86_64 4:5.16.3-299.el7_9 will be installed
--> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl-macros for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(threads::shared) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(threads) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(constant) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Time::Local) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Time::HiRes) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Storable) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Socket) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Pod::Simple::XHTML) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Pod::Simple::Search) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Getopt::Long) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Filter::Util::Call) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Temp) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Spec) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Path) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Exporter) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Cwd) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Carp) for package: 4:perl-5.16.3-299.el7_9.x86_64
---> Package perl-libs.x86_64 4:5.16.3-299.el7_9 will be installed
---> Package vim-common.x86_64 2:7.4.629-8.el7_9 will be installed
--> Processing Dependency: vim-filesystem for package: 2:vim-common-7.4.629-8.el7_9.x86_64
---> Package which.x86_64 0:2.20-7.el7 will be installed
--> Running transaction check
---> Package perl-Carp.noarch 0:1.26-244.el7 will be installed
---> Package perl-Exporter.noarch 0:5.68-3.el7 will be installed
---> Package perl-File-Path.noarch 0:2.09-2.el7 will be installed
---> Package perl-File-Temp.noarch 0:0.23.01-3.el7 will be installed
---> Package perl-Filter.x86_64 0:1.49-3.el7 will be installed
---> Package perl-Getopt-Long.noarch 0:2.40-3.el7 will be installed
--> Processing Dependency: perl(Pod::Usage) >= 1.14 for package: perl-Getopt-Long-2.40-3.el7.noarch
--> Processing Dependency: perl(Text::ParseWords) for package: perl-Getopt-Long-2.40-3.el7.noarch
---> Package perl-PathTools.x86_64 0:3.40-5.el7 will be installed
---> Package perl-Pod-Simple.noarch 1:3.28-4.el7 will be installed
--> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.28-4.el7.noarch
--> Processing Dependency: perl(Encode) for package: 1:perl-Pod-Simple-3.28-4.el7.noarch
---> Package perl-Scalar-List-Utils.x86_64 0:1.27-248.el7 will be installed
---> Package perl-Socket.x86_64 0:2.010-5.el7 will be installed
---> Package perl-Storable.x86_64 0:2.45-3.el7 will be installed
---> Package perl-Time-HiRes.x86_64 4:1.9725-3.el7 will be installed
---> Package perl-Time-Local.noarch 0:1.2300-2.el7 will be installed
---> Package perl-constant.noarch 0:1.27-2.el7 will be installed
---> Package perl-macros.x86_64 4:5.16.3-299.el7_9 will be installed
---> Package perl-threads.x86_64 0:1.87-4.el7 will be installed
---> Package perl-threads-shared.x86_64 0:1.43-6.el7 will be installed
---> Package vim-filesystem.x86_64 2:7.4.629-8.el7_9 will be installed
--> Running transaction check
---> Package perl-Encode.x86_64 0:2.51-7.el7 will be installed
---> Package perl-Pod-Escapes.noarch 1:1.04-299.el7_9 will be installed
---> Package perl-Pod-Usage.noarch 0:1.63-3.el7 will be installed
--> Processing Dependency: perl(Pod::Text) >= 3.15 for package: perl-Pod-Usage-1.63-3.el7.noarch
--> Processing Dependency: perl-Pod-Perldoc for package: perl-Pod-Usage-1.63-3.el7.noarch
---> Package perl-Text-ParseWords.noarch 0:3.29-4.el7 will be installed
--> Running transaction check
---> Package perl-Pod-Perldoc.noarch 0:3.20-4.el7 will be installed
--> Processing Dependency: perl(parent) for package: perl-Pod-Perldoc-3.20-4.el7.noarch
--> Processing Dependency: perl(HTTP::Tiny) for package: perl-Pod-Perldoc-3.20-4.el7.noarch
--> Processing Dependency: groff-base for package: perl-Pod-Perldoc-3.20-4.el7.noarch
---> Package perl-podlators.noarch 0:2.5.1-3.el7 will be installed
--> Running transaction check
---> Package groff-base.x86_64 0:1.22.2-8.el7 will be installed
---> Package perl-HTTP-Tiny.noarch 0:0.033-3.el7 will be installed
---> Package perl-parent.noarch 1:0.225-244.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                    Arch       Version                Repository   Size
================================================================================
Installing:
 vim-enhanced               x86_64     2:7.4.629-8.el7_9      updates     1.1 M
Installing for dependencies:
 gpm-libs                   x86_64     1.20.7-6.el7           base         32 k
 groff-base                 x86_64     1.22.2-8.el7           base        942 k
 perl                       x86_64     4:5.16.3-299.el7_9     updates     8.0 M
 perl-Carp                  noarch     1.26-244.el7           base         19 k
 perl-Encode                x86_64     2.51-7.el7             base        1.5 M
 perl-Exporter              noarch     5.68-3.el7             base         28 k
 perl-File-Path             noarch     2.09-2.el7             base         26 k
 perl-File-Temp             noarch     0.23.01-3.el7          base         56 k
 perl-Filter                x86_64     1.49-3.el7             base         76 k
 perl-Getopt-Long           noarch     2.40-3.el7             base         56 k
 perl-HTTP-Tiny             noarch     0.033-3.el7            base         38 k
 perl-PathTools             x86_64     3.40-5.el7             base         82 k
 perl-Pod-Escapes           noarch     1:1.04-299.el7_9       updates      52 k
 perl-Pod-Perldoc           noarch     3.20-4.el7             base         87 k
 perl-Pod-Simple            noarch     1:3.28-4.el7           base        216 k
 perl-Pod-Usage             noarch     1.63-3.el7             base         27 k
[root@localhost dockerfile]# docker build -f myDockerfile -t mycentos:0.1 .
Sending build context to Docker daemon  2.048kB
Step 1/10 : FROM centos:7
 ---> eeb6ee3f44bd
Step 2/10 : MAINTAINER xiao<1559567258@qq.com>
 ---> Using cache
 ---> 3bce5ca94a90
Step 3/10 : ENV MYPATH /usr/local
 ---> Using cache
 ---> d7b10d43dfd9
Step 4/10 : WORKDIR $MYPATH
 ---> Using cache
 ---> 2798b9857343
Step 5/10 : RUN yum -y install vim
 ---> Running in 91b1fa8ad6af
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirrors.tuna.tsinghua.edu.cn
 * extras: mirrors.bupt.edu.cn
 * updates: mirrors.bupt.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package vim-enhanced.x86_64 2:7.4.629-8.el7_9 will be installed
--> Processing Dependency: vim-common = 2:7.4.629-8.el7_9 for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: which for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: perl(:MODULE_COMPAT_5.16.3) for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: libperl.so()(64bit) for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Processing Dependency: libgpm.so.2()(64bit) for package: 2:vim-enhanced-7.4.629-8.el7_9.x86_64
--> Running transaction check
---> Package gpm-libs.x86_64 0:1.20.7-6.el7 will be installed
---> Package perl.x86_64 4:5.16.3-299.el7_9 will be installed
--> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl-macros for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(threads::shared) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(threads) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(constant) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Time::Local) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Time::HiRes) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Storable) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Socket) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Pod::Simple::XHTML) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Pod::Simple::Search) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Getopt::Long) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Filter::Util::Call) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Temp) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Spec) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(File::Path) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Exporter) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Cwd) for package: 4:perl-5.16.3-299.el7_9.x86_64
--> Processing Dependency: perl(Carp) for package: 4:perl-5.16.3-299.el7_9.x86_64
---> Package perl-libs.x86_64 4:5.16.3-299.el7_9 will be installed
---> Package vim-common.x86_64 2:7.4.629-8.el7_9 will be installed
--> Processing Dependency: vim-filesystem for package: 2:vim-common-7.4.629-8.el7_9.x86_64
---> Package which.x86_64 0:2.20-7.el7 will be installed
--> Running transaction check
---> Package perl-Carp.noarch 0:1.26-244.el7 will be installed
---> Package perl-Exporter.noarch 0:5.68-3.el7 will be installed
---> Package perl-File-Path.noarch 0:2.09-2.el7 will be installed
---> Package perl-File-Temp.noarch 0:0.23.01-3.el7 will be installed
---> Package perl-Filter.x86_64 0:1.49-3.el7 will be installed
---> Package perl-Getopt-Long.noarch 0:2.40-3.el7 will be installed
--> Processing Dependency: perl(Pod::Usage) >= 1.14 for package: perl-Getopt-Long-2.40-3.el7.noarch
--> Processing Dependency: perl(Text::ParseWords) for package: perl-Getopt-Long-2.40-3.el7.noarch
---> Package perl-PathTools.x86_64 0:3.40-5.el7 will be installed
---> Package perl-Pod-Simple.noarch 1:3.28-4.el7 will be installed
--> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.28-4.el7.noarch
--> Processing Dependency: perl(Encode) for package: 1:perl-Pod-Simple-3.28-4.el7.noarch
---> Package perl-Scalar-List-Utils.x86_64 0:1.27-248.el7 will be installed
---> Package perl-Socket.x86_64 0:2.010-5.el7 will be installed
---> Package perl-Storable.x86_64 0:2.45-3.el7 will be installed
---> Package perl-Time-HiRes.x86_64 4:1.9725-3.el7 will be installed
---> Package perl-Time-Local.noarch 0:1.2300-2.el7 will be installed
---> Package perl-constant.noarch 0:1.27-2.el7 will be installed
---> Package perl-macros.x86_64 4:5.16.3-299.el7_9 will be installed
---> Package perl-threads.x86_64 0:1.87-4.el7 will be installed
---> Package perl-threads-shared.x86_64 0:1.43-6.el7 will be installed
---> Package vim-filesystem.x86_64 2:7.4.629-8.el7_9 will be installed
--> Running transaction check
---> Package perl-Encode.x86_64 0:2.51-7.el7 will be installed
---> Package perl-Pod-Escapes.noarch 1:1.04-299.el7_9 will be installed
---> Package perl-Pod-Usage.noarch 0:1.63-3.el7 will be installed
--> Processing Dependency: perl(Pod::Text) >= 3.15 for package: perl-Pod-Usage-1.63-3.el7.noarch
--> Processing Dependency: perl-Pod-Perldoc for package: perl-Pod-Usage-1.63-3.el7.noarch
---> Package perl-Text-ParseWords.noarch 0:3.29-4.el7 will be installed
--> Running transaction check
---> Package perl-Pod-Perldoc.noarch 0:3.20-4.el7 will be installed
--> Processing Dependency: perl(parent) for package: perl-Pod-Perldoc-3.20-4.el7.noarch
--> Processing Dependency: perl(HTTP::Tiny) for package: perl-Pod-Perldoc-3.20-4.el7.noarch
--> Processing Dependency: groff-base for package: perl-Pod-Perldoc-3.20-4.el7.noarch
---> Package perl-podlators.noarch 0:2.5.1-3.el7 will be installed
--> Running transaction check
---> Package groff-base.x86_64 0:1.22.2-8.el7 will be installed
---> Package perl-HTTP-Tiny.noarch 0:0.033-3.el7 will be installed
---> Package perl-parent.noarch 1:0.225-244.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                    Arch       Version                Repository   Size
================================================================================
Installing:
 vim-enhanced               x86_64     2:7.4.629-8.el7_9      updates     1.1 M
Installing for dependencies:
 gpm-libs                   x86_64     1.20.7-6.el7           base         32 k
 groff-base                 x86_64     1.22.2-8.el7           base        942 k
 perl                       x86_64     4:5.16.3-299.el7_9     updates     8.0 M
 perl-Carp                  noarch     1.26-244.el7           base         19 k
 perl-Encode                x86_64     2.51-7.el7             base        1.5 M
 perl-Exporter              noarch     5.68-3.el7             base         28 k
 perl-File-Path             noarch     2.09-2.el7             base         26 k
 perl-File-Temp             noarch     0.23.01-3.el7          base         56 k
 perl-Filter                x86_64     1.49-3.el7             base         76 k
 perl-Getopt-Long           noarch     2.40-3.el7             base         56 k
 perl-HTTP-Tiny             noarch     0.033-3.el7            base         38 k
 perl-PathTools             x86_64     3.40-5.el7             base         82 k
 perl-Pod-Escapes           noarch     1:1.04-299.el7_9       updates      52 k
 perl-Pod-Perldoc           noarch     3.20-4.el7             base         87 k
 perl-Pod-Simple            noarch     1:3.28-4.el7           base        216 k
 perl-Pod-Usage             noarch     1.63-3.el7             base         27 k
 perl-Scalar-List-Utils     x86_64     1.27-248.el7           base         36 k
 perl-Socket                x86_64     2.010-5.el7            base         49 k
 perl-Storable              x86_64     2.45-3.el7             base         77 k
 perl-Text-ParseWords       noarch     3.29-4.el7             base         14 k
 perl-Time-HiRes            x86_64     4:1.9725-3.el7         base         45 k
 perl-Time-Local            noarch     1.2300-2.el7           base         24 k
 perl-constant              noarch     1.27-2.el7             base         19 k
 perl-libs                  x86_64     4:5.16.3-299.el7_9     updates     690 k
 perl-macros                x86_64     4:5.16.3-299.el7_9     updates      44 k
 perl-parent                noarch     1:0.225-244.el7        base         12 k
 perl-podlators             noarch     2.5.1-3.el7            base        112 k
 perl-threads               x86_64     1.87-4.el7             base         49 k
 perl-threads-shared        x86_64     1.43-6.el7             base         39 k
 vim-common                 x86_64     2:7.4.629-8.el7_9      updates     5.9 M
 vim-filesystem             x86_64     2:7.4.629-8.el7_9      updates      11 k
 which                      x86_64     2.20-7.el7             base         41 k

Transaction Summary
================================================================================
Install  1 Package (+32 Dependent packages)

Total download size: 19 M
Installed size: 63 M
Downloading packages:
warning: /var/cache/yum/x86_64/7/base/packages/perl-Carp-1.26-244.el7.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for perl-Carp-1.26-244.el7.noarch.rpm is not installed
Public key for perl-Pod-Escapes-1.04-299.el7_9.noarch.rpm is not installed
--------------------------------------------------------------------------------
Total                                              1.8 MB/s |  19 MB  00:10     
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
 Userid     : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
 Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
 Package    : centos-release-7-9.2009.0.el7.centos.x86_64 (@CentOS)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : gpm-libs-1.20.7-6.el7.x86_64                                1/33 
  Installing : 2:vim-filesystem-7.4.629-8.el7_9.x86_64                     2/33 
  Installing : 2:vim-common-7.4.629-8.el7_9.x86_64                         3/33 
  Installing : which-2.20-7.el7.x86_64                                     4/33 
install-info: No such file or directory for /usr/share/info/which.info.gz
  Installing : groff-base-1.22.2-8.el7.x86_64                              5/33 
  Installing : 1:perl-parent-0.225-244.el7.noarch                          6/33 
  Installing : perl-HTTP-Tiny-0.033-3.el7.noarch                           7/33 
  Installing : perl-podlators-2.5.1-3.el7.noarch                           8/33 
  Installing : perl-Pod-Perldoc-3.20-4.el7.noarch                          9/33 
  Installing : 1:perl-Pod-Escapes-1.04-299.el7_9.noarch                   10/33 
  Installing : perl-Encode-2.51-7.el7.x86_64                              11/33 
  Installing : perl-Text-ParseWords-3.29-4.el7.noarch                     12/33 
  Installing : perl-Pod-Usage-1.63-3.el7.noarch                           13/33 
  Installing : 4:perl-macros-5.16.3-299.el7_9.x86_64                      14/33 
  Installing : perl-Storable-2.45-3.el7.x86_64                            15/33 
  Installing : perl-Exporter-5.68-3.el7.noarch                            16/33 
  Installing : perl-constant-1.27-2.el7.noarch                            17/33 
  Installing : perl-Socket-2.010-5.el7.x86_64                             18/33 
  Installing : perl-Time-Local-1.2300-2.el7.noarch                        19/33 
  Installing : perl-Carp-1.26-244.el7.noarch                              20/33 
  Installing : perl-PathTools-3.40-5.el7.x86_64                           21/33 
  Installing : perl-Scalar-List-Utils-1.27-248.el7.x86_64                 22/33 
  Installing : 1:perl-Pod-Simple-3.28-4.el7.noarch                        23/33 
  Installing : perl-File-Temp-0.23.01-3.el7.noarch                        24/33 
  Installing : perl-File-Path-2.09-2.el7.noarch                           25/33 
  Installing : perl-threads-shared-1.43-6.el7.x86_64                      26/33 
  Installing : perl-threads-1.87-4.el7.x86_64                             27/33 
  Installing : 4:perl-Time-HiRes-1.9725-3.el7.x86_64                      28/33 
  Installing : perl-Filter-1.49-3.el7.x86_64                              29/33 
  Installing : 4:perl-libs-5.16.3-299.el7_9.x86_64                        30/33 
  Installing : perl-Getopt-Long-2.40-3.el7.noarch                         31/33 
  Installing : 4:perl-5.16.3-299.el7_9.x86_64                             32/33 
  Installing : 2:vim-enhanced-7.4.629-8.el7_9.x86_64                      33/33 
  Verifying  : perl-HTTP-Tiny-0.033-3.el7.noarch                           1/33 
  Verifying  : perl-threads-shared-1.43-6.el7.x86_64                       2/33 
  Verifying  : perl-Storable-2.45-3.el7.x86_64                             3/33 
  Verifying  : groff-base-1.22.2-8.el7.x86_64                              4/33 
  Verifying  : perl-Exporter-5.68-3.el7.noarch                             5/33 
  Verifying  : perl-constant-1.27-2.el7.noarch                             6/33 
  Verifying  : perl-PathTools-3.40-5.el7.x86_64                            7/33 
  Verifying  : 4:perl-macros-5.16.3-299.el7_9.x86_64                       8/33 
  Verifying  : 2:vim-enhanced-7.4.629-8.el7_9.x86_64                       9/33 
  Verifying  : 1:perl-parent-0.225-244.el7.noarch                         10/33 
  Verifying  : perl-Socket-2.010-5.el7.x86_64                             11/33 
  Verifying  : which-2.20-7.el7.x86_64                                    12/33 
  Verifying  : 2:vim-filesystem-7.4.629-8.el7_9.x86_64                    13/33 
  Verifying  : perl-File-Temp-0.23.01-3.el7.noarch                        14/33 
  Verifying  : 1:perl-Pod-Simple-3.28-4.el7.noarch                        15/33 
  Verifying  : perl-Time-Local-1.2300-2.el7.noarch                        16/33 
  Verifying  : 1:perl-Pod-Escapes-1.04-299.el7_9.noarch                   17/33 
  Verifying  : perl-Carp-1.26-244.el7.noarch                              18/33 
  Verifying  : 2:vim-common-7.4.629-8.el7_9.x86_64                        19/33 
  Verifying  : perl-Scalar-List-Utils-1.27-248.el7.x86_64                 20/33 
  Verifying  : perl-Pod-Usage-1.63-3.el7.noarch                           21/33 
  Verifying  : perl-Encode-2.51-7.el7.x86_64                              22/33 
  Verifying  : perl-Pod-Perldoc-3.20-4.el7.noarch                         23/33 
  Verifying  : perl-podlators-2.5.1-3.el7.noarch                          24/33 
  Verifying  : 4:perl-5.16.3-299.el7_9.x86_64                             25/33 
  Verifying  : perl-File-Path-2.09-2.el7.noarch                           26/33 
  Verifying  : perl-threads-1.87-4.el7.x86_64                             27/33 
  Verifying  : 4:perl-Time-HiRes-1.9725-3.el7.x86_64                      28/33 
  Verifying  : gpm-libs-1.20.7-6.el7.x86_64                               29/33 
  Verifying  : perl-Filter-1.49-3.el7.x86_64                              30/33 
  Verifying  : perl-Getopt-Long-2.40-3.el7.noarch                         31/33 
  Verifying  : perl-Text-ParseWords-3.29-4.el7.noarch                     32/33 
  Verifying  : 4:perl-libs-5.16.3-299.el7_9.x86_64                        33/33 

Installed:
  vim-enhanced.x86_64 2:7.4.629-8.el7_9                                         

Dependency Installed:
  gpm-libs.x86_64 0:1.20.7-6.el7                                                
  groff-base.x86_64 0:1.22.2-8.el7                                              
  perl.x86_64 4:5.16.3-299.el7_9                                                
  perl-Carp.noarch 0:1.26-244.el7                                               
  perl-Encode.x86_64 0:2.51-7.el7                                               
  perl-Exporter.noarch 0:5.68-3.el7                                             
  perl-File-Path.noarch 0:2.09-2.el7                                            
  perl-File-Temp.noarch 0:0.23.01-3.el7                                         
  perl-Filter.x86_64 0:1.49-3.el7                                               
  perl-Getopt-Long.noarch 0:2.40-3.el7                                          
  perl-HTTP-Tiny.noarch 0:0.033-3.el7                                           
  perl-PathTools.x86_64 0:3.40-5.el7                                            
  perl-Pod-Escapes.noarch 1:1.04-299.el7_9                                      
  perl-Pod-Perldoc.noarch 0:3.20-4.el7                                          
  perl-Pod-Simple.noarch 1:3.28-4.el7                                           
  perl-Pod-Usage.noarch 0:1.63-3.el7                                            
  perl-Scalar-List-Utils.x86_64 0:1.27-248.el7                                  
  perl-Socket.x86_64 0:2.010-5.el7                                              
  perl-Storable.x86_64 0:2.45-3.el7                                             
  perl-Text-ParseWords.noarch 0:3.29-4.el7                                      
  perl-Time-HiRes.x86_64 4:1.9725-3.el7                                         
  perl-Time-Local.noarch 0:1.2300-2.el7                                         
  perl-constant.noarch 0:1.27-2.el7                                             
  perl-libs.x86_64 4:5.16.3-299.el7_9                                           
  perl-macros.x86_64 4:5.16.3-299.el7_9                                         
  perl-parent.noarch 1:0.225-244.el7                                            
  perl-podlators.noarch 0:2.5.1-3.el7                                           
  perl-threads.x86_64 0:1.87-4.el7                                              
  perl-threads-shared.x86_64 0:1.43-6.el7                                       
  vim-common.x86_64 2:7.4.629-8.el7_9                                           
  vim-filesystem.x86_64 2:7.4.629-8.el7_9                                       
  which.x86_64 0:2.20-7.el7                                                     

Complete!
Removing intermediate container 91b1fa8ad6af
 ---> 3d00a2ca3556
Step 6/10 : RUN yum -y install net-tools
 ---> Running in a1734a3dafbd
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
 * base: mirrors.tuna.tsinghua.edu.cn
 * extras: mirrors.bupt.edu.cn
 * updates: mirrors.bupt.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package net-tools.x86_64 0:2.0-0.25.20131004git.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package         Arch         Version                          Repository  Size
================================================================================
Installing:
 net-tools       x86_64       2.0-0.25.20131004git.el7         base       306 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 306 k
Installed size: 917 k
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : net-tools-2.0-0.25.20131004git.el7.x86_64                    1/1 
  Verifying  : net-tools-2.0-0.25.20131004git.el7.x86_64                    1/1 

Installed:
  net-tools.x86_64 0:2.0-0.25.20131004git.el7                                   

Complete!
Removing intermediate container a1734a3dafbd
 ---> 373b9da17329
Step 7/10 : EXPOSE 80
 ---> Running in d3e42e4887ee
Removing intermediate container d3e42e4887ee
 ---> a5e76e701a21
Step 8/10 : CMD echo $MYPATH
 ---> Running in de14bbf2f0a8
Removing intermediate container de14bbf2f0a8
 ---> 2071e6abd054
Step 9/10 : CMD echo "----end----"
 ---> Running in 621b4c53b471
Removing intermediate container 621b4c53b471
 ---> c668343fed61
Step 10/10 : CMD /bin/bash
 ---> Running in d68e3457124e
Removing intermediate container d68e3457124e
 ---> 24f054918674
Successfully built 24f054918674
Successfully tagged mycentos:0.1
# 看到Successfully 就代表构建成功了
构建成功

image

对比之前原生的centos

image

我们增加之后的镜像

image

# 3.我们可以列出本地镜像的变更历史:docker history 镜像id
[root@localhost dockerfile]# docker history 24f054918674
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
24f054918674   15 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B        
c668343fed61   15 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
2071e6abd054   15 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
a5e76e701a21   15 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
373b9da17329   15 minutes ago   /bin/sh -c yum -y install net-tools             182MB     
3d00a2ca3556   15 minutes ago   /bin/sh -c yum -y install vim                   237MB     
2798b9857343   28 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B        
d7b10d43dfd9   28 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B        
3bce5ca94a90   28 minutes ago   /bin/sh -c #(nop)  MAINTAINER xiao<155956725…   0B        
eeb6ee3f44bd   11 months ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      11 months ago    /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      11 months ago    /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB 

image

6.5.用实战看CMD和ENTRYPOINT的区别

CMD 和 ENTRYPOINT 区别

测试CMD

# 1.dockefile文件
FROM centos
CMD ["ls","-a"]

image

# 2.构建CMD镜像
[root@localhost dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
 ---> Running in 0bc2d4f51b5a
Removing intermediate container 0bc2d4f51b5a
 ---> 822b816c7988
Successfully built 822b816c7988
Successfully tagged cmdtest:latest
# 3.启动CMD镜像 发现ls -a生效
[root@localhost dockerfile]# docker run cmdtest
.
..
.dockerenv
bin
dev
etc
home

image

# 4.想追加一个命令 但是却发现报错了
[root@localhost dockerfile]# docker run cmdtest -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 

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

image


测试ENTRYPOINT

# 1.dockefile文件
FROM centos
ENTRYPOINT ["ls","-a"]

image

# 2.构建CMD镜像
[root@localhost dockerfile]# docker build -f dockerfile-entrypoint-test -t myentrypoint .
Sending build context to Docker daemon  4.096kB
Step 1/2 : FROM centos
 ---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
 ---> Running in 82fc907ae06a
Removing intermediate container 82fc907ae06a
 ---> 8ff38c6303ee
Successfully built 8ff38c6303ee
Successfully tagged myentrypoint:latest

image

# 3.启动CMD镜像 发现ls -a生效
[root@localhost dockerfile]# docker run myentrypoint
.
..
.dockerenv
bin
dev
etc
home

image

# 4.想追加一个命令 成功了 
[root@localhost dockerfile]# docker run myentrypoint -l
total 0
drwxr-xr-x.   1 root root   6 Sep  6 18:24 .
drwxr-xr-x.   1 root root   6 Sep  6 18:24 ..
-rwxr-xr-x.   1 root root   0 Sep  6 18:24 .dockerenv
lrwxrwxrwx.   1 root root   7 Nov  3  2020 bin -> usr/bin
drwxr-xr-x.   5 root root 340 Sep  6 18:24 dev
drwxr-xr-x.   1 root root  66 Sep  6 18:24 etc
drwxr-xr-x.   2 root root   6 Nov  3  2020 home

#ENTRYPOINT的情况下 -l 追加了 ENTRYPOINT ["ls","-a"]命令 ls -al 是命令所以执行

通过测试可以看出:

  1. CMD和ENTRYPOINT都可以执行其中的命令
  2. 如果在运行的时候追加命令,CMD会报错,而ENTRYPOINT会将追加的命令拼接在其文件中的命令之后,并且会正常运行

6.6.实战Tomcat镜像

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

    image

  2. 编写dockerfile文件 文件命名为`Dockerfile 就不需要-f去指定了 build会自动寻找这个文件

    image

    FROM centos:7
    MAINTAINER  xiao<1559567258@qq.com>
    
    COPY readme.txt /usr/local/readme.txt
    ADD jdk-8u171-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-7.0.57.tar.gz /usr/local/
    
    RUN yum -y install vim
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_171
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-7.0.57
    ENV CATALINA_BASH /usr/local/apache-tomcat-7.0.57
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-7.0.57/bin/startup.sh && tail -F /usr/local/apache-tomcat-7.0.57/bin/logs/catalina.out
    
  3. 构建镜像

    [root@localhost build]# docker build -t diytomcat .
    Sending build context to Docker daemon  199.8MB
    Step 1/15 : FROM centos:7
     ---> eeb6ee3f44bd
    Step 2/15 : MAINTAINER  xiao<1559567258@qq.com>
     ---> Using cache
     ---> 3bce5ca94a90
    Step 3/15 : COPY readme.txt /usr/local/readme.txt
     ---> 115843bac5c9
    Step 4/15 : ADD jdk-8u171-linux-x64.tar.gz /usr/local/
     ---> 70ca3087e85f
    Step 5/15 : ADD apache-tomcat-7.0.57.tar.gz /usr/local/
     ---> 780d781b4de8
    Step 6/15 : RUN yum -y install vim
     ---> Running in 4ebb343679ea
    Loaded plugins: fastestmirror, ovl
    Determining fastest mirrors
    

    image

  4. 启动镜像

    [root@localhost build]# docker run -d -p 9090:8080 --name xiaodetomcat -v /home/xiao/build/test:/usr/local/apache-tomcat-7.0.57/webapps/test -v  /home/xiao/build/tomcatlogs/:/usr/local/apache-tomcat-7.0.57/logs diytomcat
    
    # 解释 第一个挂载是将webapps下的test映射到本地tomcat下的test
    -v /home/xiao/build/test:/usr/local/apache-tomcat-7.0.57/webapps/test
    
    # 解释 第二个挂载是将apache-tomcat-7.0.57下的日志映射到本地tomcat下的tomcatlogs
    -v  /home/xiao/build/tomcatlogs/:/usr/local/apache-tomcat-7.0.57/logs
    

    image

  5. 本地自测

    image

  6. 访问测试

    访问http://192.168.0.130:9090/ 可以看到成功的界面

    image

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

    在本地xiao/test文件夹下创建WEB-INF文件夹 在WEB-INF下编写web.xml文文件

    <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://java.sun.com/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                                   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5">
    
      </web-app>
    

    image

  8. 在xiao/test 下编写index.jsp文件

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.io.*,java.util.*, javax.servlet.*" %>
    <html>
    <head>
    <title>hello,eric</title>
    </head>
    <body>
    
    <h1>显示当前时间与日期</h1>
    
    <%
       Date date = new Date();
       out.print( "<h2 align=\"center\">" +date.toString()+"</h2>");
    %>
    </body>
    </html>
    

    image

  9. 测试访问http://192.168.0.130:9090/test/

    image

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

6.7.发布自己的镜像

Docker Hub

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

  2. 注册账号 确定这个账号可以登录

  3. 登录服务器

    # 使用docker login -u [用户名] 回车输入密码 
    [root@localhost test]# docker login -u xiaodockerhub
    Password: xxxxxxxxxxxxxxxxx
    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 # 登陆成功
    
  4. 登录完毕后就可以提交上去镜像,就是一步 docker push

    # 这里提交出现了错误,因为需要在diytomcat前面加上自己DockerHub的username
    [root@localhost build]# docker push diytomcat
    Using default tag: latest
    The push refers to repository [docker.io/library/diytomcat]
    296ed9f2d49b: Preparing 
    8e201b5db1e3: Retrying in 3 seconds 
    ac1c094ebd4b: Preparing 
    fe4ff5b5da21: Preparing 
    174f56854903: Preparing 
    denied: requested access to the resource is denied # 拒绝
    
    • 一定要修改diytomcat的镜像名字为ericbooney/diytomcat 所以为了避免出现错误 在build的时候就要在名称前面加上自己docker hub的用户名
    # 修改diytomcat为xiaodockerhub/diytomcat:1.0 也尽量带上版本号
    [root@localhost build]# docker tag diytomcat xiaodockerhub/diytomcat:1.0
    # 再次进行提交 可以看到成功提交
    [root@localhost build]# docker push xiaodockerhub/diytomcat:1.0
    The push refers to repository [docker.io/xiaodockerhub/diytomcat]
    296ed9f2d49b: Pushed 
    8e201b5db1e3: Pushed 
    ac1c094ebd4b: Pushed 
    fe4ff5b5da21: Pushed 
    174f56854903: Pushed 
    1.0: digest: sha256:10372adfe32fda75b480e72363538a2785a3c5255d67c244472d8cb98eadc5e2 size: 1372
    

    image

image

阿里云镜像服务上

  1. 登录阿里云

  2. 找到容器镜像服务

    image

  3. 创建个人实例 (我已经创建过了)

    image

  4. 创建一个命名空间(防止冲突 隔离)

image

  1. 创建容器对象

image

image

image

  1. 浏览阿里云

image

image

  1. 登陆阿里云服务器

    # docker login --username=[用户名] registry.cn-beijing.aliyuncs.com 回车输入密码 
    [root@localhost build]# docker login --username=yaoxiao registry.cn-beijing.aliyuncs.com
    Password: 
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    
    Login Succeeded # 登录成功
    

    image

  2. 生成镜像名字 + 版本号

    # docker tag [imagesID] [名字]:[imagesTag]
    [root@localhost build]# docker tag 6686537a35ad registry.cn-beijing.aliyuncs.com/xiao-namespace/xiao-repository:1.0
    [root@localhost build]# docker images
    REPOSITORY                                                        TAG       IMAGE ID       CREATED         SIZE
    xiaodockerhub/diytomcat                                           1.0       6686537a35ad   2 hours ago     842MB
    registry.cn-beijing.aliyuncs.com/xiao-namespace/xiao-repository   1.0       6686537a35ad   2 hours ago     842MB
    

    image

  3. 提交镜像

    # docker push registry.cn-beijing.aliyuncs.com/xiao-namespace/xiao-repository:[镜像版本号]
    [root@localhost build]# docker push registry.cn-beijing.aliyuncs.com/xiao-namespace/xiao-repository:1.0
    The push refers to repository [registry.cn-beijing.aliyuncs.com/xiao-namespace/xiao-repository]
    296ed9f2d49b: Pushed 
    8e201b5db1e3: Pushed 
    ac1c094ebd4b: Pushed 
    fe4ff5b5da21: Pushed 
    174f56854903: Pushed 
    1.0: digest: sha256:10372adfe32fda75b480e72363538a2785a3c5255d67c244472d8cb98eadc5e2 size: 1372
    

    image

  4. 推送镜像成功 阿里云查看

image

小结

image

7.Docker网络

7.1.理解网络

image

三个网络

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

image

# 启动一个镜像
[root@localhost ]# docker run -d -P --name tomcat01 tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
0e29546d541c: Pull complete 
9b829c73b52b: Pull complete 
cb5b7ae36172: Pull complete 
6494e4811622: Pull complete 
668f6fcc5fa5: Pull complete 
dc120c3e0290: Pull complete 
8f7c0eebb7b1: Pull complete 
77b694f83996: Pull complete 
0f611256ec3a: Pull complete 
4f25def12f23: Pull complete 
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
09f55246d8bcb638fe4eab079f9a220b8e0de68703ca61a049f4787e007fb349

image

Docker查找容器ip报错

OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "ip addr": executable file not found in $PATH: unknown

解决方案

#进入容器内部执行apt-get update
[root@aliyun ~]# docker exec -it tomcat /bin/bash
root@1a8bddcb0fdd:/usr/local/tomcat# apt-get update
Hit:1 http://security.debian.org/debian-security bullseye-security InRelease
Get:2 http://deb.debian.org/debian bullseye InRelease [116 kB]
Hit:3 http://deb.debian.org/debian bullseye-updates InRelease

# apt install -y iproute2
root@1a8bddcb0fdd:/usr/local/tomcat# apt install -y iproute2
Reading package lists... Done
Building dependency tree... Done

image

image

# 查看容器的内部网络地址 ip addr 发现容器启动的是否会得到一个eth0@if5 ip地址 docker分配
[root@localhost ~]# docker exec -it tomcat 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
6: eth0@if7: <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

image

# 思考Linux能不能ping通容器内部
[root@localhost ~]# 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.067 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.074 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.066 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.045 ms

# Linux可以ping通docker容器内部

image

原理

  • 我们每启动一个docker容器 docker就会给docker容器分配一个ip 我们只要安装了docker 就会有一个网卡docker0桥接模式 使用的技术是**evth-pair技术 ** Linux宿主机的的docker0Ip地址和容器里Ip地址是同一个网段 所以可以ping通

    再次测试ip addr 多了一对网卡

  • 再启动一个容器测试 发现又多了一对网卡

image

  • 再启动一个tomcat

    # 查看容器的内部网络地址 ip addr
    [root@localhost ~]# docker exec -it tomcat ip addr
    

image

  • 发现又多了一个 Ip

image

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

image

  • 测试tomcat01 ping tomcat02 是否可以ping通

    # 容器内没有ping的命令需要自己添加 apt-get update
    root@5935436df8be:/usr/local/tomcat# apt-get update
    Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
    Get:2 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]                      
    Get:3 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]   
    Get:4 http://deb.debian.org/debian bullseye/main amd64 Packages [8182 kB]
    Get:5 http://security.debian.org/debian-security bullseye-security/main amd64 Packages [182 kB]
    Get:6 http://deb.debian.org/debian bullseye-updates/main amd64 Packages [2596 B]                         Fetched 8574 kB in 4min 7s (34.8 kB/s)                                                                   Reading package lists... Done
    
    # 添加ping命令 apt-get install iputils-ping
    root@82eb94a7bf7e:/usr/local/tomcat# apt-get install iputils-ping
    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    The following NEW packages will be installed:iputils-ping
    0 upgraded, 1 newly installed, 0 to remove and 48 not upgraded.
    Unpacking iputils-ping (3:20210202-1) ...
    Setting up iputils-ping (3:20210202-1) ...
    

image

image

# 我们发现两个容器之间可以ping通
[root@localhost ~]# 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.086 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.048 ms

image

绘制一个网络模型图:

image

结论:

  • tomcat01和tomcat02是共用的一个路由器 docker0

  • tomcat01并不是直接ping tomcat02而是通过 docker0 进行广播或者去docker0路由表里面找tomcat02的ip地址

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

小结

  1. Docker使用的是Linux桥接 宿主机中是一个Docker容器的网桥 docker0

image

  1. Docker中所有的网络接口都是虚拟的 虚拟的转发效率比较高(内网传递文件)

  2. 只要容器删除 对应的网桥就没了

image

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

  • # tomcat01  ping  tomcat02 通过域名是否可以ping通
    [root@localhost /]# docker exec -it tomcat01 ping tomcat02
    ping: tomcat02: Name or service not known
    

    image

  • # 如何解决呢? 
    [root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat 
    
    # 通过域名ping通方法:启动tomcat03 并且加上 --link 再次ping发现可以ping通
    [root@localhost /]# 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.092 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.084 ms
    64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.081 ms
    

    image

  • # 反向的连接可以ping通吗
    [root@localhost /]#  docker exec -it tomcat02 ping tomcat03
    ping: tomcat03: Name or service not known # 因为tomcat02没有配置 --link
    
    #我们发现不可以
    

    image

  • # 通过docker network ls 找到桥接的Id 通过桥接Id 查网络详细信息
    [root@localhost /]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    d8c099900403   bridge    bridge    local
    4c7a93e7f4f3   host      host      local
    a607863d78f7   none      null      local
    

image

  • # 通过docker network inspect d8c099900403 查看到镜像启动的时候都是docker0随机分配的地址
    [root@localhost /]# docker network inspect d8c099900403
    [
        {
            "Name": "bridge",
            "Id": "d8c099900403ea6b2cc65be5a605fe6f858e56740ef1db58b08a09b7140cf962",
            "Created": "2022-09-08T16:42:16.282036189+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"
                    }
                ]
            }
    

    image

  • 其实这个tomcat03就是本地配置了tomcat02的配置

    # 查看一下tomcat03的hosts的配置
    [root@localhost /]# 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 5d2e2ec20d90
    172.17.0.4      6521f824223c
    

image

  • 本质探究:-–link就是我们在hosts配置中增加了一个172.17.0.3 tomcat02 5d2e2ec20d90

  • 我们现在 玩Docker已经不建议使用–link了

  • 自定义网络 不适用于docker0

  • dcoker0问题:他不支持容器名连接访问!

7.3.自定义网络

查看所有的docker网络

docker network ls

image

网络模式

  • bridge:桥接 docker(默认 自己创建的也是使用bridge模式)

  • none:不配置网络

  • host:和宿主机共享网络

  • container:容器内网络连通(用的少 局限很大)

测试

# 我们直接启动的命令 --net bridge 而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

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

# 我们可以自定义一个网络
# -d bridge 		   # 桥接
# --subnet 192.168.0.0/16  # 子网
# --gateway 192.168.0.1    # 网关
[root@localhost ~]# docker network create -d bridge --subnet 192.168.1.1/16 --gateway 192.168.1.0 mynet
08a4a83e77b441c97aca4b65ff98c6cea6d5c23d7960a00c5300b8dde611e957

image

# 查看创建的网络 docker network ls
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a57903d80dfc   bridge    bridge    local
4c7a93e7f4f3   host      host      local
08a4a83e77b4   mynet     bridge    local
a607863d78f7   none      null      local

image

# 查看创建的网络详细信息
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "08a4a83e77b441c97aca4b65ff98c6cea6d5c23d7960a00c5300b8dde611e957",
        "Created": "2022-09-08T18:18:58.3257889+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.1/16",
                    "Gateway": "192.168.1.0"
                }
            ]
         }

image

# 启动两个容器
[root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
7487eb49042828dabe42a5a2dbc3ef216a827fbee261604522b1b311974834c6
[root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
a573e94e493a90dcbc4fe5655219873a858ef083beb7393e283c820f4481fff1

image

# 查看创建的网络里是否包含了 tomcat-net-01和tomcat-net-02
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "08a4a83e77b441c97aca4b65ff98c6cea6d5c23d7960a00c5300b8dde611e957",
        "Created": "2022-09-08T18:18:58.3257889+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.1/16",
                    "Gateway": "192.168.1.0"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "7487eb49042828dabe42a5a2dbc3ef216a827fbee261604522b1b311974834c6": {
                "Name": "tomcat-net-01",
                "EndpointID": "33974acf020a53a54d5708c722f4ced3175fa467696fe1f86ce94b1c508db11f",
                "MacAddress": "02:42:c0:a8:00:01",
                "IPv4Address": "192.168.0.1/16",
                "IPv6Address": ""
            },
            "a573e94e493a90dcbc4fe5655219873a858ef083beb7393e283c820f4481fff1": {
                "Name": "tomcat-net-02",
                "EndpointID": "0c311ea5fdc65f2b7d405fcdcb83533ec7d83f47182c5e86398b751277b01e58",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

image

# 再次测试ping连接
[root@localhost /]# docker exec -it tomcat-net-01 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.081 ms
64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=0.075 ms

image

# 现在不需要使用--link也可以ping名字了!
[root@localhost /]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.060 ms
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.075 ms
64 bytes from tomcat-net-02.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.050 ms

image

小结:我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐使用这个网络

好处:

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

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

7.3.1.网络连通

# 查看怎么连通
[root@localhost /]# docker network --helo

image

# 查看connect 命令怎么使用
[root@localhost /] docker network connect --help

image

# 测试打通 tomcat01 -> mynet
[root@localhost ~]# docker network connect mynet tomcat01

# 连通之后将tomcat01放到了mynet网络下

# 一个容器两个ip地址 阿里云服务:公网ip 私网ip

image

# 测试tomcat01 ping tomcat-net-01 是否可以ping通
[root@localhost /]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.1) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.1): icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from tomcat-net-01.mynet (192.168.0.1): icmp_seq=2 ttl=64 time=0.092 ms
64 bytes from tomcat-net-01.mynet (192.168.0.1): icmp_seq=3 ttl=64 time=0.083 ms
64 bytes from tomcat-net-01.mynet (192.168.0.1): icmp_seq=4 ttl=64 time=0.075 ms

image

# tomcat02 和tomcat-net-01是否可以ping通
[root@localhost /]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

image

结论:如果需要跨网络操作别人 就需要使用docker network connect进行连通

7.4.实战:部署Redis集群

image

shell脚本

# 创建网卡
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

# 运行6个节点
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

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

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

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

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

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

# 创建集群
/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: ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: 2f1fdb553165c31c599f5cdbac5a42fa15901602 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: d2edadd37c2b243ffa3a13ac7bb352062160f4b8 172.38.0.14:6379
   replicates 2f1fdb553165c31c599f5cdbac5a42fa15901602
S: 98bec4772bd3cdc7335111f75bc3f6b6ad2fae26 172.38.0.15:6379
   replicates ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e
S: 6e8dda893836d8182af1a7cbe0ff71b32d0743ef 172.38.0.16:6379
   replicates ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537
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: ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 98bec4772bd3cdc7335111f75bc3f6b6ad2fae26 172.38.0.15:6379
   slots: (0 slots) slave
   replicates ebfbbc88a83fa84c3d73fe048fc37ab82841fa0e
S: d2edadd37c2b243ffa3a13ac7bb352062160f4b8 172.38.0.14:6379
   slots: (0 slots) slave
   replicates 2f1fdb553165c31c599f5cdbac5a42fa15901602
S: 6e8dda893836d8182af1a7cbe0ff71b32d0743ef 172.38.0.16:6379
   slots: (0 slots) slave
   replicates ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537
M: 2f1fdb553165c31c599f5cdbac5a42fa15901602 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: ed7bac9d22ce436c650f9a51c3ae7a3aa84a7537 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.

image

docker搭建redis集群完成

image

image

我们使用了docker后,所有技术都会变得更加方便

8.IDEA整合Dockers

创建项目

  1. 架构springboot项目

  2. 打包应用

image

  1. 编写dockerfile(idea中安装docker插件比较方便)

image

  1. 将jar包和Dockerfile文件传输到Linux服务器上

image

  1. # 构建镜像xiao666
    [root@localhost idea]# docker build -t xiao666 .
    Sending build context to Docker daemon  17.66MB
    Step 1/5 : FROM java:8
     ---> d23bdf5b1b1b
    Step 2/5 : COPY *.jar /app.jar
     ---> 3b4ebe0fcd41
    

image

  1. # 发布运行 
    [root@localhost idea]# docker run -d -P --name xiao-springboot-web xiao666 .
    3db41b0b9a9ec44f15c57e891380b0fbed580ecd949bccaf757fc5a1d8ad9598
    

image

  1. # 本地测试
    [root@localhost idea]# curl localhost:49167/hello
    Hello,Xiao[root@localhost idea]# 
    

    image

  2. 浏览器测试 浏览器测试如果没有加跨域注解是访问失败的

    image

以后我们使用了Docker之后 给别人交互的就是一个镜像即可

Docker进阶篇

1.Docker Compose

1.1.简介

DockerFile build run 单个容器

Docker Compose 来轻松高效的管理容器->批量运行编排多个容器

Compose 是Docker 官方开源项目 需要安装

官方介绍:

定义 运行多个容器

yaml file 配置文件

Compose是一个用于定义和运行多容器Docker应用程序的工具 使用Compose 您可以使用一个YAML文件来配置应用程序的服务 然后使用一个single command命令创建并启动配置中的所有服务 要了解Compose的所有特性的更多信息 请参阅特性列表

所有环境都可使用Compose

在所有环境中组合工作:生产阶段开发测试以及CI工作流 您可以在常用用例中了解更多关于每个用例的信息

三步骤:

使用Compose基本上有三个步骤:

  1. 用Dockerfile定义你的应用环境 这样它就可以在任何地方被复制

    • Dockerfile 保证我们的项目可以在任何地方运行
  2. 在docker-compose中定义组成应用程序的服务 所以它们可以在一个孤立的环境中一起运行

    • services: 容器、应用

    • docker-compose.yml

  3. 运行docker compose, docker compose命令将启动并运行你的整个应用程序 你也可以使用docker-compose二进制文件运行docker-compose

    • 启动项目
作用:批量容器编排

我自己的理解

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

Dockerfile让程序在任何地方运行

Compose

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

Compose: 重要的概念

  • 服务services 容器 应用 (web redis mysql…)
  • 项目project 一组关联的容器

1.2.安装

卸载 sudo rm /usr/local/bin/docker-compose

  1. 下载

    官网地址

    # 不建议用官方地址 非常慢 而且版本太高不稳定
    sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    
    # 这个可能快点
    curl -L https://dn-dao-github-mirror.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    

    image

  2. 授权

    sudo chmod +x /usr/local/bin/docker-compose
    

    image

1.3.体验

  • 应用 app.py
  • Dockerfile 应用打包为镜像
  • Docker-compose.yaml (定义整个服务、需要的环境:web、redis)
  • python计数器应用

官网地址

1.3.1.快速开始

  1. 应用app.py

    # 创建一个文件夹
    mkdir composetest
    # 进入这个文件夹
    cd composetest
    
  2. 创建app.py文件

    [root@localhost home]# vim 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)
    
    if __name__ == "__main__":
    	app.run(host="0.0.0.0",debug=True)
    
  3. 创建requirements.txt文件

    [root@localhost composetest]# vim requirements.txt
    
    # 文件内容
    flask
    redis
    
  4. 创建Dockerfile文件

    [root@localhost composetest]# vim Dockerfile
    
    # 文件内容
    FROM python:3.6-alpine
    ADD . /code
    WORKDIR /code
    RUN pip install -r requirements.txt
    CMD ["python","app.py"]
    
    
    # 这告诉 Docker:
    # 		从Python 3.6-alpine映像开始构建ying'xiang
    # 		将当前目录添加到./code映像中的路径中
    # 		将工作目录设置为 /code
    # 		安装Python依赖项
    # 		将容器的命令设置为python app.py
    
  5. Docker-compose.yaml文件(定义整个服务于,需要的环境,web、redis)

    # 创建一个docker-compose.yaml文件
    [root@localhost composetest]# vim docker-compose.yaml
    
    # 文件内容
    version: "3.3"
    services:
      web:
        build: .
        ports:
          - "5000:5000"
      redis:
        image: "redis:alpine"
        
    # 此Compose文件定义了两个服务 web和redis 
    # 该web服务使用从Dockerfile当前目录中构建的镜像
    # 将容器上的公开端口5000转发到主机上的端口5000
    # 我们使用Flask web服务器的默认端口5000
    # 该redis服务使用从DockerHub注册表中提取的公共Redis映像
    
  6. 在当前文件下启动docker-compose up

    [root@192 composetest]# docker-compose up
    Creating network "composetest_default" with the default driver
    Building web
    Step 1/10 : FROM python:3.7-alpine
    # ...
    Successfully built f34d94accbfe # 成功built
    Successfully tagged composetest_web:latest
    # ...
    redis_1  | 1:C 05 Feb 2022 03:43:44.272 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
    redis_1  | 1:C 05 Feb 2022 03:43:44.272 # 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 05 Feb 2022 03:43:44.274 * monotonic clock: POSIX clock_gettime
    redis_1  | 1:M 05 Feb 2022 03:43:44.275 * Running mode=standalone, port=6379. # redis 端口6379
    # ...
    redis_1  | 1:M 05 Feb 2022 03:43:44.275 * Ready to accept connections
    web_1    |  * Serving Flask app 'app.py' (lazy loading)  # Flask app 'app.py
    web_1    |  * Environment: production
    web_1    |    Use a production WSGI server instead.
    web_1    |  * Debug mode: off
    web_1    |  * Running on all addresses.
    # 警告:这是一个开发服务器。不要在生产部署中使用它。
    web_1    |    WARNING: This is a development server. Do not use it in a production deployment.
    web_1    |  * Running on http://172.18.0.2:5000/ (Press CTRL+C to quit) # Flask网页运行成功
    web_1    | 192.168.64.1 - - [05/Feb/2022 03:45:00] "GET / HTTP/1.1" 200 - # 访问常规
    

    image-20220909014555744

    # 服务启动成功
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                       NAMES
    16036f07b287   redis:alpine      "docker-entrypoint.s…"   31 minutes ago   Up 13 minutes   6379/tcp                                      composetest_redis_1
    8e2f95d3f13c   composetest_web   "python app.py"          31 minutes ago   Up 13 minutes   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   composetest_web_1
    
    # 测试服务是否正常
    [root@localhost ~]# curl localhost:5000
    Hello World! I have been seen 1 times.
    [root@localhost ~]# curl localhost:5000
    Hello World! I have been seen 2 times.
    [root@localhost ~]# curl localhost:5000
    Hello World! I have been seen 3 times.
    [root@localhost ~]# curl localhost:5000
    

    image

image

# 查看运行容器和下载的镜像
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                       NAMES
16036f07b287   redis:alpine      "docker-entrypoint.s…"   36 minutes ago   Up 18 minutes   6379/tcp                                    composetest_redis_1
8e2f95d3f13c   composetest_web   "python app.py"          36 minutes ago   Up 18 minutes   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   composetest_web_1
[root@localhost ~]# docker images
REPOSITORY        TAG          IMAGE ID       CREATED          SIZE
composetest_web   latest       3c2fcb7d9c91   36 minutes ago   55.5MB
<none>            <none>       7c0401c80946   2 hours ago      41.8MB
redis             alpine       3900abf41552   9 months ago     32.4MB
python            3.6-alpine   3a9e80fa4606   9 months ago     40.7MB
python            3.7-alpine   a1034fd13493   9 months ago     41.8MB
hello-world       latest       feb5d9fea6a5   11 months ago    13.3kB

image

composetest_web_1 默认服务名: 文件名_服务名_num

多个服务器 集群 _num 代表 副本数量

集群状态 服务都不可能只有一个运行实例 弹性 高可用

kubectl service 负载均衡

# docker-compose.yaml文件
version: "3"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

# 根据docker-compose.yaml自动生成了两个服务:
1. web(网络服务)
2. redis服务

# 该服务使用从 Docker Hub 注册表中提取的公共 Redis 映像

# 1.版本问题version 

# 2.version版本不要填太高

docker-compose步骤:

1.应用 app.py

2.创requirements.txt文件

3.Dockefile 应用打包为镜像

4.docker-compose.yaml文件(定义整个服务需要的环境 web redis) 完整的上线服务

5.启动docker-compose项目(docker-compose up)

docker-compose up启动流程:

1.创建网络

2.执行Docker-compose yaml

3.启动服务

最终上线了两个项目:

  • Creating composetest_web_1 … done
  • Creating composetest_redis_1 … done

1.3.2网络

网络

  1. 网络规则

    # 查看网络 docker network ls
    [root@localhost ~]# docker network ls
    NETWORK ID     NAME                  DRIVER    SCOPE
    75c8249cf43b   bridge                bridge    local
    109bac1879eb   composetest_default   bridge    local
    08092ffccab6   host                  host      local
    cb9aae29a8ef   none 
    

    image

    运行10个服务打包为一个完整项目Compose自动维护了一个网络(项目中的内容都在同一个网络下 可以通过域名访问)

    # 查看网络详细 docker network inspect composetest_default
    [root@localhost ~]# docker network inspect composetest_default
     "Containers": {
                "16036f07b287b0bfa28413692d04a60b15eb69d7518c480f3097c3822c7eb393": {
                    "Name": "composetest_redis_1",
                    "EndpointID": "da457e336dd031a4d62b739fb608752d614755930ef5bd4f7e39d7d82bce15bd",
                    "MacAddress": "02:42:ac:12:00:03",
                    "IPv4Address": "172.18.0.3/16",
                    "IPv6Address": ""
                },
                "8e2f95d3f13c32a87d791965f1821e0324eea13f86a6c0c1a869aa0781964bf8": {
                    "Name": "composetest_web_1",
                    "EndpointID": "c9206af0c98883cfa6bc3001e8d445c696aa0d929bbdf8c6076adcc1d36a095d",
                    "MacAddress": "02:42:ac:12:00:02",
                    "IPv4Address": "172.18.0.2/16",
                    "IPv6Address": ""
                }
            }
            
    # 如果在同一个网络下 可以通过域名进行访问
    

    image

    # 停止命令 docker-compose down
    # 方式一:
    # 		docker-compose down
    # 方式二:
    # 		Ctrl + c
    

    image

    • docker run单个容器启动
    • docker-compose通过docker-compose编写yaml配置文件 可以通过compose一键启动所有服务 停止

Docker小结:

1.Docker镜像 通过run启动容器

2.DockerFile构建镜像(服务打包)

3.docker-compose启动项目(编排 多个微服务/环境)

4.Docker网络

1.4.yaml 规则

docker-compose.yaml 核心

官网介绍

# 总共三层

version: '' # 版本
services:  #服务
	服务1: web
		# 服务配置
		images:
		port:
		network: 
		depends_on: # 启动依赖(顺序)
		...
	服务2: redis
		...
# 其他配置 网络 卷 全局规则
volumes: 
network: 
confits:

image

1.5.实战

1.6.实战开源项目-WordPress

官网

  1. 下载项目
  2. 如果需要自己的镜像,可以自定义 Dockerfile
  3. 编写docker-compose.yaml
  4. docker-compose up -d 后台启动
    • 使用Compose一键部署WP博客
    • 自己编写微服务上线
开源项目(博客)
  1. # 下载项目 我这个项目是官方的
    [root@localhost my_wordpress]# mkdir my_wordpress
    
  2. # 进入这个文件夹
    [root@localhost my_wordpress]# cd my_wordpress/
    
  3. # 创建一个文件
    [root@localhost my_wordpress]# vim docker-compose.yml
    
    # 文件内容
    services:
      db:
        image: mariadb:10.6.4-focal
        command: '--default-authentication-plugin=mysql_native_password'
        volumes:
          - db_data:/var/lib/mysql
        restart: always
        environment:
          - MYSQL_ROOT_PASSWORD=somewordpress
          - MYSQL_DATABASE=wordpress
          - MYSQL_USER=wordpress
          - MYSQL_PASSWORD=wordpress
        expose:
          - 3306
          - 33060
      wordpress:
        image: wordpress:latest
        ports:
          - 80:80
        restart: always
        environment:
          - WORDPRESS_DB_HOST=db
          - WORDPRESS_DB_USER=wordpress
          - WORDPRESS_DB_PASSWORD=wordpress
          - WORDPRESS_DB_NAME=wordpress
    volumes:
      db_data:
    
  4. 启动项目

image

  1. 访问测试:

    image

实战微服务
  1. 编写微服务

    package com.xiao.dockercloud.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @Classname 测试
     * @Description TODO
     * @Date 2022/9/9 23:59
     * @Created by ylp
     */
    
    @RestController
    public class HelloController {
    
        @Autowired
        private StringRedisTemplate redisTemplate;
    
        @GetMapping("/hello")
        public String hello(){
            Long views = redisTemplate.opsForValue().increment("views");
    
            return "Hello Xiao Thank You Views"+views;
        }
    }
    
  2. dockerfile 构建镜像

    FROM java:8
    
    COPY *.jar /app.jar
    
    CMD ["--server.port=8080"]
    
    EXPOSE 8080
    
    ENTRYPOINT ["java","-jar","/app.jar"]
    
  3. docker-compose 编排项目

    version: '3.3'
    
    services:
      xiaoapp:
        build: .
        image: xiaoapp
        depends_on:
          - redis
        ports:
        - "8080:8080"
      redis:
        image: "library/redis:alpine"
    
  4. docker-compose up --build

    # 启动项目并且部署
    [root@localhost xiaoapp]# docker-compose up --build
    Creating network "xiaoapp_default" with the default driver
    Building xiaoapp
    
  5. 本地自测 浏览器自测:

    # 本地自测 浏览器自测:
    [root@localhost ~]# curl localhost:8080/hello
    Hello Xiao Thank You Views1[root@localhost ~]# curl localhost:8080/hello
    Hello Xiao Thank You Views2[root@localhost ~]# curl localhost:8080/hello
    Hello Xiao Thank You Views3[root@localhost ~]# curl localhost:8080/hello
    Hello Xiao Thank You Views4[root@localhost ~]# curl localhost:8080/hello
    Hello Xiao Thank You Views5[root@localhost ~]# curl localhost:8080/hello
    

image

image

小结:

  • Docker Compose 是一个开源项目 用来统一编排多个应用的
  • 多个应用 多个服务 => 这些应用都会在同一个网络下 => 可通过域名直接访问
  • 默认的服务名为:文件夹名称_镜像名_副本数量(运行数量)
  • Dockerfile 用于构建镜像 docker-compose.yaml 用于编排项目 同时组装多个应用
  • docker-compose.yaml 文件结构总共三层
    • docker compose版本
    • 服务
      • 服务的属性
    • 其他配置
  • 如何使用:
    • 准备好项目并编写 Dockerfile(可省略 如果直接使用仓库镜像的话)
    • 编写docker-compose.yaml
    • 在当前目录(docker-compose.yaml文件所在目录)运行 docker-compose up 停止 docker-compose down

2.Docker Swarm

工作模式

image

搭建集群

$ docker swarm --help

Usage:  docker swarm COMMAND

Manage Swarm 

Commands:
  ca          # Display and rotate the root CA
  init        # 初始化一个Swarm
  join        # 加入一个集群作为一个节点 和/或 管理者
  join-token  # 管理生成的令牌
  leave       # 离开swarm
  unlock      # 解锁swarm
  unlock-key  # 解锁密钥管理
  update      # 更新swarm
$ docker swarm init --help
  1. 设置主节点(192.168.0.131)

    # 初始化节点
    [root@localhost /]# docker swarm init --advertise-addr 192.168.0.131
    
    # Swarm初始化: 当前节点(...)现在是一个manager(管理节点)。
    Swarm initialized: current node (wee6ow9y9nqk4ztn8xcla4309) is now a manager.
    
    # 翻译:要添加一个worker(工作节点)到这个swarm,运行以下命令(令牌)
    To add a worker to this swarm, run the following command:
        docker swarm join --token SWMTKN-1-3l5b0p89d3o87cm3khemqeignks4bgdx08jey90apd1icvfvpf-9zzk6l53ehjwv4ru3sy9zc8qm 192.168.0.131:2377
        
    # 翻译:要添加一个swarm(管理节点)到swarm,运行'docker swarm join-token manager',
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    
    
    

    image

  2. 生成令牌(管理生成的令牌)

    # 生成管理节点的令牌
    $ docker swarm join-token manager
    
    # 生成工作节点的令牌
    $ docker swarm join-token worker
    
  3. 将docker-2加入工作节点

    # 添加一个工作节点的命令
    [root@localhost /]# docker swarm join --token SWMTKN-1-3l5b0p89d3o87cm3khemqeignks4bgdx08jey90apd1icvfvpf-9zzk6l53ehjwv4ru3sy9zc8qm 192.168.0.131:2377
    This node joined a swarm as a worker. # 成功变为工作节点
    

    image

  4. 查看所有节点信息

    [root@localhost /]# docker node ls
    ID                            HOSTNAME                STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
    9u4hvly7d9c0kwg7era50iwwn     localhost.localdomain   Ready     Active                          20.10.17
    wee6ow9y9nqk4ztn8xcla4309 *   localhost.localdomain   Ready     Active         Leader           20.10.17
    
  5. 将docker-3加入工作节点

    # 添加一个工作节点的命令
    [root@localhost /]# docker swarm join --token SWMTKN-1-3l5b0p89d3o87cm3khemqeignks4bgdx08jey90apd1icvfvpf-9zzk6l53ehjwv4ru3sy9zc8qm 192.168.0.131:2377
    This node joined a swarm as a worker. # 成功变为工作节点
    

    image

    # 查看所有节点信息
    [root@localhost /]# docker node ls
    ID                            HOSTNAME                STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
    9u4hvly7d9c0kwg7era50iwwn     localhost.localdomain   Ready     Active                          20.10.17
    qhjnsfh7mekxr6rgo4j3yfaxv     localhost.localdomain   Ready     Active                          20.10.17
    wee6ow9y9nqk4ztn8xcla4309 *   localhost.localdomain   Ready     Active         Leader           20.10.17
    

    image

  6. 将docker-4加入管理节点

    # 生成管理节点的令牌
    [root@localhost /]# docker swarm join-token manager
    To add a manager to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-3l5b0p89d3o87cm3khemqeignks4bgdx08jey90apd1icvfvpf-3mpf1d2rbbjzpl7ky02qxbwa0 192.168.0.131:2377
    
    # 加入管理节点
    [root@localhost ~]# docker swarm join --token SWMTKN-1-3l5b0p89d3o87cm3khemqeignks4bgdx08jey90apd1icvfvpf-3mpf1d2rbbjzpl7ky02qxbwa0 192.168.0.131:2377
    This node joined a swarm as a manager. # 成功变为管理节点
    

    image

  7. # 查看所有节点信息
    [root@localhost /]# docker node ls
    ID                            HOSTNAME                STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
    9u4hvly7d9c0kwg7era50iwwn     localhost.localdomain   Ready     Active                          20.10.17
    i01kql67nqpayyic6i95z8aqo     localhost.localdomain   Ready     Active         Reachable        20.10.17
    qhjnsfh7mekxr6rgo4j3yfaxv     localhost.localdomain   Ready     Active                          20.10.17
    wee6ow9y9nqk4ztn8xcla4309 *   localhost.localdomain   Ready     Active         Leader           20.10.17
    
  8. 移除节点

    # 从swarm中删除一个节点 | -f 删除多个节点 $ docker node rm 节点id
    [root@localhost /]# docker node rm 6rdhf93we35s9pjlmj73tubta
    
    # 管理节点自己离开 $ docker swarm leave --force
    [root@192 ~]# docker swarm leave --force
    Node left the swarm.
    

2.1.Raft一致性协议了解

双主双从 => 假设一个节点挂了 其他节点是否可用 不可用

Raft协议:保证大多数节点存活才可用

  • 三个管理器的群体最多可以容忍一个管理器的损失
  • 一个五管理器群可以容忍最大同时丢失两个管理器节点
  • 一个N管理器集群最多可以容忍管理器的丢失 (N-1)/2
  • Docker 建议一个群最多有七个管理器节点

ps:manager 节点不是越多越好

  • 三个manager节点 停止一个manager之后仍可用
  • 三个manager节点 停止两个manager之后不可用

实验:

  1. [root@localhost /]# systemctl docker 
    [root@localhost /]# docker node ls
    # 日志含义可能在线的managers太少了 确保半数以上的managers在线
    Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.
    
  2. 将某一个worker节点离开,仍可用

    [root@localhost /]# docker node ls
    ID                            HOSTNAME                STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
    iz6uklv45q2n3m9k698h2zurf     localhost.localdomain   Down      Active                          20.10.17
    om92u8zv81jgw8aey7gdixhrs     localhost.localdomain   Ready     Active         Reachable        20.10.17
    y4o5cy31v386te7n0as513st6     localhost.localdomain   Ready     Active         Reachable        20.10.17
    yfx4k4z9h653fvrzaggt2p83j *   localhost.localdomain   Ready     Active         Leader           20.10.17
    

    image

  3. work节点不能查看节点信息 仅用来工作,命令只能在manager(管理节点)上执行

    [root@localhost /]# docker node ls
    # 来自daemon的错误响应:这个节点不是一个集群管理器
    # 工作节点不能用于查看或修改集群状态
    # 请在管理节点上执行此命令或将当前节点提升为管理节点
    Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
    

    image

2.2.Swarm集群弹性创建服务

扩缩容功能 创建服务 动态扩展服务 更新服务 日志 灰度发布(更新网站(服务)时依旧提出服务 不挂404)

功能:扩缩容功能(扩容:增加容器 缩容:减少容器)灰度发布

目的:创建 nginx 服务 动态扩展服务 动态更新服务

[root@192 ~]# docker service --help

Usage:  docker service COMMAND

Manage services

Commands:
  create      # 创建一个新服务
  inspect     # 显示一个或多个服务的详细信息
  logs        # 获取服务或任务的日志
  ls          # 服务列表
  ps          # 列出一个或多个服务的任务
  rm          # 删除一个或多个服务
  rollback    # 回滚恢复对服务配置的更改
  scale       # 扩展扩展一个或多个复制业务
  update      # 更新服务
  1. 创建服务(docker-1)

    以前是docker run(单机),现在是 docker service (集群)

    [root@localhost /]# docker service create -p 9999:80 --name xiao-nginx nginx
    lnhsiqaadct5mfl2yo52e84sv
    overall progress: 1 out of 1 tasks 
    1/1: running   [==================================================>] 
    verify: Service converged # 启动成功
    
    # 理解:
    #	docker run 容器启动 不具有扩缩容 不具有滚动更新
    #	docker service 服务启动 具有扩缩容 具有滚动更新
    

    image

  2. 查看服务(docker-1)

    [root@localhost /]# docker service ls 
    ID             NAME         MODE         REPLICAS   IMAGE          PORTS
    lnhsiqaadct5   xiao-nginx   replicated   1/1        nginx:latest   *:9999->80/tcp
    # REPLICAS副本只有一个 说明在集群中只存在一个
    # 虽然是在docker-1机器上创建的 但也有可能跑在其他机器上
    

    image

  3. 动态扩缩容 扩容到3个副本 集群中的任意节点都可访问 实现高可用

    [root@localhost /]# docker service update --replicas 3 xiao-nginx
    xiao-nginx
    overall progress: 3 out of 3 tasks 
    1/3: running   [==================================================>] 
    2/3: running   [==================================================>] 
    3/3: running   [==================================================>] 
    verify: Service converged 
    

    查看扩容是否成功

    [root@localhost /]# docker service ls
    ID             NAME         MODE         REPLICAS   IMAGE          PORTS
    lnhsiqaadct5   xiao-nginx   replicated   3/3        nginx:latest   *:9999->80/tcp # 成功
    

    image

    查看分配到哪个机器

image

image

  1. 动态扩容(scale 同 updata)

    [root@localhost /]# docker service scale xiao-nginx=10
    xiao-nginx scaled to 10
    overall progress: 10 out of 10 tasks 
    1/10: running   [==================================================>] 
    2/10: running   [==================================================>] 
    3/10: running   [==================================================>] 
    4/10: running   [==================================================>] 
    5/10: running   [==================================================>] 
    6/10: running   [==================================================>] 
    7/10: running   [==================================================>] 
    8/10: running   [==================================================>] 
    9/10: running   [==================================================>] 
    10/10: running   [==================================================>] 
    verify: Service converged 
    

    查看扩容是否成功

    [root@localhost /]# docker service ls
    ID             NAME         MODE         REPLICAS   IMAGE          PORTS
    lnhsiqaadct5   xiao-nginx   replicated   10/10      nginx:latest   *:9999->80/tcp # 成功
    

image

查看分配到哪个机器

image

image

  1. 测试访问

    image

    image

  2. 动态缩容 回滚到1个

    [root@localhost /]# docker service scale xiao-nginx=1
    xiao-nginx scaled to 1
    overall progress: 1 out of 1 tasks 
    1/1: error creating external connectivity network: Failed to Setup IP tables: U… 
    verify: Service converged 
    

    image

    查看缩容是否成功

    [root@localhost /]# docker service ls
    ID             NAME         MODE         REPLICAS   IMAGE          PORTS
    lnhsiqaadct5   xiao-nginx   replicated   1/1        nginx:latest   *:9999->80/tcp # 成功
    

    image

Swarm概念总结

  • swarm
    集群的管理和编号 docker可以初始化一个swarm集群 其他节点可以加入 (管理、工作者)
  • Node
    就是一个docker节点 多个节点就组成了一个网络集群 (管理、工作者)
  • Service
    任务,可以在管理节点或者工作节点来运行 核心 用户访问
  • Task
    容器内的命令 细节任务

image

posted @ 2022-09-07 16:12  躲不过这场雨  阅读(379)  评论(0编辑  收藏  举报