使用Kubesec检查YAML文件安全
参考文档:
-
Kubesec 官方文档
-
Security | Kubernetes
Kubesec 是一个开源的 Kubernetes 安全评估工具,可以帮助用户发现和修复 Kubernetes 配置文件中的安全问题,从而提高集群的安全性。
一、安装 Kubesec
1. 本地安装(macOS/Linux)
# 通过 curl 安装
curl -sSfL https://github.com/kubesec/kubesec/releases/download/v2.13.0/kubesec_linux_amd64.tar.gz | tar xz
sudo mv kubesec /usr/local/bin/
# 验证安装
kubesec version
2. 容器化运行(无需安装)
docker run -i kubesec/kubesec:v2.13.0 scan /dev/stdin < your-deployment.yaml
3. HTTP方式运行
二进制
# kubesec http 8080 &
[1] 28463
# {"severity":"info","timestamp":"2021-07-20T21:58:28.905+0800","caller":"server/server.go:41","message":"Starting HTTP server on port 8080"}
Docker容器
# docker run -d -p 8080:8080 kubesec/kubesec http 8080
案例
# curl -sSX POST --data-binary @ingress-controller.yaml http://localhost:8080/scan
[
{
"object": "Namespace/ingress-nginx.default",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "ConfigMap/nginx-configuration.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "ConfigMap/tcp-services.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "ConfigMap/udp-services.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "ServiceAccount/nginx-ingress-serviceaccount.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "ClusterRole/nginx-ingress-clusterrole.default",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "Role/nginx-ingress-role.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "RoleBinding/nginx-ingress-role-nisa-binding.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "ClusterRoleBinding/nginx-ingress-clusterrole-nisa-binding.default",
"valid": true,
"fileName": "API",
"message": "This resource kind is not supported by kubesec",
"score": 0,
"scoring": {}
},
{
"object": "DaemonSet/nginx-ingress-controller.ingress-nginx",
"valid": true,
"fileName": "API",
"message": "Failed with a score of -11 points",
"score": -11,
"scoring": {
"critical": [
{
"id": "HostNetwork",
"selector": ".spec .hostNetwork == true",
"reason": "Sharing the host's network namespace permits processes in the pod to communicate with processes bound to the host's loopback adapter",
"points": -9
},
{
"id": "AllowPrivilegeEscalation",
"selector": "containers[] .securityContext .allowPrivilegeEscalation == true",
"reason": "",
"points": -7
}
],
"passed": [
{
"id": "ServiceAccountName",
"selector": ".spec .serviceAccountName",
"reason": "Service accounts restrict Kubernetes API access and should be configured with least privilege",
"points": 3
},
{
"id": "CapDropAny",
"selector": "containers[] .securityContext .capabilities .drop",
"reason": "Reducing kernel capabilities available to a container limits its attack surface",
"points": 1
},
{
"id": "CapDropAll",
"selector": "containers[] .securityContext .capabilities .drop | index(\"ALL\")",
"reason": "Drop all capabilities and add only those required to reduce syscall attack surface",
"points": 1
}
],
"advise": [
{
"id": "ApparmorAny",
"selector": ".metadata .annotations .\"container.apparmor.security.beta.kubernetes.io/nginx\"",
"reason": "Well defined AppArmor policies may provide greater protection from unknown threats. WARNING: NOT PRODUCTION READY",
"points": 3
},
{
"id": "SeccompAny",
"selector": ".metadata .annotations .\"container.seccomp.security.alpha.kubernetes.io/pod\"",
"reason": "Seccomp profiles set minimum privilege and secure against unknown threats",
"points": 1
},
{
"id": "LimitsCPU",
"selector": "containers[] .resources .limits .cpu",
"reason": "Enforcing CPU limits prevents DOS via resource exhaustion",
"points": 1
},
{
"id": "RequestsMemory",
"selector": "containers[] .resources .limits .memory",
"reason": "Enforcing memory limits prevents DOS via resource exhaustion",
"points": 1
},
{
"id": "RequestsCPU",
"selector": "containers[] .resources .requests .cpu",
"reason": "Enforcing CPU requests aids a fair balancing of resources across the cluster",
"points": 1
},
{
"id": "RequestsMemory",
"selector": "containers[] .resources .requests .memory",
"reason": "Enforcing memory requests aids a fair balancing of resources across the cluster",
"points": 1
},
{
"id": "ReadOnlyRootFilesystem",
"selector": "containers[] .securityContext .readOnlyRootFilesystem == true",
"reason": "An immutable root filesystem can prevent malicious binaries being added to PATH and increase attack cost",
"points": 1
},
{
"id": "RunAsNonRoot",
"selector": "containers[] .securityContext .runAsNonRoot == true",
"reason": "Force the running image to run as a non-root user to ensure least privilege",
"points": 1
},
{
"id": "RunAsUser",
"selector": "containers[] .securityContext .runAsUser -gt 10000",
"reason": "Run as a high-UID user to avoid conflicts with the host's user table",
"points": 1
}
]
}
}
]
二、扫描 YAML 文件
1. 扫描单个文件
kubesec scan your-deployment.yaml
2. 扫描目录下所有文件
kubesec scan ./manifests/
3. 输出 JSON 格式报告
kubesec scan --format=json your-deployment.yaml > report.json
三、解读扫描结果
Kubesec 会对资源配置进行评分(0-100)并标记风险等级(Critical
/Warning
/Advise
)。以下是常见问题及示例:
1. 高风险问题(Critical)
-
容器以 root 用户运行
{ "id": "runAsRootAllowed", "selector": ".spec.securityContext.runAsNonRoot != true", "reason": "容器未强制以非 root 用户运行", "category": "Security", "severity": "Critical" }
修复方案:
在容器或 Pod 级别设置securityContext
:securityContext: runAsNonRoot: true runAsUser: 1000
-
未设置资源限制(Resource Limits)
{ "id": "unsetResources", "selector": "containers[] .resources.limits", "reason": "未定义 CPU/内存限制", "severity": "Critical" }
修复方案:
添加资源请求和限制:resources: requests: cpu: "100m" memory: "256Mi" limits: cpu: "500m" memory: "512Mi"
2. 警告问题(Warning)
-
未启用只读根文件系统
{ "id": "readOnlyRootFilesystem", "selector": "containers[] .securityContext.readOnlyRootFilesystem != true", "reason": "容器根文件系统可写", "severity": "Warning" }
修复方案:
securityContext: readOnlyRootFilesystem: true
-
允许特权模式(Privileged)
{ "id": "privileged", "selector": "containers[] .securityContext.privileged == true", "reason": "容器以特权模式运行", "severity": "Warning" }
修复方案:
避免设置privileged: true
,除非必要。
四、集成到 CI/CD 流程
1. GitLab CI 示例
stages:
- security
kubesec-scan:
stage: security
image: kubesec/kubesec:v2.13.0
script:
- kubesec scan ./k8s/*.yaml
rules:
- if: $CI_COMMIT_BRANCH == "main"
2. GitHub Actions 示例
name: Kubesec Scan
on: [push]
jobs:
kubesec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Kubesec
uses: docker://kubesec/kubesec:v2.13.0
with:
args: scan ./deploy/*.yaml
五、忽略特定规则
若需跳过某些检查,可通过 --ignore
参数排除规则 ID:
kubesec scan --ignore=unsetResources,privileged your-deployment.yaml
六、进阶用法
1. 自定义规则
创建 kubesec-rules.yaml
定义自定义规则:
customChecks:
- id: "noLatestTag"
severity: "Critical"
message: "禁止使用 'latest' 标签"
resource: "Pod"
selector: "spec.containers[].image"
regex: ":latest$"
运行扫描时加载自定义规则:
kubesec scan --rules=kubesec-rules.yaml your-deployment.yaml
2. 与 kube-score
结合使用
kube-score
提供更全面的 Kubernetes 资源健康检查:
kube-score score your-deployment.yaml
七、常见问题排查
1. 扫描结果无输出
-
原因:YAML 文件语法错误或包含非 Kubernetes 资源。
-
解决:使用
kubectl apply --dry-run=client
验证 YAML 合法性。
2. 误报或漏报
-
调整规则阈值:
kubesec scan --min-score=80 your-deployment.yaml # 仅显示评分低于 80 的资源
-
手动覆盖规则:在 YAML 中添加注释忽略检查:
# kubesec-ignore: unsetResources
总结
通过 Kubesec 扫描可有效识别 Kubernetes 资源配置中的安全隐患,建议:
-
关键修复:优先处理
Critical
问题(如 root 容器、未设置资源限制)。 -
自动化集成:将扫描嵌入 CI/CD 流水线,阻断不安全部署。
-
定期更新规则:关注 Kubesec 版本更新,及时适配新规则。