Swarm集群配置

Swarm集群特性:

1)群集管理集成进 Docker Engine:使用内置的群集管理功能,可以直接通过 Docker CLI命令来创建 Swarm 群集, 然后去部署应用服务, 而不再需要其它外部的软件来创建和管理一个 Swarm 群集。

2)去中心化设计:Swarm 群集中包含 Manager 和 Worker 两类 Node,可以直接基于 Docker Engine 来部署任何类型的 Node。 而且在 Swarm 群集运行期间, 既可以对其作出任何改变, 实现对群集的扩容和缩容等, 如添加 Manager Node, 如删除 Worker Node, 而做这些操作不 需要暂停或重启当前的 Swarm 群集服务。

3) 声明式服务模型: 在实现的应用栈中, Docker Engine 使用了一种声明的方式, 可以定义所期望的各种服务的状态, 例如, 创建了一个应用服务栈: 一个 Web 前端服务、 一个后端数据库服务、 Web 前端服务又依赖于一个消息队列服务。

4) 协调预期状态与实际状态的一致性: Swarm 群集 Manager Node 会不断地监控群集的状态, 协调群集状态使得我们预期状态和实际状态保持一致。 例如启动了一个应用服务, 指定服务副本为 10, 则会启动 10 个 Docker 容器去运行。 如果某个 Worker Node 上面运行的 2个 Docker 容器挂掉了, 则 Swarm Manager 会选择群集中其它可用的 Worker Node, 并创建 2个服务副本, 使实际运行的 Docker 容器数仍然保持与预期的 10 个一致。

5) 多主机网络: Swarm Manager 会给群集中每一个服务分配一个唯一的 DNS 名称,对运行中的 Docker 容器进行负载均衡。 可以通过 Swarm 内置的 DNS Server, 查询 Swarm 群集中运行的Docker 容器状态。

6) 负载均衡: 在 Swarm 内部, 可以指定如何在各个 Node 之间分发服务容器( Service Container) , 实现负载均衡。 如果想要使用 Swarm 群集外部的负载均衡器, 可以将服务容器的端口暴露到外部。

7) 安全策略: 在 Swarm 群集内部的 Node, 强制使用基于TLS 的双向认证, 并且在单个Node 上以及在群集中的 Node 之间, 都进行安全的加密通信。 可以选择使用自签名的根证书,或者使用自定义的根 CA( Root CA) 证书。

8) 滚动更新: 对于服务需要更新的场景, 我们可以在多个 Node 上进行增量部署更新,Swarm Manager 支持通过使用 Docker CLI 设置一个 delay 时间间隔, 实现多个服务在多个Node 上依次进行部署, 这样可以非常灵活地控制。 如果有一个服务更新失败, 则暂停后面的更新操作, 重新回滚到更新之前的版本。

Swarm架构

Swarm作为一个管理Docker集群的工具,首先需要将其部署起来,可以单独将Swarm部署于一个节点。需要一个Docker集群,集群上每一个节点均安装有Docker。

具体的Swarm架构图可以参照下图:
在这里插入图片描述
Swarm架构中最主要的处理部分自然是Swarm节点,Swarm管理的对象自然是Docker Cluster,Docker Cluster由多个Docker Node组成,而负责给Swarm发送请求的是Docker Client。

swarm关键概念

1)Swarm
集群的管理和编排是使用嵌入到docker引擎的SwarmKit,可以在docker初始化时启动swarm模式或者加入已存在的swarm

2)Node
一个节点(node)是已加入到swarm的Docker引擎的实例,当部署应用到集群,你将会提交服务定义到管理节点,接着Manager管理节点调度任务到worker节点,manager节点还执行维护集群的状态的编排和群集管理功能,worker节点接收并执行来自manager节点的任务。通常,manager节点也可以是worker节点,worker节点会报告当前状态给manager节点

3)服务(Service)
服务是要在worker节点上要执行任务的定义,它在worker节点上执行,当你创建服务的时,你需要指定容器镜像

4)任务(Task)
任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点

主要管理命令集: 
docker swarm:集群管理,子命令有init, join, leave, update。(docker swarm -help查看帮助) 
docker service:服务创建,子命令有create, inspect, update, remove, tasks。(docker service--help查看帮助) 
docker node:节点管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm。(docker node --help查看帮助) 

1)manager node管理节点:执行集群的管理功能,维护集群的状态,选举一个leader节点去执行调度任务。 
2)worker node工作节点:接收和执行任务。参与容器集群负载调度,仅用于承载task。 
3)service服务:一个服务是工作节点上执行任务的定义。创建一个服务,指定了容器所使用的镜像和容器运行的命令。service是运行在worker nodes上的task的描述,service的描述包括使用哪个docker 镜像,以及在使用该镜像的容器中执行什么命令。 
4)task任务:一个任务包含了一个容器及其运行的命令。task是service的执行实体,task启动docker容器并在容器中执行任务。 

swarm工作方式

1、Node
一个 swarm包含一个或多个节点:运行在Docker Engine1.12或更高版本的swarm模式下的物理的或虚拟的机器。有两种类型的节点:managers和workers。

Manager节点

manager节点处理集群管理任务:

  • 维护集群状态
  • 调度服务
  • 提高swarm模式的HTTP API服务

swarm管理器使用Raft来实现维护整个swarm集群一致的内部状态。如果是测试的目的可以只运行一个swarm管理节点。如果单管理器的swarm出问题下线了,服务仍然会运行,不过你需要创建一个新的集群来恢复它。

要利用swarm模式的容错功能,Docker建议根据你对高可用的要求来创建奇数的管理节点。当你有多个管理节点时,可以不用停机从故障的管理节点中恢复。

  • 三个管理节点的swarm最大允许一个管理节点宕机
  • 五个管理节点的swarm最大允许两个管理节点宕机
  • N个管理节点的swarm最大允许(N-1)/2个管理节点宕机
  • Docker推荐最多创建7个管理节点

Worker节点

Worker节点是Docker Engine的实例,其唯一目的是运行容器。Worker节点不参与Raft分布状态,作调度的决定或提供swam模式的HTTP API服务。

你可以创建单个管理节点的swarm,不过你不能只有一个Worker节点而没有管理节点。默认情况下,所有的管理节点也是Worker节点。在单管理节点的集群中,你可以运行命令docker service create,然后调度器会把所有的任务放到本地执行。如果你想阻止调度器把任务分配到多个节点的集群的管理节点上,你可以设置管理节点的状态为Drain。调度器就不会继续把任务分发这些节点上执行。

改变角色

你可以通过执行docker node promote来把一个worker节点提升为管理节点。例如,你当你的管理节点下线时你可能会想把worker节点提升为管理节点。
在这里插入图片描述
2、Service(服务, 任务, 容器)
当你部署服务到swarm,swarm管理器接收你对服务期望状态的定义。然后它为你服务在swarm中的节点调度一个或多个副本任务。这些任务在swarm的节点上彼此独立地运行。

例如假设你想负载均衡三个 HTTP 服务器实例。下面的图表展示了三个 HTTP 服务器副本。三个HTTP实例中的每一个是swarm中的一个任务。
在这里插入图片描述
一个容器是孤立的进程。在swarm模式模型中,每个任务调用一个容器。任务包含着容器。一旦容器运行正常,调度器就会把相此容器相关联的任务识别为在线状态。否则容器停止或有异常,则任务显示为终止。

3、任务和调度
任务是swarm内调度的原子单位。当你通过创建或更新服务声明一个期望状态的服务,调度器通过调度任务来实现期望的状态。例如,你指定一个服务始终保持运行三个HTTP实例。调度器就创建三个任务。每个任务运行一个容器。容器是任务的实例化。如果一个HTTP容器之后出现故障停止,此任务被标志为失败,调度器就会创建一个新的任务来生成一个新容器。

任务是一个单向机制。它单向地执行一系统状态,assigned, prepared, running等。如果一个任务失败了,调度器就会删除这个任务和它的容器,然后创建一个新的任务来替换它。

下面的图表显示swarm模式是如何接收服务创建请求和调度任务到worker节点的。
在这里插入图片描述
4、副本和全局服务
有两种类型的服务部署,副本和全局。

