Docker container (Kubernetes): Mysql user access denied

11/21/2019

Hi I have followed some k8s tutorials on how to get going with setting up a local db + WordPress installation, but user can't connect to mysql within my cluster. (everything else seems ok - in Kubernetes Dashboard Web UI)

Error: [15:40:55][~]#kubectl logs -f website-56677747c7-c7lb6 [21-Nov-2019 11:07:17 UTC] PHP Warning: mysqli::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known in Standard input code on line 22 [21-Nov-2019 11:07:17 UTC] PHP Warning: mysqli::__construct(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Name or service not known in Standard input code on line 22

MySQL Connection Error: (2002) php_network_getaddresses: getaddrinfo failed: Name or service not known [21-Nov-2019 11:07:20 UTC] PHP Warning: mysqli::__construct(): (HY000/1045): Access denied for user 'websiteu5er'@'10.1.0.35' (using password: YES) in Standard input code on line 22

MySQL Connection Error: (1045) Access denied for user 'websiteu5er'@'10.1.0.35' (using password: YES)

MySQL Connection Error: (1045) Access denied for user 'websiteu5er'@'10.1.0.35' (using password: YES)

MySQL Connection Error: (1045) Access denied for user 'websiteu5er'@'10.1.0.35' (using password: YES)

My Dockerfile (which I used to create the image pushed to docker hub then pulled into k8s service + deployment):

FROM mysql:5.7

# This should create the following default root + user?
ENV MYSQL_ROOT_PASSWORD=hello123
ENV MYSQL_DATABASE=website
ENV MYSQL_USER=websiteu5er
ENV MYSQL_PASSWORD=hello123

RUN /etc/init.d/mysql start \
    && mysql -u root --password='hello123' -e "GRANT ALL PRIVILEGES ON *.* TO 'websiteu5er'@'%' IDENTIFIED BY 'hello123';"


FROM wordpress:5.2.4-php7.3-apache

# Copy wp-config file over
COPY configs/wp-config.php .

RUN chown -R www-data:www-data *

COPY ./src/wp-content/themes/bam /var/www/html/wp-content/themes/bam
-- gvanto
docker
kubernetes

2 Answers

11/21/2019

I see you are trying to start mysql database and then grant privileges for your user but you are doing it all wrong.

After runing:

RUN /etc/init.d/mysql start \
    && mysql -u root --password='hello123' -e "GRANT ALL PRIVILEGES ON *.* TO 'websiteu5er'@'%' IDENTIFIED BY 'hello123';"

mysql starts but your query after && never runs so your user doesn't get its privileges. It will get run only if mysql exits successfully. Look here for explanation how && works in shell.

What you want to do is run this command after mysql starts and you can do it in several ways but probably the best in your case would be using PostStart hook in kubernetes:

spec:
  containers:
  - name: test
    image: someimage
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "mysql -u root --password='hello123' -e \"GRANT ALL PRIVILEGES ON *.* TO 'websiteu5er'@'%' IDENTIFIED BY 'hello123';\""]

You may also want to add few second sleep command before you run the query to make sure the server actually started before you connect to it.

Also take a look at kubernetes documentation and read more about lifecycle hooks.

Let me know if it was helpful.

-- HelloWorld
Source: StackOverflow

11/21/2019

The standard Docker Hub mysql image has the ability to run arbitrary SQL scripts on the very first startup of the database only. It can also set up an initial database user with a known password, again on the first startup only. Details are in the linked Docker Hub page.

In a Kubernetes context I’d use just the environment variables, and specify them in my pod spec.

containers:
  - name: mysql
    image: mysql:5.7 # not a custom image
    env:
      - name: MYSQL_USER
        value: websiteu5er
      - name: MYSQL_PASSWORD
        value: hello123

If you did need more involved setup, I’d create a ConfigMap that contained SQL scripts, and then mount that into the container in /docker-entrypoint-initdb.d.


There’s two things going on in your Dockerfile. One is that, when you have multiple FROM lines, you’re actually executing a multi-stage build; the image you get out at the end is only the Wordpress image, and the MySQL parts before it get skipped. The second is that you can’t actually create an image FROM mysql that contains any database-level configuration or content, so the image that comes out of the first stage has the environment variables set but won’t actually have executed your GRANT PRIVILEGES statement.

I’d just delete everything before the last FROM line and not try to build a derived MySQL image; use the /docker-entrypoint-initdb.d mechanism at startup time instead.

-- David Maze
Source: StackOverflow