Kubernetes工作负载最常用YAML格式的文件来定义。

YAML的问题之一就是很难描述清单文件之间的约束或关系。

如果你希望检查是否已从受信任的注册表中提取部署到群集中的所有映像,该怎么办?

如何防止没有Pod安全策略的工作负载提交到集群?

集成静态检查可以在更接近开发生命周期的时间内捕获错误和违反策略的行为。

并且由于改善了资源定义的有效性和安全性,因此你可以相信生产工作负载遵循最佳实践。

Kubernetes YAML文件的静态检查生态系统可以分为以下几类:

  • API验证程序:此类工具针对Kubernetes API服务器验证给定的YAML清单。
  • 内置检查器:此类工具捆绑了针对安全性,最佳实践等的自觉检查。
  • 自定义验证器:此类工具允许使用多种语言(例如python和Javascript)编写自定义检查。

在本文中,你将学习到六个不同的工具:

  1. Kubeval
  2. Kube-score
  3. Config-lint
  4. Copper
  5. Conftest
  6. Polaris

Let's Go ~~~

基准服务

首先部署一个基准服务,以便后面测试对比

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: http-echo
  5. spec:
  6. replicas: 2
  7. selector:
  8. matchLabels:
  9. app: http-echo
  10. template:
  11. metadata:
  12. labels:
  13. app: http-echo
  14. spec:
  15. containers:
  16. - name: http-echo
  17. image: hashicorp/http-echo
  18. args: ["-text", "hello-world"]
  19. ports:
  20. - containerPort: 5678
  21. ---
  22. apiVersion: v1
  23. kind: Service
  24. metadata:
  25. name: http-echo
  26. spec:
  27. ports:
  28. - port: 5678
  29. protocol: TCP
  30. targetPort: 5678
  31. selector:
  32. app: http-echo

部署完成并验证如下:

  1. [root@k8s-node001 Test]# kubectl get po
  2. NAME READY STATUS RESTARTS AGE
  3. http-echo-57dd74545-rtxzm 1/1 Running 0 65s
  4. http-echo-57dd74545-trst7 1/1 Running 0 65s
  5. [root@k8s-node001 Test]# kubectl get svc
  6. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  7. http-echo ClusterIP 10.102.221.64 <none> 5678/TCP 70s
  8. [root@k8s-node001 Test]# curl 10.102.221.64:5678
  9. hello-world

以上YAML文件能部署成功,但是,它遵循最佳做法吗?

Let's start.

kubeval

kubeval的前提是与Kubernetes的任何交互都通过其REST API进行。

因此,可以使用API模式来验证给定的YAML输入是否符合该模式。

安装kubeval

  1. wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz
  2. tar xf kubeval-linux-amd64.tar.gz
  3. cp kubeval /usr/local/bin

现在我们来改下base.yaml,删除

  1. selector:
  2. matchLabels:
  3. app: http-echo

然后使用kubeval对base.yaml检查

  1. [root@k8s-node001 Test]# kubeval base.yaml
  2. WARN - base.yaml contains an invalid Deployment (http-echo) - selector: selector is required
  3. PASS - base.yaml contains a valid Service (http-echo)

输出看到一个WARN,提示selector是必须的字段

然后恢复selector,再次检查

  1. [root@k8s-node001 Test]# kubeval base.yaml
  2. PASS - base.yaml contains a valid Deployment (http-echo)
  3. PASS - base.yaml contains a valid Service (http-echo)

检查PASS

kubeval之类的工具的优势在于,咱们可以在部署周期的早期发现此类错误。

另外,您不需要访问集群即可运行检查-它们可以脱机运行。

默认情况下,kubeval会根据最新的未发布的Kubernetes API模式验证资源。

更多用法详情请参见官网

kube-score

kube-score会对你提供的YAML清单进行分析,并针对集群的内置检查对其进行评分。

kube-score提供在线版和离线

本文偷懒就用在线版了

首先打开https://kube-score.com/ ,然后在输入框贴入写好的YAML清单,这里以上文base.yaml来分析

解析结果如下

从如上可以看到针对这个文件给出的建议,比如资源限制、镜像TAG、Pod网络策略等。不错吧,非常好用的工具。。。

当然,kube-score并不可扩展,并且您不能添加或调整策略。

如果要编写自定义检查以符合组织策略,则可以使用以下四个工具之一:config-lint,copper,conftest或Polaris。

Config-lint

Config-lint是用于验证以YAML,JSON,Terraform,CSV和Kubernetes清单编写的配置文件的工具。