对于副本服务,你可以指定运行相同任务的数量。例如,你决定部署三个HTTP实例的副本,每个提供相同的内容。

一个全局服务是在每个节点上运行一个相同的任务。不需要预先指定任务的数量。每次你增加一个节点到 swarm 中,协调器就会创建一个任务,然后调度器把任务分配给新节点。比如你希望在每个节点上运行监控代理,病毒扫描器等。

下面的图表显示以黄色标注的三个副本的服务和灰色标注的一个全局服务。
在这里插入图片描述
5、swarm调度策略
Swarm在scheduler节点(leader节点)运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, random.

1)Random
顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack策略会根据各个节点的可用的CPU, RAM以及正在运行的容器的数量来计算应该运行容器的节点。

2)Spread
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点。使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。

3)Binpack
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。

部署案例

1. 实验环境
manager:192.168.114.128
worker01:192.168.114.129
worker02:192.168.114.130

2、案例需求
部署 Docker Swarm 集群

3、案例实现思路
1) 准备 Docker Swarm 部署环境。
2) 部署 Docker Swarm 集群。

4、案例实施

Docker Swarm 系统环境准备

1、修改主机名
三台服务器修改主机名hostnamectl set-hostname 主机名
在这里插入图片描述
2、修改/etc/hosts文件,以便做名称解析,每台主机都要修改
本地文件传输: scp /etc/hosts root@192.168.114.129:/etc/
在这里插入图片描述
3、保证服务器能够上网
根据实际需求是否添加国内镜像源或配置镜像加速器

4、安装docker以及必要的软件包,每台设备都要安装
在这里插入图片描述
在这里插入图片描述
5、启动docker,每台设备都要
在这里插入图片描述
6、firewall放行端口
每台机器都需要执行, 群集节点之间保证 tcp 2377(群集管理端口)、 tcp/udp 7946(容器网络发现端口) 和 Tcp/Udp 4789(overlay 网络通信端口)。
在这里插入图片描述
重启firewall后,还要重启docker

7、关闭 Selinux,每台设备都要关闭
在这里插入图片描述

Docker Swarm 群集部署

1、创建 Swarm 群集部署命令:docker swarm init --advertise-addr <MANAGER-IP>
在 manager Node 上,创建一个 Swarm 群集,执行如下命令:
在这里插入图片描述
--advertise-addr参数配置管理节点发布它的IP地址192.168.114.128。其它的节点必须能通过此IP来连接管理节点。上面命令的输出包含了加入新节点到swarm的命令。节点将作为manager或worker加入,具体取决于–token标志的值。

运行以下命令获取来获取manager加入swarm集群的命令:docker swarm join-token manager
在这里插入图片描述
运行以下命令获取worker加入swarm集群的命令:docker swarm join-token worker
在这里插入图片描述
运行docker info查看 swarm集群信息:
在这里插入图片描述
执行docker node ls命令来查看节点的相关信息:
在这里插入图片描述
2、添加 worker 节点到 Swarm 群集
在 worker01、 worker02 两个 Worker Node 上,执行命令将 Worker Node 加入到 Swarm 群集中:
在这里插入图片描述
在这里插入图片描述
回到manager主机查看:docker info
在这里插入图片描述
在这里插入图片描述
上面信息中, AVAILABILITY 表示 Swarm Scheduler 是否可以向群集中的某个Node指派Task, 对应有如下三种状态:

  • Active: 群集中该 Node 可以被指派 Task。
  • Pause: 群集中该 Node 不可以被指派新的 Task, 但是其他已经存在的 Task 保持运行。
  • Drain: 群集中该 Node 不可以被指派新的 Task, Swarm Scheduler 停掉已经存在的Task,并将它们调度到可用的 Node 上。

查看某一个 Node 的状态信息, 只需要在该 Manager Node 上执行如下命令: docker node inspect worker01 --pretty
在这里插入图片描述
也可以查看自己的
在这里插入图片描述

Docker Swarm 群集管理

