部署搭建Docker原生容器编排工具(Docker Swarm)及Volume NFS共享存储模式

目录

一、容器编排技术介绍

二、Docker 容器编排概述

三、容器编排工具简介

四、Docker 容器编排工具的部署与使用

1、规划节点

2、基础准备

3、部署swarm集群

(1)配置主机映射

(2)配置时间同步

(3)配置Docker API

(4)初始化集群

(5)Node 节点加入集群

(6)验证swarm集群

(7)安装Portainer

1、登录Master节点,安装Portainer

2、配置镜像加速

3、拉取镜像

(8)登录Portainer

(9)运行Service


一、容器编排技术介绍

Docker 容器编排技术是一种用于管理和编排容器化应用程序的技术。它允许用户通过定义和配置容器组、服务和网络来自动化和管理多个 Docker 容器的生命周期。

以下是一些常见的 Docker 容器编排技术:

  1. Docker Compose:它是 Docker 官方提供的一个工具,用于定义和管理多个容器的应用程序。使用 Docker Compose,可以通过配置一个 YAML 文件来定义应用程序的容器、服务和网络,并通过一个简单的命令来管理整个应用程序的生命周期。

  2. Kubernetes:它是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。Kubernetes 提供了丰富的功能,如服务发现、负载均衡、自动伸缩、容器健康检查等,可以帮助用户轻松管理大规模的容器化应用程序。

  3. Mesos:它是一个分布式系统内核,用于管理和编排计算资源。Mesos 可以与 Docker 集成,提供了一个高可用的集群管理平台,可以用于部署和管理容器化应用程序。

  4. Swarm:它是 Docker 官方提供的一个原生容器编排工具,用于在多个 Docker 主机上进行容器的部署和管理。Swarm 提供了高可用性、安全性和可扩展性,并可以与其他 Docker 生态系统工具进行集成。

  5. Rancher:它是一个开源的容器管理平台,提供了一个易于使用的界面来管理和编排 Docker 容器。Rancher 支持多个容器编排技术,如 Kubernetes、Swarm 和 Mesos,并提供了许多高级功能,如监控、日志、负载均衡等。

这些容器编排技术都可以帮助用户更轻松地管理和编排容器化应用程序,提高应用程序的可伸缩性、可靠性和性能。用户可以根据自己的需求选择适合的技术来管理和编排他们的容器化应用程序。

 

二、Docker 容器编排概述

Docker让容器变成了主流。自项目发布以来,Docker 着重于提升开发者的体验,其基本理念是可以在整个行业中,在一个标准的框架上,构建、交付并且运行应用。理论上,一个机构能够从一个便携式计算机 上构建出一个持续集成和持续开发的流程,然后将其应用到生产环境。起初的一个挑战是数据中心编排。与VMware Sphere不同,当时少有能在生产环境中大规模管理负载的工具,运行一个容器就像一个单独的乐器,单独播放它的交响乐乐谱。容器编排允许指挥家通过管理和塑造整个乐团的声音来统一管弦乐队。

容器编排就是指对多个容器进行单独组件和应用层工作进行组织的流程。容器编排工具提供了有用且功能强大的解决方案,用于跨多个主机协调创建、管理和更新多个容器。最重要的是,业务流程允许异步地在服务和流程任务之间共享数据。在生产环境中,可以在多个服务器上运行每个服务的多个实例,以使应用程序具有高可用性。简化编排,可以深人了解应用程序并分解更小的微服务。可以利用容器编排工具更好地对容器进行管理。

 

三、容器编排工具简介

目前,主流的容器编排工具有Swarm、Kubemnetes 和Amazon ECS,其他的还有docker compose和Mesos等。

Swarm 是Docker自己的编排工具,现在与Docker Engine完全集成,并使用标准API和网络。Docker Swarm是Decker用来在数据中心级别进行容器编排的主要方式。Swarm 模式内置于Docker CLI中,无须额外安装,并且易于获取新的Swarm命令。部署服务可以你使用docker service create命令一样简单。 Docker Swarm正在与Kubernetes竞争,通过在性能、灵活性和简单性方面取得进步来获得用户的认可。

Kubernetes正在成为容器编排领域的领导者,由于其可配置性、可靠性和大型社区的支持,从而超越了Docker Swarm。Kubernetes 由谷歌公司创建,作为一个开源项目, 与整个谷歌云平台协调工作。此外,它几乎适用于任何基础设施。

