'Mounting ConfigMap deleted old data from MySQL my.cnf file

I am a newbee in Kubernetes/Openshift.

I am trying to update MySQL configuration using configmap. I have the below yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: slave-replcmap
data:
  my.conf: |
    [mysqld]
    server-id=2
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-slave
spec:
  selector:
    matchLabels:
      app: mysql-slave
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql-slave
    spec:
      volumes:
        - name: slave-mysql-persistent-storage
          persistentVolumeClaim:
            claimName: slave-nfs-claim1
        - name: slave-replcmap-vol
          configMap:
            name: slave-replcmap
        - name: slave-mysqlinitconf-vol
          configMap:
            name: slave-mysqlinitcmap
      containers:
      - image: mysql:5.7
        name: mysql-slave
        env:
        - name: MYSQL_SERVER_CONTAINER
          value: mysql
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
              secretKeyRef:
                name: mysql-secret
                key: MYSQL_ROOT_PASSWORD
        - name: MYSQL_DATABASE
          valueFrom:
              secretKeyRef:
                name: mysql-secret
                key: MYSQL_DATABASE
        - name: MYSQL_USER
          valueFrom:
              secretKeyRef:
                name: mysql-secret
                key: MYSQL_USER
        - name: MYSQL_PASSWORD
          valueFrom:
              secretKeyRef:
                name: mysql-secret
                key: MYSQL_PASSWORD
        ports:
        - containerPort: 3306
          name: mysql-slave
        volumeMounts:
        - name: slave-mysql-persistent-storage
          mountPath: /var/lib/mysql
        - name: slave-mysqlinitconf-vol
          mountPath: /docker-entrypoint-initdb.d
        - name: slave-replcmap-vol
          mountPath: /etc/mysql/my.cnf
          subPath: my.conf

Its updating the config file no issues in that.

But the issue is its deleting the existing content from my.cnf file and adding configmap data. I need to append this configmap data to my.cnf file without deleting the existing data.

Please let me know how i have to modify the yml file for to achieve that.

Thanks in advance.



Solution 1:[1]

Your current configuration mount volume directly to my.cnf file - mountPath: /etc/mysql/my.cnf. When you are doing that you are replacing it. subPath property is used to reference the file by key. Similar example can be found here.

Ive deployed this image on my local env. As default my.cnf inside have only some commented text and:

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

It means that all configuration files from both folders are included in main configuration.

Instead of mounting main config you might mount this config to one of the folders. For example:

...
          mountPath: /etc/mysql/conf.d/new.conf
          subPath: my.conf

Ohter ways how to pass ConfigMaps are describe here.

I would also recommended you to check this MySQL HELM Chart about configuration files in MySQL.

Solution 2:[2]

Luckily, the default /etc/mysql/my.cnf includes the following folder: /etc/mysql/conf.d/. So if you place your custom configuration in files in that folder, you are good.

You can achieve this with a ConfigMap as you propose.

Start by creating a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-custom-config
data:
  my.custom.conf: |
    [mysqld]
    server-id=2

As you can see from the example, this ConfigMap contains a single file named my.custom.conf.

Next, map this file to a file under /etc/mysql/conf.d/:

spec:
  containers:
  - image: mysql:5.7
    name: mysql
    ...
    volumeMounts:
    - name: mysql-custom-config
      mountPath: /etc/mysql/conf.d/custom.my.cnf
      subPath: custom.my.cnf #should be the name used in the ConfigMap
  volumes:
  - name: mysql-custom-config
    configMap:
      name: mysql-custom-config

Solution 3:[3]

i believe the content of existing my.cnf file is fixed .Thus you can add the existing content of my.cnf file to your configmap .

Solution 4:[4]

the way i did is super simple we need to create my.cnf on local machine then in next step we need to create configmap then we can mount

Here are the steps Step 1 : create my.cnf local

controlplane ~ ?  cat my.cnf 
[mysqld]
port=3306
confdir=conf.d/

Step 2 : Create Configmap

controlplane ~ ?  kubectl create configmap mycnf --from-file=my.cnf 

Step : Update pods definition file

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: mysql
  name: mysql
spec:
  containers:
  - image: nginx
    name: mysql
    volumeMounts:
    - name: foo
      mountPath: "/etc/my.cnf"
      subPath: my.cnf
      readOnly: true
  volumes:
  - name: foo
    configMap:
      name: mycnf

Same will work for deployment statefulsets daemonsets just ensure with indentation

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 PjoterS
Solution 2 Sam
Solution 3 shubham_asati
Solution 4 Mansur Ul Hasan