添加新的混沌实验类型
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
本文档介绍如何添加新的混沌实验类型。
以下通过 HelloWorldChaos 示例演示添加新混沌实验类型的过程,该实验会在日志中打印 Hello world!。具体步骤包括:
步骤 1:定义 HelloWorldChaos 的 schema
-
在
api/v1alpha1API 目录下创建helloworldchaos_types.go文件,内容如下:package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +kubebuilder:object:root=true
// +chaos-mesh:experiment
// +chaos-mesh:oneshot=true
// HelloWorldChaos is the Schema for the helloworldchaos API
type HelloWorldChaos struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec HelloWorldChaosSpec `json:"spec"`
Status HelloWorldChaosStatus `json:"status,omitempty"`
}
// HelloWorldChaosSpec defines the desired state of HelloWorldChaos
type HelloWorldChaosSpec struct {
// ContainerSelector specifies the target for injection
ContainerSelector `json:",inline"`
// Duration represents the duration of the chaos
// +optional
Duration *string `json:"duration,omitempty"`
// RemoteCluster represents the remote cluster where the chaos will be deployed
// +optional
RemoteCluster string `json:"remoteCluster,omitempty"`
}
// HelloWorldChaosStatus defines the observed state of HelloWorldChaos
type HelloWorldChaosStatus struct {
ChaosStatus `json:",inline"`
}
// GetSelectorSpecs is a getter for selectors
func (obj *HelloWorldChaos) GetSelectorSpecs() map[string]interface{} {
return map[string]interface{}{
".": &obj.Spec.ContainerSelector,
}
}该文件定义了
HelloWorldChaos的 schema 类型,其可用 YAML 文件描述如下:apiVersion: chaos-mesh.org/v1alpha1
kind: HelloWorldChaos
metadata:
name: <resource name>
namespace: <namespace>
spec:
duration: <duration>
#...
步骤 2:注册 CRD
需要注册 HelloWorldChaos 的 CRD(Custom Resource Definition)才能与 Kubernetes API 交互。
-
将上一步生成的
config/crd/bases/chaos-mesh.org_helloworldchaos.yaml追加到config/crd/kustomization.yaml中,以合并到 manifests/crd.yaml:resources:
- bases/chaos-mesh.org_podchaos.yaml
- bases/chaos-mesh.org_networkchaos.yaml
- bases/chaos-mesh.org_iochaos.yaml
- bases/chaos-mesh.org_helloworldchaos.yaml # This is the new line -
在 Chaos Mesh 根目录运行
make generate,生成供 Chaos Mesh 编译的HelloWorldChaos样板文件:make generate随后可在
manifests/crd.yaml中查看HelloWorldChaos的定义。
步骤 3:为 helloworldchaos 对象注册事件处理程序
-
创建新文件
controllers/chaosimpl/helloworldchaos/types.go,内容如下:package helloworldchaos
import (
"context"
"github.com/go-logr/logr"
"go.uber.org/fx"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
impltypes "github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/types"
"github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/utils"
)
var _ impltypes.ChaosImpl = (*Impl)(nil)
type Impl struct {
client.Client
Log logr.Logger
decoder *utils.ContainerRecordDecoder
}
// This corresponds to the Apply phase of HelloWorldChaos. The execution of HelloWorldChaos will be triggered.
func (impl *Impl) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
impl.Log.Info("Hello world!")
return v1alpha1.Injected, nil
}
// This corresponds to the Recover phase of HelloWorldChaos. The reconciler will be triggered to recover the chaos action.
func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
impl.Log.Info("Goodbye world!")
return v1alpha1.NotInjected, nil
}
// NewImpl returns a new HelloWorldChaos implementation instance.
func NewImpl(c client.Client, log logr.Logger, decoder *utils.ContainerRecordDecoder) *impltypes.ChaosImplPair {
return &impltypes.ChaosImplPair{
Name: "helloworldchaos",
Object: &v1alpha1.HelloWorldChaos{},
Impl: &Impl{
Client: c,
Log: log.WithName("helloworldchaos"),
decoder: decoder,
},
ObjectList: &v1alpha1.HelloWorldChaosList{},
}
}
var Module = fx.Provide(
fx.Annotated{
Group: "impl",
Target: NewImpl,
},
) -
Chaos Mesh 使用 fx 库实现依赖注入。在控制器管理器注册
HelloWorldChaos时,需在controllers/chaosimpl/fx.go中添加:var AllImpl = fx.Options(
gcpchaos.Module,
stresschaos.Module,
jvmchaos.Module,
timechaos.Module,
helloworldchaos.Module // Add a new line. Make sure you have imported helloworldchaos first.
//...
)并在
controllers/types/types.go的ChaosObjects中添加:var ChaosObjects = fx.Supply(
//...
fx.Annotated{
Group: "objs",
Target: Object{
Name: "helloworldchaos",
Object: &v1alpha1.HelloWorldChaos{},
},
},
)
步骤 4:构建 Docker 镜像
-
构建生产环境镜像:
make image -
若使用 minikube 部署 Kubernetes 集群,需将镜像加载至集群:
minikube image load ghcr.io/chaos-mesh/chaos-dashboard:latest
minikube image load ghcr.io/chaos-mesh/chaos-mesh:latest
minikube image load ghcr.io/chaos-mesh/chaos-daemon:latest
步骤 5:运行 HelloWorldChaos
此步骤需部署包含最新修改的 Chaos Mesh 来测试 HelloWorldChaos 功能。
-
在集群中注册 CRD:
kubectl create -f manifests/crd.yaml从输出中可看到
HelloWorldChaos已创建:customresourcedefinition.apiextensions.k8s.io/helloworldchaos.chaos-mesh.org created现在可通过以下命令获取
HelloWorldChaos的 CRD:kubectl get crd helloworldchaos.chaos-mesh.org -
部署 Chaos Mesh:
helm install chaos-mesh helm/chaos-mesh -n=chaos-mesh --set controllerManager.leaderElection.enabled=false,dashboard.securityMode=false验证部署是否成功,可检查
chaos-mesh命名空间中的所有 Pod:kubectl get pods --namespace chaos-mesh -l app.kubernetes.io/instance=chaos-mesh -
部署测试用 Deployment,这里使用 minikube 文档中的示例 echo 服务:
kubectl create deployment hello-minikube --image=kicbase/echo-server:1.0等待 Pod 进入运行状态:
kubectl get pods示例输出:
NAME READY STATUS RESTARTS AGE
hello-minikube-77b6f68484-dg4sw 1/1 Running 0 2m -
创建包含以下内容的
hello.yaml文件:apiVersion: chaos-mesh.org/v1alpha1
kind: HelloWorldChaos
metadata:
name: hello-world
namespace: chaos-mesh
spec:
selector:
labelSelectors:
app: hello-minikube
mode: one
duration: 1h -
运行命令:
kubectl apply -f hello.yaml
# helloworldchaos.chaos-mesh.org/hello-world created现在可检查
chaos-controller-manager日志中是否包含Hello world!:kubectl logs -n chaos-mesh chaos-controller-manager-xxx示例输出:
2023-07-16T06:19:40.068Z INFO records records/controller.go:149 apply chaos {"id": "default/hello-minikube-77b6f68484-dg4sw/echo-server"}
2023-07-16T06:19:40.068Z INFO helloworldchaos helloworldchaos/types.go:26 Hello world!
后续步骤
如果您在操作过程中遇到任何问题,请在 Chaos Mesh 仓库提交 issue。
下一节我们将深入探讨如何扩展 HelloWorldChaos 的行为。