hackertwinten/clair-helm
GitHub: hackertwinten/clair-helm
提供在 Kubernetes 上快速部署和管理 Clair 容器漏洞扫描器的 Helm Chart,支持一体化和分布式两种架构模式。
Stars: 0 | Forks: 0
# clair-helm
[](https://github.com/hackertwinten/clair-helm/actions/workflows/lint-test.yml)
[](https://github.com/hackertwinten/clair-helm/actions/workflows/release.yml)
[](LICENSE)
[](https://artifacthub.io/packages/helm/clair-helm/clair)
用于部署 [Clair](https://github.com/quay/clair) 的 Helm chart —— Red Hat/Quay 开发的开源容器漏洞静态分析工具。
支持两种部署模式:
- **`combo`**(默认)—— 单个一体式 Clair 进程运行 indexer + matcher,带有可选的独立 notifier pod
- **`distributed`** —— 每个组件(indexer、matcher、notifier)使用独立的 Deployment,并采用基于路径的 Ingress 路由
## 目录
- [前提条件](#prerequisites)
- [安装说明](#installation)
- [部署模式](#deployment-modes)
- [配置说明](#configuration)
- [配置参考](#values-reference)
- [升级指南](#upgrading)
- [卸载说明](#uninstalling)
## 前提条件
- Kubernetes 1.24+
- Helm 3.10+
- 已针对您的集群配置好的 `kubectl`
- 对于 distributed 模式:需要七层(Layer 7)Ingress controller(nginx、traefik 等)
## 安装说明
### 从 Helm 仓库安装(推荐)
```
helm repo add clair-helm https://hackertwinten.github.io/clair-helm
helm repo update
helm install clair clair-helm/clair -n clair --create-namespace
```
### 从源码安装
```
git clone https://github.com/hackertwinten/clair-helm.git
cd clair-helm
helm install clair . -n clair --create-namespace
```
验证 release:
```
helm status clair -n clair
kubectl get pods -n clair
```
运行健康检查测试:
```
helm test clair -n clair
```
通过端口转发在本地访问 API(combo 模式):
```
kubectl port-forward -n clair svc/clair 6060:6060
curl http://localhost:6060/api/v1/index_report
```
## 部署模式
### Combo 模式(默认)
在单个进程中运行所有 Clair 组件(`CLAIR_MODE=combo`)。可选的第二个 pod 可以独立处理通知。
```
helm install clair ./clair-helm -n clair --create-namespace
```
创建的资源:
| 资源 | 描述 |
|---|---|
| `Deployment/clair` | `combo` 模式下的 Clair 主进程 |
| `Deployment/clair-notifier` | 专用的 notifier pod(`combo.notifier.enabled=true`) |
| `Deployment/clair-postgresql` | 内置的 PostgreSQL 15 |
| `Service/clair` | 位于端口 6060 和 8089 的 ClusterIP |
| `Service/clair-notifier` | notifier 的 ClusterIP |
| `Service/clair-postgresql` | Postgres 的 ClusterIP |
| `Secret/clair-db` | 数据库密码(自动生成) |
| `Secret/clair-config` | Clair 配置 YAML |
| `PersistentVolumeClaim/clair-postgresql` | 10Gi 数据卷 |
### Distributed 模式
将每个 Clair 组件作为其独立的 Deployment 运行。需要七层(Layer 7)Ingress controller 以根据路径路由请求。
```
helm install clair ./clair-helm -n clair --create-namespace \
--set mode=distributed \
--set distributed.ingress.enabled=true \
--set distributed.ingress.className=nginx \
--set distributed.ingress.host=clair.example.com
```
创建的资源:
| 资源 | 描述 |
|---|---|
| `Deployment/clair-indexer` | Indexer 组件 |
| `Deployment/clair-matcher` | Matcher 组件 |
| `Deployment/clair-notifier` | Notifier 组件(如果启用) |
| `Service/clair-indexer` | indexer 的 ClusterIP |
| `Service/clair-matcher` | matcher 的 ClusterIP |
| `Service/clair-notifier` | notifier 的 ClusterIP |
| `Ingress/clair` | 将 `/indexer`、`/matcher`、`/notifier` 路由到各个 service |
| `Deployment/clair-postgresql` | 内置的 PostgreSQL 15 |
| `Secret/clair-config` | 共享的 Clair 配置 YAML |
Ingress 根据路径前缀路由流量:
- `clair.example.com/indexer/*` → indexer
- `clair.example.com/matcher/*` → matcher
- `clair.example.com/notifier/*` → notifier
## 配置说明
所有选项均在 [`values.yaml`](values.yaml) 中。常见的覆盖配置:
### 使用外部 PostgreSQL 数据库
```
helm install clair ./clair-helm -n clair --create-namespace \
--set postgresql.enabled=false \
--set database.externalConnString="host=mydb.example.com port=5432 dbname=clair user=clair password=s3cr3t sslmode=require"
```
### 设置特定的数据库密码
默认情况下,chart 会在首次安装时生成一个随机的 32 位密码,并在升级时重复使用该密码。要设置您自己的密码:
```
helm install clair ./clair-helm -n clair --create-namespace \
--set database.password=mysecretpassword
```
### 禁用 notifier
```
# Combo mode
helm install clair ./clair-helm -n clair --create-namespace \
--set combo.notifier.enabled=false
# Distributed mode
helm install clair ./clair-helm -n clair --create-namespace \
--set mode=distributed \
--set distributed.notifier.enabled=false
```
### 启用 Ingress(combo 模式)
```
helm install clair ./clair-helm -n clair --create-namespace \
--set combo.ingress.enabled=true \
--set combo.ingress.className=nginx \
--set "combo.ingress.hosts[0].host=clair.example.com" \
--set "combo.ingress.hosts[0].paths[0].path=/" \
--set "combo.ingress.hosts[0].paths[0].pathType=Prefix"
```
### 启用 HPA(combo 模式)
```
helm install clair ./clair-helm -n clair --create-namespace \
--set combo.autoscaling.enabled=true \
--set combo.autoscaling.minReplicas=2 \
--set combo.autoscaling.maxReplicas=5
```
### 启用各组件的 HPA(distributed 模式)
```
helm install clair ./clair-helm -n clair --create-namespace \
--set mode=distributed \
--set distributed.indexer.autoscaling.enabled=true \
--set distributed.indexer.autoscaling.maxReplicas=10 \
--set distributed.matcher.autoscaling.enabled=true \
--set distributed.matcher.autoscaling.maxReplicas=10
```
### 设置资源限制
```
# custom-values.yaml
combo:
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
postgresql:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
```
### 配置 webhook 通知
```
# custom-values.yaml
config:
notifier:
webhook:
target: "https://my-webhook.example.com/clair"
callback: "http://clair:6060/notifier/api/v1/notifications"
signed: false
```
## 配置参考
### 全局
| 键 | 默认值 | 描述 |
|---|---|---|
| `mode` | `combo` | 部署模式:`combo` 或 `distributed` |
| `nameOverride` | `""` | 覆盖 chart 名称 |
| `fullnameOverride` | `""` | 覆盖完整的 release 名称 |
| `image.repository` | `quay.io/projectquay/clair` | Clair 镜像 |
| `image.tag` | `4.9.0` | 镜像 tag(默认为 `appVersion`) |
| `config.logLevel` | `info` | 日志级别:`debug`、`info`、`warn`、`error` |
| `config.indexer.migrations` | `true` | 在启动时运行 DB 迁移 |
| `config.matcher.period` | `6h` | 同步漏洞数据的频率 |
| `config.matcher.disableUpdaters` | `false` | 禁用漏洞源更新 |
### 数据库
| 键 | 默认值 | 描述 |
|---|---|---|
| `database.externalConnString` | `""` | 完整的 PostgreSQL DSN(禁用内置 Postgres) |
| `database.name` | `clair` | 数据库名称 |
| `database.user` | `clair` | 数据库用户 |
| `database.password` | `""` | 密码(如果为空则自动生成) |
### PostgreSQL(内置)
| 键 | 默认值 | 描述 |
|---|---|---|
| `postgresql.enabled` | `true` | 部署内置的 PostgreSQL |
| `postgresql.image.tag` | `17-alpine` | PostgreSQL 镜像 tag |
| `postgresql.persistence.enabled` | `true` | 启用 PVC |
| `postgresql.persistence.existingClaim` | `""` | 使用预先存在的 PVC,而不是创建新的 |
| `postgresql.persistence.size` | `10Gi` | PVC 大小(设置了 `existingClaim` 时忽略) |
| `postgresql.persistence.storageClass` | `""` | 存储类(如果为空则使用集群默认值) |
### Combo 模式
| 键 | 默认值 | 描述 |
|---|---|---|
| `combo.replicaCount` | `1` | Clair 副本数 |
| `combo.service.type` | `ClusterIP` | Service 类型 |
| `combo.service.port` | `6060` | HTTP API 端口 |
| `combo.ingress.enabled` | `false` | 启用 Ingress |
| `combo.autoscaling.enabled` | `false` | 启用 HPA |
| `combo.pdb.enabled` | `false` | 启用 PodDisruptionBudget |
| `combo.notifier.enabled` | `true` | 部署专用的 notifier pod |
| `combo.notifier.replicaCount` | `1` | Notifier 副本数 |
### Distributed 模式
| 键 | 默认值 | 描述 |
|---|---|---|
| `distributed.ingress.enabled` | `true` | 启用基于路径的 Ingress(外部访问必需) |
| `distributed.ingress.host` | `clair.example.com` | Ingress 主机名 |
| `distributed.ingress.className` | `""` | Ingress 类名 |
| `distributed.indexer.replicaCount` | `2` | Indexer 副本数 |
| `distributed.indexer.autoscaling.enabled` | `false` | 为 indexer 启用 HPA |
| `distributed.matcher.replicaCount` | `2` | Matcher 副本数 |
| `distributed.matcher.autoscaling.enabled` | `false` | 为 matcher 启用 HPA |
| `distributed.notifier.enabled` | `true` | 部署 notifier |
| `distributed.notifier.replicaCount` | `1` | Notifier 副本数 |
## 安全性
所有 pod 均在以下配置下运行:
- `runAsNonRoot: true`
- `allowPrivilegeEscalation: false`
- `readOnlyRootFilesystem: true`
- 丢弃所有 Linux capabilities
Clair 配置(包含数据库密码)存储在 Kubernetes `Secret` 中,而不是 `ConfigMap` 中。当配置 secret 发生变化时,pod 会通过 checksum annotation 自动重启。
## 升级指南
```
helm upgrade clair ./clair-helm -n clair
```
数据库密码会在升级过程中保留 —— chart 使用 `lookup` 读取现有的 Secret 并重复使用相同的密码,而不是生成新密码。
## 卸载说明
```
helm uninstall clair -n clair
```
PostgreSQL PVC 会根据 Kubernetes 的默认行为保留。手动删除它以释放存储空间:
```
kubectl delete pvc clair-postgresql -n clair
```
标签:Helm, Web截图, 子域名突变, 容器安全, 日志审计, 测试用例, 运维部署