title: Can't connect to MariaDB by hostname within a Kubernetes cluster
body: <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>