Minikube Ingress DNS: Difference between revisions

From Chorke Wiki
Jump to navigation Jump to search
 
(47 intermediate revisions by the same user not shown)
Line 57: Line 57:
{|
{|
|colspan="2"|
|colspan="2"|
kubectl edit configmap coredns -n kube-system
<syntaxhighlight lang="bash">
<syntaxhighlight lang='properties' line start='5'>
# minikube nameserver ip
apiVersion: v1
printf -v MINIKUBE_NSLOOKUP '%s' $(minikube ip)
data:
  Corefile: |
    .:53 {
        log
        errors
</syntaxhighlight>
</syntaxhighlight>
|-
|colspan="2"|
----
----
<syntaxhighlight lang='properties' line start='30' highlight='4-13'>
|-
         reload
|valign='top'|
         loadbalance
<syntaxhighlight lang='bash' line>
# minikube find coredns last entry
CONFIGMAP_COREDNS_FIND=$(cat <<QRY
        }\n\
        cache 30\n\
        loop\n\
         reload\n\
         loadbalance\n\
     }
     }
     k8s.local:53 {
QRY
         errors
)
         cache 30
</syntaxhighlight>
         forward . 192.168.49.2
 
|valign='top'|
<syntaxhighlight lang='bash' line>
# minikube fill coredns last entry
CONFIGMAP_COREDNS_FILL=$(cat <<UPD
${CONFIGMAP_COREDNS_FIND}\n\
     k8s.local:53 {\n\
         errors\n\
         cache 30\n\
         forward . ${MINIKUBE_NSLOOKUP}\n\
     }
     }
    academia.local:53 {
UPD
        errors
)
        cache 30
</syntaxhighlight>
        forward . 192.168.49.2
 
    }
|-
kind: ConfigMap
|colspan="2"|
metadata:
----
  creationTimestamp: "2023-07-04T00:08:54Z"
'''K8s » CoreDNS'''
  name: coredns
----
  namespace: kube-system
|-
  resourceVersion: "300"
|colspan="2"|
  uid: d8eec45d-1452-467f-8861-8811658c773a
<syntaxhighlight lang='bash'>
# minikube update coredns entry for k8s.local
kubectl get configmap coredns -n kube-system -o yaml \
| sed -z "s|${CONFIGMAP_COREDNS_FIND}|$(echo "${CONFIGMAP_COREDNS_FILL}")|" \
| kubectl apply -n kube-system -f -
</syntaxhighlight>
</syntaxhighlight>


Line 97: Line 115:
|-
|-
|valign='top'|
|valign='top'|
<syntaxhighlight lang="properties">
<syntaxhighlight lang="yaml">
cat <<EOF | kubectl apply -n kubernetes-dashboard -f -
cat << YML | kubectl apply -n kubernetes-dashboard -f -
---
apiVersion: networking.k8s.io/v1
apiVersion: networking.k8s.io/v1
kind: Ingress
kind: Ingress
metadata:
metadata:
   name: kubernetes-dashboard
   name: kubernetes-dashboard
  namespace: kubernetes-dashboard
   labels:
   labels:
     helm.sh/chart: kubernetes-dashboard-1.0.0
     app.kubernetes.io/version: 1.0.0
    app.kubernetes.io/managed-by: kubectl
     app.kubernetes.io/name: kubernetes-dashboard
     app.kubernetes.io/name: kubernetes-dashboard
     app.kubernetes.io/instance: kubernetes-dashboard
     app.kubernetes.io/instance: kubernetes-dashboard
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/managed-by: Helm
spec:
spec:
   ingressClassName: nginx
   ingressClassName: nginx
Line 122: Line 141:
                 port:
                 port:
                   number: 80
                   number: 80
EOF
YML
</syntaxhighlight>
</syntaxhighlight>


