Skip to content

Commit 0583635

Browse files
authored
Merge pull request kubernetes#86117 from wojtek-t/node_authorizer_microbenchmark
Extend authorization benchmark
2 parents 442107b + 1657ef2 commit 0583635

File tree

1 file changed

+102
-70
lines changed

1 file changed

+102
-70
lines changed

plugin/pkg/auth/authorizer/node/node_authorizer_test.go

Lines changed: 102 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package node
1919
import (
2020
"context"
2121
"fmt"
22+
"math/rand"
2223
"runtime"
2324
"runtime/pprof"
2425
"sync/atomic"
@@ -65,7 +66,7 @@ func init() {
6566
func TestAuthorizer(t *testing.T) {
6667
g := NewGraph()
6768

68-
opts := sampleDataOpts{
69+
opts := &sampleDataOpts{
6970
nodes: 2,
7071
namespaces: 2,
7172
podsPerNode: 2,
@@ -521,14 +522,25 @@ func TestAuthorizerSharedResources(t *testing.T) {
521522
}
522523

523524
type sampleDataOpts struct {
524-
nodes int
525-
526-
namespaces int
527-
525+
nodes int
526+
namespaces int
528527
podsPerNode int
529528

530529
attachmentsPerNode int
531530

531+
// sharedConfigMapsPerNamespaces defines number of shared configmaps in a given
532+
// namespace. Each pod then mounts a random set of size `sharedConfigMapsPerPod`
533+
// from that set. sharedConfigMapsPerPod is used if greater.
534+
sharedConfigMapsPerNamespace int
535+
// sharedSecretsPerNamespaces defines number of shared secrets in a given
536+
// namespace. Each pod then mounts a random set of size `sharedSecretsPerPod`
537+
// from that set. sharedSecretsPerPod is used if greater.
538+
sharedSecretsPerNamespace int
539+
// sharedPVCsPerNamespaces defines number of shared pvcs in a given
540+
// namespace. Each pod then mounts a random set of size `sharedPVCsPerPod`
541+
// from that set. sharedPVCsPerPod is used if greater.
542+
sharedPVCsPerNamespace int
543+
532544
sharedConfigMapsPerPod int
533545
sharedSecretsPerPod int
534546
sharedPVCsPerPod int
@@ -539,7 +551,7 @@ type sampleDataOpts struct {
539551
}
540552

541553
func BenchmarkPopulationAllocation(b *testing.B) {
542-
opts := sampleDataOpts{
554+
opts := &sampleDataOpts{
543555
nodes: 500,
544556
namespaces: 200,
545557
podsPerNode: 200,
@@ -570,7 +582,7 @@ func BenchmarkPopulationRetention(b *testing.B) {
570582
// go tool pprof --inuse_space node.test plugin/pkg/auth/authorizer/node/BenchmarkPopulationRetention.profile
571583
// list populate
572584

573-
opts := sampleDataOpts{
585+
opts := &sampleDataOpts{
574586
nodes: 500,
575587
namespaces: 200,
576588
podsPerNode: 200,
@@ -608,7 +620,7 @@ func BenchmarkWriteIndexMaintenance(b *testing.B) {
608620
// Run with:
609621
// go test ./plugin/pkg/auth/authorizer/node -benchmem -bench BenchmarkWriteIndexMaintenance -run None
610622

611-
opts := sampleDataOpts{
623+
opts := &sampleDataOpts{
612624
// simulate high replication in a small number of namespaces:
613625
nodes: 5000,
614626
namespaces: 1,
@@ -639,7 +651,7 @@ func BenchmarkWriteIndexMaintenance(b *testing.B) {
639651
func BenchmarkAuthorization(b *testing.B) {
640652
g := NewGraph()
641653

642-
opts := sampleDataOpts{
654+
opts := &sampleDataOpts{
643655
// To simulate high replication in a small number of namespaces:
644656
// nodes: 5000,
645657
// namespaces: 10,
@@ -732,6 +744,8 @@ func BenchmarkAuthorization(b *testing.B) {
732744
},
733745
}
734746

747+
podToAdd, _ := generatePod("testwrite", "ns0", "node0", "default", opts)
748+
735749
b.ResetTimer()
736750
for _, testWriteContention := range []bool{false, true} {
737751

@@ -755,16 +769,7 @@ func BenchmarkAuthorization(b *testing.B) {
755769
for shouldWrite == 1 {
756770
go func() {
757771
start := time.Now()
758-
authz.graph.AddPod(&corev1.Pod{
759-
ObjectMeta: metav1.ObjectMeta{Name: "testwrite", Namespace: "ns0"},
760-
Spec: corev1.PodSpec{
761-
NodeName: "node0",
762-
ServiceAccountName: "default",
763-
Volumes: []corev1.Volume{
764-
{Name: "token", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret0-shared"}}},
765-
},
766-
},
767-
})
772+
authz.graph.AddPod(podToAdd)
768773
diff := time.Since(start)
769774
atomic.AddInt64(&writes, 1)
770775
switch {
@@ -840,71 +845,35 @@ func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*cor
840845
}
841846
}
842847

848+
func randomSubset(a, b int) []int {
849+
if b < a {
850+
b = a
851+
}
852+
return rand.Perm(b)[:a]
853+
}
854+
843855
// generate creates sample pods and persistent volumes based on the provided options.
844856
// the secret/configmap/pvc/node references in the pod and pv objects are named to indicate the connections between the objects.
845857
// for example, secret0-pod0-node0 is a secret referenced by pod0 which is bound to node0.
846858
// when populated into the graph, the node authorizer should allow node0 to access that secret, but not node1.
847-
func generate(opts sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1.VolumeAttachment) {
859+
func generate(opts *sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1.VolumeAttachment) {
848860
nodes := make([]*corev1.Node, 0, opts.nodes)
849861
pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode)
850862
pvs := make([]*corev1.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
851863
attachments := make([]*storagev1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode)
852864

865+
rand.Seed(12345)
866+
853867
for n := 0; n < opts.nodes; n++ {
854868
nodeName := fmt.Sprintf("node%d", n)
855869
for p := 0; p < opts.podsPerNode; p++ {
856-
pod := &corev1.Pod{}
857-
pod.Namespace = fmt.Sprintf("ns%d", p%opts.namespaces)
858-
pod.Name = fmt.Sprintf("pod%d-%s", p, nodeName)
859-
pod.Spec.NodeName = nodeName
860-
pod.Spec.ServiceAccountName = fmt.Sprintf("svcacct%d-%s", p, nodeName)
861-
862-
for i := 0; i < opts.uniqueSecretsPerPod; i++ {
863-
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
864-
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-%s", i, pod.Name)},
865-
}})
866-
}
867-
for i := 0; i < opts.sharedSecretsPerPod; i++ {
868-
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
869-
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-shared", i)},
870-
}})
871-
}
872-
873-
for i := 0; i < opts.uniqueConfigMapsPerPod; i++ {
874-
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
875-
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-%s", i, pod.Name)}},
876-
}})
877-
}
878-
for i := 0; i < opts.sharedConfigMapsPerPod; i++ {
879-
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
880-
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-shared", i)}},
881-
}})
882-
}
883-
884-
for i := 0; i < opts.uniquePVCsPerPod; i++ {
885-
pv := &corev1.PersistentVolume{}
886-
pv.Name = fmt.Sprintf("pv%d-%s-%s", i, pod.Name, pod.Namespace)
887-
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
888-
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
889-
pvs = append(pvs, pv)
890-
891-
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
892-
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
893-
}})
894-
}
895-
for i := 0; i < opts.sharedPVCsPerPod; i++ {
896-
pv := &corev1.PersistentVolume{}
897-
pv.Name = fmt.Sprintf("pv%d-shared-%s", i, pod.Namespace)
898-
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
899-
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
900-
pvs = append(pvs, pv)
901-
902-
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
903-
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
904-
}})
905-
}
870+
name := fmt.Sprintf("pod%d-%s", p, nodeName)
871+
namespace := fmt.Sprintf("ns%d", p%opts.namespaces)
872+
svcAccountName := fmt.Sprintf("svcacct%d-%s", p, nodeName)
906873

874+
pod, podPVs := generatePod(name, namespace, nodeName, svcAccountName, opts)
907875
pods = append(pods, pod)
876+
pvs = append(pvs, podPVs...)
908877
}
909878
for a := 0; a < opts.attachmentsPerNode; a++ {
910879
attachment := &storagev1.VolumeAttachment{}
@@ -930,3 +899,66 @@ func generate(opts sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.Per
930899
}
931900
return nodes, pods, pvs, attachments
932901
}
902+
903+
func generatePod(name, namespace, nodeName, svcAccountName string, opts *sampleDataOpts) (*corev1.Pod, []*corev1.PersistentVolume) {
904+
pvs := make([]*corev1.PersistentVolume, 0, opts.uniquePVCsPerPod+opts.sharedPVCsPerPod)
905+
906+
pod := &corev1.Pod{}
907+
pod.Name = name
908+
pod.Namespace = namespace
909+
pod.Spec.NodeName = nodeName
910+
pod.Spec.ServiceAccountName = svcAccountName
911+
912+
for i := 0; i < opts.uniqueSecretsPerPod; i++ {
913+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
914+
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-%s", i, pod.Name)},
915+
}})
916+
}
917+
// Choose shared secrets randomly from shared secrets in a namespace.
918+
subset := randomSubset(opts.sharedSecretsPerPod, opts.sharedSecretsPerNamespace)
919+
for _, i := range subset {
920+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
921+
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-shared", i)},
922+
}})
923+
}
924+
925+
for i := 0; i < opts.uniqueConfigMapsPerPod; i++ {
926+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
927+
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-%s", i, pod.Name)}},
928+
}})
929+
}
930+
// Choose shared configmaps randomly from shared configmaps in a namespace.
931+
subset = randomSubset(opts.sharedConfigMapsPerPod, opts.sharedConfigMapsPerNamespace)
932+
for _, i := range subset {
933+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
934+
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-shared", i)}},
935+
}})
936+
}
937+
938+
for i := 0; i < opts.uniquePVCsPerPod; i++ {
939+
pv := &corev1.PersistentVolume{}
940+
pv.Name = fmt.Sprintf("pv%d-%s-%s", i, pod.Name, pod.Namespace)
941+
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
942+
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
943+
pvs = append(pvs, pv)
944+
945+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
946+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
947+
}})
948+
}
949+
// Choose shared pvcs randomly from shared pvcs in a namespace.
950+
subset = randomSubset(opts.sharedPVCsPerPod, opts.sharedPVCsPerNamespace)
951+
for _, i := range subset {
952+
pv := &corev1.PersistentVolume{}
953+
pv.Name = fmt.Sprintf("pv%d-shared-%s", i, pod.Namespace)
954+
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
955+
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
956+
pvs = append(pvs, pv)
957+
958+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
959+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
960+
}})
961+
}
962+
963+
return pod, pvs
964+
}

0 commit comments

Comments
 (0)