Problem statement:
Linux users which are dynamically created in Kubernetes Containers are not persistant. Therefore, whenever a Kubernetes Pod gets restarted, the dynamically created users are lost.
For example, if you want to run multiple vhosts in a Kubernetes Container under separate UIDs and GIDs with apache2-mpm-itk (which is an MPM – Multi-Processing Module for the Apache web server), a solution for persisting Linux users like the following is required:
Solution:
This solution desribes how to survive Kubernetes Pod restarts by dynamically recreating Linux users in a Kubernetes container whenever a new pod is created.
- Create a Kubernetes ConfigMap (or Secret) for storing custom users:
apiVersion: v1 kind: ConfigMap metadata: name: my-linux-users data: linux-users: ""
- Create a script which reads the custom users from the ConfigMap mounted in /etc/linux-users and which recreates the users when the pod is restarted. Store the script in another Kubernetes ConfigMap as follows:
apiVersion: v1 kind: ConfigMap metadata: name: my-sync-script data: install-linux-users.sh: | # Install existing linux users mounted from configmap in /etc/linux-users - file echo "Install Linux Users..." cat /etc/linux-users | awk -F ":" '{ system("groupadd "$1""); system("useradd -c "$5" -s /usr/sbin/nologin -d "$6" -m -g "$4" "$1"")}'
- Mount the Kubernetes ConfigMaps in your StatefulSet (or Deployment) where your container resides (excerpt)
apiVersion: apps/v1 kind: StatefulSet spec: containers: - image: ... name: ... volumeMounts: - name: linux-users mountPath: /etc/linux-users subPath: linux-users readOnly: true - name: install-conf mountPath: /usr/local/bin/install-linux-users.sh subPath: install-linux-users.sh readOnly: true volumes: - name: linux-users configMap: name: my-linux-users items: - key: www-users path: www-users - name: install-conf configMap: name: my-sync-script items: - key: install-linux-users.sh path: install-linux-users.sh
- Hook into the postStart – Event when a container is created and run the script which recreates the users
.... lifecycle: postStart: exec: command: - "/bin/bash" - "-eu" - "/usr/local/bin/install-linux-users.sh"
- Whenever you create a Linux user in your Kubernetes container, get a custom user list from the /etc/passed -file and save in a temp directory.
# Create linux user groupadd ${WWW_GROUP}" useradd -c ${WWW_COMMENT} -s /bin/false -d /home/${LINUX_USER} -m -g ${WWW_GROUP} ${WWW_USER}"
# Save custom linux-users (filtered by a common comment) in a temp directory. grep ${WWW_COMMENT} /etc/passwd >${LINUX_USERS_FILE}
- Get the list of your linux users from the container
kubectl cp ${NAMESPACE}/${WEBSERVER_POD}:${LINUX_USERS_FILE} ${LOCAL_LINUX_USERS_FILE} -c ${WEBSERVER_CONTAINER}
- # Update the configmap with the linux-users – file
kubectl create configmap my-linux-users --namespace=${NAMESPACE} --from-file=${LOCAL_LINUX_USERS_FILE} --save-config -o=yaml --dry-run | kubectl apply -f -
Need further support or Kubernetes Consulting?
Please checkout our Consulting hours.
You don’t want to go into technical details anymore?
Check out the Blue Antoinette Commerce Cloud, which is built on and abstracts away the complexities of Kubernetes.
—