If you are using Kubernetes then you are likely familiar with the kubectl command. In this post, I would like to cover some of the application management commands it provides and you will encounter. Read on to learn more!
Delete | Describe | Edit | Get | Logs
Let’s start with the easy stuff:
# kubectl <operation> <object> <args> kubectl <delete|describe|edit|get> <configmaps|cronjobs|deployments|jobs|pods|replicasets|services>
The get
operation caught me off guard initially. While it will “get” the object specified, it does not show the objects configuration/output, but instead shows what objects exist. For example:
$ > kubectl get deployments grafana NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE grafana 1 1 1 1 46d
When I was getting started with k8s, I expected the above command to show me the configuration/output of the grafana deployment. As you can see from the above example this is not the case. Looking back on it, the behavior makes sense because if you leave out which object you want then you get all objects found:
$ > kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE grafana 1 1 1 1 46d prometheus-alertmanager 1 1 1 1 46d prometheus-kube-state-metrics 1 1 1 1 46d prometheus-pushgateway 1 1 1 1 46d prometheus-server 1 1 1 1 46d
So how do you get the actual configuration for a given object? By specifying the args -o yaml
$ > kubectl get deployments grafana -o yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: creationTimestamp: 2018-09-26T03:32:34Z generation: 5 labels: app: grafana ...
Also worth mentioning, the describe
command can be invaluable when validating configuration and checking for events that may be impacting your application. Finally, note for pods that you can use the logs
operation to get (by default) all logs from the pod:
kubectl logs pod grafana [--tail=30|-f]
Apply | Create | Delete | Patch
The kubectl
operations specified above assumes you have already deployed something into the k8s namespace you are in. If you wish to perform operations to add/remove configurations within the namespace then you can use something like:
kubectl <apply|create|delete|patch> -f <file>.yaml
You will notice a few things about these operations:
- No
update
— useapply
orcreate
instead update
does notdelete
- You cannot undo a
patch
— in general, useapply
orcreate
instead - Why have
apply
andcreate
?
K8s supports both imperative (create
) and declarative (apply
) management of objects. In general, you probably want apply
as this creates/updates. For more information, see the documentation.
One final thing to note is that you can dynamically pass in configuration. This will become critical as you start integrating k8s into your CI/CD system. For example:
envsubst > .yaml | kubectl apply -f -
Port-forward | Proxy
Now that you know how to create and manipulate objects, the next command to understand is port-forward
:
kubectl port-forward <podName> <localPort>:<sourcePort>
A couple things to note about this command:
- You can
port-forward
to a pod, not a service - If localPort and sourcePort are the same you can just specify one port (
kubectl port-forward <podName> <port>
)
In order to access non-pods (e.g. services), you can use the proxy command:
kubectl proxy
Then you can access resources via the proper URI:
http://localhost:8001/api/v1/namespaces/<namespace>/services/<serviceName>:<port>/proxy/<path>
You do this over the Internet as well assuming the k8s API is exposed. In addition, you can specify credentials to be used when accessing:
$ APISERVER=$(kubectl config view --minify | grep server | cut -f 2- -d ":" | tr -d " ") $ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep ^default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d " ") $ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
Exec
Since we are talking about connecting to applications, the exec
operation can be very handy. It allows you to run commands against an application. For example:
$ > kubectl exec -it grafana-79b4cbd679-6tvvp -- date Sun Nov 11 21:39:52 UTC 2018
You can also run a shell to remote into the pod:
$ > kubectl exec -it grafana-79b4cbd679-6tvvp bash grafana@grafana-79b4cbd679-6tvvp:/$
Note: If you run a command that is not in the PATH then you will get an error. For example, if the system has
sh
but notbash
. If this occurs, update your command accordingly. For CI/CD systems you cannot pass the-t
option. I suggest parameterizing so you can run locally or via CI.
Rollout
As you get to operationalizing your applications, you will eventually encounter other cool kubectl
commands. For example, you can check the status of a rollout:
kubectl rollout status <deployment|daemonsets|statefulsets>
This can be useful in CI/CD systems to confirm rollouts are working as expected. This command can also be used to rollback when issues arise:
kubectl rollout undo <deployment|daemonsets|statefulsets> <name> [--to-revision=2]
In fact, you can pause
and resume
a rollout as well as see the rollout history:
$ kubectl rollout history deployment.v1.apps/nginx-deployment deployments "nginx-deployment" REVISION CHANGE-CAUSE 1 kubectl create --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true 2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true 3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
Summary
As you can see, the kubectl
command is very powerful. This post covered some of the commands you will likely encounter, but only scratches the service of what is possible (e.g. if you are a cluster administrator, you will be interested in the cluster management options not covered in this post). For a complete list of all available commands see the documentation.
© 2018, Steve Flanders. All rights reserved.