Kubernetes在SHAREit的落地实战

本文分享了Kubernetes在SHAREit的实际落地经验,包括节点调度、污点管理、日志收集、Prometheus优化、资源审计、自动化注入、流量与数据处理应用策略、操作系统和镜像优化、DNS管理、服务优化以及集群扩展和容灾能力增强等多个方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

640?wx_fmt=jpeg

SHAREi在全球用户超过18亿,服务人数接近世界五分之一人口,业务成绩登顶五大洲超过70多个国家和地区的下载榜单,单从用户规模上和市场广度来说,SHAREit在全球范围内已颇具实力。为了更好的保障公司业务高速发展,SHAREit服务保障团队从2018年开始小范围试落地kubernetes,到2019年9月,实现了公司无状态业务all in Kubernetes的目标。目前生产环境Kubernetes集群Node节点数 1000+(机型配置64c 250G),Pod数13000+,包括常规业务和大数据业务。本文聚焦于Kubernetes在SHAREit落地过程中,我们在以下4个方面所做的努力:

Kubernetes产品化和可视化

640?wx_fmt=png

scmp是我们基于Kubernetes的一站式多云Kubernetes的管理平台。对Kubernetes提供的原生功能进行再度抽象,提供了简易的操作界面和向导式的操作,极大减轻开发、测试、运维的日常工作的复杂度。具体架构图如下:

640?wx_fmt=jpeg

避免被一家公有云锁定,我们IaaS层提供商包括AWS、华为云、阿里云等。为了屏蔽各家托管Kubernetes的差异性,我们中间加了一层适配层,把各家公有云当做一个个provider。这样做的结果是,我们随时可以部署一个应用到任意的云上,也可以随时迁移一个应用到其他的云上。

scmp与公司统一认证平台做了集成,未来将进一步解耦,支持LDAP和数据库认证。然后作为一个公司级别的平台,包含了用户管理,角色管理,资源管理等完善的权限管理体系,我们会根据角色QA、运维以及各个不同的研发Team作相关账号分组,每个相关部门的同学只能访问到指定的应用。同时提供了详细的操作审计,便于误操作恢复和故障追溯。

此外scmp包含了如下的功能:

集群管理

640?wx_fmt=jpeg

该功能模块纳管Kubernetes集群,同时提供了每个集群的总体预览功能,包括核心组件(kube-apiserver、kube-controller-manager、kube-scheduler、etcd)的监控状态,节点的监控状态,集群级别CPU和Memory申请,实际使用曲线图。

640?wx_fmt=png

命名空间管理

640?wx_fmt=jpeg

该模块除了常规的新建和修改功能外,将命名空间增加了镜像拉取秘钥和标签两个元数据属性,统一在命名空间这个级别设置之后,然后在该命名空间里部署的资源对象,都会被拦截并注入到资源对象里,比如Deployment、ConfigMap、Service、Ingress等。这样的好处,一方面是便于后期的资源计费和审计,另外一方面是便于统一配置。后续我们会考虑将配额管理也加入到命名空间的管理当中,目前来看互联网企业对配额不是一个强需求。

同时我们也提供了命名空间级别的预览功能,包含了集群状态,Pod数,命名空间CPU和Memory申请,实际使用,利用率曲线图。

640?wx_fmt=jpeg

由于我们实际落地过程中,每个部门对应一个命名空间,所以部门技术leader会经常关注这块,查看部门资源利用率。

Node节点管理

640?wx_fmt=jpeg

该模块主要面向运维同学。比如有如下的实际场景:

  • 需要下线替换某些Node节点。此时需要调度控制功能,将该Node标记为不可调度,然后再驱赶该Node上的Pod,最后完成Node的替换。

  • 污点管理。例如Promethues这种高耗CPU和Memory的系统组件,如果和关键业务应用混跑到一台Node节点上,在高峰期容易影响关键应用响应时间。此时就可以使用污点管理功能,配合Pod级别的容忍来实现。

  • Webshell。在某些特殊情况下,需要快速SSH到指定主机上进行debug。

  • 标签管理。例如给不同的机型,根据特点打上不同的标签,例如:storage:ssd等,配合Pod的nodeSelector和亲和性,满足业务更复杂的调度要求。


在主机列表页,点击某个主机节点打开其详情页,可以看到当前主机更详细的信息,包括主机的CPU 、内存和容器组资源运行和使用状态,以及事件(Events)和更细粒度的监控信息。

配置中心

该模块主要包括ConfigMap和Secret的管理。此处重点讲下,我们对于ConfigMap的功能增强。原生ConfigMap不提供版本管理和回滚的功能,而实际使用场景中,作为一个配置中心需要具备版本管理的功能,具体配置管理如下:

640?wx_fmt=jpeg

我们提供的回滚操作如下:

640?wx_fmt=jpeg

Ingress管理

部署一个应用,很多时候需要被集群外访问,此时Ingress是一个很好的方式。

此处支持Ingress手动和自动两种创建方式。由于Ingress对应公有云资源的LB,所以当自动创建模式的时候,我们要求填写至少三个统计维度(env、group、project)的标签,方便账单系统进行分析。

640?wx_fmt=jpeg

存储管理

我们主要业务在公有云上,所以我们没有实现自己的存储。我们对接了共有云的存储,主要包括块存储,文件存储等。

640?wx_fmt=jpeg

目前除了Prometheus和部分MQ,我们没有做太多的有状态服务的尝试。

应用部署

应用部署是所有功能中最重要也是最丰富的一个模块。包含了新建(可视化和yaml两种方式)、修改、删除、重启、回滚、手动扩缩等功能。

640?wx_fmt=jpeg

点击应用,可以进入应用详情页。我们不仅将CronHPA,金丝雀等增强功能集成了到了应用详情当中,而且将监控和日志等DevOps内容集成进来,我们希望用户可以一站式操作应用,并且具备完善的可观察性。

640?wx_fmt=jpeg

同时,由于业务部署方式由传统的虚拟机转变为容器,出于安全和稳定性考虑,我们不可能继续让业务研发在debug的时候SSH到具体的主机上。所以我们开发了Pod的webshell,查看标准输出log,查看Pod事件等功能。

640?wx_fmt=jpeg

Kubernetes与DevOps的深度结合

640?wx_fmt=png

从一开始,我们就坚持认为脱离了DevOps,Kubernetes将不具备可观察性。而且一个不合适的日志方案或是监控方案,会影响Kubernetes的稳定性。所以我们在落地Kubernetes之前,花费了大量时间完善公司的监控和日志系统。

业务日志收集方案

社区中关于Pod日志收集,有以下三种方式:

  • 将日志收集Agent打到业务容器镜像中。

  • 将日志收集Agent作为sidercar的方式与业务容器运行在同一个Pod中。

  • 宿主机Node层面统一收集:将宿主机的目录挂载为容器的日志目录,然后在宿主机上收集。


第一种方式,耦合性太高,收集日志Agent的问题会影响业务进程的正常运行。第二种方式,和最近流行的富容器思想有点类似。但是结合我们的日志量,我们选择了第三种日志收集方式,日志收集组件通过DaemonSet的形式运行在所有Node节点上。

为了稳定性和业务对于日志要求,我们做了如下的工作:

  • 我们会将一块1T大小的块存储挂载到Node节点上,作为数据盘(/data)。保证系统盘和数据盘分离。该数据盘主要用来存放业务日志和镜像。

  • 防止若干写日志比较多的Pod调度到同一个主机上,将数据盘写满,影响到其他的业务,以及防止日志收集系统有故障期间,日志丢失。我们编写了applog-cleaner组件,会定期清除旧日志数据。我们承诺保留最近两天的日志。

  • 容器本身的特点就是太多的不确定性,并且在弹性扩缩容的时候,你无法确定你的Pod调度到哪一个具体的计算节点,导致我们无法事先配置好日志收集路径。而我们规定业务日志的收集目录是/data/logs/命名空间名/应用名/poduid/下,所以我们自研了hostpathperpod volume组件。该组件通过flex volume实现,在Pod视角,业务依旧将日志写到了/data/logs下,实际上该目录挂载到了主机的/data/logs/命名空间名/应用名/poduid/ 。而在Pod的yaml中,如下配置即可:


      volumes:	
      - flexVolume:	
          driver: sgt.shareit.com/hostpathperpod	
          options:	
            hostPath: /data/logs	
        name: log-dir

