anchore/k8s-inventory
GitHub: anchore/k8s-inventory
anchore-k8s-inventory 是一个 Kubernetes 集群镜像清单采集工具,定期轮询集群 API 将当前运行中的容器和镜像信息上报给 Anchore Enterprise。
Stars: 70 | Forks: 15
# Anchore Kubernetes 清单
[](https://goreportcard.com/report/github.com/anchore/k8s-inventory)
[](https://github.com/anchore/k8s-inventory/releases/latest)
[](https://github.com/anchore/k8s-inventory/blob/main/LICENSE)
`anchore-k8s-inventory` 会定期轮询 Kubernetes API,以检索当前正在使用的镜像。
它可以在集群内部(在 Service Account 下)或集群外部(通过任何提供的 kubeconfig)运行。
## 快速开始
[安装二进制文件](#installation)或下载 [Docker 镜像](https://hub.docker.com/r/anchore/k8s-inventory/tags)
## 安装说明
`anchore-k8s-inventory` 可以作为 CLI、Docker 容器或 Helm Chart 运行
默认情况下,当作为 CLI 运行时,`anchore-k8s-inventory` 会在主目录中查找 kubeconfig 以进行身份验证。
### CLI
```
$ anchore-k8s-inventory --verbose-inventory-reports
{
"cluster_name": "docker-desktop",
"containers": [
{
"id": "docker://911d2cf6351cbafc349f131aeef1b1fb295a889504d38c89a065da1a91d828b9",
"image_digest": "sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c",
"image_tag": "docker.io/kubernetesui/metrics-scraper:v1.0.8",
"name": "dashboard-metrics-scraper",
"pod_uid": "c5b40099-20a5-4b46-8062-cf84f9d6ac23"
},
{
"id": "docker://a9cd75ad99dd4363bbd882b40e753b58c62bfd7b03cabeb764c1dac97568ad26",
"image_digest": "sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93",
"image_tag": "docker.io/kubernetesui/dashboard:v2.7.0",
"name": "kubernetes-dashboard",
"pod_uid": "72ba7e4e-6e35-48c0-bff7-558a525074d5"
},
.....
],
"namespaces": [
{
"labels": {
"kubernetes.io/metadata.name": "kube-public"
},
"name": "kube-public",
"uid": "dd561bf1-11ff-4381-8a1f-f156c206fe13"
},
{
"labels": {
"kubernetes.io/metadata.name": "kube-system"
},
"name": "kube-system",
"uid": "012ebe67-dd49-4fd9-b604-258385df3957"
},
.....
],
"nodes": [
{
"annotations": {
"kubeadm.alpha.kubernetes.io/cri-socket": "unix:///var/run/cri-dockerd.sock",
"node.alpha.kubernetes.io/ttl": "0",
"volumes.kubernetes.io/controller-managed-attach-detach": "true"
},
"arch": "arm64",
"container_runtime_version": "docker://20.10.23",
"kernel_version": "5.15.49-linuxkit",
"kube_proxy_version": "v1.26.1",
"kubelet_version": "v1.26.1",
"labels": {
"beta.kubernetes.io/arch": "arm64",
"beta.kubernetes.io/os": "linux",
"kubernetes.io/arch": "arm64",
"kubernetes.io/hostname": "minikube",
"kubernetes.io/os": "linux",
"minikube.k8s.io/commit": "ddac20b4b34a9c8c857fc602203b6ba2679794d3",
"minikube.k8s.io/name": "minikube",
"minikube.k8s.io/primary": "true",
"minikube.k8s.io/updated_at": "2023_04_11T11_20_54_0700",
"minikube.k8s.io/version": "v1.29.0",
"node-role.kubernetes.io/control-plane": "",
"node.kubernetes.io/exclude-from-external-load-balancers": ""
},
"name": "minikube",
"operating_system": "linux",
"uid": "b8334e25-68a5-4cbc-bf7a-fc188f2c6023"
}
],
"pods": [
{
"annotations": {
"seccomp.security.alpha.kubernetes.io/pod": "runtime/default"
},
"labels": {
"k8s-app": "dashboard-metrics-scraper",
"pod-template-hash": "5c6664855"
},
"name": "dashboard-metrics-scraper-5c6664855-s8lpc",
"namespace_uid": "c1d98ff5-6689-4016-aef3-8802790c3b10",
"node_uid": "b8334e25-68a5-4cbc-bf7a-fc188f2c6023",
"uid": "c5b40099-20a5-4b46-8062-cf84f9d6ac23"
},
{
"labels": {
"gcp-auth-skip-secret": "true",
"k8s-app": "kubernetes-dashboard",
"pod-template-hash": "55c4cbbc7c"
},
"name": "kubernetes-dashboard-55c4cbbc7c-6p28m",
"namespace_uid": "c1d98ff5-6689-4016-aef3-8802790c3b10",
"node_uid": "b8334e25-68a5-4cbc-bf7a-fc188f2c6023",
"uid": "72ba7e4e-6e35-48c0-bff7-558a525074d5"
},
.....
],
"serverVersionMetadata": {
"major": "1",
"minor": "26",
"gitVersion": "v1.26.1",
"gitCommit": "8f94681cd294aa8cfd3407b8191f6c70214973a4",
"gitTreeState": "clean",
"buildDate": "2023-01-18T15:51:25Z",
"goVersion": "go1.19.5",
"compiler": "gc",
"platform": "linux/arm64"
},
"timestamp": "2023-05-03T12:34:13Z"
}
```
### 容器
为了将 `anchore-k8s-inventory` 作为容器运行,它需要一个 kubeconfig
```
~ docker run -it --rm -v ~/.kube/config:/.kube/config anchore/k8s-inventory:latest --verbose-inventory-reports
```
### Helm Chart
Anchore-k8s-inventory 是 Anchore Enterprise 的 Runtime Inventory 功能的基础。通过 Helm 运行 anchore-k8s-inventory 是检索 Kubernetes 镜像清单的绝佳方式,无需向 Anchore 提供 Cluster 凭据。
Anchore-k8s-inventory 在其部署的集群中作为只读 Service Account 运行。
为了将清单报告给 Anchore,anchore-k8s-inventory 确实需要 Anchore Enterprise 部署的身份验证材料。
anchore-k8s-inventory 的 helm chart 会根据您使用的 values 文件自动为 Anchore 密码创建一个 Kubernetes secret。例如:
```
anchore-k8s-inventory:
anchore:
password: foobar
```
它会基于此设置以下环境变量:`ANCHORE_K8S_INVENTORY_ANCHORE_PASSWORD=foobar`。
如果您不想在 values 文件中存储您的 Anchore 密码,您可以自己创建一个 secret 来实现:
```
apiVersion: v1
kind: Secret
metadata:
name: anchore-k8s-inventory-anchore-password
type: Opaque
stringData:
ANCHORE_K8S_INVENTORY_ANCHORE_PASSWORD: foobar
```
然后通过 values 文件将其提供给 helm chart:
```
anchore-k8s-inventory:
existingSecret: anchore-k8s-inventory-anchore-password
```
anchore-k8s-inventory 的 helm chart 是 [charts.anchore.io](https://charts.anchore.io) 仓库的一部分。您可以通过以下方式安装它:
```
helm repo add anchore https://charts.anchore.io
helm install -f anchore/k8s-inventory
```
您始终可以[在此处](https://github.com/anchore/anchore-charts/tree/main/stable/k8s-inventory/values.yaml)找到基础的 values 文件
## 作为 Enterprise 集成的 anchore-k8s-inventory agent
在 Enterprise 的 `v5.11.0` 版本中,Enterprise 提供了让 k8s-inventory 注册并提供健康状态报告的功能。这使得 Enterprise 能够跟踪 agent 的状态,并将该信息暴露给管理员。
在 Enterprise 为此功能提供的 API 中,这些实体被称为 Integrations。因此,anchore-k8s-inventory agent 是一种类型的 Integration。
在 agent 开始发送健康状态报告之前,它需要向 Enterprise 进行注册。这是一个 agent 向 Enterprise 展示自身的握手过程。注册包含诸如集成类型、其名称、启动时间、运行时间、发送健康报告的频率等信息。其中一些属性是可选的,例如 'description' 属性。
当 agent 注册时,Enterprise 会为其分配一个 integration uuid。随后,该 uuid 将用于针对该特定集成实例的所有 API 操作。因此,当 agent 向 Enterprise 发送其健康报告时,它会向包含该 integration uuid 的 URL 发起 REST API 调用。
### 注册为集成
当 agent 向 Enterprise 注册时,注册信息将包含一个 `registration_id` 和一个 `registration_instance_id`。Enterprise 使用它们来查找该 agent 的 integration uuid。
如果是首次注册 agent,将不存在任何 integration `uuid`,因此 Enterprise 将创建一个,并在其数据库中存储该 integration uuid 与 `` 之间的关联。对于随后的重新注册(例如,如果 agent pod 被重启),此关联将允许 Enterprise 返回在早期注册中创建的 integration `uuid`。因此,只要 `` 对保持不变,Enterprise 就会将其视为相同的集成实例。之所以需要值对,是因为像 `anchore_k8s_inventory` agent 这样的集成可以被部署为多个副本(在 K8s Deployment 的情况下)。Enterprise 必须能够区分不同的 agent 副本实例。具有合理选定值的的值对使其成为可能。
可以通过配置来设置 `registration_id`(参见下面的配置部分)。
只有 agent 自身才能设置 `registration_instance_id` 值。它会将其设置为 agent 运行的 hostname(或者如果其为空,则生成一个 uuid 并使用该值)。
### 向后兼容性
## 配置
```
# 与 -q 相同;抑制所有输出(清单结果除外)
quiet: false
log:
# use structured logging
structured: false
# the log level; note: detailed logging suppress the ETUI
level: "debug"
# location to write the log file (default is not to have a log file)
file: "./anchore-k8s-inventory.log"
# 启用/禁用启动时检查应用更新
check-for-app-update: true
kubeconfig:
path:
cluster: docker-desktop
cluster-cert:
server: # ex. https://kubernetes.docker.internal:6443
user:
type: # valid: [private_key, token]
client-cert:
private-key:
token:
# 启用/禁用将清单报告打印到 stdout
verbose-inventory-reports: false
```
### 集成注册
配置将 agent 注册为 Integration 的值。
如果使用 Anchore helm charts 的 `k8s-inventory v0.5.0` 或更高版本,最好将 `registration_id` 留空。
如果在配置中显式设置,建议使用一些能够生成 uuid 的工具来确保唯一性。
```
anchore-registration:
# The id to register the agent as with Enterprise, so Enterprise can map the agent to its integration uuid.
# If left unspecified, the agent will attempt to set registration-id to the uid of the K8s Deployment for the agent.
# If that fails (e.g., if the agent is not deployed on K8s), the agent will generate a UUID to use as registration-id.
registration-id:
# The name that the agent should have. If left unspecified, the agent will attempt to set it to the name of the K8s
# Deployment for the agent. If that fails it will be empty.
integration-name:
# A short description for the agent
integration-description:
```
### Namespace 选择
配置 anchore-k8s-inventory 应该搜索哪些 namespace。
* `include` 部分
* 一个显式字符串列表,用于详细说明要从中捕获镜像数据的 namespace 列表。
* 如果留空为 `[]`,则将搜索所有 namespace
* 示例:
```
namespace-selectors:
include:
- default
- kube-system
- prod-app
```
* `exclude` 部分
* 用于排除 namespace 的显式字符串和/或正则表达式模式的列表。
* 如果字符串不符合标准 DNS 名称要求,则将其判定为正则表达式。
* 示例:
```
namespace-selectors:
exclude:
- default
- ^kube-*
- ^prod-*
```
```
# 要搜索或排除的 namespaces。
namespace-selectors:
# Namespaces to include as explicit strings, not regex
# NOTE: Will search ALL namespaces if left as an empty array
include: []
# List of namespaces to exclude, can use explicit strings and/or regexes.
# For example
#
# list:
# - default
# - ^kube-*
#
# Will exclude the default, kube-system, and kube-public namespaces
exclude: []
# If true then namespaces containing 0 pods will be omitted from the report sent to Anchore Enterprise
ignore-empty: false
```
### 账户路由
以下配置选项可以决定将清单报告发送到哪个 Anchore 账户。如果没有以下任何配置,则将使用 `anchore` 部分中设置的账户。
如果混合使用静态账户路由和按 namespace label 进行的账户路由,则 k8s-inventory 配置中配置的静态账户路由将优先于 namespace label 指定的任何账户。
#### 静态账户路由配置
设置账户列表以及应将哪些 namespace 的清单发送到该账户。您可以在每个账户的基础上覆盖默认凭据,如果未设置,则将使用 `anchore` 部分中设置的全局凭据。
```
account-routes:
# : # (this is the name of the anchore account e.g. admin)
# user:
# password:
# namespaces: # Can be a list of explicit namespaces matches or regex patterns
# -
# -
#
# Example
# admin:
# user: username
# password: password
# namespaces:
# - default
# - ^kube-*
```
#### 按 namespace label 进行账户路由
在此模式下,使用设置在 Kubernetes namespace 上的 label 来确定该 namespace 的清单数据应发送到哪个 Anchore 账户。假定在 `anchore` 部分中设置的凭据可以向所有账户发送数据。
```
# 通过 namespace 上的 label 将 namespaces 路由到 anchore accounts
account-route-by-namespace-label:
# The name of the namespace label that will be used to route the contents of
# that namespace to the Anchore account matching the value of the label
key: # e.g anchore.io/account.name
# The name of the account to route inventory to for a namespace that is
# missing the label or if the anchore account is not found.
# If not set then it will default to the account specified in the anchore credentials
default-account: # e.g. admin
# If true will exclude inventorying namespaces that are missing the specified label
ignore-namespace-missing-label: false
```
### Kubernetes API 参数
本部分将允许用户调整 anchore-k8s-inventory 与 Kubernetes API server 交互的方式。
```
# Kubernetes API 配置参数(通常无需调整)
kubernetes:
# Sets the request timeout for kubernetes API requests
request-timeout-seconds: 60
# Sets the number of objects to iteratively return when listing resources
request-batch-size: 100
# Worker pool size for collecting pods from namespaces. Adjust this if the api-server gets overwhelmed
worker-pool-size: 100
```
### anchore-k8s-inventory 的操作模式
```
# 可以是 adhoc 或 periodic 之一(默认为 adhoc)
mode: adhoc
# 仅在 mode 为 periodic 时生效
polling-interval-seconds: 300
```
### 缺失 Tag 策略
在某些情况下,Kubernetes 中的镜像没有关联的 tag - 例如当使用 digest 部署镜像时。
```
kubectl run python --image=python@sha256:f0a210a37565286ecaaac0529a6749917e8ea58d3dfc72c84acfbfbe1a64a20a
```
Anchore Enterprise 将使用镜像 digest 来处理镜像,但它仍然需要与镜像关联的 tag。`missing-tag-policy` 允许您配置在您的环境中处理缺少 tag 的边缘情况的最佳方式。
**digest** 将使用镜像 digest 作为虚拟 tag。
```
{
"tag": "alpine:4ed1812024ed78962a34727137627e8854a3b414d19e2c35a1dc727a47e16fba",
"repoDigest": "sha256:4ed1812024ed78962a34727137627e8854a3b414d19e2c35a1dc727a47e16fba"
}
```
**insert** 将使用由 `missing-tag-policy.tag` 配置的虚拟 tag
```
{
"tag": "alpine:UNKNOWN",
"repoDigest": "sha256:4ed1812024ed78962a34727137627e8854a3b414d19e2c35a1dc727a47e16fba"
}
```
**drop** 将直接忽略没有 tag 的镜像。
```
# 处理 tag 缺失的情况。例如 - 通过 digest 指定的 images
missing-tag-policy:
# One of the following options [digest, insert, drop]. Default is 'digest'
#
# [digest] will use the image's digest as a dummy tag.
#
# [insert] will insert a default tag in as a dummy tag. The dummy tag is
# customizable under missing-tag-policy.tag
#
# [drop] will drop images that do not have tags associated with them. Not
# recommended.
policy: digest
# Dummy tag to use. Only applicable if policy is 'insert'. Defaults to UNKNOWN
tag: UNKNOWN
```
### 忽略尚未处于 Running 状态的镜像
```
# 忽略未处于 Running 状态的 pods 中的 images
ignore-not-running: true
```
### 批量发送清单报告
为发送到 Anchore Enterprise 的单个清单报告 POST 设置包含内容的上限。如果清单数据大于限制,则清单报告将被分成小于等于指定限制大小的多个请求。
```
inventory-report-limits:
namespaces: 0 # default of 0 means no limit
```
### 元数据配置
每种资源类型仅包含部分 annotations/labels,或者完全禁用元数据
```
metadata-collection:
nodes:
annotations: [] # List of annotations to include (explicit or regex)
labels: [] # List of labels to include (explicit or regex)
disable: false # Remove all optional node metadata from the inventory report
namespaces:
annotations: [] # List of annotations to include (explicit or regex)
labels: [] # List of labels to include (explicit or regex)
disable: false # Remove all optional namespace metadata from the inventory report
pods:
annotations: [] # List of annotations to include (explicit or regex)
labels: [] # List of labels to include (explicit or regex)
disable: false # Remove all optional pod metadata from the inventory report
```
### Anchore API 配置
使用此部分配置 Anchore Enterprise API endpoint
```
anchore:
url:
user:
password: $ANCHORE_K8S_INVENTORY_ANCHORE_PASSWORD
account:
http:
insecure: true
timeout-seconds: 10
```
## 行为变更 (v1.7.0)
请注意,从 k8s-inventory >= v1.7.0 开始,/version/ endpoint 必须通过提供的 Anchore Enterprise URL 路由到 API 服务。/version/ endpoint 必须返回在以下 JSON payload 中找到的版本字段:
```
{
"api": {
"version": "2"
},
"db": {
"schema_version": "5260"
},
"service": {
"commit_sha": "c81dec015833e7705338ab082c8aa21c94ebfa9a",
"image_build_dt": "2026-03-31T13:21:56.051468Z",
"version": "5.26.0"
}
}
```
## 行为变更 (v0.5.0)(原名 KAI)
在低于 v0.5.0 版本的 anchore-k8s-inventory 中,默认行为是每次生成清单报告时将其输出到 stdout。anchore-k8s-inventory v0.5.0 更改了此行为,除非在配置文件中设置了 `verbose-inventory-reports: true` 或在调用 anchore-k8s-inventory 时使用了 `--verbose-inventory-reports` 标志,否则它不会打印到 stdout。
## 配置变更 (v0.2.2 -> v0.3.0)(原名 KAI)
从 v0.2.2 到 v0.3.0 有一些配置发生了变化
#### `kubernetes-request-timeout-seconds`
Kubernetes API 的请求超时时间已从
```
kubernetes-request-timeout-seconds: 60
```
更改为
```
kubernetes:
request-timeout-seconds: 60
```
anchore-k8s-inventory 仍然会沿用旧配置。在旧配置参数完全从配置中移除之前,它将优先使用旧配置参数。放弃旧配置而使用新配置是安全的。
#### `namespaces`
namespace 配置已从
```
namespaces:
- all
```
更改为
```
namespace-selectors:
include: []
exclude: []
```
添加 `namespace-selectors` 最终是为了取代 `namespaces`,以同时支持 include 和 exclude 配置。如果 `namespace-selectors.include` 为空,则将沿用旧的 `namespaces` 数组。完全放弃 `namespaces` 而使用 `namespace-selectors` 是安全的
## 开发
### 构建
**注意:** 这会将二进制文件放置在 `./snapshot/` 目录中
**在 Mac 上**
```
make mac-binary
```
**在 Linux 上**
```
make linux-binary
```
### 测试
Makefile 中内置了测试功能。要进行单元测试,只需运行
```
make unit
```
### Docker
要构建 Docker 镜像,您需要提供一个 kubeconfig。
注意:Docker 构建要求文件必须位于 Docker 构建上下文中
```
docker build -t localhost/anchore-k8s-inventory:latest --build-arg KUBECONFIG=./kubeconfig .
```
### Shell 自动补全
anchore-k8s-inventory 附带了用于指定 namespace 的 shell 自动补全功能,可以按如下方式启用。运行带有 `--help` 命令的程序以获取适合您所使用的 shell 的说明
```
anchore-k8s-inventory completion
```
### 使用 Skaffold
您可以使用 skaffold 进行开发。'bootstrap-skaffold' make 目标会将 chart 克隆到当前目录中,以便为 skaffold 配置它以供使用。要触发重新部署,您需要运行 `make linux-binary`,然后 skaffold 将重新构建镜像并更新 helm release。
```
make bootstrap-skaffold
make linux-binary
skaffold dev
```
## 发布
要创建 anchore-k8s-inventory 的发布,需要创建一个 tag,指向 `main` 中我们要发布的 commit。该 tag 应为以 `v` 为前缀的 semver,例如 `v0.2.7`。
这将触发 GitHub Action 来创建发布。
成功创建发布后,请确保在 Enterprise 和 [anchore-charts](https://github.com/anchore/anchore-charts) 中的 anchore-k8s-inventory Helm Chart 中指定更新的版本。
标签:EVTX分析, 子域名突变, 日志审计, 请求拦截