mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-08 11:38:15 +00:00
Merge pull request #122870 from wzshiming/kep-2681
Promote KEP-2681 to GA in 1.30
This commit is contained in:
commit
56a1b075cd
@ -1179,81 +1179,42 @@ func TestDropDisabledPodStatusFields(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
podStatus *api.PodStatus
|
||||
oldPodStatus *api.PodStatus
|
||||
wantPodStatus *api.PodStatus
|
||||
featureEnabled bool
|
||||
name string
|
||||
podStatus *api.PodStatus
|
||||
oldPodStatus *api.PodStatus
|
||||
wantPodStatus *api.PodStatus
|
||||
}{
|
||||
{
|
||||
name: "gate off, old=without, new=without",
|
||||
oldPodStatus: podWithoutHostIPs(),
|
||||
podStatus: podWithoutHostIPs(),
|
||||
featureEnabled: false,
|
||||
name: "old=without, new=without",
|
||||
oldPodStatus: podWithoutHostIPs(),
|
||||
podStatus: podWithoutHostIPs(),
|
||||
|
||||
wantPodStatus: podWithoutHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate off, old=without, new=with",
|
||||
oldPodStatus: podWithoutHostIPs(),
|
||||
podStatus: podWithHostIPs(),
|
||||
featureEnabled: false,
|
||||
|
||||
wantPodStatus: podWithoutHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate off, old=with, new=without",
|
||||
oldPodStatus: podWithHostIPs(),
|
||||
podStatus: podWithoutHostIPs(),
|
||||
featureEnabled: false,
|
||||
|
||||
wantPodStatus: podWithoutHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate off, old=with, new=with",
|
||||
oldPodStatus: podWithHostIPs(),
|
||||
podStatus: podWithHostIPs(),
|
||||
featureEnabled: false,
|
||||
name: "old=without, new=with",
|
||||
oldPodStatus: podWithoutHostIPs(),
|
||||
podStatus: podWithHostIPs(),
|
||||
|
||||
wantPodStatus: podWithHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate on, old=without, new=without",
|
||||
oldPodStatus: podWithoutHostIPs(),
|
||||
podStatus: podWithoutHostIPs(),
|
||||
featureEnabled: true,
|
||||
name: "old=with, new=without",
|
||||
oldPodStatus: podWithHostIPs(),
|
||||
podStatus: podWithoutHostIPs(),
|
||||
|
||||
wantPodStatus: podWithoutHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate on, old=without, new=with",
|
||||
oldPodStatus: podWithoutHostIPs(),
|
||||
podStatus: podWithHostIPs(),
|
||||
featureEnabled: true,
|
||||
|
||||
wantPodStatus: podWithHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate on, old=with, new=without",
|
||||
oldPodStatus: podWithHostIPs(),
|
||||
podStatus: podWithoutHostIPs(),
|
||||
featureEnabled: true,
|
||||
|
||||
wantPodStatus: podWithoutHostIPs(),
|
||||
},
|
||||
{
|
||||
name: "gate on, old=with, new=with",
|
||||
oldPodStatus: podWithHostIPs(),
|
||||
podStatus: podWithHostIPs(),
|
||||
featureEnabled: true,
|
||||
name: "old=with, new=with",
|
||||
oldPodStatus: podWithHostIPs(),
|
||||
podStatus: podWithHostIPs(),
|
||||
|
||||
wantPodStatus: podWithHostIPs(),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodHostIPs, tt.featureEnabled)()
|
||||
|
||||
dropDisabledPodStatusFields(tt.podStatus, tt.oldPodStatus, &api.PodSpec{}, &api.PodSpec{})
|
||||
|
||||
if !reflect.DeepEqual(tt.podStatus, tt.wantPodStatus) {
|
||||
|
@ -24590,18 +24590,6 @@ func TestValidateDownwardAPIHostIPs(t *testing.T) {
|
||||
featureEnabled: true,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIPs"},
|
||||
},
|
||||
{
|
||||
name: "has no hostIPs field, featuregate disabled",
|
||||
expectError: false,
|
||||
featureEnabled: false,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIP"},
|
||||
},
|
||||
{
|
||||
name: "has hostIPs field, featuregate disabled",
|
||||
expectError: true,
|
||||
featureEnabled: false,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIPs"},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
|
@ -596,6 +596,7 @@ const (
|
||||
// kep: http://kep.k8s.io/2681
|
||||
// alpha: v1.28
|
||||
// beta: v1.29
|
||||
// GA: v1.30
|
||||
//
|
||||
// Adds pod.status.hostIPs and downward API
|
||||
PodHostIPs featuregate.Feature = "PodHostIPs"
|
||||
@ -1088,7 +1089,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
|
||||
PodReadyToStartContainersCondition: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
PodHostIPs: {Default: true, PreRelease: featuregate.Beta},
|
||||
PodHostIPs: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
PodLifecycleSleepAction: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
|
@ -408,7 +408,6 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string // the name of the test case
|
||||
ns string // the namespace to generate environment for
|
||||
enablePodHostIPs bool // enable PodHostIPs feature gate
|
||||
enableServiceLinks *bool // enabling service links
|
||||
container *v1.Container // the container to use
|
||||
nilLister bool // whether the lister should be nil
|
||||
@ -643,7 +642,6 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "downward api pod",
|
||||
enablePodHostIPs: true,
|
||||
ns: "downward-api",
|
||||
enableServiceLinks: &falseValue,
|
||||
container: &v1.Container{
|
||||
@ -737,7 +735,6 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "downward api pod ips reverse order",
|
||||
enablePodHostIPs: true,
|
||||
ns: "downward-api",
|
||||
enableServiceLinks: &falseValue,
|
||||
container: &v1.Container{
|
||||
@ -791,7 +788,6 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "downward api pod ips multiple ips",
|
||||
enablePodHostIPs: true,
|
||||
ns: "downward-api",
|
||||
enableServiceLinks: &falseValue,
|
||||
container: &v1.Container{
|
||||
@ -1988,36 +1984,10 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "downward api pod without host ips",
|
||||
enablePodHostIPs: false,
|
||||
ns: "downward-api",
|
||||
enableServiceLinks: &falseValue,
|
||||
container: &v1.Container{
|
||||
Env: []v1.EnvVar{
|
||||
{
|
||||
Name: "HOST_IPS",
|
||||
ValueFrom: &v1.EnvVarSource{
|
||||
FieldRef: &v1.ObjectFieldSelector{
|
||||
APIVersion: "v1",
|
||||
FieldPath: "status.hostIPs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
podIPs: []string{"1.2.3.4", "fd00::6"},
|
||||
nilLister: true,
|
||||
expectedEnvs: []kubecontainer.EnvVar{
|
||||
{Name: "HOST_IPS", Value: ""},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodHostIPs, tc.enablePodHostIPs)()
|
||||
|
||||
fakeRecorder := record.NewFakeRecorder(1)
|
||||
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
|
||||
testKubelet.kubelet.recorder = fakeRecorder
|
||||
@ -3304,7 +3274,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
enablePodHostIPs bool // enable PodHostIPs feature gate
|
||||
pod *v1.Pod
|
||||
currentStatus *kubecontainer.PodStatus
|
||||
unreadyContainer []string
|
||||
@ -3349,6 +3318,7 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodFailed,
|
||||
HostIP: "127.0.0.1",
|
||||
HostIPs: []v1.HostIP{{IP: "127.0.0.1"}, {IP: "::1"}},
|
||||
QOSClass: v1.PodQOSBestEffort,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodInitialized, Status: v1.ConditionTrue},
|
||||
@ -3390,7 +3360,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3430,7 +3399,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3471,7 +3439,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3516,7 +3483,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
Reason: "Test",
|
||||
Message: "test",
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3570,7 +3536,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
Reason: "Test",
|
||||
Message: "test",
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3613,7 +3578,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
waitingState("containerB"),
|
||||
},
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3667,7 +3631,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
Reason: "Test",
|
||||
@ -3729,7 +3692,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
enablePodHostIPs: true,
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
HostIP: "127.0.0.1",
|
||||
@ -3756,7 +3718,6 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
for _, enablePodReadyToStartContainersCondition := range []bool{false, true} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodDisruptionConditions, test.enablePodDisruptionConditions)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodHostIPs, test.enablePodHostIPs)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodReadyToStartContainersCondition, enablePodReadyToStartContainersCondition)()
|
||||
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
|
||||
defer testKubelet.Cleanup()
|
||||
|
@ -112,7 +112,7 @@ var _ = common.SIGDescribe(feature.IPv6DualStack, func() {
|
||||
framework.ExpectNoError(err, "failed to delete pod")
|
||||
})
|
||||
|
||||
f.It("should create pod, add ipv6 and ipv4 ip to host ips", feature.PodHostIPs, func(ctx context.Context) {
|
||||
f.It("should create pod, add ipv6 and ipv4 ip to host ips", func(ctx context.Context) {
|
||||
podName := "pod-dualstack-ips"
|
||||
|
||||
pod := &v1.Pod{
|
||||
|
@ -31,7 +31,6 @@ import (
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
kubefeatures "k8s.io/kubernetes/pkg/features"
|
||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||
"k8s.io/kubernetes/test/e2e/feature"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
e2enetwork "k8s.io/kubernetes/test/e2e/framework/network"
|
||||
@ -49,55 +48,7 @@ var _ = common.SIGDescribe("DualStack Host IP", framework.WithSerial(), nodefeat
|
||||
f := framework.NewDefaultFramework("dualstack")
|
||||
f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
|
||||
|
||||
ginkgo.Context("when creating a Pod, it has no PodHostIPs feature", func() {
|
||||
tempSetCurrentKubeletConfig(f, func(ctx context.Context, initialConfig *kubeletconfig.KubeletConfiguration) {
|
||||
initialConfig.FeatureGates = map[string]bool{
|
||||
string(kubefeatures.PodHostIPs): false,
|
||||
}
|
||||
})
|
||||
ginkgo.It("should create pod, add host ips is empty", func(ctx context.Context) {
|
||||
|
||||
podName := "pod-dualstack-host-ips"
|
||||
|
||||
pod := genPodHostIPs(podName+string(uuid.NewUUID()), false)
|
||||
|
||||
ginkgo.By("submitting the pod to kubernetes")
|
||||
podClient := e2epod.NewPodClient(f)
|
||||
p := podClient.CreateSync(ctx, pod)
|
||||
|
||||
gomega.Expect(p.Status.HostIP).ShouldNot(gomega.BeEquivalentTo(""))
|
||||
gomega.Expect(p.Status.HostIPs).Should(gomega.BeNil())
|
||||
|
||||
ginkgo.By("deleting the pod")
|
||||
err := podClient.Delete(ctx, pod.Name, *metav1.NewDeleteOptions(1))
|
||||
framework.ExpectNoError(err, "failed to delete pod")
|
||||
})
|
||||
|
||||
ginkgo.It("should create pod with hostNetwork, add host ips is empty", func(ctx context.Context) {
|
||||
|
||||
podName := "pod-dualstack-host-ips"
|
||||
|
||||
pod := genPodHostIPs(podName+string(uuid.NewUUID()), true)
|
||||
|
||||
ginkgo.By("submitting the pod to kubernetes")
|
||||
podClient := e2epod.NewPodClient(f)
|
||||
p := podClient.CreateSync(ctx, pod)
|
||||
|
||||
gomega.Expect(p.Status.HostIP).ShouldNot(gomega.BeEquivalentTo(""))
|
||||
gomega.Expect(p.Status.HostIPs).Should(gomega.BeNil())
|
||||
|
||||
ginkgo.By("deleting the pod")
|
||||
err := podClient.Delete(ctx, pod.Name, *metav1.NewDeleteOptions(1))
|
||||
framework.ExpectNoError(err, "failed to delete pod")
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("when creating a Pod, it has PodHostIPs feature", func() {
|
||||
tempSetCurrentKubeletConfig(f, func(ctx context.Context, initialConfig *kubeletconfig.KubeletConfiguration) {
|
||||
initialConfig.FeatureGates = map[string]bool{
|
||||
string(kubefeatures.PodHostIPs): true,
|
||||
}
|
||||
})
|
||||
ginkgo.Context("when creating a Pod", func() {
|
||||
ginkgo.It("should create pod, add ipv6 and ipv4 ip to host ips", func(ctx context.Context) {
|
||||
|
||||
podName := "pod-dualstack-host-ips"
|
||||
@ -207,63 +158,6 @@ var _ = common.SIGDescribe("DualStack Host IP", framework.WithSerial(), nodefeat
|
||||
testDownwardAPI(ctx, f, podName, env, expectations)
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("when feature rollback", func() {
|
||||
tempSetCurrentKubeletConfig(f, func(ctx context.Context, initialConfig *kubeletconfig.KubeletConfiguration) {
|
||||
initialConfig.FeatureGates = map[string]bool{
|
||||
string(kubefeatures.PodHostIPs): true,
|
||||
}
|
||||
})
|
||||
ginkgo.It("should able upgrade and rollback", func(ctx context.Context) {
|
||||
podName := "pod-dualstack-host-ips"
|
||||
|
||||
pod := genPodHostIPs(podName+string(uuid.NewUUID()), false)
|
||||
|
||||
ginkgo.By("submitting the pod to kubernetes")
|
||||
podClient := e2epod.NewPodClient(f)
|
||||
p := podClient.CreateSync(ctx, pod)
|
||||
|
||||
gomega.Expect(p.Status.HostIPs).ShouldNot(gomega.BeNil())
|
||||
|
||||
ginkgo.By("Disable PodHostIPs feature")
|
||||
cfg, err := getCurrentKubeletConfig(ctx)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
newCfg := cfg.DeepCopy()
|
||||
newCfg.FeatureGates = map[string]bool{
|
||||
string(kubefeatures.PodHostIPs): false,
|
||||
}
|
||||
|
||||
updateKubeletConfig(ctx, f, newCfg, true)
|
||||
|
||||
gomega.Expect(p.Status.HostIPs).ShouldNot(gomega.BeNil())
|
||||
|
||||
ginkgo.By("deleting the pod")
|
||||
err = podClient.Delete(ctx, pod.Name, *metav1.NewDeleteOptions(1))
|
||||
framework.ExpectNoError(err, "failed to delete pod")
|
||||
|
||||
ginkgo.By("recreate pod")
|
||||
pod = genPodHostIPs(podName+string(uuid.NewUUID()), false)
|
||||
p = podClient.CreateSync(ctx, pod)
|
||||
// Feature PodHostIPs is disabled, HostIPs should be nil
|
||||
gomega.Expect(p.Status.HostIPs).Should(gomega.BeNil())
|
||||
|
||||
newCfg.FeatureGates = map[string]bool{
|
||||
string(kubefeatures.PodHostIPs): true,
|
||||
}
|
||||
|
||||
updateKubeletConfig(ctx, f, newCfg, true)
|
||||
|
||||
p, err = podClient.Get(ctx, pod.Name, metav1.GetOptions{})
|
||||
framework.ExpectNoError(err)
|
||||
// Feature PodHostIPs is enabled, HostIPs should not be nil
|
||||
gomega.Expect(p.Status.HostIPs).ShouldNot(gomega.BeNil())
|
||||
|
||||
ginkgo.By("deleting the pod")
|
||||
err = podClient.Delete(ctx, pod.Name, *metav1.NewDeleteOptions(1))
|
||||
framework.ExpectNoError(err, "failed to delete pod")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func genPodHostIPs(podName string, hostNetwork bool) *v1.Pod {
|
||||
|
Loading…
Reference in New Issue
Block a user