Skip to content

Commit

Permalink
daemon, cmd: Add benchmark for notifyOnDNSMsg()
Browse files Browse the repository at this point in the history
This allows us to stress / benchmark the main callback function of the
DNS proxy within Cilium. This callback is called on each DNS request and
response made by each endpoint managed by Cilium.

For this commit, we are only considering the DNS response path because
it is the path which contains the most work to be done. This includes
policy calculation, identity allocation, and ipcache upsert.

It is useful to establish baseline performance numbers so that we can
compare against changes to this code path. In the following commits, a
mutex will be added to this path to fix a race condition during parallel
DNS response handling.

Baseline:

```
$ go test -v -tags integration_tests ./daemon/cmd -check.b -check.bmem -check.f DaemonFQDNSuite.Benchmark_notifyOnDNSMsg -test.benchtime 100x
...
PASS: fqdn_test.go:180: DaemonFQDNSuite.Benchmark_notifyOnDNSMsg           20000             96078 ns/op        36567 B/op         482 allocs/op
```

Signed-off-by: Chris Tarazi <chris@isovalent.com>
  • Loading branch information
christarazi authored and joestringer committed Dec 13, 2022
1 parent 24eaad7 commit 25fa14c
Showing 1 changed file with 104 additions and 0 deletions.
104 changes: 104 additions & 0 deletions daemon/cmd/fqdn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"sync"
"time"

miekgdns "github.com/miekg/dns"
. "gopkg.in/check.v1"
k8sCache "k8s.io/client-go/tools/cache"

Expand All @@ -23,14 +24,19 @@ import (
"github.com/cilium/cilium/pkg/endpoint"
"github.com/cilium/cilium/pkg/fqdn"
"github.com/cilium/cilium/pkg/fqdn/dns"
"github.com/cilium/cilium/pkg/fqdn/dnsproxy"
"github.com/cilium/cilium/pkg/fqdn/re"
"github.com/cilium/cilium/pkg/identity"
"github.com/cilium/cilium/pkg/identity/cache"
"github.com/cilium/cilium/pkg/ipcache"
"github.com/cilium/cilium/pkg/k8s/client/clientset/versioned"
"github.com/cilium/cilium/pkg/kvstore"
"github.com/cilium/cilium/pkg/labels"
"github.com/cilium/cilium/pkg/lock"
"github.com/cilium/cilium/pkg/policy"
"github.com/cilium/cilium/pkg/policy/api"
"github.com/cilium/cilium/pkg/proxy/accesslog"
"github.com/cilium/cilium/pkg/proxy/logger"
testidentity "github.com/cilium/cilium/pkg/testutils/identity"
)

Expand Down Expand Up @@ -121,7 +127,20 @@ func (ds *DaemonFQDNSuite) SetUpTest(c *C) {
})
d.endpointManager = WithCustomEndpointManager(&dummyEpSyncher{})
d.policy.GetSelectorCache().SetLocalIdentityNotifier(d.dnsNameManager)
d.ipcache = ipcache.NewIPCache(&ipcache.Configuration{
Context: context.TODO(),
IdentityAllocator: d.identityAllocator,
PolicyHandler: d.policy.GetSelectorCache(),
DatapathHandler: d.endpointManager,
})
ds.d = d

logger.SetEndpointInfoRegistry(&dummyInfoRegistry{})
}

type dummyInfoRegistry struct{}

func (*dummyInfoRegistry) FillEndpointInfo(info *accesslog.EndpointInfo, ip net.IP, id identity.NumericIdentity) {
}

// makeIPs generates count sequential IPv4 IPs
Expand Down Expand Up @@ -156,6 +175,91 @@ func (ds *DaemonSuite) BenchmarkFqdnCache(c *C) {
extractDNSLookups(endpoints, "0.0.0.0/0", "*", "")
}

