Skip to content

Commit 5e826dd

Browse files
author
xiejunqiao
committed
feat:add static domain ip map
Signed-off-by: xiejunqiao <[email protected]>
1 parent 0b3bd77 commit 5e826dd

File tree

7 files changed

+231
-63
lines changed

7 files changed

+231
-63
lines changed

chaos.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const (
2626
ActionError = "error"
2727
// ActionRandom means return random IP for DNS request
2828
ActionRandom = "random"
29+
// ActionChaos means return chaos IP for DNS request
30+
ActionStatic = "static"
2931
)
3032

3133
// PodInfo saves some information for pod
@@ -39,6 +41,12 @@ type PodInfo struct {
3941
LastUpdateTime time.Time
4042
}
4143

44+
// DomainIP Domain and ip mapping
45+
type DomainIP struct {
46+
Domain string
47+
IP string
48+
}
49+
4250
// IsOverdue ...
4351
func (p *PodInfo) IsOverdue() bool {
4452
// if the pod's IP is not updated greater than 10 seconds, will treate it as overdue
@@ -55,7 +63,13 @@ func (k Kubernetes) chaosDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
5563
return dns.RcodeServerFailure, fmt.Errorf("dns chaos error")
5664
}
5765

58-
// return random IP
66+
//return static IP
67+
if podInfo.Action == ActionStatic {
68+
//return staticIP(ctx, w, r, state, podInfo)
69+
//k.chaosMap
70+
domainAndIPMap := k.domainAndIPMap[podInfo.Namespace][podInfo.Name]
71+
return generateDNSRecords(state, domainAndIPMap, r, w)
72+
}
5973

6074
answers := []dns.RR{}
6175
qname := state.Name()
@@ -166,6 +180,9 @@ func (k Kubernetes) needChaos(podInfo *PodInfo, records []dns.RR, name string) b
166180
if podInfo.Scope == ScopeAll {
167181
return true
168182
}
183+
if podInfo.Action == ActionStatic && k.domainAndIPMap[podInfo.Namespace][podInfo.Name] != nil {
184+
return true
185+
}
169186

170187
rules := podInfo.Selector.Match(name, "")
171188
if len(rules) == 0 {
@@ -188,3 +205,34 @@ func (k Kubernetes) getPodFromCluster(namespace, name string) (*api.Pod, error)
188205
}
189206
return pods.Get(context.Background(), name, meta.GetOptions{})
190207
}
208+
209+
func generateDNSRecords(state request.Request, domainAndIpMap map[string]string, r *dns.Msg, w dns.ResponseWriter) (int, error) {
210+
answers := []dns.RR{}
211+
qname := state.Name()
212+
if domainAndIpMap == nil {
213+
return dns.RcodeServerFailure, nil
214+
}
215+
ip, ok := domainAndIpMap[qname]
216+
if !ok {
217+
//如果不存在则
218+
return dns.RcodeServerFailure, fmt.Errorf("domain %s not found", qname)
219+
}
220+
switch state.QType() {
221+
case dns.TypeA:
222+
ips := []net.IP{net.ParseIP(ip)}
223+
log.Debugf("dns.TypeA %v", ips)
224+
answers = a(qname, 10, ips)
225+
case dns.TypeAAAA:
226+
// TODO: return random IP
227+
ips := []net.IP{net.ParseIP(ip)}
228+
log.Debugf("dns.TypeAAAA %v", ips)
229+
answers = aaaa(qname, 10, ips)
230+
}
231+
m := new(dns.Msg)
232+
m.SetReply(r)
233+
m.Authoritative = true
234+
m.Answer = answers
235+
236+
w.WriteMsg(m)
237+
return dns.RcodeSuccess, nil
238+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ require (
99
github.com/miekg/dns v1.1.43
1010
github.com/pingcap/tidb-tools v6.3.0+incompatible
1111
github.com/prometheus/client_golang v1.11.0
12-
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
1312
google.golang.org/grpc v1.41.0
1413
k8s.io/api v0.22.2
1514
k8s.io/apimachinery v0.22.2
@@ -45,6 +44,7 @@ require (
4544
github.com/prometheus/common v0.31.1 // indirect
4645
github.com/prometheus/procfs v0.6.0 // indirect
4746
github.com/spf13/pflag v1.0.5 // indirect
47+
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
4848
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
4949
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect
5050
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect

grpc_server.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ func (k Kubernetes) SetDNSChaos(ctx context.Context, req *pb.SetDNSChaosRequest)
4444

4545
k.Lock()
4646
defer k.Unlock()
47-
4847
k.chaosMap[req.Name] = req
4948

5049
var scope string
@@ -70,6 +69,15 @@ func (k Kubernetes) SetDNSChaos(ctx context.Context, req *pb.SetDNSChaosRequest)
7069
}
7170
}
7271
}
72+
if req.Action == ActionStatic && req.IpDomainMaps != nil {
73+
for _, domainIPMap := range req.IpDomainMaps {
74+
err := selector.Insert(domainIPMap.Domain, "", true, trieselector.Insert)
75+
if err != nil {
76+
log.Errorf("fail to build selector %v", err)
77+
return nil, err
78+
}
79+
}
80+
}
7381

