Server Fault Asked by wandawata on November 14, 2021
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?
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP