首页 文章 精选 留言 我的

精选列表

搜索[k8s],共3934篇文章
优秀的个人博客,低调大师

大规模微服务想上 K8s?用 Zadig 实在香!

Zadig on Github/Zadig on Gitee 阅读原文/加入 Zadig 技术交流群 大家对 CI/CD 的概念并不陌生,但真实世界的 CI/CD 绝不是一段代码做「构建->部署->发布」那么简单,大部分情况下一个产品是由若干个微服务组成的,而微服务之间互相有依赖,不同角色基于不同测试环境进行协作。这里给大家介绍一个典型的微服务架构项目,如何用 Zadig 实现全流程自动化、持续交付。该项目包含 Python, Redis, Postgres, Node.js, and .Net 等前后端、数据库、中间件、相对典型的微服务应用程序组合。 大家对 CI/CD 的概念并不陌生,但真实世界的 CI/CD 绝不是一段代码做「构建->部署->发布」那么简单,大部分情况下一个产品是由若干个微服务组成的,而微服务之间互相有依赖,不 准备工作 本案例所用代码及配置 fork 自 GitHub Zadig 仓库,主要包括: 案例中 5 个服务的 Kubernetes YAML 配置:YAML 案例中 3 个业务服务的 Dockerfile 文件:result、vote、worker 接入 GitHub 代码源 第一步:新建 GitHub OAuth 应用程序 个人账号下的代码库接入:可以通过点击用户名 -> Settings -> Developer settings -> OAuth Apps 来新建应用程序。 GitHub Organization 下的代码仓库接入:可以通过点击 Organization Settings -> Developer settings -> OAuth Apps 来新建应用程序。 下面以 GitHub Organization 为例,如下所示。 打开 Organization Settings。 选择 Developer settings -> OAuth Apps,点击 New OAuth App 新建应用程序。 第二步:配置 GitHub OAuth 应用程序 在 新建应用程序页面,你需要进行如下步骤: Application name:zadig,也可以填写可识别的任一名称 Homepage URL:http://[koderover.yours.com] Authorization callback URL:http://[koderover.yours.com]/api/directory/codehosts/callback 点击注册 第三步:获取 Client ID、Client Secret 信息 应用创建成功后,GitHub 会返回应用的基本信息,点击 Generate a new client secret 生成 Client Secret。 此时页面包括完整的 Client ID 、Client Secret。 第四步:将 Client ID、Client Secret 集成到系统 切换到 Zadig 系统,管理员依次点击系统设置 -> 集成管理 -> 代码源集成 -> 点击添加按钮。 依次填入如下已知信息: 代码源:此处选择 GitHub Client ID:应用的 Client ID Client Secret:应用生成的 Client Secret Organization:GitHub 要授权的 Organization 名称或者个人 GitHub Username 信息确认无误后点击、前往授权,耐心等待,此时系统会跳转到 GitHub 进行授权。 点击授权按钮,同意授权后,GitHub 会跳转到 Zadig 系统,至此 GitHub 集成完毕。 产品交付 第一步:项目配置 进入 Zadig 系统,新建项目 voting。 进 第二步:创建服务与服务构建 这里我们需要为以下 5 个服务添加服务配置: vote worker result redis db 并为以下三个业务服务添加构建以支持持续交付: vote worker result 注:服务配置指的是 YAML 对这个服务的定义。Kubernetes 可以根据这个定义产生出服务实例。可以理解为 Service as Code 。 Zadig 提供两种方式管理这些模板: 系统平台管理:在 Zadig 中直接输入 YAML 。 代码仓导入与同步:从某个代码仓库中导入,之后提交到代码仓的 YAML 变更会被自动同步到 Zadig 系统上。 这里,我们使用代码仓导入的方式。案例所需 YAML 配置位于 koderover/zadig仓库freestyle-k8s-specifications文件目录中,现在要做的就是把它们导入。 加载服务配置:点击仓库托管 按钮 -> 选择仓库信息 -> 选择文件目录。Zadig 支持一次性导入多个服务,同步 examples -> voting-app -> freestyle-k8s-specifications 文件目录可导入此次案例中所需的 5 个服务。 配置服务构建:选择服务 -> 点击添加构建 -> 填写构建脚本。 以 result 服务为例,在构建脚本中填写以下代码: cd$WORKSPACE/voting-app/<service-directory>dockerbuild-t$IMAGE-fDockerfile.docker push $IMAGE 重复以上配置服务构建过程,完成 vote 、 result 和 worker 的构建配置,注意根据不同的服务修改脚本中的 <service-directory> 参数。 第三步:加入运行环境 点击向导的“下一步”。这时,Zadig 会根据你的配置,创建两套环境(dev,qa),以及相关工作流。 点击下一步完成向导。至此,onboarding 完成。一个有 5 个微服务的系统,2 套环境、3 条工作流已经产生。 第四步:工作流交付 点击运行触发工作流启动。 选择需要更新的服务,比如 vote 和 result,点击「启动任务」运行工作流。 查看工作流运行状况: 下面是项目的总体状态: 进入集成环境,查看服务列表并点击 result 和 vote暴露出来的 URL 可以查看网站。 vote 页面: result 页面: 第五步:配置自动触发工作流 添加触发器,使得代码 Push 或者 Pull Request 都触发 result,vote,worker 三个服务的重新构建和部署: 进入工作流配置页面 添加 Webhook 触发器 配置 Webhook 触发器 保存工作流 第六步:代码改动持续交付 提交 GitHub PR 修改源代码,交换 vote 服务中 CATS 和 DOGS 的背景颜色。 进入 项目->voting->工作流->voting-workflow-dev 查看工作流,可以看到 PR 变更已自动触发工作流执行: 待 voting-workflow-dev 工作流执行完毕,进入 项目->voting->集成环境,点击 dev 环境中 vote 服务的服务入口,查看网站结果,可以看见 CATS 和 DOGS 背景栏颜色已被更改。 关于 Zadig Zadig 是基于 Kubernetes 设计、研发的开源分布式持续交付 (Continuous Delivery) 产品,为开发者提供云原生运行环境,支持开发者本地联调、微服务并行构建和部署、集成测试等。Zadig 内置了面向 Kubernetes、Helm、云主机、大体量微服务等复杂业务场景的最佳实践,为工程师一键生成自动化工作流 。 欢迎大家 Star、Fork、 Watch!和众多开发者一起探讨、交流,共建开源社区! Zadig on Github/Zadig on Gitee 阅读原文/加入 Zadig 技术交流群

优秀的个人博客,低调大师

Spring Boot 项目想上 K8s?用 Zadig 就完事了

Zadig on Github/Zadig on Gitee 阅读原文/加入 Zadig 技术交流群 ​Spring Boot 是构建 Java 后端应用程序的一种非常流行的框架,被企业和开发者广泛采用。本文介绍如何使用Zadig 持续交付Spring Boot 项目到Kubernetes上,该项目主要包含 Maven 构建的 Worker 、DB(Postgres) 以及 Redis 这三个服务,以下步骤包含从 Code 到 Ship 的整个过程的演示。 准备工作 项目案例中用到的worker 服务源代码、YAML 文件、Dockerfile 文件,可以在 GitHub Zadig仓库examples/voting-app项目中找到 建议把源码放到自己的 GitHub代码仓库后再进行下面的操作 项目配置 创建项目,具体内容如下图所示: 接下来会看到创建成功的提示: 创建服务 创建服务 创建服务有两种方式,第一种是选择平台编辑直接把 YAML 内容粘到系统中。第二种是选择从仓库导入 YAML 文件,示例中采用第二种。 点击仓库托管,在弹出的窗口中选择代码仓库,同步 examples->voting-app->freestyle-k8s-specifications->worker 文件目录,加载 worker 服务 YAML 配置文件。 系统会自动检测 YAML 格式是否合法,右侧会自动解析出来系统变量、自定义变量和服务组件,这里也可以继续添加自定义变量。具体过程如下图所示: 创建构建 这里可以选择 worker-e2e 这个服务组件添加构建,然后选择代码库和添加构建脚本,具体如下图所示: 构建脚本如下 cd$WORKSPACE/zadig/examples/voting-app/workerdockerbuild-t$IMAGE-fDockerfile.j.docker push $IMAGE 添加完成后,点击保存构建。然后点击仓库托管,继续添加 DB(Postgres) 和 Redis 服务,如下图所示: 实际场景中已存在现有可用的中间件服务,在网络联通情况下可以直接使用;若同一中间件服务针对不同环境需要使用不同的服务地址,可以通过设置环境变量的方式配置 添加成功后,点击下一步,完成服务配置。 加入运行环境 进入「加入运行环境」,系统会自动创建两套集成环境和三条工作流,两套集成环境可分别给开发和测试使用,三条工作流也会自动绑定对应的集成环境以达到持续交付的目的。具体如下图所示: 工作流交付 点击运行工作流 voting-app-workflow-dev 对 worker 服务进行更新,来实现 dev 环境的持续交付 qa 环境的持续交付类似的操作,不赘述。 到此,您已熟悉 Zadig 的基本功能了,下面将展示如何配置自动触发工作流。 配置自动触发工作流 创建基于 GitHub 事件的触发器,修改 voting-app-workflow-dev 工作流,为 dev 环境设置 GitHub 事件触发器,系统目前支持 push 和 pull_request 两种事件,具体如下图所示: 前提条件:需要配置 GitHub Webhook,全局 Webhook 请参考GitHub Webhook 提交代码库PR,在 Check runs 中会展示具体的系统工作流的状态,具体如下图所示: 点击任务链接可以跳转到 Zadig 系统里查看工作流具体执行信息,如下图所示: 待工作流执行完毕,可看到 dev 环境 worker 服务的镜像已经被更新了,具体如下图所示: 通过以上步骤,我们已经完成了部署在 Kubernetes 上的 Spring Boot 项目持续交付配置,通过接入 Zadig 开发者可以方便的对服务进行查看、管理和更新,比如服务查看、Pod Debug、实时日志等。 关于 Zadig Zadig 是基于 Kubernetes 设计、研发的开源分布式持续交付 (Continuous Delivery) 产品,为开发者提供云原生运行环境,支持开发者本地联调、微服务并行构建和部署、集成测试等。Zadig 内置了面向 Kubernetes、Helm、云主机、大体量微服务等复杂业务场景的最佳实践,为工程师一键生成自动化工作流 。 欢迎大家 Star、Fork、 Watch!和众多开发者一起探讨、交流,共建开源社区! 加入开源 Zadig 技术交流群🔥

优秀的个人博客,低调大师

Docker与k8s的恩怨情仇(五)——Kubernetes的创新

转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 上节中我们提到了社区生态的发展使得Kubernetes得到了良性的发展和传播。比起相对封闭的Docker社区开放的CNCF社区获得了更大成功,但仅仅是社区的活力对比还不足以让Docker这么快的败下阵来,其根本原因是Kubernetes的对容器编排技术的理解比起Docker更胜一筹。这种优势几乎是压到性的降维打击,Docker毫无还手之力。 接下来便为大家介绍在这场容器大战之中,Kubernetes如何占据优势地位。 容器编排 所谓容器编排,其实就是处理容器和容器之间的关系,在一个分布式的大型系统里,不可能是以多个单一个体存在的,它们可能是一个与多个,一群与一群这样相互交织着。 Docker的容器编排功能 Docker构建的是以Docker容器为最核心的PaaS生态,包括以Docker Compose为主的简单容器关系编排,以及以Docker Swarm为主的线上运维平台。用户可以通过Docker Compose处理自己集群中容器之间的关系,并且通过Docker Swarm管理运维自己的集群,可以看到这一切其实就是当初Cloud Foundry的PaaS功能,所主打的就是和Docker容器的无缝集成。 Docker Compose做到的是为多个有交互关系建立一种“连接”,把它们全部编写在一个docker-compose.yaml文件中,然后统一发布(我后面说到的组里的ELK功能就是这样做的),这样做也有优点,就是对于简单的几个容器之间的交互来说非常便利。但是对于大型的集群来说却有些杯水车薪,并且这种每出现一种新需求就需要单独做一项新功能的开发模式,将使后期代码维护变得十分困难。 Kubernetes如果要和Docker对抗,肯定不能仅仅只做Docker容器管理这种Docker本身就已经支持的功能了,这样的话别说分庭抗礼,可能连Docker的基本用户都吸引不到。因此在Kubernetes设计之初,就确定了不以Docker为核心依赖的设计理念。在Kubernetes中,Docker仅是容器运行时实现的一个可选项,用户可以依据自己的喜好任意调换自己需要的容器内容且Kubernetes为这些容器都提供了接口。此外,Kubernetes准确的抓住了Docker容器的一个致命性的弱点进行了自身创新。 接下来就让我们一起来了解,这个给Docker造成降维打击的内容究竟是什么? Kubernetes的容器编排功能 与Docker这种站在容器视角上只能处理容器之间的关系所不同,Kubernetes所做的是从软件工程的设计理念出发,将关系进行了不同类的划分,定义了紧密关系(Pod之间)和交互关系(Service之间)的概念,然后再对不同的关系进行特定的编排实现。 乍一听你可能是一头雾水。这里举个不太实际但是一看就懂的例子:如果把容器之间的关系比作人之间的关系,Docker能处理的是仅仅是站在单一个体的角度上,处理人与人之间的人际关系;而Kubernetes确是上帝,站在上帝视角不仅能处理人与人之间的人际关系,还能处理狗与狗之间的狗际关系,最主要的是能处理人与狗之间的交往关系。 而实现上述紧密关系的原理,就是Kubernetes创新的Pod。 Pod是Kubernetes所创新的一个概念,其原型是Borg中的Alloc,是Kubernetes运行应用的最小执行单元,由一个或者多个紧密协作的容器组合而成,其出现的原因是针对容器的一个致命性弱点——单一进程这问题的扩展,让容器有了进程组的概念。通过第一节,我们知道了容器的本质是一个进程,其本身就是超级进程,其他进程都必须是它的子进程,因此在容器中,没有进程组的概念,而在日常的程序运行中,进程组是常常配合使用的。 使用Pod处理紧密关系 为了给大家介绍Pod处理紧密关系的原理,这里举一个进程组的例子: Linux中有一个负责操作系统日志处理的程序rsyslogd是由三个模块组成,分别是:imklog模块、muxsock模块以及rsyslogd自己的main函数主进程。这三个进程组一定要运行在同一台机器上,否则它们之间的基于Socket的通信和文件的交换都会出现问题。 而上述的这个问题,如果出现在Docker中,就不得不使用三个不同的容器分别描述了,并且用户还得自己模拟处理它们三个之间的通信关系,这种复杂度可能比使用容器运维都高的多。并且对于这个问题的运维,Docker Swarm也有自己本身的问题。以上述的例子为基础,如果三个模块分别都需要1GB的内存运行,如果Docker Swarm运行的集群中有两个node,node-1剩余2.5GB,node-2剩余3GB。这种情况下分别使用docker run 模块运行上述三个容器,基于Swarm的affinity=main约束,他们三个都必须要调度到同一台机器上,但是Swarm却很有可能先分配两个去node-1,然后剩余的一个由于还剩0.5GB不满足调度而使这次调度失败。这种典型的成组调度(gang scheduling)没有被妥善处理的例子在Docker Swarm中经常存在。 基于上述的需求,Kubernetes有了Pod这个概念来处理这种紧密关系。在一个Pod中的容器共享相同的Cgroups和Namespace,因此它们之间并不存在边界和隔离环境,它们可以共享同一个网络IP,使用相同的Volume处理数据等等。其中的原理就是在多个容器之间创建其共享资源的链接。但是为了解决到底是A共享B,还是B共享A,以及A和B谁先启动这种拓扑性的问题,一个Pod其实是由一个Infra容器联合AB两个容器共同组成的,其中Infra容器是第一个启动的: Infra容器是一个用汇编语言编写的、主进程是一个永远处于“暂停”状态的容器,其仅占用极少的资源,解压之后也仅有100KB左右。 实例演示在Kubernetes中的Pod 介绍了一通,接下来我们在实例中为大家演示Pod长什么样子。 我们在任意一个装有Kubernetes的集群中通过以下的yaml文件和shell命令运行处一个Pod,这个YAML文件具体是什么意思暂时不用理会,之后我会对这个YAML做一说明,我们目前只需要明白:Kubernetes中的所有资源都可以通过以下这种YAML文件或者json文件描述的,现在我们只需要知道这是一个运行着busybox和nginx的Pod即可: 创建这个hello-pod.yaml文件之后运行以下命令: 通过上述命令,我们就成功创建了一个pod,我们可以从执行结果看到infra容器的主进程成为了此Pod的PID==1的超级进程,说明了Pod是组合而成的: 至此,我们应该要理解Pod是Kubernetes的最小调度单位这个概念了,并且也应该把Pod作为一个整体而不是多个容器的集合来看待。 我们再看看描述这个Pod的文件类型YAML。 YAML的语法定义: YAML是一种专门编写配置文件的语言,其简洁且强大,在描述配置文件方面远胜于JSON,因此在很多新兴的项目比如Kubernetes和Docker Compose等都通过YAML来作为配置文件的描述语言。与HTML相同,YAML也是一个英文的缩写:YAML Ain't Markup Language,聪明的同学已经看出来了,这是一个递归写法,突出了满满的程序员气息。其语法有如下特征: - 大小写敏感 - 使用缩进表示层级关系,类似Python - 缩进不允许使用Tab,只允许使用空格 - 缩进的空格数目不重要,只要相同层级的元素左侧对其即可 - 数组用短横线-表示 - NULL用波浪线~表示 明确了以上概念,我们把YAML改写成一个JSON,看看这之间的区别: 这两种写法在Kubernetes中是等效的,上述的JSON可以正常运行,但是Kubernetes还是更推荐使用YAML。从上面的对比中我们也能发现,在之前的使用中一直很好用的JSON现在也略显笨拙,需要些大量的字符串标志。 看完语法,我们再来说说上述YAML中的各个节点在Kubernetes所表示的意思。Kubernetes中的有一种类似于Java语法万物皆对象的概念,所有内部的资源,包括服务器node、服务service以及运行组Pod在kubernetes中皆是以对象的形式存储的,其所有对象都由一下固定的部分组成: - apiVersion:在官方文档中并没有给出相应的解释,但是从名字可以看出这是一个规定API版本的字段,但是此字段不能自定义,必须符合Kubernetes的官方约束,目前我们用到的基本都是v1稳定版 - kind:指明当前的配置是什么类型,比如Pod、Service、Ingress、Node等,注意这个首字母是大写的 - metadata:用于描述当前配置的meta信息,比如name,label等 - spec:指明当前配置的具体实现 所有的Kubernetes对象基本都满足以上的格式,因此最开始Pod的YAML文件的意思是“使用v1稳定版本的API信息,类型是Pod,名称是hello-pod,具体实现是开启ProcessNamespace,有两个容器。 知道了YAML的概念,让我们在回归主题。为了解决容器单一进程问题,只创建Pod的原因之一是Google通过Pod实现了自己的容器设计模式,而Google则为Kubernetes编写了最适合的容器设计模式。 举个最常用的例子: Java项目并不能像.Net Core项目那样编译完成后直接自宿主运行,必须要把编译生成的war包拷贝到服务宿主程序比如Tomcat的运行目录下才可以正常使用。但是在实际情况中越大的公司分工越明确,很大概率负责Java项目开发和服务宿主程序开发的团队并不是同一团队。 为了让上述情况中的两个团队可以各自独立开发并且还可以紧密合作,我们可以使用Pod解决这个问题。 下面这个yaml文件就定义了一个满足上述需求的Pod: 在这个yaml文件中,我们定义了一个java程序和tomcat程序的容器,并且对这两个容器之间的容器进行了一次挂载操作:将java程序的/app路径以及tomcat程序的/root/apache-tomcat/webapps同时挂载到了sample-volume这个挂载卷上,并且最后定了这个挂载卷就是一个内存数据卷。并且定义了java程序所在的容器是一个initContainer,说明此容器是在tomcat容器之前启动的,并且启动之后执行了一个cp的命令。 在上述Pod描述了这样一个场景:程序运行开始运行时,Java容器启动,把自己的war包sample.war拷贝到了自己的/app目录下;之后tomcat容器启动,执行启动脚本,执行的war包从自己的/root/apache-tomcat/webapps路径下获得。 可以看到通过上述的配置描述,我们既没有改动Java程序,也没有改动tomcat程序,却让它们完美的配合工作了,完成了解耦操作。这个例子就是容器设计模式中的Sidecar模式,还有很多设计模式,感兴趣的同学可以去进一步自行学习。 总结 以上介绍的就是Kubernetes为了解决紧密关系而抽象出来的概念Pod的基础内容了,需要注意的是,Pod提供的只是一种编排的思想,而不是具体的技术方案,在我们使用的Kubernetes框架中,Pod只不过是以Docker作为载体实现了而已,如果你使用的底层容器是虚拟机,比如virtlet,那这个Pod创建时就根本不需要Infra Container,因为虚拟机天生就支持多进程协同。 在说完了Pod的基础的内容,在下一节中我们将会为大家介绍在接下来的容器编排战争之中,Kubernetes又是如何脱颖而出。

优秀的个人博客,低调大师

K8s 平台可以如何处理 Pod 预授权问题

前言 TKEx-CSIG 是基于腾讯公有云 TKE 和 EKS 容器服务开发的内部上云容器服务平台,为解决公司内部容器上云提供云原生平台,以兼容云原生、适配自研业务、开源协同为最大特点。 业务容器上云过程中,会遇到一些问题,有的需要业务进行容器化改造,有的需要平台赋能。平台赋能的部分,有一类问题是 CVM 场景下已经有解决方案的,而因运维方式不同在 Kubernetes 平台上不兼容的,比如 Pod 预授权的问题。我们希望用云原生的方式解决这一类问题并提供平台化的能力,让每一位用户都能够在平台上便捷的部署和管理自己的业务。 背景 **新部署业务或者扩容,如何对新设备进行预授权?**相信大家对这个问题并不陌生,基于安全考虑,公司内部往往重要组件、存储都会对访问请求进行来源控制,常见的如 CDB 的 IP 访问授权,OIDB、VASKEY 命令字的模块授权等。它们或者有自己的授权 WEB 可以让用户提单申请,或者提供授权 API 可以让运维平台调用。而路由系统往往在发现注册时需要准确获取 IP 设备的地域信息以提供就近访问的能力,这就需要预注册 CMDB。 在以前使用 CVM/TVM 部署业务时,这个问题可以较容易的处理,因为我们是预先拿到了一台虚拟机,已经分配好了 IP 注册好了 CMDB,业务要做的就是用这个 IP 去提单授权,部署业务程序,在一切完备后加上路由上线,这个过程是可以用运维平台的流水线能力做成自动化。 区别于 VM 的拿到可用设备后的步骤型过程化部署,Kubernetes管理的是 Pod 从生产、IP 分配、业务容器启动、路由维护的整个生命周期,由多个系统 Controller 的 Control Loop 做自动化的管理,基于镜像的部署提供了业务实例的伸缩一致性保障,Pod 的销毁重建变成常态,IP 也并非能固定下来。 业务往往面对多种预授权的需要,授权均值时间从秒级到几分钟不等,授权 API 大多并没有设计为承载高 QPS,有一定的复杂性。我们需要能找到一种方法,在 Pod IP 分配后,业务容器起来前处理授权,阻塞住并保障成功后再进行后续过程,并且控制重建过程对授权API的压力。 经过设计与迭代优化,TKEx-CSIG 平台提供给了业务易用的产品能力化的授权能力,方便应对这类 Pod 预授权的问题。 架构和能力解析 架构 上图所示是授权系统的架构,核心思路是使用 init Container 先于业务容器执行的特性,实现在业务 Pod 启动前进行复杂的逻辑预处理。官方对 init Container 的定义如下 This page provides an overview of init containers: specialized containers that run before app containers in a Pod. Init containers can contain utilities or setup scripts not present in an app image 如果是小规模或单个业务的解决方案,我们是可以做的很简单,在业务 Worklooad yaml 中注入 init Container,调用需要的授权 API 实现即可,而要做成平台产品化的能力,还需要考虑以下几点: 易用与可维护 需要充分考虑业务使用上的效率和可管理性,将权限作为一项资源由平台记录管理,减小变更对业务的侵入性影响。 限频与自愈 权限 API 往往并没有对高 QPS 的设计,需要限制调用保护下游。 权限收敛 安全性,Pod 的销毁重建可能导致 IP 变化,考虑主动回收已经过期的权限 授权过程产品能力化 业务仅需在平台 WEB 控制台上登记需要的权限资源,配置权限组,关联权限组到 Workload,平台自动进行 init Container 的配置注入,通过 ENV 传递授权配置索引和相关信息,在 Pod 创建时进行授权过程。授权过程涉及的几个组件功能设计如下: init-action-client init Container,仅作一个触发装置,仅做一件事,就是发起 HTTP 调用请求,保持不可变,这样当功能迭代时不必修改业务的 yaml,主逻辑后移处理 init-action-server deployment 部署可横向扩展,执行预处理逻辑,预注册 CMDB 等操作,并发起流水线调用,启动权限的申请过程并轮询查询,将过程信息关联 POD 暴露出来方便业务自查和管理员定位问题。后文提到的退避重试和断路器逻辑也在这里实现。 PermissionCenter 平台管控组件,位于集群外,负责权限资源的存储和实际申请。包含一个权限资源中心,存储业务登记的权限详情参数方便复用,提供权限 Set 组管理,简化授权过程中的参数传递;使用生产者/消费者模式,基于 Pipline 实现授权 API 的调用和结果查询。 断路器和退避重试机制 可能导致授权过程的异常状况不少,例如权限参数错误的配置,授权 API 服务质量下降或不可用,甚至是网络原因导致的接口错误、超时等。授权 API 往往也并没有设计支持高 QPS,我们采用超时重试,加断路器和指数退避重试去做一个容错性。 超时重试 体现在接口调用和异步任务的超时设置与重试机制,应对瞬时故障,init-action-client 容器非正常退出也会进行重建,每次创建就是新一轮的重试。 断路器 使用一个 Configmap 专门记录集群里 Pod 权限申请的失败次数,3次即断路不给申请。并提供一个重置能力,暴露给前端,让用户和管理员可以便捷进行重试。 指数退避 断路器模式可以阻断用户配置错误这类永远也不可能授权成功的案例,但是无法应对长时间的瞬时故障。比如裁撤期,授权 API 后端可能会有一段时间的拒绝服务,10分钟到几小时,此时会有大量 Pod 授权命中断路器规则无法继续授权,人为处理时效性差也繁琐。我们为每个 Pod 添加了一个带抖动的指数退避器并记录最近的失败时间戳,能够在一段时间后允许尝试一次,如果成功就重置对指定 Pod 的退避,如若不成功更新时间戳重新计时,参数如下, bk := &PodBreaker{ NamespacePod: namespacePod, LastRequestFailTime: time.Now(), Backoff: wait.Backoff{ Duration: 2 * time.Minute, Factor: 2.0, Jitter: 1.0, Steps: 5, Cap: 1 * time.Hour, }, } Finalizer 收敛权限 权限的收敛问题往往被忽略,但是也是安全需要考虑的,Pod 的销毁重建可能是常态,IP 指不准也动态变化,长时间可能产生大量垃圾权限,或者已经授权过的 IP 分配到别的业务 Pod,产生安全风险。我们做了一个 Finalizer 控制器来在 Pod 销毁前进行权限回收,回收动作是幂等性的,而且是尽力而为的,因为回收的能力也依赖于权限方是否具备回收能力,我们对新对接的权限都会考虑这一点,比如腾讯云 MySQL 的 IP 自动授权。 为了减少打 Finalizer 的动作,尽可能不影响非授权关心的 Pod,我们只在 Pod 进行了变更事件时识别有授权 init Container 的 Pod,Patch 上 Finalizer 标记,在这些 Pod 缩容销毁时进行权限的回收并删除 Finalizer,随后 GC 会删除这个 Pod。 kind: Pod metadata: annotations: ~ creationTimestamp: "2020-11-13T09:16:52Z" finalizers: - stke.io/podpermission-protection 总结 本文解决的是业务使用容器平台时,在业务进程启动前的预处理如自动化授权的一类问题。使用 init Container 实现业务容器启动前的预处理,并将授权特性产品能力化让业务能较为方便的管理和申请权限资源,断路器和退避重试机制提供容错性,使用 Finalizer 提供一个回收的能力防止权限扩散。 参考文章 Init Containers [译] 重试、超时和退避 Using Finalizers 【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册