I agree with some other comments in this thread about a general fervor in the Enterprise space to "modernize" needlessly. This conversation usually lands on the company copying what everyone else is doing or what Gartner tells them to do. Cue "DevOps".
100 percent agree with your comments on something simpler. I can't tell you how many times I've debated with our Analytics teams to just use Docker Compose/Swarm.
I don't agree. I spun up a Kubernetes cluster in Azure, which was indeed easy. But then I had to figure out how to write the correct deployment scripts to deploy my docker containers to it, and how to configure all the security stuff. After more than a week of trying to figure it out, I decided to ditch the whole solution and go for Azure Container Instances instead. It was too much for me to learn about all the concepts of Kubernetes, how you configure them, how to make it work for solutions that are not as simple as the example on the website, and how to navigate through the various different methods of deploying stuff.
Maybe I'm just too dumb. But I wasn't going to invest a month of my time into doing something that should be simple enough for an average developer to accomplish.
Once we deployed, we ran into all sorts of SRE-issues. Turns out AWS sets all those “sane limits” that our own folks never did. Still hunting ghosts from the rollout 6 months ago.
Makes for good resume fodder, and makes me laugh at the prestigious titles and positions the folks who built this system went on to receive at big name firms.
Guess it is someone else’s management problem now. :shrug:
For what it's worth, deploying in Kubernetes is pretty easy once you figure it out (and often finding the information is the hardest part). All you need to do is update the Deployment resource's "image" parameter. You can do that with `kubectl patch` like so:
kubectl patch deployment foo -p '{"spec":{"containers":[{"name":"main","image":"new-image"}]}}'
Kubernetes will handle bringing up a new replicaset, validating health checks, draining the old replicaset, etc.If everything is in code, and you have a reasonable branching strategy, it's much easier to control change, to rollback bad merges, to run pre-hooks like security checks and configuration validation tools, etc.
I think you're assuming that invoking kubectl means invoking it directly from a user's command line, but kubectl can also be called in a CD script.
This state can be version controlled, written in stone, whatever you prefer and it can always be attained.
When administrators start issuing imperative commands to a cluster, state starts being changed and there is no record[0] of the state Kubernetes is being asked to maintain.
[0] Not entirely true, the state can always be retrieved from the cluster so long as it hasn't failed.
Firstly as you point out, there is a record of the state Kubernetes is being asked to maintain: it's in the API server as the spec of each resource.
Secondly, using `kubectl` "patch" in the manner described is not making changes to the cluster state directly, it's making changes to the specification of what should be maintained, and the various controllers effect the state changes.
Fundamentally, the argument seems to come down to "you don't have a record of what you once asked the API server to do", and that's fair enough - you don't. But that has nothing to do with imperative or declarative models.
I'm not advocating actually doing this on a day-to-day basis, but the arguments against it are not ones of imperative vs declarative.
[0] https://kubernetes.io/docs/tasks/manage-kubernetes-objects/i...
Applying a patch is "make these changes to your existing state".
That dependency on existing state is a difference, and it seems to map reasonably well to what declarative/imperative seem to usually be used to mean in this context.
2. "make these changes to your existing state" is still declarative
It isn’t though. It’s “please make the state look like this eventually”. You do not patch state, just spec. Controllers effect the changes.
That said, the parent is wrong that a full manifest is declaring the (etcd) state in a way that a (strategic merge) patch isn't--both are declaring etcd state, but a strategic merge patch is doing so in finer-grained increments. A strategic merge patch can declare zero state or many full manifests, while applying full manifests can only work in increments of complete resource manifests. But both are telling Kubernetes "this is your (etcd) state now".
You do actually have this record. First of all, because k8s has an audit log, and secondly because deployments maintain a revision history (so you can always rollback--kubectl even supports this via `kubectl rollback undo`).
Updating the manifests, pushing them to version control and having CD deploy them encourages humans to "do the right thing".
It would be quite easy though to just tweak that one environment variable though while I patch in the new image version to update that one service; until the entire cluster dies and I can't retrieve the last definition and need an equivalent cluster up within the hour.
This is really more about the practice of writing down the state you want the cluster to be in (the spec) and showing it to the cluster, than just ordering it to do one thing without context.
In this sense, Declarative Vs Imperative is just a proxy term for "do I have a record of the state I asked the cluster to keep?"
Moreover, people in this thread also don't know what "declarative" means. The patch is declarative, and "declarative" doesn't provide the claimed benefits. For example, as with the patch command, I can create, apply, and delete a Kubernetes manifest file (indeed, I can apply directly from stdin!) and there is no additional record of the change beyond that which would exist if I had just applied the patch.
I will grant you that `kubectl delete -f` breaks my argument, since it's imperatively modifying objects given a declarative manifest. Re: changes via stdin, I mean sure; you can also pipe a deployment manifest into `ex` or `sed` to make changes on the fly and then echo it back to `kubectl apply -` but I wouldn't recommend it.
Also, working in raw manifests isn't a panacea; if you delete a resource's manifest, Kubernetes won't delete its corresponding resource (maybe this is what you were referring to with your bit about `kubectl delete -f`). You need something that diffs the manifests against the current state of the world and applies the requisite patches (something like Terraform) but this isn't related to how you change image versions.
[0] https://kubernetes.io/docs/tasks/manage-kubernetes-objects/i...
I managed my stateful sets/services for a while with terraform, but my experience was absolutely terrible and I have stopped that eventually. I now use "kubectl patch" and "kubectl apply" with handwritten yaml, but the workflow feels very clunky.
Intuitively it seems obvious to me that there must be a tool helping with that, but for some reason I was absolutely not able to find anything that would be even a little bit helpful. I am considering writing a couple python scripts that will automate it.
If you need something more flexible than that, try making your own helm chart. Helm will give you some text templating, pre and post hooks, some basic functions, and some versioning and rollback functionality.
You can start simple by just pasting in your existing k8s yaml, and then just pull out the pieces you need into variables in your values file. If you need to change an image version, then you just update the variable and `helm upgrade mychart ./mychart`
I only use ‘kubectl apply’ for small stuff where I only have a couple resources. Anything more complicated and a tool like helm is much more useful.
* shell interactions with quotes * double quotes * interpolating into image namespace with no autocomplete * easy to forget an argument * do you get autocomplete against the deployment name?
Comparison: C# declaration of a complex type - it's less complex than the `kubectl` command above, but IDEs offer way more support to get it right.
* var x = new List<Dictionary<CustomType,int?>>()
This will light up warnings if you get anything wrong;
You get: * go to definition of `CustomType` * autocomplete on classnames * highlighting on type mismatches * warnings about unused vars. * if you initialize the var, the IDE will try hard to not let you do it wrong
So structurally,
1) in the code realm, for doing minor work we have really strong guarantees,
2) in deployment realm, even though it's likely going to hit customers harder, the guarantees are weaker.
I think this is behind the feeling that the k8s system is not ready yet.
2. kubernetes will abort the change if it doesn’t syntax check or the types don’t match.
> I think this is behind the feeling that the k8s system is not ready yet.
Whether you patch the deployment image from bash or from C# doesn't indict the k8s ecosystem.
or
What I'm trying to say is that as an operating system, Kubernetes is now a young adult, and historically speaking, operating systems at this level of maturity have been adopted and ridden for decades, with much success. But, ya know, if you chose OS/360 in 1996 you would have a point.
This a stretch, but to me Kubernetes is like the C programming language for infra. If you look at the entire software stack today, drill down (all the turtles), and you will eventually find C (everything goes back to libc or a C/C++ kernel). I assume any commercial (or non-!) "higher-level abstraction" for infra is already (or will be soon) built on top of Kubernetes. I am OK with it.
I write this post as someone who is uber-techincal, but I know nothing about actually using Kubernetes. I can do vanilla "hand-coded/snowflake" infra just fine in my constrained, private cloud environments, but nothing that scales like Kubernetes.
I might be nitpicking, but I'm not sure that's necessarily true. You could in theory write a compiler for a new language in C (or even assembly!), and once you have a working language, re-write the compiler in that new language. Now that there is no C code involved in the stack anymore, would that still count as a C-turtle?
Haskell for example, has some "bits" written in C, but a lot is written in Haskell or assembly[1]. So if you look at the WHOLE stack you'll find C _somewhere_ (probably most places), but I don't think _everything_ boils down to C.
Granted, a LOT of stuff is written on top of C.
[1] https://stackoverflow.com/questions/23912375/what-language-i...
After seeing so much great work done with JavaScript in the form of "transpilers", I think a lot can be done in that area. I feel Zig is a crazy good idea: A brand new language that produces binaries that are 100% compatible with C linkers. If all goes well, in a few years, why would anyone use C over Zig? It seems like the future.
Lots of people think C++ is bat sh-t crazy complex (me too, but I still like the mental gymnastics!). What if there were different C++ dialects supported by transpilers that intentionally restricted features? I think kernel and embedded programmers would the primary audience.
kubectl set image deployment/foo main=main:new-image
instead kubectl set image deployment/foo "*=the/new/image"
and then, my other favorite (albeit horribly named, IMHO) "rollout status" to watch it progress: kubectl rollout status deployment/foohttps://www.oreilly.com/library/view/kubernetes-in-action/97...
If you try digital ocean k8s offering it's fairly straightforward.
Google cloud was the first to offer a decent k8s as a service, if I recall correctly. We didn't have DevOps back in 2015 and we were on GCloud.
Personally I don't pick k8s just because it's heavy to run and I don't want to waste machines (plain docker is good enough for a large part of what people actually need). Sometimes in a project when I can't figure something out with just docker, I just bite the bullet and install k0s.
What we need is a Next.js for Kubernetes. Something that delivers a full stack solution on top of base Kubernetes.
The core system is great, but we need to replace these DevOps with a framework or platform.
Doesn't Rancher fit this description? It's pretty resource-heavy though.
- Deploys kubernetes clusters - includes Fleet for CI/CD - install apps with helm - ISTIO (awesome)
It feels like it is positioned for orgs with large needs. I'm looking for k8s for small nimble orgs.
I will look at Rancher more, thanks for reminding me of it!
Google's Anthos is also hard to describe now as they cover similar "everything" product features.
GCP now has Autopilot which lets you pay just for the cpu you use (no cluster management at all).
Anthos includes ISTIO which may at some point work on Autopilot. This would mean not having to fiddle with GKE Ingress (which I found unpleasant) and instead use the new standard Gateway.
I believe that eventually GKE Autopilot will offer running individual pods on GPU/TPU, pay as you go.
But when is this all as easy as using Next.js ?
YAML: significant whitespace is always unwelcome but YAML also introduces unexpected problems, like how it deals with booleans. For example, say you have this array:
foo:
- x
- y
- z
You might think this is an array of strings, but you'd be wrong.It's also difficult to read through a YAML config and understand the parent of each key, especially in code reviews or just on GH.
I believe k8s life would have been easier with JSON configs, where it's impossible to confuse e.g. booleans for strings and where it's easier to understand the object's hierarchy.
Helm's use of gotpl: this choice exacerbates the problems with YAML. Now you're treating a structured language with a text template library. You have to spend energy thinking about indentation levels and how the values will be interpreted by both the templater and k8s.
I think helm would be less frustrating if they chose some templating library that made objects first class citizens. Where you can inject values at specific locations with one-liners or simple blocks of code (e.g. `ingress.spec.rules[0].append(yadda yadda)`)
I'm sure there was debate about these choices early on and I don't have any unique ideas here, so I don't want to be too critical. These are just a couple of pain points I've personally experienced.
["x","y","z"]
["x", True, "z"]
[1] https://yaml-online-parser.appspot.com/?yaml=foo%3A+%0A-+x%0...
If you're going to use JSON for config, it's better to use an actual JSON parser.
https://john-millikin.com/json-is-not-a-yaml-subset https://news.ycombinator.com/item?id=31406473
You could mitigate some of the issues and get JSONs "strictness as a feature" by passing the document through e.g. `jq . $file` as a CI step, but I don't think that'd resolve the 1e2 issue. TBH I didn't know you could write numbers in JSON like that, so I imagine it'd be an issue that doesn't come up often. But it's disappointing that it wouldn't just work.
That's false. http://p3rl.org/JSON::XS#JSON-and-YAML
Technically YAML is (supposed to be) a superset of JSON - (almost) all valid JSON is valid YAML. So you could write all your configs in JSON and they'd (probably) work just fine (assuming you keep things relatively simple).
My cofounders and I are working on a solution to this at https://www.jetpack.io/. If you're interested in early access, we'd love your feedback!
eksctl create cluster --name mycluster --region us-west1 --with-oidc --fargate --external-dns-access --asg-access --full-ecr-access --alb-ingress-access
Now the fun starts:"Kubernetes Failure Stories"
Sure, one can break anything, but our anecdotal experience is we’re now focused on actually delivering code rather than fretting about node failures.
Definitely a lot of work.
...until you need to debug something somewhere in the enormous stack.
The lower level infrastructure/platform/kubeadm type stuff isn't really 'Dev' related at all.
This has been the biggest drain on my career. Everyone wants to be an "engineer" ready to handle every problem like its the next facebook. Like bruh, this service is going to get like 100 req/hour max and only when the sun is up - just **ing throw it on cloud run. We can tell the only thing you want to build is your resume.
But what would you suggest in lieu of Kubernetes? What would save work for a shop which is not yet a giant but has already overgrown the capabilities of 2-3 manually managed boxes / instances?
I can think of several options. Management by Ansible / Saltstack / Chef can easily become a rabbit hole comparable to maintaining K8s's YAML. In your experience, does Nomad save SRE work at smaller scales? Does Terraform? CloudFormation?
It's "Amazon ECS", and it works pretty well for standard fare CRUD web services, but more complex use cases quickly end up pulling in more and more AWS services (for example, if you need to run a cron job, you can use EventBridge to trigger an ECS task or just do it all with Lambda). This isn't dramatically worse--it's mostly just different. Kubernetes APIs are more consistent than in AWS, and Kubernetes tends to be more flexible and less limited than AWS. It's also much easier to extend Kubernetes or find a pre-existing extension than in AWS. But mostly it's not going to make or break your project one way or the other.
If you're just running CRUD web services, this is fine, but if you need to spin up a background job or do more complex orchestration then it can quickly become advantageous to
I run a small cluster for my side projects consisting of 3 nodes. 1 node is dedicated to run database containers and control plane node (it's also a worker node but strictly for database statefulsets only), and the other 2 as worker nodes, but one of them also run an NFS server that mounted as persistent volumes so every worker nodes can have access to it.
Self-healing? Internet-scale? I have on interest for them on my small cluster. I just want my apps to not go down while I'm updating them without writing complicated blue-green deployment scripts, ability to move around pods to other nodes when one got overloaded, and ability to add or remove nodes when needed without starting again from scratch. I basically treat it like docker-compose on steroid. So far it works really well.
Kubernetes only exists, because Google lost the Cloud Wars, and this was their Hail Mary pass.
At my first job outside of Google we used something called Convox, which was very similar to running things in production at Google. You triggered a package build from your workstation (!) and then adjusted production to pick that up. Very similar to mpm packages and GCL files. (The difference is that Google had some machinery to say "while the build might have been triggered from a workstation, all this code has actually been checked in and reviewed". Convox did not have that part, so yeah, you could just edit some files and push them to production without checking them in, which wasn't great. But when you are a 4 person development team, not the end of the world by any means.)
All this is not to say that Kubernetes is the right solution to your problem, or to almost anyone's problem. It was just an improvement to Google's infrastructure, for the sort of problems that Google had. For some people it makes sense... for you it might not.
Borg is far more advanced in its scaling abilities.
If Kubernetes does indeed provide the best solution to provide scalability and availability, one can argue that this would result in a decreased demand for dev ops engineers, as they "would just have to use Kubernetes" and it would decrease their workload.
In reality this does not seem to be the case, that's why I asked.
I'd say it would result in either:
- the same scalability and availability with fewer DevOps engineers - better scalability and availability with a similar number or more DevOps engineers
In my experience, it's almost always the second case that happens. For example, a service would be moved from a few (virtualized or physical) servers that can only be scaled manually, to a k8s cluster with either autoscaling or at least scaling by changing a configuration file.
Pretty much every piece of software I've written in the past decade that tends to have configs in production can also work with little or no config. Including clustered software that just exploits things that are widely available like Zeroconf to get a decent low effort cluster up and running. No, you probably won't be able to (or want to) use those features in production, but that's beside the point. The point is to lower the thresholds. And then keep aiming at lowering them wherever you can because asking other people to care about your software is seriously uncool. Other people will never care as much as you do.
It is normal for programmers to become defensive about software. Be it their own or software they really like. But it is far more productive to assume that when users think something is awkward, perhaps it is because it is awkward. And perhaps it could have been done better.
Nobody actually gives a crap what someone thinks Kubernetes was built for -- and what kind of rubbish experience they think is deeply justified by the goals.
It is either needlessly awkward to use or it isn't. And guess what: most people think it is awkward. And I seriously doubt it needs to be this awkward.
Of course, there's a huge cost to building your own framework as well... And it's easy to get wrong.
I started https://www.jetpack.io/ recently to try and build a better solution on top of Kubernetes. If you're interested in checking it out and giving us early feedback, you can signup on the website, or email us at `demo at jetpack.io`
k8s is not the right tool for every job. Most companies are not at the scale where they need to worry about the problems that it's trying to solve. But it's a cargo cult - they see the blog posts about how moving to k8s solves a bunch of problems that come up as you scale and decide they need to be solving all of those problems also even though there are simpler solutions at their current scale.
There's a bunch of other platforms out there that are way more opinionated and less "awkward" but they don't have the buzz that k8s has.
Kubernetes ought at least to be the right tool for a wider range of compute task. And I think it could have been the right tool for a wider range of compute tasks.
For instance, I don't regard one of our products that runs in three availability zones and has 3-4 instances per AZ as being "large scale". It is still a small system. And it doesn't run in multiple AZs for performance reasons but because we really need high availability.
We embedded discovery, failover and automatic cluster management in the server software itself. But it isn't really how we'd like to do it. But it is still less of a hassle than running K8S. (It also means that we can do that if you license our software to run it on-prem on pretty much most runtime environments, and that has its value, but again, this isn't functionality you want or should have to do yourself)
At ~12 instances probably still in "pets aren't so bad" territory.
Kubernetes is a great tool if you have scaling management problems.
"Things" here mean different things for different people. For me, it's secrets/certs, better rolling deploys and infra as code.
I have to manage like half a dozen docker images. K8s seems like a massive overkill, but managing by hand is rather error-prone.
yet its really not great at the first, and I'm strongly suspicious about the latter claim. Its very simple to make boneheaded decisions about networking that makes thing fragile.
In terms of scale, you have a limit of 5k nodes. given how fucking chatty it is, it costs a lot to run loads of nodes.
Sure could, if it provides benefits that outweight the additional work. Insurance companies will happily pay a couple more IT-specialists if it reduces the amount of cases they have to cover by an arbitrary percentage. Tools very much can serve other purposes than reducing the friction of human attention.
If you can containerize your infra and thereby mitigate threat vectors that may put your entire enterprise at risk if exploited, that's a good business call to make, even if the cost of your IT-department gets inflated by some margin.
Does it add work compared to setting up a VM with Docker and Watchtower? - for sure..
But does it add work compared to setting up something that gives you all the same benefits of k8s without using k8s? - imho definitely not.
That's the catch, if running your app on a manually setup VM is equivalent to running your app on Kubernetes then you don't understand what Kuberentes is or provide.
More work means
- more employees needed
- more direct reports for managers
- more jobs for x technology
- more people learning x technology because of those jobs
- more StackOverflow questions for x
- more companies using x technology because it's "easy to hire for"
- more money to be made in teaching x
- more learning material for x
https://www-users.cs.york.ac.uk/susan/joke/cpp.htm
Warning to bashers...it's a fake interview...
This is wrong, deploying on Kubernetes is easy and quick for most apps, you have one docker image one deployment spec and that's it.
https://kubernetes.io/docs/concepts/workloads/controllers/de...
Probably 98% of the devs were blissfully unaware of that complexity that the charts abstracted, and it let them focus on the services they were writing. I wasn't one of them, and always made sure to thank the devops team for simplifying the day to day deployments whenever I had to deal with writing a custom one.
It Handles the devops jobs for dev teams.
Full disclosure, I work for Bunnyshell.
Bunnyshell makes it easy to create and manage environments. (EaaS - environments as a service)
You connect your k8s cluster(s) and git accounts/repos, it reads the docker-compose files and creates deployments on the cluster.
You don’t need to know or write Kubernetes manifests, those are created for you.
You also get auto updates and ephemeral/preview environments (when a PR is created against the branch of your env, Bunnyshell deploys a new env with the proposed changes).
You are not restricted to creating resources only on the cluster, you can use Terraform for any resource that is external to the cluster ( like S3 buckets, RDS instances, anything Terraform can handle).
Hope this helps,
A day's work for one person to accomplish that isn't bad, IMO, but what that doesn't capture is the literal weeks I spent poring over documentation, trying things, running tests, learning what didn't work (Rook + Ceph is a nightmare), and so on. I went so far the day before the cutover as to recreate my homelab in Digital Ocean and run through the entire installation process.
Having services that magically work is hard. Having a golden path so you can create a new one with a few clicks is even harder.
> the pod networking implementation (a whole virtual IP space!!)
That part, at least, can be made simple: https://john-millikin.com/stateless-kubernetes-overlay-netwo... > DNS, loadbalancing, persistent volumes, monitoring, etc etc
None of that is part of Kubernetes, and you'll need it (or not) regardless of how you choose to handle process scheduling.There's a sort of common idea that a "Kubernetes cluster" is an entire self-contained PaaS, and that (for example) monitoring in Kubernetes is somehow fundamentally different from what came before. It's easy to fall into the trap of creating an internal clone of Heroku, but Kubernetes itself doesn't require you to do so and it can be a lot faster to just run Nagios (etc).
Well, load balancing is part of Kubernetes (except that it does not provide a sane implementation), and tbh having to debug strange failures caused by seemingly-innocent Service configuration is my least-favorite part of Kubernetes.
I agree with you on other points.
I’ve seen actually decent engineers (maybe they’re not decent?) bring down prod because they accidentally Kubectl deploy’ed from their command line.
Also, self-healing can create interesting problems which are fun to trace, debug and understand.