1、Docker Swarm 节点
运行 Docker 主机时可以自动初始化一个 Swarm 群集, 或者加入一个已存在的 Swarm 群集, 这样运行 Docker 主机将成为 Swarm 群集中的节点(node)。

Swarm 群集中节点可分为管理(manager)节点和工作(worker)节点。

管理节点用于 Swarm 群集的管理, Docker Swarm 命令基本只能在管理节点执行, 而工作节点退出群集命令 docker swarm leave 可以在工作节点上执行。

Manager node 负责执行编排和集群管理工作, 保持并维护 Swarm 处于期望的状态。

Swarm 中, 如果有多个 manager node, 它们会自动协商并选举出一个 leader 执行编排任务。

工作节点是任务执行节点,管理节点将服务(service)下发至工作节点执行。 管理节点默认也作为工作节点。 也可以通过配置让服务只运行在管理节点。

2、服务和任务
任务(Task) 是 Swarm 中的最小的调度单位, 一个单一的容器。

服务(Services)是指一组任务的集合,服务定义了任务的属性。服务有两种模式:

  • replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
  • global services 每个工作节点上运行一个任务。

两种模式都可以通过 docker service create--mode 参数指定。

Docker Swarm 日常操作管理

实现 Docker Swarm 日常操作管理,包括:
1)节点管理
2)服务管理
3)网络管理
4)数据卷管理

1、Docker Swarm 节点管理**

1.1 Node 状态变更管理
Node 的 AVAILABILITY 有三种状态: Active、 Pause、 Drain。 对某个 Node进行变更, 可以将其 AVAILABILITY 值通过 Docker CLI 修改为对应的状态。 下面是常见的变更操作:
1)设置 Manager Node 只具有管理功能。
2)对服务进行停机维护, 可以修改 AVAILABILITY 为 Drain 状态。
3)暂停一个 Node, 然后该 Node 就不再接收新的 Task。
4)恢复一个不可用或者暂停的 Node。

如:将 Manager Node 的 AVAILABILITY 值修改为 Drain 状态, 使其只具备管理功能: docker node update --availability drain manager
在这里插入图片描述
这样, Manager Node 不能被指派 Task, 也就是不能部署实际的 Docker 容器来运行服务, 而只是作为管理 Node 的角色。

1.2 给 Node 添加标签元数据
每个 Node 的主机配置情况可能不同, 比如: 有的适合运行 CPU 密集型应用, 有的适合运行 IO 密集型应用。 Swarm 支持给每个 Node 添加标签元数据, 这样可以根据 Node 的标签,选择性地调度某个服务部署到期望的一组 Node 上。

给 Swarm 群集中的某个 Worker Node 添加标签, 执行如下命令格式如下: docker node update --label-add 值 键

如: worker01 主机在名称为 BJ-IDC-01 这个数据中心, 执行如下命令添加标签:docker node update --label-add BJ-IDC-01 worker01
在这里插入图片描述
1.3 Node 提权/降权
改变 Node 的角色,Worker Node可以变为 Manager Node, 即: 由工作 Node
变成了管理 Node,对应提权操作。

如: 将 worker1 升级为 Manager Node: docker node promote worker01
在这里插入图片描述
对上面已提权的 worker1 执行降权:docker node demote worker01
在这里插入图片描述
1.4 退出 Swarm 群集
如果 Manager 想要退出 Swarm 群集, 在 Manager Node 上执行如下命令: docker swarm leave

如果群集中还存在其它的 Worker Node, 还希望 Manager 退出群集, 则加上一个强制选 项, 命令行如下所示: docker swarm leave --force

如果 Worker 想要退出 Swarm 群集, 在 Worker Node 上, 执行如下命令:docker swarm leave

即使 Manager 已经退出 Swarm 群集, 执行上述命令也可以使得 Worker Node 退出群集。之后, 根据需要, 还可以加入到其它新建的 Swarm 群集中。

2、Docker Swarm 服务管理

在 Swarm mode下使用Docker, 可以实现部署运行服务(create)、 服务扩容缩容(scale)、 删除服务、 滚动更新等功能。

2.1 创建服务
创建 Docker 服务, 可以使用 docker service create 命令实现。

如:从docker镜像busybox创建名称为hello的服务,指定副本数量为2,执行ping命令:docker service create --replicas 2 --name hello busybox ping www.baidu.com
在这里插入图片描述
查看服务日志:docker service logs -f hello
在这里插入图片描述
查看当前已经部署启动的全部应用服务:docker service ls
在这里插入图片描述
以查询指定服务的详细信息:docker service ps hello
在这里插入图片描述
上面信息中, 在 worker01 和 worker02 这两个 Node 上部署了 hello 这个应用服务, 也包含了它们对应的当前状态信息。 此时, 也可以通过执行 docker ps 命令, 在 Manager Node 上查看当前启动的 Docker 容器:
在这里插入图片描述
使用易于阅读的方式显示服务详细信息:docker service inspect --pretty hello
在这里插入图片描述
默认以json格式显示:docker service inspect hello

2.2 服务的扩容缩容
Docker Swarm 支持服务的扩容缩容, Swarm 通过–mode 选项设置服务类型,提供了两种模式:

  • 一种是 replicated, 可以指定服务 Task 的个数(也就是需要创建几个冗余副本),这也是 Swarm 默认使用的服务类型。
  • 另一种是 global, 会在 Swarm 群集的每个 Node 上都创建一个服务。

命令格式:docker service scale 服务 ID=服务Task总数

如:将前面已经部署的 2 个副本的hello服务, 扩容到 3 个副本:docker service scale hello=3
在这里插入图片描述
通过 docker service ps hello 查看一下各个副本的状态信息:
在这里插入图片描述
而缩容服务只需要将副本数小于当前应用服务拥有的副本数即可实现, 大于指定缩容副本数的副本会被删除。
在这里插入图片描述
2.3 删除服务
删除服务, 只需要在 Manager Node 上执行命令
命令格式: docker service rm 服务名称

如:删除 hello 应用服务,则应用服务 hello 的全部副本都会被删除:docker service rm hello
在这里插入图片描述
2.4 滚动更新

在 Manager Node 上执行如下命令,先创建一个nginx 1.14版本:docker service create --replicas 3 --name web-server --update-delay 10s nginx:1.14
在这里插入图片描述
在服务部署时配置了滚动更新策略:

  • --update-delay参数配置更新服务任务之间的延迟时间或一组任务之间的延迟时间。你可以以秒s,分m,时h单位来配置延迟时间。所以10m30s表示10分钟 30秒的延迟。
  • 默认情况下,调度程序一次执行一个更新任务。你可以传递–update-parallelism参数来配置调度程序同时执行的最大更新服务任务数。
  • 默认情况下,当单个更新任务返回RUNNING的状态时,调度器调度继续其它任务直到所有任务更新完成。如果在更新任务期间的任何时候一个任务返回FAILED,调度器暂停更新。你可以在docker service createdocker service update时使用–update-failure-action来控制其行为。

查看服务nginx的详细信息:
在这里插入图片描述
始更新nginx容器。swarm管理器根据UpdateConfig策略来对节点应用更新:docker service update --image nginx:1.18 web-server
在这里插入图片描述
默认情况下调度器应用滚动更新的步骤如下:

  • 停止第一个任务
  • 对已停止的任务执行更新
  • 启动已经完成更新的容器
  • 如果更新任务返回RUNNING,等待一个指定的延迟然后停止下一个任务
  • 如果在任何时候任务返回FAIlED,停止更新

查看更新后的nginx服务详细信息:
在这里插入图片描述
查看服务,发现以前的版本也在,只是处于停止状态 :
在这里插入图片描述
如果更新暂停,执行docker service update 命令来重启已暂停的更新,如:docker service update web-server

2.5 回滚版本
回滚版本:docker service update web-server --rollback
在这里插入图片描述

3、添加自定义 Overlay 网络

Docker Engine的swarm模式原生支持覆盖网络(overlay networks),所以你可以启用容器到容器的网络。swarm模式的覆盖网络包括以下功能:

你可以附加多个服务到同一个网络
默认情况下,service discovery为每个swarm服务分配一个虚拟IP地址(vip)和DNS名称,使得在同一个网络中容器之间可以使用服务名称为互相连接。

你可以配置使用 DNS 轮循而不使用 VIP

为了可以使用 swarm 的覆盖网络,在启用 swarm 模式之间你需要在 swarm 节点之间开放以下端口:

  • TCP/UDP 端口 7946 – 用于容器网络发现
  • UDP 端口 4789 – 用于容器覆盖网络

在 Manager Node 上创建一个 Overlay 网络:

命令:
docker network create --driver overlay --subnet 192.168.1.0/24 --opt encrypted my-network
其中:
默认情况下swarm中的节点通信是加密的。在不同节点的容器之间,可选的-–opt encrypted 参数能在它们的vxlan流量启用附加的加密层。
-–subnet 参数指定覆盖网络的子网。当你不指定一个子网时,swarm管理器自动选择一个子网并分配给网络。在一些旧的内核,包括 kernel 3.10,自动分配的地址可能会与其它子网重叠。这样的重叠可能引起连接问题。

查看网络:docker network ls
在这里插入图片描述
swarm scope 表示部署到 swarm 的服务可以使用这个网络。当你创建一个服务并附加到一个网络后,swarm 仅仅扩展该网络到服务运行的节点上。在一个没有运行有附加到网络的服务 worker 节点上,network ls 命令不会显示有任何网络。

要附加一个服务到一个覆盖网络,在创建服务的时候传递-–network 参数。例如创建一个nginx服务并附加到一个名为 my-network 的网络:docker service create --replicas 3 --name web-server1 --network my-network nginx
在这里插入图片描述
查看服务所在的节点信息:
在这里插入图片描述查看网络具体信息
在这里插入图片描述
默认情况下,当你创建一个服务并附加到一个网络时,swarm 就给服务分配一个 VIP。VIP 根据服务名称映射到 DNS 别名。在该网络的容器之间通过 gossip 来共享 DNS 映射信息,所以在该网络的容器能通过服务名称来访问彼此

查看VIP:docker service inspect --format='{{json .Endpoint.VirtualIPs}}' web-server1
在这里插入图片描述
默认情况下,以上发布的端口都是 TCP 端口。你可以指定发布一个 UDP 端口,如:docker service create --name dns-cache -p 53:53/udp dns-cache

发布web-server1的TCP8080端口:docker service update --publish-add 8080:80 web-server1
在这里插入图片描述
查看发布的端口:docker service inspect --format='{{json .Endpoint.Ports}}' web-server1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

当你访问任意节点的 8080 端口,swarm 的负载均衡会把你的请求路由到一个任意节点的可用的容器上。routing mesh 在 swarm 节点的所有 IP 上监听 published 端口
在这里插入图片描述
可以配置一个外部负载均衡来路由请求到 swarm 服务。例如,你可以配置 HAProxy 来路由请求到一个 published 端口为 8080 的 nginx 服务。
在这里插入图片描述

4、创建数据卷

4.1 创建数据卷

创建数据卷:docker volume create volume-test
在这里插入图片描述
查看创建的数据卷:docker volume ls
在这里插入图片描述
应用上述创建的数据卷:docker service create --mount type=volume,src=volume-test,dst=/usr/local/apache2/htdocs --replicas 2 --name web-test httpd
在这里插入图片描述
查看数据卷的详细信息:docker volume inspect volume-test
在这里插入图片描述
查看服务所在的节点:
在这里插入图片描述
登录到worker01主机,测试
在这里插入图片描述
在这里插入图片描述
从上面的验证结果看, 在本地数据卷的目录下创建几个文件, 在进入到容器后, 找到对应的目录,数据依然存在。

4.2 采用 bind mount 挂载类型挂载数据卷

在worker02主机上创建本地挂载目录:
在这里插入图片描述
在manager主机上创建服务:docker service create --mount type=bind,source=/webroot,target=/usr/local/apache2/htdocs --replicas 2 --name web-test1 httpd
其中,参数 target 表示容器里面的路径,source 表示本地硬盘路径
在这里插入图片描述
在这里插入图片描述
该报错是由于worker01没有相应的挂载目录导致的

进入worker02进行测试:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值