Running your container

Now, let's run the container we just made. We will use the kubectl run command to specify the simplest deployment—just the container:

kubectl run flask --image=quay.io/kubernetes-for-developers/flask:latest --port=5000 --save-config
deployment “flask” created

To see what this is doing, we need to ask the cluster for the current state of the resources we just created. When we use the kubectl run command, it will implicitly create a Deployment resource for us, and as you learned in the last chapter, a Deployment has a ReplicaSet within it, and a Pod within the ReplicaSet:

kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
flask 1 1 1 1 20h
kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-1599974757-b68pw 1/1 Running 0 20h

We can get details on this deployment by asking for the raw data associated with the Kubernetes deployment resource flask:

kubectl get deployment flask -o json

We could just as easily request the information in YAML format, or query a subset of these details leveraging JsonPath or the other capabilities of the kubectl command. The JSON output will be extensive. It will start with a key indicating apiVersion from Kubernetes, the kind of resource, and metadata about the resource:

{
"apiVersion": "extensions/v1beta1",
"kind": "Deployment",
"metadata": {
"annotations": {
"deployment.kubernetes.io/revision": "1"
},
"creationTimestamp": "2017-09-16T00:40:44Z",
"generation": 1,
"labels": {
"run": "flask"
},
"name": "flask",
"namespace": "default",
"resourceVersion": "51293",
"selfLink": "/apis/extensions/v1beta1/namespaces/default/deployments/flask",
"uid": "acbb0128-9a77-11e7-884c-0aef48c812e4"
},

Beneath this is usually the specification of the deployment itself, which has a lot of the core of what is running:

    "spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"run": "flask"
}
},
"strategy": {
"rollingUpdate": {
"maxSurge": 1,
"maxUnavailable": 1
},
"type": "RollingUpdate"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"run": "flask"
}
},
"spec": {
"containers": [
{
"image": "quay.io/kubernetes-for-developers/flask:latest",
"imagePullPolicy": "Always",
"name": "flask",
"ports": [
{
"containerPort": 5000,
"protocol": "TCP"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File"
}
],
"dnsPolicy": "ClusterFirst",
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"terminationGracePeriodSeconds": 30
}
}
},

And the last part is usually the status, which indicates the current state of the deployment, as of the time you made the request for the information:

    "status": {
"availableReplicas": 1,
"conditions": [
{
"lastTransitionTime": "2017-09-16T00:40:44Z",
"lastUpdateTime": "2017-09-16T00:40:44Z",
"message": "Deployment has minimum availability.",
"reason": "MinimumReplicasAvailable",
"status": "True",
"type": "Available"
}
],
"observedGeneration": 1,
"readyReplicas": 1,
"replicas": 1,
"updatedReplicas": 1
}
}

Remember that when a Pod runs in Kubernetes, it is running in a sandbox, isolated from the rest of the world. Kubernetes does this intentionally, so you can specify how Pods are supposed to be connected and what can be accessed from outside the cluster. We will cover how to set up external access in a later chapter. In the meantime, you can leverage one of two commands with kubectl to get direct access from your development machine: kubectl port-forward or kubectl proxy.

These commands both work by making proxies from your local development machine into the Kubernetes cluster, providing you private and personal access to your running code. The port-forward command will open a specific TCP (or UDP) port and arrange all traffic to forward to your Pod in the cluster. The proxy command uses an HTTP proxy that already exists to forward HTTP traffic in and out of your Pod. Both of these commands rely on knowing the Pod name to make the connections.