Home > Software engineering >  Pre-populated mysql docker image doesn't start when setup pod template security context
Pre-populated mysql docker image doesn't start when setup pod template security context

Time:11-04

I have a mysql image with a prepolutated schema, below I share the setup files.

My dockerfile:

FROM mysql:8.0.31 as builder

# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init
RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"]

# needed for intialization
ENV MYSQL_ROOT_PASSWORD=test

COPY ./sql-scripts /docker-entrypoint-initdb.d/

# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume.
# https://docs.docker.com/engine/reference/builder/#volume :
#       Changing the volume from within the Dockerfile: If any build steps change the data within the volume after
#       it has been declared, those changes will be discarded.
RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db"]

FROM mysql:8.0.31

COPY --from=builder /initialized-db /var/lib/mysql

My pod template yaml:

apiVersion: v1
kind: Pod
metadata:
  labels:
    label: 'backend'
spec:
  shareProcessNamespace: true
  containers:
    - name: "maven"
      image: maven:3.6.3-openjdk-11
      resources:
        requests:
          memory: "2Gi"
          cpu: "2"
        limits:
          memory: "10Gi"
          cpu: "10"
      command: [ sleep ]
      args: [ 1h ]
      securityContext:
        capabilities:
          add:
            - SYS_PTRACE
    - name: mysql
      image: myDockerRegistry/mysql8-integration-test:v5
      env:
        - name: MYSQL_USER
          value: test
        - name: MYSQL_PASSWORD
          value: test
        - name: MYSQL_ROOT_PASSWORD
          value: test
      securityContext:
        capabilities:
          add:
            - SYS_PTRACE

My pipeline:

pipeline {
    agent {
        kubernetes {
            yaml libraryResource('pod-templates/backend.yaml')
        }
    }
    stages { ... }
}

The above setup works fine, but I want to use a dynamic PVC for the workspace, then I add the following line to my pipeline after the pod template.

workspaceVolume dynamicPVC(accessModes: 'ReadWriteOnce',requestsSize: "10Gi", storageClassName: 'premium-rwo')

But I have to add securityContext to my pod template so jenkins will able to mount the PVC in the agent:

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000

With those changes the pod start and the volume is mounted correctly, but the mysql container doesn't work. This is the error log:

2022-11-03 09:33:25 00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.31-1.el8 started.
'/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
2022-11-03T09:33:25.839933Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
2022-11-03T09:33:25.842508Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.31) starting as process 13
2022-11-03T09:33:25.845263Z 0 [Warning] [MY-010122] [Server] One can only use the --user switch if running as root
mysqld: File './binlog.index' not found (OS errno 13 - Permission denied)
2022-11-03T09:33:25.845867Z 0 [ERROR] [MY-010119] [Server] Aborting
2022-11-03T09:33:25.846078Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.31)  MySQL Community Server - GPL.

I asume is something related with root rights in the mysql container, but is weird because the official image runs perfectly.

Finally this is the raw yaml generated after inject the jenkins agent:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    buildUrl: >-
      http://jenkins.jenkins.svc.cluster.local:8080/job/LegacyProjects/job/my-project/job/k8s-test/79/
    runUrl: job/LegacyProjects/job/my-project/job/k8s-test/79/
  labels:
    label: backend
    jenkins/jenkins-jenkins-agent: 'true'
    jenkins/label-digest: 4581eadfdfcb3d0141b8e8727b53b2ff9a3575ec
    jenkins/label: LegacyProjects_my-project_k8s-test_79-xgtxd
  name: my-project-k8s-test-79-xgtxd-2xw2r-8wj64
  namespace: jenkins
spec:
  containers:
    - args:
        - 1h
      command:
        - sleep
      image: 'maven:3.6.3-openjdk-11'
      name: maven
      resources:
        limits:
          memory: 10Gi
          cpu: '10'
        requests:
          memory: 2Gi
          cpu: '2'
      securityContext:
        capabilities:
          add:
            - SYS_PTRACE
      volumeMounts:
        - mountPath: /home/jenkins/agent
          name: workspace-volume
          readOnly: false
    - env:
        - name: MYSQL_USER
          value: test
        - name: MYSQL_PASSWORD
          value: test
        - name: MYSQL_ROOT_PASSWORD
          value: test
      image: 'myDockerRegistry/mysql8-integration-test:v5'
      name: mysql
      securityContext:
        capabilities:
          add:
            - SYS_PTRACE
      volumeMounts:
        - mountPath: /home/jenkins/agent
          name: workspace-volume
          readOnly: false
    - env:
        - name: JENKINS_SECRET
          value: '********'
        - name: JENKINS_TUNNEL
          value: 'jenkins-agent.jenkins.svc.cluster.local:50000'
        - name: JENKINS_AGENT_NAME
          value: my-project-k8s-test-79-xgtxd-2xw2r-8wj64
        - name: JENKINS_NAME
          value: my-project-k8s-test-79-xgtxd-2xw2r-8wj64
        - name: JENKINS_AGENT_WORKDIR
          value: /home/jenkins/agent
        - name: JENKINS_URL
          value: 'http://jenkins.jenkins.svc.cluster.local:8080/'
      image: 'jenkins/inbound-agent:4.11-1-jdk11'
      name: jnlp
      resources:
        limits: {}
        requests:
          memory: 256Mi
          cpu: 100m
      volumeMounts:
        - mountPath: /home/jenkins/agent
          name: workspace-volume
          readOnly: false
  nodeSelector:
    kubernetes.io/os: linux
  restartPolicy: Never
  securityContext:
    fsGroup: 1000
    runAsGroup: 1000
    runAsUser: 1000
  shareProcessNamespace: true
  volumes:
    - name: workspace-volume
      persistentVolumeClaim:
        claimName: pvc-workspace-my-project-test-79-xgtxd-2xw2r-8wj64
        readOnly: false

Any help will be appreciated

CodePudding user response:

COPY command by default works only as root user, you should specify --chown=1000:1000 flag to that command to set the correct user and group (in your case - it's user with uid and gid 1000, which is specified in securityContext), see https://stackoverflow.com/a/44766666 and https://docs.docker.com/engine/reference/builder/#copy for more details

While your use case might require pre-building image with database, consider running official mysql image as db, and your application with init container with liquibase/flyway or other (even in-built) database migration toolkit, which might be a more portable solution in a long run

  • Related