/
pod_kill.go
94 lines (79 loc) · 2.67 KB
/
pod_kill.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package nemesis
import (
"context"
"log"
"math/rand"
"strings"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
chaosv1alpha1 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
"github.com/pingcap/tipocket/pkg/cluster"
"github.com/pingcap/tipocket/pkg/core"
)
// podKillGenerator generate code about PodKill chaos.
type podKillGenerator struct {
name string
}
func (g podKillGenerator) Generate(nodes []cluster.Node) []*core.NemesisOperation {
return podKillNodes(nodes, len(nodes), time.Second*time.Duration(rand.Intn(120)+60))
}
func (g podKillGenerator) Name() string {
return g.name
}
func podKillNodes(nodes []cluster.Node, n int, freq time.Duration) []*core.NemesisOperation {
ops := make([]*core.NemesisOperation, len(nodes))
// randomly shuffle the indices and get the first n nodes to be partitioned.
indices := shuffleIndices(len(nodes))
for i := 0; i < n; i++ {
ops[indices[i]] = &core.NemesisOperation{
Type: core.PodKill,
Node: &nodes[indices[i]],
InvokeArgs: nil,
RecoverArgs: nil,
// Note: PodKill is a instant action, Runtime means the duration of next time pod kill here.
RunTime: freq,
}
}
return ops
}
// NewPodKillGenerator creates a generator.
func NewPodKillGenerator(name string) core.NemesisGenerator {
return podKillGenerator{name: name}
}
// podKill implements Nemesis
type podKill struct {
k8sNemesisClient
}
func (k podKill) Invoke(ctx context.Context, node *cluster.Node, args ...interface{}) error {
log.Printf("apply nemesis %s on node %s(ns:%s)", core.PodKill, node.PodName, node.Namespace)
podChaos := buildPodKillChaos(node.Namespace, node.Namespace,
node.PodName)
return k.cli.ApplyPodChaos(ctx, &podChaos)
}
func (k podKill) Recover(ctx context.Context, node *cluster.Node, args ...interface{}) error {
log.Printf("unapply nemesis %s on node %s(ns:%s)", core.PodKill, node.PodName, node.Namespace)
podChaos := buildPodKillChaos(node.Namespace, node.Namespace, node.PodName)
return k.cli.CancelPodChaos(ctx, &podChaos)
}
func (podKill) Name() string {
return string(core.PodKill)
}
func buildPodKillChaos(ns string, chaosNs string, podName string) chaosv1alpha1.PodChaos {
chaos := chaosv1alpha1.PodKillAction
pods := make(map[string][]string)
pods[ns] = []string{podName}
return chaosv1alpha1.PodChaos{
ObjectMeta: metav1.ObjectMeta{
Name: strings.Join([]string{podName, string(chaos)}, "-"),
Namespace: chaosNs,
},
Spec: chaosv1alpha1.PodChaosSpec{
Selector: chaosv1alpha1.SelectorSpec{
Pods: pods,
},
Action: chaos,
Mode: chaosv1alpha1.OnePodMode,
Scheduler: &chaosv1alpha1.SchedulerSpec{Cron: "@every 1000000s"}, // let it be scheduled in our control
},
}
}