'ingress mariadb always return This site can’t be reached

I'm just learning about Kubernetes using ingress and MariaDB. I don't know which one make my code error that return "This site can’t be reached". The requirement including Services, ConfigMap, and Secret. Make sure it is exposed by Ingress (make a simple local DNS in /etc/hosts) and can be accessed by Postman / Web Browser (do not port forwarding). All the CRUD features (Article) must be included in the video demo.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: toto-mariadb-volume
spec:
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 5Gi
  hostPath:
    path: /data

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: toto-mariadb-volume-claim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi

---

apiVersion: v1
kind: Secret
metadata:
  name: toto-mariadb-secret
stringData:
  MYSQL_DATABASE: toto
  MYSQL_PASSWORD: password
  MYSQL_ROOT_PASSWORD: P@ssw0rd
  MYSQL_USER: toto_user
data:
  toto_VERY_SECRET: "a3ViZXJuZXRlcwo="

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: toto-mariadb-config
data:
  APP_NAME: "toto-mariadb"
  APP_PORT: "3306"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: toto-mariadb
  labels:
    app: toto-mariadb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: toto-mariadb
  template:
    metadata:
      name: toto-mariadb
      labels:
        app: toto-mariadb
    spec:
      containers:
        - name: toto-mariadb
          image: mariadb
          resources:
            limits:
              memory: "1Gi"
              cpu: "500m"
          ports:
            - containerPort: 3306
              protocol: TCP
          envFrom:
            - secretRef:
                name: toto-mariadb-secret
            - configMapRef:
                name: toto-mariadb-config

---
apiVersion: v1
kind: Service
metadata:
  name: toto-mariadb-service
spec:
  selector:
    name: toto-mariadb
  ports:
    - port: 3306
      targetPort: 3306
      protocol: TCP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: toto-mariadb-ingress
  labels:
    app: toto-mariadb-ingress
spec:
  rules:
  - host: toto-mariadb.lovanto.local
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: toto-mariadb-service
            port: 
              number: 3306

The code work properly when using port-forward, but when using the host still not working



Solution 1:[1]

MariaDB does not use the HTTP protocol which is what postman and a browser use. Ingress are only concerned with http/https. So for your use case you most likely do not need an ingress.

There are a couple of easy ways to handle this.

kubectl port-forward ...


If you are just using this for fun/learning a quick way is to use port-forward using kubectl for example:

kubectl port-forward service/toto-mariadb-service 3306:3306

Then you would use an app/client like MariaDB Client to access the db using localhost at port 3306. You could also make a /etc/hosts entry with 127.0.0.1 <your-desired-hostname>

read more on this: https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/#forward-a-local-port-to-a-port-on-the-pod

Service of type: LoadBalancer


This is a better way if you want to have a port easily available long term to connect to. You will need to add type: LoadBalancer to the spec of your service (see below for example).

By default if type: is omitted from the service's spec field it will default to type: ClusterIP which will only assign an ip from the serviceCidr range which is not accessible from outside the cluster.

The potential problem with this approach is if you cluster is not configured to provide you an external ip when you kubectl get svc ... the external ip column will stay stuck at pending. If this happens to you you will need to see what methods will work for your flavor of K8s. A common approach is to use metallb

apiVersion: v1
kind: Service
metadata:
  name: toto-mariadb-service
spec:
  selector:
    name: toto-mariadb
  ports:
    - port: 3306
      targetPort: 3306
      protocol: TCP
  type: LoadBalancer

Then you would use your app/client to talk to the external ip the service has. Get this ip from your service with kubectl get svc ...

read more on this: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer

Solution 2:[2]

Ingress is HTTP only. Most if not all databases, including MariaDB, don't use http as protocol.

From the docs:

An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically uses a service of type Service.Type=NodePort or Service.Type=LoadBalancer.

You could expose this as a TCP service, if your ingress controller supports it. For example, see this: https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/

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
Solution 2