在Docker swarm模式下,介绍Docker的编排工具
这篇文章是为那些已经接触过 Docker,但从未使用过像 Kubernetes 这样的编排工具的人准备的。我们将通过使用 Docker 的 Swarm mode 来构建一个多主机集群,并介绍一些代表性功能(如扩容和滚动更新)的实际操作。
只需要一个选项,以下是对该句子的中文释义:
虽然我想尝试一下编排工具,但Kubernetes有点门槛高,对于那些想要简单方便的人来说,Swarm模式是个不错的选择。
这次试验的环境如下所示。
环境
-
- Ubuntu 18.04 LTS 3台
-
- Docker version 18.09.7
- docker-compose version 1.24.0
Docker swarm mode 是什么?
这是Docker在1.12版本之后引入的编排工具。
通过使用这个,不仅可以利用Docker的功能,还可以粗略地实现以下内容。
-
- 複数ホスト間でのクラスタの構築
-
- コンテナレベルでのスケールアウト
-
- ローリングアップデートを用いた無停止デプロイ
- コンテナレベルでの迅速なロールバック
另外,Swarm与docker-compose非常兼容,在基于docker-compose.yml文件定义的容器组中一次性应用上述功能是可以实现的。
(从docker-compose的版本3开始,甚至提供了一种专门适用于swarm模式的deploy语法)
这非常强大,如果您平常使用docker-compose,可以轻松获得一个集群环境,而无需破坏现有的工作流程。
作为容器编排工具,最近有一种感觉是Kubernetes成为了无可争议的霸主,但Docker swarm mode已被默认集成在Docker的CE版中,所以只需安装Docker即可轻松开始使用。
构建集群也只需输入几行命令,非常简单。作为了解容器编排的入口,试用一下会非常有利。
顺便说一下,在EnterPrise版的Docker中,似乎将kubernetes与swarm一样集成到了Docker里,如果您有可以使用的环境,也可以尝试使用它。
我想在本次活动中,基于官方的Swarm教程,并稍作修改以便更易理解,进行实地操作。如果想要更详细了解的话,可能更好去看一下教程。
环境准备
好吧,这次我打算使用三台Linux服务器(Ubuntu 18.04LTS)来建立一个集群。
为此,首先我需要准备三台Linux机器。
虽然可以在AWS或Azure上租虚拟机,但由于这次只是试验,我想在本地环境中使用Virtualbox和Vagrant来创建三台虚拟机。
构成如下所示

顺便提一下,这次用来创建虚拟机的主机是Mac。请注意,我们没有在Windows环境中进行验证。总之,只要能够建立三台虚拟机,使用任何方法都可以。
安装Virtual Box和Vagrant。
从官方网站上下载对应的安装程序并进行安装。
-
- Virtual box
- Vagrant
2. 创建虚拟机
安装完成后,我们将创建虚拟机。首先,为Vagrant创建一个目录,每个虚拟机一个。我们将把它们命名为node1、node2、node3。
.
├── node1
│ └── data // VMとホストの共有フォルダ docker-compose.ymlなどの構築資材を置く
├── node2
│ └── data
└── node3
└── data
请进入每个节点目录的根目录,并执行以下命令。
$ cd ./node1
$ vagrant init ubuntu/bionic64
然后根据以下内容创建Vagrantfile,我认为为每个节点分配IP地址可以按以下方式进行修改。请确保为每个节点设置不同的IP地址。
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "ubuntu/bionic64"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10" ## ここのコメントアウトを外し、一意なipアドレスを各nodeに割り振る
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# dataディレクトリをVMにマウントする
config.vm.synced_folder "./data", "/home/vagrant/vagrant_data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end
通过执行以下操作,创建并启动虚拟机。
$ vagrant up
您可以使用以下命令连接到启动的虚拟机:
$ vagrant ssh
如果能够连接到服务器,我们可以将每个Node服务器的hostname更改为node1、node2和node3,以便更易于理解。
$ sudo hostnamectl set-hostname ubuntu-node1 // node1の場合
$ hostname
ubuntu-node1 // 変わったことを確認
请对这三个节点执行以上操作。最终的目录结构应该是下面这个样子。
.
├── node1
│ ├── data
│ ├── Vagrantfile
│ └── ubuntu-bionic-18.04-cloudimg-console.log
├── node2
│ ├── data
│ ├── Vagrantfile
│ └── ubuntu-bionic-18.04-cloudimg-console.log
└── node3
├── data
├── Vagrantfile
└── ubuntu-bionic-18.04-cloudimg-console.log
安装Docker和Docker Compose。
为了使每个节点运行Swarm,需要在每个节点上安装Docker和docker-compose。
尽管不安装docker-compose也可以使用,但在Docker的swarm模式中,可以使用docker-compose的yaml语法来定义容器组并一起部署,所以有它会更加方便。
安装Docker
在大多数情况下,按照官方网站的指示进行安装是最保险的方法。为您做个备忘,下面列出了截至目前(2019/07)的安装步骤。
- インストールされている古いDockerの削除
$ sudo apt-get remove docker docker-engine docker.io containerd runc
- Dockerのインストール
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
最終步骤是将当前用户(vagrant)加入docker组,以便无需使用sudo命令即可执行docker命令。
# dockerグループがなければ作る
$ sudo groupadd docker
# 現行ユーザをdockerグループに所属させる
$ sudo gpasswd -a $USER docker
# dockerをrestert
$ sudo service docker restart
# 一度ログアウトして入り直す
$ exit
$ vagrant ssh
# dockerコマンドが実行できることを確認
$ docker ps -a
安装Docker Compose
最好还是按照官方网站的指示去做。
我会简单地记录下截至现在(2019/07)的安装方法。
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
我将在三个节点上执行上述操作。
Docker Swarm的初始设置和集群构建
首先,我们需要将Node1作为ManagerNode注册到swarm中。
请使用ssh登录到Node1,并执行以下命令。
$ docker swarm init --advertise-addr="192.168.33.10" --listen-addr=0.0.0.0:2377
Swarm initialized: current node (ql8aefbw7rg8nfmznejnzfeus) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-66qe5cyf31fd8rktwvjbrtpd63l32789aqpbfheauwgfh38g8wrf2ey-bob77wfdnrkpcmqtxfgkiu47a 192.168.33.10:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
– 在advertise-addr中填写你自己的IP地址。在listen-addr中指定用于集群间通信的端口号。由于在该端口上进行集群间通信,所以需要在虚拟机上预先打开每个集群的这个端口。
通过这样做,将创建一个Swarm集群。以后,您可以通过使其他节点加入到上述创建的集群中来不断扩大集群规模。
要查看参与集群的节点列表,执行以下操作。
目前只有自己一个。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ql8aefbw7rg8nfmznejnzfeus * ubuntu-node1 Ready Active Leader 18.09.7
我们立即将Node2和Node3作为工作节点加入。
可以使用在swarm init时生成的令牌来加入集群。
$ docker swarm join --token SWMTKN-1-66qe5cyf31fd8rktwvjbrtpd63l32789aqpbfheauwgfh38g8wrf2ey-bob77wfdnrkpcmqtxfgkiu47a 192.168.33.10:2377
如果你忘记了 token,可以使用以下命令来查看。
$ docker swarm join-token -q worker
再次运行docker node ls命令,您将看到集群中参与的节点数量增加了。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ql8aefbw7rg8nfmznejnzfeus * ubuntu-node1 Ready Active Leader 18.09.7
uusz619ly0y6zp3zsdh0br31y ubuntu-node2 Ready Active 18.09.7
pgouhk6cndlxddjhll1vo1rfv ubuntu-node3 Ready Active 18.09.7
使用一个管理节点和两个工作节点,共计三个虚拟机可以组成一个集群。
(補充)关于管理节点(manager node)和工作节点(worker node)
在Swarm中,我们称Docker Engine实例组成的集群为节点。
迄今为止,我们一直使用类似于”node = LinuxVM”的表达方式,但准确来说是在Linux上运行的Docker引擎来构建集群。
这个集群由两种节点组成,分别是管理节点和工作节点,它们各自承担以下的职责。
-
- maneger nodeは一つのリーダー(leader node)を選出し、コンテナのオーケストレーションや管理指示をworker nodeに送信する。デフォルトではmanager nodeもworker nodeとして動作する
- worker nodeはmanager nodeからの指示を受け取り、コンテナをデプロイしたり削除したりする。
请阅读以下以获取更详细的信息。
Swarm 模式的重要概念 – 节点
使用Portainer进行构建
虽然建立Swarm不需要,但是有一个名为Portainer的工具可以从GUI上监控容器状态,因此我们在每个节点上安装它。创建一个名为portainer的目录,并创建以下docker-compose.yml文件。
.
├── node1
│ ├── Vagrantfile
│ └── data
│ └── portainer
│ └── docker-compose.yml // 追加
├── node2
│ ├── Vagrantfile
│ └── data
│ └── portainer
│ └── docker-compose.yml // 追加
└── node3
├── Vagrantfile
└── data
└── portainer
└── docker-compose.yml // 追加
version: '3'
services:
portainer:
container_name: my-portainer
hostname: my_portainer
image: portainer/portainer
ports:
- "9000:9000"
command: -H unix:///var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- data:/data
restart: always
volumes:
data:
让我们最后执行以下命令,启动Portainer容器。
$ cd ./<Portainerのdocker-composeファイルをおいたディレクトリ>
$ docker-compose up -d
访问以下URL,您可以登录到Portainer。
http://<节点IP地址>:9000
容器的部署
好的,现在让我们在刚刚创建的集群上部署容器。使用docker service命令可以进行容器部署,但是如果要部署复杂配置的容器,命令会变得很长且难以使用。
由于Swarm可以使用docker-compose的yaml格式定义文件来部署容器,所以建议使用它进行部署。
首先,在Node1下准备一个如下的docker-compose.yml文件。
version: '3.7'
services:
nginx:
image: nginx
ports:
- target: 80
published: 8080
protocol: tcp
mode: ingress
.
├── node1
│ ├── Vagrantfile
│ └── data
│ ├── nginx
│ │ └── docker-compose.yml // 追加
│ └── portainer
│ └── docker-compose.yml
├── node2
│ ├── Vagrantfile
│ └── data
│ └── portainer
│ └── docker-compose.yml
└── node3
├── Vagrantfile
└── data
└── portainer
└── docker-compose.yml
对于熟悉使用Docker Compose的人来说,这是一个熟悉的文件格式。
为了简单起见,我们将使用一个空的nginx容器进行操作确认。
让我们在Node1上执行以下命令。
$ cd <docker-compose.ymlを用意した場所>
$ docker stack deploy nginx --compose-file ./docker-compose.yml
请访问以下链接以确认容器已启动。如果显示了nginx的默认界面,则表示成功。
根据上述步骤创建NodeServer后的网址应为 http://192.168.33.10:8080。
现在通过ingress模式将容器的端口公开了。在这种情况下,即使不是容器所在的主机(本次是Node1),也可以从其他节点访问该容器。
您也可以尝试连接到以下的URL,并确认页面是否能够显示出来。
http://<Node2的IP>:8080
http://<Node3的IP>:8080

可以使用Portainer查看在Swarm集群上如何部署容器。
请在侧边栏中选择“swarm”,然后单击“前往集群可视化器”的链接试试看。

因为现在只部署了一个容器,所以感觉如下。

顺便说一句,为了简单起见,我们这次只定义了一种服务。但是在Swarm中,只要不是非常特殊的语法,它支持docker-compose.yml中可用的所有语法。因此,如果定义多个服务,当然也可以将多个容器协同部署。
能够直接使用现有的docker-compose.yml文件真是太好了。
扩大规模
目前只有一个容器正在运行,但实际服务中,根据使用情况可能会希望扩容容器。
你可以通过输入以下命令来轻松进行扩展以实现该功能。
首先,找到想要扩展规模的服务(使用docker-compose定义的服务)的名称。
$ docker stack ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
p1syqxgwanpy nginx_nginx.1 nginx:latest ubuntu-node1 Running Running 27 minutes ago
使用docker-compose部署容器时,每个服务的名称将根据compose文件所在的目录名_compose和定义的服务名称确定。在本例中,我们在nginx目录下创建了docker-compose.yml文件,所以服务名称为nginx_nginx。(为什么要选择这个名称呢?)
在上述命令中,“.1”位于末尾,这是用来区分当服务进行扩展并创建多个相同容器时使用的。因此,实际服务名称应为nginx_nginx。
为了将该服务扩展,需要在Node1上执行以下的service scale命令。
$ docker service scale nginx_nginx=5 // コンテナの数を5個にスケールアウトする
nginx_nginx scaled to 5
overall progress: 5 out of 5 tasks
1/5: running
2/5: running
3/5: running
4/5: running
5/5: running
verify: Service converged
在Portainer上查看,可以发现容器的数量增加到了5个。

使用Compose文件进行横向扩展
尽管可以使用上述方法进行横向扩展,但也可以事先在compose文件中定义要创建的容器数量。让我们将docker-compose.yml按照以下方式进行修改。
version: '3.7'
services:
nginx:
image: nginx
ports:
- target: 80
published: 8080
protocol: tcp
mode: ingress
deploy:
mode: replicated
replicas: 3 ## コンテナを3つ作成する
在修改了docker-compose后,再次执行stack deploy命令可以自动检测docker-compose.yml文件的差异,并重新部署容器到该状态。
这个声明听起来不错。
$ cd <docker-compose.ymlを用意した場所>
$ docker stack deploy nginx --compose-file ./docker-compose.yml

恢复
好了,现在我们可以创建多个相同的容器并进行负载均衡了。
那么,在这种情况下,如果关闭容器或节点会发生什么呢?
我想试试看。
删除容器
まず削除対象のコンテナを探します
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e504778aab7 nginx:latest "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp nginx_nginx.1.p1syqxgwanpys3c64kx9dlwsl
让我们尝试删除此次的 node1 容器。
$ docker rm 7e504778aab7
すると、以下のように削除したはずのコンテナが復活します。

実はDocker swarmはdocker-compose.ymlのreplicasで指定した数のコンテナが起動するように常に維持しようとします。なので、もしもコンテナが止まったり、削除されたりした場合は、新しいコンテナを作成してこれを補おうとします。上では一度コンテナの作成に失敗しているようですが、最終的には起動しているコンテナが3つになるように常に調整してくれます。
减少工作节点数
现在让我们减少工作节点,看看它的行为。在这种情况下,关闭Node3的虚拟机电源。
$ sudo init 0 // Node3の電源を落とす
すると以下のような状態になります。Node3がdown状態になって、Node1にもう一つコンテナが立ち上がっているのがわかります。
このようにNodeがダウンすると、Swarmはそこにデプロイされていたコンテナを別のNodeで起動して数を調整します。賢いですね

如果在这个状态下重新启动Node3,将会得到以下的状态。

あれ、Node3にデプロイされていたコンテナがshatdownされちゃいましたね。なんだかNode1にデプロイ先が偏っていて微妙な感じです。うーん。。。
SwarmがNodeの再接続を検知しても、現在のコンテナの状態が正しい場合は、既存のコンテナを移動してrebalanceするようなことはしてくれないみたいですね。
如果想要重新定位偏移的容器,请执行以下命令。
$ docker service update --force nginx_nginx
但是这个命令的作用是按顺序销毁现有的容器,并全部替换为新的容器。主要用于后续介绍的滚动更新等情况。因此会导致大量的停止的容器产生。

