<p>If I set up MariaDB form the official image within a Docker Compose configuration, I can access it by its host name - for example if in a bash shell within the MariaDB container:</p>

<pre><code># host db
db has address 172.21.0.2


# curl telnet://db:3306
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: &lt;FILE&gt;" to save to a file.
</code></pre>

<ul>
<li>no connection refused issue here</li>
</ul>

<p>But if have MariaDB deployed from the official image within a Kubernetes cluster (tried both MicroK8s and GKE), I can connect to it via <code>localhost</code> but not by its host name:</p>

<pre><code># host db
db.my-namspace.svc.cluster.local has address 10.152.183.124

# curl telnet://db:3306
curl: (7) Failed to connect to db port 3306: Connection refused

# curl telnet://localhost:3306
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: &lt;FILE&gt;" to save to a file.
</code></pre>

<ul>
<li>connection is refused for the service host name, but localhost responds</li>
</ul>

<p>I've tried to replace the included <code>my.cnf</code> with a simplified version like:</p>

<pre><code>[mysqld]
skip-grant-tables
skip-networking=0
#### Unix socket settings (making localhost work)
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock

#### TCP Socket settings (making all remote logins work)
port         = 3306
bind-address = *
</code></pre>

<ul>
<li>with no luck</li>
</ul>

<p>The MariaDB Kubernetes deployment is like:</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      name: db
  template:
    metadata:
      labels:
        name: db
    spec:
      containers:
      - env:
        - name: MYSQL_PASSWORD
          value: template
        - name: MYSQL_ROOT_PASSWORD
          value: root
        - name: MYSQL_USER
          value: template
        image: mariadb:10.4
        name: db
        ports:
        - containerPort: 3306
        resources: {}
        volumeMounts:
        - mountPath: /var/lib/mysql
          name: dbdata
      restartPolicy: Always
      volumes:
      - name: dbdata
        persistentVolumeClaim:
          claimName: dbdata
status: {}
</code></pre>

<p>and the corresponding Persistent Volume Claim:</p>

<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    io.kompose.service: dbdata
  name: dbdata
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi
status: {}
</code></pre>

<p>It baffles me that the same configuration works with Docker Compose but not within a Kubernetes cluster.</p>

<p>Any ideas what may be going on?</p>

<p><em>Update 2020-03-18</em>
I forgot to include the service declaration for the database and add it here:</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app: db
  name: db
spec:
  ports:
  - name: "3306"
    port: 3306
    targetPort: 3306
  selector:
    app: db
    name: db
  type: ClusterIP
status:
  loadBalancer: {}

</code></pre>

<p>...am including both <code>app</code> and <code>name</code> for the <code>spec.selector</code> - am used to having only <code>name</code> but @Al-waleed Shihadeh's example includes <code>app</code> so I'll include that also, just in case - but without success.</p>

<p>Here are outputs from a couple of kubectl listing commands:</p>

<pre><code>$ sudo microk8s.kubectl get svc db -n my-namespace
NAME   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
db     ClusterIP   10.152.183.246   &lt;none&gt;        3306/TCP   35m
</code></pre>

<pre><code>$ sudo microk8s.kubectl get pods -owide -n my-namespace
NAME                           READY   STATUS             RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES
db-77cbcf87b6-l44lm            1/1     Running            0          34m   10.1.48.118   microk8s-vm   &lt;none&gt;           &lt;none&gt;
</code></pre>

<p><strong><em>Solution</em></strong>
Comparing the service declaration posted by KoopaKiller, which proved to work, I finally noticed that setting the <code>protocol</code> attribute to "TCP" in the ports declaration was missing - this part:</p>

<pre><code>spec:
  ports:
  - protocol: TCP
...
</code></pre>

<p>Since you are using Kubernetes Deployment, the name of your pods will be generated dinamically based on the name you gave in spec file, in your example, the pods will be create with the name <code>db-xxxxxxxxxx-xxxxx</code>. </p>

<p>In order to make a 'fixed' hostname, you need to create a service for reach your pods, example:</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  selector:
    name: db
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  type: ClusterIP
</code></pre>

<p>And to check if was successfully deployed:</p>

<pre><code>$ kubectl get svc db
NAME   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
db     ClusterIP   10.96.218.18   &lt;none&gt;        3306/TCP   89s
</code></pre>

<p>The fullname of your service will be: <code>&lt;name&gt;.&lt;namespace&gt;.cluster.local</code> in this case using <code>default</code> namespace will be <code>db.default.cluster.local</code> pointing to ip <code>10.96.218.18</code> as showed in example above.</p>

<p>To reach your service you need to configure your /etc/hosts with his information:</p>

<pre><code>echo -ne "10.96.218.18\tdb.default.cluster.local db db.default" &gt;&gt; /etc/hosts
</code></pre>

<p>After that you will be able to reach your service by dns:</p>

<pre><code>$ dig +short db
10.96.218.18

$ mysql -h db -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.5.5-10.4.12-MariaDB-1:10.4.12+maria~bionic mariadb.org binary distribution

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; 
</code></pre>

<p>Just for you know, you could also use HELM template to setup a mariadb with replication. See this <a href="https://engineering.bitnami.com/articles/deploy-a-production-ready-mariadb-cluster-on-kubernetes-with-bitnami-and-helm.html" rel="nofollow noreferrer">article</a></p>

<p><strong>References:</strong></p>

<p><a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">https://kubernetes.io/docs/concepts/services-networking/service/</a></p>

<p><a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/" rel="nofollow noreferrer">https://kubernetes.io/docs/concepts/workloads/controllers/deployment/</a></p>