|valign='top'|
|valign='top'|
<syntaxhighlight lang="properties">
<syntaxhighlight lang="yaml">
cat <<EOF | kubectl delete -n kubernetes-dashboard -f -
cat <<YML | kubectl delete -n kubernetes-dashboard -f -
---
apiVersion: networking.k8s.io/v1
apiVersion: networking.k8s.io/v1
kind: Ingress
kind: Ingress
metadata:
metadata:
   name: kubernetes-dashboard
   name: kubernetes-dashboard
  namespace: kubernetes-dashboard
   labels:
   labels:
     helm.sh/chart: kubernetes-dashboard-1.0.0
     app.kubernetes.io/version: 1.0.0
    app.kubernetes.io/managed-by: kubectl
     app.kubernetes.io/name: kubernetes-dashboard
     app.kubernetes.io/name: kubernetes-dashboard
     app.kubernetes.io/instance: kubernetes-dashboard
     app.kubernetes.io/instance: kubernetes-dashboard
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/managed-by: Helm
spec:
spec:
   ingressClassName: nginx
   ingressClassName: nginx
Line 151: Line 171:
                 port:
                 port:
                   number: 80
                   number: 80
EOF
YML
</syntaxhighlight>
</syntaxhighlight>


Line 217: Line 237:


==Dynamic DNS Script==
==Dynamic DNS Script==
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash" highlight="1,24-27,59-63,78" line>
cat << EVT | sudo tee /etc/network/if-up.d/minikube-ifupdown
cat << EXE | sudo tee /etc/network/if-{up,post-down}.d/minikube-ifupdown >/dev/null
#!/bin/bash
#!/bin/bash
: '
: '
Line 241: Line 261:


function verify_kube(){
function verify_kube(){
   printf -v K8S_JSON '%s' \$(sudo -u \${USER_TARGET} minikube status -o 'json');
   printf -v K8S_JSON '%s' \$(sudo -u \${USER_TARGET} minikube status -o 'json')
   printf -v K8S_REST '%s' \$(echo \${K8S_JSON} | jq -r '.APIServer')
   printf -v K8S_REST '%s' \$(echo \${K8S_JSON} | jq -r '.APIServer')
   printf -v K8S_KUBE '%s' \$(echo \${K8S_JSON} | jq -r '.Kubelet')
   printf -v K8S_KUBE '%s' \$(echo \${K8S_JSON} | jq -r '.Kubelet')
   printf -v K8S_HOST '%s' \$(echo \${K8S_JSON} | jq -r '.Host')
   printf -v K8S_HOST '%s' \$(echo \${K8S_JSON} | jq -r '.Host')
  KUBE_STATUS='Running'
 
   if [[ "\${K8S_HOST}" == "\${KUBE_STATUS}" ]]&&[[ "\${K8S_KUBE}" == "\${KUBE_STATUS}" ]]&&
   if [[ "\${K8S_HOST}" == 'Running' ]]&&
    [[ "\${K8S_REST}" == "\${KUBE_STATUS}" ]]; then verify_addr
    [[ "\${K8S_KUBE}" == 'Running' ]]&&
    [[ "\${K8S_REST}" == 'Running' ]]; then verify_addr
   else silent_exit; fi
   else silent_exit; fi
}
function verify_tool(){
  if [[ -x "\$(command -v jq)" ]]; then verify_kube; else silent_exit; fi
}
}


function verify_mini(){
function verify_mini(){
   if [[ -x "\$(command -v minikube)" ]]&&[[ -x "\$(command -v jq)" ]]; then verify_kube; else silent_exit; fi
   if [[ -x "\$(command -v minikube)" ]]; then verify_tool; else silent_exit; fi
}
}


Line 258: Line 283:
   HOST_ETHERS="\$(ip -j link show | jq -r '.[].ifname'| paste -sd' ' -)"
   HOST_ETHERS="\$(ip -j link show | jq -r '.[].ifname'| paste -sd' ' -)"
   if [[ "\${HOST_ETHERS}" =~ "\${IFACE}" ]]; then verify_mini; else silent_exit; fi
   if [[ "\${HOST_ETHERS}" =~ "\${IFACE}" ]]; then verify_mini; else silent_exit; fi
}
function verify_mode(){
  if [[ "\${MODE}" == 'start' ]]; then verify_link; else verify_mini; fi
}
}


function verify(){
function verify(){
   verify_link
   verify_mode
}
}


Line 285: Line 314:


init
init
EVT
EXE
sudo chmod +x /etc/network/if-up.d/minikube-ifupdown
sudo chmod +x /etc/network/if-{up,post-down}.d/minikube-ifupdown
</syntaxhighlight>
 
==Swiss Knife==
<syntaxhighlight lang="bash">
kubectl -n kube-system run -i --tty --rm nslookup-cli --image=alpine --restart=Never -- sh
apk --update add inetutils-telnet
 
nslookup kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local
nslookup postgresql-hl.postgresql.svc.cluster.local
nslookup minikube-host.internal.svc.cluster.local
nslookup postgresql.postgresql.svc.cluster.local
nslookup redis-headless.redis.svc.cluster.local
nslookup www.k8s.local
</syntaxhighlight>
</syntaxhighlight>


Line 340: Line 382:
----
----
|-
|-
| valign="top" colspan="3" |
<syntaxhighlight lang="bash">
export SYSTEM_RAM_QUOTA=$((3*1024))
export SYSTEM_RAM_LIMIT=$(awk '/^MemTotal:/ {print int($2/1024-3*1024);}' /proc/meminfo)
export SYSTEM_RAM_LIMIT=$(awk -v QUOTA="${SYSTEM_RAM_QUOTA}" '/^MemTotal:/ {print int($2/1024-QUOTA);}' /proc/meminfo)
</syntaxhighlight>
|-
| colspan="3" |
----
|-
| valign="top" colspan="3" |
<syntaxhighlight lang="bash">
bash <(curl -s 'https://cdn.chorke.org/exec/cli/bash/install/minikube/network/ifupdown/1.0.0-ubuntu-22.04.sh.txt')
sudo su -c 'export IFACE=lo;export MODE=stop; /etc/network/if-post-down.d/minikube-ifupdown'
sudo su -c 'export IFACE=lo;export MODE=start;/etc/network/if-up.d/minikube-ifupdown'
</syntaxhighlight>
|-
| colspan="3" |
----
|-
| valign="top" colspan="3" |
<syntaxhighlight lang="bash">
echo 'export IFACE=lo;export MODE=stop; /etc/network/if-post-down.d/minikube-ifupdown'|sudo su
echo 'export IFACE=lo;export MODE=start;/etc/network/if-up.d/minikube-ifupdown'|sudo su
  ls -lah /etc/network/if-{up,post-down}.d/minikube-ifupdown
sudo rm -f /etc/network/if-{up,post-down}.d/minikube-ifupdown
</syntaxhighlight>
|-
| colspan="3" |
----
|-
| valign="top" colspan="3" |
<syntaxhighlight lang="bash">
bash <(curl -s 'https://cdn.chorke.org/exec/cli/bash/install/minikube/network/ifupdown/1.0.0-ubuntu-24.04.sh.txt')
sudo /etc/NetworkManager/dispatcher.d/minikube-ifupdown lo down
sudo /etc/NetworkManager/dispatcher.d/minikube-ifupdown lo up
</syntaxhighlight>
|-
| colspan="3" |
----
|-
| valign="top" |
<syntaxhighlight lang="bash">
CONFIGMAP_COREDNS_FIND=$(cat <<QRY
        }\n\
        cache 30\n\
        loop\n\
        reload\n\
        loadbalance\n\
    }
QRY
)
</syntaxhighlight>
| valign="top" colspan="2" |
| valign="top" colspan="2" |
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo ln -s  /etc/network/if-up.d/minikube-ifupdown /etc/network/if-down.d/minikube-ifupdown
CONFIGMAP_COREDNS_FILL=$(cat <<UPD
sudo rm -f  /etc/network/if-down.d/minikube-ifupdown
${CONFIGMAP_COREDNS_FIND}\n\
    k8s.local:53 {\n\
        errors\n\
        cache 30\n\
        forward . 192.168.49.2\n\
    }
UPD
)
</syntaxhighlight>
</syntaxhighlight>


| valign="top" |
|-
| colspan="3" |
----
|-
| valign="top" colspan="3" |
<syntaxhighlight lang="bash">
kubectl get configmap coredns -n kube-system -o yaml\
| sed -z "s|${CONFIGMAP_COREDNS_FIND}|$(echo "${CONFIGMAP_COREDNS_FILL}")|"
</syntaxhighlight>


|}
|}
Line 373: Line 488:
* [https://stackoverflow.com/questions/66016567 Minikube » Uninstall]
* [https://stackoverflow.com/questions/66016567 Minikube » Uninstall]
* [https://minikube.sigs.k8s.io/docs/handbook/filesync/ Minikube » File Sync]
* [https://minikube.sigs.k8s.io/docs/handbook/filesync/ Minikube » File Sync]
* [[Minikube Systemd|Minikube » Systemd]]
* [https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/ Minikube » Ingress]
* [https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/ Minikube » Ingress]


| valign="top" |
| valign="top" |
* [[Minikube Tunnel|Minikube » Tunnel]]


|-
|-
Line 394: Line 511:


| valign="top" |
| valign="top" |
* [https://github.com/coredns/coredns/issues/2347  K8s » CoreDNS » Configure » Rewrite » Custom DNS]
* [https://audun-nes.medium.com/configure-coredns-as-basic-dns-server-on-your-local-area-network-at-home-e67463b83ba3 CoreDNS » Configure as basic DNS server at Home]
* [https://askubuntu.com/questions/1512141/ Ubuntu » 24.04 » <code>if-up.d</code> doesn't executed]
* [https://stackoverflow.com/questions/19075671/ Bash » Use Shell Variables In An <code>awk</code> Script]
* [https://www.alibabacloud.com/help/en/ack/ack-managed-and-ack-dedicated/user-guide/configure-coredns#:~:text=rewrite%20stop K8s » CoreDNS » Configure » Rewrite]
* [https://coredns.io/plugins/rewrite/ CoreDNS » Plugins » Rewrite]
* [https://www.hostinger.my/tutorials/cron-job Understanding Cron Syntax]
* [https://www.hostinger.my/tutorials/cron-job Understanding Cron Syntax]
* [[Google Cloud CLI]]
* [[Google Cloud CLI]]
* [[Free Up RAM|Free Up RAM]]
* [[AWS CLI]]
* [[AWS CLI]]


| valign="top" |
| valign="top" |
* [https://stackoverflow.com/questions/54509142/ K8s » CoreDNS » Rewrite » Return the rewritten name]
* [https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/ K8s » CoreDNS » Customizing DNS Service]
* [https://github.com/coredns/coredns/blob/master/plugin/rewrite/README.md CoreDNS » Plugins » Rewrite » README]
* [[Swap Space]]


|}
|}

Latest revision as of 21:10, 5 October 2024

minikube stop
minikube delete --all
rm -rf ${HOME}/.minikube/*
minikube start
minikube docker-env
minikube addons list
minikube addons enable ingress
minikube addons enable ingress-dns
minikube addons enable metrics-server

kubectl get ns
kubectl get all
kubectl get all  -A
kubectl get pods -A
kubectl get namespaces
minikube kubectl -- get ns
minikube kubectl -- get all
minikube kubectl -- get all  -A
minikube kubectl -- get pods -A
minikube kubectl -- get namespaces
kubectl get  all -n kube-system
kubectl get  configmap -n kube-system
kubectl get  configmap coredns -n kube-system
kubectl edit configmap coredns -n kube-system
kubectl get  configmap coredns -n kube-system -o yaml

Ingress DNS

# minikube nameserver ip
printf -v MINIKUBE_NSLOOKUP '%s' $(minikube ip)

# minikube find coredns last entry
CONFIGMAP_COREDNS_FIND=$(cat <<QRY
        }\n\
        cache 30\n\
        loop\n\
        reload\n\
        loadbalance\n\
    }
QRY
)
# minikube fill coredns last entry
CONFIGMAP_COREDNS_FILL=$(cat <<UPD
${CONFIGMAP_COREDNS_FIND}\n\
    k8s.local:53 {\n\
        errors\n\
        cache 30\n\
        forward . ${MINIKUBE_NSLOOKUP}\n\
    }
UPD
)

K8s » CoreDNS


# minikube update coredns entry for k8s.local
kubectl get configmap coredns -n kube-system -o yaml \
 | sed -z "s|${CONFIGMAP_COREDNS_FIND}|$(echo "${CONFIGMAP_COREDNS_FILL}")|" \
 | kubectl apply -n kube-system -f -

K8s » Dashboard


cat << YML | kubectl apply -n kubernetes-dashboard -f -
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  labels:
    app.kubernetes.io/version: 1.0.0
    app.kubernetes.io/managed-by: kubectl
    app.kubernetes.io/name: kubernetes-dashboard
    app.kubernetes.io/instance: kubernetes-dashboard
spec:
  ingressClassName: nginx
  rules:
    - host: "www.k8s.local"
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: kubernetes-dashboard
                port:
                  number: 80
YML
cat <<YML | kubectl delete -n kubernetes-dashboard -f -
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
  labels:
    app.kubernetes.io/version: 1.0.0
    app.kubernetes.io/managed-by: kubectl
    app.kubernetes.io/name: kubernetes-dashboard
    app.kubernetes.io/instance: kubernetes-dashboard
spec:
  ingressClassName: nginx
  rules:
    - host: "www.k8s.local"
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: kubernetes-dashboard
                port:
                  number: 80
YML

kubectl run -i --tty --rm debug --image=alpine  --restart=Never -- nslookup www.k8s.local
kubectl run -i --tty --rm debug --image=alpine  --restart=Never -- ping www.k8s.local
nslookup www.k8s.local $(minikube ip)

K8s » DNS Config


RESOLVE='/etc/resolv.conf';\
printf -v K8S_DNS '%s' $(minikube ip);\
if  [ -f ${RESOLVE} ]&&[ "$(grep -c ${K8S_DNS} ${RESOLVE})" == 0 ];then\
 cat << EOF | sudo tee -a ${RESOLVE} >/dev/null

nameserver ${K8S_DNS}
EOF
fi;\
cat ${RESOLVE}

nslookup www.k8s.local
ping www.k8s.local

xdg-open http://www.k8s.local &>/dev/null &
gnome-open http://www.k8s.local &>/dev/null &
x-www-browser http://www.k8s.local &>/dev/null &
sensible-browser http://www.k8s.local &>/dev/null &

Dynamic DNS Script

cat << EXE | sudo tee /etc/network/if-{up,post-down}.d/minikube-ifupdown >/dev/null
#!/bin/bash
: '
 @vendor    Chorke Academia, Inc.
 @web       https://cdn.chorke.org/docs/academia
 @version   1.0.00
 @since     1.0.00
'

USER_TARGET="${USER}"

function silent_exit(){
  exit 0
}

function verify_addr(){
  printf -v DNS_HOST '%s' \$(sudo -u \${USER_TARGET} minikube ip)
  if [[ "\${DNS_HOST}" =~ ^(([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))\.){3}([1-9]?[0-9]|1[0-9][0-9]|2([0-4][0-9]|5[0-5]))$ ]]; then
    if [[ "\${DNS_HOST}" == '127.0.0.1' ]]; then silent_exit; fi
  else silent_exit; fi
}

function verify_kube(){
  printf -v K8S_JSON '%s' \$(sudo -u \${USER_TARGET} minikube status -o 'json')
  printf -v K8S_REST '%s' \$(echo \${K8S_JSON} | jq -r '.APIServer')
  printf -v K8S_KUBE '%s' \$(echo \${K8S_JSON} | jq -r '.Kubelet')
  printf -v K8S_HOST '%s' \$(echo \${K8S_JSON} | jq -r '.Host')

  if [[ "\${K8S_HOST}" == 'Running' ]]&&
     [[ "\${K8S_KUBE}" == 'Running' ]]&&
     [[ "\${K8S_REST}" == 'Running' ]]; then verify_addr
  else silent_exit; fi
}

function verify_tool(){
  if [[ -x "\$(command -v jq)" ]]; then verify_kube; else silent_exit; fi
}

function verify_mini(){
  if [[ -x "\$(command -v minikube)" ]]; then verify_tool; else silent_exit; fi
}

function verify_link(){
  HOST_ETHERS="\$(ip -j link show | jq -r '.[].ifname'| paste -sd' ' -)"
  if [[ "\${HOST_ETHERS}" =~ "\${IFACE}" ]]; then verify_mini; else silent_exit; fi
}

function verify_mode(){
  if [[ "\${MODE}" == 'start' ]]; then verify_link; else verify_mini; fi
}

function verify(){
  verify_mode
}

function amend_nameserver(){
  RESOLV_CONF='/etc/resolv.conf'
  if  [[ -f \${RESOLV_CONF} ]]&&[[ "\$(grep -c \${DNS_HOST} \${RESOLV_CONF})" == 0 ]];then
    cat << CON | sudo tee -a \${RESOLV_CONF} >/dev/null

# minikube dns server
nameserver \${DNS_HOST}
CON
  else silent_exit; fi
}

function handle(){
  amend_nameserver
}

function init(){
  verify
  handle
}

init
EXE
sudo chmod +x /etc/network/if-{up,post-down}.d/minikube-ifupdown

Swiss Knife

kubectl -n kube-system run -i --tty --rm nslookup-cli --image=alpine --restart=Never -- sh
apk --update add inetutils-telnet

nslookup kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local
nslookup postgresql-hl.postgresql.svc.cluster.local
nslookup minikube-host.internal.svc.cluster.local
nslookup postgresql.postgresql.svc.cluster.local
nslookup redis-headless.redis.svc.cluster.local
nslookup www.k8s.local

Playground

minikube status -f '{{.Kubeconfig}}'
minikube status -f '{{.APIServer}}'
minikube status -f '{{.Kubelet}}'
minikube status -f '{{.Worker}}'
minikube status -f '{{.Host}}'
minikube status -o 'json' | jq -r '.Kubeconfig'
minikube status -o 'json' | jq -r '.APIServer'
minikube status -o 'json' | jq -r '.Kubelet'
minikube status -o 'json' | jq -r '.Worker'
minikube status -o 'json' | jq -r '.Host'
ip -j link show | jq -r '.[].ifname'| paste -sd' ' -
ip -j link show type bridge | jq -r '.[].ifname'
ip -o link show | awk -F': ' '{print $2}'
ip -j link show | jq -r '.[].ifname'
ls /sys/class/net

minikube status -f '{{- if .TimeToStop }} timeToStop: {{.TimeToStop}} {{- end }}'
minikube status -f '{{- if .DockerEnv }} docker-env: {{.DockerEnv}} {{- end }}'
minikube status -o 'json' | jq
ip -j link show | jq -r '.[]|select(.link_type=="loopback")'
ip -j link show | jq -r '.[]|select(.link_type=="ether")'
ip -j link show | jq -r '.[]|select(.link_type==null)'

export SYSTEM_RAM_QUOTA=$((3*1024))
export SYSTEM_RAM_LIMIT=$(awk '/^MemTotal:/ {print int($2/1024-3*1024);}' /proc/meminfo)
export SYSTEM_RAM_LIMIT=$(awk -v QUOTA="${SYSTEM_RAM_QUOTA}" '/^MemTotal:/ {print int($2/1024-QUOTA);}' /proc/meminfo)

bash <(curl -s 'https://cdn.chorke.org/exec/cli/bash/install/minikube/network/ifupdown/1.0.0-ubuntu-22.04.sh.txt')
sudo su -c 'export IFACE=lo;export MODE=stop; /etc/network/if-post-down.d/minikube-ifupdown'
sudo su -c 'export IFACE=lo;export MODE=start;/etc/network/if-up.d/minikube-ifupdown'

echo 'export IFACE=lo;export MODE=stop; /etc/network/if-post-down.d/minikube-ifupdown'|sudo su 
echo 'export IFACE=lo;export MODE=start;/etc/network/if-up.d/minikube-ifupdown'|sudo su 
   ls -lah /etc/network/if-{up,post-down}.d/minikube-ifupdown
sudo rm -f /etc/network/if-{up,post-down}.d/minikube-ifupdown

bash <(curl -s 'https://cdn.chorke.org/exec/cli/bash/install/minikube/network/ifupdown/1.0.0-ubuntu-24.04.sh.txt')
sudo /etc/NetworkManager/dispatcher.d/minikube-ifupdown lo down
sudo /etc/NetworkManager/dispatcher.d/minikube-ifupdown lo up

CONFIGMAP_COREDNS_FIND=$(cat <<QRY
        }\n\
        cache 30\n\
        loop\n\
        reload\n\
        loadbalance\n\
    }
QRY
)
CONFIGMAP_COREDNS_FILL=$(cat <<UPD
${CONFIGMAP_COREDNS_FIND}\n\
    k8s.local:53 {\n\
        errors\n\
        cache 30\n\
        forward . 192.168.49.2\n\
    }
UPD
)

kubectl get configmap coredns -n kube-system -o yaml\
 | sed -z "s|${CONFIGMAP_COREDNS_FIND}|$(echo "${CONFIGMAP_COREDNS_FILL}")|"

References