How to Create a Kubernetes Pod

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.

Leave a Comment

Subscribe To Our Newsletter

Subscribe To Our Newsletter

Join our mailing list to receive the latest news and updates from our team.

We promise not to spam you, and we don't usually send more than one email a week.

You have Successfully Subscribed!