Can somene explain the different Kubernetes yaml files and types? - kubernetes

First off, I'm completely new with Kubernetes so I may have missed something completely obvious but the documentation is exactly helping, so I'm turning to you guys for help.
I'm trying to figure out just how many types of "deployment files" there are for Kubernetes. I call them "deployment files" because I really don't know what else to call them and they're usually associated with a deployment.
So far, every yml/yaml file I've seen start like this:
apiVersion:
kind: << this is what I'm asking about >>
metadata:
And so far I have seen this many "kind"(s)
ClusterConfig
ClusterRole
ClusterRoleBinding
CronJob
Deployment
Job
PersistentVolumeClaim
Pod
ReplicationController
Role
RoleBinding
Secret
Service
ServiceAccount
I'm sure there are many more. But I can't seem to find a location where they are listed and the contexts broken down.
So what I want to know is this,
Where can I find an explanation for these yaml files?
Where can I learn about the different kinds?
Where can I get a broken down explanation of the minimum required fields/values are for any of these?
Are there templates for these files?
Thanks

This question will need a blog to answer but still in short you can try these options and command to learn from your kubectl CLI.
Learn to use kubectl explain command which shows you a list of Kubernetes objects:
$ kubectl explain
You can get detailed information about any of listed resources using this syntax
`$ kubectl explain pod
$ kubectl explain pod.spec
$ kubectl explain pod.spec.containers`
Or you can get yam template of the object by adding --recursive flag to explain command.
$ kubectl explain pod --recursive
This will also give you official document link.
So in short running kubectl explain with recursive option will list every thing.

When you are talking about specific yaml file containing the definition of specific kubernetes object, you can call them yaml manifests or simply yaml definition files. Using word Deployment for all of them isn't a good idea as there is already specific resource type defined and called by this name in kubernetes. So it's better you don't call them all deployments for consistency.
I'm sure there are many more. But I can't seem to find a location
where they are listed and the contexts broken down.
Yes, there are a lot more of them and you can list those which are available by running:
kubectl api-resources
These different objects are actually called api-resources. As you can see they are listed in three columns: NAME, SHORTNAMES, APIGROUP, NAMESPACED and KIND
NAME SHORTNAMES APIGROUP NAMESPACED KIND
bindings true Binding
componentstatuses cs false ComponentStatus
configmaps cm true ConfigMap
endpoints ep true Endpoints
events ev true Event
limitranges limits true LimitRange
namespaces ns false Namespace
nodes no false Node
Note that the name of resource corresponds to its KIND but it is slightly different. NAME simply describes resource types as we are referring to them e.g. using kubectl command line utility. Just to give one example, when you want to list pods available in your cluster you simply type kubectl get pods. You don't have to use resource kind i.e. Pod in this context. You can but you don't have to. So kubectl get Pod or kubectl get ConfigMap will also return desired result. You can also refer to them by their shournames so kubectl get daemonsets and kubectl get ds are equivalent.
It's totally different when it comes to specific resource/object definition. In context of yaml definition file we must to use proper KIND of the resource. They are mostly start with capital letter and are written by co called CamelCase but there are exceptions from this rule.
I really recommend you to familiarize with kubernetes documentation. It is very user-friendly and nicely explains both key kubernetes concepts as well as all very tiny details.
Here you have even more useful commands for exploring API resources:
kubectl api-resources --namespaced=true # All namespaced resources
kubectl api-resources --namespaced=false # All non-namespaced resources
kubectl api-resources -o name # All resources with simple output (just the resource name)
kubectl api-resources -o wide # All resources with expanded (aka "wide") output
kubectl api-resources --verbs=list,get # All resources that support the "list" and "get" request verbs
kubectl api-resources --api-group=extensions # All resources in the "extensions" API group
As #wargre already suggested in his comment, kubernetes official documentetion is definitely the best place to start as you will find there very detailed description of every resource.

