标签 Kubernetes 下的文章

在Kubernetes上如何基于自定义指标实现应用的自动缩放

img{512x368}

如何在Kubernetes上实现应用缩放?

使用静态配置将应用程序部署到生产环境并不是最佳选择。

流量模式可能会快速变化,应用程序应该能够实现自适应:

  • 当需求增加时,应用程序应扩大规模(增加副本数)以保持响应速度。
  • 当需求减少时,应用程序应缩小规模(减少副本数量),以免浪费资源。

Kubernetes以Horizontal Pod Autoscaler的形式为自动缩放应用程序提供了出色的支持。

下面我们将学习如何使用它。

不同类型的自动缩放

首先,为了消除任何误解,让我们澄清一下Kubernetes中的术语“自动缩放”的不同用法。

在Kubernetes中,有几件事可被称为“自动缩放”,包括:

  • 水平Pod自动缩放器:调整应用程序的副本数
  • Vertical Pod Autoscaler:调整容器的资源请求(request)和限制(limit)
  • 集群自动缩放器:调整集群的节点数

尽管这些组件都可以“自动缩放”某些东西,但是它们彼此之间完全不相关。

它们都针对非常不同的用例,并使用不同的概念和机制。

它们是在单独的项目中开发的,可以彼此独立使用。

本文介绍的是水平Pod自动缩放器。

什么是水平Pod自动缩放器?

水平Pod自动配置器是Kubernetes内置的功能,允许基于一个或多个被监测的指标水平缩放应用规模。

水平缩放意味着增加和减少副本数量。垂直缩放意味着增加和减少单个副本的计算资源。

从技术上讲,Horizontal Pod Autoscaler是Kubernetes控制器管理器(controller manager)中的控制器(controller),它是由HorizontalPodAutoscaler资源对象配置的。

Horizontal Pod Autoscaler可以监视有关应用程序的指标,并不断调整副本数以最佳地满足当前需求。

Horizontal Pod Autoscaler可缩放的资源包括Deployment,StatefulSet,ReplicaSet和ReplicationController。

为了自动缩放应用程序,Horizontal Pod自动缩放器会执行一个永久控制循环:

img{512x368}

此控制循环的步骤为:

  • 查询缩放指标
  • 计算所需的副本数
  • 将应用程序缩放到所需数量的副本

控制循环的默认周期为15秒

所需副本数的计算基于缩放度量和该度量的用户提供的目标值。

目的是计算一个副本计数,该副本计数将使度量值尽可能接近目标值。

例如,假设缩放指标是每个副本的每秒请求速率:

  • 如果目标值为10 req / sec,而当前值为20 req / sec,则Horizontal Pod Autoscaler将按比例放大应用程序(即增加副本数),以使度量标准减小并更接近目标值。
  • 如果目标值为10 req / sec,当前值为2 req / sec,则Horizontal Pod Autoscaler将按比例缩小应用程序(即减少副本数),以使度量标准增加并更接近目标值。

用于计算所需副本数的算法基于以下公式:

X = N * (c/t)

其中X是所需的副本数,N是当前副本数,c是度量的当前值,t是目标值。

您可以在文档中找到有关算法的详细信息。

这就是Horizontal Pod Autoscaler的工作方式,但是如何使用它呢?

如何配置水平pod自动缩放器?

通过创建HorizontalPodAutoscaler资源,可以将Horizontal Pod Autoscaler配置为自动缩放应用程序。

此资源使您可以指定以下参数:

  • 可扩展的资源(例如,部署)
  • 最小和最大副本数
  • 缩放指标
  • 缩放指标的目标值

创建此资源后,Horizontal Pod Autoscaler将使用提供的参数开始对您的应用执行上述控制循环。

具体的HorizontalPodAutoscaler资源如下所示:

//hpa.yaml

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myhpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: myapp_requests_per_second
        target:
          type: AverageValue
          averageValue: 2