Amazon ECS是亚马逊专有的容器调度程序,旨在与其他AWS服务协调工作。这意味着以AWS为中心的解决方案( 如监控、负载均衡和存储)可轻松集成到用户的服务中。如果用户正在使用亚马逊之外的云提供商,或者在本地运行工作负载,那么ECS可能不合适。

这里我们需要搭建的是Docker Swarm。

 

四、Docker 容器编排工具的部署与使用

1、规划节点

2、基础准备

所有节点配置好主机名和网卡,并安装好docker-ce

[root@localhost ~]# hostnamectl set-hostname master
[root@localhost ~]# hostnamectl
   Static hostname: master
   
[root@master ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=eth0
UUID=d8e921ba-2d3a-46c8-9651-c95abf136b02
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.100.22
NETMASK=255.255.255.0
GATEWAY=192.168.100.2
DNS1=192.168.100.2

       
[root@localhost ~]# hostnamectl set-hostname node
[root@localhost ~]# hostnamectl
   Static hostname: node

[root@node ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=eth0
UUID=1e90196e-9079-4770-a5de-df8b7839a089
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.100.23
NETMASK=255.255.255.0
GATEWAY=192.168.100.2
DNS1=192.168.100.2


两台主机关闭防火墙、关闭SElinux
systemctl stop firewalld && systemctl disable firewalld

sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

 

两个节点安装docker-ce

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# Step 4: 更新并安装Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo service docker start
systemctl enable docker

# 注意:
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,您可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将[docker-ce-test]下方的enabled=0修改为enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showdup licates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]

 

3、部署swarm集群

(1)配置主机映射

所有节点修改/etc/hosts文件配置主机映射

cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.22 master
192.168.100.23 node

(2)配置时间同步

所有节点安装chrony服务

yum install -y chrony

Master节点修改/etc/chrory.conf文件,注释默认NTP服务器,指定上游公共NTP股务器,并允许其他节点同步时间

[root@master ~]# sed -i 's/server/#&/' /etc/chrony.conf

[root@master ~]# cat >> /etc/chrony.conf  << EOF
> local stratum 10
> server master iburst
> allow all
> EOF

Master节点重启chronyd服务并设为开机启动,开启网络时间同步功能

[root@master ~]# systemctl restart chronyd && systemctl enable chronyd
[root@master ~]# timedatectl set-ntp true

Node节点修改/etc/chrony. conf文件,指定内网Master 节点为上游NTP服务器,重启服务并设为开机启动

[root@node ~]# sed -i 's/server/#&/' /etc/chrony.conf
[root@node ~]# echo server 192.168.100.22 iburst >> /etc/chrony.conf
[root@node ~]# systemctl restart chronyd && systemctl enable chronyd

所有节点执行chrony sources命令,查询结果中如果存在以“*”开头的行,即说明已经同步成功

[root@master ~]# chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* master                       10  10   377  168m   +378ns[  -19us] +/-   27us


[root@node ~]# chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* master                       11  10   377   318    +45us[  +79us] +/-   22ms

 

(3)配置Docker API

所有节点开启Docker API

将“ExecStart=”对应的行修改成下面的
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

当在所有节点上启用 Docker API 时,意味着您可以通过远程访问的方式来管理和控制每个节点上的 Docker 守护进程。

Docker API 是 Docker 提供的一组 RESTful 接口,允许用户与 Docker 守护进程进行通信,执行各种操作,如创建、启动、停止和删除容器,构建和管理镜像,管理网络和存储等。

在默认情况下,Docker API 只允许本地访问,只有在宿主机上通过本地的 Unix 套接字或 TCP 端口进行访问。然而,当在所有节点上启用 Docker API 时,意味着您允许从网络上的其他计算机上进行远程访问。

启用 Docker API 的主要用途是允许用户通过命令行工具、脚本或其他远程的管理工具来管理并操作 Docker 守护进程。这样,您就可以在网络中的任何一个节点上远程管理整个集群的 Docker 容器和服务,从而简化了集群管理和容器编排的操作。

然而,需要注意的是在启用 Docker API 时需要确保安全性,因为任何可以访问 Docker API 的人都可以对 Docker 守护进程进行操作。建议在启用 Docker API 时使用身份验证和授权机制,以确保只有经过授权的用户可以访问和操作 Docker 守护进程。

 

(4)初始化集群

在master节点创建swarm集群

[root@master ~]# vi /lib/systemd/system/docker.service
[root@master ~]# docker swarm init --advertise-addr 192.168.100.22
Swarm initialized: current node (7gimaxvm6k86a9orwh3swfaz8) is now a manager.

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

    docker swarm join --token SWMTKN-1-5flws89ta4pj5veyowesmg5u09gyc42t21lngjsz1w9uadvgna-11kg0kqajj1mptmp3leqj17tt 192.168.100.22:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

初始化命令中“--advertise-addr" 选项表示管理节点公布它的IP是多少。其他节点必须能通过这个IP找到管理节点。

输出结果中包含3个步骤

1、Swarm创建成功,swarm-manager成为manager node

2、添加worker node需要执行的命令

3、添加manager node需要执行的命令

 

(5)Node 节点加入集群

复制前面的docker swarm join命令,在Node节点执行以加入Swarm集群

[root@node ~]# docker swarm join --token SWMTKN-1-5flws89ta4pj5veyowesmg5u09gyc42t21lngjsz1w9uadvgna-11kg0kqajj1mptmp3leqj17tt 192.168.100.22:2377
This node joined a swarm as a worker.

如果没有初始化时没有记录下docker swarm init 提示的添加Worker的完整命令。可以通过docker swarm join-token worker命令查看

[root@master ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-5flws89ta4pj5veyowesmg5u09gyc42t21lngjsz1w9uadvgna-11kg0kqajj1mptmp3leqj17tt 192.168.100.22:2377

 

(6)验证swarm集群

登录Maler节点,查看各节点状态,命令如下:

[root@master ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
7gimaxvm6k86a9orwh3swfaz8 *   master     Ready     Active         Leader           24.0.7
030it82939yphbhwsu8cwh10l     node       Ready     Active                          24.0.7

 

(7)安装Portainer

Portainer 是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传和下载镜像、创建容器等操作)、事件日志显示,容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型企业对容器管理的全部需求。

1、登录Master节点,安装Portainer
[root@master ~]# docker volume create portainer_data
portainer_data

`docker volume create` 是用于创建 Docker 卷(Volume)的命令。Docker 卷是一种用于持久化存储容器数据的机制,可以在容器之间共享和重用数据。

使用 `docker volume create` 命令,可以在主机上创建一个新的 Docker 卷。该命令的基本语法如下:


docker volume create [OPTIONS] [VOLUME]
 

其中,常用的选项包括:

- `-d, --driver`:指定所创建卷的驱动程序,默认为 "local"。
- `-o, --opt`:用于传递额外的选项给卷驱动程序。
- `--label`:为卷添加标签,可以使用多个 `--label` 参数。

示例:


docker volume create portainer_data
 

上述命令将在主机上创建一个名为 "portainer_data" 的 Docker 卷。创建成功后,可以使用 `docker volume ls` 命令查看已创建的卷列表。


$ docker volume ls
DRIVER    VOLUME NAME
local             portainer_data
 

创建的卷可以在容器中被挂载使用。例如,可以使用 `docker run` 命令将卷挂载到容器的指定路径上:


docker run -v portainer_data:/path/in/container ...

这将将卷 "portainer_data" 挂载到容器内的 "/path/in/container" 路径上。

Docker 卷提供了一种方便且可移植的方法来管理和共享容器数据,无论是在单个主机上的容器间共享,还是在多主机或集群中的容器间共享。`docker volume create` 命令可以帮助我们创建和管理这些卷。

2、配置镜像加速

在此之前先配置一个镜像加速

编辑或新建配置文件 /etc/docker/daemon.json

sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"],
    "live-restore": true
}
EOF


重新启动docker服务
sudo systemctl daemon-reload
sudo systemctl restart docker
3、拉取镜像

在拉取镜像中遇到这样的一个错误 该错误通常表示 Docker 无法连接到 Docker Hub 注册表。所以我怀疑是由于网络问题或 DNS 解析问题引起的。

在拉取镜像中遇到这样的一个错误
该错误通常表示 Docker 无法连接到 Docker Hub 注册表。所以我怀疑是由于网络问题或 DNS 解析问题引起的。
[root@master ~]# docker pull portainer/portainer
Using default tag: latest
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on 192.168.100.2:53: read udp 192.168.100.22:46695->192.168.100.2:53: i/o timeout


查看网络配置信息,检查自己的 DNS 设置后,我尝试使用其他 DNS 服务器,例如 Google DNS(8.8.8.8)或 Cloudflare DNS(1.1.1.1)

cat >> /etc/sysconfig/network-scripts/ifcfg-eth0 <<EOF
DNS2=8.8.8.8
EOF

systemctl restart network
如果还没有解决就重启一下docker(要注意的是在关闭SElinux后需要重启一下主机)

再次拉取
[root@master ~]# docker pull portainer/portainer
Using default tag: latest
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
docker.io/portainer/portainer:latest

果然是我在配置网络是疏忽了配置DNS!

Docker Service命令用于管理Docker Swarm集群中的服务。以下是一些常用的Docker Service命令及其解释:

  1. docker service create:创建一个新的服务。你可以指定要运行的镜像、服务名称、副本数等。
  2. docker service ls:列出当前集群中的所有服务。
  3. docker service inspect:显示指定服务的详细信息,包括服务名称、副本数、镜像、端口映射等。
  4. docker service update:更新一个已存在的服务。你可以修改副本数、镜像、环境变量等。
  5. docker service scale:调整一个服务的副本数。你可以增加或减少服务的副本数量。
  6. docker service rm:删除一个服务。此命令会停止该服务的所有容器,并且从集群中移除该服务。
  7. docker service logs:查看一个服务的日志。你可以实时查看服务容器的日志输出。
  8. docker service ps:列出指定服务的任务(即容器)列表。你可以查看每个任务的状态、节点分配等信息。
  9. docker service inspect:获取服务的详细信息,包括任务的状态、配置、环境变量等。

这些命令可以帮助你管理和监控Docker Swarm集群中的服务。你可以使用这些命令创建、更新、删除服务,以及查看服务的详细信息和日志。

 

[root@master ~]# docker service create --name portainer --publish 9000:9000 --replicas=1 --constraint 'node.role == manager' --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock --mount type=volume,src=portainer_data,dst=/data portainer/portainer -H unix:///var/run/docker.sock
3un6dh1ldi3wpc4j5b7a5bs5e
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

[root@master ~]# docker ps -a
CONTAINER ID   IMAGE                        COMMAND                  CREATED              STATUS                          PORTS      NAMES
4c0ea06f9f8d   portainer/portainer:latest   "/portainer -H unix:…"   About a minute ago   Up About a minute               9000/tcp   portainer.1.sm29d8dq1ye58k3ojm1air602
[root@master ~]# docker service ls
ID             NAME        MODE         REPLICAS   IMAGE                        PORTS
3un6dh1ldi3w   portainer   replicated   1/1        portainer/portainer:latest   *:9000->9000/tcp
[root@master ~]# docker service ps portainer
ID             NAME              IMAGE                        NODE      DESIRED STATE   CURRENT STATE           ERROR                       PORTS
sm29d8dq1ye5   portainer.1       portainer/portainer:latest   master    Running         Running 4 minutes ago

[root@master ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp6       0      0 :::9000                 :::*                    LISTEN      1035/dockerd
docker  service create

`docker service create` 是用于在 Docker Swarm 集群中创建一个服务的命令。服务是运行在 Swarm 集群中的可扩展的分布式应用程序。

下面是对 `docker service create` 命令参数的解释:

- `--name`:为服务指定一个名称,这里是 "portainer"。
- `--publish`:将服务的端口映射到主机的端口,这里将容器的 9000 端口映射到主机的 9000 端口。
- `--replicas`:指定服务的副本数量,这里是 1。
- `--constraint`:设置服务的约束条件,这里通过 'node.role == manager' 指定服务只能运行在 Swarm 集群的管理节点上。
- `--mount`:指定挂载到服务中的卷或目录,这里使用了两个挂载选项:
  - `type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock`:将主机上的 Docker.sock 文件挂载到服务中,这样服务可以与主机上的 Docker 守护进程进行交互。
  - `type=volume,src=portainer_data,dst=/data`:将名为 "portainer_data" 的卷挂载到服务中的 "/data" 目录,用于持久化存储 Portainer 数据。
- `portainer/portainer -H unix:///var/run/docker.sock`:指定要运行的服务镜像及其启动命令。

上述命令将在 Swarm 集群的管理节点上创建一个名为 "portainer" 的服务。这个服务将暴露 9000 端口,将容器的 "/var/run/docker.sock" 文件挂载到服务中,以便访问主机上的 Docker 守护进程,并将 "portainer_data" 卷挂载到服务中的 "/data" 目录,用于持久化存储数据。服务的副本数量为 1,意味着只有一个实例运行。

这个服务可以用于在 Swarm 集群中部署和管理容器,提供了一个用户界面来管理 Docker 容器和相关资源。

 

(8)登录Portainer

打开浏览器,输人地址http://master_IP:9000访问Portainer主页(在访问之前务必保证portainer后台运行,如遇到访问失败则重启两台主机)

首次登录时需设置用户名和密码,进行用户创建,然后输入设置的用户名和密码进行登录,进入Swarm控制台

 

(9)运行Service

  • 部署Service

现在已经创建好了Swarm 集群,执行如下命令部署一个运行httpd镜像的Service

[root@master ~]# docker service create --name web_server httpd
rk2ea1k2pb5ukeormiqhyq2eh
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged

部署Service的命令形式与运行容器的docker run 很相似,--name 为Service命名为web_server,httpd为镜像的名字。

通过docker service Is命令可以在看当前Swarm中的Service

[root@master ~]# docker service ls
ID             NAME         MODE         REPLICAS   IMAGE                        PORTS
3un6dh1ldi3w   portainer    replicated   1/1        portainer/portainer:latest   *:9000->9000/tcp
rk2ea1k2pb5u   web_server   replicated   1/1        httpd:latest

REPLICAS显示当前副本信息,1/ 1意思是web_server这个Service期望的容器副本数量为1,目前已经启动的副本数量为1,即当前Service已经部署完成。使用命令service ps可以查看Service每个副本的状态

[root@master ~]# docker service ps web_server
ID             NAME           IMAGE          NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
o6dm47aftnqa   web_server.1   httpd:latest   node      Running         Running 4 minutes ago    

可以在看到Service唯一的副本被分派到 node,当前的状态是Running

 

  • Service伸缩

刚刚仅部署了只有一个副本的Service,不过对于Web服务,通常会运行多个实例。这样可以负载均衡,同时也能提供高可用。

Swarm 要实现这个目标非常简单,增加Service的副本数就可以了。在Master节点上执行如下命令

[root@master ~]# docker service scale web_server=5
web_server 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

副本数增加到5,通过docker service Is和docker service ps命令查看副本的详细信息

[root@master ~]# docker service ls
ID             NAME         MODE         REPLICAS   IMAGE                        PORTS
3un6dh1ldi3w   portainer    replicated   1/1        portainer/portainer:latest   *:9000->9000/tcp
rk2ea1k2pb5u   web_server   replicated   5/5        httpd:latest

[root@master ~]# docker service ps web_server
ID             NAME           IMAGE          NODE      DESIRED STATE   CURRENT STATE                ERROR     PORTS
o6dm47aftnqa   web_server.1   httpd:latest   node      Running         Running 10 minutes ago        
tgzwqs3r2v63   web_server.2   httpd:latest   node      Running         Running 2 minutes ago         
jq7x23cg0fb1   web_server.3   httpd:latest   master    Running         Running about a minute ago    
q9teohrxyokt   web_server.4   httpd:latest   node      Running         Running 2 minutes ago         
m6idqkohhpjg   web_server.5   httpd:latest   master    Running         Running about a minute ago    

 

5个副本已经分布在Swarm的所有节点上

 

既然可以通过scale up扩容服务,当然也可以通过scale down减少副本数。运行下面的命令

[root@master ~]# docker service scale web_server=2
web_server scaled to 2
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged

[root@master ~]# docker service ps web_server
ID             NAME           IMAGE          NODE      DESIRED STATE   CURRENT STATE            ERROR     PORTS
o6dm47aftnqa   web_server.1   httpd:latest   node      Running         Running 13 minutes ago
jq7x23cg0fb1   web_server.3   httpd:latest   master    Running         Running 4 minutes ago

可以看到web_server.2, web_server.4和web_server.5这3个副本已经被删除了。

 

 

  • 访问Service

要访问HTTP服务,首先得保证网络通畅,其次需要知道服务的IP地址。查看容器的网络配置


[root@master ~]# docker ps
CONTAINER ID   IMAGE                        COMMAND                  CREATED             STATUS             PORTS      NAMES
36087a72904e   httpd:latest                 "httpd-foreground"       8 minutes ago       Up 8 minutes       80/tcp     web_server.3.jq7x23cg0fb1ra80vmiamknok
f52d6afef703   portainer/portainer:latest   "/portainer -H unix:…"   About an hour ago   Up About an hour   9000/tcp   portainer.1.wlvfkx1qj40up7dx4ukpp6gp6

在Master上运行了一个容器,是web_server 的一个副本,容器监听了80端口,但并没有映射到Docker Host,所以只能通过容器的IP地址访问。但是服务并没有暴露给外部网络,只能在Docker主机上访问,外部无法访问。要将服务暴露到外部,让外部进行访问,方法其实很简单,执行下面的命令:

[root@master ~]# docker service update --publish-add 8080:80 web_server
web_server
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged

--publish-add 8080:80将容器的80映射到主机的808端口。这样外部网络就能访问到Service了。通过http://任意节点IP:8080即可访问Service

master节点

 

node节点

 

 

 

  • Service 存储数据

Service的容器副本可能会伸缩,甚至失败,会在不同的主机让创建和销毁,这就引出一个问题,如果Service有需要管理的数据,那么这些数据应该如何存放呢?如果把数据打包在容器里,这显然不行,除非数据不会发生变化,否则,如何在多个副本之间保持同步呢?

volume是将宿主级的目录映射到容器中,以实现数据持久化,我们可以用以下两种方式来实现。

①volume默认模式:工作节点宿主机数据同步到容器内。

②volume NFS共享存储模式:管理节点宿主同步到工作节点宿主,工作节点宿主同步到容器。

生产环境中一般推荐使用volume NFS共享存储模式。

登录Master节点,安装NFS服务端,配置NFS主配置文件,添加权限并启动,命令如下:

[root@master ~]# yum install nfs-utils -y

 

添加目录让相应网段可以访问并添加读写权限

[root@master ~]# vi /etc/exports

[root@master ~]# cat /etc/exports
/root/share 192.168.100.22/24(rw,async,insecure,anonuid=1000,anongid=1000,no_root_squash)

创建共享目录,添加权限,命令如下

[root@master ~]# mkdir -p /root/share
[root@master ~]# chmod 777 /root/share

/root/share为共享目录,生效配置,命令如下:


[root@master ~]# exportfs -rv
exporting 192.168.100.22/24:/root/share

开启RPC服务并设置开机自启,命令如下:

[root@master ~]# systemctl start rpcbind
[root@master ~]# systemctl enable rpcbind

启动NFS服务并设置开机自启,命令如下:

[root@master ~]# systemctl start nfs
[root@master ~]# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.

在看NFS是否挂载成功,命令如下:

[root@master ~]# cat /var/lib/nfs/etab
/root/share     192.168.100.22/24(rw,async,wdelay,hide,nocrossmnt,insecure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=1000,anongid=1000,sec=sys,rw,insecure,no_root_squash,no_all_squash)

登录Node节点,安装NFS客户端井启动服务,命令如下:

[root@node ~]# yum install nfs-utils -y
[root@node ~]# systemctl start rpcbind
[root@node ~]# systemctl enable rpcbind
[root@node ~]# systemctl start nfs
[root@node ~]# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.

部署的服务可能分不到各个节点上,在所有节点创建docker volume,命令如下

[root@master ~]# docker volume create --driver local --opt type=nfs --opt o=addr=192.168.100.22,rw --opt device=:/root/share foo33
foo33



[root@node ~]# docker volume create --driver local --opt type=nfs --opt o=addr=192.168.100.22,rw --opt device=:/root/share foo33
foo33

--opt device=:/root/share用于指向共享目录,也可以是共享目录下的子目录。

查看volume,命令如下:

[root@master ~]# docker volume ls
DRIVER    VOLUME NAME
local     foo33
local     portainer_data

[root@node ~]# docker volume ls
DRIVER    VOLUME NAME
local     foo33

可以在看到docker volume列表中有foo33 的volume详细信息,命令如下

 

[root@master ~]# docker volume inspect foo33
[
    {
        "CreatedAt": "2024-01-24T07:42:00-05:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/foo33/_data",
        "Name": "foo33",
        "Options": {
            "device": ":/root/share",
            "o": "addr=192.168.100.22,rw",
            "type": "nfs"
        },
        "Scope": "local"
    }
]

可以看出NFS的/root/share被挂载到了/var/lib/docker/volumes/foo33/_data目录

创建并发布服务,命令如下:

[root@master ~]# docker service create --name test-nginx-nfs --publish 80:80 --mount type=volume,source=foo33,destination=/app/share --replicas 3 nginx
f2tv70be6237df3eu7lztvhxn
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service converged

 

查看服务分布的节点,命令如下:

[root@master ~]# docker service ps test-nginx-nfs
ID             NAME               IMAGE          NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
4otdns93k4uu   test-nginx-nfs.1   nginx:latest   node      Running         Running 3 minutes ago   
8xxnqfn6n7vq   test-nginx-nfs.2   nginx:latest   node      Running         Running 3 minutes ago   
qbugjzaa921v   test-nginx-nfs.3   nginx:latest   master    Running         Running 3 minutes ago 

 

在Master节点/root/share目录中生成一个 index. html文件,命令如下:

[root@master ~]# cd /root/share
[root@master share]# touch index.html
[root@master share]# ll
total 0
-rw-r--r-- 1 root root 0 Jan 24 07:51 index.html

 

查看宿主机目录挂载情况,命令如下:

[root@master share]# docker volume inspect foo33
[
    {
        "CreatedAt": "2024-01-24T07:42:00-05:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/foo33/_data",
        "Name": "foo33",
        "Options": {
            "device": ":/root/share",
            "o": "addr=192.168.100.22,rw",
            "type": "nfs"
        },
        "Scope": "local"
    }
]

[root@master ~]# ls /var/lib/docker/volumes/foo33/_data/
index.html

 

查看容器目录,命令如下:

[root@master ~]# docker ps
CONTAINER ID   IMAGE                        COMMAND                  CREATED         STATUS         PORTS      NAMES
2a2657b01e8a   nginx:latest                 "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp     test-nginx-nfs.3.qbugjzaa921v8nsdp3px6ijy1
550e35f305f5   httpd:latest                 "httpd-foreground"       5 hours ago     Up 5 hours     80/tcp     web_server.3.jmawiw2ibttqoif6e8shestoq
979c60a321f8   portainer/portainer:latest   "/portainer -H unix:…"   5 hours ago     Up 5 hours     9000/tcp   portainer.1.uqr6u378gyubqtbusahyx4t97

[root@master ~]# docker exec -it 2a26 bash
root@2a2657b01e8a:/# ls app/share
index.html

可以发现,NFS已经挂载成功。

 

 

  • 调度节点

默认配置下Master 也是worker node, 所以Maser上也运行了副本。如果不希望在Master 上运行Service, 可以执行如下命令:

[root@master ~]# docker node update --availability drain master
master

 

通过docker node Is命令查看各节点现在的状态:

[root@master ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
7gimaxvm6k86a9orwh3swfaz8 *   master     Ready     Drain          Leader           24.0.7
030it82939yphbhwsu8cwh10l     node       Ready     Active                          24.0.7

状态为Drain表示Master已经不负责运行Service

 

那之前Master运行的那1个副本会如何处理呢?使用docker service ps命令来查看


[root@master ~]# docker service ps test-nginx-nfs
ID             NAME                   IMAGE          NODE      DESIRED STATE   CURRENT STATE             ERROR     PORTS
4otdns93k4uu   test-nginx-nfs.1       nginx:latest   node      Running         Running 11 minutes ago
8xxnqfn6n7vq   test-nginx-nfs.2       nginx:latest   node      Running         Running 11 minutes ago
oxcpp9q8y5ra   test-nginx-nfs.3       nginx:latest   node      Running         Running 56 seconds ago
qbugjzaa921v    \_ test-nginx-nfs.3   nginx:latest   master    Shutdown        Shutdown 57 seconds ago

Master上的副本test-nginx-nfs.3已经被Shutdown了,为了达到3个副本数的目标,会在Node上添加了新的副本test-nginx-nfs.3

 

如果想master继续工作则继续运行master

[root@master ~]# docker node update --availability active master
master
[root@master ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
7gimaxvm6k86a9orwh3swfaz8 *   master     Ready     Active         Leader           24.0.7
030it82939yphbhwsu8cwh10l     node       Ready     Active                          24.0.7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值