Skip to content

Commit a5ab01f

Browse files
committed
Run glance-api as privileged container when image cache is enabled
ImageCache currently uses two different cronJobs associated to each glance-api instance (-cleaner and -pruner cronJobs). They mount /var/lib/glance/image-cache, a RWO Pvc, and execute a glance utility on the filestem owned by glance kolla user/group. Without glance-api being privileged, after the cronJob execution the Glance Pod is not able to access the image-cache path anymore, resulting in a Permission denied error. This patch defines a FSGroup that should be set at Pod level to make sure we always have the right privileges on the container fs, and, in addition, it runs glance-api as a privileged container when Cache is enabled. Jira: https://issues.redhat.com/browse/OSPRH-9842 Signed-off-by: Francesco Pantano <[email protected]>
1 parent 8fb0d09 commit a5ab01f

File tree

8 files changed

+31
-33
lines changed

8 files changed

+31
-33
lines changed

api/v1beta1/common_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ type GlanceAPITemplate struct {
108108
APITimeout int `json:"apiTimeout,omitempty"`
109109
}
110110

111+
// Storage -
111112
type Storage struct {
112113
// +kubebuilder:validation:Optional
113114
// StorageClass -

api/v1beta1/glance_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const (
3535
APIEdge = "edge"
3636
)
3737

38-
// GlanceSpec defines the desired state of Glance
38+
// GlanceSpecCore defines the desired state of Glance
3939
type GlanceSpecCore struct {
4040
// +kubebuilder:validation:Optional
4141
// +kubebuilder:default=glance

api/v1beta1/glance_webhook.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ func (r *GlanceSpec) ValidateUpdate(old GlanceSpec, basePath *field.Path) field.
346346
return r.GlanceSpecCore.ValidateUpdate(old.GlanceSpecCore, basePath)
347347
}
348348

349+
// ValidateUpdate -
349350
func (r *GlanceSpecCore) ValidateUpdate(old GlanceSpecCore, basePath *field.Path) field.ErrorList {
350351
var allErrs field.ErrorList
351352

controllers/glanceapi_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ func (r *GlanceAPIReconciler) reconcileNormal(
802802

803803
// This is currently required because cleaner and pruner cronJobs
804804
// mount the same pvc to clean data present in /var/lib/glance/image-cache
805+
// TODO (fpantano) reference a Glance spec/proposal to move to a different
806+
// approach
805807
if len(instance.Spec.ImageCache.Size) > 0 {
806808
privileged = true
807809
}

pkg/glance/const.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const (
5454
GlanceInternalPort int32 = 9292
5555
// GlanceUID - https://github.com/openstack/kolla/blob/master/kolla/common/users.py
5656
GlanceUID int64 = 42415
57-
// GlanceGid - https://github.com/openstack/kolla/blob/master/kolla/common/users.py
57+
// GlanceGID - https://github.com/openstack/kolla/blob/master/kolla/common/users.py
5858
GlanceGID int64 = 42415
5959
// DefaultsConfigFileName -
6060
DefaultsConfigFileName = "00-config.conf"

pkg/glance/funcs.go

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package glance
22

33
import (
44
corev1 "k8s.io/api/core/v1"
5+
"k8s.io/utils/ptr"
56
"sigs.k8s.io/controller-runtime/pkg/client"
67
)
78

@@ -13,19 +14,16 @@ func GetOwningGlanceName(instance client.Object) string {
1314
return ownerRef.Name
1415
}
1516
}
16-
1717
return ""
1818
}
1919

2020
// dbSyncSecurityContext - currently used to make sure we don't run db-sync as
2121
// root user
2222
func dbSyncSecurityContext() *corev1.SecurityContext {
23-
runAsUser := int64(GlanceUID)
24-
runAsGroup := int64(GlanceGID)
2523

2624
return &corev1.SecurityContext{
27-
RunAsUser: &runAsUser,
28-
RunAsGroup: &runAsGroup,
25+
RunAsUser: ptr.To(GlanceUID),
26+
RunAsGroup: ptr.To(GlanceGID),
2927
Capabilities: &corev1.Capabilities{
3028
Drop: []corev1.Capability{
3129
"MKNOD",
@@ -40,16 +38,12 @@ func dbSyncSecurityContext() *corev1.SecurityContext {
4038
// BaseSecurityContext - currently used to make sure we don't run cronJob and Log
4139
// Pods as root user, and we drop privileges and Capabilities we don't need
4240
func BaseSecurityContext() *corev1.SecurityContext {
43-
falseVal := false
44-
trueVal := true
45-
runAsUser := int64(GlanceUID)
46-
runAsGroup := int64(GlanceGID)
4741

4842
return &corev1.SecurityContext{
49-
RunAsUser: &runAsUser,
50-
RunAsGroup: &runAsGroup,
51-
RunAsNonRoot: &trueVal,
52-
AllowPrivilegeEscalation: &falseVal,
43+
RunAsUser: ptr.To(GlanceUID),
44+
RunAsGroup: ptr.To(GlanceGID),
45+
RunAsNonRoot: ptr.To(true),
46+
AllowPrivilegeEscalation: ptr.To(false),
5347
Capabilities: &corev1.Capabilities{
5448
Drop: []corev1.Capability{
5549
"ALL",
@@ -63,11 +57,10 @@ func BaseSecurityContext() *corev1.SecurityContext {
6357

6458
// APISecurityContext -
6559
func APISecurityContext(userID int64, privileged bool) *corev1.SecurityContext {
66-
runAsUser := int64(userID)
67-
trueVal := true
60+
6861
return &corev1.SecurityContext{
69-
AllowPrivilegeEscalation: &trueVal,
70-
RunAsUser: &runAsUser,
62+
AllowPrivilegeEscalation: ptr.To(true),
63+
RunAsUser: ptr.To(userID),
7164
Privileged: &privileged,
7265
SeccompProfile: &corev1.SeccompProfile{
7366
Type: corev1.SeccompProfileTypeRuntimeDefault,
@@ -77,16 +70,15 @@ func APISecurityContext(userID int64, privileged bool) *corev1.SecurityContext {
7770

7871
// HttpdSecurityContext -
7972
func HttpdSecurityContext() *corev1.SecurityContext {
80-
runAsUser := int64(0)
81-
falseVal := false
73+
8274
return &corev1.SecurityContext{
83-
AllowPrivilegeEscalation: &falseVal,
8475
Capabilities: &corev1.Capabilities{
8576
Drop: []corev1.Capability{
86-
"ALL",
77+
"MKNOD",
8778
},
8879
},
89-
RunAsUser: &runAsUser,
80+
RunAsUser: ptr.To(GlanceUID),
81+
RunAsGroup: ptr.To(GlanceGID),
9082
SeccompProfile: &corev1.SeccompProfile{
9183
Type: corev1.SeccompProfileTypeRuntimeDefault,
9284
},

pkg/glanceapi/cachejob.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,20 @@ limitations under the License.
1616
package glanceapi
1717

1818
import (
19+
"fmt"
1920
glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1"
2021
"github.com/openstack-k8s-operators/glance-operator/pkg/glance"
21-
22-
"fmt"
23-
2422
batchv1 "k8s.io/api/batch/v1"
2523
corev1 "k8s.io/api/core/v1"
2624
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/utils/ptr"
2726
)
2827

2928
// ImageCacheJob -
3029
func ImageCacheJob(
3130
instance *glancev1.GlanceAPI,
3231
cronSpec glance.CronJobSpec,
3332
) *batchv1.CronJob {
34-
runAsUser := int64(0)
3533
var config0644AccessMode int32 = 0644
3634

3735
cronCommand := fmt.Sprintf(
@@ -100,6 +98,9 @@ func ImageCacheJob(
10098
Completions: &completions,
10199
Template: corev1.PodTemplateSpec{
102100
Spec: corev1.PodSpec{
101+
SecurityContext: &corev1.PodSecurityContext{
102+
FSGroup: ptr.To(glance.GlanceUID),
103+
},
103104
Affinity: GetGlanceAPIPodAffinity(instance),
104105
Containers: []corev1.Container{
105106
{
@@ -108,11 +109,9 @@ func ImageCacheJob(
108109
Command: []string{
109110
"/bin/bash",
110111
},
111-
Args: args,
112-
VolumeMounts: cronJobVolumeMounts,
113-
SecurityContext: &corev1.SecurityContext{
114-
RunAsUser: &runAsUser,
115-
},
112+
Args: args,
113+
VolumeMounts: cronJobVolumeMounts,
114+
SecurityContext: glance.BaseSecurityContext(),
116115
},
117116
},
118117
Volumes: cronJobVolume,

pkg/glanceapi/statefulset.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ func StatefulSet(
179179
Labels: labels,
180180
},
181181
Spec: corev1.PodSpec{
182+
SecurityContext: &corev1.PodSecurityContext{
183+
FSGroup: &userID,
184+
},
182185
ServiceAccountName: instance.Spec.ServiceAccount,
183186
// When using Cinder we run as privileged, but also some
184187
// commands need to be run on the host using nsenter (eg:

0 commit comments

Comments
 (0)