Skip to content

Commit 597b21d

Browse files
giorio94adamjensenbot
authored andcommitted
Virtual kubelet: improve pod translation
1 parent 0771d4c commit 597b21d

File tree

2 files changed

+89
-47
lines changed

2 files changed

+89
-47
lines changed

pkg/virtualKubelet/forge/pods.go

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const (
3333
PodOffloadingBackoffReason = "OffloadingBackoff"
3434
// PodOffloadingAbortedReason -> the reason assigned to pods rejected by the virtual kubelet after offloading has started.
3535
PodOffloadingAbortedReason = "OffloadingAborted"
36+
37+
// ServiceAccountVolumeName is the prefix name that will be added to volumes that mount ServiceAccount secrets.
38+
// This constant is taken from kubernetes/kubernetes (plugin/pkg/admission/serviceaccount/admission.go).
39+
ServiceAccountVolumeName = "kube-api-access-"
3640
)
3741

3842
// PodIPTranslator defines the function to translate between remote and local IP addresses.
@@ -126,18 +130,33 @@ func RemoteShadowPod(local *corev1.Pod, remote *vkv1alpha1.ShadowPod, targetName
126130
// RemotePodSpec forges the specs of the reflected pod specs, given the local ones.
127131
// It expects the local and remote objects to be deepcopies, as they are mutated.
128132
func RemotePodSpec(local, remote *corev1.PodSpec) corev1.PodSpec {
129-
remote.TerminationGracePeriodSeconds = local.TerminationGracePeriodSeconds
130-
remote.Volumes = forgeVolumes(local.Volumes)
131-
remote.InitContainers = forgeContainers(local.InitContainers, remote.Volumes)
132-
remote.Containers = forgeContainers(local.Containers, remote.Volumes)
133133
remote.Tolerations = RemoteTolerations(local.Tolerations)
134+
remote.Volumes = RemoteVolumes(local.Volumes)
135+
136+
remote.Containers = RemoteContainers(local.Containers, remote.Volumes)
137+
remote.InitContainers = RemoteContainers(local.InitContainers, remote.Volumes)
138+
139+
remote.ActiveDeadlineSeconds = local.ActiveDeadlineSeconds
140+
remote.AutomountServiceAccountToken = local.AutomountServiceAccountToken
141+
remote.DNSConfig = local.DNSConfig
142+
remote.DNSPolicy = local.DNSPolicy
134143
remote.EnableServiceLinks = local.EnableServiceLinks
144+
remote.HostAliases = local.HostAliases
135145
remote.Hostname = local.Hostname
136-
remote.Subdomain = local.Subdomain
137-
remote.TopologySpreadConstraints = local.TopologySpreadConstraints
146+
remote.ImagePullSecrets = local.ImagePullSecrets
147+
remote.ReadinessGates = local.ReadinessGates
138148
remote.RestartPolicy = local.RestartPolicy
139-
remote.AutomountServiceAccountToken = local.AutomountServiceAccountToken
140149
remote.SecurityContext = local.SecurityContext
150+
remote.SetHostnameAsFQDN = local.SetHostnameAsFQDN
151+
remote.ShareProcessNamespace = local.ShareProcessNamespace
152+
remote.Subdomain = local.Subdomain
153+
remote.TerminationGracePeriodSeconds = local.TerminationGracePeriodSeconds
154+
remote.TopologySpreadConstraints = local.TopologySpreadConstraints
155+
156+
// This fields are currently forced to false, to prevent invasive settings on the remote cluster (which might not work).
157+
remote.HostIPC = false
158+
remote.HostNetwork = false
159+
remote.HostPID = false
141160

142161
return *remote
143162
}
@@ -147,7 +166,7 @@ func RemoteTolerations(inputTolerations []corev1.Toleration) []corev1.Toleration
147166
tolerations := make([]corev1.Toleration, 0)
148167

149168
for _, toleration := range inputTolerations {
150-
// copy all tolerations except the one for the virtual node.
169+
// Copy all tolerations except the one for the virtual node.
151170
// This prevents by default the possibility of "recursive" scheduling on virtual nodes on the target cluster.
152171
if toleration.Key != liqoconst.VirtualNodeTolerationKey {
153172
tolerations = append(tolerations, toleration)
@@ -157,59 +176,47 @@ func RemoteTolerations(inputTolerations []corev1.Toleration) []corev1.Toleration
157176
return tolerations
158177
}
159178

160-
func forgeContainers(inputContainers []corev1.Container, inputVolumes []corev1.Volume) []corev1.Container {
161-
containers := make([]corev1.Container, 0)
162-
163-
for _, container := range inputContainers {
164-
volumeMounts := filterVolumeMounts(inputVolumes, container.VolumeMounts)
165-
containers = append(containers, translateContainer(container, volumeMounts))
179+
// RemoteContainers forges the containers for a reflected pod.
180+
func RemoteContainers(containers []corev1.Container, volumes []corev1.Volume) []corev1.Container {
181+
for i := range containers {
182+
// Containers are reflected verbatim, except for the removal of the volume mounts
183+
// referring to volumes that have been previously filtered.
184+
containers[i].VolumeMounts = RemoteVolumeMounts(volumes, containers[i].VolumeMounts)
166185
}
167186

168187
return containers
169188
}
170189

171-
func translateContainer(container corev1.Container, volumes []corev1.VolumeMount) corev1.Container {
172-
return corev1.Container{
173-
Name: container.Name,
174-
Image: container.Image,
175-
Command: container.Command,
176-
Args: container.Args,
177-
WorkingDir: container.WorkingDir,
178-
Ports: container.Ports,
179-
Env: container.Env,
180-
Resources: container.Resources,
181-
LivenessProbe: container.LivenessProbe,
182-
ReadinessProbe: container.ReadinessProbe,
183-
StartupProbe: container.StartupProbe,
184-
SecurityContext: container.SecurityContext,
185-
VolumeMounts: volumes,
186-
}
187-
}
190+
// RemoteVolumes forges the volumes for a reflected pod.
191+
func RemoteVolumes(inputVolumes []corev1.Volume) []corev1.Volume {
192+
volumes := make([]corev1.Volume, 0)
188193

189-
func forgeVolumes(volumesIn []corev1.Volume) []corev1.Volume {
190-
volumesOut := make([]corev1.Volume, 0)
191-
for _, v := range volumesIn {
192-
if v.ConfigMap != nil || v.EmptyDir != nil || v.DownwardAPI != nil || v.Projected != nil || v.PersistentVolumeClaim != nil {
193-
volumesOut = append(volumesOut, v)
194-
}
195-
// copy all volumes of type Secret except for the default token
196-
if v.Secret != nil && !strings.Contains(v.Secret.SecretName, "default-token") {
197-
volumesOut = append(volumesOut, v)
194+
for i := range inputVolumes {
195+
// Skip the projected volume which refers to the service account (if any).
196+
// This is a temporary fix, until service account reflection is fully supported.
197+
if inputVolumes[i].Projected != nil && strings.HasPrefix(inputVolumes[i].Name, ServiceAccountVolumeName) {
198+
continue
198199
}
200+
201+
volumes = append(volumes, inputVolumes[i])
199202
}
200-
return volumesOut
203+
204+
return volumes
201205
}
202206

203-
// remove from volumeMountsIn all the volumeMounts with name not contained in volumes.
204-
func filterVolumeMounts(volumes []corev1.Volume, volumeMountsIn []corev1.VolumeMount) []corev1.VolumeMount {
207+
// RemoteVolumeMounts forges the volume mounts for a reflected pod, given the selected volumes.
208+
func RemoteVolumeMounts(volumes []corev1.Volume, inputVolumeMounts []corev1.VolumeMount) []corev1.VolumeMount {
205209
volumeMounts := make([]corev1.VolumeMount, 0)
206-
for _, vm := range volumeMountsIn {
207-
for _, v := range volumes {
208-
if vm.Name == v.Name {
209-
volumeMounts = append(volumeMounts, vm)
210+
211+
for _, volumeMount := range inputVolumeMounts {
212+
for i := range volumes {
213+
if volumeMount.Name == volumes[i].Name {
214+
volumeMounts = append(volumeMounts, volumeMount)
215+
break
210216
}
211217
}
212218
}
219+
213220
return volumeMounts
214221
}
215222

pkg/virtualKubelet/forge/pods_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,41 @@ var _ = Describe("Pod forging", func() {
211211
It("should filter out liqo-related tolerations", func() { Expect(output).To(ConsistOf(included)) })
212212
})
213213

214+
Describe("the RemoteVolumes function", func() {
215+
var included, excluded, output []corev1.Volume
216+
217+
BeforeEach(func() {
218+
included = []corev1.Volume{
219+
{Name: "first", VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{}}},
220+
{Name: "second", VolumeSource: corev1.VolumeSource{Projected: &corev1.ProjectedVolumeSource{}}},
221+
{Name: "third", VolumeSource: corev1.VolumeSource{PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{}}},
222+
}
223+
excluded = []corev1.Volume{
224+
{Name: "kube-api-access-projected", VolumeSource: corev1.VolumeSource{Projected: &corev1.ProjectedVolumeSource{}}},
225+
}
226+
})
227+
228+
JustBeforeEach(func() { output = forge.RemoteVolumes(append(included, excluded...)) })
229+
It("should propagate all volume types, except the one referring to the service account", func() { Expect(output).To(ConsistOf(included)) })
230+
})
231+
232+
Describe("the RemoteVolumeMounts function", func() {
233+
var (
234+
input, output []corev1.VolumeMount
235+
volumes []corev1.Volume
236+
)
237+
238+
BeforeEach(func() {
239+
volumes = []corev1.Volume{{Name: "first"}, {Name: "third"}, {Name: "forth"}}
240+
input = []corev1.VolumeMount{{Name: "first"}, {Name: "second"}, {Name: "third"}, {Name: "forth"}, {Name: "fifth"}}
241+
})
242+
243+
JustBeforeEach(func() { output = forge.RemoteVolumeMounts(volumes, input) })
244+
It("should filter out the volume mounts without an associated volume", func() {
245+
Expect(output).To(ConsistOf([]corev1.VolumeMount{{Name: "first"}, {Name: "third"}, {Name: "forth"}}))
246+
})
247+
})
248+
214249
Describe("the *Stats functions", func() {
215250
PodStats := func(cpu, ram float64) statsv1alpha1.PodStats {
216251
Uint64Ptr := func(value uint64) *uint64 { return &value }

0 commit comments

Comments
 (0)