我们日志收集的Agent选用Filebeat。

当业务跑在容器中,业务日志往往需要增加Pod的一些元数据,方便在出现问题的时候排查定位。为了配合上面的方案,我们fork了Filebeat的代码,增加了一种新的matchers——hostpath。在Filebeat的配置文件中如下:

- add_kubernetes_metadata:	
    in_cluster: true	
    host: ${NODE_NAME}	
    # namespace: ${POD_NAMESPACE}	
    default_indexers.enabled: false	
    default_matchers.enabled: false	
    indexers:	
      - pod_uid:	
    matchers:	
      - logs_path:	
          logs_path: /data/logs/	
          resource_type: hostpath

监控方案

SHAREit整个监控系统Hawkeye基于Prometheus和M3DB实现。没有使用Prometheus官方联邦的特性。引入M3DB, 可以实现采集和查询分离的架构,提升整个监控系统的稳定性,所以我们每个集群的Prometheus只是我们整个监控体系的一个采集端而已。

640?wx_fmt=png

这样的架构好处在于:

  • 采集查询分离。我们严格规定不得从采集Prometheus查询数据。如果是单一的Prometheus,在实际使用中,大家在查询了一个较大时间维度后,Prometheus会OOM,这个时候,你在Grafana中看到,你的曲线是有中断的。同时查询端,可以多个Prometheus,前置一个LB,起到高可用的作用。

  • metrics,不仅仅是在监控领域发挥作用,而且对于资源的计费和审计也是极其重要的,将不同采集源的metrics汇聚到一个TSDB集群中,提供了一个全公司的维度。同时对于后续的AIOps也是非常重要的。


M3DB是一个分布式时间序列数据库,提供可扩展存储和时间序列的反向索引。 它经过优化,具有成本效益,并且可以在较长的保留时间内可靠地存储大规模指标。

640?wx_fmt=png

在生产环境,我们3个etcd节点单独部署,6个高配主机作为storage节点。

M3Coordinator作为sidecar的方式,与Prometheus部署到同一个Pod中。之所以这么部署,因为同一个Pod同一个network namespace,网络优势更大。

同时建议大家部署kube-state-metrics组件,将更详细的metrics采集到监控系统中。

具体Kubernetes集群中的关于监控的配置文件如下:

apiVersion: v1	
kind: ConfigMap	
metadata:	
  labels:	
    app: prometheus	
  name: prometheus	
  namespace: kube-admin	
data:	
  prometheus.yml: |-	
    global:	
      scrape_interval: 30s	
      evaluation_interval: 30s	
      # The labels to add to any time series or alerts when communicating with	
      # external systems (federation, remote storage, Alertmanager).	
      external_labels:	
        cluster: 'SGT-eks-apse1-prod'	
    # Settings related to the remote write feature.	
    remote_write:	
      - url: "http://localhost:7201/api/v1/prom/remote/write"	
        queue_config:	
          max_samples_per_send: 60000	
    scrape_configs:	
      - job_name: prometheus	
        static_configs:	
          - targets:	
            - localhost:9090	
      - job_name: kube-state-metrics	
        static_configs:	
          - targets:	
            - kube-state-metrics.kube-system:8080  	
      - job_name: kubernetes-apiservers	
        kubernetes_sd_configs:	
        - role: endpoints	
        relabel_configs:	
        - action: keep	
          regex: default;kubernetes;https	
          source_labels:	
          - __meta_kubernetes_namespace	
          - __meta_kubernetes_service_name	
          - __meta_kubernetes_endpoint_port_name	
        scheme: https	
        tls_config:	
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt	
          insecure_skip_verify: true	
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token	
      - job_name: kubernetes-nodes-kubelet	
        kubernetes_sd_configs:	
        - role: node	
        relabel_configs:	
        - action: labelmap	
          regex: __meta_kubernetes_node_label_(.+)	
        scheme: https	
        tls_config:	
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt	
          insecure_skip_verify: true	
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token	
      - job_name: kubernetes-nodes-cadvisor	
        kubernetes_sd_configs:	
        - role: node	
        relabel_configs:	
        - action: labelmap	
          regex: __meta_kubernetes_node_label_(.+)	
        - target_label: __metrics_path__	
          replacement: /metrics/cadvisor	
        scheme: https	
        tls_config:	
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt	
          insecure_skip_verify: true	
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token	
      - job_name: kubernetes-service-endpoints	
        kubernetes_sd_configs:	
        - role: endpoints	
        relabel_configs:	
        - action: keep	
          regex: true	
          source_labels:	
          - __meta_kubernetes_service_annotation_prometheus_io_scrape	
        - action: replace	
          regex: (https?)	
          source_labels:	
          - __meta_kubernetes_service_annotation_prometheus_io_scheme	
          target_label: __scheme__	
        - action: replace	
          regex: (.+)	
          source_labels:	
          - __meta_kubernetes_service_annotation_prometheus_io_path	
          target_label: __metrics_path__	
        - action: replace	
          regex: ([^:]+)(?::\d+)?;(\d+)	
          replacement: $1:$2	
          source_labels:	
          - __address__	
          - __meta_kubernetes_service_annotation_prometheus_io_port	
          target_label: __address__	
        - action: labelmap	
          regex: __meta_kubernetes_service_label_(.+)	
        - action: replace	
          source_labels:	
          - __meta_kubernetes_namespace	
          target_label: kubernetes_namespace	
        - action: replace	
          source_labels:	
          - __meta_kubernetes_service_name	
          target_label: kubernetes_name	
      - job_name: kubernetes-services	
        kubernetes_sd_configs:	
        - role: service	
        metrics_path: /probe	
        params:	
          module:	
          - http_2xx	
        relabel_configs:	
        - action: keep	
          regex: true	
          source_labels:	
          - __meta_kubernetes_service_annotation_prometheus_io_probe	
        - source_labels:	
          - __address__	
          target_label: __param_target	
        - replacement: blackbox	
          target_label: __address__	
        - source_labels:	
          - __param_target	
          target_label: instance	
        - action: labelmap	
          regex: __meta_kubernetes_service_label_(.+)	
        - source_labels:	
          - __meta_kubernetes_namespace	
          target_label: kubernetes_namespace	
        - source_labels:	
          - __meta_kubernetes_service_name	
          target_label: kubernetes_name	
      - job_name: kubernetes-pods	
        kubernetes_sd_configs:	
        - role: pod	
        relabel_configs:	
        - action: keep	
          regex: true	
          source_labels:	
          - __meta_kubernetes_pod_annotation_prometheus_io_scrape	
        - action: replace	
          regex: (.+)	
          source_labels:	
          - __meta_kubernetes_pod_annotation_prometheus_io_path	
          target_label: __metrics_path__	
        - action: replace	
          regex: ([^:]+)(?::\d+)?;(\d+)	
          replacement: $1:$2	
          source_labels:	
          - __address__	
          - __meta_kubernetes_pod_annotation_prometheus_io_port	
          target_label: __address__	
        - action: labelmap	
          regex: __meta_kubernetes_pod_label_(.+)	
        - action: replace	
          source_labels:	
          - __meta_kubernetes_namespace	
          target_label: kubernetes_namespace	
        - action: replace	
          source_labels:	
          - __meta_kubernetes_pod_name	
          target_label: kubernetes_pod_name	
  m3coordinator.yaml: |-	
    listenAddress:	
      type: "config"	
      value: "0.0.0.0:7201"	
    metrics:	
      scope:	
        prefix: "coordinator"	
      prometheus:	
        handlerPath: /metrics	
        listenAddress: 0.0.0.0:7203 # until https://github.com/m3db/m3/issues/682 is resolved	
      sanitization: prometheus	
      samplingRate: 1.0	
      extended: none	
    tagOptions:	
      idScheme: quoted	
    clusters:	
    # Fill-out the following and un-comment before using, and	
    # make sure indent by two spaces is applied.	
      - namespaces:	
          - namespace: default	
            retention: 48h	
            type: unaggregated	
          - namespace: metrics	
            type: aggregated	
            retention: 720h	
            resolution: 5m	
        client:	
          config:	
            service:	
              env: default_env	
              zone: embedded	
              service: m3db	
              cacheDir: /var/lib/m3kv	
              etcdClusters:	
                - zone: embedded	
                  endpoints:	
                    - 172.xx.61.23:2379	
                    - 172.xx.70.225:2379	
                    - 172.xx.77.220:2379	
    #                ... etc, list only M3DB seed nodes	
          writeConsistencyLevel: majority	
          readConsistencyLevel: unstrict_majority

