...

Source file src/github.com/chaos-mesh/chaos-mesh/api/v1alpha1/stresschaos_types.go

Documentation: github.com/chaos-mesh/chaos-mesh/api/v1alpha1

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package v1alpha1
    17  
    18  import (
    19  	"fmt"
    20  
    21  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    22  )
    23  
    24  // Stress chaos is a chaos to generate plenty of stresses over a collection of pods.
    25  
    26  // +kubebuilder:object:root=true
    27  // +kubebuilder:printcolumn:name="duration",type=string,JSONPath=`.spec.duration`
    28  // +chaos-mesh:experiment
    29  
    30  // StressChaos is the Schema for the stresschaos API
    31  type StressChaos struct {
    32  	metav1.TypeMeta   `json:",inline"`
    33  	metav1.ObjectMeta `json:"metadata,omitempty"`
    34  
    35  	// Spec defines the behavior of a time chaos experiment
    36  	Spec StressChaosSpec `json:"spec"`
    37  
    38  	// +optional
    39  	// Most recently observed status of the time chaos experiment
    40  	Status StressChaosStatus `json:"status,omitempty"`
    41  }
    42  
    43  var _ InnerObjectWithCustomStatus = (*StressChaos)(nil)
    44  var _ InnerObjectWithSelector = (*StressChaos)(nil)
    45  var _ InnerObject = (*StressChaos)(nil)
    46  
    47  // StressChaosSpec defines the desired state of StressChaos
    48  type StressChaosSpec struct {
    49  	ContainerSelector `json:",inline"`
    50  
    51  	// Stressors defines plenty of stressors supported to stress system components out.
    52  	// You can use one or more of them to make up various kinds of stresses. At least
    53  	// one of the stressors should be specified.
    54  	// +optional
    55  	Stressors *Stressors `json:"stressors,omitempty"`
    56  
    57  	// StressngStressors defines plenty of stressors just like `Stressors` except that it's an experimental
    58  	// feature and more powerful. You can define stressors in `stress-ng` (see also `man stress-ng`) dialect,
    59  	// however not all of the supported stressors are well tested. It maybe retired in later releases. You
    60  	// should always use `Stressors` to define the stressors and use this only when you want more stressors
    61  	// unsupported by `Stressors`. When both `StressngStressors` and `Stressors` are defined, `StressngStressors`
    62  	// wins.
    63  	// +optional
    64  	StressngStressors string `json:"stressngStressors,omitempty"`
    65  
    66  	// Duration represents the duration of the chaos action
    67  	// +optional
    68  	Duration *string `json:"duration,omitempty" webhook:"Duration"`
    69  
    70  	// RemoteCluster represents the remote cluster where the chaos will be deployed
    71  	// +optional
    72  	RemoteCluster string `json:"remoteCluster,omitempty"`
    73  }
    74  
    75  // StressChaosStatus defines the observed state of StressChaos
    76  type StressChaosStatus struct {
    77  	ChaosStatus `json:",inline"`
    78  	// Instances always specifies stressing instances
    79  	// +optional
    80  	Instances map[string]StressInstance `json:"instances,omitempty"`
    81  }
    82  
    83  // StressInstance is an instance generates stresses
    84  type StressInstance struct {
    85  	// UID is the stress-ng identifier
    86  	// +optional
    87  	UID string `json:"uid,omitempty"`
    88  	// MemoryUID is the memStress identifier
    89  	// +optional
    90  	MemoryUID string `json:"memoryUid,omitempty"`
    91  	// StartTime specifies when the stress-ng starts
    92  	// +optional
    93  	StartTime *metav1.Time `json:"startTime,omitempty"`
    94  	// MemoryStartTime specifies when the memStress starts
    95  	// +optional
    96  	MemoryStartTime *metav1.Time `json:"memoryStartTime,omitempty"`
    97  }
    98  
    99  // Stressors defines plenty of stressors supported to stress system components out.
   100  // You can use one or more of them to make up various kinds of stresses
   101  type Stressors struct {
   102  	// MemoryStressor stresses virtual memory out
   103  	// +optional
   104  	MemoryStressor *MemoryStressor `json:"memory,omitempty"`
   105  	// CPUStressor stresses CPU out
   106  	// +optional
   107  	CPUStressor *CPUStressor `json:"cpu,omitempty"`
   108  }
   109  
   110  // Normalize the stressors to comply with stress-ng
   111  func (in *Stressors) Normalize() (cpuStressors string, memoryStressors string, err error) {
   112  	cpuStressors = ""
   113  	memoryStressors = ""
   114  	err = nil
   115  
   116  	if in.MemoryStressor != nil && in.MemoryStressor.Workers != 0 {
   117  		memoryStressors += fmt.Sprintf(" --workers %d", in.MemoryStressor.Workers)
   118  
   119  		if len(in.MemoryStressor.Size) != 0 {
   120  			memoryStressors += fmt.Sprintf(" --size %s", in.MemoryStressor.Size)
   121  		}
   122  
   123  		if in.MemoryStressor.Options != nil {
   124  			for _, v := range in.MemoryStressor.Options {
   125  				memoryStressors += fmt.Sprintf(" %v ", v)
   126  			}
   127  		}
   128  	}
   129  	if in.CPUStressor != nil && in.CPUStressor.Workers != 0 {
   130  		// Without these two args, we may not reach the resource limit of pod,
   131  		// especially when we set cpu workers > 1
   132  		// More details see: https://github.com/chaos-mesh/chaos-mesh/issues/3100
   133  		cpuStressors += " --cpu-load-slice 10 --cpu-method sqrt"
   134  		cpuStressors += fmt.Sprintf(" --cpu %d", in.CPUStressor.Workers)
   135  
   136  		if in.CPUStressor.Load != nil {
   137  			cpuStressors += fmt.Sprintf(" --cpu-load %d",
   138  				*in.CPUStressor.Load)
   139  		}
   140  
   141  		if in.CPUStressor.Options != nil {
   142  			for _, v := range in.CPUStressor.Options {
   143  				cpuStressors += fmt.Sprintf(" %v ", v)
   144  			}
   145  		}
   146  	}
   147  
   148  	return
   149  }
   150  
   151  // Stressor defines common configurations of a stressor
   152  type Stressor struct {
   153  	// Workers specifies N workers to apply the stressor.
   154  	// Maximum 8192 workers can run by stress-ng
   155  	// +kubebuilder:validation:Maximum=8192
   156  	Workers int `json:"workers"`
   157  }
   158  
   159  // MemoryStressor defines how to stress memory out
   160  type MemoryStressor struct {
   161  	Stressor `json:",inline"`
   162  
   163  	// Size specifies N bytes consumed per vm worker, default is the total available memory.
   164  	// One can specify the size as % of total available memory or in units of B, KB/KiB,
   165  	// MB/MiB, GB/GiB, TB/TiB.
   166  	// +optional
   167  	Size string `json:"size,omitempty" webhook:"Bytes"`
   168  
   169  	// OOMScoreAdj sets the oom_score_adj of the stress process. See `man 5 proc` to know more
   170  	// about this option.
   171  	// +kubebuilder:validation:Minimum=-1000
   172  	// +kubebuilder:validation:Maximum=1000
   173  	// +kubebuilder:default=0
   174  	// +optional
   175  	OOMScoreAdj int `json:"oomScoreAdj,omitempty"`
   176  
   177  	// extend stress-ng options
   178  	// +optional
   179  	Options []string `json:"options,omitempty"`
   180  }
   181  
   182  // CPUStressor defines how to stress CPU out
   183  type CPUStressor struct {
   184  	Stressor `json:",inline"`
   185  	// Load specifies P percent loading per CPU worker. 0 is effectively a sleep (no load) and 100
   186  	// is full loading.
   187  	// +kubebuilder:validation:Minimum=0
   188  	// +kubebuilder:validation:Maximum=100
   189  	// +optional
   190  	Load *int `json:"load,omitempty"`
   191  
   192  	// extend stress-ng options
   193  	// +optional
   194  	Options []string `json:"options,omitempty"`
   195  }
   196  
   197  func (obj *StressChaos) GetSelectorSpecs() map[string]interface{} {
   198  	return map[string]interface{}{
   199  		".": &obj.Spec.ContainerSelector,
   200  	}
   201  }
   202  
   203  func (obj *StressChaos) GetCustomStatus() interface{} {
   204  	return &obj.Status.Instances
   205  }
   206