• [技术干货] k8s的高可用架构原理
    k8s的高可用架构,也就是扩容多Master架构。这是因为,k8s作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,监控其预期副本数,并根据Node失效状态自动在正常Node启动Pod,实现了应用层的高可用性。Node节点是不需要考虑高可用架构。而Master节点扮演着总控中心的角色,通过不断与工作节点上的Kubelet和kube-proxy进行通信来维护整个集群的健康工作状态。如果Master节点故障,将无法使用kubectl工具或者API任何集群管理而Master节点主要有三个服务kube-apiserver、kube-controller-mansger和kube-scheduler,其中kube-controller-mansger和kube-scheduler组件自身通过选择机制已经实现了高可用,就是说,如果集群里配置了多个kube-controller-mansger和kube-scheduler组件,他们会根据自己的竞争机制选出主用组件。所以Master高可用主要针对kube-apiserver组件,而该组件是以HTTP API提供服务,因此对他高可用实际上与Web服务器类似,增加负载均衡器(如nginx)对其负载均衡即可,而且可以继续水平扩容。针对Kubernetes集群,高可用性还应包含以下两个层面的考虑:Etcd数据库的高可用性和K8s Master组件的高可用性。 而Etcd已经采用多个节点组建集群实现高可用,所以对Master节点高可用就等同于对kube-apiserver的负载均衡的部署实施。
  • [问题求助] kubernetes操作文档错误,此处的源是404
  • [认证交流] 关于 kubernetes的微认证的问题
    这个topic是需要自己搞的?你们是自己购买的,还是使用了代金券啊
  • [认证交流] 【我与华为云认证】微认证之轻松玩转Kubernetes
    Kubernetes作为容器编排工具,简化容器管理,提升工作效率而颇受青睐,我们可以借助云容器引擎CCE平台快速搭建 Kubernetes环境,轻松玩转 Kubernetes。什么是容器?容器为Ap提供独立的、受控的运行环境,是_种轻量级的操作系统虚拟Concept for create environment for software, without disturbing the rest of the core operating system running job filesystem简单的容器: SandBox(沙盒、沙箱)Kubernetes-大海航行的舵手K8s集群主要包括两个部分: Master节点(管理节点)和Node节点(计算节点)Master节点主要还是负责管理和控制。Node节点是工作负载节点,里面是具体的容器。Master节点Master节点提供的集群控制,对集群做出全局性决策,例如调度等。通常在 master节点上不运行用户容器。Master节点包括AP| Server、 Scheduler、 Controller manager、etcdAPI Server:整个系统的对外接囗Scheduler:集群内部的资源进行调度Controller Manager:负责管理控制器etd: Kubernetes的后端存储Node节点节点组件运行在每一个Node节点上,维护运行的pod并提供 kubernetes运行时环境。Node节点包括Pod、 Docker、 kubelet、kube-proy、 Fluent、kube-dns(可选)Pod: Kubernetes最基本的操作单元;Docker:创建容器;Kubelet:负责监视指派到它所在Node上的Pod,包括创建、修改、监控、删除等Kube-proxy:负责为Pod对象提供代理  Fluent:主要负责日志收集、存储与查询。Kubernetes最小管理单元-PoDPod是 Kubernetes管理的最小基础单元。一个Pod中封装了:一个或多个紧耦合的应用容器,存储资源,独立的IP,容器运行的选项相同Pod中的任何容器都将其享相同的名称空间和本地网络。容器可以很容易地与其他容器在相同的容器中进行通信。有状态应用和无状态应用无状态应用有状态的服务,从部署开始,这些容器就开始与上游镜像不同了,时间越长它们的差异越大,每个运行的应用程序都至少有一个小状态,(差异),但对于“无状态”应用程序来说,状态(差异)很小,而目可以进行快速替换有状态应用无状态服务,易于部署且易于扩展。如果流量上升,则只需添加更多的负载平衡上游容器镜像和基础架构中正在运行的容器其实几乎没有区别;可以随时被替代,而且容器实例切换过程中几乎不需要耗费“切换成本
  • Serverless在前端工程化的实践
    为什么要做 Serverless 平台触发这件事情的原因有两部分,第一是趋势,因为前端发展趋势使得前端工程师的工程化效率正在降低,作为基础软件团队,需要思考能否从基础软件层面解决前端的困扰,第二部分是当前前端工程师正面临服务端渲染的问题。首先说趋势,体现在整个前端发展过程中。从以前的 Web 工程师,到前端工程师的职位的出现,当时还只是逻辑分工。第三阶段是前端工程师时代,是一个前后端分离的时代。到我们目前正在处于的前后端(BFF)时代,前端工程师需要去负责部分后端的数据。甚至有些公司已经到了全栈工程师的时代,前端工程师需要负责后端所有的数据。第二阶段和第三阶段,前端人员不需要关心后端资源,只需要把自己的代码写好,由后端或者是运维帮他们去做发布。但是目前所处的阶段,前端人员是需要去关心后端数据的,将来的全栈工程师时代,他们还需要去直接从数据库里边获取 / 操作数据,这个时候我们会发现,他需要操心低层的资源,因为他需要把他的程序跑在服务端的后端,而前端工程师实际上不擅长操作和运维后端资源,因此会使得前端工程师的工程化效率降低。第二点是我们当前正在面临的问题,因为前端工程师目前在做服务端渲染(SSR),采用这个技术的时候他需要自己申请机器,自己部署,同时他还得关注机器的状态,并且他还得时常地翻阅基础设施提供一些运维指南去做运维,其实这个事情是他们很不擅长的,并且对他们来说是一个负担。同时从后端运维的视角来看,前端工程师是在浪费资源。这有两个原因,第一,很多业务属于活动类型的;第二,前端工程师在申请机器的时候,他往往按照上限来预留资源,这就导致了大量的浪费。因此这就产生了“前端工程师在浪费资源”的问题。但其实前端工程师不是故意的,因为他们不擅长运维服务器。因此我们需要解决前端工程师正在面临的痛点。从前端工程师的角度,他们的核心诉求就是只写代码,聚焦核心业务,去创造核心价值,把一些服务端后端运维的事情完全交付给基础设施去做,他们不需要去 care 这个事情。Serverless 的先进理念,其精华正是复杂度转移,使得业务人员能够聚焦他的核心场景,所以我们想打造一款 Serverless 产品,来解决前端工程师当前的困扰。如何打造 Serverless 平台 技术选型打造 Serverless 平台之前,首先要对这个目标做拆解,然后再去做产品选型、技术选型。首先看目标拆解,第一点业务层的需求是即用即上,也就是说前端他想上线一个业务,他不需要去关心太多,他想什么时候上线就可以什么时候上线;第二点就是前端工程师不想去做后端资源的运维;第三点实际上不是前端工程师的需求,而是基础设施层面的一个需求,就是尽量地能支撑好业务,同时也能够省机器省钱。这相对应的目标拆解为:即用即上——需要在技术上具备一键部署的能力;免运维——需要把具体的运维沉淀到基础设施层;节省开支——要求我们这个业务状态相对来说是无状态的,具备高弹性的能力。因此我们的 Serverless 平台要能够集成 CI/CD,同时也能够进行容器化,工作在 Kubernetes 上,具备自动扩缩容的能力。再看产品选型。既然公有云 Serverless 做得这么成熟,我们能否直接采用公有云产品来满足我们业务开发需求?我们的回答是 NO,因为我们需要去满足一些定制化的用户需求,而公有云的 Serverless 产品会受到很多资源包括使用的一些限制;第二个因素是我们的业务存在一些环境依赖,前端所依赖的一些数据库、中间件,都是运行在公司的私有云环境中,这些东西公有云环境上都没有;第三点也是追求技术自由,避免厂商锁定。 所以,我们需要在私有云平台中打造自己的 Serverless 平台。在技术选型上,我们基于三个原因选型了 Knative。底层要基于 Kubernetes: 因为数帆对 Kubernetes 的运维手段比较成熟,本身有大量的业务运行在 Kubernetes 上,我们有专业的团队来做相应的支撑。基于镜像去构建 Serverless: 因为本身的业务是比较灵活多变的,会存在一些程序启动时间比较长的业务,这种业务不是很适合 FaaS。因此我们考虑让它把整个启动过程压缩,通过镜像打包的一种方式来去解决。另外我们还要求易扩展成 FaaS。这些 Knative 都能满足。背景深厚:Knative 后面还有 Google、IBM、Redhat 这些大厂作为支撑。 平台构建轻舟 Serverless 平台设计全景图如下,从下往上有基础设施层、服务层、应用编排层和业务层。其中我们比较关注的是应用编排层和服务层。整个 Serverless 平台工作在已有的基础设施之上,并且我们通过这个 Serverless 平台后端,把它所需要的资源纳入平台组件能力,比如说 CI/CD、Knative API 网关,把这些资源结合起来,满足我们 Serverless 的具体需求。轻舟 Serverless 平台具体的构成,从下图可以看到,Serverless 的核心,我们可以理解成额外做的核心组件,包括一个 Serverless 前端控制台和一个 Serverless 后端。这个核心负责把现有的一些组件联合起来:通过 CI 去完成镜像构建的需求;通过 Knative 去做部署;通过 API 网关去做具体业务的数据链路打通;同时还需要 Gitlab 来存储代码;为了更高的开发效率,需要集成 Web IDE,这样前端开发人员可以只在一个浏览器上就完成他所有的需求;同时为了运维能力,需要去支持平台层面的日志平台,以及监控告警的平台;还需要一些预警,就是 Serverless 跑批和预警的一些组件。轻舟 Serverless 平台在这样的构成下,它具体的流程,我们从业务开发者的视角来看,业务开发者先通过 Web IDE,或者是其他的本地开发工具来完成编码,再把代码 Push 到 GitLab 上去,然后就会触发构建镜像,或者他可以选择手动触发,或者是通过命令行触发。当然这一步也可以把相关的一些资源,降级的静态资源,构建到放到对象存储里面去。Serverless 控制台构建完镜像以后,会通过 Knative 的 Service 去发布这个程序。整个发布过程它会主动地拉取刚才构建的镜像,去做应用的部署和数据链路的打通。这就完成了整个业务的一键部署。一键部署的业务流量模型,首先流量从外网打到外层的基于 Envoy 的 API 网关,API 网关会把流量发给内层的 Knative 网关。随着访问压力的增大,我们要求它能够扩容;而随着资源处在访问的低档期,为了能腾出更多的资源,我们要求它具备缩容的能力。同时这个 Serverless 平台还必须考虑,当这一部分产生了异常的情况下,是否具备降级的能力。我们通过外层的 API 网关去做降级和和静态资源的获取,通过这种方式,如果 Serverless 平台或者 Knative 这一层出了问题,用户可以一键切到已经准备好的静态资源中,不至于让业务产生异常。 产品形态的思考打造 Serverless 平台还有很多必要的考虑。首先平台构建形态方面,为了满足用户的效率需求,我们支持了 FaaS 层平台;为了满足业务复杂又多变的需求,我们支持了传统工程的形态。其中 FaaS 形态最主要的目的是让我们的业务方,特别是前端开发者,可以完全在 Web 浏览器上编码、发布,也就是说他只要身边有一台电脑,通过浏览器就可以随时随地完成他的业务目标,不需要安装一些开发环境。除了这种方式以外,考虑传统使用者的诉求,我们也支持集成到 VS Code 中,同时还支持最传统的通过命令行直接构建 FaaS 的方式,当前我们支持的还只是 Node.js,这个是属于我们用得比较多的技术栈。对于传统工程形态这种方式,Knative 当前是支持的,这种方式最主要的作用是,用户不需要学习新知识就可以直接使用 Serverless,可以像以前一样开发代码,同时它的运营实施比较灵活。一些启动过程很慢的业务,也完全可以采用传统工程形态去做,这样不至于说这类业务没有办法在这个平台上运行。所以说,我们做了这两种产品形态来满足业务方在不同状况下的使用需求。 数据路径的适配因为 Knative 网关只能通过子域名的方式去做业务区分,而我们传统业务,特别是现有的很多线上业务,往往是使用 Host+Path 这种方式去做区分的。为了满足用户的这种使用习惯,我们当然可以修改 Knative 层的开源实现,但是开源又是在不断迭代的,我们考虑再三,做了一些框架结构,通过外置的一层 API 网关去做具体的 Host+Path 的区分,然后转换成 Knative 所支持的子域名方式去做应用区分。同时,我们引入外层的 API 网关还有另一个好处,当 Knative 这一层出问题时,我们可以通过这一层网关去做灰度降级,来保证业务的稳定性。当然,加一层外置网关也会导致数据链路变长,它从外层 API 网关,到内层 Knative 网关,再到 Activator 组件,甚至到 QueueProxy,最后才到业务容器。这样会导致 QPS 比较低,这方面后文我们会给出轻舟团队具体的解决办法。 平台能力的集成平台需要的日志、监控告警、BaaS 等能力,由于轻舟平台已有现成的封装,Serverless 平台直接集成。此外,为了适应 Serverless 这种业务场景,我们额外开发了一个预警的组件,去模拟前端业务方发布一个业务,发布之后把它给部署到 Serverless 平台上,然后检查它能否很好地完成扩缩容。Knative 的实践踩坑和优化接下来分享在打造轻舟 Serverless 平台的过程中,我们对选型的 Knative 这个开源组件所做的事情,主要分为三个部分,第一部分是我们在数据面上做了哪些东西,第二部分是我们在控制面做了哪些优化,第三部分是说使用了 Knative 组件,我们遇到了哪些问题,又是如何解决的。 数据面的优化我们在数据面做的主要工作是数据链路调优。上文也提到 Knative 整个数据链路比较长,我们通过对 Knative 的压测,确定 Knative 的性能有很大的问题。我们通过以下的 5 个步骤来做优化:在整个的数据路径上,把 Activator 从数据路径上去除,因为我们是面向 Web 场景,去除之后不会产生任何业务问题。把 Knative 做升级,从以前的 0.9 升级到 0.14。通过 1 和 2,整个 QPS 提升了大概 50%。为了满足我们一些核心业务对延迟或者是对高性能的需求,我们采用 Fast HTTP 优化了 QueueProxy,把 QueueProxy 的 CPU 使用率降了 50%,同时在降低 CPU 使用率的情况下,它的延迟也降了 30% 左右,QPS 也提升了 30%,也就说使用更少的 CPU,反而带来更多的 QPS 和更低的延迟效果。同时我们做了一个 Revision Deployment 级别的灰度,来降低修改 QeueuProxy 带来的业务风险。在第 3 步优化完 QueueProxy 以后,我们引入了的 Sockops 组件来做框架优化,通过 eBPF 技术实现 QueueProxy 和业务容器之间的 Sidecar 方式的链路优化,QPS 可以在之前的基础上再额外提升 20%,同时延迟降低 8% 左右。针对一些特殊业务需求,我们选型更高性能的容器网络,叫 SR-IOV 网络,来满足它的需求。从我们的实测来看,SR-IOV 容器网络在延迟方面比普通的容器网络大概要降低 10%,同时它的 QPS 是接近物理机的。通过这 5 个步骤,我们满足了不同的业务方的需求。一般来讲,做完 1 和 2 能满足差不多满足一半的业务需求,做完 3 和 4 基本上能满足绝大部分需求,第 5 步是满足一些特殊的业务场景的需求。 控制面的优化控制面上我们主要解决了 Knative ksvc Ready 时间变长的问题。Knative ksvc Ready 时间变长有两个原因。第一个原因是 Serverless Knative 网关,我们采用的是轻舟的 API 网关,它的控制面是依赖于 Pilot,而我们的业务集群又是和服务网格在一起运行的,在默认情况下,Knative 的 Pilot 能感知到服务网格的 VS、DR、SE 这些资源,这就导致了它去做一些无关的资源运算,从而 Knative ksvc Ready 时间变长。第二原因,Knative 有一个组件叫做 network-istio,这个组件需要对整个数据路径去做健康检查,只有在健康检查成功以后它才把 ksvc 置成 Ready 状态。但健康检查有一个特点,它是指数级别回退的,这就导致了如果 5 秒内它没有检查通过,它就只能在 10 秒内才能发现这个东西是健康的;如果它在 10 秒内还没有解决这个问题,检查出来业务已经 Ready 了,它就只能在 20 秒内才能发现业务已经 Ready,这就导致 ksvc Ready 时间变得更长。我们解决的办法有两种,第一种是针对于第一个问题,Knative 网关它只 care 自己的 Namespace 级别的资源,去做一些资源隔离,它不 care 同一个集群内的服务网格的相关的其他资源。第二种就是我们调整了 network-istio 健康检查回退机制,调整成前 20 秒内每秒钟检查一次,20 秒以后才进行指数级回退,通过这种方法防止 ksvc Ready 时间慢的问题。 遇到的困难和解法Knative 层我们主要遇到了如下的困难:Knative 的一个 Autoscaler 组件,它是不支持 HA 的,但是 Knative Autoscaler 组件是扩缩容的核心组件,因此这是业务无法忍受的。一个老生常谈的冷启动问题,我们经过实测,整个的冷启动过程需要 5 秒以上,如果算上拉镜像的时间,甚至可能需要 6~7 秒。做 Knative 适配的时候,和我们内部的容器网络有些冲突,它会导致 Knative 的一些 Webhook 启动失败。适配轻舟 API 网关的时候出现 503 问题。net-isito 组件做完健康检查以后它的连接不会释放,这就导致它的连接大量的堆积,最终导致业务异常。我们的解法如下:针对 Autoscaler 不支持 HA 的问题,我们通过 Pick Knativ0.19 这个版本的一些代码去解决。针对冷启动,我们通过一些预留和一个默认实例来避免冷启动。Webhook 这个问题,最主要是和我们内部容器网络的冲突,我们通过调整网络方式为 hostNetwork 来规避。适配轻舟 API 网关出现 503,最主要也是 Knative 本身的一些问题,因为网关的控制面上存在一些特殊符号,它没有办法识别,这种情况下 0.14 版本的 Network-isito 就没有办法继续往下工作,不过这个问题在 Knative0.15 得到了修复。健康检查连接不释放,这也在 Knative 0.15 得到了解决。当然我们在一开始踩这个坑的时候,Knative 社区还没有解决这些问题,后面我们解决完问题以后,发现社区也已经解决了。所以说我们也是通过检验了,因为我们是尽量地少动 Knative 本身的代码,也是通过这种升级的方式来解决的。    收益    目前轻舟 Serverless 平台在内部已经上线了大概 200 多个前端应用,当然在 2020 年的 Q4 我们也 Release 了一个商业化版本满足对外的需求。我们做完这个事情以后,前端人员的体验是怎么样的呢?首先,我们从前端人员那边收集到的数据,他们以前去部署环境,新员工可能要两周左右,老员工也要三天左右,有了 Serverless 平台,整个部署时间统一降低到三分钟内搞定。其次,因为 Serverless 平台的一些封装使得了前端人员不再需要关注后端资源,所以说他们从业务选型上,可以考虑一些服务端渲染的技术来提升业务的首屏体验。再次,从趋势上来说,免去运维的困扰更加符合前端趋势,这让前端人员可以轻松地去开发 BFF 层的一些需求,甚至可以支撑他们往全栈工程师去过渡,通过这些支持给前端提供一个更大的灵活度。未来展望展望未来,我们需要在公司内部业务场景继续打磨轻舟 Serverless 平台,让它变得更加稳定,功能更加强大,主要聚焦三个方面:首先我们会提升 Serverless 平台的产品能力,考虑使用 Knative 的 Eventing 组件,去融合我们的轻舟中间件、对象存储这些底层设施的资源,来满足业务更加多变的需求。其次是我们 Serverless 平台上线以后,前段时间业务方反馈它整个的调试化过程的效率降低了,所以我们打算提供一些本地的调试套件去解决调试的困扰。最后,我们会紧跟着 Knative 社区,关注 Knative FaaS Kn 的实现,同时也考虑去对接公有云的一些 Serverless Framwork,一些 API 规范标准,这样将来如果业务方有需求,它完全可以无感地从私有云平台上迁到公有云平台上,所以我们打算做这么一层封装。
  • [技术干货] 混合云、边缘计算走向主流
    2021年3月22日,业界应用最为广泛的企业级Kubernetes管理平台Rancher发布了2020年Kubernetes行业调研报告,研究结果表明,2020年,更多的受访者在混合云环境中使用Kubernetes 运行容器,与此同时,更多的企业将功能和服务部署至边缘,最终进一步推动企业IT现代化的进程。2019年和2020年,Rancher分别对近1,000名专业人员展开了调查。调查结果表明,Kubernetes在不同行业连续两年保持了90%以上的采用率,而生产环境中的容器采用率从2019年的85%增长至2020年的87%。“从调研结果可以清晰地看到,用户持续推动容器在混合云和多云环境落地,92%的受访者将容器作为DevOps、IT运维、IT架构、应用程序开发和基础架构转型的关键部分。”Kubernetes和云:真实环境下的真实工具近1,000名在技术、工程、电信、银行、网络安全和咨询等行业工作的专业人员的反馈,他们主要专注于实现DevOps、IT运维、IT架构、应用程序开发和基础架构转型,92%的受访者选择使用容器来实现这些目标。另一方面,这些受访者均更倾向于采用Rancher所推出的Kubernetes发行版。36%的受访者将RKE作为其Kubernetes发行版,而32%的受访者使用K3s。受访者指出,在容器快速发展的大前提下,多层级控制和功能是RKE被广泛采用的关键原因。推动传统IT架构现代化受访者表示,容器化是推动传统IT现代化的关键路径。49%的受访者通过容器实现传统IT应用程序的现代化,而67%的受访者利用容器设计基于微服务的应用程序。通过使用Kubernetes,企业可以将使用了数十年的传统IT系统转化为基于微服务的容器应用程序,并通过Kubernetes进行编排。迁移到Kubernetes还可以使开发团队并行工作,从而减少了重复的可能性,简化开发并加速部署。在混合云环境中,开发团队还可以通过云托管集群完全替代某些本地工作负载,这些集群可以在像Rancher一样的Kubernetes管理平台上运行和管理,进一步实现IT架构现代化的战略。推动边缘环境生产落地容器在生产环境中的采用率逐步增长,也覆盖到了应用端。基于此,许多受访者使用容器来为客户提供各种服务,包括应用程序、边缘计算、混合/多云应用程序、内部应用程序、传统应用程序现代化和将传统应用程序迁移上云等。K3s等体积较小的Kubernetes已经使企业可以更容易地将功能和服务部署至边缘,它赋予了组织从试点项目转向生产环境的能力,并使其能够根据需要进行扩展。2020年,62%的受访者在边缘使用K3s,去年这一比例仅为50%。随着混合云网络的成熟,客户可以部署面向客户的云原生微服务应用程序,所需的维护量更少,迭代次数更多,并且可以随时间轻松添加新功能。我们完全有理由相信,在面向客户的环境中几乎完全采用由Kubernetes管理的容器的这一趋势将持续发展。结论随着公司将他们的网络、应用程序和流程发展成为一个更现代的框架,他们发现无论环境如何,Kubernetes 都可以随之改变。世界各地的组织正在利用 Kubernetes 解决方案来创建一个云原生微服务集群。他们还对单体系统进行现代化,建立强大的云架构,同时无缝管理现有集群。这是向加速和保护应用程序的时代迈进的一步,同时赋予了DevOps和工程团队利用未来“更聪明地工作”而不是“更努力地工作”的能力。“容器及Kubernetes是混合云时代软件定义基础架构的最佳选择,它们不仅能帮助企业实现传统IT基础架构的容器化改造,还能帮助企业释放混合云的全部价值。”通过结合容器及Kubernetes的可靠性和灵活性推动企业在任意场景进行无限创新,从而推动创新无处不在。”文章转载自:https://tech.china.com/article/20210325/032021_738288.html
  • Loki和Fluentd的那点事儿
    跟大家分享下loki跟fluentd结合的一些实践。为什么是FluentdFluentd是一个由云原生基金会(CNCF)管理的统一日志层数据收集器。它可以从多种数据源里采集、处理日志,并集中将它们存储到文件或者数据库当中。其主要的目的也是让你的基础设施能够实现统一的数据收集和分发,以便业务可以更好的使用和理解数据。作为第六个从CNCF里面毕业的项目,fluentd拥有大量的数据处理插件和生产环境的实践指导,同时还有GKE和AWS这样公有云大厂应用为其背书,小白毅然的选择了fluentd作为我们kubernetes上唯一日志采集器。Loki插件Loki为fluetnd提供了一个输出插件fluent-plugin-grafana-loki,它可以将采集到的日志传送到Loki实例当中。当然,在实际的应用当中,还需需要我们自己去构建fluentd的docker镜像, 那么我们需要将下面几行加入到自己的dockerfile里面# 必要的loki输出插件和kubernetes元数据插件gem install fluent-plugin-grafana-lokigem install fluent-plugin-kubernetes_metadata_filter# 小白建议安装的prometheus,字段修改和tag修改插件gem install fluent-plugin-prometheusgem install fluent-plugin-record-modifiergem install fluent-plugin-rewrite-tag-filter采集流程按照Kubernetes上运行应用的日志一般建议Kubernetes 无状态应用的一般特征应用不应继续把日志输出到本地文件,而应该输出到 stdout 和 stderr;集群应该针对容器的 stdout、stderr 提供统一的日志采集,建议使用 Daemonset 而非 Sidecar;进行日志采集的同时,集群应提供 ES、Loki 或其它类似机制来对日志进行处理,并且其处理和存储能力应该有初步预案;应用日志应提供分级开关,保证同一镜像在不同环境中可以输出不同数量和级别的日志信息。小白将fluentd在k8s上的采集流程设计如下:Pre Input阶段默认情况下docker会将容器的stdout/stderr日志重定向到/var/lib/docker/containers,其日志也为json格式如下{    "log":"xxxxxxxxxxx",    "stream":"stdout",    "time":"2020-09-15T23:09:04.902156725Z"}对于将fluentd部署在node上的同学则需要将node的这个目录映射到容器内。# fluentd的workerload中关于映射容器标准输入的volume...volumeMounts:- mountPath: /var/lib/docker/containers  name: varlibdockercontainersvolumes:- hostPath:    path: /var/lib/docker/containers    name: varlibdockercontainers...Input阶段在采集阶段, 利用fluentd的in_tail插件对docker标准输出采集即可,参照如下:<worker 0>  <source>    @type tail    @id input.containers.out    path /var/log/containers/*.log    exclude_path ["/var/log/containers/*fluentd*.log"]    pos_file /var/log/fluentd/container.out.pos    limit_recently_modified 86400    read_from_head true    tag kubernetes.*    <parse>      @type json      time_key time      time_format %Y-%m-%dT%H:%M:%S.%NZ      utc true    </parse>  </source></worker>Fluentd可以通过定义<worker>标签来支持多进程并发采集,如果你的node上是容器密度和小白一样大,我们就创建两个worker来同时采集docker日志,参照如下:<worker 0>  <source>    @type tail    @id input.containers.out.0    path /var/log/containers/*[0-7].log    exclude_path ["/var/log/containers/*fluentd*.log"]    pos_file /var/log/fluentd/container.out.pos.0    limit_recently_modified 86400    read_from_head true    tag kubernetes.*    <parse>      @type json      time_key time      time_format %Y-%m-%dT%H:%M:%S.%NZ      utc true    </parse>  </source></worker><worker 1>  <source>    @type tail    @id input.containers.out.1    path /var/log/containers/*[8-f].log    exclude_path ["/var/log/containers/*fluentd*.log"]    pos_file /var/log/fluentd/container.out.pos.1    limit_recently_modified 86400    read_from_head true    tag kubernetes.*    <parse>      @type json      time_key time      time_format %Y-%m-%dT%H:%M:%S.%NZ      utc true    </parse>  </source></worker>提醒,默认情况下docker没有对容器标准输出的日志存储空间做限制。但实际情况下,我们为了避免生产环境容器日志占满服务器磁盘,会通过修改docker daemon的启动参数--log-opt=10G来限制容器的最大输出日志空间。这里对于fluentd来说,如果在采集停滞时间内容器的日志桶被完全轮转,那么就会出现日志丢失的风险。对于该如何调整参数,小白建议按照大家自己公司情况合理规划即可。Filter阶段Filter阶段主要用来处理日志采集之后的kubernetes元数据标注以及修改、提取自定义字段,这里面主要用了两个插件fluent-plugin-kubernetes_metadata_filter和fluent-plugin-record-modifier来处理以上逻辑。kubernetes_metadata主要作用为提取tag中的关键信息来向kubernetes查询Pod和Namespace上的Label,并将其添加到日志的json结构体内,它的配置可参照如下:<filter kubernetes.var.log.containers.**>  @type kubernetes_metadata  @id kubernetes_metadata_container_out  skip_container_metadata true  skip_master_url true  cache_size 3000  cache_ttl 1800</filter>metadata插件有Cache的机制,大家根据自己集群的规模合理调整cache的容量和cache的过期时间。正常情况下,metadata插件会watch k8s api来更新cache,如果出现新部署的容器日志没有相关标签,那么你可能需要再等一会或者重启fluentd客户端可以解决record_modifier主要用于提取和修改kubernetes元数据标签,修改成我们自定义的字段,这些字段可以为后面存储在Loki的里面的Label提前建立好索引规则。这部分可参考小白下面的配置:<match kubernetes.var.log.containers.**>  @type record_modifier  @id label.container.out  tag ${record.dig('k8s_std_collect') ? 'loki.kubernetes.var.log.containers' : 'dropped.var.log.containers'}  <record>    k8s_container_id ${record.dig("docker", "container_id")}    k8s_cloud_cluster "#{ENV['CLOUD_CLUSTER'] || 'default'}"    k8s_node ${record.dig('kubernetes', 'host')}    k8s_container_name ${record.dig('kubernetes', 'container_name')}    k8s_app_name ${record.dig('kubernetes', 'labels', 'app_kubernetes_io/name')}    k8s_svc_name ${record.dig('kubernetes', 'labels', 'app')}    k8s_pod_name ${record.dig('kubernetes', 'pod_name')}    k8s_namespace_name ${record.dig('kubernetes', 'namespace_name')}    k8s_image_version ${record.dig('kubernetes', 'labels', 'app_image_version')}    k8s_std_collect ${record.dig("kubernetes", "labels", "log-collect") or false}    formated_time "${Time.at(time).to_datetime.iso8601(9)}"    fluentd_worker "#{worker_id}"  </record>  remove_keys docker,kubernetes   //删除原生metadata字段</match>大部分情况下,我们对运行在kubernetes里面的workerload都有自己特定的labels规范,并且这部分内容通常被CD系统集成在发布模板当中。这里大家可以按照自己公司情况构建日志索引结构,当然你可以参考小白定的label规范:...metadata:   labels:    app: <componet_name>   //组件名    app.kubernetes.io/name: <app_name>   //应用名    app.kubernetes.io/version: <app_release>  //应用版本spec:  template:    metadata:      labels:        app: <componet_name>        app.image.version: <componet_image_tag>        app.kubernetes.io/name: <app_name>        log-collect: "true"   //日志采集开关...注意:log-collect可以灵活控制容器是否需要做日志采集,如果不需要控制,可以忽略此标签,同时还需修改record_modifier中的tag处理逻辑如下tag loki.kubernetes.var.log.containersOutput阶段在此阶段,基本上由fluentd采集的日志已经完成了索引构建,我们只需匹配相关的tag将其转发指定的上游数据服务即可,这里我们当然用fluent-plugin-grafana-loki插件将日志抓发给Loki存储。loki插件提供了比较丰富label和buffer参数调试,这里关于Loki的label小白可以直接采用按照前面自定义规则里面的标签即可,参照如下:<match loki.**>  @type loki  @id loki.output  url "http://loki:3100"  remove_keys topic,k8s_std_collect,formated_time,k8s_container_id  drop_single_key true  <label>    stream    k8s_cloud_cluster    k8s_container_name    k8s_node    k8s_app_name    k8s_svc_name    k8s_pod_name    k8s_image_version    k8s_namespace_name </label>  <buffer label>    @type file    path /var/log/fluentd-buffers/loki.buffer    flush_mode interval    flush_thread_count 4    flush_interval 3s    retry_type exponential_backoff    retry_wait 2s    retry_max_interval 60s    retry_timeout 12h    chunk_limit_size 8M    total_limit_size 5G    queued_chunks_limit_size 64    overflow_action drop_oldest_chunk  </buffer></match>关于Buffer的配置,大部分情况下我们可以不用关心,不过你还记得前面小白说的关于docker日志桶的参数配置不当引起丢失日志的风险吗?这里的buffer配置可以根据情况缓解这类问题走到这里我们基本完成了在k8s上较为云原生方式的日志采集架构。另外值得一提的是,Loki本身支持对多租户日志分级存储,如若你的kubernetes平台是基于多租户管理的,那么你可以将租户信息提取出来引入到loki当中。
  • Jenkins 大叔与 kubernetes 船长手牵手
    背景虽然云原生时代有了 JenkinsX、Drone、Tekton 这样的后起之秀,但 Jenkins 这样一个老牌的 CI/CD 工具仍是各大公司主流的使用方案。比如我司的私有云产品打包发布就是用这老家伙完成的。然而传统的 Jenkins Slave 一主多从方式会存在一些痛点,比如:每个 Slave 的配置环境不一样,来完成不同语言的编译打包等操作,但是这些差异化的配置导致管理起来非常不方便,维护起来也是比较费劲资源分配不均衡,有的 Slave 要运行的 job 出现排队等待,而有的 Slave 处于空闲状态资源有浪费,每台 Slave 可能是物理机或者虚拟机,当 Slave 处于空闲状态时,也不会完全释放掉资源。正因为上面的 Jenkins slave 存在这些种种痛点,我们渴望一种更高效更可靠的方式来完成这个 CI/CD 流程,而 Docker 虚拟化容器技术能很好的解决这个痛点,又特别是在 Kubernetes 集群环境下面能够更好来解决上面的问题:Jenkins Master 时以 docker-compose 的方式运行在一个节点上。Jenkins Slave 以 Pod 形式运行在 Kubernetes 集群的 Node 上,并且它不是一直处于运行状态,它会按照需求动态的创建并自动删除。这种方式的工作流程大致为:当 Jenkins Master 接受到 Build 请求时,会根据配置的 Label 动态创建一个运行在 Pod 中的 Jenkins Slave 并注册到 Master 上,当运行完 Job 后,这个 Slave 会被注销并且这个 Pod 也会自动删除,恢复到最初状态。那么我们使用这种方式带来了以下好处:动态伸缩,合理使用资源,每次运行 Job 时,会自动创建一个 Jenkins Slave,Job 完成后,Slave 自动注销并删除容器,资源自动释放,而且 Kubernetes 会根据每个资源的使用情况,动态分配 Slave 到空闲的节点上创建,降低出现因某节点资源利用率高,还排队等待在该节点的情况。扩展性好,当 Kubernetes 集群的资源严重不足而导致 Job 排队等待时,可以很容易的添加一个 Kubernetes Node 到集群中,从而实现扩展。上面的大半段复制粘贴自 基于 Jenkins 的 CI/CD (一)kubernetes 集群关于 kubernetes 集群部署,使用 kubeadm 部署是最为方便的了,可参考我很早之前写过的文章《使用 kubeadm 快速部署体验 K8s》,在这里只是简单介绍一下:使用 kubeadm 来创建一个单 master 节点的 kubernets 集群root@jenkins:~ # kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.20.11集群成功部署完成之后会有如下提示:Your Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:  mkdir -p $HOME/.kube  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config  sudo chown $(id -u):$(id -g) $HOME/.kube/config查看节点状态和 pod 都已经正常root@jenkins:~ # kubectl get pod -ANAMESPACE     NAME                              READY   STATUS    RESTARTS   AGEkube-system   coredns-f9fd979d6-9t6qp           1/1     Running   0          89skube-system   coredns-f9fd979d6-hntm8           1/1     Running   0          89skube-system   etcd-jenkins                      1/1     Running   0          106skube-system   kube-apiserver-jenkins            1/1     Running   0          106skube-system   kube-controller-manager-jenkins   1/1     Running   0          106skube-system   kube-proxy-8pzkz                  1/1     Running   0          89skube-system   kube-scheduler-jenkins            1/1     Running   0          106sroot@jenkins:~ # kubectl get nodeNAME      STATUS   ROLES    AGE    VERSIONjenkins   Ready    master   119s   v1.19.8去除 master 节点上的污点,允许其他的 pod 调度在 master 节点上,不然后面 Jenkins 所创建的 pod 将无法调度在该节点上。kubectl taint nodes $(hostname) node-role.kubernetes.io/master:NoSchedule-Jenkins master至于 Jenkins master 的部署方式,个人建议使用 docker-compose 来部署。运行在 kubernetes 集群集群中也没什么毛病。但从个人运维踩的坑来讲,还是将 Jenkins master 独立于 kubernetes 集群部署比较方便 。docker-compose.yamlversion: '3.6'services:  jenkins:    image: jenkins/jenkins:2.263.4-lts-slim    container_name: jenkins    restart: always    volumes:      - ./jenkins_home:/var/jenkins_home    network_mode: host    user: root    environment:      - JAVA_OPTS=-Duser.timezone=Asia/Shanghai使用 docker-compose up 来启动,成功启动后会有如下提示,日志输出的密钥就是 admin 用户的默认密码,使用它来第一次登录 Jenkins。jenkins    | 2021-03-06 02:22:31.741+0000 [id=41] INFO jenkins.install.SetupWizard#init:jenkins    |jenkins    | *************************************************************jenkins    | *************************************************************jenkins    | *************************************************************jenkins    |jenkins    | Jenkins initial setup is required. An admin user has been created and a password generated.jenkins    | Please use the following password to proceed to installation:jenkins    |jenkins    | 4c2361968cd94323acdde17f7603d8e1jenkins    |jenkins    | This may also be found at: /var/jenkins_home/secrets/initialAdminPasswordjenkins    |jenkins    | *************************************************************jenkins    | *************************************************************jenkins    | *************************************************************登录上去之后,建议选择 选择插件来安装,尽可能少地安装插件,按需安装即可。在 Jenkins 的插件管理那里安装上 kubernetes 插件接下来开始配置 Jenkins 大叔如何与 kubernetes 船长手牵手 ‍‍ :-)。配置 kubernets 的地方是在 系统管理 > 节点管理 > Configure Clouds。点击 Add a new cloud,来添加一个 kubernetes 集群。配置连接参数参数值说明名称kubernetes也是后面 pod 模板中的 cloud 的值凭据kubeconfig 凭据 id使用 kubeconfig 文件来连接集群Kubernetes 地址默认即可Use Jenkins Proxy默认即可Kubernetes 服务证书 key默认即可禁用 HTTPS 证书检查默认即可Kubernetes 命名空间默认即可WebSocket默认即可Direct Connection默认即可Jenkins 地址http://jenkins.k8s.li:8080Jenkins pod 连接 Jenkins master 的 URLJenkins 通道50000Jenkins JNLP 的端口,默认为 50000Connection Timeout默认即可Jenkins 连接 kubernetes 超时时间Read Timeout默认即可容器数量默认即可Jenkins pod 创建的最大数量Pod Labels默认即可Jenkins pod 的 lables连接 Kubernetes API 的最大连接数默认即可Seconds to wait for pod to be running默认即可等待 pod 正常 running 的时间在 Jenkins 的凭据那里添加上 kubeconfig 文件,凭据的类型选择为 Secret file,然后将上面使用 kubeadm 部署生成的 kubeconfig 上传到这里。点击连接测试,如果提示 Connected to Kubernetes v1.19.8 就说明已经成功连接上了 kubernetes 集群。关于 pod 模板其实就是配置 Jenkins Slave 运行的 Pod 模板,个人不太建议使用插件中的模板去配置,推荐将 pod 的模板放在 Jenkinsfile 中,因为这些配置与我们的流水线紧密相关,把 pod 的配置存储在 Jenkins 的插件里实在是不太方便;不方便后续的迁移备份之类的工作;后续插件升级后这些配置也可能会丢失。因此建议将 pod 模板的配置直接定义在 Jenkinsfile 中,灵活性更高一些,不会受 Jenkins 插件升级的影响。总之用代码去管理这些 pod 配置维护成本将会少很多。Jenkinsfile流水线 Jenkinsfile,下面是一个简单的任务,用于构建 webp-server-go项目的 docker 镜像。// Kubernetes pod template to run.def JOB_NAME = "${env.JOB_NAME}"def BUILD_NUMBER = "${env.BUILD_NUMBER}"def POD_NAME = "jenkins-${JOB_NAME}-${BUILD_NUMBER}"podTemplate(# 这里定义 pod 模版){ node(POD_NAME) {    container(JOB_NAME) {      stage("Build image") {        sh """#!/bin/bash          git clone https://github.com/webp-sh/webp_server_go /build          cd /build          docker build -t webps:0.3.2-rc.1 .        """      }    }  }}pod 模版如下,将模板的内容复制粘贴到上面的 Jenkinsfile 中。在容器中构建镜像,我们使用 dind 的方案:将 pod 所在宿主机的 docker sock 文件挂载到 pod 的容器内,pod 容器内只要安装好 docker-cli 工具就可以像宿主机那样直接使用 docker 了。podTemplate(  cloud: "kubernetes",  namespace: "default",  name: POD_NAME,  label: POD_NAME,  yaml: """apiVersion: v1kind: Podspec:  containers:  - name: ${JOB_NAME}    image: "debian:buster-docker"    imagePullPolicy: IfNotPresent    tty: true    volumeMounts:    - name: dockersock      mountPath: /var/run/docker.sock  - name: jnlp    args: ["\$(JENKINS_SECRET)", "\$(JENKINS_NAME)"]    image: "jenkins/inbound-agent:4.3-4-alpine"    imagePullPolicy: IfNotPresent  volumes:  - name: dockersock    hostPath:      path: /var/run/docker.sock""",)构建 debian:buster-docker 镜像,使用它来在 pod 的容器内构建 docker 镜像,使用的 Dockerfile 如下:FROM debian:busterRUN apt update \    && apt install -y --no-install-recommends \        vim \        curl \        git \        make \        ca-certificates \        gnupg \    && rm -rf /var/lib/apt/lists/*RUN curl -fsSL "https://download.docker.com/linux/debian/gpg" | apt-key add -qq - >/dev/null \    && echo "deb [arch=amd64] https://download.docker.com/linux/debian buster stable" > /etc/apt/sources.list.d/docker.list \    && apt update -qq \    && apt-get install -y -qq --no-install-recommends docker-ce-cli \    && rm -rf /var/lib/apt/lists/*定义好 jenkinsfile 文件并且构建好 pod 模板中的镜像后,接下来我们开始使用它来创建流水线任务。流水线在 Jenkins 上新建一个任务,选择任务的类型为 流水线将定义好的 Jenkinsfile 内容复制粘贴到流水线定义 Pipeline script 中并点击保存。在新建好的 Job 页面点击 立即构建 来运行流水线任务。在 kubernetes 集群的机器上使用 kubectl 命令查看 pod 是否正常 Runningroot@jenkins:~ # kubectl get podNAME                              READY   STATUS    RESTARTS   AGEjenkins-webps-9-bs78x-5x204   2/2     Running   0          66sJob 正常运行并且状态为绿色表明该 job 已经成功执行了。在 kubernetes 集群机器上查看 docker 镜像是否构建成功root@jenkins:~ # docker images | grep webpswebps                                0.3.2-rc.1          f68f496c0444        20 minutes ago      13.7MB踩坑pod 无法正常 RunningRunning in Durability level: MAX_SURVIVABILITY[Pipeline] Start of Pipeline[Pipeline] podTemplate[Pipeline] {[Pipeline] nodeCreated Pod: kubernetes default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Scheduled] Successfully assigned default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r to jenkins[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Pulling] Pulling image "debian:buster"[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Pulled] Successfully pulled image "debian:buster" in 2.210576896s[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Created] Created container debian[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Started] Started container debian[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Pulling] Pulling image "jenkins/inbound-agent:4.3-4-alpine"Still waiting to schedule task‘debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r’ is offline[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Pulled] Successfully pulled image "jenkins/inbound-agent:4.3-4-alpine" in 3.168311973s[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Created] Created container jnlp[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-9wm0r][Started] Started container jnlpCreated Pod: kubernetes default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Scheduled] Successfully assigned default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m to jenkins[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Pulled] Container image "debian:buster" already present on machine[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Created] Created container debian[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Started] Started container debian[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Pulled] Container image "jenkins/inbound-agent:4.3-4-alpine" already present on machine[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Created] Created container jnlp[Normal][default/debian-35a11b49-087b-4a8c-abac-bd97d7eb5a1f-fkmzq-qdw4m][Started] Started container jnlp这是因为 Jenkins pod 中的 jnlp 容器无法连接 Jenkins master。可以检查一下 Jenkins master 上 系统管理 > 节点管理 > Configure Clouds 中 Jenkins 地址 和 Jenkins 通道 这两个参数是否配置正确。结束到此为止,我们就完成了让 Jenkins 大叔与 kubernetes 船长手牵手 ‍‍ 啦!上面使用了一个简单的例子来展示了如何将 Jenkins 的 Job 任务运行在 kubernetes 集群上,但在实际工作中遇到的情形可能比这要复杂一些,流水线需要配置的参数也要多一些。那么我将会在下一篇博客中再讲一下高级的用法:使用 Jenkins 完成 kubespray 离线安装包打包。
  • [技术干货] 【智简联接,万物互联】华为云·云享专家张玉云:万物互联只是第一步,IoT的价值点在“物”会思考
    每天早晨,闹铃一响,窗帘自动拉开,屋外的阳光洒在自动播放早间新闻的床头音箱上。这是一个最简单的智能家居场景,也是最为典型的物联网应用,以家庭为平台,人与物、物与物之间能够互相通信,设备间可以对一个事件进行联动处理,极大方便我们的生活。不过,在资深系统工程师张玉云看来,IoT的万物互联只是第一步,让每个“物”都会学习、能思考,为人类社会产生价值,这才是物联网的价值点。 IoT的第一步:物和物的联接当研究操作系统的工程师碰上IoT会擦出什么火花?张玉云可以给出一个可参考的答案,有着三年操作系统维护,一年容器经验的他,既从事过欧拉操作系统外围包的维护,也定位过系统启动、运行等各层面的问题,这让他养成了一种全局观的思维意识:从系统维度去思考问题,从而更快地理解整个系统。举个例子,智能家居和智慧园区两个场景下的IoT联接,不仅规模数量不同,而且在系统性设计方面,也是各有乾坤。智能家居如果仅仅以家庭为单位,WiFi已经可以提供足够的设备接入能力,以及理想的信号覆盖范围。但是扩展到更大的地域范围,比如智慧园区,就需要系统性设计IoT各设备间的通信以及数据处理功能。在一个园区中,各类传感器采集到的数据,会通过网关设备进行数据清洗,然后再发往云平台完成遥测数据的上报。云平台上的数据,利用大数据等技术做进一步分析处理,让它们产生价值。这其中关键的环节包括数据的采集、上传以及分析。张玉云提到了华为云IoTDA云服务,其提供的物模型概念,可以很轻松地完成设备的抽象建模,定义设备的属性/命令,平台侧无需编码就能理解设备。再配合编解码插件,能够适应更多场景要求。另外,边缘侧可利用华为云提供的SDK完成设备的注册、数据上报等,也很方便。在实际应用中,他也提出了一些产品优化建议,比如IoT上报数据的展示部分是缺失的,需搭配其他云服务进行使用。同时,张玉云和我们分享了一个具体落地的案例,“之前工作中接触过一家传统设备生产厂商,典型的设备覆盖食品加工全过程。基于数字化转型的需求,需要对已有MES系统的数据加以清洗整理后发往平台,再从云端加以存储分析,以便挖掘其中的价值。我们基于华为云提供的云服务,很快为客户提供了解决方案,较好地贴合客户的业务场景。” IoT的第二步:“物”学会思考纯粹的“云—端”模式的物联网架构,存在着实时性、安全性以及成本居高不下的难题,此时如果要让IoT设备端产生的数据可以就近直接分析处理,让“物”学会思考,就需要边缘计算、5G等技术的加入。在张玉云看来,随着地理空间的扩大以及设备规模的增大,搭建局域网使这些设备接入网络的成本也在急剧增加。5G突破了地理位置限制的同时,提供了海量的设备接入能力,理所当然地成为智慧城市等项目网络层的解决方案。随着5G的普及,相信它会大大促进物联网的发展。参与项目的过程中,张玉云发现边缘计算也成为了不少客户关注的香饽饽。边缘计算减少了发往云平台的数据流量、节约成本的同时,使得事件更快地被处理。当前,市面上有不少开源的边缘框架正在帮助开发者完成相关的产品开发,这里就不得不提一嘴华为云开源的KubeEdge。KubeEdge基于kubernetes构建,也是CNCF首个提供云原生智能边缘计算能力的开源项目,它在架构上分为三个部分,其中云端负责云上应用和配置的校验、下发,边缘侧则负责运行边缘应用和管理接入设备,设备端运行各种边缘设备。它能完整的打通边缘计算中云、边、设备协同的场景。张玉云简单描述了它的工作原理,将部署KubeEdge的网关设备理解成node注册给kubernetes平台,所有网关设备又组成一个大的集群,这样的话,对有kubernetes经验的人员来说是零学习成本。张玉云认为,使用kubernetes原生的方式进行管理,还是极具创新精神的。不过,开源产品也存在诸多待改善的地方,需要开源社区的开发者们共同去发现、优化它。张玉云就提到了KubeEdge一些让他难以接受的“功能”,按照kubernetes网络模型,Pods之间无需NAT转换即可互相通讯,由于当前CNI支持的缺失,导致边缘侧Pod中的应用无法直接使用PodIP对接平台。除此之外,如何让边缘侧网关自动发现加入集群,将所有边缘网关组合形成一个集群进行管理,这样做是否有意义,也需要社区进一步讨论使之明朗。结语总而言之,即便当前的IoT工具产品还有待优化,但瑕不掩瑜,在经历了N个loT产品开发后,张玉云最后感慨道,“物联网包含的可能性是其魅力所在,或许,无人驾驶正在离我们越来越近,让我们拭目以待吧。”
  • 有状态应用管理
            以容器为代表的云原生技术,用开放、标准的技术体系,帮助企业和开发者在云上构建和运行可弹性扩展、容错性好、易于管理、便于观察的系统,已经成为释放云价值的最短路径。通过声明式API 和控制器模式(Controller Pattern),Kubernetes 构建出一套“面向终态”的编排体系,已经成为容器编排的事实标准,为用户提供了敏捷、弹性、可移植性等核心价值,被广泛用于自动部署、扩展和管理容器化应用。无状态应用容器化已是非常普遍地现状,但由于有状态应用基本上都是分布式的,其生命周期管理比无状态应用会复杂很多。        Kubernetes 现有资源类型无法实现有状态应用的合理抽象与描述,有状态应用对外部资源具有一定的绑定性依赖,多个实例之间往往有着拓扑关系,且这些实例本身并不完全等价。Kubernetes 内置的StatefulSet 资源类型在管理有状态应用方面仅解决了启动顺序、存储状态依赖性,无法实现应用“状态”的合理的抽象与描述,状态和容器进程本身无法解耦;有状态应用的管理经验无法得到有效沉淀,在当前环境下,开发者不得不去尝试编写一套复杂的管理脚本,而这些脚本、知识、和经验,并没有一个很好的办法能够有效的沉淀下来。这一现状制约着云原生应用更广泛的普及。        面向交付及运维的Operator 技术提供了打包、部署、管理Kubernetes 应用的全新方式。Operator 一种通过扩展Kubernetes 的资源模型,引入自定义控制器,实现对资源及其状态的灵活控制的技术。 Operator 把控制器模式的思想贯彻得更加彻底,在CRD 基础上加上自定义控制器,实现丰富、可扩展的调度及运维功能。Operator的本质是一段代码,这段代码通过实现Kubernetes 的控制器模式,来保证这个CRD 资源始终跟用户的定义完全相同,而在这个过程中,Operator 也有能力利用Kubernetes 的存储、网络插件等外部资源,协同的为应用状态的保持提供帮助。来源:云原生产业联盟
  • [技术干货] Red Hat将Ansible自动化引入Kubernetes
    2020年10月13日上午11:02,作者:Mike MelansonRed Hat的Ansible自动化平台很快就会来到您附近的OpenShift Kubernetes集群。本周在AnsibleFest上,redhat预览了Ansible与高级集群管理(ACM)的集成,ACM是一个用于管理和扩展OpenShift集群的工具,该工具在今年早些时候发布。ACM提供了生命周期集群管理、基于策略的管理和高级应用程序部署,通过添加Ansible,Red Hat OpenShift用户现在可以在这些生命周期中直接插入Ansible自动化,而不需要特殊脚本或其他方法。“您可以在OpenShift环境中始终使用Ansible,但我们在这里所做的是将其插入工具。例如,在创建集群生命周期的过程中,有一个地方可以实际配置Ansible脚本,使其在适当的时间点运行,”Red Hat管理业务部门的副总裁兼总经理Joe Fitzgerald解释说。“您以前也可以这样做,但问题是,当有人去配置集群时,他们是在脚本之外执行的吗?他们是在控制台上做的吗?它可以是一个单行本,可以打开一单子,也可以这么简单,但现在,你可以把它**去,而在此之前,人们有责任说出在正确的时间点被调用的机制是什么。”Fitzgerald提供了许多可以使用Ansible自动化的示例,包括在部署后将应用程序连接到负载平衡器,或者在流程和治理方面,Ansible可用于修复目的,警告应用程序何时违反某些策略,并根据需要将其恢复到法规遵从性。至于Ansible可能实现的各种自动化操作,这是该平台在过去一年中一直关注的问题,因为它引入了Ansible内容集合。这些集合现在已经超过55个,提供由Red Hat维护的经过认证的Ansible内容,而私有自动化中心为Ansible用户提供了一种在内部共享自定义脚本的方法。虽然Advanced Cluster Management这个名字似乎暗示了该工具只适用于那些具有更复杂OpenShift部署的用户,但Fitzgerald说,相反,它已经看到了对该工具的兴趣,“无论范围和大小”,“几乎所有客户都对ACM感兴趣”。虽然一个组织可能只运行一个集群,但它们可能处于受管制的行业中,需要执行策略,ACM提供了这一点。类似地,对于运行几个集群的组织,ACM提供了对集群运行状况的可见性,现在通过Ansible集成,ACM充当了“一个管理控制平面,它允许我们非常清晰地构建这些Ansible点。”目前,Ansible与ACM的集成正在TechPreview中引入,尚未确定其通用性。同时,红帽也展示了一个“概念的证明”,菲茨杰拉德说,对于knative调用Ansible。Knative是一个开源项目,允许用户在Kubernetes上运行容器,作为无服务器、事件驱动的工作负载。“想想事件驱动的自动化,其中可以调用Ansible脚本,而不是Python或其他东西。然后,你可以在将来开始配置这样的东西:“当我收到这个事件时,我想运行这个脚本。”这是另一种方法,可以在发生事情时轻松地插入自动化,而不是通过非常复杂的管道或让一个团队参与进来,菲茨杰拉德说:“为了在适当的时间点实现自动化。原文参见:https://thenewstack.io/red-hat-brings-ansible-automation-to-kubernetes/
  • [交流吐槽] 提一个kubernetes镜像的BUG
    网站上给出的创建kubernetes.repo的命令有问题,感觉完全没做过测试嘛,原命令是这样的:使用这个命令后的结果,是这样的:
  • [技术干货] 《ONAP技术详解与应用实践》读书笔记7
    ONAP安装部署指南在Kubernetes(简称K8s)上安装部署ONAP。可以将ONAP各个组件以容器的形式进行部署,并通过Kubernetes进行管理。ONAP的所有组件均运行在Docker之中,而且需要一个Kubernetes集群进行编排管理。安装要求说明多种场景下部署,ONAP的部署可以分为物理裸机部署、私有云环境部署和公有云环境部署。ONAP的安装将以C版本为例ram 224GB  harddist 160GBvCPU 112ports:all open2.2 在物理裸机上部署ONAP2.2.1 资源准备—安装OS物理裸机安装Ubuntu Server 16.04 LTS。1.设置iptables默认规则为ACCEPT新安装的系统默认的规则可能是DROP,运行下列命令修改默认为ACCEPT。iptables -p INPUT ACCEPTiptables -p FORWARD ACCEPTiptables -p OUTPUT ACCEPTiptables-save> /etc/iptables.rules2.设置虚拟内存的最大值将进程可以使用的内存区域设置为最大值,以避免内存溢出等异常。sysctrl -w vm.max_map_count=10243.安装及配置openssh-server需要安装openssh-server之后才能远程登录服务器。安装openssh-server的命令如下:sudo apt updatesudo apt install openssh-server配置openssh-server机器的用户名/密码登录方式,脚本如下:#setup ssh access -default login:ubuntu/ubuntused -i 's/PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_configsed -i \'s/PasswordAuthentication yes/' /etc/ssh/sshd_configcat >> /etc/ssh/sshd_config <<EOFCiphers aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,3des-cbc,arcfour128,arcfour256,arcfour,blowfish-cbc,cast128-cbcMACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-sha1-96,hmac-md5-96kexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,echhsha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1,curve25519-sha256@libssh.orgClientAliveInterval 60ClientAliveCountMax 5EOF脚本运行之后service sshd restart2.2.2 在物理服务器上安装KubernetesKubernetes是Google开源的一款基于容器的集群管理系统,是其内部Borg工具的开源版。Kubernetes是目前公认的最成熟、先进的开源容器集群管理系统,发展非常迅猛,得到了容器生态圈厂商的全面支持。许多公有云服务厂商都提供基于Kubernetes的基础设施层支持。一个Kubernetes集群,是由Kubernetes Master及若干Worker(节点)组成的。节点上最小的操作单元被称为Pod:相关的一个或多个容器构成一个Pod,Pod包含的容器运行在同一个上下文中,可看作一个统一的管理单元,共享相同的volumes和network namespace空间。Kubernetes Master作为集群的中心控制节点,会运行3个关键进程:kube-apiserver、kube-manager及kube-scheduler。另外,在Kubernetes的Master和Worker上还需要安装ETCD及容器网络插件(例如Flannel),以负责存储Kubernetes的信息以及同一个集群内容器的内网规划和支持。kube-apiserverkube-managerkube-scheduler在一个Worker节点上,会运行两个进程:kubeletkube-proxy安装k8s步骤略2.2.4 在Kubernetes上安装部署ONAP1.部署工具安装在安装ONAP之前,需要先安装相关的工具—Kubectl和Helm。2.部署ONAP登录Kubernetes Master节点,从ONAP社区代码仓库下载OOM代码:git clone -b casablanca http://gerrit.onap.org/r/oomcd oom/kubernetes 拷贝Helm的deploy插件到helm目录下:sudo cp -R ./helm/plugins/ ~/.helm启动Helm Server,作为ONAP charts的本地仓库服务器:helm inithelm serve&添加本地Helm仓库:helm repo remove stablehelm repo remove localhelm repo add local http://127.0.0.1:8879/charts验证Helm仓库是否添加成功:helm repo list给Helm创建权限:kubectl create serviceaccount --namespace kubesystem tillerkubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tillerkubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"ServiceAccount":"tiller"}}}}'构建ONAP各个组件的Helm Chart(如果想要选择性地构建,可以编辑oom/kuber-netes/onap下的values.yaml文件,把相应的组件开关改为true或false即可实现):make all显示已经安装的Helm Chart的方法如下:helm search -l然后执行如下命令来部署ONAP:helm deploy dev local/onap --namespace onap如果要监控安装状态和是否成功完成安装,则执行以下命令:kubectl get pods -n onap如果所有pod的STATUS都是Running则表示ONAP安装结束,此时便可以进行health测试来验证ONAP是否安装成功了。如果ONAP健康检查通过,则可认为ONAP安装成功。运行以下命令验证:bash ./robot/ete-k8s.sh onap health如果需要安装ONAP的某一个组件,如SO,可执行以下命令,-n后面指定在Helm中的release名字:helm install onap/so --version 2.0.1 -n so可执行下面的命令删除ONAP:helm undeploy dev -purge如果需要删除Helm,需停止Helm相关服务,并且移除Kubernetes环境中的相关组件,即执行如下命令:helm reset -forcerm /usr/local/bin/helmrm -rf /root/.helmps /aux |grep helm#find the pid of helm related process and #kill -9 <pid>kubectl delete serviceaccount --namespace cubesystem tillerkubectl delete --namespace cubesystem tille-deploy2.3 在OpenStack私有云环境下部署ONAP在OpenStack上创建虚拟机部署ONAP,需要数据中心或者实验室有一个OpenStack的集群。可参见链接:https://docs.openstack.org/horizon/latest/user/index.html# 。使用Rancher安装Kubernetes,参见链接:https://docs.onap.org/en/casablanca/submodules/oom.git/docs/oom_setup_kubernetes_rancher.html 。2.4 在公有云虚拟机上部署ONAP以华为公有云为例1.注册账号华为公有云的主页https://www.huaweicloud.com/ ,注册华为公有云的账号账号注册完成后,依照匹配的类型完成实名认证2.购买弹性云服务器点击服务列表中的弹性云服务器(Elastic Cloud Server,ECS)订购云服务器(虚拟机),以便用于部署ONAP。3. CCE环境准备ECS服务器购买完成后,将基于购买的ECS服务器创建云容器引擎CCE(Cloud Container Engine,云容器引擎,一种Kubernetes集群服务)。和购买ECS服务器类似,点击服务列表选择云容器引擎CCE进行购买。集群的管理节点规模可以按照购买的ECS服务器个数来选择。完成Kubernetes集群的购买后就可以新增节点了然后安装Kubectl,作为Kubernetes控制节点的客户端。当前支持两种安装方式:第一种是选择一台和ONAP-Node在一个VPC下的服务器;第二种就是选择一台在互联网上的服务器。2.5 ONAP as A Service展望SaaS是SoftwareasaService(软件即服务)的简称。SaaS与on-demand software(按需软件)、the application service provider(ASP,应用服务提供商)、hosted soft-ware(托管软件)具有相似的含义。与传统软件需要先安装在本地再使用不同,SaaS是一种通过互联网提供软件的模式。厂商将应用软件统一部署在自己的服务器上,客户可以根据自己的实际需求,通过互联网向厂商定购所需的应用软件服务,按定购的服务多少和时间长短向厂商支付费用,最后通过互联网获得厂商提供的服务。SaaS形态的软件消除了传统软件在每一个用户主机上对软件安装、升级和维护的工作,可以有效降低成本。借鉴SaaS软件的思路,将ONAP部署在公有云中,可以有效减少本地搭建ONAP环境的开销,包括服务器的硬件资源开销和搭建基础设施层的人力开销等。而对云上的ONAP进一步改造也可以将ONAP作为SaaS服务提供出来,一些设计态组件的功能和认证功能甚至可以独立对外提供服务。实现ONAPaaS将很大程度上提升ONAP的易用性:不同地域的网络设计人员可以登录同一个位于云端的ONAP环境进行合作设计开发,提高网络设计的效率。运维人员可以远程登录ONAP并对指定地域的网络进行管理,不同地区的网络运行事件都将上报给云端的ONAP,事件的处理和策略的制定将变得简单。对于VNF的认证也只需要VNF供应商上传VNF Package到云端的ONAP,就能方便地进行认证测试,无须额外搭建测试环境来进行验证。对云端的ONAP进行升级维护后,所有用户都能立即获得最新的ONAP功能,不再需要对每一个区域的ONAP进行单独升级操作。2.6 本章小结本章介绍了在三种场景下如何使用OOM在Kubernetes上安装部署ONAP。三种场景分别是物理裸机、OpenStack私有云环境和公有云环境。使用OOM可以将ONAP各个组件以容器的形式进行部署,并通过Kubernetes进行管理。同时利用了容器轻量化以及Kubernetes成熟管理的优势,使得ONAP更易于安装并且更加稳定可扩展。最后,对ONAP的SaaS化进行了展望,展示了ONAP的SaaS形态易用性的提升和能为用户带来的好处。注:还是saas最方便。
  • [云原生生态] 首个容器批量计算项目Volcano 1.0版本正式发布
    在刚刚结束的CLOUD NATIVE+ OPEN SOURCE Virtual Summit China 2020上,由华为云云原生团队主导的容器批量计算项目Volcano正式发布1.0版本,标志着Volcano项目已经开始走向成熟与稳定。Volcano项目介绍Volcano是基于Kubernetes的云原生批量计算引擎,基于华为云在AI、大数据领域的深厚业务积累,补齐了Kubernetes在面向AI、大数据、高性能计算等批量计算任务调度、编排等场景下的短板,向下支持鲲鹏、昇腾、X86等多元算力,向上使能TensorFlow、Spark、华为MindSpore等主流行业计算框架,让数据科学家和算法工程师充分享受到云原生技术所带来的高效计算与极致体验。Volcano架构示意图随着Kubernetes作为AI、大数据和高性能批量计算的下一代基础设施的趋势逐渐清晰,越来越多的企业对Kubernetes在深度学习、科学计算、高性能渲染等方面提出了更高的要求。然而Kubernetes作为普适的容器化解决方案,仍与业务诉求存在一定差距,主要体现在:K8s的原生调度功能无法满足计算要求K8s作业管理能力无法满足AI训练的复杂诉求数据管理方面,缺少计算侧数据缓存能力,数据位置感知等功能资源管理方面缺少分时共享,利用率低硬件异构能力弱Volcano的诞生正是基于这些痛点,在调度、作业管理、数据管理、资源管理四个方面进行了重点优化。增强了任务调度能力,如公平的调度(fair-share)、组调度(gang-scheduling)  进一步优化了作业管理能力,如multiple pod template能力、更灵活的error handling机制  增加计算侧数据缓存,提升数据的传输与读取效率引入多维度的综合评分机制,实现资源更高效的管理和分配多元算力支持:支持x86、鲲鹏和昇腾等算力   Volcano项目进展时间轴Volcano v1.0新特性介绍Volcano v1.0的核心概念和关键特性,主要包含以下要点:Queue、PodGroup、Volcano Job等核心概念均已实现支持Binpack、Conformance、DRF、Gang、Preempt、Reclaim、Priority、Proportion等多种调度策略支持Rest API、CLI等多种交互方式完成与Spark、Argo、MPI、Flink、Mxnet、Paddlepaddle、Tensorflow、MindSpore等主流高性能计算框架的无缝对接支持Job的全生命周期管理和动态扩缩容支持GPU异构与共享完备的golangCI-lint check、e2e以建立增强代码质量和稳定性除以上特性外,Volcano始终保持与Kubernetes社区、Golang最新版本保持一致。Volcano社区和生态建设进展经过一年多的发展,Volcano的社区和生态建设已经步入快车道。截至目前,社区和生态建设取得了以下成绩:社区贡献者80+社区贡献参与组织15+,包括华为、百度、腾讯、AWS、IBM、 Oracle等获得Star 1100+,Fork 220+代码库7个,Release 6个Issue 320+,PR 590+已完成对Spark、Argo、MPI、Flink、Mxnet、Paddlepaddle、Tensorflow、MindSpore、Cromwell等10+主流计算框架的支持华为云CCE(云容器引擎)、CCI(云容器实例)、ModelArts等多个云服务已将Volcano集成为基础设施底座并商用,服务领域已涵盖AI、大数据应用、基因计算、批处理等场景,并实现与华为鲲鹏、昇腾处理器深度融合,最快每秒1000个容器的调度发放,成为高性能、极致性价比的批量计算解决方案。深入了解Volcano如果想更加深入了解Volcano,可以参考以下资源:Volcano官网:https://volcano.sh/Github:https://github.com/volcano-shVolcano简介:https://github.com/volcano-sh/volcanoVolcano设计:https://github.com/volcano-sh/volcano/tree/master/docs/designVolcano路线图:https://github.com/volcano-sh/volcano/blob/master/docs/community/roadmap.mdVolcano社区交流微信群:Volcano CN未来可期随着Volcano v1.0的发布,Volcano社区建设与上下游生态的融合必将更加紧密,基于Volcano的商业应用也将极大地促进AI、大数据、科学计算、渲染等领域充分享受到云计算带来的极大便利和极致体验,助力企业数字化转型进入新的高度。展望未来,华为云也将在云原生领域持续耕耘,持续引领创新、繁荣生态,助力各行业走向快速智能发展之路。
  • [分享交流] EdgeGallery开源平台简介四
    MEP管理面: 特性简介MEP管理面提供应用的生命周期管理,通过支持管理多个边缘计算平台。支持基于虚拟机的应用部署,同时也支持基于Docker的应用部署。在部署过程中,可以同步MEP应用商店的应用包到平台,然后通过MEP管理面分发到边缘,进行部署。 客户价值● 方便管理应用的增删改查。● 方便查看边缘节点的资源使用情况。● 方便管理边缘节点的MEP平台。特性描述同时支持容器化和基于虚拟机的应用管理MEP管理面基于kubernetes 进行应用管理,可以支持Helm和Kubernetes deployment两种部署方式,同时通过Kubevirt可以支持基于Kubernetes的虚拟机管理。节点管理MEP管理面通过集成Grafna可以支持对每个Edge节点进行监控,同时MEP管理面也可以分节点进行所有资源的查看,包括MEP,APP,以及Kubernetes自身进行监控。CatalogMEP管理面的Catalog管理MECM从MEP应用商店同步过来的APP Package。并且可以通过注册系统,将APP Package提前分发到边缘计算节点,节省了MEP管理面在部署过程中需要提前下载相关镜像的时间。