存在清单文件结构不同的HorizontalPodAutoscaler资源的不同版本。上面的示例使用version v2beta2,它是撰写本文时的最新版本。

此资源myapp根据myapp_requests_per_second一个目标值为2 的指标指定一个名为Deployment的部署,该部署将在1到10个副本之间自动缩放。

您可以想象到,该myapp_requests_per_second指标代表此部署中各个Pod的请求率-因此,本规范的目的是自动调整Deployment的目标,以使每个Pod保持每秒2个请求的请求率。

到目前为止,这听起来不错,但有一个问题。

指标来自哪里?

什么是指标注册表?

整个自动缩放机制均基于代表应用程序当前负载的指标。

定义HorizontalPodAutoscaler资源时,您必须指定此类指标。

但是Horizontal Pod Autoscaler如何知道如何获取这些指标?

事实证明,还有另一个组件在起作用-指标注册表。

Horizontal Pod Autoscaler从指标注册表查询指标:

img{512x368}

度量标准注册表是集群中的中心位置,度量标准(任何类型)向客户端(任何类型)公开。

Horizontal Pod Autoscaler是这些客户端之一。

度量标准注册表的目的是为客户端提供从中查询度量标准的标准接口。

指标注册表的接口包含三个单独的API:

img{512x368}

这些API旨在提供不同类型的指标:

  • 资源度量标准API: Pod和节点的预定义资源使用度量标准(CPU和内存)
  • 自定义指标API:与Kubernetes对象关联的自定义指标
  • 外部指标API:与Kubernetes对象不关联的自定义指标

所有这些度量标准API都是扩展API

这意味着它们是核心Kubernetes API的扩展,可通过Kubernetes API服务器进行访问。

如果要自动缩放应用程序,这对您意味着什么?

您想要用作缩放指标的任何指标都必须通过这三个指标API之一公开。

因为只有这样,Horizontal Pod Autoscaler才能访问它们。

因此,要自动缩放应用程序,您的任务不仅是配置Horizontal Pod自动缩放器…

您还必须通过度量标准注册表公开所需的缩放度量标准。

如何通过度量标准API公开度量标准?

通过在集群中安装和配置其他组件。

对于每个度量标准API,您需要一个相应的度量标准API服务器,并且需要对其进行配置以通过度量标准API公开特定的度量标准。

默认情况下,Kubernetes中未安装任何度量标准API服务器,这意味着默认情况下未启用度量标准API 。

此外,您需要一个指标收集器,该指标收集器从源(例如,从目标应用的Pod)收集所需的指标,并将其提供给指标API服务器。

img{512x368}

对于不同的度量标准API,度量标准API服务器和度量标准收集器有不同的选择。

资源指标API:

  • 指标收集器是cAdvisor,它在每个工作程序节点上作为kubelet的一部分运行(因此默认情况下已安装)
  • 资源指标API的官方指标API服务器是metrics-server

自定义指标API和外部指标API:

  • 指标收集器的一个流行选择是Prometheus。但是,也可以使用其他指标系统(例如Datadog或Google Stackdriver)代替
  • prometheus适配器是与普罗米修斯集成为度量收集的度量标准API服务器-但是,其他度量收集器有自己的度量标准API服务器

因此,要通过一种度量标准API公开度量标准,您必须执行以下步骤:

  • 安装指标收集器(例如Prometheus)并将其配置为收集所需指标(例如从您的应用程序的Pod中收集)
  • 安装度量标准API服务器(例如Prometheus适配器)并将其配置为通过相应的度量标准API从度量标准收集器暴露度量数据

请注意,这专门适用于提供自定义指标的自定义指标API和外部指标API。Resource Metrics API仅提供默认指标,而不能配置为提供自定义指标。

以上信息很多,让我们把它们放在一起再完整过一遍。

放在一起

让我们来看一个完整的示例,该示例将应用配置为由Horizontal Pod Autoscaler自动缩放。

想象一下,您想基于副本的平均每秒请求速率来自动缩放Web应用程序。

另外,假设您要使用基于Prometheus的设置来通过Custom Metrics API公开请求率指标。

请求速率是与Kubernetes对象(Pods)关联的自定义指标,因此必须通过Custom Metrics API公开。

以下是达到目标的一系列步骤:

  • 设置您的应用程序,以将接收到的请求总数作为Prometheus指标公开
  • 安装Prometheus并将其配置为从应用程序的所有Pod中收集此指标
  • 安装Prometheus适配器并将其配置为将度量标准从Prometheus转换为每秒请求速率(使用PromQL)并且作为myapp_requests_per_second指标通过Custom Metrics API 公开
  • 创建一个HorizontalPodAutoscaler资源(如上所示),指定myapp_requests_per_second为缩放指标和适当的目标值

一旦创建HorizontalPodAutoscaler资源,Horizontal Pod Autoscaler就会启动,并开始根据您的配置自动缩放您的应用程序。

现在,您可以观察您的应用程序适应流量的情况。

本文为基于自定义指标自动缩放应用程序设置了理论框架。

在以后的文章中,您将把这些知识付诸实践,并在自己的集群上使用自己的应用程序执行上述步骤。

本文翻译自《How to autoscale apps on Kubernetes with custom metrics》


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网上线了,感谢小伙伴们学习支持!

我爱发短信:企业级短信平台定制开发专家 https://51smspush.com/
smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

我的联系方式:

微博:https://weibo.com/bigwhite20xx
微信公众号:iamtonybai
博客:tonybai.com
github: https://github.com/bigwhite

微信赞赏:
img{512x368}

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

构建Kubernetes集群 – 选择工作节点大小

近期learnk8s网站上发布了一些关于k8s的好文章,这里搬运并翻译了一些,供大家参考。

本文翻译自《Architecting Kubernetes clusters — choosing a worker node size》

img{512x368}

当您创建Kubernetes集群时,冒出的第一个问题之一是:“我应该使用哪种类型的工作节点以及需要多少个这样的节点”。

如果您正在构建在内部部署的k8s集群,是应该订购一些最近一代的新服务器,还是使用数据中心内的十几台旧机器?

或者,如果您使用Google Kubernetes Engine(GKE)等托管Kubernetes服务,您是否应该使用八个n1-standard-1或两个n1-standard-4实例来实现所需的计算能力呢?

集群容量

通常,Kubernetes集群可以被视为将一组单个节点抽象为一个大的“超级节点”。

该超级节点的总计算容量(就CPU和内存而言)是所有组成节点容量的总和。

有多种方法可以实现集群的所需目标容量。

例如,假设您需要一个总容量为8个CPU内核和32 GB RAM的集群。

例如,因为要在集群上运行的应用程序集需要如此数量的资源。

以下是设计集群的两种可能方法:

img{512x368}

这两个选项都会产生具有相同容量的集群 – 但左侧选项使用4个较小的节点,而右侧选项使用2个较大的节点。

哪个更好?

为了解决这个问题,让我们来看看“少数大节点”和“许多小节点”这两个相反方向思路的优缺点。

请注意,本文中的“节点”始终指的是工作节点(worker node)。master节点的数量和大小的选择是完全不同的话题。

使用少量大节点

这方面最极端的情况是仅使用一个可以提供整个所需集群容量的工作节点。

如果要满足上面的示例中容量的需求,这将是一个具有16个CPU内核和16 GB RAM的单个工作节点。

让我们来看看这种方法可能具有的优势。

1. 减少管理成本

简单地说,管理少量机器比管理大量机器要更省力。

更新和补丁可以更快地应用,机器可以更容易保持同步。

此外,对于机器数量少而言,预期故障的绝对数量要小于机器数量多的情况。

但请注意,这主要适用于裸机服务器而不适用于云实例。

如果您使用云实例(作为托管Kubernetes服务的一部分或您在云基础架构上安装的Kubernetes),则将底层机器的管理外包给云提供商。

因此,管理云中的10个节点并不比管理云中的单个节点成本多得多。

2. 每个节点的成本更低

虽然更强大的机器比低端机器更昂贵,但价格上涨不一定是线性的。

换句话说,具有10个CPU内核和10 GB RAM的单台机器可能比具有1个CPU内核和1 GB RAM的10台机器便宜。

但请注意,如果您使用云实例,这可能同样不适用。

在主要云提供商Amazon Web Services,Google Cloud Platform和Microsoft Azure的当前定价方案中,实例价格是随容量线性增加的。

例如,在Google Cloud Platform上,64个n1-standard-1实例的成本与单个n1-standard-64实例完全相同- 两个选项都为您提供64个CPU内核和240 GB内存。

因此,在云中,您通常无法通过使用更大的机器来节省成本。

3. 允许运行资源消耗较大的应用程序

拥有大型节点可能只是您要在集群中运行一类应用程序的要求。

例如,如果您有一台需要8 GB内存的机器学习应用程序,你无法在仅具有1 GB内存的节点的集群上运行它。

但是,您可以在具有10 GB内存节点的群集上运行它。

看过优势后,让我们再来看看其弊端又是什么。

1. 每个节点有大量的pod

在较少的节点上运行相同的工作负载自然意味着在每个节点上运行更多的pod。

这可能成为一个问题。

原因是每个pod都会在节点上运行的Kubernetes代理上引入一些开销 – 例如容器运行时(例如Docker),kubelet和cAdvisor。

例如,kubelet对节点上的每个容器执行常规活动和就绪探测 – 更多容器意味着在每次迭代中kubelet需要做更多的工作。

cAdvisor收集节点上所有容器的资源使用统计信息,并且kubelet定期查询此信息并通过其API发布它 – 再次,这意味着每次迭代中cAdvisor和kubelet的工作量都会增加。

如果pod的数量变大,这些东西可能会开始减慢系统速度,甚至使系统变得不可靠。

img{512x368}

issue称节点因常规的kubelet运行状况检查花费了太长时间来迭代节点上的所有容器而导致节点处于非就绪状态。

出于这些原因,Kubernetes 建议每个节点最多110个pod

针对这个数字,Kubernetes已经做过测试,结果证明是可以在通常节点类型上可靠地工作的。

根据节点的性能,您可能能够成功地为每个节点运行更多的pod – 但这依然很难预测事情是否会顺利运行,又或您将遇到问题。

大多数托管Kubernetes服务甚至对每个节点的pod数量施加了严格的限制:

  • 在Amazon Elastic Kubernetes Service(EKS)上,每个节点的最大pod数取决于节点类型,范围从4到737。
  • 在Google Kubernetes Engine(GKE)上,无论节点类型如何,每个节点的限制为100个pod。
  • 在Azure Kubernetes服务(AKS)上,默认限制是每个节点30个pod,但最多可以增加到250个。

因此,如果您计划为每个节点运行大量pod,则应该事先测试事情是否能按预期工作。

2. 有限的复制

少量节点可能会限制应用程序的有效复制程度。

例如,如果您有一个由5个副本组成的高可用性应用程序,但您只有2个节点,那么应用程序的有效复制程度将减少到2。

这是因为5个副本只能分布在2个节点上,如果其中一个失败,它可能会同时删除多个副本。

另一方面,如果您有至少5个节点,则理想情况下每个副本可以在单独的节点上运行,并且单个节点的故障最多只会删除一个副本。

因此,如果您具有高可用性要求,则可能需要对集群中的最小节点数提出要求。

3. 更大的爆破半径

如果您只有几个节点,那么失败节点的影响比您有许多节点的影响要大。

例如,如果您只有两个节点,并且其中一个节点出现故障,那么大约一半的节点会消失。