Understanding Kubernetes Objects
You may start from reading this article: Understanding Kubernetes Objects
Kubernetes Objects are persistent entities in the Kubernetes system. Kubernetes uses these entities to represent the state of your cluster. Specifically, they can describe:
What containerized applications are running (and on which nodes)
The resources available to those applications
The policies around how those applications behave, such as restart policies, upgrades, and fault-tolerance
A Kubernetes object is a “record of intent”–once you create the object, the Kubernetes system will constantly work to ensure that object exists. By creating an object, you’re effectively telling the Kubernetes system what you want your cluster’s workload to look like; this is your cluster’s desired state.
K8s API reference
A detailed description of all objects can be found in the Kubernetes API reference guide.

Related

What is `deployment.apps` in Kubernetes?

I am surprised that nobody has yet asked this, but what exactly is deployment.apps?
I see it often in commands e.g
kubectl rollout pause deployment.apps/nginx-deployment
or even used interchangably for the deployments keyword:
kubectl get deployments= kubectl get deployment.apps
I do not understand what it indicates though. Even in K8s official docs, they just take for granted that the reader understands the term.
Could someone please explain it to me?
Kubernetes API has its different resources (e.g. Pods, Deployments, Ingress) grouped in what they call "api groups" and in the notation deployment.apps - "deployment" is the resource name and the "apps" is the api group name.
Also see the motivation for API groups

Find usage of ServceAccount in Kubernates cluster

I am running a Kubernates Cluster in bare metal of three nodes.
I have applied a couple of yaml files of different services.
Now I would like to make order in the cluster and clean some orphaned kube objects.
To do that I need to understand the set of pods or other entities which use or refer a certain ServiceAccount.
For example, I can dig ClusterRoleBinding of the, say, admin-user and investigate it:
kubectl get сlusterrolebinding admin-user
But is there a good kubectl options combination to find all the usages/references of some ServiceAccount?
You can list all resources using a service account with the following command:
kubectl get rolebinding,clusterrolebinding --all-namespaces -o jsonpath='{range .items[?(#.subjects[0].name=="YOUR_SERVICE_ACCOUNT_NAME")]}[{.roleRef.kind},{.roleRef.name}];{end}' | tr ";" "\n"
You just need to replace YOUR_SERVICE_ACCOUNT_NAME to the one you are investigating.
I tested this command on my cluster and it works.
Let me know if this solution helped you.
Take a look at this project. After installing via homebrew or krew you can use it find a service account and look at its role, scope, source. It does not tell which pods are referring to it but still a useful tool.
rbac-lookup serviceaccountname --output wide --kind serviceaccount

Manually creating and editing Kubernetes objects

Most Kubernetes objects can be created with kubectl create, but if you need e.g. a DaemonSet — you're out of luck.
On top of that, the objects being created through kubectl can only be customized minimally (e.g. kubectl create deployment allows you to only specify the image to run and nothing else).
So, considering that Kubernetes actually expects you to either edit a minimally configured object with kubectl edit to suit your needs or write a spec from scratch and then use kubectl apply to apply it, how does one figure out all possible keywords and their meanings to properly describe the object they need?
I expected to find something similar to Docker Compose file reference, but when looking at DaemonSet docs, I found only a single example spec that doesn't even explain most of it's keys.
The spec of the resources in .yaml file that you can run kubectl apply -f on is described in Kubernetes API reference.
Considering DeamonSet, its spec is described here. It's template is actually the same as in Pod resource.

Editing Kubernetes pod on-the-fly

