Leveraging InitContainers to Streamline Bitnami MySQL Initialization

In my previous post, How to Install and Use Starboard to Protect Your Kubernetes Cluster, I successfully secured my Bitnami MySQL deployment. The problem is that I also broke my Bitnami MySQL deployment. By upgrading the deployment, I lost the curl command that I used to pull down sample data into my pod. I realized that I could add an initContainer to Bitnami MySQL in order to mount the repo as a directory instead.

Adding the git-sync Container

Adding an initContainer seemed like a relatively simple task so I got right to it by first adding the SSH keys as a secret in my Kubernetes cluster and in Github. I won’t go too far into these steps because I’ve blogged about this in the past in my Building a Kubernetes Container That Synchs with Private Git Repo post. One thing that I did notice is that the original ssh-keyscan github.com > /tmp/known_hosts command isn’t sufficient to get all of the keys. I have also had to add the keys lists here too.

With the secret in place, I made some initial changes to my YAML file:

# Config values : https://github.com/bitnami/charts/tree/master/bitnami/mysql/
image:
  tag: 8.2.0-debian-11-r0
auth:
  rootPassword: "admin_password"
  username: "app_user"
  password: "user_password"
primary:
  initContainers:
    - env:
      - name: GIT_SYNC_REPO
        value: [email protected]:salgattcy/sample_dbs
      - name: GIT_SYNC_BRANCH
        value: master
      - name: GIT_SYNC_SSH
        value: "true"
      - name: GIT_SYNC_PERMISSIONS
        value: "0777"
      - name: GIT_SYNC_DEST
        value: sample_dbs
      - name: GIT_SYNC_ROOT
        value: /git
      - name: GIT_SYNC_ONE_TIME
        value: "true"
      name: git-sync
      image: registry.k8s.io/git-sync/git-sync:v3.6.5
      securityContext:
        runAsUser: 65533 # git-sync user
        allowPrivilegeEscalation: false
      volumeMounts:
      - name: git-secret
        mountPath: /etc/git-secret
      - name: dir
        mountPath: /git
  persistence:
    enabled: false
  extraVolumeMounts: |
      - name: dir
        mountPath: /opt/src
  extraVolumes: |
      - name: dir
        emptyDir: {}
      - name: git-secret
        secret:
          secretName: some-secret
          defaultMode: 288
initdbScripts:
  my_init_script.sh: |
    #!/bin/sh
    echo "Adding Sample Data"
    # curl https://raw.githubusercontent.com/salgattcy/sample_dbs/master/sampleData/sakila-schema.sql |mysql -P 3306 -uroot -p'admin_password'
    # curl https://raw.githubusercontent.com/salgattcy/sample_dbs/master/sampleData/sakila-data.sql |mysql -P 3306 -uroot -p'admin_password'

With that in place, I updated my code to see what happens. Everything deployed successfully so let’s see if my code is there

% kubectl -n ctesting exec -it prod-mysql-0 -- /bin/bash

I have no name!@prod-mysql-0:/$ ls -al /opt/src/sample_dbs/sampleData/
total 7528
drwxrwsrwx 2 65533 1001    4096 Nov 18 13:35 .
drwxrwsrwx 3 65533 1001    4096 Nov 18 13:35 ..
-rwxrwxrwx 1 65533 1001 2835456 Nov 18 13:35 dvdrental.tar
-rwxrwxrwx 1 65533 1001  161765 Nov 18 13:35 mongo.csv
-rwxrwxrwx 1 65533 1001    4570 Nov 18 13:35 mssql_create_objects.sql
-rwxrwxrwx 1 65533 1001 1306643 Nov 18 13:35 mssql_load_data.sql
-rwxrwxrwx 1 65533 1001 3351744 Nov 18 13:35 sakila-data.sql
-rwxrwxrwx 1 65533 1001   24254 Nov 18 13:35 sakila-schema.sql

Let’s go! It looks like I’ve now got my sample data on the ready.

Looking at the Bitnami MySQL YAML Changes

Before I move forward, let’s first look at the changes that I made to my YAML values file. I’ve added the following entries to my YAML

  • primary.initContainers
  • primary.extraVolumeMounts
  • primary.extraVolumes

There is nothing too special about these changes. These are similar to the extra Kubernetes configurations I made in my Building a Kubernetes Container That Synchs with Private Git Repo post. The only thing to note is that these go under primary in the YAML file. Adding them to primary makes them available for the primary MySQL pod and it shows based upon my deployment.

Getting My Sample Data Back Into MySQL

Now that I am synching my sample_dbs repo into my deployment, I need to update my deployment script to use this git mount. I updated my initdbScripts parameter like the below:

initdbScripts:
  my_init_script.sh: |
    #!/bin/sh
    echo "Adding Sample Data"
    mysql -P 3306 -uroot -p'admin_password' < /opt/src/sample_dbs/sampleData/sakila-schema.sql
    mysql -P 3306 -uroot -p'admin_password' < /opt/src/sample_dbs/sampleData/sakila-data.sql

After doing my commit again, I can connect to the DB and confirm I’ve got all of my sample data:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_database        |
| mysql              |
| performance_schema |
| sakila             |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> select * from actor limit 1;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        1 | PENELOPE   | GUINESS   | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)

Conclusion

This was just a quick detour on my Devops journey to explain how to add an initContainer to a Bitnami MySQL deployment. This was needed because in my How to Install and Use Starboard to Protect Your Kubernetes Cluster post I secured my MySQL deployment but broke the way I was adding sample data. Now that I have my sample data back and MySQL functioning as it was before I tried addressing the vulnerability scan results, It’s time to continuing addressing vulnerability scan results and audit results from Starboard.