云原生安全管理器-kyverno

74 阅读2分钟

前言

随着云原生技术的普及,越来越多的企业开始拥向云原生基础架构的怀抱,随之带来的云原生安全问题同样很严峻, 从 Redhat 公司 《2022 年 Kubernetes 安全现状报告》中,我们发现,受访者最担心由于容器和 Kubernetes 环境中的错误配置而导致的风险

所以kyverno应运而生,它是专门为kubernetes 设计的策略引擎 它的功能包括

  • 作为k8s 的资源策略
  • validate 、 mutate 、create 、clean 任何策略
  • 验证容器镜像保证软件源安全
  • 校验镜像元数据安全
  • 使用标签选择器和通配符匹配资源
  • 使用覆盖层进行validate和mutate(例如 Kustomize!)
  • 跨命名空间同步配置
  • 使用准入控制阻止不合格的资源,或报告策略违规行为
  • 自助服务报告(无专有审核日志!)
  • 自主服务政策例外情况
  • 在应用于集群之前,在CI/CD管道中使用kyvernoCli测试策略并验证资源
  • 使用git 以代码形式管理kustomize

工作原理

简单来说kyverno 就是一个k8s层面的准入控制器,依靠很多webhook 来实现功能 image.png

安装

kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.11.1/install.yaml

简单来说kyverno 就四个功能validate 、mutate、generate、cleanup 其中官方文档给了前三个例子

validate

比如说我们要求创建的pod 必须有hello这个label的key 我们首先创建如下资源

apiVersion: kyverno.io/v1 
kind: ClusterPolicy 
metadata:
  name: require-labels 
spec: 
  validationFailureAction: Enforce
  rules: 
  - name: check-team 
    match: any: 
    - resources: 
      kinds: 
      - Pod 
    validate: 
      message: "label 'team' is required" 
      pattern: 
        metadata: 
          labels: 
            hello: "?*"

然后创建对应pod

kubectl create deploy nginx --image=nginx

会发现创建失败

当执行

kubectl run nginx --image nginx --labels hello=world 

mutate

mutate 是一个更改操作,下面是一个演示,要求所有pod创建前都要加上 hello=world 的label 1 下发如下资源

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-labels
spec:
  rules:
  - name: add-team
    match:
      any:
      - resources:
          kinds:
          - Pod
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            +(hello): world

2 创建pod

kubectl run redis --image redis

3 等pod runing 起来后检查

kubectl get pod redis --show-labels

Generation

1 创建secret

kubectl -n default create secret docker-registry regcred \
  --docker-server=myinternalreg.corp.com \
  --docker-username=john.doe \
  --docker-password=Passw0rd123! \
  --docker-email=john.doe@corp.com

2 下发策略

kubectl create -f- << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: sync-secrets
spec:
  rules:
  - name: sync-image-pull-secret
    match:
      any:
      - resources:
          kinds:
          - Namespace
    generate:
      apiVersion: v1
      kind: Secret
      name: regcred
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      clone:
        namespace: default
        name: regcred
EOF

3 创建ns

kubectl create ns hello-world

然后发现secret regcred 已经在 hello-world 命名空间创建好了