Create multiple similar pods with different names - kubernetes

I would like to benchmark my system by creating many pods running the same container. I'm using the following example:
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
# https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1 # requesting 1 GPU
How can I run this YAML file multiple times such that a new pod with a different name is created?

Creating several similar objects to benchmark some component in Kubernetes, I would either sed the resources name from some file/template, eg:
#!/bin/sh
# make sure my-bench.yaml resource names are set to/based on PLACEHOLDER_NAME
for count in $(seq 1 10)
do
sed "s|PLACEHOLDER_NAME|bench-$count|" my-bench.yaml | kubectl apply -f-
done
This can be useful when you have lots of objects, keeping your script readable.
When I don't have a lot of yaml to write, I would just use cat, eg:
#!/bin/sh
for count in $(seq 1 10)
do
cat <<EOF | kubectl apply -f-
apiVersion: v1
kind: Pod
metadata:
name: bench-$count
namespace: my-bench-ns
spec:
...
EOF
done
While as suggested by #replicaSets and #karan525: when working with a deployment/replicaset/... you should be able to scale out, adding replicas.

You can use replicas in spec. All pods created will have different names but the container in every one of them will be the same

Your setup is running a bare Kubernetes Pod. This is unusual for a couple of reasons, one of the key ones being that there is only one of it.
In practice you almost always use one of the higher-level objects; most often a Deployment, but occasionally a StatefulSet (if you need persistence or a fixed, ordered naming for the Pods) or a Job (for things that need to run once and then exit).
Both Deployments and StatefulSets support replicas: which do exactly what you want, run multiple identical copies of a Pod. You'll frequently want this for resiliency if nothing else.
apiVersion: apps/v1 # <-- matches kind:
kind: Deployment # <-- not Pod
metadata:
name: cuda-vector-add
spec:
replicas: 3 # <-- add
template:
spec: # <-- same as your existing Pod spec
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
You can use imperative commands like kubectl scale to dynamically change the replicas: value.

Related

What would be the fastest way to generate persistentVolume, persistentVolumeClaim, and storageClass correct yaml file from kubectl?

Two years ago while I took CKA exam, I already have this question. At that time I only could do was to see k8s.io official documentation. Now just curious on generating pv / pvc / storageClass via pure kubectl cli. What I look for is similar to the similar logic as deployment, for example:
$ kubectl create deploy test --image=nginx --port=80 --dry-run -o yaml
W0419 23:54:11.092265 76572 helpers.go:553] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: test
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
resources: {}
status: {}
Or similar logic to run a single pod:
$ kubectl run test-pod --image=nginx --port=80 --dry-run -o yaml
W0419 23:56:29.174692 76654 helpers.go:553] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test-pod
name: test-pod
spec:
containers:
- image: nginx
name: test-pod
ports:
- containerPort: 80
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
So what should I type in order to generate pv / pvc / storageClass yaml? The current only declarative fastest way:
cat <<EOF | kubectl create -f -
<PV / PVC / storageClass yaml goes here>
EOF
Edited: Please note that I look any fast way to generate correct pv / pvc / storageClass template without remembering specific syntax thru cli, and not necessary via kubectl.
There is no kubectl command to create a resource like PV, PVC, and storage class.
From certificate points of view, you have go over k8.io and look for the PV, PVC, and storage class under the task link.
Under task link, most of the YAML will be the same and for now, this is one of the fastest ways in exam.
TL;DR:
Look, bookmark and build index your brain in all yaml files in this Github directory (content/en/examples/pods) before the exam. 100% legal according to CKA curriculum.
https://github.com/kubernetes/website/tree/master/content/en/examples/pods/storage/pv-volume.yaml
Then use this form during exam:
kubectl create -f https://k8s.io/examples/pods/storage/pv-volume.yaml
In case you need edit and apply:
# curl
curl -sL https://k8s.io/examples/pods/storage/pv-volume.yaml -o /your/path/pv-volume.yaml
# wget
wget -O /your/path/pv-volume.yaml https://k8s.io/examples/pods/storage/pv-volume.yaml
vi /your/path/pv-volume.yaml
kubectl apply -f /your/path/pv-volume.yaml
Story:
Actually after look around for my own answer, there's an article floating around that suggest me to bookmark these 100% legal pages:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume
https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#creating-a-cron-job
https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/
Note that:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
kubectl could create objects from URL
Where is the original https://k8s.io pointing to?
What else I could benefit from?
Then after digging up the page above "pods/storage/pv-volume.yaml" code, the link points to:
https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/pods/storage/pv-volume.yaml
Which direct to:
https://github.com/kubernetes/website/tree/master/content/en/examples/pods
So https://k8s.io is a shorten uri as well as a http 301 redirect to https://github.com/kubernetes/website/tree/master/content/en to help the exam candidate easy to produce (not copy-n-paste) in the exam terminal.

Kubernetes Job is not getting terminated even after specifying "activeDeadlineSeconds"

My yaml file
apiVersion: batch/v1
kind: Job
metadata:
name: auto
labels:
app: auto
spec:
backoffLimit: 5
activeDeadlineSeconds: 100
template:
metadata:
labels:
app: auto
spec:
containers:
- name: auto
image: busybox
imagePullPolicy: Always
ports:
- containerPort: 9080
imagePullSecrets:
- name: imageregistery
restartPolicy: Never
The pods are killed appropriately but the job ceases to kill itself post 100 seconds.
Is there anything that we could do to kill the job post the container/pod's functionality is completed.
kubectl version --short
Client Version: v1.6.1
Server Version: v1.13.10+IKS
kubectl get jobs --namespace abc
NAME DESIRED SUCCESSFUL AGE
auto 1 1 26m
Thank you,
The default way to delete jobs after they are done is to use kubectl delete command.
As mentioned by #Erez:
Kubernetes is keeping pods around so you can get the
logs,configuration etc from it.
If you don't want to do that manually you could write a script running in your cluster that would check for jobs with completed status and than delete them.
Another way would be to use TTL feature that deletes the jobs automatically after a specified number of seconds. However, if you set it to zero it will clean them up immediately. For more details of how to set it up look here.
Please let me know if that helped.

how to set different environment variables of Deployment replicas in kubernetes

I have 4 k8s pods by setting the replicas of Deployment to 4 now.
apiVersion: v1
kind: Deployment
metadata:
...
spec:
...
replicas: 4
...
The POD will get items in a database and consume it, the items in database has a column class_name.
now I want one pod only get one class_name's item.
for example pod1 only get item which class_name equals class_name_1, and pod2 only get item which class_name equals class_name_2...
So I want to pass different class_name as environment variables to different Deployment PODs. Can I define it in the yaml file of Deployment?
Or is there any other way to achieve my goal?(like something other than Deployment in k8s)
For distributed job processing Deployments are not very good, because they don't have any type of ordering or consistent pod hostnames. You'd better use StatefulSet for it, because they have consistent naming, like pod-0, pod-1, pod-2. You can rely on that hostname index.
For example, if your class_name_idx - is the index of class name in class names list, num_replicas - is the number of replicas in StatefulSet and pod_idx - is the index of pod in StatefulSet, then pod should run the job only if: class_name_idx % num_replicas == pod_idx.
Unfortunately number of StatefulSet replicas cannot be obtained within the pod dynamically using Downward API, so you can either hardcode it or use Kubernetes API to obtain it from cluster.
Neither Deployment nor anything else won't help to achieve your goal. Your goal is some kind of logic and it should be implemented via code in your application.
Since the Deployment is some instances of the same application the only thing that might be useful for you is: using multiple deployments, each for its own task. The first could get class_name_1 item, while other class_name_2, class_name_3 etc. But it is not a good idea
I would not recommend this approach, but the closest thing to do what you want is using the stateful-set and use the pod name as the index.
When you deploy a stateful set, the pods will be named after their statefulset name, in the following sample:
apiVersion: v1
kind: Service
metadata:
name: kuard
labels:
app: kuard
spec:
type: NodePort
ports:
- port: 8080
name: web
selector:
app: kuard
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kuard
spec:
serviceName: "kuard"
replicas: 3
selector:
matchLabels:
app: kuard
template:
metadata:
labels:
app: kuard
spec:
containers:
- name: kuard
image: gcr.io/kuar-demo/kuard-amd64:1
ports:
- containerPort: 8080
name: web
The pods created by the statefulset will be named as:
kuard-0
kuard-1
kuard-2
This way you could either, name the stateful-set according to the classes, i.e: class-name and the pod created will be class-name-0 and you can replace the _ by -. Or just strip the name out to get the index at the end.
To get the name just read the environment variable HOSTNAME
This naming is consistent, so you can make sure you always have 0, 1, 2, 3 after the name. And if the 2 goes down, it will be recreated.
Like I said, I would not recommend this approach because you tie the infrastructure to your code, and also can't scale(if needed) because each service are unique and adding new instances would get new ids.
A better approach would be using one deployment for each class and pass the proper values as environment variables.

Restart a Successful/Failed pod manually

running kubernetes v1.2.2 on coreos on vmware:
I have a pod with the restart policy set to Never. Is it possible to manually start the same pod back up?
In my use case we will have a postgres instance in this pod. If it was to crash I would like to leave the pod in a failed state until we can look at it closer to see why it failed and then start it manually. Rather than try to restart with a restartpolicy of Always.
Looking through kubectl it doesnt seem like there is a manual start option. I could delete and recreate but i think this would remove the data from my container. Maybe I should be mounting a local volume on my host, and I should not need to worry about losing data?
this is my sample pod yaml. I dont seem to be able to restart the 'health' pod.
apiVersion: v1
kind: Pod
metadata:
name: health
labels:
environment: dev
app: health
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Never
One simple method that might address your needs is to add a unique instance label, maybe a simple counter. If each pod is labelled differently you can start as many as you like and keep around as many failed instances as you like.
e.g. first pod
apiVersion: v1
kind: Pod
metadata:
name: health
labels:
environment: dev
app: health
instance: 0
spec:
containers: ...
second pod
apiVersion: v1
kind: Pod
metadata:
name: health
labels:
environment: dev
app: health
instance: 1
spec:
containers: ...
Based on your question and comments sounds like you want to restart a failed container to retain its state and data. In fact, application containers and pods are considered to be relatively ephemeral (rather than durable) entities. When a container crashes its files will be lost and kubelet will restart it with a clean state.
To retain your data and logs use persistent volume types in your deployment. This will let you to preserve data across container restarts.

Adding pod nodeSelector after creation

Using OpenShift 3.1/K8 1.1 and given a pod that has already been created with/without a nodeSelector.
I.e.
apiVersion: v1
kind: Pod
metadata:
generateName: blah-
labels:
name: blah
spec:
containers:
image: some/image
name: blah-image
ports:
- containerPort: 8080
nodeSelector: # can you add this after this pod has been created?
region: infra
Is it possible to change/add a nodeSelector?
Similar to the way you add/modify labels
You can change it in the associated ReplicationController (if any) but not in the definition of a running Pod. If you edit the RC as suggested the Pod itself must be recreated in order to start on the selected node(s).
In OpenShift if you are using a deployment config (the predecessor to Kube's Deployment object) you can edit your DC and add them. On the cli it's:
oc edit dc/NAME
That will trigger a rolling update that creates a new RC and scales down the old, unlabeled pods.