天天看点

Docker学习笔记1. Docker学习笔记

文章目录

  • 1. Docker学习笔记
    • 1.1. Docker简介
    • 1.2. Ubuntu安装Docker CE(社区版)
      • 1.2.1. 卸载旧版本
      • 1.2.2. 使用存储库安装
        • 1.2.2.1. 设置存储库
        • 1.2.2.2. 安装Docker CE
        • 1.2.2.3. 升级 Docker CE
      • 1.2.3. 卸载 Docker CE
    • 1.3. Docker 可选设置
      • 1.3.1. 创建Docker组,并添加用户
      • 1.3.2. 配置Docker以在启动计算机时启动
    • 1.4. CentOS安装Docker CE(社区版)
      • 1.4.1. 卸载旧版本
      • 1.4.2. 安装Docker CE 存储库
      • 1.4.3. 可选项
      • 1.4.4. 安装Docker CE
    • 1.5. 入门
      • 1.5.1. 第1部分:方向和设置
        • 1.5.1.1. Docker的概念
        • 1.5.1.2. Images and containers(映像和容器)
        • 1.5.1.3. Containers and virtual machines(容器和虚拟机)
        • 1.5.1.4. 安装Docker
        • 1.5.1.5. Test Docker version
        • 1.5.1.6. Test Docker installation
        • 1.5.1.7. Recap and cheat sheet(回顾和备忘单)
      • 1.5.2. 第2部分: 容器
        • 1.5.2.1. Introduction
        • 1.5.2.2. Your new development environment
        • 1.5.2.3. Define a container with `Dockerfile` (使用`Dockerfile`文件定义容器)
        • 1.5.2.4. The app itself
        • 1.5.2.5. Build the app
        • 1.5.2.6. Run the app
        • 1.5.2.7. Share your image
        • 1.5.2.8. Log in with your Docker ID
        • 1.5.2.9. Tag the image
        • 1.5.2.10. Publish the image
        • 1.5.2.11. Pull and run the image from the remote repository
        • 1.5.2.12. Recap and cheat sheet(回顾和备忘单)
      • 1.5.3. 第3部分: services
        • 1.5.3.1. About services
        • 1.5.3.2. `Your first docker-compose.yml` file
        • 1.5.3.3. Run your new load-balanced app
        • 1.5.3.4. Sclae the app
        • 1.5.3.5. Take down the app and the swarm
        • 1.5.3.6. Recap and cheat sheet(回顾和备忘单)
      • 1.5.4. 第4部分: Swarms
        • 1.5.4.1. Introduction
        • 1.5.4.2. Understanding Swarm clusters
        • 1.5.4.3. Set up your swarm
        • 1.5.4.4. 安装docker-machine
        • 1.5.4.5. Create a cluster
        • 1.5.4.6. LIST THE VMS AND GET THEIR IP ADDRESSES
        • 1.5.4.7. INITIALIZE THE SWARM AND ADD NODES
        • 1.5.4.8. 在集群上部署你的应用
        • 1.5.4.9. 给集群管理员配置`docker-machine`脚本
        • 1.5.4.10. 在集群管理员节点上部署app
        • 1.5.4.11. 访问你的集群
        • 1.5.4.12. 迭代和扩展你的app
        • 1.5.4.13. 清除并重启
        • 1.5.4.14. Recap and cheat sheet(回顾和备忘单)
      • 1.5.5. 第5部分:Stacks
        • 1.5.5.1. Introduction
        • 1.5.5.2. 增加新服务器并部署
        • 1.5.5.3. 存储数据
      • 1.5.6. 第六部分:部署应用
        • 1.5.6.1. Introduction
        • 1.5.6.2. 创建一个集群
        • 1.5.6.3. 部署APP
        • 1.5.6.4. 运行集群命令来验证部署成功
        • 1.5.6.5. 在云主机上为服务打开端口
        • 1.5.6.6. 跟新和清除
        • 1.5.6.7. Congratulations!
    • 1.6. Docker设置技巧
      • 1.6.1. 更改image默认存储位置

1. Docker学习笔记

1.1. Docker简介

  • Docker是目前最火的开源项目之一
  • 由Docker公司开发
  • 托管于github docker地址
  • go语言编写
  • 提供了打包,传输,运行任意应用的容器解决方案
  • 适用于Linux,Windows,Mac平台
  • 简单易用

1.2. Ubuntu安装Docker CE(社区版)

Ubuntu系统上安装Docker

1.2.1. 卸载旧版本

sudo apt-get remove docker docker-engine docker.io containerd runc
           

1.2.2. 使用存储库安装

安装步骤:

1.2.2.1. 设置存储库

  1. 更新软件包索引
    sudo apt-get update
               
  2. 安装包以允许apt通过HTTPS使用存储库:
    sudo apt-get install \
    apt-transport-https \
    curl \
    gnupg-agent \
    software-properties-common
               
  3. 添加Docker官方GPG密匙
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
               
    通过搜索指纹的最后8个字符,验证您现在拥有带指纹的密钥
    $ sudo apt-key fingerprint 0EBFCD88
    
    pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
    uid           [ unknown] Docker Release (CE deb) <[email protected]>
    sub   rsa4096 2017-02-22 [S]
               
  4. 使用以下命令设置稳定存储库。要添加

    nightly

    test

    存储库,请在下面的命令中的单词后添加单词

    nightly

    test

    (或两者)stable。了解夜间和测试频道.

    x86_64/arm64处理器使用一下命令

    sudo add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"
               

