It is possible to create a service that only points to a pod, created by a statefulset?
The solutions that make me would be:
Put as a provider on behalf of the pod.
Dynamic labels with the name of the pod.
As per Kubernetes 1.9 you can use: statefulset.kubernetes.io/pod-name
From the documentation:
"When the StatefulSet controller creates a Pod, it adds a label,
statefulset.kubernetes.io/pod-name, that is set to the name of the
Pod. This label allows you to attach a Service to a specific Pod in
the StatefulSet."
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-name-label
You can use the ordinal value of statefulset pod to label a pod.
I would use kubectl in initContainer to label the pods from within the pods created by statefulset and use that label in service selector spec.
example init container:
initContainers:
- name: set-label
image: lachlanevenson/k8s-kubectl:v1.8.5
command:
- sh
- -c
- '/usr/local/bin/kubectl label pod $POD_NAME select-id=${HOSTNAME##*-} --server=https://kubernetes.default --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt -n $POD_NAMESPACE'
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
example service selector:
selector:
app: my-app
select-id: <0|1|2 ordinal value>
Related
I want to run Python code inside a pod. The pod is created by airflow that I don't control.
I want to somehow get the name of the pod I'm running in.
How can it be done?
You can tell kuberenetes to mount an env variable for you:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
and then in python you can access it like:
import os
pod_name = os.environ['MY_POD_NAME']
Or you can just open and read /etc/hostname:
f = open('/etc/hostname')
pod_name = f.read()
f.close()
Exposing Pod and Cluster Vars to Containers
Lets say you need some data about Pod or K8s environment in your application to add Pod informnation as metada tp logs. such as e.g.
Pod IP
Pod Name
Service Account of Pod
NOTE: All Pod information can be made available in the config file.
There are 2 ways to expose Pod fields into a running Container:
Environment Variables
Volume Files
Example of Environment Variable
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-env
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- name: log-sider
image: busybox
command: [ 'sh', '-c' ]
args:
- while true; do
echo sync app logs;
printenv POD_NAME POD_IP POD_SERVICE_ASCCOUNT;
sleep 20;
done;
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: POD_SERVICE_ASCCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
Kubernets Docs
Source
one way can be
So in the Kubernetes cluster you are operating in do
kubectl get pods
now see the yaml of all pods by
oc get pods <pod-name> -o yaml
then in that find the container images being used by the pods .
identify the image tag that belongs to your container creation.
That means that when you build you image , image has a name and a tag , which is further pushed to some cloud hub from where your pod will pull the image and start the container .
you need to find the image tag and name in pod yaml using the above commands given .
Try the below :
# List all pods in all namespaces
kubectl get pods --all-namespaces
# List all pods in the current namespace
kubectl get pods -o wide
Then u can see more details using the below :
kubectl describe pod <pod-name>
Also you can refer to the following stackoverflow question and the related answers.
get-current-pod
I have a kubernetes service, written in Go, and am using client-go to access the kubernetes apis.
I need the Pod of the service's own pod.
The PodInterface allows me to iterate all pods, but what I need is a "self" concept to get the currently running pod that is executing my code.
It appears by reading /var/run/secrets/kubernetes.io/serviceaccount/namespace and searching pods in the namespace for the one matching hostname, I can determine the "self" pod.
Is this the proper solution?
Expose the POD_NAME and POD_NAMESPACE to your pod as environment variables. Later use those values to get your own pod object.
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_POD_NAME MY_POD_NAMESPACE;
sleep 10;
done;
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: Never
Ref: environment-variable-expose-pod-information
I have installed kubernetes on my VM. And I run my application inside pod on kubernetes.
Now I want to get IP address of my VM in my application which is running inside pod.
Is there any way to do this?
Here's how you can get the host IP:
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
command: ["ash","-c","echo $MY_HOST_IP && sleep 3600"]
env:
- name: MY_HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
kubectl logs busybox will print you the IP.
Yes, it is possible to get the host ip and the hostname from the pod running on a specific node. Use the below variable to get those values
spec.nodeName - the name of the node to which the scheduler always attempts to schedule the pod
status.hostIP - the IP of the node to which the Pod is assigned
following link would be helpful --> https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/
I have an application that has 3 pods and each pod needs a fixed variable name stored in each pod. So if everything is running fine, the three pods would have var1, var2, and var3 stored on the corresponding pods.
If the first pod gets replaced which has var1, how can I determine that the other 2 pods have var2 and var3, and thus know that the new pod should be assigned var1?
Can this be done with Stateful Sets?
I see two ways of doing that:
Using StatefulSets:
For a StatefulSet with N replicas, each Pod in the StatefulSet will be
assigned an integer ordinal, from 0 up through N-1, that is unique
over the Set.
Creating the Pods manually. Example:
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-3
namespace: mem-example
spec:
containers:
- name: memory-demo-3-ctr
image: polinux/stress
If you need your application to be aware of the Pod where it is running on, there is an interesting page in Kubernetes documentation: "Expose Pod Information to Containers Through Environment Variables".
Example:
apiVersion: v1
kind: Pod
metadata:
name: mypod-var1
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
Using a StatefulSet you can extract this from the pod-name.
env:
- name: podname
valueFrom:
fieldRef:
fieldPath: metadata.name
and then get it from the end of the name. The pods in a StatefulSet will be named <StatfulSetName>-<ordinal>, see pod-identity
I'm currently using Kubernetes to schedule a DaemonSet on both master and worker nodes.
The DaemonSet definition is the same for both node types (same image, same volumes, etc), the only difference is that when the entrypoint is executed, I need to write a different configuration file (which is generated in Python with some dynamic values) if the node is a master or a worker.
Currently, to overcome this I'm using two different DaemonSet definitions with an env value which tells if the node is a master or not. Here's the yaml file (only relevant parts):
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: worker-ds
namespace: kube-system
labels:
k8s-app: worker
spec:
...
spec:
hostNetwork: true
containers:
- name: my-image
...
env:
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: IS_MASTER
value: "false"
...
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: master-ds
namespace: kube-system
labels:
k8s-app: master
spec:
...
spec:
hostNetwork: true
nodeSelector:
node-role.kubernetes.io/master: ""
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: my-image
...
env:
- name: NODE_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: IS_MASTER
value: "true"
...
However, since the only difference is the IS_MASTER value, I want to collapse both the definitions in a single one that programmatically understands if the current node where the pod is being scheduled is a master or a worker.
Is there any way to know this information about the node programmatically (even reading a configuration file [for example something that only the master has or viceversa] in the node or something like that)?
Thanks in advance.
Unfortunately, there is not a convenient way to access the node information in pod.
If you only want a single DaemonSet definition, you can add a sidecar container to your pod, the sidecar container can access the k8s api, then your main container can get something useful from the sidecar.
By the way, I think your current solution is properly :)
You can tell a node is the master if it has the label node-role.kubernetes.io/master: "".
What you need to do is access that label from your containers which can be done with the Downward Api (Edit: Wrong, only Pod information can be accessed from the Downward Api). You can mount the labels inside your containers using:
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
You can then search the content of that file from within the container.