template-chart: seccomp profile, unprivileged port, and two placeholder fixes
Five changes to the scaffold every future chart is copied from: 1. seccompProfile.type: RuntimeDefault in the pod security context, in line with the rest of the seccomp series (#84). Pod context, because from there it also covers init containers and any container added later without being repeated. 2. containerPort 80 -> 8080, clearing AVD-KSV-0117. Note that the usual justification for this does not hold: a non-root container CAN bind port 80 on current Kubernetes, because the kubelet sets net.ipv4.ip_unprivileged_port_start=0 in the pod network namespace. Measured, not assumed - see the values.yaml comment. The reason to stay above 1024 is that this is a runtime default rather than a guarantee, and that every real chart here already does. 3. The ConfigMap placeholder key is renamed from the literal "key" to "example-setting", clearing AVD-KSV-01010 (secret-scanner patterns match any key named "key"). 4. The image placeholder is fully qualified as ghcr.io/ORG/IMAGE, so the template stops teaching the unqualified form that produced the repo's unqualified Docker Hub images. 5. env values are rendered through "quote". Without it a value like "8080" renders as a YAML number and the API server rejects the whole manifest ("cannot unmarshal number into Go struct field EnvVar.value of type string"). Every real chart in the repo already quotes here; only the template did not. Found by instantiating the template and installing it, not by rendering it. Verified by instantiating the scaffold into a working chart per the README procedure and installing it in k3d: the workload becomes Ready, the Service routes to the app on 8080 and an ephemeral container added to the running pod inherits Seccomp: 2 from the pod context. Refs #84
This commit is contained in:
7 files changed
+71
-19
No files matched your search
@@ -229,7 +229,8 @@ guidelines"):
|
||||
"runAsUser" 20000
|
||||
"runAsGroup" 1000
|
||||
"fsGroup" 1000
|
||||
"fsGroupChangePolicy" "Always" -}}
|
||||
"fsGroupChangePolicy" "Always"
|
||||
"seccompProfile" (dict "type" "RuntimeDefault") -}}
|
||||
{{- include "xxx.defaultedDict" (dict "defaults" $defaults "given" $given "path" "xxx.securityContext.pod") -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
@@ -3,4 +3,8 @@ kind: ConfigMap
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-{{ .Chart.Name }}-configmap"
|
||||
data:
|
||||
key: "value"
|
||||
# Placeholder for the chart's real configuration keys. Named for what it is:
|
||||
# a key literally called "key" matches the patterns secret scanners use to
|
||||
# find hardcoded credentials, so every copy of this template inherited a
|
||||
# false positive.
|
||||
example-setting: "value"
|
||||
@@ -27,26 +27,34 @@ spec:
|
||||
{{- include "xxx.podSecurityContext" .Values.xxx.securityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
||||
image: "registry/image:{{ .Chart.AppVersion }}"
|
||||
# Fully qualified on purpose: an unqualified "registry/image" resolves
|
||||
# to Docker Hub, which is how the repo accumulated its unqualified
|
||||
# images. Replace host/org/image, keep the registry host.
|
||||
image: "ghcr.io/ORG/IMAGE:{{ .Chart.AppVersion }}"
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
{{- range $value := .Values.xxx.env }}
|
||||
{{- if $value.value }}
|
||||
- name: {{ $value.name }}
|
||||
value: {{ tpl $value.value $ }}
|
||||
- name: {{ $value.name | quote }}
|
||||
# quote is required, not cosmetic: a value like "8080" or "true"
|
||||
# renders unquoted as a YAML number/bool, and the API server then
|
||||
# rejects the whole manifest with "cannot unmarshal number into
|
||||
# Go struct field EnvVar.value of type string". Every chart in
|
||||
# this repo quotes here.
|
||||
value: {{ tpl $value.value $ | quote }}
|
||||
{{- else if $value.valueFrom }}
|
||||
{{- if $value.valueFrom.secretKeyRef }}
|
||||
- name: {{ $value.name }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ tpl $value.valueFrom.secretKeyRef.name $ }}
|
||||
key: {{ tpl $value.valueFrom.secretKeyRef.key $ }}
|
||||
name: {{ tpl $value.valueFrom.secretKeyRef.name $ | quote }}
|
||||
key: {{ tpl $value.valueFrom.secretKeyRef.key $ | quote }}
|
||||
{{- else if $value.valueFrom.configMapKeyRef }}
|
||||
- name: {{ $value.name }}
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: {{ tpl $value.valueFrom.configMapKeyRef.name $ }}
|
||||
key: {{ tpl $value.valueFrom.configMapKeyRef.key $ }}
|
||||
name: {{ tpl $value.valueFrom.configMapKeyRef.name $ | quote }}
|
||||
key: {{ tpl $value.valueFrom.configMapKeyRef.key $ | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -28,26 +28,34 @@ spec:
|
||||
{{- include "xxx.podSecurityContext" .Values.xxx.securityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
|
||||
image: "registry/image:{{ .Chart.AppVersion }}"
|
||||
# Fully qualified on purpose: an unqualified "registry/image" resolves
|
||||
# to Docker Hub, which is how the repo accumulated its unqualified
|
||||
# images. Replace host/org/image, keep the registry host.
|
||||
image: "ghcr.io/ORG/IMAGE:{{ .Chart.AppVersion }}"
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
{{- range $value := .Values.xxx.env }}
|
||||
{{- if $value.value }}
|
||||
- name: {{ $value.name }}
|
||||
value: {{ tpl $value.value $ }}
|
||||
- name: {{ $value.name | quote }}
|
||||
# quote is required, not cosmetic: a value like "8080" or "true"
|
||||
# renders unquoted as a YAML number/bool, and the API server then
|
||||
# rejects the whole manifest with "cannot unmarshal number into
|
||||
# Go struct field EnvVar.value of type string". Every chart in
|
||||
# this repo quotes here.
|
||||
value: {{ tpl $value.value $ | quote }}
|
||||
{{- else if $value.valueFrom }}
|
||||
{{- if $value.valueFrom.secretKeyRef }}
|
||||
- name: {{ $value.name }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ tpl $value.valueFrom.secretKeyRef.name $ }}
|
||||
key: {{ tpl $value.valueFrom.secretKeyRef.key $ }}
|
||||
name: {{ tpl $value.valueFrom.secretKeyRef.name $ | quote }}
|
||||
key: {{ tpl $value.valueFrom.secretKeyRef.key $ | quote }}
|
||||
{{- else if $value.valueFrom.configMapKeyRef }}
|
||||
- name: {{ $value.name }}
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: {{ tpl $value.valueFrom.configMapKeyRef.name $ }}
|
||||
key: {{ tpl $value.valueFrom.configMapKeyRef.key $ }}
|
||||
name: {{ tpl $value.valueFrom.configMapKeyRef.name $ | quote }}
|
||||
key: {{ tpl $value.valueFrom.configMapKeyRef.key $ | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
Reference in new issue
Block a user