安装Config-lint

  1. wget https://github.com/stelligent/config-lint/releases/download/v1.6.0/config-lint_Linux_x86_64.tar.gz
  2. tar -zxf config-lint_Linux_x86_64.tar.gz
  3. mv config-lint /usr/local/bin/

Config-lint并没有对Kubernetes清单进行内置检查。你必须编写自己的规则才能执行任何验证。

规则被写为YAML文件,称为规则集,并具有以下结构:

  1. version: 1
  2. description: Rules for Kubernetes spec files
  3. type: Kubernetes
  4. files:
  5. - "*.yaml"
  6. rules:
  7. # list of rules

假设咱们希望检查部署中的镜像是否总是从可信任的仓库(例如kubeops.net/app:1.0 )中提取。

实施此类检查的config-lint规则如下所示:

  1. - id: MY_DEPLOYMENT_IMAGE_TAG
  2. severity: FAILURE
  3. message: Deployment must use a valid image tag
  4. resource: Deployment
  5. assertions:
  6. - every:
  7. key: spec.template.spec.containers
  8. expressions:
  9. - key: image
  10. op: starts-with
  11. value: "kubeops.net/"

一个完整的规则集如下所示:

  1. version: 1
  2. description: Rules for Kubernetes spec files
  3. type: Kubernetes
  4. files:
  5. - "*.yaml"
  6. rules:
  7. - id: DEPLOYMENT_IMAGE_REPOSITORY
  8. severity: FAILURE
  9. message: Deployment must use a valid image repository
  10. resource: Deployment
  11. assertions:
  12. - every:
  13. key: spec.template.spec.containers
  14. expressions:
  15. - key: image
  16. op: starts-with
  17. value: "kubeops.net/"

如果要测试检查,可以将规则集另存为check_image_repo.yaml。

然后使用config-lint执行检查

  1. [root@k8s-node001 Test]# config-lint -rules check_image_repo.yaml base.yaml
  2. [
  3. {
  4. "AssertionMessage": "Every expression fails: And expression fails: image does not start with kubeops.net/",
  5. "Category": "",
  6. "CreatedAt": "2020-11-02T08:28:43Z",
  7. "Filename": "base.yaml",
  8. "LineNumber": 0,
  9. "ResourceID": "http-echo",
  10. "ResourceType": "Deployment",
  11. "RuleID": "DEPLOYMENT_IMAGE_REPOSITORY",
  12. "RuleMessage": "Deployment must use a valid image repository",
  13. "Status": "FAILURE"
  14. }
  15. ]

可以看到Every expression fails,检测不通过。

现在我们来改下images地址为image: kubeops.net/http-echo,再来检查一次

  1. [root@k8s-node001 Test]# config-lint -rules check_image_repo.yaml base.yaml
  2. []

输出不报错即为成功。

Config-lint是一个很有前途的框架,可以让你使用YAML DSL为Kubernetes YAML清单编写自定义检查。

但是,如果您想表达更复杂的逻辑和检查该怎么办?

YAML对此是否也有限制?

如果您可以使用真正的编程语言来表达这些检查,该怎么办?接下来看Copper

Copper

Copper V2是一个使用自定义检查来验证清单的框架,就像config-lint一样。

但是,Copper不使用YAML定义检查。

相反,测试是用JavaScript编写的,而Copper提供了一个包含一些基本帮助程序的库,以帮助读取Kubernetes对象和报告错误。

安装Copper

  1. https://github.com/cloud66-oss/copper/releases/download/2.0.1/linux_amd64_2.0.1
  2. mv linux_amd64_2.0.1 copper
  3. chmod + x copper
  4. mv copper /usr/local/bin/

与config-lint相似,Copper并没有提供内置检查。

让我们自定义一个检查,以确保部署镜像tag必须非latest。

check_image_repo.js

  1. $$.forEach(function($){
  2. if ($.kind === 'Deployment') {
  3. $.spec.template.spec.containers.forEach(function(container) {
  4. var image = new DockerImage(container.image);
  5. if (image.tag === 'latest') {
  6. errors.add_error('no_latest',"latest is used in " + $.metadata.name, 1)
  7. }
  8. });
  9. }
  10. });

执行检查

  1. [root@k8s-node001 Test]# copper validate --in=base.yaml --validator=check_image_tag.js
  2. Check no_latest failed with severity 1 due to latest is used in http-echo
  3. Validation failed

现在修改为image: kubeops.net/http-echo:v1.0.0

  1. [root@k8s-node001 Test]# copper validate --in=base.yaml --validator=check_image_tag.js
  2. Validation successful

更多用法参见

Conftest

Conftest是用于配置数据的测试框架,可用于检查和验证Kubernetes清单。

测试使用专用查询语言Rego编写的。

安装Conftest

  1. wget https://github.com/open-policy-agent/conftest/releases/download/v0.21.0/conftest_0.21.0_Linux_x86_64.tar.gz
  2. tar -xzf conftest_0.21.0_Linux_x86_64.tar.gz
  3. mv conftest /usr/local/bin

与config-lint和copper类似,conftest没有任何内置检查。

首先创建一个新目录conftest-checks和一个名为check_image_registry.rego的文件,其内容如下:

  1. package main
  2. deny[msg] {
  3. input.kind == "Deployment"
  4. image := input.spec.template.spec.containers[_].image
  5. not startswith(image, "kubeops.net/")
  6. msg := sprintf("image '%v' doesn't come from kubeops.net repository", [image])
  7. }

先修改base.yaml,image: docker.io/http-echo

使用conftest执行检测

  1. [root@k8s-node001 Test]# conftest test --policy ./conftest-checks base.yaml
  2. FAIL - base.yaml - image 'docker.io/http-echo:v1.0.0' doesn't come from kubeops.net repository
  3. 2 tests, 1 passed, 0 warnings, 1 failure, 0 exceptions

再次修改为base.yaml,image: kubeops.net/http-echo

  1. [root@k8s-node001 Test]# conftest test --policy ./conftest-checks base.yaml
  2. 2 tests, 2 passed, 0 warnings, 0 failures, 0 exceptions

更多用法参见

Polaris

最后一个工具了,Polaris既可以安装在集群内部,也可以作为命令行工具来静态分析Kubernetes清单。

作为命令行工具运行时,它包含多个内置检查,涉及诸如安全性和最佳实践等方面,类似于kube-score。

另外,你可以使用它来编写类似于config-lint,copper和conftest的自定义检查。

换句话说,Polaris结合了两类的优点:内置和自定义检查器。

安装Polaris,这里只安装命令行模式

  1. wget https://github.com/FairwindsOps/polaris/releases/download/1.2.1/polaris_1.2.1_linux_amd64.tar.gz
  2. tar -zxf polaris_1.2.1_linux_amd64.tar.gz
  3. mv polaris /usr/local/bin/

安装完成后,就可以使用Polaris对base.yaml进行检查

[root@k8s-node001 Test]# polaris audit --audit-path base.yaml

结果如下,信息比较多,这里只截取部分信息,自己可以仔细看看分析出来的结果。

  1. "PolarisOutputVersion": "1.0",
  2. "AuditTime": "0001-01-01T00:00:00Z",
  3. "SourceType": "Path",
  4. "SourceName": "base.yaml",
  5. "DisplayName": "base.yaml",
  6. "ClusterInfo": {
  7. "Version": "unknown",
  8. "Nodes": 0,
  9. "Pods": 1,
  10. "Namespaces": 0,
  11. "Controllers": 1
  12. },
  13. "Results": [
  14. {
  15. "Name": "http-echo",
  16. "Namespace": "",
  17. "Kind": "Deployment",
  18. "Results": {},
  19. "PodResult": {
  20. "Name": "",
  21. "Results": {
  22. "hostIPCSet": {
  23. "ID": "hostIPCSet",
  24. "Message": "Host IPC is not configured",
  25. "Success": true,
  26. "Severity": "danger",
  27. "Category": "Security"
  28. ..............
  29. "tagNotSpecified": {
  30. "ID": "tagNotSpecified",
  31. "Message": "Image tag is specified",
  32. "Success": true,
  33. "Severity": "danger",
  34. "Category": "Images"
  35. }
  36. }
  37. }
  38. ]
  39. },
  40. "CreatedTime": "0001-01-01T00:00:00Z"
  41. }
  42. ]
  43. }

另外,可以只输出评分

  1. [root@k8s-node001 Test]# polaris audit --audit-path base.yaml --format score
  2. 66

下面使用YAML代码段定义了一个称为checkImageRepo的新检查:

config_with_custom_check.yaml

  1. checks:
  2. checkImageRepo: danger
  3. customChecks:
  4. checkImageRepo:
  5. successMessage: Image registry is valid
  6. failureMessage: Image registry is not valid
  7. category: Images
  8. target: Container
  9. schema:
  10. '$schema': http://json-schema.org/draft-07/schema
  11. type: object
  12. properties:
  13. image:
  14. type: string
  15. pattern: ^kubeops.net/.+$

现在base.yaml的image为:image: docker.io/http-echo:v1.0.0