1.2.2.2. 安装Docker CE

  1. 更新apt包索引
    sudo apt-get update
               
  2. 安装最新的docker CE 和 containerd
    sudo apt-get install docker-ce docker-ce-cli containerd.io
               
  3. 安装特定版本的Docker CE

    列出可用版本

    apt-cache madison docker-ce
               
    例如,使用版本

    5:18.09.1-3-0-ubuntu-xenial

    sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
               
  4. 运行

    hello-word

    验证是否正确安装了Docker CE
    sudo docker run hello-word
               

此时Docker CE 已经正确安装.

docker

组已经创建,但是尚未向其添加任何用户.

1.2.2.3. 升级 Docker CE

先运行

sudo apt-get update

, 然后按要求选择版本

1.2.3. 卸载 Docker CE

  1. 卸载Docker CE软件包
    sudo apt-get purge docker-ce
               
  2. 主机上的图像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷:
    sudo rm -rf /var/lib/docker
               

1.3. Docker 可选设置

1.3.1. 创建Docker组,并添加用户

Docker守护程序绑定到Unix套接字而不是TCP端口。默认情况下,Unix套接字由用户拥有root,其他用户只能使用它sudo。Docker守护程序始终以root用户身份运行。

如果您不想在docker命令前加上sudo,请创建一个名为的Unix组docker并向其添加用户。当Docker守护程序启动时,它会创建一个可由该docker组成员访问的Unix套接字。

  1. 创建Docker组
    sudo groupadd docker
               
  2. 将我的用户添加到Docker组
  3. 注销账户重新登录

1.3.2. 配置Docker以在启动计算机时启动

大多数的Linux发行版使用

systemd

命令,Ubuntu 14.10及以下使用upstart。

sudo systemctl enable docker
           

如果要禁止自启动

sudo systemctl disable docker
           

1.4. CentOS安装Docker CE(社区版)

1.4.1. 卸载旧版本

使用一下命令卸载

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

           
docker images,containers,volumes,networks 保存在

/var/lib/docker/

目录中.

1.4.2. 安装Docker CE 存储库

第一次安装之前,你需要设置

Docker

存储库. 之后,你可以在存储库中安装和升级.

  1. 安装需要的包.

    yum-utils

    提供

    yum-config-manager

    功能, 并且存储驱动程序需要

    device-mapper-persistent-data

    devicemapper

    sudo yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2
               
  2. 使用以下命令设置

    稳定版

    存储库
    sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
               

1.4.3. 可选项

Docker CE 有三个版本:

  • Stable : 稳定版
  • Test : 测试版
  • Nightly : 开发版
  1. 可以设置

    开发版

    版本库
    sudo yum-config-manager --enable docker-ce-nightly
               
  2. 设置

    测试版

    存储库
    sudo yum-config-manager --enable docker-ce-test
               
  3. 可以关闭

    开发版

    或者

    测试版

    存储库, 使用命令:

    yum-config-manager --disable

    .
    sudo yum-config-manager --disable docker-ce-nightly
               

1.4.4. 安装Docker CE

  1. 安装最新版的

    Docker CE

    containerd

    .
    sudo yum install docker-ce docker-ce-cli containerd.io
               

    如果安装了多个存储库

    如果有多个Docker版本存储库可以使用,那么使用

    yum > install

    或者

    yum update

    安装时, 系统会自动选> 择最新的版本安装. 如果要安装特定的版本, 请看步骤2.
  2. 安装特定版本的Docker

    a. 列出Docker CE 的版本

    yum list docker-ce --showduplicates | sort -r
    
               
    b. 根据版本的包名称,安装特定版本.
    sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
               
  3. 启动Docker
    sudo systemctl start docker
               
  4. 验证是否安装成功. 运行测试映像,

    hello-world

    sudo docker run hello-world
               
    此命令会下载一个测试映像.

现在Docker 已经安装完成, Docker 需要管理员权限才能运行. 如果你是非管理员用户,且不想用

sudo

命令, 可以设置(Linux postinstall)[https://docs.docker.com/install/linux/linux-postinstall/]

1.5. 入门

1.5.1. 第1部分:方向和设置

1.5.1.1. Docker的概念

Docker是开发人员和系统管理人员使用容器开发,部署,运行应用程序的平台. 使用Linux容器部署应用程序称为容器化.

Docker的优点:

  • 灵活: 即使是最复杂的应用也可以集成装箱化
  • 轻量级: 各个容器共享主机内核
  • 可互换: 可以及时部署和更新
  • 便携性: 可以本地构建,部署到云,并在任何地方运行它
  • 可扩展: 可以增加并自动分发容器的副本
  • 可堆叠: 可以垂直和即时堆叠服务

1.5.1.2. Images and containers(映像和容器)

容器是通过运行一个映像来启动.映像是一个可执行的包,它包含了所有运行一个目标程序所需要的: 代码,运行环境, 函数库, 环境变量, 配置文件.

容器是映像的一个运行实例.可以使用命令

docker ps

来列出当前在运行的容器

1.5.1.3. Containers and virtual machines(容器和虚拟机)

一个容器运行在原生的Linux上并且和其他容器共享主机内核. 它运行在一个独立的进程中,并不比其他可自行程序占用更多的内存,使得容器是轻量级的.

相比之下,虚拟机通过管理程序使用虚拟通道在主机上运行一个成熟的系统. 总之,虚拟机提供了一个远超过目标程序所需要的环境资源.

1.5.1.4. 安装Docker

见开头

1.5.1.5. Test Docker version

  1. 参看版本信息
    docker --version
               
  2. 查看更多详细信息
    docker info
               
    docker version
               

1.5.1.6. Test Docker installation

  1. 运行hello-word测试
    docker run hello-word
               
  2. 列出已经下载到本地的映像
  3. 列出所有的容器, --all 表示包括没有运行的
    docker container ls --all
               

1.5.1.7. Recap and cheat sheet(回顾和备忘单)

## List Docker CLI commands
docker
docker container --help

## 列出Docker版本和信息
docker --version
docker version
docker info

## 执行docker映像
docker run hello-world

## 列出docker镜像
docker image ls

## 列出Docker容器(running,all,all in quiet mode)
docker container ls
docker conainer ls --all
docker conainer ls -aq

           

1.5.2. 第2部分: 容器

1.5.2.1. Introduction

现在可以使用docker创建app.

  • Stack(栈)
  • Server(服务)
  • Container(容器)

1.5.2.2. Your new development environment

在过去, 如果你要写一个Python程序, 你的第一个任务是安装一个Python运行环境在你的机器上. 但是, 这会使你的计算机的运行环境既要运行你的app,又要匹配你的生产环境.

使用Docker, 你可以抓取一个便携的Python运行环境作为一个映像,没有必要安装. 然后, 你的构建可以包含基础的Python运行环境作为一个映像,确保你的app的依赖,运行环境等一起工作.

1.5.2.3. Define a container with

Dockerfile

(使用

Dockerfile

文件定义容器)

Dockerfile

定义那些程序运行在你的容器内的环境上. 有权使用的资源,例如:网络接口和磁盘在环境上是虚拟化的, 它是和电脑的其他部分相隔离的, 所以需要向外界露出接口, 确定什么文件需要复制到容器环境中. 做好这些之后,你可以期待定义在

Dockerfile

中的你的app的构建无论在哪里都可以有相同的运行表现.

Dockerfile

在本机计算机上创建一个空文件夹. 在该文件夹中创建一个名为

Dockerfile

的文件, 将以下信息复制粘贴到改文件中.

# Use an official Python runtime as a parent image
# 使用官方的Python运行环境作为一个母映像
FROM python:2.7-slim

# Set the working directory to /app
# 设置工作目录为 /app
WORKDIR /app

# Copy the current directory contents into the container at /app
# 复制当前目录的内容到容器中的 /app
COPY . /app

# Install any needed packages specified in requirements.txt
# 安装任何在requirements.txt中指定的包
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
# 该容器向外界开发80端口
EXPOSE 80

# Define environment variable
# 定义环境变量
ENV NAME World

# Run app.py when the container launches
# 当容器启动时,运行app.py
CMD ["python", "app.py"]

           

Dockerfile

引用的文件

app.py

,

requirements.txt

. 接下来创建他们.

1.5.2.4. The app itself

创建至少两个文件

requirements.txt

,

app.py

,将它们和

Dockerfiler

放入同一文件夹. 这便完成了我们的程序. 当上述的

Dockerfile

被构建到一个映像中,

app.py

requirements.txt

被表达, 因为

Dockerfile

COPY

命令. 并且输出文件

app.py

可以通过HTTP获得,是由于

EXPOSE

命令.

requirements.txt

Flask
Redis
           

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)
           

现在可以发现

pip install -r requirements.txt

安装

Flask

Redis

Python库, 并且app输出环境变量

NAME

, 同时调用输出

socket.gethostname()

. 最后Redis没有运行(因为我们只安装了Python库,并不是Redis本身),我们期望尝试使用它出错并且输出错误信息.

注意: 在容器内部访问容器ID时,访问主机名称, 如同进程ID一样.

你不需要Python或者其他在

requirements.txt

文件中的东西在你的系统中, 也不需要构建或者运行映像安装到你的系统中. 似乎也没有真正设置Python环境.

1.5.2.5. Build the app

现在开始构建应用程序,打开上述建立的根目录.目录中的文件包括:

$ ls
Dockerfile		app.py			requirements.txt
           

运行build命令, 它将创建一个Docker映像,

--tag=

将设置映像的名称.

-t

是缩写.

docker build --tag=friendlyhello .
# 注意最后的一个`.`,表示当前文件夹中的所有文件
           

创建的镜像将会在本地计算机的Docker映像仓库.

docker image ls
REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398
           

注意 标签项是

lstest

, 如果要加入版本号, 完整的tag设置,

--tag=friendlyhello:v0.0.1

linux用户故障排除

代理服务器设置

代理服务器可能在启动时阻塞你的web应用的连接. 如果你在代理服务器的后面, 加入一下内容在你的

Dockerfile

文件中, 使用

ENV

命令

来指定你的代理服务器的host和port.

# Set proxy server, replace host:port with values for your servers
ENV http_proxy host:port
ENV https_proxy host:port
           

DNS setting

DNS 的错误设置可能会产和

pip

产生错误. 你需要设置自己的DNS server地址来使

pip

正常工作. 你可以更改Docker进程守护的DNS,编辑在

/etc/docker/daemon.json

中的配置文件.如下:
{
	"dns": ["your_dns_address", "8.8.8.8"]
}
           

上述设置中,第一是你自己的DNS server , 第二个是备用的Google DNS(在中国可以正常使用?)

保存

daemon.json

并且重启docker服务.
sudo server docker restart
           
修复完成后尝试重置运行

build

命令

1.5.2.6. Run the app

运行应用, 使用

-p

命令匹配计算机的4000端口到容器的端口

80

.

docker run -p 4000:80 friendlyhello
           

现在可以在看见Python在

http://0.0.0.0:80

为你的应用提供消息. 但是该消息来着容器内部, 我们已经将容器的80端口映射到主机的4000端口, 所以在浏览器中访问