// Benchmark_notifyOnDNSMsg stresses the main callback function for the DNS
// proxy path, which is called on every DNS request and response.
func (ds *DaemonFQDNSuite) Benchmark_notifyOnDNSMsg(c *C) {
var (
nameManager = ds.d.dnsNameManager
ciliumIOSel = api.FQDNSelector{MatchName: "cilium.io"}
ciliumIOSelMatchPattern = api.FQDNSelector{MatchPattern: "*cilium.io."}
ebpfIOSel = api.FQDNSelector{MatchName: "ebpf.io"}
ciliumDNSRecord = map[string]*fqdn.DNSIPRecords{
dns.FQDN("cilium.io"): {TTL: 60, IPs: []net.IP{net.ParseIP("192.0.2.3")}},
}
ebpfDNSRecord = map[string]*fqdn.DNSIPRecords{
dns.FQDN("ebpf.io"): {TTL: 60, IPs: []net.IP{net.ParseIP("192.0.2.4")}},
}

wg sync.WaitGroup
)

// Register rules (simulates applied policies).
selectorsToAdd := api.FQDNSelectorSlice{ciliumIOSel, ciliumIOSelMatchPattern, ebpfIOSel}
nameManager.Lock()
for _, sel := range selectorsToAdd {
nameManager.RegisterForIdentityUpdatesLocked(sel)
}
nameManager.Unlock()

// Initialize the endpoints.
endpoints := make([]*endpoint.Endpoint, c.N)
for i := range endpoints {
endpoints[i] = &endpoint.Endpoint{
ID: uint16(c.N % 65000),
IPv4: netip.MustParseAddr(fmt.Sprintf("10.96.%d.%d", (c.N>>16)%8, c.N%256)),
SecurityIdentity: &identity.Identity{
ID: identity.NumericIdentity(c.N % int(identity.MaximumAllocationIdentity)),
},
DNSZombies: &fqdn.DNSZombieMappings{
Mutex: lock.Mutex{},
},
}
ep := endpoints[i]
ep.UpdateLogger(nil)
ep.DNSHistory = fqdn.NewDNSCache(0)
}

c.ResetTimer()
// Simulate parallel DNS responses from the upstream DNS for cilium.io and
// ebpf.io, done by every endpoint.
for i := 0; i < c.N; i++ {
wg.Add(1)
go func(ep *endpoint.Endpoint) {
defer wg.Done()
// Using a hardcoded string representing endpoint IP:port as this
// parameter is only used in logging. Not using the endpoint's IP
// so we don't spend any time in the benchmark on converting from
// net.IP to string.
c.Assert(ds.d.notifyOnDNSMsg(time.Now(), ep, "10.96.64.8:12345", 0, "10.96.64.1:53", &miekgdns.Msg{
MsgHdr: miekgdns.MsgHdr{
Response: true,
},
Question: []miekgdns.Question{{
Name: dns.FQDN("cilium.io"),
}},
Answer: []miekgdns.RR{&miekgdns.A{
Hdr: miekgdns.RR_Header{Name: dns.FQDN("cilium.io")},
A: ciliumDNSRecord[dns.FQDN("cilium.io")].IPs[0],
}}}, "udp", true, &dnsproxy.ProxyRequestContext{}), IsNil)

c.Assert(ds.d.notifyOnDNSMsg(time.Now(), ep, "10.96.64.4:54321", 0, "10.96.64.1:53", &miekgdns.Msg{
MsgHdr: miekgdns.MsgHdr{
Response: true,
},
Compress: false,
Question: []miekgdns.Question{{
Name: dns.FQDN("ebpf.io"),
}},
Answer: []miekgdns.RR{&miekgdns.A{
Hdr: miekgdns.RR_Header{Name: dns.FQDN("ebpf.io")},
A: ebpfDNSRecord[dns.FQDN("ebpf.io")].IPs[0],
}}}, "udp", true, &dnsproxy.ProxyRequestContext{}), IsNil)
}(endpoints[i%len(endpoints)])
}

wg.Wait()
}

func (ds *DaemonFQDNSuite) TestFQDNIdentityReferenceCounting(c *C) {
var (
idAllocator = ds.d.identityAllocator.(*FakeRefcountingIdentityAllocator)
Expand Down

0 comments on commit 25fa14c

Please sign in to comment.