腾讯云原生

腾讯云原生 查看完整档案

深圳编辑  |  填写毕业院校腾讯云  |  云原生 编辑 cloud.tencent.com 编辑
编辑

云原生技术交流阵地,汇聚云原生最新技术资讯、文章、活动,以及云原生产品及用户最佳实践内容。

个人动态

腾讯云原生 发布了文章 · 11月25日

如何用Prometheus监控十万container的Kubernetes集群

概述

不久前,我们在文章《如何扩展单个Prometheus实现近万Kubernetes集群监控?》中详细介绍了TKE团队大规模Kubernetes联邦监控系统Kvass的演进过程,其中介绍了针对规模较大的集群,我们是如何通过修改Prometheus代码来实现横向扩缩容的。经过方案上的改进,Kvass目前已经支持以Sidecar的方式实现Prometheus集群化,而不是修改Prometheus代码。由于方案对社区有一定价值,团队决定将项目开源出来,分享给社区。项目地址

本文首先将给出Prometheus的单机性能瓶颈,以及现有的社区集群化方案,随后将详细介绍开源版Kvass的设计思想,使用案例及压测结果。

另外,腾讯云容器团队在Kvass的设计思想上进一步优化,构建了支持多集群的高性能云原生监控服务,产品目前已正式公测,欢迎读者试用。传送门: https://console.cloud.tencent...

后续章节我们也将直接使用该产品来展示Kvass对大规模集群的监控能力。
1

Prometheus

Prometheus依靠其强劲的单机性能,灵活的PromSQL,活跃的社区生态,逐渐成为云原生时代最核心的监控组件,被全球各大产商用于监控他们的核心业务。

然而,面对大规模监控目标(数千万series)时,由于原生Prometheus只有单机版本,不提供集群化功能,开发人员不得不通过不断增加机器的配置来满足Prometheus不断上涨的内存。

单机性能瓶颈

我们对单机Prometheus进行的压测,用以探测单个Prometheus分片的合理负载,压测的目标有两个。

  • 确定target数目对Prometheus负载的关系
  • 确定series数目和Prometheus负载的关系

target相关性

我们保持总series为100万不变, 通过改变target个数,观察Prometheus负载变动。
2
压测结果

target数量CPU (core)mem (GB)
1000.174.6
5000.194.2
10000.163.9
50000.34.6
  • 从表中我们发现target数目的改动对Prometheus负载的影响并不是强相关的。在target数目增长50倍的情况下,CPU消耗有小量增长,但是内存几乎不变。

series相关性

我们保持target数目不变,通过改变总series数,观察Prometheus的负载变动。

3

压测结果

series数量 (万)CPU (core)mem (GB)查询1000 series 15m数据(s)
1000.1913.150.2
3000.93920.141.6
5002.02630.571.5
  • 从表中,Prometheus的负载受到series的影响较大,series越多,资源消耗越大。
  • 当series数据超过300万时,Prometheus内存增长较为明显,需要使用较大内存的机器来运行。
压测过程中,我们使用了工具去生成预期数目的series,工具生成的series每个label的长度及值的长度都较小,固定为10个字符左右。我们的目的是观察相对负载变化,实际生产中由于label长度不同,服务发现机制的消耗不同,相同的series数目所消耗的负载会比压测中高不少。

现有集群化方案

针对单机Prometheus在大规模数据监控时的性能瓶颈问题,社区目前已经存在一些分片化方案,主要包括以下几种。

hash_mod

Prometheus官方支持通过Relabel机制,在配置文件中,对采集上来的数据进行hash,通过在不同Prometheus实例的配置文件中指定不同的moduleID来进行分片化,然后通过联邦,Thanos等方式将数据进行统一汇总,如下图所示,读者也可以直接参考【官方文档】。
4

配置文件分割

还有一种方法是根据业务进行job层面的分割,不同Prometheus使用完全独立的采集配置,其中包含了不同的job,。
5

上述方案存在的问题

无论是hash_mod的方式,还是配置文件分割的方式,其本质都是将数据切分到多个采集配置中,由不同Prometheus进行采集。两者都存在以下几个缺点。

  • 对预监控数据要有所了解:使用上述方法的前提是使用者必须对监控对象会上报的数据有所了解,例如必须知道监控对象会上报某个用于hash_mod的label,或者必须知道不同job的整体规模,才能对job进行划分。
  • 实例负载不均衡:虽然上述方案预期都是希望将数据打散到不同Prometheus实例上,但实际上通过某些label的值进行hash_mod的,或者干脆按job进行划分的方式并不能保证每个实例最终所采集的series数是均衡的,实例依旧存在内存占用过高的风险。
  • 配置文件有侵入:使用者必须对原配置文件进行改造,加入Relabel相关配置,或者将一份配置文件划分成多份,由于配置文件不再单一,新增,修改配置难度大大增加。
  • 无法动态扩缩容:上述方案中的由于配置是根据实际监控目标的数据规模来特殊制定的,并没有一种统一的扩缩容方案,可以在数据规模增长时增加Prometheus个数。当然,用户如果针对自己业务实际情况编写扩缩容的工具确实是可以的,但是这种方式并不能在不同业务间复用。
  • 部分API不再正常:上述方案将数据打散到了不同实例中,然后通过联邦或者Thanos进行汇总,得到全局监控数据,但是在不额外处理的情况下会导致部分Prometheus 原生API无法得到正确的值,最典型的是/api/v1/targets ,上述方案下无法得到全局targets值。

Kvass的原理

设计目标

针对上述问题,我们希望设计一种无侵入的集群化方案,它对使用者表现出来的,是一个与原生Prometheus配置文件一致,API兼容,可扩缩容的虚拟Prometheus。具体而言,我们有以下设计目标。

  • 无侵入,单配置文件:我们希望使用者看到的,修改的都是一份原生的配置文件,不用加任何特殊的配置。
  • 无需感知监控对象:我们希望使用者不再需要预先了解采集对象,不参与集群化的过程。
  • 实例负载尽可能均衡:我们希望能根据监控目标的实际负载来划分采集任务,让实例尽可能均衡。
  • 动态扩缩容:我们希望系统能够根据采集对象规模的变化进行动态扩缩容,过程中数据不断点,不缺失。
  • 兼容核心PrometheusAPI:我们希望一些较为核心的API,如上边提到的/api/v1/target接口是正常的。

架构

Kvass由多个组件构成,下图给出了Kvass的架构图,我们在架构图中使用了Thanos,实际上Kvass并不强依赖于Thanos,可以换成其他TSDB。

  • Kvass sidecar: 用于接收Coordinator下发的采集任务,生成新的配置文件给Prometheus,也服务维护target负载情况。
  • Kvass coordinator: 该组件是集群的中心控制器,负责服务发现,负载探测,targets下发等。
  • Thanos 组件: 图中只使用了Thanos sidecar与Thanos query,用于对分片的数据进行汇总,得到统一的数据视图。

Coordinator

Kvass coordinaor 首先会代替Prometheus对采集目标做服务发现,实时获得需要采集的target列表。

针对这些target,Kvass coordinaor会负责对其做负载探测,评估每个target的series数,一旦target负载被探测成功,Kvass coordinaor 就会在下个计算周期将target分配给某个负载在阈值以下的分片。

Kvass coordinaor 还负责对分片集群做扩缩容。
7

服务发现

Kvass coordinaor引用了原生Prometheus的服务发现代码,用于实现与Prometheus 100%兼容的服务发现能力,针对服务发现得到的待抓取targets,Coordinaor会对其应用配置文件中的relabel_configs进行处理,得到处理之后的targets及其label集合。服务发现后得到的target被送往负载探测模块进行负载探测。

负载探测

负载探测模块从服务发现模块获得处理之后的targets,结合配置文件中的抓取配置(如proxy,证书等)对目标进行抓取,随后解析计算抓取结果,获得target的series规模。

负载探测模块并不存储任何抓取到的指标数据,只记录target的负载,负载探测只对target探测一次,不维护后续target的负载变化,长期运行的target的负载信息由Sidecar维护,我们将在后面章节介绍。

target分配与扩容

在Prometheus单机性能瓶颈那一节,我们介绍过Prometheus的内存和series相关,确切来说,Prometheus的内存和其head series直接相关。Prometheus 会将最近(默认为2小时)采集到的数据的series信息缓存在内存中,我们如果能控制好每个分片内存中head series的数目,就能有效控制每个分片的内存使用量,而控制head series实际就是控制分片当前采集的target列表。

基于上边的思路,Kvass coordinaor会周期性的对每个分片当前采集的target列表进行管理:分配新target,删除无效target。

在每个周期,Coordinaor会首先从所有分片获得当前运行状态,其中包括分片当前内存中的series数目及当前正在抓取的target列表。随后针对从服务发现模块得到的全局target信息进行以下处理

  • 如果该target已经被某个分片抓取,则继续分配给他,分片的series数不变。
  • 如果该target没有任何分片抓取,则从负载探测模块获得其series(如果还未探测完则跳过,下个周期继续),从分片中挑一个目前内存中series加上该target的series后依然比阈值低的,分配给他。
  • 如果当前所有分片没法容纳所有待分配的targets,则进行扩容,扩容数量与全局series总量成正比。

target迁移和缩容

在系统运行过程中,target有可能会被删除,如果某个分片的target被删除且超过2小时,则该分片中的head series就会降低,也就是出现了部分空闲,因为target分配到了不同分片,如果有大量target被删除,则会出现很多分片的内存占用都很低的情况,这种情况下,系统的资源利用率很低,我们需要对系统进行缩容。

当出现这种情时,Coordinaor会对target进行迁移,即将序号更大的分片(分片会从0进行编号)中的target转移到序号更低的分片中,最终让序号低的分片负载变高,让序号高的分片完全空闲出来。如果存储使用了thanos,并会将数据存储到cos中,则空闲分片在经过2小时候会删除(确保数据已被传到cos中)。

多副本

Kvass的分片当前只支持以StatefulSet方式部署。

Coordinator将通过label selector来获得所有分片StatefulSet,每个StatefulSet被认为是一个副本,StatefulSet中编号相同的Pod会被认为是同一个分片组,相同分片组的Pod将被分配相同的target并预期有相同的负载。
8

/api/v1/targets接口

上文提到Coordinator根据配置文件做了服务发现,得到了target列表,所以Coordinator实际上可以得到/api/v1/targets接口所需要的返回结果集合,但是由于Coordinator只做了服务发现,并不进行实际采集,所以target的采集状态(例如健康状态,上一次采集时间等)都无法直接得知。

当Coordinator接收到/api/v1/targets请求时,他会基于服务发现得到的target集合,结合向Sidecar(如果target已分配)或向探测模块(target还未分配)询问target采集状态,综合后将正确的/api/v1/targets结果返回。

Sidecar

上一节介绍了Kvass coordinaor的基本功能,要想系统正常运行,还需要Kvass sidecar的配合,其核心思想是将配置文件中所有服务发现模式全部改成static_configs并直接将已经relabel过的target信息写入配置中,来达到消除分片服务发现和relabel行为,只采集部分target的效果。
9

每个分片都会有一个Kvass sidecar,其核心功能包括从Kvass coordinator接受本分片负责的target列表,生成新的配置文件给该分片的Prometheus使用。另外,Kvass sidecar还会劫持抓取请求,维护target最新负载。Kvass sidecar还作为PrometheusAPI的网关,修正部分请求结果。
10

配置文件生成

Coordinaor经过服务发现,relabel及负载探测后,会将target分配给某个分片,并将target信息下发给Sidecar,包括

  • target的地址,
  • target预估的series值
  • target的hash值
  • 处理完relabel之后的label集合。