CI/CD

该方案中,我们选用了Jenkins。Jenkins拥有几千种功能强大的插件,可以不需要太多的开发,就可以满足业务研发的需求。

底层我们封装了静态代码质量检测,单测,构建,打镜像等功能,以模块化的思想提供Pipeline,业务研发可以根据自己实际需求,类似搭积木的方式组建自己的CI/CD,比如,在测试环境,某些业务部门会把静态代码检测加到CI的环境中,而在Autotest环境中则不会这样做。我们集成了Jenkins的API,在UI上可视化操作,业务研发或是运维只需要拖拉具体的模块即可。

我们所有的镜像都会通过Clair镜像扫描,保证安全性。

在CI/CD这块,后续我们会将整个Jenkins系统容器化,利用Kubernetes动态扩缩的特点,进一步提升构建系统的资源利用率和减少构建高峰期的排队。

自研多种组件,满足业务更多需求

640?wx_fmt=png

Kubernetes提供了CRD、Webhook、CSI、CNI、CRI等多种方式增加其可扩展性。在实际落地过程中,我们根据业务的需求以及我们对于Kubernetes的理解,我们开发了一系列的组件,进一步丰富Kubernetes的功能,加强应用容器化的规范,降低研发的工作量。

injector

该组件基于Kubernetes 中 ValidatingAdmissionWebhook和MutatingAdmissionWebhook两个功能实现。实现的功能包括:

  • 检查部署到生产环境中的应用,资源的limit和request是否相等,保证业务的稳定性。同时检查是否具有env,group,project等标签,方便后续的分析和审计。检查容器是否以特权容器模式运行。

  • 根据Pod的annotations,注入volume或环境变量或注入特定功能的init container或注入sidecar辅助容器。例如AKSK,之前我们的业务代码运行在虚机上,引用了公有云的SDK后,SDK会自动优先到某路径下查找credentials文件,获取访问对应资源的操作凭证。在容器化的过程中,我们为了让业务代码不做任何更改,所以会自动注入AKSK到指定路径下。同时也保证了AKSK的安全,避免了泄露的风险。


add-resource-tags

在公有云的环境中,例如LB和块存储等IaaS层资源,需要打各种标签,方便账单分析。但是大多数的托管Kubernetes并没有提供类似的功能,尤其是一些自动创建的资源,比如Ingress、PVC等。所以我们研发了add-resource-tags组件,该组件监听了Service、Ingress、PVC等资源对象,当发现以上三种对象创建或是修改后,会将对应的标签通过调用公有云的SDK,给对应的IaaS层资源打上标签。

eventer

