如何检测过时的Kubernetes API

最近,已弃用的API对每个人的Kubernetes清单造成了严重破坏。 为什么会这样?! 这是因为我们所认识和喜爱的物品正在转移到他们的新家中。 这不是一夜之间发生的事情。 现在已经有很多版本发布了弃用警告。 我们都只是懒惰,以为这一天永远不会到来。 好吧, 它在这里

因此,这一次也许赶上了我们。 但是我们下次会准备的吧?!? 是的,那是我们上次所说的。 但是,如果我们可以采取一些措施确保不会发生这种情况怎么办?

什么是Deprek8?

Deprek8是一组开放策略代理 (OPA)策略,使您可以检查存储库中是否已弃用的API版本。 这些策略提供了一种方法,可以在某些事物正在被使用或已被弃用时提供警告和错误。 但是Deprek8只是一组定义要注意什么的策略。 您实际上如何积极地使用这些策略来监视折旧?

有很多方法和工具可以做到这一点。 一种方法是使用OPA Deprek8策略。

OPA Deprek8政策是什么?

Rego查询语言 。 该用例不一定依赖于OPA应用程序,而是更具体地说,它使用此查询语言来完成繁重的工作。 通过使用Rego,您可以检查各种清单是否符合特定条件,然后根据定义对它们进行警告或错误提示。 例如,在Kubernetes 1.16中,不再可以通过extensions / v1beta1 apiVersion提供Deployment对象。 因此,在您的.rego文件中,可能会有类似以下内容:

   
   
_deny = msg {
  resources := [ "Deployment" ]
  input.apiVersion == "extensions/v1beta1"
  input.kind == resources [ _ ]
  msg := sprintf ( "%s/%s: API extensions/v1beta1 for %s is no longer served by default, use apps/v1 instead." , [ input.kind, input.metadata.name, input.kind ] )
}

这将提醒您您已弃用清单,并显示以下消息:

部署/ myDeployment:默认不再提供用于扩展的API扩展/ v1beta1,请改用apps / v1。

那很棒! 这正是您需要的,以避免周围出现旧清单。 但这只是政策; 您需要可以检查这些政策并将其付诸实施的措施。

竞赛

这就是Conftest的用处 。Conftest是一个实用程序,它使您可以对任意数量的配置文件实施Rego策略。 根据该回购协议,Conftest当前支持:


   
   
 - YAML
 - JSON
 - INI
 - TOML
 - HOCON
 - HCL
 - CUE
 - Dockerfile
 - HCL2 ( Experimental )
 - EDN
 - VCL
 - XML

它具有一些相当严格的默认值(即,期望策略文件位于某些位置),但是如果您具有自己喜欢的布局,则可以使用适当的标志来覆盖它们。 如果您想进一步了解这些细节,请查阅存储库中的文档

例如,您可以使用以下命令在Conftest上运行任何策略文件:

 helm template --set podSecurityPolicy.enabled=true --set server.ingress.enabled=true . | conftest -p mypolicy.rego - 

这将从Helm模板生成适当的输出,并将其直接传递到Conftest实用程序。 Conftest根据mypolicy.rego文件中定义的任何策略检查该输出,然后针对与那些策略匹配的对象给出任何适当的警告或错误。 当然,您可以交换选择的任何模板工具,也可以将特定文件直接输入Conftest工具。

因此,现在您有了工具来设置策略并针对配置文件实施策略。 但是,如何将这两件事联系在一起? 更好的是:如何使此过程自动化以持续监视代码库,以确保您再也不会落后于弃用线?

使用Git运行检查

有许多方法和工具可以对代码进行检查。 通过为持续集成(CI)工具(例如Jenkins,Tekton等)添加类似的步骤,您可以实现相同的目标。 在这个非常基本的用例中,我使用了GitHub Actions ,这是GitHub存储库的新功能。