For the debug and testing purposes I'd like to find a most convenient way launching Kubernetes pods and altering its specification on-the-fly.
The launching part is quite easy with imperative commands.
Running
kubectl run nginx-test --image nginx --restart=Never
gives me exactly what I want: the single pod not managed by any controller like Deployment or ReplicaSet. Easy to play with and cleanup when it needed.
However when I'm trying to edit the spec with
kubectl edit po nginx-test
I'm getting the following warning:
pods "nginx-test" was not valid:
* spec: Forbidden: pod updates may not change fields other than spec.containers[*].image, spec.initContainers[*].image, spec.activeDeadlineSeconds or spec.tolerations (only additions to existing tolerations)
i.e. only the limited set of Pod spec is editable at runtime.
OPTIONS FOUND SO FAR:
Getting Pod spec saved into the file:
kubectl get po nginx-test -oyaml > nginx-test.yaml
edited and recreated with
kubectl apply -f
A bit heavy weight for changing just one field though.
Creating a Deployment not single Pod and then editing spec section in Deployment itself.
The cons are:
additional API object needed (Deployment) which you should not forget to cleanup when you are done
the Pod names are autogenerated in the form of nginx-test-xxxxxxxxx-xxxx and less
convenient to work with.
So is there any simpler option (or possibly some elegant workaround) of editing arbitrary field in the Pod spec?
I would appreciate any suggestion.
You should absolutely use a Deployment here.
For the use case you're describing, most of the interesting fields on a Pod cannot be updated, so you need to manually delete and recreate the pod yourself. A Deployment manages that for you. If a Deployment owns a Pod, and you delete the Deployment, Kubernetes knows on its own to delete the matching Pod, so there's not really any more work.
(There's not really any reason to want a bare pod; you almost always want one of the higher-level controllers. The one exception I can think of is kubectl run a debugging shell inside the cluster.)
The Pod name being generated can be a minor hassle. One trick that's useful here: as of reasonably recent kubectl, you can give the deployment name to commands like kubectl logs
kubectl logs deployment/nginx-test
There are also various "dashboard" type tools out there that will let you browse your current set of pods, so you can do things like read logs without having to copy-and-paste the full pod name. You may also be able to set up tab completion for kubectl, and type
kubectl logs nginx-test<TAB>

kubernetes - kubectl run vs create and apply

I'm just getting started with kubernetes and setting up a cluster on AWS using kops. In many of the examples I read (and try), there will be commands like:
kubectl run my-app --image=mycompany/myapp:latest --replicas=1 --port=8080
kubectl expose deployment my=app --port=80 --type=LoadBalancer
This seems to do several things behind the scenes, and I can view the manifest files created using kubectl edit deployment, and so forth However, i see many examples where people are creating the manifest files by hand, and using commands like kubectl create -f or kubectl apply -f
Am I correct in assuming that both approaches accomplish the same goals, but that by creating the manifest files yourself, you have a finer grain of control?
Would I then have to be creating Service, ReplicationController, and Pod specs myself?
Lastly, if you create the manifest files yourself, how do people generally structure their projects as far as storing these files? Are they simply in a directory alongside the project they are deploying?
The fundamental question is how to apply all of the K8s objects into the k8s cluster. There are several ways to do this job.
Using Generators (Run, Expose)
Using Imperative way (Create)
Using Declarative way (Apply)
All of the above ways have a different purpose and simplicity. For instance, If you want to check quickly whether the container is working as you desired then you might use Generators .
If you want to version control the k8s object then it's better to use declarative way which helps us to determine the accuracy of data in k8s objects.
Deployment, ReplicaSet and Pods are different layers which solve different problems.All of these concepts provide flexibility to k8s.
Pods: It makes sure that related containers are together and provide efficiency.
ReplicaSet: It makes sure that k8s cluster has desirable replicas of the pods
Deployment: It makes sure that you can have different version of Pods and provide the capability to rollback to the previous version
Lastly, It depends on use case how you want to use these concepts or methodology. It's not about which is good or which is bad.
There is a little more nuance to the difference between apply and create than what is already mentioned here. Kubectl create can be used imperatively on the command line or declaratively against a manifest file.
Kubectl apply is used declaratively against a manifest file. You can't use kubectl apply imperatively.
One key difference is when you already have an object and you want to update something. Even if you used a manifest file with kubectl create, you will get an error when you use kubectl create again to update the same resource. But, if you use kubectl apply, you will not get an error. It will update the resource without any issues.
So, the convention is to use kubectl apply to create AND update resources, kubectl create is used to create resources, and kubectl run is used to create a pod with a specific image, namespace, etc. for experimentation and testing with the --dry-run=client option.