mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #52106 from tallclair/aa-e2e
Automatic merge from submit-queue (batch tested with PRs 50289, 52106) Fix AppArmor test at scale **What this PR does / why we need it**: The AppArmor test only runs on a single node, but previously was loading the necessary profiles to every node. This caused unnecessary churn in very large clusters, so this PR updates the test to only load the profiles to a single node, and ensure the test pod is run on that node (using pod affinity). **Which issue this PR fixes**: fixes #51791 **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
This commit is contained in:
commit
99b2ee1697
@ -50,7 +50,6 @@ go_library(
|
||||
"//vendor/golang.org/x/net/websocket:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
|
@ -20,16 +20,21 @@ import (
|
||||
"fmt"
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/security/apparmor"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
const (
|
||||
appArmorProfilePrefix = "e2e-apparmor-test-"
|
||||
appArmorAllowedPath = "/expect_allowed_write"
|
||||
appArmorDeniedPath = "/expect_permission_denied"
|
||||
|
||||
loaderLabelKey = "name"
|
||||
loaderLabelValue = "e2e-apparmor-loader"
|
||||
)
|
||||
|
||||
// AppArmorDistros are distros with AppArmor support
|
||||
@ -40,10 +45,8 @@ func SkipIfAppArmorNotSupported() {
|
||||
}
|
||||
|
||||
func LoadAppArmorProfiles(f *framework.Framework) {
|
||||
_, err := createAppArmorProfileCM(f)
|
||||
framework.ExpectNoError(err)
|
||||
_, err = createAppArmorProfileLoader(f)
|
||||
framework.ExpectNoError(err)
|
||||
createAppArmorProfileCM(f)
|
||||
createAppArmorProfileLoader(f)
|
||||
}
|
||||
|
||||
// CreateAppArmorTestPod creates a pod that tests apparmor profile enforcement. The pod exits with
|
||||
@ -71,6 +74,18 @@ sleep 1
|
||||
done`, testCmd)
|
||||
}
|
||||
|
||||
loaderAffinity := &api.Affinity{
|
||||
PodAffinity: &api.PodAffinity{
|
||||
RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{{
|
||||
Namespaces: []string{f.Namespace.Name},
|
||||
LabelSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{loaderLabelKey: loaderLabelValue},
|
||||
},
|
||||
TopologyKey: "kubernetes.io/hostname",
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "test-apparmor-",
|
||||
@ -82,6 +97,7 @@ done`, testCmd)
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Affinity: loaderAffinity,
|
||||
Containers: []api.Container{{
|
||||
Name: "test",
|
||||
Image: busyboxImage,
|
||||
@ -95,15 +111,22 @@ done`, testCmd)
|
||||
pod = f.PodClient().Create(pod)
|
||||
framework.ExpectNoError(framework.WaitForPodSuccessInNamespace(
|
||||
f.ClientSet, pod.Name, f.Namespace.Name))
|
||||
var err error
|
||||
pod, err = f.PodClient().Get(pod.Name, metav1.GetOptions{})
|
||||
framework.ExpectNoError(err)
|
||||
} else {
|
||||
pod = f.PodClient().CreateSync(pod)
|
||||
framework.ExpectNoError(f.WaitForPodReady(pod.Name))
|
||||
}
|
||||
|
||||
// Verify Pod affinity colocated the Pods.
|
||||
loader := getRunningLoaderPod(f)
|
||||
Expect(pod.Spec.NodeName).To(Equal(loader.Spec.NodeName))
|
||||
|
||||
return pod
|
||||
}
|
||||
|
||||
func createAppArmorProfileCM(f *framework.Framework) (*api.ConfigMap, error) {
|
||||
func createAppArmorProfileCM(f *framework.Framework) {
|
||||
profileName := appArmorProfilePrefix + f.Namespace.Name
|
||||
profile := fmt.Sprintf(`#include <tunables/global>
|
||||
profile %s flags=(attach_disconnected) {
|
||||
@ -125,21 +148,23 @@ profile %s flags=(attach_disconnected) {
|
||||
profileName: profile,
|
||||
},
|
||||
}
|
||||
return f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(cm)
|
||||
_, err := f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(cm)
|
||||
framework.ExpectNoError(err, "Failed to create apparmor-profiles ConfigMap")
|
||||
}
|
||||
|
||||
func createAppArmorProfileLoader(f *framework.Framework) (*extensions.DaemonSet, error) {
|
||||
func createAppArmorProfileLoader(f *framework.Framework) {
|
||||
True := true
|
||||
// Copied from https://github.com/kubernetes/contrib/blob/master/apparmor/loader/example-configmap.yaml
|
||||
loader := &extensions.DaemonSet{
|
||||
One := int32(1)
|
||||
loader := &api.ReplicationController{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "apparmor-loader",
|
||||
Namespace: f.Namespace.Name,
|
||||
},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: &One,
|
||||
Template: &api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{"name": "apparmor-loader"},
|
||||
Labels: map[string]string{loaderLabelKey: loaderLabelValue},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{{
|
||||
@ -191,5 +216,18 @@ func createAppArmorProfileLoader(f *framework.Framework) (*extensions.DaemonSet,
|
||||
},
|
||||
},
|
||||
}
|
||||
return f.ClientSet.Extensions().DaemonSets(f.Namespace.Name).Create(loader)
|
||||
_, err := f.ClientSet.Core().ReplicationControllers(f.Namespace.Name).Create(loader)
|
||||
framework.ExpectNoError(err, "Failed to create apparmor-loader ReplicationController")
|
||||
|
||||
// Wait for loader to be ready.
|
||||
getRunningLoaderPod(f)
|
||||
}
|
||||
|
||||
func getRunningLoaderPod(f *framework.Framework) *api.Pod {
|
||||
label := labels.SelectorFromSet(labels.Set(map[string]string{loaderLabelKey: loaderLabelValue}))
|
||||
pods, err := framework.WaitForPodsWithLabelScheduled(f.ClientSet, f.Namespace.Name, label)
|
||||
framework.ExpectNoError(err, "Failed to schedule apparmor-loader Pod")
|
||||
pod := &pods.Items[0]
|
||||
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(f.ClientSet, pod), "Failed to run apparmor-loader Pod")
|
||||
return pod
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user