关闭管理节点
ではworker nodeではなくmanager nodeを落とすとどうなってしまうのでしょう?
Swarmでは現在リーダーとなっているノード(manager nodeの中から一つ選ばれる)が落ちると、残りのmanager nodeの中から一つを選出し、そのnodeがleader node(Swarmをコントロールするノード)になります。
由于当前是一个由Manager节点1和Worker节点2组成的环境,首先需要增加Manager节点的数量。
在这种情况下,至少需要3个Manager节点才能选出新的Leader。所以首先将新建的Node2和Node3都提升为Manager节点。
昇格させる場合は、Node1で以下を実行します。
$ docker node promote ubuntu-node2 // node2をManagerに昇格
$ docker node promote ubuntu-node3 // node3をManagerに昇格
当执行docker node ls命令时,可以看到MANAGER STATUS变为Reachable,你能理解吗?
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ql8aefbw7rg8nfmznejnzfeus * ubuntu-node1 Ready Active Leader 18.09.7
uusz619ly0y6zp3zsdh0br31y ubuntu-node2 Ready Active Reachable 18.09.7
pgouhk6cndlxddjhll1vo1rfv ubuntu-node3 Ready Active Reachable 18.09.7
我将尝试关闭Node1处于这种状态下。
当在Node2上运行docker node ls时,我们可以看到Node3已经被提升为Leader。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ql8aefbw7rg8nfmznejnzfeus ubuntu-node1 Unknown Active Unreachable 18.09.7
uusz619ly0y6zp3zsdh0br31y * ubuntu-node2 Ready Active Reachable 18.09.7
pgouhk6cndlxddjhll1vo1rfv ubuntu-node3 Ready Active Leader 18.09.7
观察Node3的Portainer,你会看到如下情况:
可以看出,Node3成功地启动了适当数量的容器并且保持了容器的数量,作为已宕机的Node1的替代。

(補充) 关于Leader节点的选择逻辑
在Swarm中,如果管理Swarm的领导节点宕机了,则会根据一个叫做Raft的逻辑选择新的领导节点。
この場合、ロスト可能なNodeの最大数は、manager nodeの数をNとして(N-1)/2で計算されます。
3台の場合は(3-1)/2 = 1なので1台までなら落ちても大丈夫です。
ただし多ければ良いというものでもないみたいで、主にパフォーマンス上の理由から、Docker swarmではmanager nodeの数は最大でも7台までに抑えることが推奨されています。
詳しくは以下を参照して見てください
https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/
・A three-manager swarm tolerates a maximum loss of one manager.
・A five-manager swarm tolerates a maximum simultaneous loss of two manager nodes.
・An N manager cluster tolerates the loss of at most (N-1)/2 managers.
・Docker recommends a maximum of seven manager nodes for a swarm.
滚动更新
さて、個人的にSwarmの目玉機能だと思っているローリングアップデートを紹介したいと思います。今まで見てきたように、Swarmでは同じイメージのコンテナを複数立ててロードバランシングすることができます。
そして複数コンテナを立てている環境では、デプロイされているコンテナを順番に更新していくことで、無停止デプロイを実現することができます。俗に言うローリングアップデートと言うやつですね。
我们立即试一试,将docker-compose.yml按以下方式进行修改。
version: '3.7'
services:
nginx:
image: httpd ## => イメージをnginxからApacheに変更
ports:
- target: 80
published: 8080
protocol: tcp
mode: ingress
deploy:
mode: replicated
replicas: 3
そして再びdocker stack deploy を実行しましょう。これだけでローリングアップデートによって、3つのコンテナが順番にApache serverに差し替わります。
$ cd <docker-compose.ymlを用意した場所>
$ docker stack deploy nginx --compose-file ./docker-compose.yml
実行した後、今までnginxが動いていたURLを更新してみてください。どこかのタイミングでnginxがhttpdに差し替わっているのが確認できると思います。
http://<节点的IP>:8080
Apache HTTP服务器的初始界面。

