Skip to content

Commit

Permalink
Merge #182
Browse files Browse the repository at this point in the history
182: Run meilisearch as non-root user with readOnlyRootFilesystem r=alallema a=legal90

# Pull Request

## Related issue
- meilisearch/meilisearch#2051  (it's just a relevant issue raised on the meilisearch image level)

This PR was created in the continuation to our discussion here: #176 (comment)

## What does this PR do?

That PR changes the default behaviour of the chart so it runs meilisearch under a non-root user, following the principal of least permissions and improve the security posture:

- Enable `securityContext.readOnlyRootFilesystem: true` by default and mount required writable points:
  - `/tmp` as `emptyDir: {}` [1]
  - `/meili_data` as `emptyDir: {}` by default, or as a PVC if `persistence.enabled: true`

- Default values `fsGroup: 1000` and `fsGroupChangePolicy: OnRootMismatch` allow to keep backward compatibility with existing installations. If the data volume already has files previously created and owned by root (e.q. `persistence.enabled: true`), then k8s will automatically change the group ownership of these files to 1000, so they will still be writable by the non-privileged user in this new chart version. That happens automatically - no user action is needed. [2]

- **Small chance of backward incompatibility for some users:**  those users who already have `/tmp` mount configured via `volumes` and `volumeMounts` values, might get a failure in upgrade to this new version, because this volume is now declared in the template by default. The fix is simple - just remove the definition of /tmp from your custom values.

Due to that I'm bumping the minor version of the chart to 0.2.0. Please let me know if you think we should update it differently.

## Links 
[1] https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
[2] https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#configure-volume-permission-and-ownership-change-policy-for-pods

## PR checklist
Please check if your PR fulfills the following requirements:
- [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
- [x] Have you read the contributing guidelines?
- [x] Have you made sure that the title is accurate and descriptive of the changes?



Co-authored-by: Mikhail Zholobov <legal90@gmail.com>
Co-authored-by: Amélie <alallema@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 26, 2023
2 parents 0ad1b81 + 5794610 commit 0dda412
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 12 deletions.
2 changes: 1 addition & 1 deletion charts/meilisearch/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v1
appVersion: "v1.2.0"
description: A Helm chart for the Meilisearch search engine
name: meilisearch
version: 0.1.59
version: 0.2.0
icon: https://res.cloudinary.com/meilisearch/image/upload/v1597822872/Logo/logo_img.svg
home: https://github.com/meilisearch/meilisearch-kubernetes/tree/main/charts/meilisearch
maintainers:
Expand Down
9 changes: 7 additions & 2 deletions charts/meilisearch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A Helm chart for the Meilisearch search engine

![Version: 0.1.58](https://img.shields.io/badge/Version-0.1.58-informational?style=flat-square) ![AppVersion: v1.2.0](https://img.shields.io/badge/AppVersion-v1.2.0-informational?style=flat-square)
![Version: 0.2.0](https://img.shields.io/badge/Version-0.2.0-informational?style=flat-square) ![AppVersion: v1.2.0](https://img.shields.io/badge/AppVersion-v1.2.0-informational?style=flat-square)

Helm works as a package manager to run pre-configured Kubernetes resources.

Expand Down Expand Up @@ -88,13 +88,18 @@ You can also use `auth.existingMasterKeySecret` to use an existing secret that h
| persistence.volume.name | string | `"data"` | |
| podAnnotations | object | `{}` | |
| podLabels | object | `{}` | Additional labels to add to the pod(s) only |
| podSecurityContext | object | `{}` | |
| podSecurityContext.fsGroup | int | `1000` | |
| podSecurityContext.fsGroupChangePolicy | string | `"OnRootMismatch"` | |
| podSecurityContext.runAsGroup | int | `1000` | |
| podSecurityContext.runAsNonRoot | bool | `true` | |
| podSecurityContext.runAsUser | int | `1000` | |
| readinessProbe.InitialDelaySeconds | int | `0` | |
| readinessProbe.periodSeconds | int | `10` | |
| replicaCount | int | `1` | Number of Meilisearch pods to run |
| resources | object | `{}` | Resources allocation (Requests and Limits) |
| securityContext.allowPrivilegeEscalation | bool | `false` | |
| securityContext.capabilities.drop[0] | string | `"ALL"` | |
| securityContext.readOnlyRootFilesystem | bool | `true` | |
| service | object | `{"annotations":{},"port":7700,"type":"ClusterIP"}` | Service HTTP port |
| service.annotations | object | `{}` | Additional annotations for service |
| service.type | string | `"ClusterIP"` | Kubernetes Service type |
Expand Down
13 changes: 7 additions & 6 deletions charts/meilisearch/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,34 @@ spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- end }}
{{- if or .Values.persistence.enabled .Values.volumes }}
volumes:
- name: tmp
emptyDir: {}
{{- if .Values.persistence.enabled }}
- name: {{ .Values.persistence.volume.name }}
persistentVolumeClaim:
claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ include "meilisearch.fullname" . }}{{- end }}
{{- else }}
- name: {{ .Values.persistence.volume.name }}
emptyDir: {}
{{- end }}
{{- if .Values.volumes }}
{{ toYaml .Values.volumes | indent 8 }}
{{- end }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{ toYaml .Values.securityContext | indent 12 }}
{{- if or .Values.persistence.enabled .Values.volumeMounts }}
volumeMounts:
{{- if .Values.persistence.enabled }}
- name: tmp
mountPath: /tmp
- name: {{ .Values.persistence.volume.name }}
mountPath: {{ .Values.persistence.volume.mountPath }}
{{- end }}
{{- if .Values.volumeMounts }}
{{ toYaml .Values.volumeMounts | indent 12 }}
{{- end }}
{{- end }}
envFrom:
- configMapRef:
name: {{ template "meilisearch.fullname" . }}-environment
Expand Down
9 changes: 7 additions & 2 deletions charts/meilisearch/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,19 @@ service:
container:
containerPort: 7700

podSecurityContext: {}
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch

securityContext:
capabilities:
drop:
- ALL
allowPrivilegeEscalation: false
# readOnlyRootFilesystem: true
readOnlyRootFilesystem: true

ingress:
# -- Enable ingress controller resource
Expand Down
19 changes: 18 additions & 1 deletion manifests/meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,20 @@ spec:
app.kubernetes.io/component: search-engine
app.kubernetes.io/part-of: meilisearch
annotations:
checksum/config: ae9884187319e63ffb542daf76a83b035abbfb6fe306768ab983e82d34048dca
checksum/config: 2feedcfe9e2a9425200a2c547238c64e882bd9160bf3a521e1dbab0e83ee246f
spec:
serviceAccountName: meilisearch
securityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}
- name: data
emptyDir: {}
containers:
- name: meilisearch
image: "getmeili/meilisearch:v1.2.0"
Expand All @@ -87,6 +98,12 @@ spec:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
- name: data
mountPath: /meili_data
envFrom:
- configMapRef:
name: meilisearch-environment
Expand Down

0 comments on commit 0dda412

Please sign in to comment.