该组件source为Kubernetes的event。然后设计了类似于日志收集的Pipeline的方式,包括print,drop or add metadata,周期内merge等filter,通过yaml配置文件的方式针对某种类型的event或是针对某种插件做各种设置,从而满足不同环境,不同集群,不同业务团队对于event报警的差异性需求。该组件sink到公司统一的报警平台,然后分发给不同的团队,目前支持DingTalk和邮件两种方式。

prophet

该组件主要包含了cron hpa, custom hpa, canary部署等功能。主要利用CRD的扩展方式实现。

在业务实际使用的场景中,官方HPA并不能完全满足业务,所以我们开发了cron hpa和custom hpa。

cron hpa主要用于有着明确高峰期和低峰期的业务类型,比如我司的push业务,每天在固定的时间进行全量push,所以我们完全利用cron hpa在push前自动增加Pod数目,在push 后,降低Pod数目。

原生的HPA,冷却时间是针对controller全局设置的,而Pod扩缩的比例和数目是硬编码在代码中的。而实际中不同的应用程序,其对扩缩容的要求也不同。例如:

  • 关键流量处理应用:该类应用希望在流量到来时快速的扩容,在流量高峰过去后,希望慢慢的缩容,以避免流量反弹。

  • 关键数据处理应用:该类应用希望当大量数据到达时希望快速扩容,在数据减少时,希望快速的缩容,以节省成本。

  • 一些不重要的业务,我们希望缓慢的扩缩,避免抖动,尤其是频繁的扩缩,可能导致Node节点的频繁的扩缩。


所以我们定义了自己的HPA,可以允许研发针对具体的应用设置自己的扩展冷却时间,收缩冷却时间,metrcis计算周期,以及每次伸缩的比例或是固定的个数。

在实际落地过程中,基于CPU和Memory的HPA,并不能很好的满足扩缩要求。所以我们正在开发基于外部metrics的HPA,对接监控系统和公有云厂商的云监控。比如消息队列积压数和QPS。

最后我们知道Kubernetes提供了recreate和rollup两种升级方式。在核心业务上线的过程中,研发更希望通过金丝雀的方式发版。所以我们开发了canary部署。具体思路是,研发开启某个deployment的金丝雀发版,控制器会自动启动指定数目的canary版本Pod,然后研发通过监控和log等方式判断canary的功能是否正常来决定是否对此次金丝雀发版提交或失败回退。

spark-ui-controller

为了落地Spark on Kubernetes,基于Kubernetes watch机制,我们开发了spark-ui-controller,结合泛域名解析,实现查看spark driver的管理UI。

容器及基础设施优化

640?wx_fmt=png

  • 操作系统优化:单机支持百万TCP并发,/etc/sysctl.conf,/etc/security/limits.conf。传统的虚拟机基本上运行一个业务,很多内核参数不需要过多更改,即可满足业务。但是在Kubernetes中,一个Node节点会混跑,此时必须优化一些内核参数,从而满足混跑业务。

  • 基础镜像的优化和把控。一方面,容器镜像的内核参数并不是全部继承了Node主机,所以对于核心高并发业务,必须在镜像内核级再次调优。另外一方面,出于安全的考虑,所以我们专门定制了基础镜像,供业务研发使用。

  • CoreDNS。在实际大集群中,DNS实例数目需要根据集群规模或是Pod数目进行扩缩。但是传统的PHA存在诸多问题,并不适合用于CoreDNS的扩缩。我们选择了dns-horizontal-autoscaler,进行梯度扩缩。此外CoreDNS耗费资源非常小,尤其是在集群规模比较小的时候,及其容易被调度到同一台主机,假如恰好调度到一台上,当由于物理故障,Node节点需要下线的时候,会引起大面积DNS解析失败。所以需要加上Pod的硬反亲和。

  • 修改Docker存储目录和kubelet存储目录到数据盘,做到数据盘和系统盘分离。

  • 配置Node节点的系统预留资源和Kubernetes预留资源,防止雪崩。

  • 对于一些高并发业务,使用Kubernetes svc spec external TrafficPolicy: Local方式,不对客户端IP做SNAT。Local模式性能最优最稳定。

  • 业务优化,主要是容器感知容器分配资源。例如Java程序,我们选择了OpenJDK 8u212版本。对于Go程序,我们设置了CPUs环境变量,而代码中在init函数中根据环境变量值设置GOMAXPROCS。

未来的工作

640?wx_fmt=png

  • 加强应用容灾能力,增加备份和一键恢复功能。

  • 将自研插件和集群管理采用cluster-operator的模式,方便集群管理。进一步提高集群管理者的工作效率。

  • 扩展Kuberntes调度器,增加更丰富的调度方式,比如组调度。

  • Service Mesh试落地和产品化。

  • 我们已经配合大数据团队做了Spark on Kubernetes的实践工作。接着我们将配合基础架构和推荐团队,做好AI on Kubernetes和Flink on Kubernetes等。

Q&A

640?wx_fmt=png

Q: 直接采用物理机还是有先做IaaS层虚拟化?
A:我们做的是出海业务,基本上考虑到合规等问题,我们主要项目全部运行在公有云上。

Q: 有没有碰到调度的问题,某台服务器CPU或内存高了仍调度到这台上?
A:遇到过,一般情况下,需要考虑你的应用是否加了很多亲和性或是nodeSelector。正常的调度器,是会优先考虑资源平衡的。

Q: 请问下,不同云之间的延时怎么解决? 你们是一朵云就部署一个完整的业务么?
A:我们会在不同云之间通过专线打通。基本上相关联的业务会部署在一家云上。但是我们会尽量保证同一个业务部署在不同的AZ。

Q: 告警策略上有没有最佳实践分享?
A:我们的统一报警平台基于Alertmanager实现,基本上用到了它提供的静默、分组、抑制等特性。只不过我们对接了它的API,也集成到SCMP当中。

Q: 配置管理是怎么做到不同环境,不同配置?
A:我们的配置是在ConfigMap结合数据库来实现版本管理,本质上每个集群都需要单独设置。所以不同的环境,设置不同的ConfigMap即可。

Q: Linux内核参数优化具体你们碰到过哪些坑呢,怎么优化的呢? 线上使用的CentOS版本和内核如何选择的?
A:我们使用的是公有云,内核版本一般公有云提供版本中最新的。其实不同的主机类型,相应的参数不一样,需要在选型主机的时候,做大规模测试。比如net.netfiletr下的参数。我们会基于公有云镜像,做优化,然后利用pakcer打成新的镜像使用。

Q: 自研组件,可以开源吗,比如日志的那个?
A:SHAREit是一个技术非常open的单位。我们从上到下,鼓励技术人员去分享。所以如果大家有需要,我们会做一下内部的整理,开源出去。同时,我也会写一些具体的文章,来讲具体的细节。

Q: Alertmanager报警,我使用的Prometheus Operator安装的,使用默认的微信报警,这个报警时区问题,是修改源码解决,还是使用一个webhook? 报警的模板文件是如何管理的?
A:我觉得你应该需要重新定制Alertmanager的镜像,在Dockerfile中修改时区。其实我们这边也fork了Alertmanager,做了一些优化和功能增强,比如直接将DingTalk集成进来,避免引入webhook组件,所以我们也是自己打的镜像。至于报警模板,我们这边先把报警模板数据存放到数据库当中,然后结合confd来实现Alertmanager 配置文件刷新的。

Kubernetes入门与实战培训

640?wx_fmt=png

Kubernetes入门与实战培训将于2019年11月22日在北京开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:Docker基础、容器技术、Docker镜像、数据共享与持久化、Docker实践、Kubernetes基础、Pod基础与进阶、常用对象操作、服务发现、Helm、Kubernetes核心组件原理分析、Kubernetes服务质量保证、调度详解与应用场景、网络、基于Kubernetes的CI/CD、基于Kubernetes的配置管理等等,点击下方图片或者阅读原文链接查看详情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值