Table of Contents
Introduction
Right after setting up our Kubernetes cluster, our first thinking will be how to create a pod on it. Let’s see how to create a Kubernetes Pod in this guide. For illustrating purpose we are not going to create a separate namespace, Instead, we will use the default namespace. If you are unaware about what is namespace have a quick read.
In the default namespace of kubernetes cluster we don’t have a pod yet. Let’s start with listing and creating one.
root@k8mas1:~# kubectl get pods
No resources found in default namespace.
root@k8mas1:~#
The above output shows we don’t have a pod.
Creating a Kubernetes Pod in easy way
To create a pod in single command with options and arguments use
root@k8mas1:~# kubectl run nginx-pod --image=nginx
pod/nginx-pod created
root@k8mas1:~#
This will take few seconds to complete creating the pod by downloading its image from docker.io
Let’s list the created Pods
root@k8mas1:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 0/1 ContainerCreating 0 5s
root@k8mas1:~#
root@k8mas1:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 10s
root@k8mas1:~#
To know the pod running on which node, use wide
option with -o
option.
root@k8mas1:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 3m57s 192.168.145.223 k8nod1.linuxsysadmins.local <none> <none>
root@k8mas1:~#
To get more information about the created pod we can use describe
option.
root@k8mas1:~# kubectl describe pods nginx-pod
Name: nginx-pod
Namespace: default
Priority: 0
Node: k8nod1.linuxsysadmins.local/192.168.0.27
Start Time: Sun, 24 May 2020 00:02:22 +0000
Labels: run=nginx-pod
Annotations: cni.projectcalico.org/podIP: 192.168.145.223/32
Status: Running
IP: 192.168.145.223
IPs:
IP: 192.168.145.223
Containers:
nginx-pod:
Container ID: docker://2e413b101b7f121e132cabadf6d543c880a206215d9d907f51be4aad0413aac5
Image: nginx
Image ID: docker-pullable://nginx@sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 24 May 2020 00:02:28 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-f4srz (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-f4srz:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-f4srz
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m45s default-scheduler Successfully assigned default/nginx-pod to k8nod1.linuxsysadmins.local
Normal Pulling 2m44s kubelet, k8nod1.linuxsysadmins.local Pulling image "nginx"
Normal Pulled 2m39s kubelet, k8nod1.linuxsysadmins.local Successfully pulled image "nginx"
Normal Created 2m39s kubelet, k8nod1.linuxsysadmins.local Created container nginx-pod
Normal Started 2m39s kubelet, k8nod1.linuxsysadmins.local Started container nginx-pod
root@k8mas1:~#
Running a Dry Run
Before creating a pod if you need to know what will happen when we run the kubectl run
command it’s possible by adding --dry-run
option. This won’t create the pod instead it will show what will happens.
# kubectl run nginx-pod --image=nginx --dry-run=client
If you need to print the YAML format or JSON format in screen it’s too possible by including -o yaml
or -o json
.
Output in YAML format
root@k8mas1:~# kubectl run nginx-pod --image=nginx --dry-run=client -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: nginx-pod name: nginx-pod spec: containers: - image: nginx name: nginx-pod resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} root@k8mas1:~#
Printing the output in JSON format.
root@k8mas1:~# kubectl run nginx-pod --image=nginx --dry-run=client -o json { "kind": "Pod", "apiVersion": "v1", "metadata": { "name": "nginx-pod", "creationTimestamp": null, "labels": { "run": "nginx-pod" } }, "spec": { "containers": [ { "name": "nginx-pod", "image": "nginx", "resources": {} } ], "restartPolicy": "Always", "dnsPolicy": "ClusterFirst" }, "status": {} } root@k8mas1:~#
Without typing any YAML coding it’s possible to redirect the output to a file by running.
# kubectl run nginx-pod --image=nginx --dry-run=client -o yaml > nginx-pod.yaml
This will create the YAML file as show below.
root@k8mas1:~# cat nginx-pod.yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: nginx-pod name: nginx-pod spec: containers: - image: nginx name: nginx-pod resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} root@k8mas1:~#
This is the easiest way to create a Kubernetes Pod. However, if you need to add more options to the pod it’s better to go with creating in a hard way.
Creating a Kubernetes Pod in a Hard way
To create a pod in a hard way first we need to create with a YAML file. To prepare the YAML file we can use vim or some other IDE. Personally, I use Sublime, Atom and Visual Studio Code. Atom one is very lightweight and handy to me.
Alternatively, as shown above we can create by redirecting the output to a file and then modify as per our need.
I have created a YAML file quickly by using atom.
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: name: web-app spec: containers: - name: web-app-container image: nginx resources: limits: memory: "128Mi" cpu: "500m" ports: - containerPort: 80
Let’s copy paste and create a yaml file in server. To keep the same Syntax while copy paste run cat > my_first_pod.yaml
.
To create the Pod from YAML file run the command kubectl
.
root@k8mas1:~# kubectl create -f my_first_pod.yaml
pod/nginx-pod created
root@k8mas1:~#
To list the pod use the same command as we discussed above.
root@k8mas1:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 55s
root@k8mas1:~#
However, we have another way to list the created pod as well. If you need to know which pods are created using a specific YAML file use the command as follow.
root@k8mas1:~# kubectl get -f my_first_pod.yaml
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 63s
root@k8mas1:~#
For a brief information about the created pod describe with -f
option by pointing the YAML file.
root@k8mas1:~# kubectl describe -f my_first_pod.yaml
Name: nginx-pod
Namespace: default
Priority: 0
Node: k8nod1.linuxsysadmins.local/192.168.0.27
Start Time: Sun, 24 May 2020 00:15:16 +0000
Labels: name=web-app
Annotations: cni.projectcalico.org/podIP: 192.168.145.222/32
Status: Running
IP: 192.168.145.222
IPs:
IP: 192.168.145.222
Containers:
web-app-container:
Container ID: docker://9a1d8adde97ad1d0c0db957f8f913c00f8d3d8278246c96ba04964409d3f7655
Image: nginx
Image ID: docker-pullable://nginx@sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 24 May 2020 00:15:22 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 500m
memory: 128Mi
Requests:
cpu: 500m
memory: 128Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-f4srz (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-f4srz:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-f4srz
Optional: false
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m default-scheduler Successfully assigned default/nginx-pod to k8nod1.linuxsysadmins.local
Normal Pulling 3m59s kubelet, k8nod1.linuxsysadmins.local Pulling image "nginx"
Normal Pulled 3m54s kubelet, k8nod1.linuxsysadmins.local Successfully pulled image "nginx"
Normal Created 3m54s kubelet, k8nod1.linuxsysadmins.local Created container web-app-container
Normal Started 3m54s kubelet, k8nod1.linuxsysadmins.local Started container web-app-container
root@k8mas1:~#
Exposing the Created Kubernetes Pod
Once after creating the pod, we need to reach the web server for that we need to expose the pod by creating a service.
root@k8mas1:~# kubectl create service clusterip nginx-service --tcp 80:80
service/nginx-service created
root@k8mas1:~#
List the created Service.
root@k8mas1:~# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30d
nginx-service ClusterIP 10.101.209.142 <none> 80/TCP 3s
root@k8mas1:~#
To access the Pod list the pod with more information by using -o wide
option.
root@k8mas1:~# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 9m18s 192.168.145.231 k8nod1.linuxsysadmins.local <none> <none>
root@k8mas1:~#
And do a curl to verify the reachability.
root@k8mas1:~# curl http://192.168.145.231
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@k8mas1:~#
Shell access to Pod
To access the shell of any pod use
root@k8mas1:~# kubectl exec nginx-pod -it /bin/bash
root@nginx-pod:/#
root@nginx-pod:/# hostname
nginx-pod
root@nginx-pod:/#
These are the environment variables set inside this Pod.
root@nginx-pod:/# env
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=nginx-pod
PWD=/
NGINX_SVC_PORT_80_TCP=tcp://10.107.251.87:80
NGINX_SVC_PORT=tcp://10.107.251.87:80
PKG_RELEASE=1~buster
HOME=/root
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
NGINX_SVC_SERVICE_PORT=80
NGINX_SVC_PORT_80_TCP_ADDR=10.107.251.87
NGINX_SVC_SERVICE_PORT_80_80=80
NJS_VERSION=0.3.9
TERM=xterm
NGINX_SVC_PORT_80_TCP_PORT=80
SHLVL=1
NGINX_SVC_PORT_80_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PORT=443
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_VERSION=1.17.10
NGINX_SVC_SERVICE_HOST=10.107.251.87
_=/usr/bin/env
root@nginx-pod:/#
Finally, let see how to do a clean up.
Deleting a Kubernetes Pod
To delete the pod we can remove it by running.
root@k8mas1:~# kubectl delete pods nginx-pod
pod "nginx-pod" deleted
root@k8mas1:~#
root@k8mas1:~# kubectl get pods
No resources found in default namespace.
root@k8mas1:~#
Once the pod removed we can’t revert back.
To remove a service or svc.
root@k8mas1:~# kubectl delete service nginx-service
service "nginx-service" deleted
root@k8mas1:~#
That’s it we have successfully completed with creating our first Kubernetes Pod.
Conclusion
Creating a Kubernetes Pod in several ways are discussed above. To get more updates on Kubernetes guides follow us by subscribing to our newsletter.