Kubernetes可以将失败节点的工作负载重新安排到其他节点。

但是,如果您只有几个节点,则风险更高,因为剩余节点上没有足够的备用容量来容纳故障节点的所有工作负载。

结果是,部分应用程序将永久停机,直到再次启动故障节点。

因此,如果您想减少硬件故障的影响,您可能希望选择更多的节点。

4. 大比例增量

Kubernetes 为云基础架构提供了一个Cluster Autoscaler,允许根据当前需求自动添加或删除节点。

如果使用大型节点,则会有大的缩放增量,这会使缩放更加笨重。

例如,如果您只有2个节点,则添加其他节点意味着将群集容量增加50%。

这可能比您实际需要的多得多,这意味着您需要为未使用的资源付费。

因此,如果您计划使用集群自动缩放,则较小的节点允许更流畅且经济高效的缩放行为。

在讨论了使用”很少几个大节点”的方案的优缺点之后,让我们转向”许多小节点”的场景。

使用大量小节点

这种方法包括从许多小节点而不是几个大节点中形成集群。

这种方法的优点和缺点是什么?

使用许多小节点的优点主要对应于使用少量大节点的缺点。

1. 较小的爆破半径

如果您有更多节点,则每个节点上的pod自然会更少。

例如,如果您有100个pod和10个节点,则每个节点平均只包含10个pod。

因此,如果其中一个节点发生故障,则影响仅限于总工作负载的较小比例。

有可能只有一些应用程序受到影响,并且可能只有少量副本,因此整个应用程序都会保持运行状态。

此外,剩余节点上的备用资源很可能足以容纳故障节点的工作负载,因此Kubernetes可以重新安排所有pod,并且您的应用程序可以相对快速地返回到完全正常运行的状态。

2. 允许高可复制性

如果您有高可用性需求的应用程序和足够的可用节点,Kubernetes调度程序可以将每个副本分配给不同的节点。

您可以通过节点亲缘关系pod亲和力/反亲和力以及taint和tolerations来影响调度程序对pod放置位置的选择。

这意味着如果某个节点出现故障,则最多只有一个副本受影响且您的应用程序仍然可用。

看到使用许多小节点的优点,那它有什么缺点呢?

1. 节点数量大

如果使用容量较小的节点,则自然需要更多节点来实现给定的集群容量。

但是大量节点对Kubernetes控制平面来说可能是一个挑战。

例如,每个节点都需要能够与每个其他节点通信,这使得可能的通信路径数量以节点数量的平方的量级增长 – 所有节点都必须由控制平面管理。

Kubernetes控制器管理器中的节点控制器定期遍历集群中的所有节点以运行运行状况检查 – 更多节点意味着节点控制器的负载更多。

更多节点意味着etcd数据库上的负载也更多 – 每个kubelet和kube-proxy都会导致etcd的观察者(watch)客户端(通过API服务器),etcd必须广播对象更新。

通常,每个工作节点都会给主节点上的系统组件增加一些开销。

img{512x368}

据官方统计,Kubernetes声称支持最多5000个节点的集群

然而,在实践中,500个节点可能已经构成了较大的挑战

通过使用性能更高的主节点,可以减轻大量工作节点的影响。

这就是在实践中所做的 – 这里是kube-up在云基础架构上使用的主节点大小

  • Google云端平台
    • 5个工作节点→ n1-standard-1主节点
    • 500个工作节点→ n1-standard-32主节点
  • 亚马逊网络服务
    • 5个工作节点→ m3.medium主节点
    • 500个工作节点→ c4.8xlarge主节点

如您所见,对于500个工作节点,使用的主节点分别具有32和36个CPU核心以及120 GB和60 GB内存。

这些都是相当大的机器!

因此,如果您打算使用大量小节点,则需要记住两件事:

  • 您拥有的工作节点越多,您需要的性能就越高
  • 如果您计划使用超过500个节点,则可能会遇到一些需要付出一些努力才能解决的性能瓶颈

