I saw generators except run-pod/v1 are deprecated in kubectl run. Previously, it was convenient to create deployments without creating a YAML file for testing purposes, wondering why it is deprecated?
From the Changelog:
All kubectl run generators have been deprecated except for run-pod/v1. This is part of a move to make kubectl run simpler, enabling it create only pods; if additional resources are needed, you should use kubectl create instead. (#68132, #soltysh)
Related
I have one kubernetes operator (ex: kubectl get oracle_ctrl). Now I want to provide custom arguments for the kubectl command.
ex: kubectl apply oracle_ctrl --auto-discover=true --name=vcn1
I can write one more controller to do the same job. But I don't want to write one more controller and make use of existing controller.
Is it possible to use operator-sdk to provide custom args to kubectl?
No, this isn't possible.
kubernetes/kubectl#914 has a little bit further discussion of this, but its essential description is "we should start the proposal and design process to eventually write something better than kubectl create to support it". Your CRD can define additional columns to be shown in kubectl get but this is really the only kubectl-related extension point. You could potentially create a kubectl plugin or another CLI tool that does what you need.
Rather than using the kubectl imperative tools, it's often a better practice to directly write YAML artifacts and commit them to source control. You can parameterize these using tools like Helm or Kustomize. If kubectl apply -f or helm install is your primary way of loading things into the cluster, then you don't need custom CLI options to make this work.
I am seeing multiple and different explanations for imperative Vs Declarative for Kubernetes - something like Imperative means when we use yaml files to create the resources to describe the state and declarative vice versa.
what is the real and clear difference between these two. I would really appreciate if you can put the group of commands fall under the same - like Create under imperative way etc ..
"Imperative" is a command - like "create 42 widgets".
"Declarative" is a statement of the desired end result - like "I want 42 widgets to exist".
Typically, your yaml file will be declarative in nature: it will say that you want 42 widgets to exist. You'll give that to Kubernetes, and it will execute the steps necessary to end up with having 42 widgets.
"Create" is itself an imperative command, but what you're creating is a Kubernetes cluster. What the cluster should look like is determined by the declarations in the yaml file.
Imperative
Official docs on Managing Kubernetes Objects Using Imperative Commands.
Kubernetes objects can quickly be created, updated, and deleted directly using imperative commands built into the kubectl command-line tool.
kubectl run nginx --generator=run-pod/v1 --image=nginx
kubectl create service nodeport <myservicename>
kubectl delete pod
Declarartive
Kubernetes objects can be created, updated, and deleted by storing multiple object configuration files in a directory and using kubectl apply to recursively create and update those objects as needed. This method retains writes made to live objects without merging the changes back into the object configuration files. kubectl diff also gives you a preview of what changes apply will make.
Official docs on Declarative Management of Kubernetes Objects Using Configuration Files.
Official docs on Declarative Management of Kubernetes Objects Using Kustomize
Define what you want in an yaml file and use kubectl apply
kubectl apply -f app.yaml
kubectl apply -f <directory>/
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Imperative command means::: We are not creating any yaml file and directly changing resources like pod service network anything via
Command line so that is imperative command.
Imperative object configuration::: means we are creating any resources as per our requirement in yaml file where we will remove
default value's which we don’t need everything except required things so in that case this is imperative object configuration AND that is CREATE command..
Declarative object configuration:: We don’t care about anything just we need final output so in simple words we copied
yaml from internet and created a pod where motive is to only create pod/resources So in that case we use APPLY command.
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.
One of the points in the kubectl best practices section in Kubernetes Docs state below:
Pin to a specific generator version, such as kubectl run
--generator=deployment/v1beta1
But then a little down in the doc, we get to learn that except for Pod, the use of --generator option is deprecated and that it would be removed in future versions.
Why is this being done? Doesn't generator make life easier in creating a template file for resource definition of deployment, service, and other resources? What alternative is the kubernetes team suggesting? This isn't there in the docs :(
kubectl create is the recommended alternative if you want to use more than just a pod (like deployment).
https://kubernetes.io/docs/reference/kubectl/conventions/#generators says:
Note: kubectl run --generator except for run-pod/v1 is deprecated in v1.12.
This pull request has the reason why generators (except run-pod/v1) were deprecated:
The direction is that we want to move away from kubectl run because it's over bloated and complicated for both users and developers. We want to mimic docker run with kubectl run so that it only creates a pod, and if you're interested in other resources kubectl create is the intended replacement.
For deployment you can try
kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node
and
Note: kubectl run --generator except for run-pod/v1 is deprecated in v1.12.
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.