45

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?

Sam
  • 5,375
  • 2
  • 45
  • 54
djt
  • 7,297
  • 11
  • 55
  • 102
  • Does this answer your question? [kubectl apply vs kubectl create?](https://stackoverflow.com/questions/47369351/kubectl-apply-vs-kubectl-create) – Inanc Gumus Apr 21 '20 at 12:50

2 Answers2

55

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.

Suresh Vishnoi
  • 17,341
  • 8
  • 47
  • 55
  • thanks for all that. As far as version controlling configuration files, do people generally just store these alongside the code for their project? – djt Dec 29 '17 at 19:08
  • We found there's too much repetition in the 80% case - a pod with a single container that we mount a single configmap in to, that we create a single service for that we expose through a single ingress, so we have an Ansible role that takes some values (Docker registry, number of replicas, health probe URLs) and stamps out and applies the manifests. We store the Ansible playbook that calls the role with the correct values for the project together with our source code, like you suggest. If you needed more fine-grained control, storing the actual manifests with your code would make sense. – Frans Jun 06 '19 at 16:21
2

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.

Amit L.
  • 81
  • 6