Sidecar根据从Coordinator得到的target信息,结合原始配置文件,生成一个新的配置文件给Prometheus使用,这个新的配置文件做了如下改动。

  • 将所有服务发现机制改为static_configs模式,并直接写入target列表,每个target包含经过relabel之后的label值
  • 由于现在target已经relabel过了,所以删除job配置中的relabel_configs项,但是依旧保留metrics_rebale_configs
  • 将target的label中的scheme字段全部替换成http,并将原schme以请求参数的形式加入到label集合中
  • 将target的job_name以请求参数的形式加入到label集合中* 注入proxy_url将所有抓取请求代理到Sidecar

11

我们来看一个例子,假如原来的配置是一个kubelet的采集配置

global:
  evaluation_interval: 30s
  scrape_interval: 15s
scrape_configs:
- job_name: kubelet
  honor_timestamps: true
  metrics_path: /metrics
  scheme: https
  kubernetes_sd_configs:
  - role: node
  bearer_token: xxx
  tls_config:
    insecure_skip_verify: true
  relabel_configs:
  - separator: ;
    regex: __meta_kubernetes_node_label_(.+)
    replacement: $1
    action: labelmap

通过注入将生成一个新的配置文件

global:
  evaluation_interval: 30s
  scrape_interval: 15s
scrape_configs:
- job_name: kubelet                                        
  honor_timestamps: true                                                                      
  metrics_path: /metrics                                   
  scheme: https  
  proxy_url: http://127.0.0.1:8008 # 所有抓取请求代理到Sidecar
  static_configs:                                          
  - targets:                                               
    - 111.111.111.111:10250                                   
    labels:                                                
      __address__: 111.111.111.111:10250                      
      __metrics_path__: /metrics                           
      __param__hash: "15696628886240206341"                
      __param__jobName: kubelet                            
      __param__scheme: https  # 保存原始的scheme                             
      __scheme__: http        # 设置新的scheme,这将使得代理到Sidecar的抓取请求都是http请求
      # 以下是经过relabel_configs处理之后得到的label集合
      beta_kubernetes_io_arch: amd64                       
      beta_kubernetes_io_instance_type: QCLOUD             
      beta_kubernetes_io_os: linux                         
      cloud_tencent_com_auto_scaling_group_id: asg-b4pwdxq5
      cloud_tencent_com_node_instance_id: ins-q0toknxf     
      failure_domain_beta_kubernetes_io_region: sh         
      failure_domain_beta_kubernetes_io_zone: "200003"     
      instance: 172.18.1.106                               
      job: kubelet                                         
      kubernetes_io_arch: amd64                            
      kubernetes_io_hostname: 172.18.1.106                 
      kubernetes_io_os: linux

上边新生成的配置文件是Prometheus真正使用的配置文件,Sidecar通过Coordinator下发的target列表来生成配置,就可以让Prometheus有选择性得进行采集。

抓取劫持

在上边的配置生成中,我们会将proxy注入到job的配置中,并且target的label中,scheme会被设置成http,所以Prometheus所有的抓取请求都会被代理到Sidecar,之所以要这么做,是因为Sidecar需要维护每个target新的series规模,用于Coordinator查阅后作为target迁移的参考。

从上边配置生成我们可以看到,有以下几个额外的请求参数会被一并发送到Sidecar

  • hash:target的hash值,用于Sidecar识别是哪个target的抓取请求,hash值由Coordinator根据target的label集合进行计算获得并传递给Sidecar。
  • jobName:是哪个job下的抓取请求,用于Sidecar根据原配置文件中job的请求配置(如原proxy_url,证书等)对抓取目标发起真正的请求。
  • scheme:这里的scheme是target通过relabel操作之后最终得到的协议值,虽然在job配置文件中已经有scheme字段,但Prometheus配置文件依旧支持通过relabel指定某个target的请求协议。在上述生成新配置过程中,我们将真实的scheme保存到这个参数里,然后将scheme全部设置成http。

有了上述几个参数,Sidecar就可以对抓取目标发起正确的请求,并得到监控数据,在统计的target这次抓取的series规模后,Sidecar会将监控数据拷贝一份给Prometheus。

API代理

由于Sidecar的存在,部分发往Prometheus的API请求需要被特殊处理,包括

  • /-/reload:由于Prometheus真正使用的配置文件由Sidecar生成,针对该接口,需要由Sidecar去处理并在处理成功后调用Prometheus的/-/reload接口。
  • /api/v1/status/config:该接口需要由Sidecar处理并把原配置文件返回。
  • 其他接口直接发往Prometheus。

全局数据视图

由于我们将采集目标分散到了不同分片中,导致每个分片的数据都只是全局数据的一部分,所以我们需要使用额外的组件来将所有数据进行汇总并去重(多副本的情况下),得到全局数据视图。

以thanos为例

thanos是一个非常好的方案,通过加入thanos组件,可以很方便得得到kvass集群的全局数据视图。当然我们也可以通过加入remote writer配置来使用其他TSDB方案,例如influxdb,M3等等。

使用例子

这一节我们通过一个部署例子,来直观感受一下Kvass的效果,相关yaml文件可以在这里找到https://github.com/tkestack/k...
读者可以将项目clone到本地,并进入examples。

git clone https://github.com/tkestack/kvass.git
cd kvass/examples

部署数据生成器

我们提供了一个metrics数据生成器,可以指定生成一定数量的series,在本例子中,我们将部署6个metrics生成器副本,每个会生成10045 series (其中45 series为golang的metrics)。

kubectl create -f  metrics.yaml

部署kvass

现在我们部署基于Kvass的Prometheus集群,用以采集这6个metrics生成器的指标。

首先我们部署rbac相关配置

kubectl create -f kvass-rbac.yaml

接着部署一个Prometheus config文件,这个文件就是我们的原始配置,我们在这个配置文件中,使用kubernetes_sd来做服务发现

kubectl create -f config.yaml

配置如下

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    cluster: custom
scrape_configs:
- job_name: 'metrics-test'
  kubernetes_sd_configs:
    - role: pod
  relabel_configs:
  - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
    regex: metrics
    action: keep
  - source_labels: [__meta_kubernetes_pod_ip]
    action: replace
    regex: (.*)
    replacement: ${1}:9091
    target_label: __address__
  - source_labels:
    - __meta_kubernetes_pod_name
    target_label: pod

现在我们来部署Kvass coordinator

kubectl create -f coordinator.yaml

我们在Coordinator的启动参数中设置每个分片的最大head series数目不超过30000

--shard.max-series=30000

我们现在就可以部署带有Kvass sidecar的Prometheus了,这里我们只部署单个副本

kubectl create -f prometheus-rep-0.yaml

部署thanos-query

为了得到全局数据,我们需要部署一个thanos-query

kubectl create -f thanos-query.yaml

查看结果

根据上述计算,监控目标总计6个target, 60270 series,根据我们设置每个分片不能超过30000 series,则预期需要3个分片。

我们发现,Coordinator成功将StatefulSet的副本数改成了3。
14

我们看下单个分片内存中的series数目,发现只有2个target的量
15

我们再通过thanos-query来查看全局数据,发现数据是完整的(其中metrics0为指标生成器生成的指标名)
16

17

云原生监控

腾讯云容器团队在Kvass的设计思想上进一步优化,构建了高性能支持多集群云原生监控服务,产品目前已正式公测。

大集群监控

这一节我们就直接使用云原生监控服务来监控一个规模较大的真实集群,测试一下Kvass监控大集群的能力。
18

集群规模

我们关联的集群规模大致如下

  • 1060个节点
  • 64000+ Pod
  • 96000+ container

采集配置

我们直接使用云原生监控服务在关联集群默认添加的采集配置,目前已包含了社区主流的监控指标:

  • kube-state-metrics
  • node-exporer
  • kubelet
  • cadvisor
  • kube-apiserver
  • kube-scheduler
  • kube-controler-manager

19

20

测试结果

21

  • 总计3400+target, 2700+万series
  • 总计扩容了17个分片
  • 每个分片series稳定在200w以下
  • 每个分片消耗内存在6-10G左右

云原生监控所提供的默认Grafana面板也能正常拉取
22

targets列表也能正常拉取
23

多集群监控

值得一提的是,云原生监控服务不仅支持监控单个大规模集群,还可以用同个实例监控多个集群,并支持采集和告警模板功能,可一键将采集告警模板下发至各地域各个集群,彻底告别了每个集群重复添加配置的问题。
24

总结

本文从问题分析,设计目标,原理剖析,使用案例等方面详细介绍了一种开源Prometheus集群化技术,可在不修改Prometheus代码的前提下使其支持横向扩缩容,从而监控单机Prometheus无法监控的大规模集群。

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 1 收藏 1 评论 0

腾讯云原生 发布了文章 · 11月19日

腾讯云容器服务 TKE 推出新一代零损耗容器网络

随着容器技术的发展成熟,越来越多的组件迁移到容器,在技术迁移过程中,数据库,游戏,AI 这些组件对容器网络性能(时延,吞吐,稳定性)提出了更高的要求。为了得到更优的时延和吞吐表现,各大云厂商都在致力于缩短节点内容器的网络访问链路,让数据包能尽可能快地转发到容器网卡。

腾讯云容器服务 TKE 借助智能网卡推出下一代容器网络方案,该方案实现了一个 Pod 独占一张弹性网卡,不再经过节点网络协议栈(default namespace),极大缩短了容器访问链路,缩短了访问时延,并使 PPS 可以达到整机上限。该方案实现了短链接场景下 QPS 相比之前容器网络方案(策略路由方案,网桥方案)提升 50%-70%;长链接场景下 QPS 提升 40%-60%。

由于不再经过节点网络协议栈,传统基于 iptables 和 IPVS 的 ClusterIP service 访问方案不能直接适用于该方案。为了实现该方案下 Pod 可以直接访问 ClusterIP service,TKE 推出 share-NS IPVS 方案,使得在容器网络命名空间下也可以访问到节点网络协议栈的 IPVS 规则,同时配合 CLB 直通 Pod,实现了完整意义上的弹性网卡直通。

该方案实现了针对 ClusterIP service 短链接场景下 QPS 相比 iptables 方案提升 40%-60%,IPVS 方案提升 70%-90%;长链接场景下 QPS 相比 iptables 方案提升 30%-50%,IPVS 方案提升 50%-70%。

新一代容器网络方案推出背景

在介绍新一代容器网络方案前,先和大家介绍一下 TKE 现有网络方案,和现有网络方案面临的挑战,以及客户新诉求。

现有网络方案介绍

腾讯云容器服务 TKE 目前提供了两种容器网络模式可供用户选择使用。

GlobalRouter 模式:基于 vpc 实现的全局路由模式, 目前是 TKE 默认网络方案。该模式依托于 vpc 底层路由能力,不需要在节点上配置 vxlan 等 overlay 设备,就可以实现容器网络 和 vpc 网络的互访,并且相比于 calico/flannel 等网络方案,因为没有额外的解封包,性能也会更好。

VPC-CNI 模式: TKE 基于 CNI 和 VPC 弹性网卡实现的容器网络能力,适用于 Pod 固定 IP,CLB 直通 Pod,Pod 直绑 EIP 等场景。该网络模式下,容器与节点分布在同一网络平面,容器 IP 为 IPAMD 组件所分配的弹性网卡 IP。

GlobalRouter 和 VPC-CNI 模式目前已服务 TKE 上万企业用户, 两种网络模式也存在一定使用限制见:如何选择TKE网络模式,随着客户使用场景的丰富, TKE 的客户对容器网络又提出了更高的要求。

客户对 TKE 网络方案的新需求

除了在为腾讯外部 TKE 客户提供容器网络能力之外,腾讯云容器服务 TKE 作为腾讯内部业务云原生的底座,在支持腾讯内部自研业务上云如 QQ、腾讯会议、游戏、CDB、大数据等业务的过程中也收到以下的需求点:

  • 在 VPC-CNI 模式的基础上进一步降低资源损耗,降低网络时延,提高网络吞吐(关键点)
  • 支持 Pod 级别的安全隔离
  • 支持 CLB 直通Pod,不再经过 NodePort 转发,提升转发性能并拥有统一的负载均衡视图

基于以上场景,TKE 团队联合底层腾讯云 VPC 团队、虚拟化团队推出了新一代的独立网卡的 VPC-CNI 方案。

TKE新一代网络方案介绍

TKE 新一代网络方案在原有 VPC-CNI 模式单网卡多 IP 模式的基础上, 进阶为容器直接独享使用弹性网卡,无缝对接腾讯云私有网络产品的全部功能,同时在性能做了极大的提升(详情见下文性能介绍)。

压测数据说明

  • 为了得到不同网络方案下的 QPS,这里控制变量,让不同网络方案的 nginx Pod 运行在同一个节点,使用 wrk 分别压测不同 Pod,并让服务端节点的 cpu 接近100%。

  • 为了得到不同 Service 方案下的 QPS,这里控制变量,让 kube-proxy 和 wrk Pod 运行在同一节点,压测相同后端,并让客户端节点的 cpu 接近100%。

功能简介

新一代 VPC-CNI 模式的网络方案中,能够在原有的网络能力中额外增加

  1. 支持 Pod 绑定 EIP/NAT,不再依赖节点的外网访问能力,无须做 SNAT,可以满足直播、游戏、视频会议等高并发,高带宽外网访问场景
  2. 支持 Pod 绑定安全组,实现 Pod 级别的安全隔离
  3. 支持基于 Pod 名称的固定 IP,Pod 重新调度后仍能保证 IP 不变
  4. 支持 CLB 直通 Pod,不再经过 NodePort 转发,提升转发性能并拥有统一的负载均衡视图
  5. 即将支持黑石 2.0物理服务器(推荐使用, 默认使用智能网卡,网络性能更高)
  6. 即将支持基于 Pod 名称的固定 EIP,满足 Pod 固定外网出口

使用方法

申请新一代容器网络方案内测开通后,创建 TKE 集群时容器网络模式选择 VPC-CNI/Pod 独立网卡模式即可:

实现原理简介

新一代方案在原有 VPC-CNI 模式的基础上扩展,依托于弹性网卡,将绑定到节点的弹性网卡通过 CNI 配置到容器网络命名空间,实现容器直接独享使用弹性网卡。

您可以关注腾讯云原生公众号,后续将会推送 TKE 新一代网络方案实现的技术细节

当前内测阶段使用限制

  1. 仅支持部分 S5 的机型使用该网络模式。
  2. 节点上运行的 Pod 数量限制为节点核数的5倍。
  3. 仅支持新集群,存量 TKE 集群暂不支持变更网络方案。

TKE新一代网络方案内测邀请

我们诚挚邀请您参与腾讯云下一容器独立网卡网络方案产品能力的内测, 您可以通过以下链接提交内测申请:https://cloud.tencent.com/app...

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 1 收藏 0 评论 0

腾讯云原生 发布了文章 · 11月12日

【有奖征文】会容器,Docker,K8s,Istio等的人看过来啦!

你对Docker, K8s,微服务,边缘容器等等各种云原生技术感兴趣吗?

你想和更多同行分享你对云原生技术的独特见解吗?

快来参与腾讯云原生有奖征文活动吧!Cherry机械键盘,Airpodspro等你拿!

腾讯云原生面向广大云原生技术爱好者推出征文计划,凡符合活动规则并通过征选的文稿,将会被发布在腾讯云原生的微信公众号及各大社区相关专栏。参与便有机会获取精美周边礼品哦!

活动评奖数据统计时间:2020年11月3日-12月25日15点截止

文章评审:11月10日-12月23日期间持续进行,每篇文稿预计评审时间为3天,审核通过后会联系作者并排期发布。

结果公布:主办方将于12月30日根据统计的总阅读数公布获奖结果

参与方式:个人撰文或多人团队合作出品皆可

投稿方式:点击 这里 提交你的文稿。

征文规则:

1.内容要求:文章内容必须保证原创性,且需通过腾讯云原生公众号首次对外发布,一经发现侵权行为,取消活动参与资格。

2.内容范围:基于腾讯云容器服务TKE、弹性容器EKS、服务网格TCM、容器服务私有云TKEStack、边缘容器TKE@edge、容器镜像TCR等产品技术内容,具体方向包括但不限于以下:

  1. 产品学习/使用攻略
  2. 应用案例分享
  3. 技术架构解析/优化
  4. 行业趋势见解及总结
  5. 问题及解决方案分享
  6. CODING+TKE的最佳实践

3.内容规范:文章内容字数不少于600字,且要求文字通顺、图片清晰、代码规范,文章逻辑及层次清晰,阅读时长建议在8-15分钟之间

4.作者权利:参与征文活动的文章作者拥有著作权,腾讯云原生所有官号拥有使用权。

5.推广福利:所有成功被征选的文章将会获得腾讯云原生微信公众号及其在相关技术社区的渠道推广资源

6. 评选规则:评选规则:评奖按照12月25日15点截止的【总阅读数】进行排名。总阅读数=微信文章底部阅读数+点赞数+在看数。1点赞数=10个阅读数,1在看数=10个点赞数。

腾讯云原生有权根据自身运营安排,自主决定和调整本活动的具体规则,具体活动规则以活动页面规则为准。相关规则一经公布即产生效力,参与者应当予以遵守。

参考资料:

[1] 腾讯云容器产品体验登录网址:https://console.cloud.tencent...

[2] CODING产品体验网址:https://coding.net/products/cd

[3] 参考范文1:《TKE基于弹性网卡直连Pod的网络负载均衡》https://mp.weixin.qq.com/s/fJ...

[4] 参考范文2:《揭秘日活千万腾讯会议全量云原生化上TKE技术实践》https://mp.weixin.qq.com/s/LQ...

[5] 参考范文3:《大型Kubernetes集群的资源编排优化》

https://mp.weixin.qq.com/s/lY...

[6] 参考范文4:《大数据平台是否更应该容器化?》

https://mp.weixin.qq.com/s/kK...

[7] 参考范文5:《Istio 运维实战系列(1):应用容器对 Envoy Sidecar 的启动依赖问题》

https://mp.weixin.qq.com/s/iX...

[8] 参考范文6:《CD+服务网格灰度发布实践,一文带你体验如何编排更灵活》

https://mp.weixin.qq.com/s/9q...

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 0 收藏 0 评论 0

腾讯云原生 发布了文章 · 11月12日

容器场景要选择什么 Linux 版本?

容器的底层实现深度依赖于内核的众多特性,如 overlay 文件系统,namespace, cgroup 等,因此内核的功能和稳定性,在很大程度上,决定了整个容器PaaS平台的功能和稳定性。从 TKE 上线三年多以来,上万集群,数十万个节点的运营经验来看,内核问题约占所有节点问题的三分之一。

那么容器场景选择哪个Linux版本最好呢?在腾讯云,这个答案是 Tencent Linux

这时候大家应该会有很多的疑问,接下来的 FAQ 会尽力解答大家的疑问。

Tencent Linux是谁维护的? 基于什么发行版的?

是腾讯内核和虚拟化团队负责维护的。Tencent Linux 2.4 基于CentOS 7, 用户态软件包保持与最新版 CentOS 7 兼容,CentOS 7 版本的软件包可以直接在 Tencent Linux 2.4 中使用

Tencent Linux跟CentOS有什么区别?

关键的区别在内核版本,本文后面会详细介绍。 用户态有少量调整,如 YUM 源的配置等,详情请参考官方介绍文档:https://cloud.tencent.com/doc...

内核是什么版本?

Tencent Linux 2.4 目前是4.14内核。
代码和 rpm 包在 GitHub 可以获取: https://github.com/Tencent/Te...
年底会推出5.4版本。

Tencent Linux跟TKE的Optimized镜像是什么关系?

它们的内核是一样的,但Tencent Linux 2.4 是CVM公共镜像, TKE Optimized镜像是市场镜像。

TKE将使用Tencent Linux2.4来替代CentOS 7.6 TKE Optimized以及Ubuntu18.04 TKE Optimized。已经在使用CentOS 7.6 TKE OptimizedUbuntu18.04 TKE Optimized的集群还可以继续使用,但以后新建集群将不再支持这两种镜像。

预计11月下旬起,TKE用户可以自行在控制台操作,将集群新创建的节点的OS镜像切换为Tencent Linux2.4,操作入口如下图(把操作系统修改为Tencent Linux2.4):

相比 CentOS 和 Ubuntu 等发行版有什么优势?

主要优势如下, 后文会详细介绍:

  1. 经过腾讯大量内部业务多年的验证和打磨。
  2. 顶级内核专家团队的支持。
  3. 包含一些关键的性能优化和针对容器场景的定制特性。

腾讯内部业务多年的验证和打磨

Tencent Linux 从 2010 年启动研发,在腾讯内部已经上线运营了 10 年,总部署量已经是百万级,在腾讯内部 Linux 系统里占比 99%,覆盖了腾讯所有的业务,同时腾讯有着国内最种类繁多的业务生态,从社交,游戏,到金融支付,AI, 安全等, 所以对底层操作系统的稳定性,性能,兼容性等都有更强的要求。

对于容器场景来讲,腾讯大量核心业务几乎已经部分或全部容器化,例如微信所有的逻辑业务全部容器化, 针对微信业务特点,进行系列优化,顺利保障了每年春节的红包高峰运营,同时在数据安全方面,也跟微信紧密合作,提供解决方案。

内核专家团队的支持

目前有三十多位全职内核专家为这个内核版本提供支持。其中有 kvm 维护者,还有很多内核网络,存储,cgroup,调度等各个子系统的专家。

支持力度也体现在版本更新节奏和热补丁服务。

从版本记录(https://github.com/Tencent/Te... 可以看到,从 7 月到 10 月, Tencent Linux 4.14 内核系列发布了 5 个版本。腾讯内部业务和腾讯云外部客户碰到的绝大多数问题,都能及时得到定位和修复。

另外我们针对一些重要的修复,会提供内核热补丁的在线修复方式。热补丁的安装和生效,不需要重启机器,在不中断客户业务的情况下,提升客户业务的时延 SLA。

对于漏洞修复,Tencent Linux 有着全套的热补丁方案,包括:应用程序级热补丁,内核级热补丁等。每年发布 100 多个热补丁。 大多数漏洞在一周内提供修复方案。

性能优化

Tecent Linux 在根据内部与外部的用户在大规模落地实践中遇到的问题,针对容器场景也做了大量性能优化,包括但不限于:

  1. 解决 IPVS 模式高并发场景下,连接复用引发连接异常的问题 (#81775)。
  2. 解决 IPVS 模式在高配节点 (核数多) 下 IPVS 规则过多引发网络毛刺的问题。
  3. 解决在容器密集场景下(单节点上容器数量较多),cAdvisor 读取 memcg 陷入内核态过久引发网络毛刺的问题。
  4. 解决大 Pod (占用核数多,单核占用高) 在高配节点 (核数多) 场景下,CPU 负载均衡引发网络毛刺的问题。
  5. 解决高并发场景下的 TCP 连接监控(比如单独部署 cAdvisor 配置监控 TCP 连接) 引发网络周期性抖动问题。
  6. 优化网络收包软中断,提升网络性能。

这些针对各种容器场景的优化效果非常显著,以第 3 点为例,ping 时延监控效果图如下 (11:00 之后是优化后):

容器定制特性

容器资源展示隔离

很多 golang, java 程序的高效运行依赖于正确获取进程可用的 CPU 和内存资源。但这类程序在容器中获取到的是节点的 CPU 和内存资源, 与实际容器所分配的资源并不匹配,往往会造成进程的线程池等参数不合理,从而带来问题。

社区主流的解决方案是通过部署 FUSE 实现的 LXCFS 来实现/proc/cpuinfo, /proc/meminfo等资源展示按容器隔离。这个方案需要在节点部署 LXCFS 文件系统, 也需要往 POD sepc 中插入相关 volume 和挂载点的配置。详情可以参考:Kubernetes Demystified: Using LXCFS to Improve Container Resource Visibility

Tencnet Linux内核中实现了类似 LXCFS 特性,用户无需在节点部署 LXCFS 文件系统, 也无需修改 POD spec。只需在节点开启一个全局开关(sysctl -w kernel.stats_isolated=1), 容器中读取 /proc/cpuinfo, /proc/meminfo 等文件获取的就是按容器隔离的,就是这么简单。

另外,考虑到有些特殊容器, 比如节点监控组件, 可能就是需要读取节点级的信息。为了解决这个问题,专门增加了容器级的开关kernel.container_stats_isolated。在主机级开关开启的情况下,只需要在容器的启动脚本里面,关闭容器级的开关(sysctl -w kernel.container_stats_isolated=0),以后在这个容器里面读取 /proc/cpuinfo, /proc/meminfo 等文件获取的就是主机的信息了。(注: 容器级开关必须在容器中设置,才能对本容器生效)

请参考详细使用文档:容器内CPU、内存、进程、磁盘等信息隔离

更多内核参数的隔离

  • net.ipv4.tcp_max_orphans
  • net.ipv4.tcp_workaround_signed_windows
  • net.ipv4.tcp_rmem
  • net.ipv4.tcp_wmem
  • vm.max_map_count

这些内核参数都是业务经常需要定制修改的。但是社区内核里面并没有对这些参数做 namespace 化隔离。一个容器对以上参数的修改,会对主机以及所有其他容器都起作用。 Tencent Linux根据内外部客户的需求,实现了这些内核参数的 namespace 化隔离,业务容器可以放心的对这些参数进行个性化设置而不用担心对其他业务的干扰了。

容器缺省内核参数优化

在高并发的情况下,可能会发生半连接队列满而丢包, 可以通过调大 net.core.somaxconn 来缓解问题。但是容器网络 namespace 里面的 net.core.somaxconn 缺省值只有 128,而且是代码写死的。 在 Tencent Linux 内核中,我们把这个缺省值调整到 4096, 从而可以减少高并发情况下半连接队列满的丢包问题。

在 TKE 如何使用 Tencent Linux

如果希望 TKE 集群的节点使用 Tencent Linux 的操作系统,需要在创建 TKE 集群时,操作系统选择 Tencent Linux 的:

注: Tencent Linux 除了支持普通的云服务器机型外,还支持黑石物理机与 Nvidia GPU 的机型。

参考资料

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 0 收藏 0 评论 0

腾讯云原生 发布了文章 · 11月9日

手把手教你使用容器服务 TKE 集群审计排查问题

概述

有时候,集群资源莫名被删除或修改,有可能是人为误操作,也有可能是某个应用的 bug 或恶意程序调用 apiserver 接口导致,需要找出 "真凶"。这时候,我们需要为集群开启审计,记录 apiserver 的接口调用,然后根据条件检索和分析审计日志来找到原因。

关于 TKE 的集群审计简介与基础操作,请参考官方文档 集群审计。因为集群审计的数据存储在日志服务,所以我们需要在日志服务控制台去对审计结果进行检索和分析,检索语法请参考 日志检索语法与规则,要进行分析就还需要写日志服务所支持的 SQL 语句,请参考 日志服务分析简介

注: 本文仅适用于 TKE 集群

场景示例

下面给出一些集群审计使用场景和查询的示例。

找出是谁做的操作

如果节点被封锁了,不知道是哪个应用或人为操作的,需要查出来,可以在开启集群审计后,使用下面的语句来检索:

objectRef.resource:nodes AND requestObject:unschedulable

版面设置可以设置显示 user.username, requestObjectobjectRef.name 三个字段,分别表示做操作的用户、请求内容以及节点名称:

img

从上图可以看出,是 10001****958 这个子账号在 2020-10-09 16:13:22 的时候对 main.63u5qua9.0 这台节点进行了封锁操作,我们在 访问管理-用户-用户列表 里可以根据账号 ID 找到关于这个子账号的详细信息。

如果某个工作负载被删除,想知道是谁删除的,这里以 deployments/nginx 为例来查询:

objectRef.resource:deployments AND objectRef.name:"nginx" AND verb:"delete"

查询结果:

img

揪出导致 apiserver 限频的真凶

apiserver 会有默认的请求频率限制保护,避免恶意程序或 bug 导致对 apiserver 请求频率过高,使得 apiserver/etcd 负载过高,影响正常请求。如果发生了限频,我们可以通过审计来找出到底是谁在发大量请求。

如果我们通过 userAgent 来分析统计请求的客户端,首先需要修改下日志主题的键值索引,为 userAgent 字段开启统计:

img

通过以下 SQL 语句进行统计每种客户端请求 apiserver 的 QPS 大小:

* | SELECT CAST((__TIMESTAMP_US__ /1000-__TIMESTAMP_US__ /1000%1000) as TIMESTAMP) AS time, COUNT(1) AS qps,userAgent GROUP BY time,userAgent ORDER BY time

切换到图标分析,选择折线图,X 轴用 time,Y 轴用 qps,聚合列使用 userAgent:

img

可以看到查到数据了,但可能结果太多,小面板显示不下,点击添加到仪表盘,放大显示:

img

此例中可以看到 kube-state-metrics 这个客户端对 apiserver 请求频率远远高于其它客户端,这就找到了 "真凶" 是 kube-state-metrics,查看日志可以发现是因为 RBAC 权问题导致 kube-state-metrics 不停的请求 apiserver 重试,触发了 apiserver 的限频:

I1009 13:13:09.760767       1 request.go:538] Throttling request took 1.393921018s, request: GET:https://172.16.252.1:443/api/v1/endpoints?limit=500&resourceVersion=1029843735
E1009 13:13:09.766106       1 reflector.go:156] pkg/mod/k8s.io/client-go@v0.0.0-20191109102209-3c0d1af94be5/tools/cache/reflector.go:108: Failed to list *v1.Endpoints: endpoints is forbidden: User "system:serviceaccount:monitoring:kube-state-metrics" cannot list resource "endpoints" in API group "" at the cluster scope

同理,如果要使用其它字段来区分要统计的客户端,可以根据需求灵活修改 SQL,比如使用 user.username 来区分,SQL 这样写:

* | SELECT CAST((__TIMESTAMP_US__ /1000-__TIMESTAMP_US__ /1000%1000) as TIMESTAMP) AS time, COUNT(1) AS qps,user.username GROUP BY time,user.username ORDER BY time

显示效果:

img

小结

本文介绍了如何利用 TKE 的集群审计功能来辅助我们排查问题,给出了一些实践的例子。

参考资料

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 0 收藏 0 评论 0

腾讯云原生 发布了文章 · 11月6日

使用 Iceberg on Kubernetes 打造新一代云原生数据湖

背景

大数据发展至今,按照 Google 2003年发布的《The Google File System》第一篇论文算起,已走过17个年头。可惜的是 Google 当时并没有开源其技术,“仅仅”是发表了三篇技术论文。所以回头看,只能算是揭开了大数据时代的帷幕。随着 Hadoop 的诞生,大数据进入了高速发展的时代,大数据的红利及商业价值也不断被释放。现今大数据存储和处理需求越来越多样化,在后 Hadoop 时代,如何构建一个统一的数据湖存储,并在其上进行多种形式的数据分析,成了企业构建大数据生态的一个重要方向。怎样快速、一致、原子性地在数据湖存储上构建起 Data Pipeline,成了亟待解决的问题。并且伴随云原生时代到来,云原生天生具有的自动化部署和交付能力也正催化这一过程。本文就主要介绍如何利用 Iceberg 与 Kubernetes 打造新一代云原生数据湖。

何为 Iceberg

Apache Iceberg is an open table format for huge analytic datasets. Iceberg adds tables to Presto and Spark that use a high-performance format that works just like a SQL table.

Apache Iceberg 是由 Netflix 开发开源的,其于2018年11月16日进入 Apache 孵化器,是 Netflix 公司数据仓库基础。Iceberg 本质上是一种专为海量分析设计的表格式标准,可为主流计算引擎如 Presto、Spark 等提供高性能的读写和元数据管理能力。Iceberg 不关注底层存储(如 HDFS)与表结构(业务定义),它为两者之间提供了一个抽象层,将数据与元数据组织了起来。

Iceberg 主要特性包括:

  • ACID:具备 ACID 能力,支持 row level update/delete;支持 serializable isolation 与 multiple concurrent writers
  • Table Evolution:支持 inplace table evolution(schema & partition),可像 SQL 一样操作 table schema;支持 hidden partitioning,用户无需显示指定
  • 接口通用化:为上层数据处理引擎提供丰富的表操作接口;屏蔽底层数据存储格式差异,提供对 Parquet、ORC 和 Avro 格式支持

依赖以上特性,Iceberg 可帮助用户低成本的实现 T+0 级数据湖。

Iceberg on Kubernetes

传统方式下,用户在部署和运维大数据平台时通常采用手动或半自动化方式,这往往消耗大量人力,稳定性也无法保证。Kubernetes 的出现,革新了这一过程。Kubernetes 提供了应用部署和运维标准化能力,用户业务在实施 Kubernetes 化改造后,可运行在其他所有标准 Kubernetes 集群中。在大数据领域,这种能力可帮助用户快速部署和交付大数据平台(大数据组件部署尤为复杂)。尤其在大数据计算存储分离的架构中,Kubernetes 集群提供的 Serverless 能力,可帮助用户即拿即用的运行计算任务。并且再配合离在线混部方案,除了可做到资源统一管控降低复杂度和风险外,集群利用率也会进一步提升,大幅降低成本。

我们可基于 Kubernetes 构建 Hadoop 大数据平台:

在近几年大热的数据湖领域,通过传统 Hadoop 生态构建实时数据湖,受制于组件定位与设计,较为复杂与困难。Iceberg 的出现使得依赖开源技术快速构建实时数据湖成为可能,这也是大数据未来发展方向 - 实时分析、仓湖一体与云原生。引入 Iceberg 后,整体架构变为:

Kubernetes 负责应用自动化部署与资源管理调度,为上层屏蔽了底层环境复杂性。Iceberg + Hive MetaStore + HDFS 实现了基于 Hadoop 生态的实时数据湖,为大数据应用提供数据访问及存储。Spark、Flink 等计算引擎以 native 的方式运行在 Kubernetes 集群中,资源即拿即用。与在线业务混部后,更能大幅提升集群资源利用率。

如何构建云原生实时数据湖

架构图

  • 资源层:Kubernetes 提供资源管控能力
  • 数据层:Iceberg 提供 ACID、table 等数据集访问操作能力
  • 存储层:HDFS 提供数据存储能力,Hive MetaStore 管理 Iceberg 表元数据,Postgresql 作为 Hive MetaStore 存储后端
  • 计算层:Spark native on Kubernetes,提供流批计算能力

创建 Kubernetes 集群

首先通过官方二进制或自动化部署工具部署 Kubernetes 集群,如 kubeadm,推荐使用腾讯云创建 TKE 集群

推荐配置为:3 台 S2.2XLARGE16(8核16G)实例

部署 Hadoop 集群

可通过开源 Helm 插件或自定义镜像在 Kubernetes 上部署 Hadoop 集群,主要部署 HDFS、Hive MetaStore 组件。在腾讯云 TKE 中推荐使用 k8s-big-data-suite 大数据应用自动化部署 Hadoop 集群。

k8s-big-data-suite 是我们基于生产经验开发的大数据套件,可支持主流的大数据组件在 Kubernetes 上一键部署。部署之前请先按照要求做集群初始化:

# 标识存储节点,至少三个
$ kubectl label node xxx storage=true

部署成功后,连入 TKE 集群查看组件状态:

$ kubectl  get po
NAME                                                   READY   STATUS      RESTARTS   AGE
alertmanager-tkbs-prometheus-operator-alertmanager-0   2/2     Running     0          6d23h
cert-job-kv5tm                                         0/1     Completed   0          6d23h
elasticsearch-master-0                                 1/1     Running     0          6d23h
elasticsearch-master-1                                 1/1     Running     0          6d23h
flink-operator-controller-manager-9485b8f4c-75zvb      2/2     Running     0          6d23h
kudu-master-0                                          2/2     Running     2034       6d23h
kudu-master-1                                          2/2     Running     0          6d23h
kudu-master-2                                          2/2     Running     0          6d23h
kudu-tserver-0                                         1/1     Running     0          6d23h
kudu-tserver-1                                         1/1     Running     0          6d23h
kudu-tserver-2                                         1/1     Running     0          6d23h
prometheus-tkbs-prometheus-operator-prometheus-0       3/3     Running     0          6d23h
superset-init-db-g6nz2                                 0/1     Completed   0          6d23h
thrift-jdbcodbc-server-1603699044755-exec-1            1/1     Running     0          6d23h
tkbs-admission-5559c4cddf-w7wtf                        1/1     Running     0          6d23h
tkbs-admission-init-x8sqd                              0/1     Completed   0          6d23h
tkbs-airflow-scheduler-5d44f5bf66-5hd8k                1/1     Running     2          6d23h
tkbs-airflow-web-84579bc4cd-6dftv                      1/1     Running     2          6d23h
tkbs-client-844559f5d7-r86rb                           1/1     Running     6          6d23h
tkbs-controllers-6b9b95d768-vr7t5                      1/1     Running     0          6d23h
tkbs-cp-kafka-0                                        3/3     Running     2          6d23h
tkbs-cp-kafka-1                                        3/3     Running     2          6d23h
tkbs-cp-kafka-2                                        3/3     Running     2          6d23h
tkbs-cp-kafka-connect-657bdff584-g9f2r                 2/2     Running     2          6d23h
tkbs-cp-schema-registry-84cd7cbdbc-d28jk               2/2     Running     4          6d23h
tkbs-grafana-68586d8f97-zbc2m                          2/2     Running     0          6d23h
tkbs-hadoop-hdfs-dn-6jng4                              2/2     Running     0          6d23h
tkbs-hadoop-hdfs-dn-rn8z9                              2/2     Running     0          6d23h
tkbs-hadoop-hdfs-dn-t68zq                              2/2     Running     0          6d23h
tkbs-hadoop-hdfs-jn-0                                  2/2     Running     0          6d23h
tkbs-hadoop-hdfs-jn-1                                  2/2     Running     0          6d23h
tkbs-hadoop-hdfs-jn-2                                  2/2     Running     0          6d23h
tkbs-hadoop-hdfs-nn-0                                  2/2     Running     5          6d23h
tkbs-hadoop-hdfs-nn-1                                  2/2     Running     0          6d23h
tkbs-hbase-master-0                                    1/1     Running     3          6d23h
tkbs-hbase-master-1                                    1/1     Running     0          6d23h
tkbs-hbase-rs-0                                        1/1     Running     3          6d23h
tkbs-hbase-rs-1                                        1/1     Running     0          6d23h
tkbs-hbase-rs-2                                        1/1     Running     0          6d23h
tkbs-hive-metastore-0                                  2/2     Running     0          6d23h
tkbs-hive-metastore-1                                  2/2     Running     0          6d23h
tkbs-hive-server-8649cb7446-jq426                      2/2     Running     1          6d23h
tkbs-impala-catalogd-6f46fd97c6-b6j7b                  1/1     Running     0          6d23h
tkbs-impala-coord-exec-0                               1/1     Running     7          6d23h
tkbs-impala-coord-exec-1                               1/1     Running     7          6d23h
tkbs-impala-coord-exec-2                               1/1     Running     7          6d23h
tkbs-impala-shell-844796695-fgsjt                      1/1     Running     0          6d23h
tkbs-impala-statestored-798d44765f-ffp82               1/1     Running     0          6d23h
tkbs-kibana-7994978d8f-5fbcx                           1/1     Running     0          6d23h
tkbs-kube-state-metrics-57ff4b79cb-lmsxp               1/1     Running     0          6d23h
tkbs-loki-0                                            1/1     Running     0          6d23h
tkbs-mist-d88b8bc67-s8pxx                              1/1     Running     0          6d23h
tkbs-nginx-ingress-controller-87b7fb9bb-mpgtj          1/1     Running     0          6d23h
tkbs-nginx-ingress-default-backend-6857b58896-rgc5c    1/1     Running     0          6d23h
tkbs-nginx-proxy-64964c4c79-7xqx6                      1/1     Running     6          6d23h
tkbs-postgresql-5b9ddc464c-xc5nn                       1/1     Running     1          6d23h
tkbs-postgresql-ha-pgpool-5cbf85d847-v5dsr             1/1     Running     1          6d23h
tkbs-postgresql-ha-postgresql-0                        2/2     Running     0          6d23h
tkbs-postgresql-ha-postgresql-1                        2/2     Running     0          6d23h
tkbs-prometheus-node-exporter-bdp9v                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-cdrqr                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-cv767                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-l82wp                    1/1     Running     0          6d23h
tkbs-prometheus-node-exporter-nb4pk                    1/1     Running     0          6d23h
tkbs-prometheus-operator-operator-f74dd4f6f-lnscv      2/2     Running     0          6d23h
tkbs-promtail-d6r9r                                    1/1     Running     0          6d23h
tkbs-promtail-gd5nz                                    1/1     Running     0          6d23h
tkbs-promtail-l9kjw                                    1/1     Running     0          6d23h
tkbs-promtail-llwvh                                    1/1     Running     0          6d23h
tkbs-promtail-prgt9                                    1/1     Running     0          6d23h
tkbs-scheduler-74f5777c5d-hr88l                        1/1     Running     0          6d23h
tkbs-spark-history-7d78cf8b56-82xg7                    1/1     Running     4          6d23h
tkbs-spark-thirftserver-5757f9588d-gdnzz               1/1     Running     4          6d23h
tkbs-sparkoperator-f9fc5b8bf-8s4m2                     1/1     Running     0          6d23h
tkbs-sparkoperator-f9fc5b8bf-m9pjk                     1/1     Running     0          6d23h
tkbs-sparkoperator-webhook-init-m6fn5                  0/1     Completed   0          6d23h
tkbs-superset-54d587c867-b99kw                         1/1     Running     0          6d23h
tkbs-zeppelin-controller-65c454cfb9-m4snp              1/1     Running     0          6d23h
tkbs-zookeeper-0                                       3/3     Running     0          6d23h
tkbs-zookeeper-1                                       3/3     Running     0          6d23h
tkbs-zookeeper-2                                       3/3     Running     0          6d23h

注意

当前 TKE k8s-big-data-suite 1.0.3 在初始化 Postgresql 时,缺少对 Hive transaction 的支持,从而导致 Iceberg 表创建失败。请先执行以下命令手动修复:

$ kubectl  get pod | grep postgresql
tkbs-postgresql-5b9ddc464c-xc5nn                       1/1     Running            1          7d18h
$ kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -c "UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'metastore';SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'metastore'"; kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -c "drop database metastore"; kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -c "create database metastore"
$ kubectl get pod | grep client
tkbs-client-844559f5d7-r86rb                           1/1     Running     7          7d18h
$ kubectl exec tkbs-client-844559f5d7-r86rb -- schematool -dbType postgres -initSchema

集成 Iceberg

当前 Iceberg 对 Spark 3.0 有较好支持,对比 Spark 2.4 有以下优势:

所以我们默认采用 Spark 3.0 作为计算引擎。Spark 集成 Iceberg,首先需引入 Iceberg jar 依赖。用户可在提交任务阶段手动指定,或将 jar 包直接引入 Spark 安装目录。为了便于使用,我们选择后者。笔者已打包 Spark 3.0.1 的镜像,供用户测试使用:ccr.ccs.tencentyun.com/timxbxu/spark:v3.0.1。

我们使用 Hive MetaStore 管理 Iceberg 表信息,通过 Spark Catalog 访问和使用 Iceberg 表。在 Spark 中做如下配置:

spark.sql.catalog.hive_prod = org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.hive_prod.type = hive
spark.sql.catalog.hive_prod.uri = thrift://metastore-host:port

若使用 TKE k8s-big-data-suite 套件部署 Hadoop 集群,可通过 Hive Service 访问 Hive MetaStore:

$ kubectl  get svc | grep hive-metastore
tkbs-hive-metastore                                 ClusterIP      172.22.255.104   <none>           9083/TCP,8008/TCP                                             6d23h

Spark 配置变更为:

spark.sql.catalog.hive_prod = org.apache.iceberg.spark.SparkCatalog
spark.sql.catalog.hive_prod.type = hive
spark.sql.catalog.hive_prod.uri = thrift://tkbs-hive-metastore

创建和使用 Iceberg 表

执行 spark-sql 进行验证:

$ spark-sql --master k8s://{k8s-apiserver} --conf spark.kubernetes.container.image=ccr.ccs.tencentyun.com/timxbxu/spark:v3.0.1 --conf spark.sql.catalog.hive_prod=org.apache.iceberg.spaparkCatalog --conf spark.sql.catalog.hive_prod.type=hive --conf spark.sql.catalog.hive_prod.uri=thrift://tkbs-hive-metastore --conf spark.sql.warehouse.dir=hdfs://tkbs-hadoop-hdfs-nn/iceberg

各参数含义如下:

  • --master k8s://{k8s-apiserver}:Kubernetes 集群地址
  • --conf spark.kubernetes.container.image=ccr.ccs.tencentyun.com/timxbxu/spark:v3.0.1:Spark Iceberg 镜像
  • --conf spark.sql.catalog.hive_prod.type=hive:Spark Catalog 类型
  • --conf spark.sql.catalog.hive_prod.uri=thrift://tkbs-hive-metastore:Hive MetaStore 地址
  • --conf spark.sql.warehouse.dir=hdfs://tkbs-hadoop-hdfs-nn/iceberg:Spark 数据地址

创建 Iceberg 表:

spark-sql> CREATE TABLE hive_prod.db.table (id bigint, data string) USING iceberg;

查看是否创建成功:

spark-sql> desc hive_prod.db.table;
20/11/02 20:43:43 INFO BaseMetastoreTableOperations: Refreshing table metadata from new version: hdfs://10.0.1.129/iceberg/db.db/table/metadata/00000-1306e87a-16cb-4a6b-8ca0-0e1846cf1837.metadata.json
20/11/02 20:43:43 INFO CodeGenerator: Code generated in 21.35536 ms
20/11/02 20:43:43 INFO CodeGenerator: Code generated in 13.058698 ms
id    bigint
data    string
# Partitioning
Not partitioned
Time taken: 0.537 seconds, Fetched 5 row(s)
20/11/02 20:43:43 INFO SparkSQLCLIDriver: Time taken: 0.537 seconds, Fetched 5 row(s)

查看 HDFS 是否存在表信息:

$ hdfs dfs -ls /iceberg/db.db
Found 5 items
drwxr-xr-x   - root supergroup          0 2020-11-02 16:37 /iceberg/db.db/table

查看 Postgresql 是否存在表元数据信息:

$ kubectl get pod | grep postgresql
tkbs-postgresql-5b9ddc464c-xc5nn                       1/1     Running     1          7d19h$ kubectl exec tkbs-postgresql-5b9ddc464c-xc5nn -- psql -d metastore -c 'select * from "TBLS"'

向 Iceberg 表插入数据:

spark-sql> INSERT INTO hive_prod.db.table VALUES (1, 'a'), (2, 'b');

查看是否插入成功:

spark-sql> select * from hive_prod.db.table;
...
1    a
2    b
Time taken: 0.854 seconds, Fetched 2 row(s)
20/11/02 20:49:43 INFO SparkSQLCLIDriver: Time taken: 0.854 seconds, Fetched 2 row(s)

查看 Kubernetes 集群 Spark 任务运行状态:

$ kubectl get pod | grep spark
sparksql10-0-1-64-ed8e6f758900de0c-exec-1              1/1     Running            0          86s
sparksql10-0-1-64-ed8e6f758900de0c-exec-2              1/1     Running            0          85s

Iceberg Spark 支持的更多操作可见:https://iceberg.apache.org/sp...

通过以上步骤,我们即可在 Kubernetes 上快速部署生产可用的实时数据湖平台。

总结

在这个数据量爆炸的时代,传统数仓已较难很好满足数据多样性需求。数据湖凭借开放、低成本等优势,逐渐居于主导地位。并且用户和业务也不再满足于滞后的分析结果,对数据实时性提成了更多要求。以 Iceberg、Hudi、Delta Lake 为代表的开源数据湖技术,填补了这部分市场空白,为用户提供了快速搭建适用于实时 OLAP 的数据湖平台能力。另外云原生时代的到来,更是大大加速了这一过程。大数据毋庸置疑正朝着实时分析、计算存储分离、云原生,乃至于湖仓一体的方向发展。大数据基础设施也正因为 Kubernetes、容器等云原生技术的引入,正发生巨大变革。未来大数据会更好的“长于云上”,Bigdata as a Service 的时代,相信很快会到来。

参考材料

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 0 收藏 0 评论 0

腾讯云原生 发布了文章 · 11月5日

在腾讯云容器服务 TKE 中实践 DevOps

概述

DevOps 理念被越来越多的企业采纳,DevOps 是 Development 和 Operations 的组合词,代表着重视「软件开发人员(Dev)」和「IT 运维技术人员(Ops)」之间沟通合作的文化;旨在透过自动化「软件交付」和「架构变更」的流程,使得构建、 测试、发布软件的过程能够更加地快捷、频繁和可靠。在云原生时代,我们更需要 Devops 思维来实现敏捷开发, 本文将介绍和实践专为云原生打造的 TKE 容器 DevOps 服务,实现从代码提交时触发镜像的自动构建,再到镜像构建成功时触发自动部署流程将应用部署、更新到 TKE 集群中的一整套无缝衔接的 Devops 流水线。

TKE 容器 DevOps 简介

TKE 容器 DevOps 是 容器服务 TKE容器镜像服务 TCRCODING DevOps 三个服务紧密结合,面向容器业务场景,具备自动化代码编译、容器镜像构建、镜像推送及应用部署等功能,为客户提供强大的一站式云原生 DevOps 服务。容器 DevOps 快速入门请参考 TKE 和 Coding 协同业务实现快速迭代 最佳实践文档。

TKE 容器 DevOps 业务流程

TKE 容器 DevOps 服务贯穿了整个应用开发和部署流程的全生命周期管理,实现了从更新代码到应用部署、更新的自动化,如下图所示:

img

如何使用 TKE 容器 DevOps

操作场景

TKE 容器 Devops 功能提供了强大的云原生 Devops服务,下面将按照上述 TKE 容器 Devops 业务流程图来实现从源码更新到业务发布的整套自动化流程。

前提条件

操作步骤

TKE 容器 Devops 访问入口

在 TKE 控制台左侧功能菜单栏点击【Devops】功能链接即可进入【容器 Devops】介绍界面,如下图所示:

img

点击 【立即使用】即可跳转到所属团队的 Coding 主页面使用相关 DevOps 功能。

配置代码托管

在 Coding 团队主页面创建一个测试项目和测试代码仓库,关于 Coding 代码托管介绍请参考 代码托管介绍 。创建步骤如下:

步骤 1:在 Coding 团队主页面【 项目】中创建测试项目,如下图所示:

img

步骤 2:点击已创建的测试项目 “test-jokey” 进入项目主页面,在【代码仓库】菜单中新建测试代码仓库,如下图所示:

img

创建构建计划

在测试项目 “test-jokey” 主页面左侧菜单【持续集成】的子菜单 【构建计划】中创建一个构建计划,构建计划是持续集成的基本单元,可以通过选择构建计划模版快速创建一个构建计划,详情请参考文档 快速开始持续集成

步骤 1:选择 “构建镜像并推送到 TCR 企业版” 模版快速创建一个构件计划,创建示例如下:

img

步骤 2:根据构建计划模版选择要检出的代码源和配置 TCR 访问凭证相关环境变量, 右边可以看到模版生成的 Jenkinsfile 预览,如下图:

提示:Coding devops 和 TCR 实例之间内网互通,镜像 push 默认使用内网传输,无需另外配置。

img

使用构建模版生成的构建项目,也可以通过点击构建项目的【设置】菜单再对构建详情进行自定义配置,构建计划配置页面的功能说明如下:

img

【基础信息】: 基础配置页面可选择代码源和节点池等基础配置,节点池相关说明请参考文档 构建节点

【流程配置】:用来配置运行构建任务的环境,相关说明请参考 构建环境

【触发规则】:用来配置构建计划的触发规则,可支持通过多种方式来触发构建计划,相关说明请参考 触发规则

【变量与缓存】:环境变量与缓存配置,相关说明请参考 环境变量缓存目录

【通知提醒】:构建计划完成时可向指定的 Coding 团队成员发送通知提醒。

另外还可以在【项目配置 -> 开发者选项 -> WebHook】 中新建 WebHook 的方式将事件通知推送到企业微信等即时通信平台,详情请参考 WebHook绑定企业微信群机器人,配置示例如下图:

img

想了解更多关于 Coding 持续集成的详细介绍请参考 持续集成介绍

创建持续部署

在测试项目 “test-jokey” 主页面左侧菜单 【持续集成】的子菜单 【Kubernetes】中根据步骤引导创建持续部署流水线,如下图所示:

img

配置云账号

请参考 云账号 文档,添加配置部署云上资源的访问云账号信息,可以选择【腾讯云 TKE】或者【Kubernetes】 类型的云账号,输入相关认证配置添加云账号,这里选择了【Kubernetes】方式绑定。

img

配置应用和流程

关于 Coding 应用与项目相关说明请参考文档 应用与项目流程配置 ,这里仅简单说明下在配置应用和流程过程中的关键配置项。

在创建应用时,需要勾选【 Kubernetes(TKE) 部署】方式:

img

在新建的应用中创建部署流程时,选择【Kubernetes】流程模版,再根据实际需要选择模版下的流程,这里选择了下图中第二个流程,部署 Deployment 和 Service 到 Kubernets 集群的流程:

img

在【部署流程】中配置部署流程时,【启动所需制品】选项关联之前的持续集成环节生成的 TCR 仓库镜像制品:

img

使用【自动触发器】绑定 TCR 仓库镜像制品,这里是重点,作用是当有新版本镜像构建成功时,将自动触发部署流程,配置方式如下:

img

接下来就是配置【部署 Deployment】和【部署 Service】部署阶段,两个阶段的配置方式类似,选择之前添加的有部署权限的云账号和填写自定义的 Manifest,即自定义部署 YAML 模版。

img

自定义 Deployment YAML 示例如下:

提示:关于持续部署更新策略

本示例仅使用了一个简单的 Deployment YAML 部署到 Kubernetes 集群,使用了默认的滚动部署(RollingUpdate)更新策略。实际上,可以借助 Nginx-ingress / Istio 等工具配置更高级的更新策略,如蓝绿发布、金丝雀、A/B 测试等,具体使用方法请参阅 蓝绿发布Nginx-ingress 实现自动化灰度发布持续部署 + TKE Mesh 灰度发布实践

apiVersion: apps/v1
kind: Deployment
metadata:
  name: devops-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: devops-app
  template:
    metadata:
      labels:
        app: devops-app
    spec:
      containers:
        - image: xxx-test.tencentcloudcr.com/xxx-test/jokey-test  # 示例镜像地址
          name: devops-app
          ports:
            - containerPort: 5000
      imagePullSecrets:  # 私有仓库访问凭证配置 
        - name: tcr-secret # 访问凭证 secret

其中, 对于 spec.template.spec.containers.*.image 的镜像地址字段 Coding 会有一个转换匹配规则, 关于转换匹配规则的说明请参考文档 在 manifest 中绑定制品

关于 TKE 拉取 TCR 私有仓库镜像有两种方式:

注意:上面的 Deployment YAML 示例使用了 “手动配置 TKE 拉取 TCR 私有仓库镜像的访问凭证” 的方式。

自定义的 Service Manifest YAML 示例:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: devops-svc
  name: devops-svc
spec:
  ports:
    - port: 5000
      protocol: TCP
  selector:
    app: devops-app

另外可以为部署流程的每个阶段配置自定义事件通知(可选),以便方便快捷的获知部署流程执行情况,这里配置了企业微信通知方式,获取企业微信 Webook 机器人链接的方法可参考 创建企业微信群机器人

img

关联项目和应用

关联项目和应用配置请参考文档 项目和应用关联

提单发布

提单发布使用和配置请参考文档 新建发布单

想了解更多关于 Coding 持续部署的详细介绍请参考 持续部署介绍

测试验证

在项目代码文件中修改添加如下所示的 v2 API 代码后提交 master 分支:

img

由于【持续集成】中的构建计划使用了 “代码更新时自动执行” 的事件触发配置, 了解相关触发配置请参考 触发规则。当提交修改的代码时,会自动触发关联的构建计划执行:

img

如果为持续集成配置了企业微信 Webhook 通知,企业微信也会收到相应的即时通知消息,如下图所示:

img

当构建计划生成 Docker 镜像制品时,又会自动触发关联的【持续部署】流程,将新的镜像应用更新到 TKE 集群中:

img

如果部署流程有配置企业微信通知的话,当部署流程任务完成时,会收到对应的企业微信部署完成通知,如下图所示:

img

此时,可以在 TKE 中看到已经成功更新了工作负载:

img

从测试验证结果可以看出,我们在 TKE 中实现了从源码更新到业务发布的整套 DevOps 流程。

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 0 收藏 0 评论 0

腾讯云原生 发布了文章 · 11月2日

手把手教你使用 Prometheus 监控 MySQL 与 MariaDB.md

概述

MySQL 是常用的关系型数据库,MariaDB 作为 MySQL 的分支版本,兼容 MySQL 协议,也越来越流行。在 Kubernetes 环境中如何使用 Prometheus 来对它们进行监控呢?通常是借助开源的 mysqld-exporter 来实现,本文将围绕这个主题展开详细介绍下。

mysqld-exporter 原理介绍

mysqld-exporter 通过读取 MySQL 或 MariaDB 中的一些数据库状态的数据,并将其转换为 Prometheus 的指标格式并暴露成 http 接口被 Prometheus 所采集,来实现让原本不支持 Prometheus 指标的 MySQL 和 MariaDB 能够被 Prometheus 监控起来:

img

操作步骤

部署 mysqld-exporter

在部署 mysqld-exporter 之前首先保证 MySQL 或 MariaDB 已经部署,可以在集群内,也可以在集群外,或者使用现成的云服务。如果还没有,这里以从应用市场部署到集群为例来部署一个 MySQL:

  1. 在应用市场中找到 MySQL,点击 创建应用-创建

img

  1. 查看 mysql 是否正常运行:
$ kubectl get pods
NAME                     READY   STATUS        RESTARTS   AGE
mysql-698b898bf7-4dc5k   1/1     Running       0          11s
  1. 获取 root 密码:
$ kubectl get secret -o jsonpath={.data.mysql-root-password} mysql
6ZAj33yLBo

有了 MySQL 后,我们开始准备部署 mysqld-exporter,首先为 mysqld-exporter 创建一个账号,登录 MySQL:

$ kubectl exec -it mysql-698b898bf7-4dc5k bash
$ mysql -uroot -p6ZAj33yLBo

然后输入 SQL 来创建账号,这里以 mysqld-exporter/123456 为例:

CREATE USER 'mysqld-exporter' IDENTIFIED BY '123456' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, REPLICATION SLAVE, SELECT ON *.* TO 'mysqld-exporter';
flush privileges;

然后使用以下 yaml 来部署 mysqld-exporter:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysqld-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysqld-exporter
  template:
    metadata:
      labels:
        app: mysqld-exporter
    spec:
      containers:
      - name: mysqld-exporter
        image: prom/mysqld-exporter:v0.12.1
        args:
        - --collect.info_schema.tables
        - --collect.info_schema.innodb_tablespaces
        - --collect.info_schema.innodb_metrics
        - --collect.global_status
        - --collect.global_variables
        - --collect.slave_status
        - --collect.info_schema.processlist
        - --collect.perf_schema.tablelocks
        - --collect.perf_schema.eventsstatements
        - --collect.perf_schema.eventsstatementssum
        - --collect.perf_schema.eventswaits
        - --collect.auto_increment.columns
        - --collect.binlog_size
        - --collect.perf_schema.tableiowaits
        - --collect.perf_schema.indexiowaits
        - --collect.info_schema.userstats
        - --collect.info_schema.clientstats
        - --collect.info_schema.tablestats
        - --collect.info_schema.schemastats
        - --collect.perf_schema.file_events
        - --collect.perf_schema.file_instances
        - --collect.perf_schema.replication_group_member_stats
        - --collect.perf_schema.replication_applier_status_by_worker
        - --collect.slave_hosts
        - --collect.info_schema.innodb_cmp
        - --collect.info_schema.innodb_cmpmem
        - --collect.info_schema.query_response_time
        - --collect.engine_tokudb_status
        - --collect.engine_innodb_status
        ports:
        - containerPort: 9104
          protocol: TCP
        env:
        - name: DATA_SOURCE_NAME
          value: "mysqld-exporter:123456@(mysql.default.svc.cluster.local:3306)/"
---
apiVersion: v1
kind: Service
metadata:
  name: mysqld-exporter
  labels:
    app: mysqld-exporter
spec:
  type: ClusterIP
  ports:
  - port: 9104
    protocol: TCP
    name: http
  selector:
    app: mysqld-exporter
! 注意根据实际情况替换 DATA_SOURCE_NAME 中的账号密码,以及 MySQL 的连接地址

添加监控采集配置

有了 mysqld-exporter 后,我们就可以配置监控的采集,让 mysqld-exporter 暴露的数据被采集起来,如果你的集群中安装了 prometheus-operator,可以通过定义 ServiceMonitor 来配置采集规则,示例:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: mysqld-exporter
spec:
  endpoints:
    interval: 5s
    targetPort: 9104
  namespaceSelector:
    matchNames:
    - default
  selector:
    matchLabels:
      app: mysqld-exporter

你可以通过修改 Prometheus 原生的配置文件来配置采集规则,示例:

    - job_name: mysqld-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
        namespaces:
          names:
          - default
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: mysqld-exporter
      - action: keep
        source_labels:
        - __meta_kubernetes_endpoint_port_name
        regex: http

添加监控面板

采集配置好,正常采集有了数据之后,还需要为 Grafana 添加监控面板进行展示,如果只是看 MySQL 或 MariaDB 的一些概览情况,可以导入 grafana.com 的这个面板: https://grafana.com/grafana/d...

img

如果需要更丰富的面板,可以导入 percona 开源的一些面板,地址: https://github.com/percona/gr... (导入 MySQL_ 开头的 json 文件中的内容即可)。

小结

本文介绍了如何利用开源的 mysqld-exporter 将原本不支持 Prometheus 的 MySQL 或 MariaDB 接入进来,让 Prometheus 也能采集数据库的监控指标,并添加 Grafana 监控面板,让查看监控更加方便。

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 2 收藏 2 评论 0

腾讯云原生 发布了文章 · 10月29日

完爆!用边缘容器,竟能秒级实现团队七八人一周的工作量

导语 | 云端管控、边缘计算、处于局域网内的微服务如何做Devops呢?腾讯优图业务是结合了腾讯云边缘容器TKE@edge来做服务Devops, 并对服务做了自定义定制, 以支持相应的业务场景。本篇文章接下来将详细展示实践落地细节,希望能够给大家带来灵感。

背景

所谓私有云, 其实就是在多个局域网玩服务,基本等同于开发运维全包。每个局域网都要需要一个跳板机、局域网环境(每个局域网环境不一)以及硬件、软件等,然后还需要大量人肉运维部署升级服务(传统做法譬如ansible, fabric, scp, 诸如拷贝、配置更新、版本维护都很麻烦, 所以弃用), 而且不同局域网服务需要差异化配置, 配置管理也是问题。

笔者也思考过做一套局域网自动化部署的东西, 思路就是在局域网部署agent来和云端打通, 然后各种传数据发命令。就在这个时候突然看到同事在写TKE@edge的东西, 看了之后感觉是我想要的东西, 于是就开干了。

现状

批量部署问题:为了批量部署部署, 采用了scp、fabric部署工具, 每个局域网采用不同配置, 要改配置的话就需要挨个登录机器修改;
差异化配置问题:为了解决配置问题, 采用配置中心, 将所有配置集中化管理, 但是每个局域网的配置中心还是不一样, 尽管已经收敛到一个服务了, 还是感觉很累且容易出错;
服务上下游调用:采用自研服务发现组件, 结合了consul的DNS服务功能, 上下游服务通过DNS寻址。 这个问题可以很好地解决。

TKE@edge简介

有没有一种能在云上控制服务部署升级的产品呢?据了解,TKE@edge就是其中一种,它可以比较好地解决这个问题。

另外,业界还有一个开源解决方案K3s,这个方案虽然通过裁剪让资源有限的设备也能运行 K8s,然而依然不能解决我最关心的几个问题,如:

1)云端运维;

2)在一个集群中管理跨网络和地域的边缘节点;

3)简化不同地域差异化配置管理问题。

接下来,我们来分别看下K3s、TKE@edge的工作原理以及两者之间的差异。

K3s 工作原理图

引用自K3S官网https://k3s.io/

TKE@edge架构图

引用自【TKE 边缘容器系列】边缘计算与边缘容器简介。

从上方架构图可以看出,TKE@edge增加tunnel来打通外网, 传输数据和命令, 就是我之前提到的需要设计的agent, 另外增加了边缘节点自治组件hub-edge, 这个跟云端管控一一对应的。

TKE@edge做了几个亮点:

1. ServiceGroup:跨局域网服务的隔离, 局域网内服务互通, 但是不能跨局域网访问, 另外可以自动复制业务系统, 注意是一套业务系统,不是单个Pod, 比如增加一个局域网Zone, 可以在不干预的情况下,自动复制到新的局域网, 意外亮点

2. 分布式健康检测: 为了避免弱网环境 和云端管控存在网络问题, 可以采用自治的决定哪些Pod真正被驱逐。

3. 支持异构节点。

我的核心问题(Q)和解决方案(A)

1. 服务能在云端控制部署升级

tke@edge提供了类腾讯云容器服务TKE控制台, 可以批量操作。

2. 服务不能跨局域网访问

ServiceGroup, 通过对节点打上Zone的标签, 同一个Zone的服务互通, 不同Zone的服务进行隔离, TKE@edge通过Deploymentgrid的资源来创建Deployment。

3. 服务在K8s要做一致性hash这种复杂化LB策略

先用K8s的downward API讲Pod的NodeName导入到POD环境变量, 通过node的zone信息, 结合client-go的API进行Label过滤, 这个需要上层服务发现组件支持, 为啥不用K8s Ingress和Service方案, 不好意思, 不支持。

4. 服务流量的注入

通过nodePort暴露服务, 为了避免网卡爆掉需要利用多个宿主机nodePort承接流量, 采用consul来注册服务, 类似腾讯云CLB方案

5. 服务流量的导出

小问题

6. 服务分区域差异化配置,一套代码, 云端定制配置, 通过zone来关联
将服务配置采用Configmap管理, 并且通过Volume机制将Configmap挂载到Pod的容器目录, 那怎么决定哪个区域采用哪个配置呢, 通过传入NodeName的来进行选择。这个问题解决好了之后, 新增商场(局域网), 只需要在云端配置好对应的配置, 就可以自动扩容了, 碉堡了简直。

7. 一些次要问题, 不在此列举了

成果展示

笔者在西安商场和河北商场做了部署, 并且对西安场切了部分流量。

云端部署

对于Deploymentgrid控制台还没开发好, 只能通过kubectl来创建资源

配置管理

这两个棘手问题解决了, 就大功告成了。

成本和收益对比

过去:部署一套商场多个服务, 一个团队7八个人 一周(多则两周)的人力天, 上下游打通;

现在呢: 秒级!!!而且可以自动!!!真的是牛!!!搞完, 有预感感觉自己要被裁了, 牛逼的程序员, 就是为了革普通程序员的命。

总结展望

目前我觉得存在的问题是, tke@edge应该是基于k8s定制的, 资源占用比较多,对于ai设备有些要求,比如要能跑docker, 还有硬件平台和操作系统等一些要求;另外节点添加过程, 没有为节点批量打标签的功能, 对于node标签修改, 调度规则有待明确;对tke@edge单集群能管理的节点极限、大规模Pod调度性能方面尚未深入研究。

随着5G的到来, 越来越多设备边缘化, 计算也边缘化, 边缘容器和调度会是一个大有前景的方向。

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 9 收藏 8 评论 0

腾讯云原生 发布了文章 · 10月27日

手把手教你使用 cert-manager 签发免费证书

概述

随着 HTTPS 不断普及,越来越多的网站都在从 HTTP 升级到 HTTPS,使用 HTTPS 就需要向权威机构申请证书,需要付出一定的成本,如果需求数量多,也是一笔不小的开支。cert-manager 是 Kubernetes 上的全能证书管理工具,如果对安全级别和证书功能要求不高,可以利用 cert-manager 基于 ACME 协议与 Let's Encrypt 来签发免费证书并自动续期,实现永久免费使用证书。

cert-manager 工作原理

cert-manager 部署到 Kubernetes 集群后,它会 watch 它所支持的 CRD 资源,我们通过创建 CRD 资源来指示 cert-manager 为我们签发证书并自动续期:

img

解释下几个关键的资源:

  • Issuer/ClusterIssuer: 用于指示 cert-manager 用什么方式签发证书,本文主要讲解签发免费证书的 ACME 方式。ClusterIssuer 与 Issuer 的唯一区别就是 Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书。
  • Certificate: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对 Issuer/ClusterIssuer 的引用。

免费证书签发原理

Let’s Encrypt 利用 ACME 协议来校验域名是否真的属于你,校验成功后就可以自动颁发免费证书,证书有效期只有 90 天,在到期前需要再校验一次来实现续期,幸运的是 cert-manager 可以自动续期,这样就可以使用永久免费的证书了。如何校验这个域名是否属于你呢?主流的两种校验方式是 HTTP-01 和 DNS-01,详细校验原理可参考 Let's Encrypt 的运作方式,下面将简单描述下。

HTTP-01 校验原理

HTTP-01 的校验原理是给你域名指向的 HTTP 服务增加一个临时 location ,Let’s Encrypt 会发送 http 请求到 http:///.well-known/acme-challenge/YOUR_DOMAIN 就是被校验的域名,TOKEN 是 ACME 协议的客户端负责放置的文件,在这里 ACME 客户端就是 cert-manager,它通过修改或创建 Ingress 规则来增加这个临时校验路径并指向提供 TOKEN 的服务。Let’s Encrypt 会对比 TOKEN 是否符合预期,校验成功后就会颁发证书。此方法仅适用于给使用 Ingress 暴露流量的服务颁发证书,并且不支持泛域名证书。

DNS-01 校验原理

DNS-01 的校验原理是利用 DNS 提供商的 API Key 拿到你的 DNS 控制权限, 在 Let’s Encrypt 为 ACME 客户端提供令牌后,ACME 客户端 (cert-manager) 将创建从该令牌和您的帐户密钥派生的 TXT 记录,并将该记录放在 _acme-challenge.。 然后 Let’s Encrypt 将向 DNS 系统查询该记录,如果找到匹配项,就可以颁发证书。此方法不需要你的服务使用 Ingress,并且支持泛域名证书。

校验方式对比

HTTP-01 的校验方式的优点是: 配置简单通用,不管使用哪个 DNS 提供商都可以使用相同的配置方法;缺点是:需要依赖 Ingress,如果你的服务不是用 Ingress 暴露流量的就不适用,而且不支持泛域名证书。

DNS-01 的校验方式的优点是没有 HTTP-01 校验方式缺点,不依赖 Ingress,也支持泛域名;缺点就是不同 DNS 提供商的配置方式不一样,而且 DNS 提供商有很多,cert-manager 的 Issuer 不可能每个都去支持,不过有一些可以通过部署实现了 cert-manager 的 Webhook 的服务来扩展 Issuer 进行支持,比如 DNSPod 和 阿里 DNS,详细 Webhook 列表请参考: https://cert-manager.io/docs/...

选择哪种方式呢?条件允许的话,建议是尽量用 DNS-01 的方式,限制更少,功能更全。

操作步骤

安装 cert-manager

通常直接使用 yaml 方式一键安装 cert-manager 到集群,参考官网文档 Installing with regular manifests

cert-manager 官方使用的镜像在 quay.io,国内拉取可能比较慢,也可以使用下面命令一键安装(使用同步到国内 CCR 的镜像):

kubectl apply --validate=false -f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/cert-manager/cert-manager.yaml
! 以上命令安装方式要求集群版本不低于 1.16。

配置 DNS

登录你的 DNS 提供商后台,配置域名的 DNS A 记录,指向你需要证书的后端服务对外暴露的 IP 地址,以 cloudflare 为例:

img

HTTP-01 校验方式签发证书

如果使用 HTTP-01 的校验方式,需要用到 Ingress 来配合校验。cert-manager 会通过自动修改 Ingress 规则或自动新增 Ingress 来实现对外暴露校验所需的临时 HTTP 路径,这个就是在给 Issuer 配置 http01 校验,指定 Ingress 的 nameclass 的区别 (见下面的示例)。

TKE 自带的 Ingress 是每个 Ingress 资源都会对应一个 CLB,如果你使用 TKE 自带的 Ingress 暴露服务,并且使用 HTTP-01 方式校验,那么只能使用自动修改 Ingress 的方式,不能自动新增 Ingress,因为自动新增出来的 Ingress 会自动创建其它 CLB,对外的 IP 地址就与我们后端服务的 Ingress 不一致,Let's Encrypt 校验时就无法从我们服务的 Ingress 找到校验所需的临时路径,从而导致校验失败,无法签发证书。如果使用自建 Ingress,比如 在 TKE 上部署 Nginx Ingress,同一个 Ingress class 的 Ingress 共享同一个 CLB,这样就可以使用自动新增 Ingress 的方式。

下面给出一些示例。

如果你的服务使用 TKE 自带的 Ingress 暴露服务,不太适合用 cert-manager 签发管理免费证书,因为证书是要上传到 证书管理 来引用的,不在 K8S 中管理。

假设是 在 TKE 上部署 Nginx Ingress,且后端服务的 Ingress 是 prod/web,创建 Issuer 示例:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-http01
  namespace: prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-http01-account-key
    solvers:
    - http01:
       ingress:
         name: web # 指定被自动修改的 Ingress 名称

使用上面的 Issuer 签发证书,cert-manager 会自动修改 prod/web 这个 Ingress 资源,以暴露校验所需的临时路径,这是自动修改 Ingress 的方式,你可以使用自动新增 Ingress 的 方式,示例:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-http01
  namespace: prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-http01-account-key
    solvers:
    - http01:
       ingress:
         class: nginx # 指定自动创建的 Ingress 的 ingress class

使用上面的 Issuer 签发证书,cert-manager 会自动创建 Ingress 资源,以暴露校验所需的临时路径。

有了 Issuer,接下来就可以创建 Certificate 并引用 Issuer 进行签发了,示例:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: test-mydomain-com
  namespace: prod
spec:
  dnsNames:
  - test.mydomain.com # 要签发证书的域名
  issuerRef:
    kind: Issuer
    name: letsencrypt-http01 # 引用 Issuer,指示采用 http01 方式进行校验
  secretName: test-mydomain-com-tls # 最终签发出来的证书会保存在这个 Secret 里面

DNS-01 校验方式签发证书

如果使用 DNS-01 的校验方式,就需要看你使用的哪个 DNS 提供商了,cert-manager 内置了一些 DNS 提供商的支持,详细列表和用法请参考 Supported DNS01 providers,不过 cert-manager 不可能去支持所有的 DNS 提供商,如果没有你所使用的 DNS 提供商怎么办呢?有两种方案:

  • 方案一:设置 Custom Nameserver。在你的 DNS 提供商后台设置 custom nameserver,指向像 cloudflare 这种可以管理其它 DNS 提供商域名的 nameserver 地址,具体地址可登录 cloudflare 后台查看:

    img

    下面是 namecheap 设置 custom nameserver 的示例:

    img

    最后配置 Issuer 指定 DNS-01 验证时,加上 cloudflare 的一些信息即可(见下文示例)。

  • 方案二:使用 Webhook。使用 cert-manager 的 Webhook 来扩展 cert-manager 的 DNS-01 验证所支持的 DNS 提供商,已经有许多第三方实现,包括国内常用的 DNSPod 与阿里 DNS,详细列表参考: Webhook

下面以 cloudflare 为例来签发证书:

  1. 登录 cloudflare,点到 My Profile > API Tokens > Create Token 来创建 Token:

    img

    复制 Token 并妥善保管:

    img

    将 Token 保存到 Secret 中:

    apiVersion: v1
    kind: Secret
    metadata:
      name: cloudflare-api-token-secret
      namespace: cert-manager
    type: Opaque
    stringData:
      api-token: <API Token> # 粘贴 Token 到这里,不需要 base64 加密。
    ! 如果是要创建 ClusterIssuer,Secret 需要创建在 cert-manager 所在命名空间中,如果是 Issuer,那就创建在 Issuer 所在命名空间中。

    创建 ClusterIssuer:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: letsencrypt-dns01
    spec:
      acme:
        privateKeySecretRef:
          name: letsencrypt-dns01
        server: https://acme-v02.api.letsencrypt.org/directory
        solvers:
        - dns01:
            cloudflare:
              email: my-cloudflare-acc@example.com # 替换成你的 cloudflare 邮箱账号,API Token 方式认证非必需,API Keys 认证是必需
              apiTokenSecretRef:
                key: api-token

创建 Certificate:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:

 name: test-mydomain-com
 namespace: default

spec:

 dnsNames:
 - test.mydomain.com # 要签发证书的域名
 issuerRef:
   kind: ClusterIssuer
   name: letsencrypt-dns01 # 引用 ClusterIssuer,指示采用 dns01 方式进行校验
 secretName: test-mydomain-com-tls # 最终签发出来的证书会保存在这个 Secret 里面

### 获取和使用证书

创建好 Certificate 后,等一小会儿,我们可以 kubectl 查看是否签发成功:

$ kubectl get certificate -n prod
NAME READY SECRET AGE
test-mydomain-com True test-mydomain-com-tls 1m


如果 `READY` 为 `False` 表示失败,可以通过 describe 查看 event 来排查失败原因:

$ kubectl describe certificate test-mydomain-com -n prod


如果为 `True` 表示签发成功,证书就保存在我们所指定的 Secret 中 (上面的例子是 `default/test-mydomain-com-tls`),可以通过 kubectl 查看:

$ kubectl get secret test-mydomain-com-tls -n default
...
data:
tls.crt: <cert>
tls.key: <private key>


其中 `tls.crt` 就是证书,`tls.key` 是密钥。

你可以将它们挂载到你需要证书的应用中,或者使用自建的 Ingress,可以直接在 Ingress 中引用 secret,示例:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:

kubernetes.io/Ingress.class: nginx

spec:
rules:

  • host: test.mydomain.com
    http:

    paths:
    - path: /web
      backend:
        serviceName: web
        servicePort: 80

tls:

hosts:
- test.mydomain.com
secretName: test-mydomain-com-tls

## 小结

本文介绍了 cert-manager 的工作原理,安装方法以及签发免费证书的两种校验方式 (HTTP-01 与 DNS-01) 的原理、对比以及操作方法。

## 参考资料

- cert-manager 官网: https://cert-manager.io/
- Let's Encrypt 的运作方式: https://letsencrypt.org/zh-cn/how-it-works/
- Issuer API 文档: https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Issuer
- Certificate API 文档: https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Certificate
>【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
查看原文

赞 1 收藏 1 评论 0

认证与成就

  • 获得 52 次点赞
  • 获得 0 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 0 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 5月18日
个人主页被 2k 人浏览