http://localhost:4000

4000:80端口的重映射说明了

Dockerfile

中的

EXPOSE

publish

值在启动

docker run -p

时的不同.

使用

ctrl + c

来退出容器.

现在让我们在后台以分离模式运行应用程序:

docker run -d -p 4000:80 friendlyhello
           

此时获得容器的长ID,并且容器在后台运行. 可以使用

docker container ls

命令查看 容器ID.

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago
           

使用

docker container stop progressID

来停止进程.

docker container stop 1fa4ab2cf395
           

1.5.2.7. Share your image

为了证明我们创建的容器的可移植性,上传我们构建的image并且在其他地方运行它.

注册表是仓库的集合, 仓库是映像的集合. 许多代码仓库,例如Github, 会排除已经构建的代码. 注册表上的一个账号可以创建许多仓库.

docker

命令行默认使用Docker的公共注册表.

也可以选择其他的注册表,Docker Trusted Registry

1.5.2.8. Log in with your Docker ID

注册一个Docker账号 hub.docker.com.在本地登录使用:

docker login
           

1.5.2.9. Tag the image

结合本地映像和注册表上的仓库的标记是

username/repository:tag

. 这个标记是可选的, 但是推荐选择. 它的作用是给image一个版本号. 给仓库和版本号一个有意义的名字,例如

get-started:part2

,它将会把映像放在

get-started

仓库中并且标记它为

part2

.

保存映像:

docker tag image username/repository:tag
           

例如:

docker tag friendlyhello gordon/get-started:part2
           

查看映像:

docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
gordon/get-started         part2               d9e555c53008        3 minutes ago       195MB
python                   2.7-slim            1c7128a655f6        5 days ago          183MB
           

1.5.2.10. Publish the image

上传你标记的映像到仓库:

docker push username/repository:tag
           

完成之后登录Docker Hub.

1.5.2.11. Pull and run the image from the remote repository

使用

docker run

命令在其他机器上运行.

docker run -p 4000:80 username/repository:tag
           

如果本地没有该映像, Docker将会从仓库中拉去下来.

docker run -p 4000:80 gordon/get-started:part2
Unable to find image 'gordon/get-started:part2' locally
part2: Pulling from gordon/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for gordon/get-started:part2
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
           

无论在哪运行

docker run

命令, 它都会拉去你的映像,并且会拉去所有在

requirements.txt

中的依赖文件, 并且运行你的代码. 它们将会在一个小而紧凑的包里运行, 不需要再安装额外的软件.

1.5.2.12. Recap and cheat sheet(回顾和备忘单)

docker build -t friendlyhello .  # 使用Dockerfile创建映像
docker run -p 4000:80 friendlyhello  # Run "friendlyhello" mapping port 4000 to 80
docker run -d -p 4000:80 friendlyhello         # 在分离模式下运行,即在后台运行
docker container ls                                # 列出所有在运行的容器
docker container ls -a             # 列出所有运行和不运行的容器
docker container stop <hash>           # 停止指定的容器
docker container kill <hash>         # 强制关闭指定容器
docker container rm <hash>        # 从机器中删除指定的容器
docker container rm $(docker container ls -a -q)         # Remove all containers
docker image ls -a                             # List all images on this machine
docker image rm <image id>            # Remove specified image from this machine
docker image rm $(docker image ls -a -q)   # Remove all images from this machine
docker login             # Log in this CLI session using your Docker credentials
docker tag <image> username/repository:tag  # Tag <image> for upload to registry
docker push username/repository:tag            # Upload tagged image to registry
docker run username/repository:tag                   # Run image from a registry
           

1.5.3. 第3部分: services

在第三部分, 规划我们的应用程序并且使其加载均衡. 为了实现它,我们要在分布式应用程序的上一层:server层.

  • Stack
  • Services
  • Container

1.5.3.1. About services

在一个分布式的应用中, app的不同部分被称为

services

. 例如, 如果你想建立一个视频分享网站, 当用户上传了一个视频之后一个转码的服务将在后台运行, 并且前端服务等程序在运行.

servives

仅仅是

containers in production

. 服务仅仅运行在一个

image

上, 但是它编码了映像运行的方式:它应该运行在那些端口,应该运行多少的副本,等等. 扩展服务会增加运行程序的容器实例的数量, 会分配更多的计算机资源给服务进程.

在Docker中,定义,运行,和规划服务将会非常容易. --仅仅写一个

docker-compose.yml

文件即可.

1.5.3.2.

Your first docker-compose.yml

file

docker-compose.yml

是一个

YAML

文件, 它定义了Docker容器在生产环境的表现.

在任何地都可以保存

docker-compose.yml

文件. 确保你在第二部分已经将映像推送到注册表中, 并且通过替换

username/repo:tag

来更新

.yml

.

.yml

文件信息

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: username/repo:tag
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "4000:80"
    networks:
      - webnet
networks:
  webnet:

           

上述的

docker-compose.yml

文件告诉Docker做以下工作:

  • 从注册表中拉取下来我们在第二部中上载的映像
  • 运行5个实例作为一个名为

    web

    的服务, 限制每个实例最多占用10%的CUP使用率,和50M 内存.
  • 如果有一个实例运行失败,立即重启服务
  • 映射4000端口到web’s 80 端口
  • 指导

    web

    '的容器通过一个叫做

    webnet

    的加载均衡网络共享80端口.
  • 定义

    webnet

    网络使用默认设置.

    webnet

    是一种负载均衡的覆盖网络.

1.5.3.3. Run your new load-balanced app

在我们运行

docker stack deploy

命令之前, 先运行:

docker swarm init
           
关于

docker swarm init

的介绍将在第四部分.

现在可以运行了. 需要给你的app一个名称, 下面的命令中名称为

getstartedlab

:

docker stack deploy -c docker-compose.yml getstartedlab
           

我们的一个服务栈将运行5个容器在我们部署的端口上.

获取服务的 ID

根据app的名字来寻找我们创建的

web

服务. 在上面的例子中我们将其命名为

getstartedlab

.

docker stack services getstartedlab
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
bqpve1djnk0x        getstartedlab_web   replicated          5/5                 username/repo:tag   *:4000->80/tcp

           

在输出中,将会看家服务的ID, 名称, 模式, 重复数量, 映像, 端口信息

运行在service中的一个容器被称为一个

task

.

tasks

被赋予数字上递增的唯一ID,取决于

docker-compose.yml

文件中的

replicas

定义的参数.

列出service中的

task

s

docker service ps getstartedlab_web
           

如果仅仅列出所有系统中的

task

,没有被服务过滤的和被服务过滤的都会被列出来.

docker container ls -q
           

你可以在多运行

curl -4 https://localhost:4000

(如果由于报错可以试试将https改为http)几次, 或者去在浏览器中多刷新几次.

你会发现容器的ID变了, 证明负载均衡在这5个task中选择.

你可以运行

docker stack ps

来查看所有的tasks. 输出如下:

docker stack ps getstartedlab
ID                  NAME                  IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
uwiaw67sc0eh        getstartedlab_web.1   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
sk50xbhmcae7        getstartedlab_web.2   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
c4uuw5i6h02j        getstartedlab_web.3   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
0dyb70ixu25s        getstartedlab_web.4   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
aocrb88ap8b0        getstartedlab_web.5   username/repo:tag   docker-desktop      Running             Running 9 minutes ago
           

1.5.3.4. Sclae the app

你可以通过在

docker-compose.yml

文件中修改

replicas

来修改app的规模.

保存修改后,重新运行

docker stack deploy

命令:

docker stack deploy -c docker-complose.yml getstartedlab
           

docker 进行一个现场更新, 不需要先撤销

task

和kill 容器.

现在运行

docker container ls -q

命令来查看部署的实例的配置信息.

1.5.3.5. Take down the app and the swarm

  • 使用

    docker stack rm

    命令来拆解app:
    docker stack rm getstartedlab
               
  • 拆解群
    docker swarm leave --force
               

下一个部分将学习在Docker机器集群运行你的app.

1.5.3.6. Recap and cheat sheet(回顾和备忘单)

docker stack ls                                            # List stacks or apps
docker stack deploy -c <composefile> <appname>  # Run the specified Compose file
docker service ls                 # List running services associated with an app
docker service ps <service>                  # List tasks associated with an app
docker inspect <task or container>                   # Inspect task or container
docker container ls -q                                      # List container IDs
docker stack rm <appname>                             # Tear down an application
docker swarm leave --force      # Take down a single node swarm from the manager
           

1.5.4. 第4部分: Swarms

1.5.4.1. Introduction

第四部分将介绍怎样将你的应用部署到集群, 将它运行在多机器系统中.

荣通过连接多个机器到一个被称为

Dockerized

的簇,使得多容器和多机器程序构成一个群集.

1.5.4.2. Understanding Swarm clusters

集群是一组计算机运行Docker并且加入到集群中. 在这之后,你可以继续运行你习惯的docker命令, 但是现在他们通过

swarm manager

(集群管理器)运行在集群中. 集群中的机器可以是实际的机器也可以是虚拟机. 当加入到集群之后他们都被称为

node

(节点).

集群管理器可以运用几种策略来运行容器, 例如:

emptiest node

(最空节点):它用容器填充利用率最低的机器;

global

(全局):它确保每个机器恰好启动一个指定容器的实例. 你可以在

Compose file

中为集群管理器指定策略.

集群管理器是在一个集群中唯一一个你可以执行你的命令的机器, 或者授权背的机器加入集群作为

workers

.

workers

仅仅能够提供生产力并没有权限告诉其他机器自己能做什么.

到目前为止, 你只是使用Docker在你本地的一个主机上. 但是Docker的强大之处在于它可以切换到

swarm mode

集群模式. 启动集群模式会立即使得当前机器称为集群管理员. 之后,Docker在集群的机器上执行你的任务,而不是只在你的当前主机上.

1.5.4.3. Set up your swarm

集群是由多节点组成, 实际的机器或是虚拟机都可以作为节点.

运行

docker swarm init

来打开集群模式并使你当前机器作为集群管理员.

之后在其他机器运行

docker swarm join

来使他们加入到集群中.

1.5.4.4. 安装docker-machine

Docker Machine是一个工具,可让你在虚拟主机上安装Docker Engine,并使用docker-machine命令管理主机。docker-machine

base=https://github.com/docker/machine/releases/download/v0.16.0 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
  sudo install /tmp/docker-machine /usr/local/bin/docker-machine
           

1.5.4.5. Create a cluster

  1. 首先安装虚拟机 ( install Oracle VirtualBox )[https://www.virtualbox.org/wiki/Downloads].
  2. 使用

    docker-machine

    创建一些虚拟机:
    docker-machine create --driver virtualbox myvm1
    docker-machine create --driver virtualbox myvm2
               

1.5.4.6. LIST THE VMS AND GET THEIR IP ADDRESSES

现在你创建了两个虚拟机,

myvm1

,

myvm2

.

使用一下命令列出虚拟机的IP, 可能需要管理员权限.

docker-machine ls`
           

以下是输出样例:

$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
myvm1   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce
           

1.5.4.7. INITIALIZE THE SWARM AND ADD NODES

第一台机器作为管理员, 它执行管理命令和授权其他机器加入集群.

使用

docker-machine ssh

发送命令到虚拟机.

使用

docker swarm init

命令来使

myvm1

成为集群管理员,输入如下:

$ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"
Swarm initialized: current node <node ID> is now a manager.

To add a worker to this swarm, run the following command:

  docker swarm join \
  --token <token> \
  <myvm ip>:<port>

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
           
  • 端口2377 和端口 2376

    docker swarm init

    docker swarm join

    使用>端口2377或者使用默认端口.

    docker-machine ls

    命令返回机器的IP地址包括端口>2376,改端口是docker守护进程的端口, 请不要使用该端>口做其他事情.
  • 使用SSH有问题? 试试

    --native-ssh

    标签

    Docker 机器可以让你使用原生ssh而不是docker集成的ssh.使用一下命令将会调用机器原生的ssh

    docker-machine --native-ssh ssh myvm1 ...
               

docker swarm init

命令包含了预设的

docker swarm join

命令, 复制它,然后在

myvm2

上执行,使

myvm2

作为一个工作节点加入到集群.

$ docker-machine ssh myvm2 "docker swarm join \
--token <token> \
<ip>:2377"

This node joined a swarm as a worker.
           

到此,一个简单的集群创建完成.

在管理员机器上运行

docker node ls

:

$ docker-machine ssh myvm1 "docker node ls"
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
brtu9urxwfd5j0zrmkubhpkbd     myvm2               Ready               Active
rihwohkh3ph38fhillhhb84sk *   myvm1               Ready            
           
如果想使得一个节点脱离集群, 使用命令:

docker swarm leave

.

1.5.4.8. 在集群上部署你的应用

有两点需要记住

  • 只有集群管理员节点可以执行Docker 命令
  • workers

    节点只能进行工作

1.5.4.9. 给集群管理员配置

docker-machine

脚本

到目前已经学习了:

docker-machine ssh

命令来控制虚拟机.

另外一种方法是

docker-machinne env <maxhine>

命令配置当前脚本并与虚拟机上的Docker守护程序进行通信. 在下一部分中该方法的效果更好,因为它允许你使用本地的

docker-compose.yml

文件配置远程的app.

输入

docker-machine env myvm1

, 之后复制粘贴并运行输出的最后一行提供的命令,配置shell与集群管理员通信(myvm1).

配置shell的命令根据系统不同而提供不同版本.以下只研究Linux版本

运行

docker-machine env myvm1

来获取一条命令,该命令用于配置你的的shell与

myvm1

进行通信.

$ docker-machine env myvm1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)
           

接下来运行给出的命令:

运行

docker-machine ls

来查看

mymv1

是否在运行,

*

表示激活作态.

$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
myvm1   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce
           

1.5.4.10. 在集群管理员节点上部署app

现在

myvm1

已经启动, 可以使用它作为集群管理员使用

docker stack deploy

命令和

docker-compose.yml

文件来配置你的app,

在集群管理员上使用

docker service ps <service_name>

命令确认所有的服务被重新部署.

确保当前终端路径中包含

docker-compose.yml

文件. 运行以下命令:

docker stack deploy -c docker-compose.yml getstartedlab
           

现在,app已经成功部署到了集群上.

如果你的

image

是存储在私有仓库的,那么你需要

docker login <your-registry>

命令来登录; 另外还要 >

--with-registry-auth

标志.
docker login registry.example.com

docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab
           

现在使用和第三部分相同的命令查看

task

, 方向,

servers

被分配在了

myvm1

myvm2

上.

$ docker stack ps getstartedlab

ID            NAME                  IMAGE                   NODE   DESIRED STATE
jq2g3qp8nzwx  getstartedlab_web.1   gordon/get-started:part2  myvm1  Running
88wgshobzoxl  getstartedlab_web.2   gordon/get-started:part2  myvm2  Running
vbb1qbkb0o2z  getstartedlab_web.3   gordon/get-started:part2  myvm2  Running
ghii74p9budx  getstartedlab_web.4   gordon/get-started:part2  myvm1  Running
0prmarhavs87  getstartedlab_web.5   gordon/get-started:part2  myvm2  Running
           
  • 使用

    docker-machine env

    docker-machine ssh

    来连接虚拟机.
    • 为了设置你的shell终端与别的机器通信,比如在本次例子中的

      myvm2

      ,仅需要再次在shell终端中运行

      docker-machine env

      命令, 之后运行给出的命令连接

      myvm2

      .如果你换了一个没有配置的shell或一个新的shell,你需要重新运行配置指令. 使用

      docker-machine ls

      列出所有的机器, 查看它们的状态,IP的信息,并找出哪一个已经连接.
    • 另外一种选择是,你可以用一下命令包裹Docker命令,

      docker-machine ssh <machine> "<command>"

      , 该方式的logs会直接记录到VM中,但是不会立即给你在本地机器上的访问通道.
    • 在Mac或者Linux中,你可以使用

      docker-machine scp <file> <machine>:~

      来复制文件到其他机器.

1.5.4.11. 访问你的集群

你可以通过

myvm1

myvm2

的IP地址来访问你的app.

运行

docker-machine ls

来获取 VMs’ IP地址并且在浏览器中访问他们.

确保集群节点上的7946和4789端口打开:
  • 7946 TCP/UDP 用于容器网络发现
  • 4789 UDP 用于容器入口网络

1.5.4.12. 迭代和扩展你的app

在这里可以做第二部分和第三部分的操作.

扩展app通过更在

docker-compose.yml

文件.

更在app的行为,通过编辑代码,重构,并推送新的

image

.

无论在什么情况下,运行

docker stack deploy

来部署更改.

你可以使用

docker warm join

来增加集群的节点. 在运行

docker stack deploy

之后, app即可利用新的计算资源.

1.5.4.13. 清除并重启

  1. Stacks and swarms

    你可以撤销

    stack

    使用命令:

    docker stack rm

    :
    docker stack rm getstartedlab
               
    保留机器或者移除
    • 移除工作节点使用:

      docker-machine ssh myvm2 "docker swarm leave"

    • 移除管理员节点:

      docker-machine ssh myvm1 "docker swarm leave --force"

  2. 取消对docker-machine shell的变量设置

    在 Mac or Linux 上:

    在Windows系统上:

    "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env -u | Invoke-Expression
               
    以上命令将会断开与

    docker-machine

    创建的虚拟机的连接.
  3. 重启

    如果关闭了本地主机, Docker机器停止执行. 查看Docker机器的状态使用命令:

    docker-machine ls

    .
    $ docker-machine ls
    NAME    ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
    myvm1   -        virtualbox   Stopped                 Unknown
    myvm2   -        virtualbox   Stopped                 Unknown
               

    为重启机器,运行:

    例如:

    $ docker-machine start myvm1
    Starting "myvm1"...
    (myvm1) Check network to re-create if needed...
    (myvm1) Waiting for an IP...
    Machine "myvm1" was started.
    Waiting for SSH to be available...
    Detecting the provisioner...
    Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
    
    $ docker-machine start myvm2
    Starting "myvm2"...
    (myvm2) Check network to re-create if needed...
    (myvm2) Waiting for an IP...
    Machine "myvm2" was started.
    Waiting for SSH to be available...
    Detecting the provisioner...
    Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
               

1.5.4.14. Recap and cheat sheet(回顾和备忘单)

docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1                # View basic information about your node
docker-machine ssh myvm1 "docker node ls"         # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>"        # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker"   # View join token
docker-machine ssh myvm1   # Open an SSH session with the VM; type "exit" to end
docker node ls                # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave"  # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1            # Start a VM that is currently not running
docker-machine env myvm1      # show environment variables and command for myvm1
eval $(docker-machine env myvm1)         # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression   # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app>  # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"   # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u)     # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q)               # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images

           

1.5.5. 第5部分:Stacks

1.5.5.1. Introduction

该部分是分布式应用程序的顶层:

stack

.

stack

是是一组共享依赖,可以相互协调和扩展的一组服务.

一个

stack

可以定义和协调一个完整的app的功能(尽管复杂的程序可能会需要多个

stack

).

一些好消息是,从第3部分开始,当您创建Compose文件并使用时,您在技术上一直在使用

stack

docker stack deploy

。但这是在单个主机上运行的单个服务堆栈,不是生产环境所用device方法。在这部分,将使多个服务相互关联,并在多台计算机上运行它们。

1.5.5.2. 增加新服务器并部署

使用

docker-compose.yml

文件可以很容易的添加服务.

首先增加一个观察者服务, 用它来观察我们的集群怎么调度容器.

  1. 打开

    docker-compose.yml

    文件, 使用一下文件替换内容.注意

    username/repo:tag

    version: "3"
    services:
      web:
        # replace username/repo:tag with your name and image details
        image: username/repo:tag
        deploy:
          replicas: 5
          restart_policy:
            condition: on-failure
          resources:
            limits:
              cpus: "0.1"
              memory: 50M
        ports:
          - "80:80"
        networks:
          - webnet
      visualizer:
        image: dockersamples/visualizer:stable
        ports:
          - "8080:8080"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
          placement:
            constraints: [node.role == manager]
        networks:
          - webnet
    networks:
      webnet:
               
    这里新加入了一个名为

    visualizer

    web

    服务.

    注意这里有两个新的东西:

    • valumes

      键: 让可视化工具访问Docker的主机套接字文件;
    • placement

      秘钥: 确保这个服务只能在

      swarm

      管理器上运行,但不是一个

      worker

      节点.
    该容器是docker开源项目创建的, 用一个图标来展示集群上运行的Docker服务.
  2. 确保shell终端与

    myvm1

    在通信状态.
    • 运行

      docker-machine ls

      列出计算机并确保已经连接上

      myvm1

      .

      *

      表示连接上.
    • 如果没有连接,重新运行

      docker-machine env myvm1

      , 详情请看第四部分.
  3. 在管理器上重新运行命令

    docker stack deplay

    , 并更新需要更新的任何服务:
    $ docker stack deploy -c docker-compose.yml getstartedlab
    Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)
    Creating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
               
  4. 查看可视化工具

    在compose文件中设置了

    visualizer

    的端口的

    8080

    , 运行

    docker-machine ls

    获取其IP地址. 然后在浏览器中查看.

1.5.5.3. 存储数据

现在添加

Redis

数据库来存储aap的数据.

  1. 修改

    docker-compose.yml

    文件:
    version: "3"
    services:
      web:
        # replace username/repo:tag with your name and image details
        image: username/repo:tag
        deploy:
          replicas: 5
          restart_policy:
            condition: on-failure
          resources:
            limits:
              cpus: "0.1"
              memory: 50M
        ports:
          - "80:80"
        networks:
          - webnet
      visualizer:
        image: dockersamples/visualizer:stable
        ports:
          - "8080:8080"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
          placement:
            constraints: [node.role == manager]
        networks:
          - webnet
      redis:
        image: redis
        ports:
          - "6379:6379"
        volumes:
          - "/home/docker/data:/data"
        deploy:
          placement:
            constraints: [node.role == manager]
        command: redis-server --appendonly yes
        networks:
          - webnet
    networks:
      webnet:
    
               
    在Docker中有一个

    Redis

    的官方映像,并拥有一个简短的映像名称:

    redis

    . Redis默认使用容器的6379端口暴露给主机.

    最重要的是,在

    redis

    的规范中有如下几个事情会使数据在

    stack

    的部署之间保持不变:
    - `redis`总是在管理器(管理员节点)上运行,所以它总是使用相同的文件系统.
     - `redis`在主机的任意文件路径下作为数据的存储路径.
               
    总之, 它在主机的物理文件系统中为redis数据创建数据库, 否则,

    redis

    将数据存储在容器的文件系统中, 如果重启容器,数据将会丢失.

    "数据的真实来源"包含一下两个内容:

    • 放置Redi服务的主机要确保它所使用的host不会变.
    • 你在主机上创建的存储空间,Redis可以访问. 容器的销毁与新建不会影响到数据.
  2. 在管理员节点上创建一个

    ./data

    文件夹.
  1. 确保shell终端已经配置了和

    myvm1

    的通讯.
  • 运行

    docker-machine ls

    来列出并且确认你已经连接上了

    myvm1

    ,连接上以后会有一个

    *

    号.
  • 如果没有连接上,那么运行命令

    docker-machine env myvm1

    , 该命令会给出一条命令,复杂这条命令并运行它.
    • 在Mac或者Linux上,命令如下: 在Windows系统上:
      "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
                 
  1. 再一次运行

    docker stack deploy

    docker stack deploy -c docker-compose.yml getstartedlab
               
  2. 运行

    docker service ls

    命令,来查看这三个服务已经在正确的运行.
    docker service ls
    ID                  NAME                       MODE                REPLICAS            IMAGE                             PORTS
    x7uij6xb4foj        getstartedlab_redis        replicated          1/1                 redis:latest                      *:6379->6379/tcp
    n5rvhm52ykq7        getstartedlab_visualizer   replicated          1/1                 dockersamples/visualizer:stable   *:8080->8080/tcp
    mifd433bti1d        getstartedlab_web          replicated          5/5                 gordon/getstarted:latest    *:80->80/tcp
    
               
  3. 在一个节点上访问:

    http://192.168.99.101

    ,查看访问者数量,现在它被Redis存储,并可以被正确访问.

    另外,在任一个节点的IP加端口号8080访问Docker可视化界面,例如:

    192.168.99.100:8080

    .可以看见正在运行的

    redis

    服务.

1.5.6. 第六部分:部署应用

1.5.6.1. Introduction

本节将学习

Dockerized application

的一些选项.

1.5.6.2. 创建一个集群

运行

docker swarm init

来创建一个集群.

1.5.6.3. 部署APP

运行

docker stack deploy -c docker-compose.yml getstartedlab

命令来部署应用在云主机上.

docker stack deploy -c docker-compose.yml getstartedlab

Creating network getstartedlab_webnet
Creating service getstartedlab_web
Creating service getstartedlab_visualizer
Creating service getstartedlab_redis
           

1.5.6.4. 运行集群命令来验证部署成功

以下为一些必须熟悉的命令:

  • docker node ls

    列出集群所有节点.
  • docker service ls

    列出所有服务
  • docker service ps <service>

    列出一个服务的所有

    tasks

    (任务).

1.5.6.5. 在云主机上为服务打开端口

如果app被部署到了云服务器,需要在服务器上打开几个必须的端口.因为一下几个原因:

  • 如果使用许多节点,允许

    redis

    web

    服务之间通信
  • 允许访问

    web

    的任何节点,以便web服务和

    visualizer

    可以在浏览器中访问.
  • 允许

    manager

    节点的ssh访问.

以下是服务需要暴露的端口:

service Tpye Protocol Port
web HTTP TCP 80
visualizer HTTP TCP 8080
redis TCP TCP 6379

1.5.6.6. 跟新和清除

  • 缩放app通过更改

    docker-compose.yml

    文件并且使用命令

    docker stack deploy

    重新部署
  • 更改app的行为通过更改code,重构,推送新的映像.
  • 拆卸stack,使用命令

    docker stack rm

    .例如:
    docker stack rm getstartedlab
               

1.5.6.7. Congratulations!

现在我以及学习完docker的使用,以下为进一步学习内容:

  • Samples 包含了一些流行软件在Docker上的使用.
  • User Guide 包含一个示例,深入解释联网和存储功能
  • Admin Guide 管理Docker化的生成环境的程序
  • Training 官方的Docker课程,它提供了可以实验的学习环境.
  • Blog 官方博客

1.6. Docker设置技巧

1.6.1. 更改image默认存储位置

docker默认的存储位置为

/val/lib/docker

更改存储位置

  1. 备份重要的映像
docker save -o 文件名.tar 镜像名
           
  1. 指定新位置
sudo mkdir /etc/systemd/system/docker.service.d
sudo touch /etc/systemd/system/docker.service.d/docker-overlay.conf #文件名应该可以随便取
sudo vim /etc/systemd/system/docker.service.d/docker-overlay.conf
           
  1. 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
           
  1. 恢复备份的映像
  1. (可选) 删除旧的

    /var/lib/docker

    目录
sudo rm -r /var/lib/docker