GitHub Actions允许您自动化整个工作流程,因此您不必坐在键盘前就可以一起破解所有这些内容。 使用动作,您可以通过滚动自己的动作(如果您要进行自定义)或在大多数情况下使用Marketplace中已经存在的动作将任意数量的步骤组合到一个(或多个)工作流中。 幸运的是,其他人提供了Actions来完成您在本示例中需要做的事情,因此您可以依靠社区的专业知识来将您的工作流整合在一起。

如以上步骤所述,工作流程如下所示:

  1. 检索您需要的Deprek8策略并将其存储在以后的地方。
  2. 使用您在步骤1中抓取的策略文件,对适当的文件/图表运行Conftest。

归结为什么? 好吧,您真正需要做的就是使用curl提取策略文件,然后使用curlConftest Actions在指向您的代码后通过Conftest运行它。 由于这些操作已经存在,因此您无需编写任何自定义代码! 而且,正如我确定的名称所示,它们使您可以运行关联的命令,而无需进行任何自定义工作来预处理任何内容或提取任何二进制文件。

现在您有了需要使用的动作,如何将它们组合在一起? 这就是您的工作流程发挥作用的地方。 虽然动作是完成任务的代码段,但是如果没有将它们串在一起以致可以被某个事件触发的方法,它们就毫无用处。 GitHub Action工作流将如下所示:


   
   
name : Some Awesome Workflow Name
on
: An Event That Triggers Our Workflow
jobs
:
  awesome-job-name
:
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@master
      - name
: awesome-step-name
        uses
: someorg/someaction@version
        with
:
          args
: some args that I might pass to someaction

现在,您有了一个包含多个步骤的工作流,可以由特定的GitHub事件触发,并且可以传递一组参数(如果适用于该特定Action的话)。 这个例子非常基础 。 但是幸运的是,您要组合在一起的工作流程同样简单。 这不应该作为GitHub Action的综合示例,因为您可以执行许多更复杂(更优雅)的操作。 如果您想了解更多信息,请查看GitHub Actions文档

现在,您已经了解了工作流的外观,并且知道了您对使用什么操作感兴趣,接下来将两者结合起来。 对于此示例,您想确保每当更新代码时,都对其进行检查以确保其未使用任何不推荐使用的API。

首先,使用一些名称和要触发的事件来装配工作流程。 给您的工作流程和作业一个有用的名称,以帮助您识别它(及其作用)。


   
   
name : API Deprecation Check
on
: pull_request, push
jobs
:
 deprecation-check:

接下来,您需要告诉您的工作流您要基于此存储库中发生的任何pull_requestpush触发这些操作,因为这是将新代码获取到存储库中的两个主要事件。 您可以通过使用on关键字来做到这一点。


   
   
name : API Deprecation Check
on
: pull_request, push
jobs
:
  deprecation-check
:
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@master

然后,添加要在其中运行这些操作的位置以及该操作如何获取代码。 您可以使用runs-on关键字告诉Action在哪里运行。 您可以在此处选择几个选项:Windows,Mac或Ubuntu。 在大多数情况下,使用Ubuntu很好,因为您将经常依赖在自己容器中运行的Action(与在此处定义的基本OS上运行的操作相反)。 了解动作默认不会签出代码也非常重要。 当您需要执行与代码交互的操作时,请确保使用Action actions / checkout 。 如果包含此内容,您的代码将在您的操作中可用,您可以将其传递到工作流程的下一步。


   
   
name : API Deprecation Check
on
: pull_request, push
name
: API Deprecation Check
jobs
:
  deprecation-check
:
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@master
      - name
: curl
        uses
: wei/curl@master
        with
:
          args
: https://raw.githubusercontent.com/naquada/deprek8/master/policy/deprek8.rego > /github/home/deprek8.rego

现在您的代码已签出,您可以开始准备对其进行处理。 如前所述,在检查代码是否弃用之前,首先需要包含要检查的策略的文件,因此只需使用curl Action即可检索该文件。 这是一个相当简单的动作,因为它接受通常会传递给curl命令的任何参数。 如果您要执行更复杂的操作,则可以在其中传递特定的HTTP Action,标头等信息。但是,在这种情况下,您只是尝试检索文件,因此唯一需要传递给您的操作是您要检索的URL(在本例中为包含原始策略文件的URL),然后告诉它您要将文件写入何处。 在这种情况下,您将把它写入/ github / home 。 为什么? 这是因为此文件系统在步骤之间保持不变,并允许您在下一步中使用策略文件。


   
   
name : API Deprecation Check
on
: pull_request, push
jobs
:
  deprecation-check
:
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@master
      - name
: curl
        uses
: wei/curl@master
        with
:
          args
: https://raw.githubusercontent.com/naquada/deprek8/master/policy/deprek8.rego > /github/home/deprek8.rego
      - name
: Check helm chart for deprecation
        uses
: instrumenta/conftest-action/helm@master
        with
:
          chart
: nginx-test
          policy
: /github/home/deprek8.rego

现在您有了策略文件,只需要通过conftest对代码运行它即可 。 与curl动作类似, conftest动作仅需要一系列参数来了解如何针对代码运行。 在上面的示例中,它针对Helm图表运行,但是可以通过将uses值更改为instrumenta / conftest-action @ master来针对特定文件(或文件集)运行。 只需指向图表在存储库中的路径,然后提供策略文件的路径即可(在上一步中指定)。 一旦将所有这些结合在一起,便拥有了完整的工作流程。 但这是什么样子(假设您的Helm图表中有一些错误的代码)? 要找出答案,请看一下示例存储库

在Nginx Helm图表中,您会注意到其中一个模板是statefulset 。 您可能还会注意到StatefulSet使用的apiVersion是apps / v1beta1 。 该API在Kubernetes 1.16中已弃用,现在托管在apps / v1中 。 因此,当您的GitHub Actions工作流运行时,它应该检测到此问题并产生如下错误:


   
   
FAIL - StatefulSetf/web: API apps/v1beta1 is no longer served by default, use apps/v1 instead.
Error: plugin "conftest" exited with error
##[error]Docker run failed with exit code 1

该操作表明有问题,然后其余操作失败。 如果您有兴趣,可以查看完整的工作流程

结语

该工作流程通过提醒您进入代码库的所有已弃用的API,可以节省将来的痛苦。 需要明确的是,这是一个警报机制。 这不会阻止您将不良代码合并到您的代码库中。 但是,只要您注意,就应该在合并有问题的代码之前(或之后)完全意识到。

你从这里去哪里? 好吧,有几件事要牢记。 当前,Deprek8是Kubernetes 1.16的最新版本。 如果您对最新版本感兴趣,我相信Deprek8很乐意接受您的pull request

该方法的另一个缺点是conftest和GitHub Actions有点局限性,因为它们一次只允许您指向特定文件或单个图表。 如果要指向清单的多个目录或存储库中有多个图表怎么办? 当前,解决该问题的唯一方法是要么列出您感兴趣的每个文件(如果有多个图表),要么在工作流中包含多个步骤。 其他场景可能会出现问题,例如其他模板引擎需要一些自定义逻辑来将参数和模板文件配对在一起。 但是一个简单的解决方法是在您的工作流程中迈出一步,拉低Conftest以及一个很小的内联脚本来循环其中的一些操作。 我敢肯定,还有更优雅的解决方案(如果您提出一个解决方案,我相信这些项目将很乐意了解您的PR)。

无论如何,您现在都拥有一种机制,可以使您在签入代码时更轻松地入睡! 希望这种方法将帮助您构建更强大的工作流来保护您的代码。


文档最初发布在Tyler Auerbeck的GitHub存储库中 ,并经许可在编辑后重新发布。

翻译自: https://opensource.com/article/20/3/deprek8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值