Virtual Kubelet这样的新项目允许绕过这些限制,并允许具有大量工作节点的集群。

2. 更多系统开销

Kubernetes在每个工作节点上运行一组系统守护进程 – 包括容器运行时(例如Docker),kube-proxy和包含cAdvisor的kubelet。

cAdvisor包含在kubelet二进制文件中。

所有这些守护进程一起消耗固定数量的资源。

如果使用许多小节点,则这些系统组件使用的资源部分比例会更大。

例如,假设单个节点的所有系统守护程序一起使用0.1个CPU内核和0.1 GB内存。

如果您拥有10个CPU核心和10 GB内存的单个节点,那么守护程序将占用集群容量的1%。

另一方面,如果您有1个CPU核心和1 GB内存的10个节点,则后台程序将占用集群容量的10%。

因此,在第二种情况下,10%的账单用于运行系统,而在第一种情况下,它只有1%。

因此,如果您希望最大化基础架构支出的回报,那么您可能更喜欢更少的节点。

3. 降低资源利用率

如果您使用较小的节点,那么最终可能会有大量资源片段太小而无法分配给任何工作负载,因此保持未使用状态。

例如,假设您的所有pod都需要0.75 GB的内存。

如果你有10个1 GB内存的节点,那么你可以运行10个这些pod – 你最终会在每个节点上有一块0.25 GB的内存,你不能再使用它了。

这意味着,集群总内存的25%被浪费了。

另一方面,如果您使用具有10 GB内存的单个节点,那么您可以运行13个这样的pod – 而只有0.25 GB的单块内存剩下无法使用。

在这种情况下,您只会浪费2.5%的内存。

因此,如果您想最大限度地减少资源浪费,使用更大的节点可能会提供更好的结果。

4. 小节点上的Pod限制

在某些云基础架构上,小节点上允许的最大pod数量比您预期的要限制得多。

Amazon Elastic Kubernetes Service(EKS)就是这种情况,其中每个节点的最大pod数取决于实例类型。

例如,对于一个t2.medium实例,pod的最大数量是17,因为t2.small它是11,而t2.micro它是4。

这些都是非常小的数字!

任何超出这些限制的pod都无法由Kubernetes调度程序安排,这些pod会一直保持在Pending状态。

如果您不了解这些限制,则可能导致难以发现的错误。

因此,如果您计划在Amazon EKS上使用小节点,请检查相应的每节点pods数,并多算几次计算节点是否可以容纳所有pod。

结论

那么,您应该在集群中使用少量大型节点还是许多小型节点?

一如既往,没有明确的答案。

您要部署到集群的应用程序类型可能会指导您的决策。

例如,如果您的应用程序需要10 GB内存,则可能不应使用小节点 – 集群中的节点应至少具有10 GB内存。

或者,如果您的应用程序需要10倍的复制性以实现高可用性,那么您可能不应该只使用2个节点 – 您的集群应该至少有10个节点。

对于中间的所有场景,它取决于您的具体要求。

以上哪项优缺点与您相关?哪个不是?

话虽如此,没有规则规定所有节点必须具有相同的大小。

没有什么能阻止您在集群中使用不同大小节点混合在一起的方案。

Kubernetes集群的工作节点可以是完全异构的。

这可能会让您权衡两种方法的优缺点。

最后,证明布丁好坏就在于吃 – 最好的方法是试验并找到最适合你的组合!


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网上线了,感谢小伙伴们学习支持!

我爱发短信:企业级短信平台定制开发专家 https://51smspush.com/
smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

我的联系方式:

微博:https://weibo.com/bigwhite20xx
微信公众号:iamtonybai
博客:tonybai.com
github: https://github.com/bigwhite

微信赞赏:
img{512x368}

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! 图片广告位1 图片广告位2 图片广告位3 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats