Docker知识点整理

Docker

什么是Docker?

  • 官方文档:https://docs.docker.com/
  • docker是Go语言开发的应用容器引擎
  • 以前一个产品从开发到上线,开发人员将项目打包后给运维人员部署,结果运维人员经常跑不起来,于是docker应运而生,将应用的操作系统、运行环境、配置等一起打包,解决了开发与运维的冲突!
  • 虽然以前是通过虚拟机来解决这种问题,但是虚拟机是模拟硬件实现资源消耗非常大,而docker则是虚拟OS粒度更小

Docker的基本组成

Docker 是C/S架构,通过操作本地docker Engine 使用镜像(模板)来创建对应容器(实例),可以从远程仓库中推送自己制作的镜像或者拉取自己想要的镜像

docker的基本组成

镜像

镜像是我们的软件与环境打包成的模板(分层构建),用这个镜像可以创建多个容器

容器

容器就是我们软件运行的实例,里面包括了一个虚拟的操作系统、可以运行独立的应用软件,每个容器是互相隔离的

仓库

官方仓库 https://hub.docker.com/ 是最大的镜像仓库、我们可以去注册账号发布自己的镜像,也可以搭建自己的镜像仓库

一张图了解docker的常用命令

一张图了解docker的常用命令

安装/配置docker

安装

基于CentOS安装,版本至少要 centos7: https://docs.docker.com/engine/install/centos/

  1. 卸载旧的版本

    yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
  2. 安装环境、软件包、配置镜像地址

    yum install -y yum-utils
    # 配置镜像地址
    # 官方地址(可能比较慢):--add-repo https://download.docker.com/linux/centos/docker-ce.repo
    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  3. 安装docker引擎

    # docker-ce 社区版本, docker-ee 企业版本
    yum install -y docker-ce docker-ce-cli containerd.io
  4. 启动docker

    systemctl start docker

配置镜像仓库

默认在官方的 https://hub.docker.com/ 去下载镜像可能非常慢,登录阿里云搜索 容器镜像服务 可查看自己的镜像加速地址

多平台镜像加速地址

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://sgivcmi6.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

Docker 底层原理

Docker与虚拟机VM

虚拟机:创建 GuestOS,模拟硬件,粒度很大重型的虚拟技术,性能只能达到宿主机的80%

vm

Docker:不需要再去虚拟化硬件资源,资源开销直接使用宿主机的,性能没有损耗

docker

优劣势对比:

优劣势对比

Docker镜像

什么是镜像?

  • 镜像就是一个轻量级的,独立的软件包!
  • 软件 + 运行环境 + linux 进行打包,只要运行这个容器即可提供服务!
  • 以前需要在每台linux系统上安装软件所需环境,现在只需安装docker,直接运行集成了环境的镜像即可!

镜像的加载原理

联合文件系统(Union FS)

核心:分层

bootfs/rootfs联合文件系统

bootfs与rootfs

  • bootfs(boot file system):bootloader + kernel ,bootloader进行引导加载 kernel 内核!此时内核已经在内存中了,内存的使用权从bootfs转交给了kernel,这时候就会自动卸载bootfs!在最底层Linux/Unix操作系统都是一样的!
  • rootfs(root file system):在bootfs之上,包含基本目录 /dev /bin /etc …. 等标准目录文件!市面上不同的操作系统发行版的区别就在于rootfs,所以底层都是bootfs!

以bootfs的基础的docker,镜像就可以只提供rootfs文件管理系统(只要包含一些基本的命令、工具、库即可),所有镜像统一使用宿主机上的kernel,大大缩小了镜像的大小,我们pull一个centOS的镜像也只需230M左右!也同时代表着所有的镜像底层都是linux系统!

分层概念

  • docker中的镜像也是分层的,从底层一层层往上构建起来,只要增加一层就会形成一个新的镜像

分层构建

  • 如果镜像毎发生一次变化,一旦被提交就会产生一个新的镜像,并且在上一个镜像增加一层

    # 可以将一个容器再次提交成镜像
    # -a 作者信息
    # -m 提交信息
    # -c 可使用dockerfile的指令来创建这个镜像
    # -p 提交期间暂停容器(默认true)
    docekr commit container newImgName[:tag]
    • commit之后使用 docker inspect img 对比原来镜像与最新镜像

    docker inspect redis:latest

    docker inspect redis:hth

  • 每个容器做的改变其实都发生在最上层 writeable 层,提交时 writeable 就会变成新镜像的最新层!

分层的好处:资源共享,每一层就像一个个组件存储在宿主机上,将需要的组件进行组装就可以组成一个镜像!如果已经有相同的组件多个镜像就可以共享一份!

Docker 基本使用

帮助命令

# 列出docker所有命令
docker --help
# 查看某个命令的用法
docker xxx --help

镜像命令

# 查看镜像
# -a, --all 查看所有的
# -f, --filter 查询条件
# -q, --quiet 只显示id
docker images
# 搜索镜像 只能看到镜像的名字,看不到tag与更详细的说明所以建议直接去dockerHub上搜索
# -f stars=5000 查看收藏不小于5000的镜像
# --limit 最大搜索结果
docker search imgName
# 下载镜像,tag就是镜像的版本号,不指定默认latest
docker pull imgName[:tag]
# 删除一个或多个镜像,如果还有容器在运行则删除不了,可以加上-f强制删除(此时会留下一个名为None的镜像删不了)
# 所以一般还是先删除次镜像的所有容器再删除镜像
docker rmi imgName[:tag]
# 组合命令 删除所有镜像
docker rmi -f $(docker images -aq)
# 查看镜像每一层的内容
docker history imgName[:tag]

容器命令

# 查看所有容器,默认只看处于运行状态的容器
# -a, --all 查看所有的
# -q, --quiet 只显示id
docker ps
# 创建一个新容器
# --name "Redis" 给容器指定一个名字
# -d 后台运行
# -i 保持打开状态
# -t 交互模式运行,分配终端。进入容器
# -P 大P,随机暴露端口
# -p 宿主机端口:容器内端口 小p,将容器内部的端口映射到宿主机端口
# -m 1024 指定内存为1024字节
# -v 挂载卷(目录挂载、具名挂载、匿名挂载)
docker run imgName[:tag]
# 停止
docker stop container
# 启动
docker start container
# 重启
docker restart container
# 强制停止
docker kill container
# 删除容器
docker rm container
# 删除全部容器
docker rm -f $(docker ps -qa)
# 提交为一个镜像
# -a 作者信息
# -m 提交信息
# -c 可使用dockerfile的指令来创建这个镜像
# -p 提交期间暂停容器(默认true)
docekr commit container newImgName[:tag]

其它命令

# 登录到远程仓库
# -u 用户名
# -p 密码
docker login [服务地址,默认为dockerHub]
# 查看某个容器中日志
# -f 跟踪日志持续输出
# --tail 查看最后多少条
# -t 显示时间戳
# --since 在指定时间之前的日志 🌰 --since 2020-06-01T10:53:50
# --until 在指定时间之后的日志
docker logs container
# 查看容器相关进程信息
docker top container
# 使用容器执行
# -d 后台执行
# -w 指定执行目录
# -e 设定环境变量
# -it 以交互模式运行
docker exec container 命令
# 进入正在执行的终端,不会创建新的终端
docker attach
# 复制容器内的文件到宿主机
docker cp container:/home/file /home
# 查看容器或镜像的详细信息
docker inspect container|image

Docker 数据卷

什么是数据卷?

  • 我们毎运行一个容器,文件都在容器内部的系统中,如果运行一些持久化软件,容器被删除了那么持久化文件也同时被删除!所以我们需要卷来将文件挂载到宿主机的文件系统中,这样即使删除容器挂载的文件依然存在!
  • 卷可以在一个或者多个容器内进行通信、共同存储文件。不属于联合文件系统。
  • 关键作用:只要挂载了的目录,无论在容器内修改还是在宿主机上修改,两边都会同步!

目录挂载

# 使用-v来进行挂载,指定 宿主机的目录 挂载到-> 容器内的目录
docker run -d -v /home/ceshi:/home centos

inspect 容器

匿名挂载

匿名挂载的方式会在宿主机 /var/lib/docker/volumes/ 下随机分配一个目录名字进行挂载,缺点是不好维护,所以一般会使用具名挂载。

# 匿名挂载,只指定一个容器内目录
docker run -d -v /etc/nginx nginx

inspect 容器

具名挂载

# 查看所有卷
docker volume ls
# 查看某个卷的挂载信息
docker volume inspect 卷名称
# 创建一个卷
docker volume create [卷名称(不写随机生成)]
# 删除一个卷
docker volume rm 卷名称
# 删除本地所有未使用的卷
docker volume prune
  • 具名挂载同样是在宿主机 /var/lib/docker/volumes/ 下创建

具名挂载

  • 指定具名卷进行挂载

    # 具名卷redisVolume 挂载到-> 容器内的目录/home 
    docker run -d -v redisVolume:/home redis

    inspect 容器

DockerFile

什么是DockerFile?

DockerFile是用于构建镜像的文本文件,内容包含了一条条要构建一个镜像所需的指令!

DockerFile

构建镜像的指令

完整指令

  • FROM 指定基于哪个镜像开始构建。(scratch是一个空的镜像,可以说是真正的从零开始构建自己的镜像)
  • RUN 编译镜像时运行的脚本,一般用于安装一些基础工具、依赖
  • CMD 指定要执行的命令但是只会执行最后一条命令。
    • 并且docker run img xxx 后面跟的xxx命令会覆盖这个 CMD 命令。
    • 比如一个redis的镜像 ENTRYPOINT 为redis-server,我们可以这么Run:docker run redis redis-server -raw -h localhost xxx -p 6380)
    • (注意:与 ENTRYPOINT 有细节上的区别 )
  • ENTRYPOINT 同样指定要执行的命令但是只会执行最后一条命令。
    • 并且docker run img xxx 后面跟的命令会与这个 CMD 命令进行拼接。
    • 比如一个redis的镜像 ENTRYPOINT 为 [“redis-server”] ,我们可以这么Run:docker run redis -raw -h localhost xxx -p 6380
  • WORKDIR 指定工作目录,进入容器后或使用exec执行的命令的默认路径
  • ADD 可以将一个 .tar.gz (不是这种压缩包就是直接复制)压缩包自动解压到镜像中指定目录
  • COPY 复制一个文件到镜像中指定目录
  • EXPOESE 暴漏容器运行时的监听端口给外部,但是EXPOSE并不会使容器访问主机的端口,如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P 或 -p 参数

编写Dockerfile

尝试自己写一个Dockerfile

目录结构

FROM centos:latest

# 构建者信息
MAINTAINER HTH<hth0406@163.com>
# 设置工作目录
ENV MYHOME /home
WORKDIR $MYHOME
# install vim
RUN yum -y install vim
# install 时区依赖 tzdata
ENV TZ Asia/Shanghai
RUN yum -y install tzdata

# 可替换命令
#CMD echo $MYHOME
#CMD echo $TZ
#CMD echo "---------END---------"
# -a 也可拼接输入到下面 ENTRYPOINT 后面
#CMD -a

# 可拼接命令
#ENTRYPOINT ["ls"]

# 暴露端口
EXPOSE 8080

# 添加或自动解压
ADD apache-tomcat-9.0.36.zip $MYHOME
ADD apache-tomcat-9.0.36.tar.gz $MYHOME

# 复制文件
COPY apache-tomcat-9.0.36.zip $MYHOME/xx/apache-tomcat-9.0.36.zip
COPY apache-tomcat-9.0.36.tar.gz $MYHOME/xx/apache-tomcat-9.0.36.tar.gz

构建镜像

# 使用Dockerfile构建镜像
# -t 构建镜像的 名称:标签,默认为dockerfile所在文件夹名称
# -f 指定的Dockerfile文件名称,如果名称为:Dockerfile 则不需要指定
docker build dockerfile文件路径
  • 我们编写的每一条指令最后都会commit变成一层层镜像

docker build

  • 注意:如果容器中没有正在运行的终端,容器运行完启动命令则会自动停止!所以在这里run的时候执行脚本保证容器不被停止

    docker run -it -d test-my-docker-file /bin/sh -c "while true; do sleep 1; done"

进入容器看看

Docker网络

  • 不同操作系统docker的网络实现有所不同,这里以linux系统为例。
  • 了解docker网络可以使我们更加了解容器与容器之间如何进行通信

docker0 网卡

  • 创建容器时不指定网卡默认为docker0,不能使用类似域名或者网卡名字进行联通
  • 使用 ip address 查看docker有独立的网卡管理docker的网段172.17.0.1/16 (一个网卡大概可以创建16位=255*255-1=65024个容器)

ip address

  • 运行一个tomcat容器随机暴露端口 docker run -d -P --name tomcat1 tomcat 并查看容器内的网卡 docker exec -it tomcat1 ip address,可以发现容器内的的ip在同一网段,并且得出结论可以在主机上ping通容器内部

    容器内网卡

  • 此时,在主机上再次查看网卡信息,可以发现多个一个网卡,并且与容器内部形成了配对关系

    每次启动一个容器都会产生一对的网卡

  • 在linux中只要是这类成对出现的网卡一般都是veth-pair技术

veth-pair

顾名思义,veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。可以使容器内的网卡与主机网卡形成一个整体,就像是在同一个网络当中。

正常情况下容器之间是互相隔离ping不通的,但是有了veth-pair技术,使我们在容器tomcat1中可以ping通tomcat2的ping!

Docker网络命令

网络模式

Docker网络模式 配置 说明
host模式 –net=host 容器和宿主机共享Network namespace。主机!
container模式 –net=container:NAME_or_ID 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。
none模式 –net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。自己设置
bridge模式 –net=bridge (默认为该模式)路由器,自动划分ip!
# 查看doker所有网络
docker network list
# 创建自定义网络
# -d 网络模式默认为 bridge
# --subnet 代表网段的CIDR格式的子网(例如:192.168.0.0/16)
# --gateway 网关(例如:192.168.0.1)
docker network create [OPTIONS] network-name
# 删除网络
docker network rm network-name
  • 使用 docker network inspect 查看bridge桥接模式的网络可以看到所有容器的网卡信息及对应ip

    docker network inspect c88973e0f000

  • 创建docker3 docker run -d -P --name tomcat3 --link tomcat2 tomcat 指定连通tomcat2

    tomcat3 ping tomcat2

  • 此时tomcat3已经被单向连接到了tomcat2,而单相连接顾名思义tomcat2并不会连通tomcat3

    tomcat2 ping tomcat3

  • 进入tomcat3容器,发现其实就是修改了hosts文件实现的域名解析!

    cat /etc/hosts

自定义网卡

  • 创建自定义网卡

    docker network create HTH

  • 创建容器使用 --net 指定自定义的网卡:docker run -d -P --name tomcat4 --net HTH tomcat

  • 再查看自定义网卡信息,发现分配了新的网段、网关(可自定),及网段中容器的网络信息!

    docker network inspect HTH

  • 此时在同一个网络下的多个容器即可使用容器名进行通信!

    docker exec -it tomcat4 ping tomcat5

Redis集群配置

# 创建网卡
docker network create redis --subnet 172.38.0.0/16

# 通过脚本创建6个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

docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done

# 进入一个redis
docker exec -it redis-1 /bin/sh

# 创建集群
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

# 连接集群 (-c 连接集群)
redis-cli -c

# 查看集群信息
cluster info

# 查看节点
cluster nodes

Docker Compose

简介

  • 官方文档: https://docs.docker.com/compose/
  • 微服务场景下,需要部署多个服务实例,如果每个服务一个个手动操作将会非常麻烦!
  • Docker Compose是Docker官方的开源项目,用来批量管理服务的工具。
  • Docker Compose核心就是配置一个yaml文件,配置在一个文件中的服务即可使用一键启停等高校方便的操作!
  • 一个docker-compose.yml编排多个容器为一个项目(project),其中每个容器(可能有多个副本)称为服务(service)。
  • 使用compose分为三步:
    1. 编写Dockerfile用于打包镜像(如果你的镜像已经存在或来自官网,就省略这步)
    2. 在docker-compose.yml里定义自己想要的服务(包括容器、网络、环境变量、挂载等)
    3. 通过docker-compose up 命令启动服务

安装

# 下载
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

# 第二步:修改此文件的权限,增加可执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 版本信息
docker-compose version

docker-compose.yml

  • 官方文件关键字详细说明https://docs.docker.com/compose/compose-file/
  • docker-compose可分为3个部分
    1. version 第一个部分指定版本(⤴️连接有version与docker引擎的对照表),向下兼容
    2. services 第二个部分是编排的服务,可写多个
    3. 第三部分分为其它命令,比如:networksvolumessecretsconfig 等等…

docker-compose 常用命令

# 启动所有服务,如果镜像不存在则先pull镜像或者buil镜像
# -d 后台方式启动
docker-compose up
# 一键stop、rm容器,rm网络
docker-compose down
# 只执行构建操作
docker-compose build
# 停止一个或多个服务
docker-compose stop [SERVICE...]
# 强制停止一个或多个服务
docker-compose kill [SERVICE...]
# 删除一个或多个服务所有容器
docker-compose rm [SERVICE...]
# 使用服务执行命令
# -d 后台执行
# -w 指定执行目录
docker-compose exec SERVICE COMMAND [ARG...]

部署一个简单的web项目

构建服务镜像

  1. 编写一个web服务,用redis实现毎访问一次累加,并且返回累加后的值

    @RestController
    @RequestMapping("/")
    public class HelloController {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping
    public Long hello() {
    return redisTemplate.opsForValue().increment(1);
    }
    }
    • application.yml
    server:
    port: 8091
    spring:
    main:
    allow-bean-definition-overriding: true
    redis:
    # 让环境变量进行覆盖
    host: ${SPRING_REDIS_HOST:localhost}
    port: 6379
  2. 用maven打成jar包

  3. 编写Dockerfile构建镜像

    # 指定java8基础镜像
    FROM java:8
    # 指定工作目录
    WORKDIR /home
    # 将web服务jar包复制到镜像工作目录中(Dockerfile所在文件夹中存放了刚刚打的jar包)
    COPY . .
    # 运行容器时使用java -jar 运行服务
    CMD ["java", "-jar","web-server-1.0-SNAPSHOT.jar"]

编写docker-compose

  • 编写docker-compose.yml
version: '3.8'
services:
# 命名为my-java-web服务
my-java-web:
# 构建当前目录下的Dockerfile
build: .
# 暴露端口相当于 run -p 8889:8091
ports:
- "8889:8091"
# 指定环境变量
environment:
- SPRING_REDIS_HOST=redis
# 依赖于redis,会在redis启动完毕之后再启动,redis停止之前先停止
depends_on:
- redis
networks:
- java-web
# 命名为redis服务
redis:
# 使用redis镜像运行
image: "redis"
networks:
- java-web
# 定义这个项目的网络名称后缀(可以不指定,默认创建的网络名为:default),前缀统一为compose.yml所在目录名_
networks:
java-web:

启动web服务

一切准备就绪只需 docker-compose up 即可将所有服务一键启动!

docker-compose up

访问测试

Docker Swarm

什么是Docker Swarm?

  • Swarm是Docker公司推出的用来管理docker集群的平台, 它是将一群Docker宿主机变成一个单一的虚拟主机,Swarm通过Docker客户端为入口进行工作
  • Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合
  • Swarm自己不运行容器,它是接收docker客户端发来的执行去调度适合的节点去执行任务

Swarm 架构

  • Worker:主要职责是接收 Manager 分派的任务
  • Manager:主要职责是维护集群的状态和信息、分派任务给合适的 Worker

Swarm 架构

Raft一致性协议

  • Swarm 遵循Raft一致性协议
  • Raft一致性协议保证绝大多数节点存活才可以使用
  • 如果有两个Manager节点,挂了一个,那么集群将不可用!所以一般配置Manager节点为奇数

创建/管理一个Swarm集群

搭建集群所需条件

  • 至少要3个能进行网络通信节点(买3台服务器)
  • 每个节点上都安装了安装了Docker 1.12或更高版本

开始搭建

# 初始化一个集群
docker swarm init

docker swarm init

  • docker告诉我们已经创建了一个Manager,接下来可以使用 docker swarm join --token TOKEN 命令在别的节点上加入集群成为Worker,或者使用 docker swarm join-token manager 查看管理者的join token:

    # 可以再次查看swarm加入集群所需的token
    docker swarm join-token manager|worker

    docker swarm join-token manager

  • 在其它两个节点上执行了join之后,在Manager上使用 docker node ls 可以查看集群节点列表

    docker node ls而Wroker则没有资格查看节点信息

详细命令整理

# 初始化一个集群
# --advertise-addr 设置广播地址,默认为私网ip
docker swarm init
# 查看swarm加入集群所需的token
docker swarm join-token manager|worker
# 加入集群
# --token Manager生成的token
docker swarm join [OPTIONS] HOST:PORT
# 离开当前集群
# -f 强制离开忽略警告
docker swarm leave
# 查看swarm集群列表
docker node ls

使用Swarm集群管理服务

创建nginx集群

  • 使用 docker service 可以向Swarm集群节点分配任务

  • 创建一个服务 docker service create -p 8888:80 --name myNginx nginx

    docker service create -p 8888:80 --name myNginx nginx

  • 查看服务列表

    docker service ls

  • 如此简单的配置,此时所有节点都可访问该服务

    访问测试

  • 当前是一个容器副本,使用 docker service update 来动态扩容

    docker service update --replicas 5 myNginx

  • 查看服务所有容器

    docker service ps myNginx

  • 此时,Swarm将容器随机分发到不同节点中运行,一个节点可运行多个容器互相隔离。整个集群服务对外暴露的只有一个8888端口,无论请求打在了哪个节点上Swarm会使用负载均衡算法分发到不同的节点上!

详细命令整理

# 创建服务
# --name 服务名称
# --replica 副本数量
docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
# 更新某个服务,参数与创建服务大部分一样
# --image 使用新的镜像
# --update-parallelism 同时更新的最大数量,配合--image可实现灰度发布
# --update-delay 每次升级的间隔(ns|us|ms|s|m|h)
docker service update [OPTIONS] SERVICE
# 查看一个或多个服务的容器信息
docker service ps [OPTIONS] SERVICE [SERVICE...]
# 删除一个或多个服务
docker service rm SERVICE [SERVICE...]
# 回滚上一次执行的任务,注意:重复执行会在两个状态下来切换(可用于高并发与平常状态的切换)
docker service rollback [OPTIONS] SERVICE
文章作者: 何同昊
文章链接: http://hetonghao.cn/2020/06/Docker/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 何同昊 Blog
支付宝超级火箭🚀
微信超级火箭🚀