7482
for _, pod := range req.Pods {
7583
v1Pod, err := k.getPodFromCluster(pod.Namespace, pod.Name)
@@ -100,8 +108,15 @@ func (k Kubernetes) SetDNSChaos(ctx context.Context, req *pb.SetDNSChaosRequest)
100108

101109
k.podMap[pod.Namespace][pod.Name] = podInfo
102110
k.ipPodMap[v1Pod.Status.PodIP] = podInfo
103-
}
111+
domainIPMap := saveDomainAndIp(req.IpDomainMaps)
112+
if domainIPMap != nil {
113+
if _, ok := k.domainAndIPMap[pod.Namespace]; !ok {
114+
k.domainAndIPMap[pod.Namespace] = make(map[string]map[string]string)
115+
}
116+
k.domainAndIPMap[pod.Namespace][pod.Name] = domainIPMap
117+
}
104118

119+
}
105120
return &pb.DNSChaosResponse{
106121
Result: true,
107122
}, nil
@@ -125,6 +140,9 @@ func (k Kubernetes) CancelDNSChaos(ctx context.Context, req *pb.CancelDNSChaosRe
125140
delete(k.podMap[pod.Namespace], pod.Name)
126141
delete(k.ipPodMap, podInfo.IP)
127142
}
143+
if _, ok1 := k.domainAndIPMap[pod.Namespace][pod.Name]; ok1 {
144+
delete(k.domainAndIPMap[pod.Namespace], pod.Name)
145+
}
128146
}
129147
}
130148

@@ -136,6 +154,7 @@ func (k Kubernetes) CancelDNSChaos(ctx context.Context, req *pb.CancelDNSChaosRe
136154
}
137155
for _, namespace := range shouldDeleteNs {
138156
delete(k.podMap, namespace)
157+
delete(k.domainAndIPMap, namespace)
139158
}
140159

141160
delete(k.chaosMap, req.Name)
@@ -144,3 +163,16 @@ func (k Kubernetes) CancelDNSChaos(ctx context.Context, req *pb.CancelDNSChaosRe
144163
Result: true,
145164
}, nil
146165
}
166+
167+
// save domain and ip
168+
func saveDomainAndIp(domainMapList []*pb.IpDomainMap) map[string]string {
169+
if len(domainMapList) == 0 {
170+
return nil
171+
}
172+
domainIPMap := make(map[string]string)
173+
for _, domainMap := range domainMapList {
174+
key := fmt.Sprintf("%s.", domainMap.Domain)
175+
domainIPMap[key] = domainMap.Ip
176+
}
177+
return domainIPMap
178+
}

handler.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package kubernetes
22

33
import (
44
"context"
5-
65
"github.com/coredns/coredns/plugin"
76
"github.com/coredns/coredns/request"
87

@@ -22,10 +21,13 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
2221

2322
records, extra, zone, err := k.getRecords(ctx, state)
2423
log.Debugf("records: %v, err: %v", records, err)
25-
26-
if k.needChaos(chaosPod, records, state.QName()) {
24+
if k.needChaos(chaosPod, records, state.QName()) && chaosPod.Action != ActionStatic {
2725
return k.chaosDNS(ctx, w, r, state, chaosPod)
2826
}
27+
if k.needChaos(chaosPod, records, state.QName()) && chaosPod.Action == ActionStatic {
28+
log.Infof("need chaos, but action is static")
29+
return generateDNSRecords(state, k.domainAndIPMap[chaosPod.Namespace][chaosPod.Name], r, w)
30+
}
2931

3032
if k.IsNameError(err) {
3133
if len(zone) == 0 {

kubernetes.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import (
55
"context"
66
"errors"
77
"fmt"
8+
"github.com/chaos-mesh/k8s_dns_chaos/pb"
89
"math/rand"
910
"net"
1011
"strings"
1112
"sync"
1213
"time"
1314

14-
"github.com/chaos-mesh/k8s_dns_chaos/pb"
1515
"github.com/coredns/coredns/plugin"
1616
"github.com/coredns/coredns/plugin/etcd/msg"
1717
"github.com/coredns/coredns/plugin/kubernetes/object"
@@ -68,6 +68,8 @@ type Kubernetes struct {
6868
podMap map[string]map[string]*PodInfo
6969

7070
ipPodMap map[string]*PodInfo
71+
72+
domainAndIPMap map[string]map[string]map[string]string
7173
}
7274

7375
// New returns a initialized Kubernetes. It default interfaceAddrFunc to return 127.0.0.1. All other
@@ -81,6 +83,7 @@ func New(zones []string) *Kubernetes {
8183
k.chaosMap = make(map[string]*pb.SetDNSChaosRequest)
8284
k.podMap = make(map[string]map[string]*PodInfo)
8385
k.ipPodMap = make(map[string]*PodInfo)
86+
k.domainAndIPMap = make(map[string]map[string]map[string]string)
8487
rand.Seed(time.Now().UnixNano())
8588

8689
return k

0 commit comments

Comments
 (0)