InsideDarkWeb.com

How do you get the external ip-address from inside a running Pod in a Kubernetes cluster?

Some services require their external ip-address as provided by a loadbalancer-object like Metallb at runtime (say for example an LHOST or pasv_address).

Let’s say you have build an image based on Alpine:latest. Attached to the pod, there seems to be no way internal of the running Pod to know which ip-address was assigned to the it by the loadbalancer,

so how do you do get the external ip-address from inside a running Pod in a Kubernetes cluster?

Server Fault Asked by wandawata on November 14, 2021

1 Answers

One Answer

And here I'll save you hours of research:

The trick is to use the API provided by the control node in the cluster (which if you are experimenting, is probably the minikube virtualbox vm or a docker container). You can access it as follows:

First create a serviceaccount with which you will gain access to the kubernetes control plane API (the name pod-service-access is completely arbitrary btw):

 kubectl create serviceaccount pod-service-access

Alternatively, you can also create a serviceaccount by applying the following yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-service-access
  namespace: default

Then apply the following ClusterRole and Rolebinding yaml, which will assign permissions to the serviceaccount and bind it to a clusterrole. As you can see, the serviceaccount pod-service-access has read only access to all services in the 'default' namespace. Which is desirable (I presume).

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-services
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "watch", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-services
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: read-services
subjects:
- kind: ServiceAccount
  name: pod-service-access
  namespace: default

Now you will have to assign the serviceaccount to a deployment, so when the deploynment will spawn pods, these running pods will access the control node api with the permissions of the useraccount. This is an example deployment, pay particular attention the the "serviceAccount: pod-service-access" line and don't forget to install the packages "jq" and "curl" when you build the dockerimage:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vsftpd
  labels:
    app: vsftpd
spec:
  selector:
    matchLabels:
      app: vsftpd
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: vsftpd
    spec:
      serviceAccount: pod-service-access
      containers:
      - image: vsftpd-alpine:v1
        imagePullPolicy: Never
        name: vsftpd
        ports:
        - containerPort: 21
          hostPort: 21
        - containerPort: 21000
          hostPort: 21000
        volumeMounts:
        - name: vsftpd-persistent-storage
          mountPath: /data
        - name: cluster-authentication
          mountPath: /auth
        - name: varlog
          mountPath: /var/log
        - name: certificate
          mountPath: /cert
      volumes:
      - name: vsftpd-persistent-storage
        persistentVolumeClaim:
          claimName: vsftpd-pv-claim
      - name: cluster-authentication
        secret:
          secretName: cluster-authentication
      - name: certificate
        secret:
          secretName: vsftpd-cert
      - name: varlog
        emptyDir: {}

Now, when you have your deployment spawning fresh pods, you'll be able to access the kubernetes control node api. Here is a script which will pull information for the service 'vsftpd' from the api (important: here I assume your service name is the same as your deployment name, as can be seen in the SERVICE= line), and by some jq (json processor) magic extracts the external ip:

#!/bin/sh
# Point to the internal API server hostname
APISERVER=https://kubernetes.default.svc

# Path to ServiceAccount token
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount

# Read this Pod's namespace
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)

# Read the ServiceAccount bearer token
TOKEN=$(cat ${SERVICEACCOUNT}/token)

# Reference the internal certificate authority (CA)
CACERT=${SERVICEACCOUNT}/ca.crt

SERVICE=$(echo $HOSTNAME | cut -d- -f1)

# Explore the API with TOKEN
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/$NAMESPACE/services/$SERVICE/ 2>/dev/null| jq -r '.status | .loadBalancer | .ingress | .[] | .ip'

exit $?

Good luck with ft_services from Codam (ja toch).

Answered by wandawata on November 14, 2021

Add your own answers!

Related Questions

Error while mounting partition with Live CD

1  Asked on January 21, 2021 by sat

     

logrotate not rotating the logs

4  Asked on January 21, 2021 by carmen

 

How to troubleshoot GRE tunnel issues?

1  Asked on January 21, 2021 by linux911

     

Dell PowerEdge R430 iDRAC8 snmp OIDs for hardware

1  Asked on January 20, 2021 by alex_90

 

Snort in KVM machines

1  Asked on January 20, 2021 by emilio-macias

   

check_nrpe: ssocket time out after 10 seconds

1  Asked on January 19, 2021 by suganya

       

Curl verify certificate improperly

1  Asked on January 19, 2021 by jitesh-t

         

Choose best raid for SAN storage

0  Asked on January 19, 2021 by gkaveh

     

Windows to Linux Ping not working while Telnet works

1  Asked on January 17, 2021 by ehsan-sajjad

       

Configuring Heartbeat to run shell script

1  Asked on January 17, 2021 by alessandro-cardoso

         

Ask a Question

Get help from others!

© 2021 InsideDarkWeb.com. All rights reserved.