我们来使用自定义的规则执行检查

  1. [root@k8s-node001 Test]# polaris audit --config config_with_custom_check.yaml --audit-path base.yaml
  2. {
  3. "PolarisOutputVersion": "1.0",
  4. "AuditTime": "0001-01-01T00:00:00Z",
  5. "SourceType": "Path",
  6. "SourceName": "base.yaml",
  7. "DisplayName": "base.yaml",
  8. "ClusterInfo": {
  9. "Version": "unknown",
  10. "Nodes": 0,
  11. "Pods": 1,
  12. "Namespaces": 0,
  13. "Controllers": 1
  14. },
  15. "Results": [
  16. {
  17. "Name": "http-echo",
  18. "Namespace": "",
  19. "Kind": "Deployment",
  20. "Results": {},
  21. "PodResult": {
  22. "Name": "",
  23. "Results": {},
  24. "ContainerResults": [
  25. {
  26. "Name": "http-echo",
  27. "Results": {
  28. "checkImageRepo": {
  29. "ID": "checkImageRepo",
  30. "Message": "Image registry is not valid",
  31. "Success": false,
  32. "Severity": "danger",
  33. "Category": "Images"
  34. }
  35. }
  36. }
  37. ]
  38. },
  39. "CreatedTime": "0001-01-01T00:00:00Z"
  40. }
  41. ]
  42. }

结果显示"Message": "Image registry is not valid", "Success": false,

然后修改base.yaml的image为:image: kubeops.net/http-echo:v1.0.0

再次执行检查

  1. [root@k8s-node001 Test]# polaris audit --config config_with_custom_check.yaml --audit-path base.yaml
  2. {
  3. "PolarisOutputVersion": "1.0",
  4. "AuditTime": "0001-01-01T00:00:00Z",
  5. "SourceType": "Path",
  6. "SourceName": "base.yaml",
  7. "DisplayName": "base.yaml",
  8. "ClusterInfo": {
  9. "Version": "unknown",
  10. "Nodes": 0,
  11. "Pods": 1,
  12. "Namespaces": 0,
  13. "Controllers": 1
  14. },
  15. "Results": [
  16. {
  17. "Name": "http-echo",
  18. "Namespace": "",
  19. "Kind": "Deployment",
  20. "Results": {},
  21. "PodResult": {
  22. "Name": "",
  23. "Results": {},
  24. "ContainerResults": [
  25. {
  26. "Name": "http-echo",
  27. "Results": {
  28. "checkImageRepo": {
  29. "ID": "checkImageRepo",
  30. "Message": "Image registry is valid",
  31. "Success": true,
  32. "Severity": "danger",
  33. "Category": "Images"
  34. }
  35. }
  36. }
  37. ]
  38. },
  39. "CreatedTime": "0001-01-01T00:00:00Z"
  40. }
  41. ]
  42. }

从输出看到 "Message": "Image registry is valid","Success": true,,检查通过。。。

更多用法参见

总结

尽管有很多工具可以对Kubernetes YAML文件进行验证,评分和整理,但重要的是要有一个健康的模型来设计和执行检查。

例如,如果你要考虑通过管道的Kubernetes清单,则kubeval可能是该管道中的第一步,因为它可以验证对象定义是否符合Kubernetes API模式。一旦此检查成功,你可以继续进行更详尽的测试,例如标准最佳实践和自定义策略。

Kube-score和Polaris是比较好的选择。

如果你有复杂的要求,并且想要自定义检查的细节,则应考虑使用copper ,config-lint和conftest。

尽管conftest和config-lint都使用更多的YAML来定义自定义验证规则,但是Copper允许访问一种真正的编程语言,这使其颇具吸引力。

但是,你应该使用其中之一并从头开始编写所有检查吗?还是应该使用Polaris并仅编写其他自定义检查?

这都取决于你自己,合适自己的才是最好的。。。

Kubernetes YAML最佳实践和策略的更多相关文章

  1. 验证Kubernetes YAML的最佳实践和策略

    本文来自Rancher Labs Kubernetes工作负载最常见的定义是YAML格式的文件.使用YAML所面临的挑战之一是,它相当难以表达manifest文件之间的约束或关系. 如果你想检查所有部 ...

  2. Kubernetes Deployment 最佳实践

    零.示例 首先给出一个 Deployment+HPA+ PodDisruptionBudget 的完整 demo,后面再详细介绍其中的每一个部分: apiVersion: apps/v1 kind: ...

  3. Kubernetes生产环境最佳实践

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 众所周知,Kubernetes很难! 以下是在生产中使用 ...

  4. 生产环境容器落地最佳实践 --JFrog 内部K8s落地旅程

    引言 Kubernetes已经成为市场上事实上领先的编配工具,不仅对技术公司如此,对所有公司都是如此,因为它允许您快速且可预测地部署应用程序.动态地伸缩应用程序.无缝地推出新特性,同时有效地利用硬件资 ...

  5. Kubernetes集群的监控报警策略最佳实践

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79652064 本文为Kub ...

  6. 可能是Asp.net Core On host、 docker、kubernetes(K8s) 配置读取的最佳实践

    写在前面 为了不违反广告法,我竭尽全力,不过"最佳实践"确是标题党无疑,如果硬要说的话 只能是个人最佳实践. 问题引出 ​ 可能很多新手都会遇到同样的问题:我要我的Asp.net ...

  7. Kubernetes 服务部署最佳实践(二) ——如何提高服务可用性

    引言 上一篇文章我们围绕如何合理利用资源的主题做了一些最佳实践的分享,这一次我们就如何提高服务可用性的主题来展开探讨. 怎样提高我们部署服务的可用性呢?K8S 设计本身就考虑到了各种故障的可能性,并提 ...

  8. 在CentOS 7.6 以 kubeadm 安装 Kubernetes 1.15 最佳实践

    前言 Kubernetes作为容器编排工具,简化容器管理,提升工作效率而颇受青睐.很多新手部署Kubernetes由于"scientifically上网"问题举步维艰,本文以实战经 ...

  9. Kubernetes 微服务最佳实践

    本文由个人笔记 ryan4yin/knowledge 整理而来 本文主要介绍我个人在使用 Kubernetes 的过程中,总结出的一套「Kubernetes 配置」,是我个人的「最佳实践」. 其中大部 ...

随机推荐

  1. requests和正则表达式爬取猫眼电影Top100练习

    1 import requests 2 import re 3 from multiprocessing import Pool 4 from requests.exceptions import R ...

  2. Shiro入门学习---使用自定义Realm完成认证|练气中期

    写在前面 在上一篇文章<shiro认证流程源码分析--练气初期>当中,我们简单分析了一下shiro的认证流程.不难发现,如果我们需要使用其他数据源的信息完成认证操作,我们需要自定义Real ...

  3. Java知识系统回顾整理01基础05控制流程08综合练习

    一.练习--黄金分割点 题目: 寻找某两个数相除,其结果 离黄金分割点 0.618最近 分母和分子不能同时为偶数 分母和分子 取值范围在[1,20] (即1到20) 要求效果: public clas ...

  4. Win10桌面不见了只显示开始菜单该怎么办?

    来源:http://www.w10zj.com/Win10xy/Win10xf_4256.html 在Win10系统中,有用户反应桌面不见了,只显示开始菜单的情况,该怎么办呢?出现这样的情况一般由于桌 ...

  5. 下载 node.js 步骤 bower npm 报错解决

    1,下载node.js  ,安装之后就可以 了 2,解决"npm不是内部或外部命令"   ,打开安装的node.js  的文件夹 将这个地址,放在环境变量里面 <1,属性环境 ...

  6. dirsearch下载与简单实用

    下载 下载地址   我的电脑是Windows,而且我也有python3.6的环境,所以我是直接clone到本地就能使用了.   命令的提示在上面的下载地址里就有,这里给个最简单的命令(脚本小子专属,我 ...

  7. 使用AirtestProject+pytest做支付宝小程序UI自动化测试

    一,前言 1,背景 因公司业务需要做支付宝小程序的UI自动化测试,于是在网上查找小程序的自动化资料,发现微信小程序是有自己的测试框架的,但几乎找不到支付宝小程序UI自动化测试相关的资料.白piao失败 ...

  8. MeteoInfoLab脚本示例:TRMM 3B43 HDF数据

    TRMM 3B43是卫星观测月平均降水量产品,是HDF的格点数据.需要注意的是数据中降水变量维的顺序里经度维在前纬度维在后,这与通常的设置(纬度维在前经度维在后)相反,需要对获取的二维数组进行转置,使 ...

  9. .Net Core中使用Grpc

    一.Grpc概述 gRPC 基于如下思想:定义一个服务, 指定其可以被远程调用的方法及其参数和返回类型.gRPC 默认使用protocol buffers作为接口定义语言,来描述服务接口和有效载荷消息 ...

  10. day58 Pyhton 框架Django 01

    内容回顾 python基础    网路编程    并发编程    数据库    前端     osi7层           tcp/ip 5层模型    应用层    表示层             ...