顺便提一下,docker stack deploy在运行时会检测docker-compose.yml的差异,并且只更新有差异的service,因此实际执行的是docker service update。
回滚
我已经顺利将nginx从上面更新到httpd。
しかし世は大nginx時代、皆さんの中にはこのアップデートを快く思わない人もいるでしょう。今すぐ、Apacheを窓から投げ捨て、サーバーのアップデートをなかったコトにして、もとのnginxに戻したくなるかもしれません
即使在这种情况下,选择Swarm也是安心的。Swarm已经实现了以服务为单位的回滚功能。
请尝试执行以下命令。
在中文中进行本地化改写只需要一种选项:
可以把更新被视为未发生,并且再次能够看到nginx的初始界面。
$ docker service rollback nginx_nginx

移除堆栈
让我们尝试执行以下操作,将最近部署的整个堆栈删除。
$ docker stack rm nginx
Removing service nginx_nginx
Removing network nginx_default
デプロイされたコンテナがすべて削除され、docker-stack deploy を行う前の状態に戻った事がわかるかと思います。Swarmの場合は、このように、デプロイしているサービス群を、docker-compose.ymlで定義された単位でまるごと削除することができます。docker-composeで言うところの、$ docker-compose down と同じようなものだと思えばよいかと思います。
这种便利的管理方式也是Docker Swarm的吸引力所在。
抛开题外话
我想限制创建的容器数量。
ローリングアップデートを繰り返していると、過去のイメージで作られた停止済みコンテナが大量にできてしまいます。
それが嫌な場合は、swarmのoptionでこれを制限することができます。
$ docker swarm update --task-history-limit 5 // 一つのServiceについてコンテナを5世代前まで残す
请注意,这个设置只会在下一次的docker service update时生效。换句话说,仅启用这个设置并不会删除旧的容器。
如果您想删除旧的容器,请尝试执行以下命令。您将会发现已经删除了现有的旧容器,只剩下当前的容器了。
$ docker swarm update --task-history-limit 0 // コンテナ履歴を残さない
$ docker service update --force nginx_nginx
尽管有大量停止的容器存在,并不意味着大量的存储被消耗了。
请运行以下命令,并查看已停止容器的存储容量。
$ docker ps -a -s
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
3bb6e4eac2a7 nginx:latest "nginx -g 'daemon of…" 42 seconds ago Up 35 seconds 80/tcp nginx_nginx.2.nd8v1m97djhykqhe1jd7xoopb 2B (virtual 109MB)
cf9d34de148f nginx:latest "nginx -g 'daemon of…" About a minute ago Exited (0) 38 seconds ago nginx_nginx.2.z7h14vx534milfsml9zddyvu7 0B (virtual 109MB)
1369522e3aca portainer/portainer "/portainer -H unix:…" 30 hours ago Up About a minute 0.0.0.0:9000->9000/tcp my-portainer 0B (virtual 75.4MB)
你能看出来文件大小是0B(虚拟109MB)吗?
实际上,Docker容器的存储机制是仅保持与原始容器镜像的差异。因此,无论有多少个相同镜像的容器被创建,所使用的容量都是0B。
在运行Docker时,应该关注容器镜像。特别是当我们的应用容器镜像通过增强功能不断增加时,每次部署新的镜像都有可能占用越来越多的存储空间。
在这种情况下,最好定期删除存储中的旧镜像等等。
整理
Docker Swarm模式的实践到此结束。
除了这里介绍的功能外,Swarm还配备了许多其他功能,所以如果您感兴趣,请自行了解。
順便提一下在这里没有介绍的是,Docker的Swarm模式可以在单个节点上运行。
在这种情况下,只需要输入”docker swarm init”命令即可,这样您就可以在单个服务器上利用滚动更新和回滚等吸引人的功能。
虽然不需要组建集群,但是我想要进行滚动更新的时候,这种方式非常简便和方便呢~ 在单节点Docker Swarm中进行这种方便的滚动更新真是很有参考价值。
这些好处在Kubernetes中是否也不存在呢?
以上
提供的链接可供参考。
-
- docker swarm – 公式リファレンス
-
- docker stack – 公式リファレンス
-
- docker node – 公式リファレンス
- docker compose deploy – 公式リファレンス