Pods

A pod is the smallest deployable unit in Kubernetes. It can contain one or more containers. Most of the time, we just need one container per pod. In some special cases, more than one container is included in the same pod, such as sidecar containers (http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html). Containers in the same pod run in a shared context, on the same node, sharing the network namespace and shared volumes. Pods are also designed as mortal. When a pod dies for some reason, for example, if it's killed by Kubernetes controller if resources are lacking, it won't recover by itself. Instead, Kubernetes uses controllers to create and manage the desired state of pods for us.

We can use kubectl explain <resource> to get the detailed description of the resource by the command line. This will show the fields that the resource supports:

// get detailed info for `pods`
# kubectl explain pods
KIND: Pod
VERSION: v1

DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.

FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status

In the following example, we'll show how to create two containers in a pod, and demonstrate how they access each other. Please note that this is neither a meaningful nor a classic sidecar pattern example. Instead, it's just an example of how we can access other containers within a pod:

// an example for creating co-located and co-scheduled container by pod
# cat 3-2-1_pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
containers:
- name: web
image: nginx
- name: centos
image: centos
command: ["/bin/sh", "-c", "while : ;do curl http://localhost:80/; sleep 10; done"]

The following diagram shows the relationship between containers in a Pod. They share the same network namespace:

Containers inside a pod are visible via localhost

This spec will create two containers, web and centos. Web is an nginx container (https://hub.docker.com/_/nginx/). The container port 80 is exposed by default. Since centos shares the same context as nginx, when using curl in http://localhost:80/, it should be able to access nginx.

Next, use the kubectl create command to launch the pod. The -f argument allows us to feed a configuration file to the kubectl command and creates the desired resources specified in the file:

// create the resource by `kubectl create` - Create a resource by filename or stdin
# kubectl create -f 3-2-1_pod.yaml pod "example" created
If we add --record=true at the end of the kubectl command when we create the resources, Kubernetes will add the latest command while creating or updating this resource. Therefore, we won't forget which resources are created by which spec.

We can use the kubectl get <resource> command to get the current status of the object. In this case, we use the kubectl get pods command:

// get the current running pods 
# kubectl get pods
NAME READY STATUS RESTARTS AGE
example 0/2 ContainerCreating 0 1s
Adding --namespace=$namespace_name allows us to access the object in different namespaces. The following is an example of how to check the pods in the kube-system namespace, which is used by system-type pods:
// list pods in kube-system namespace
# kubectl get pods --namespace=kube-system
NAME                            READY STATUS RESTARTS AGE
coredns-99b9bb8bd-p2dvw               1/1 Running 0 1m
etcd-minikube                         1/1 Running 0 47s
kube-addon-manager-minikube           1/1 Running 0 13s
kube-apiserver-minikube               1/1 Running 0 38s
kube-controller-manager-minikube      1/1 Running 0 32s
kube-proxy-pvww2                      1/1 Running 0 1m
kube-scheduler-minikube               1/1 Running 0 26s
kubernetes-dashboard-7db4dc666b-f8b2w 1/1 Running 0 1m
storage-provisioner                   1/1 Running 0 1m

The status of our example pod is ContainerCreating. In this phase, Kubernetes has accepted the request and is trying to schedule the pod and pull down the image. Zero containers are currently running. 

Most objects have short names, which come in handy when we use kubectl get <object> to list their status. For example, pods could be called po, services could be called svc, and deployment could be called deploy. Type kubectl get to know more. Alternatively, the kubectl api-resources command could list all resources with their short names and attributes. 

After waiting a moment, we could get the status again:

// get the current running pods
# kubectl get pods
NAME READY STATUS RESTARTS AGE
example 2/2 Running 0 3s

We can see that two containers are currently running. The uptime is three seconds. Using kubectl logs <pod_name> -c <container_name> gets stdout for the container, similar to docker logs <container_name>:

// get stdout for centos
# kubectl logs example -c centos
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

centos in the pod shares the same networking with nginx via localhost. Kubernetes creates a network container along with the pod. One of the functions in the network container is to forward the traffic between containers within a pod. We'll learn more about this in Chapter 6Kubernetes Network.

If we specify labels in the pod spec, we could use the kubectl get pods -l <requirement> command to get the pods that satisfy the requirements, for example, kubectl get pods -l 'tier in (frontend, backend)'. Additionally, if we use kubectl pods -o wide, this will list which pods are running on which nodes.

We could use kubectl describe <resource> <resource_name> to get detailed information about a resource:

// get detailed information for a pod
# kubectl describe pods example Name: example
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/10.0.2.15
Start Time: Sun, 07 Oct 2018 15:15:36 -0400
Labels: <none>
Annotations: <none>
Status: Running
IP: 172.17.0.4
Containers: ...

At this point, we know which node this pod is running on. In minikube, we only get a single node so it won't make any difference. In the real cluster environment, knowing which node the pod is running on is useful for troubleshooting. We haven't associated any labels, annotations, or controllers for it:

  web:
Container ID: docker://d8284e14942cbe0b8a91f78afc132e09c0b522e8a311e44f6a9a60ac2ca7103a
Image: nginx
Image ID: docker-pullable://nginx@sha256:9ad0746d8f2ea6df3a17ba89eca40b48c47066dfab55a75e08e2b70fc80d929e
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 07 Oct 2018 15:15:50 -0400
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-bm6vn (ro)

In the containers section, we'll see there are two containers included in this pod. We can see their states, source images, port mappings, and restart count:

Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True

A pod has PodStatus, which includes a map of array representations as PodConditions. The possible types of PodConditions are PodScheduled, Ready, InitializedUnschedulable, and ContainersReady. The value will be true, false, or unknown. If the pod isn't created accordingly, PodStatus will give us a brief overview of which part failed. In the preceding example, we launched the pod successfully in each phase without any errors:

Volumes:
default-token-bm6vn:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-bm6vn
Optional: false

A pod is associated with a service account that provides an identity for processes that are running the pod. It's controlled by service account and a token controller in the API Server.

It'll mount a read-only volume to each container under /var/run/secrets/kubernetes.io/serviceaccount in a pod that contains a token for API access. Kubernetes creates a default service account. We can use the kubectl get serviceaccounts command to list the service accounts:

QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s

We don't assign any selectors to this pod yet. Toleration is used to restrict how many pods a node can use. We'll learn more about this in Chapter 8Resource Management and Scaling:

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m22s default-scheduler Successfully assigned default/example to minikube
Normal Pulling 2m21s kubelet, minikube pulling image "nginx"
Normal Pulled 2m8s kubelet, minikube Successfully pulled image "nginx"
Normal Created 2m8s kubelet, minikube Created container
Normal Started 2m8s kubelet, minikube Started container
Normal Pulling 2m8s kubelet, minikube pulling image "centos"
Normal Pulled 93s kubelet, minikube Successfully pulled image "centos"
Normal Created 92s kubelet, minikube Created container
Normal Started 92s kubelet, minikube Started container

By seeing the events, we can identify the steps required for Kubernetes to run a node. First, the scheduler assigns the task to a node, which here is called minikube. Then, kubelet starts pulling the first image and creates a container accordingly. After that, kubelet pulls down the second container and starts the container.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset