4. 压测环境搭建:在 K8s 集群中部署压测工具(以 k6 Operator 为例)
在 Kubernetes 资源限制场景下,压测工具本身也必须以云原生的方式运行,才能与被压测服务处于同一网络平面、共享节点资源视图,并避免宿主机环境差异带来的干扰。k6 Operator 是 Grafana 官方维护的 Kubernetes 原生压测方案,它通过自定义资源(CRD)将压测脚本、执行参数、并行副本声明式地提交给集群,天然适配 RBAC 与 ServiceAccount 体系。本节将完整演示从 Operator 安装到 RBAC 配置的全流程。
4.1 部署架构概览
k6 Operator 在集群中的工作分为三个层次:Operator 控制器监听 CRD 事件,k6 Runner Pod 执行实际压测,ServiceAccount + RBAC 控制 Operator 对集群资源的访问权限。下图展示了核心组件及其交互关系。
4.2 安装 k6 Operator
推荐使用 Helm Chart 进行安装,版本锁定与升级管理更可控。以下步骤基于 k6 Operator v0.0.17 版本。
4.2.1 添加 Helm 仓库并安装
# 添加 Grafana 官方 Helm 仓库
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
# 创建命名空间
kubectl create namespace k6-operator-system
# 安装 k6 Operator
helm install k6-operator grafana/k6-operator \
--namespace k6-operator-system \
--version 0.0.17 \
--set operator.resources.requests.cpu=100m \
--set operator.resources.requests.memory=128Mi \
--set operator.resources.limits.cpu=500m \
--set operator.resources.limits.memory=256Mi
4.2.2 验证安装状态
# 检查 Operator Pod 运行状态
kubectl get pods -n k6-operator-system -l app.kubernetes.io/name=k6-operator
# 预期输出示例:
# NAME READY STATUS RESTARTS AGE
# k6-operator-controller-manager-xxx 1/1 Running 0 2m
# 检查 CRD 是否注册
kubectl get crd | grep k6
# 预期输出:
# k6s.k6.io 2025-01-15T10:00:00Z
# k6runners.k6.io 2025-01-15T10:00:00Z
4.3 配置 RBAC 与 ServiceAccount
k6 Operator 默认会创建专用的 ServiceAccount 和 ClusterRole,但在生产环境中,建议按最小权限原则显式声明绑定关系。以下配置适用于 Operator 需要跨命名空间管理 K6 资源的场景。
4.3.1 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: k6-operator-sa
namespace: k6-operator-system
4.3.2 定义 ClusterRole
Operator 需要以下权限:对 K6 CRD 的 get/list/watch/create/update/patch/delete,以及对 Pod、ConfigMap、Service 的 get/list/watch(用于管理 Runner Pod 生命周期)。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: k6-operator-role
rules:
# K6 CRD 资源
- apiGroups: ["k6.io"]
resources: ["k6s", "k6runners"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# 核心资源(Runner Pod 管理)
- apiGroups: [""]
resources: ["pods", "configmaps", "services", "events"]
verbs: ["get", "list", "watch"]
# 部署与副本集(可选,用于高级编排)
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
4.3.3 绑定 ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k6-operator-bind
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: k6-operator-role
subjects:
- kind: ServiceAccount
name: k6-operator-sa
namespace: k6-operator-system
default)。如果压测目标需要身份认证,应在 Runner Pod 的 spec.serviceAccountName 字段指定。
4.4 配置 Helm Values 注入 RBAC
如果使用 Helm 安装,可以在 values 文件中直接指定 ServiceAccount 和 RBAC 参数,避免手动创建 YAML 文件。
| 参数路径 | 类型 | 默认值 | 说明 |
|---|---|---|---|
serviceAccount.create |
bool | true | 是否自动创建 ServiceAccount |
serviceAccount.name |
string | k6-operator | 自定义 ServiceAccount 名称 |
rbac.create |
bool | true | 是否自动创建 ClusterRole 与 ClusterRoleBinding |
rbac.rules |
list | 内置默认规则 | 自定义 RBAC 规则列表,覆盖默认值 |
# values-override.yaml
serviceAccount:
create: true
name: k6-operator-sa
rbac:
create: true
rules:
- apiGroups: ["k6.io"]
resources: ["k6s", "k6runners"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods", "configmaps", "events"]
verbs: ["get", "list", "watch"]
# 使用自定义 values 重新安装
helm upgrade --install k6-operator grafana/k6-operator \
--namespace k6-operator-system \
-f values-override.yaml
4.5 验证 RBAC 配置有效性
使用 kubectl auth can-i 命令验证 Operator 的 ServiceAccount 是否具备预期权限。
# 验证对 K6 CRD 的创建权限
kubectl auth can-i create k6s.k6.io \
--as=system:serviceaccount:k6-operator-system:k6-operator-sa
# 验证对 Pod 的读取权限
kubectl auth can-i list pods \
--as=system:serviceaccount:k6-operator-system:k6-operator-sa
# 验证对 Deployment 的读取权限(如果配置了)
kubectl auth can-i list deployments.apps \
--as=system:serviceaccount:k6-operator-system:k6-operator-sa
auth can-i 返回 no,请检查 ClusterRoleBinding 的 subjects.namespace 是否与 ServiceAccount 所在命名空间一致。跨命名空间绑定时,subjects.namespace 必须显式指定,不能为空。
4.6 提交第一个压测任务(端到端验证)
完成 RBAC 配置后,提交一个最小化的 K6 CRD 实例,验证整个链路是否通畅。
apiVersion: k6.io/v1alpha1
kind: K6
metadata:
name: hello-k6
namespace: default
spec:
parallelism: 2
script:
configMap:
name: k6-script-cm
file: script.js
runner:
serviceAccountName: default
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
# 创建 ConfigMap 存放压测脚本
kubectl create configmap k6-script-cm \
--from-literal=script.js='
import http from "k6/http";
import { sleep } from "k6";
export default function () {
http.get("http://test-service:8080/health");
sleep(1);
}
'
# 提交 K6 资源
kubectl apply -f hello-k6.yaml
# 观察 Runner Pod 启动
kubectl get pods -l app.kubernetes.io/instance=hello-k6
# 查看压测日志
kubectl logs -l app.kubernetes.io/instance=hello-k6 --tail=20
4.7 环境验证清单
完成部署后,建议逐项检查以下关键点,确保压测环境就绪。
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| Operator Pod 运行 | kubectl get pods -n k6-operator-system |
1/1 Running |
| CRD 注册 | kubectl get crd | grep k6 |
k6s.k6.io / k6runners.k6.io |
| ServiceAccount 存在 | kubectl get sa -n k6-operator-system |
k6-operator-sa 列出 |
| RBAC 权限 | kubectl auth can-i create k6s --as=... |
yes |
| Runner Pod 创建 | kubectl apply -f hello-k6.yaml |
Pod 进入 Running 状态 |
| 压测日志输出 | kubectl logs <runner-pod> |
显示 k6 执行指标 |
post-install 测试阶段,确保每次集群更新或 Operator 升级后压测环境依然可用。同时建议为压测任务单独创建命名空间(如 loadtest),并通过 ResourceQuota 限制 Runner Pod 的资源消耗上限,避免压测任务影响集群中其他业务。