#96: With the advent of software like Crossplane, we are beginning to see the Kubernetes API coming more to the forefront. In today’s episode, we attempt to tackle why it appears that events are still not completely understood.
Viktor Farcic is a member of the Google Developer Experts and Docker Captains groups, and published author.
His big passions are DevOps, Containers, Kubernetes, Microservices, Continuous Integration, Delivery and Deployment (CI/CD) and Test-Driven Development (TDD).
He often speaks at community gatherings and conferences (latest can be found here).
His random thoughts and tutorials can be found in his blog TechnologyConversations.com.
If you like our podcast, please consider rating and reviewing our show! Click here, scroll to the bottom, tap to rate with five stars, and select “Write a Review.” Then be sure to let us know what you liked most about the episode!
Also, if you haven’t done so already, subscribe to the podcast. We're adding a bunch of bonus episodes to the feed and, if you’re not subscribed, there’s a good chance you’ll miss out. Subscribe now!
That's how we operate. It's more that we understood that machines cannot operate that way, which is silly because machines are better at multitasking than we are.
This is DevOps Paradox episode number 96. The Kubernetes API Is Becoming Omnipresent
Welcome to DevOps Paradox. This is a podcast about random stuff in which we, Darin and Viktor, pretend we know what we're talking about. Most of the time, we mask our ignorance by putting the word DevOps everywhere we can, and mix it with random buzzwords like Kubernetes, serverless, CI/CD, team productivity, islands of happiness, and other fancy expressions that make it sound like we know what we're doing. Occasionally, we invite guests who do know something, but we do not do that often, since they might make us look incompetent. The truth is out there, and there is no way we are going to find it. PS: it's Darin reading this text and feeling embarrassed that Viktor made me do it. Here are your hosts, Darin Pope and Viktor Farcic.
We've talked about in the past that we wish, we really wish, that the Kube API would become the universal API of everything. And guess what? It's starting to get there.
Yeah. I think that that's amazing prospect of the future because right now situation might be better than it was in the past, but still figuring out what is the API, CLI, whatever you're using, to deploy your apps here, to deploy your apps there, to manage virtual machines in AWS and do something else in Azure. It's a complicated endeavor. Now, if we focus only on certain aspect of managing. Let's say, if you focus only on Terraform, for example, infrastructure, we can say, Hey, Terraform is unifying all my needs for infrastructure. I'm still not very happy with that, to be honest, because it's better than it was before, but still the way how I'm going to define, let's say a Kubernetes cluster for AWS is completely different than for let's say Azure, but still at least I have one tool that I can use Terraform or Pulumi to manage all my infrastructure needs, but Kubernetes API I believe goes beyond that. It is focused on scheduling pods and being API that serves all your needs for running your applications in a Kubernetes cluster. Terraform is equivalent let's say for infrastructure, even though it's not really the same API across different platforms. Now with Kubernetes, what we're seeing is that that API can be not only for running your pods, but it can be for running your VMs. It could be for creating your infrastructure. It could be for potentially many different things. In theory, it could be anything. At least the way I look at Kubernetes API, it's more that it is a very well designed and very extensible system to queue requests that are fulfilled by some entities listening to that API. So it's almost like eventing mechanism. Hey, I want to do this. I want this to be done. Sometime. Somehow. Then something listens to that, let's say event, and does something with it. For example, I want to expose my, and I'm now going pure Kubernetes, I want to expose my application to the outside world. I'm going to create an ingress resource, whether that is nginx, listening to that event or it happens to be Istio for example, gateway or any other of 50, maybe different providers is less of a concern. Now that something is already actually, when you think about it there, because we are not really running when I say I want to expose this application, Kubernetes this will not only configure itself and do whatever it needs to do. It will go and create a load balancer in my let's say AWS infrastructure. So Kubernetes is already managing infrastructure without necessarily that being obvious. The same thing I can say, Hey, I want a volume. I want a volume with a fast disk attached to my application and it will go beyond itself. It will communicate that desire with Azure, Google, DigitalOcean, whatever you're using, fetch the volume and attach it to your application. So it is already managing infrastructure. The major difference is that right now Kubernetes is managing infrastructure completely for the needs of applications running in pods. Now we can go further than that and say, Hey, if it can already manage load balancers and drives, why not actually manage everything? Why not use it to manage my whole AWS infrastructure, even if I'm not actually even deploying anything to Kubernetes? It's theoretically doable and we've seen projects doing that. I'm going to mention one, which is Crossplane. I think it is crossplane.io, we'll put the link down, which is doing just that. I've been trying it for a while now and for example, I can set up my minikube on my laptop and install Crossplane and say, Hey, now you manage my Azure infrastructure. Doesn't even have to be Kubernetes. I mean, there is a Kubernetes, but simply because API needs to run on top of Kubernetes, but it could be just Kubernetes that serves API and nothing else.
So basically all you would need is the control plane at that point?
Yeah. Control plane of Kubernetes because it needs to be capable of doing stuff and Crossplane itself in that specific example. We can talk about how quite a few companies are using Kubernetes to manage VMs that are basically treated as if they are pods. I want to run my application, it just so happens that that application, in that specific scenario, will not run in a container. It will get a dedicated VM, created, scaled up.
Well, that brings up an interesting point because I still see people believe that they need to spin up all of the infrastructure themselves and they have that as a quote unquote, mandate that they have to manage the infrastructure themselves, and that Kubernetes cannot manage any infrastructure for them. I see that, especially like, well, we have to provision our specific load balancers, so there's no way that provisioning an ingress should create a load balancer. How do we make that conversation disappear?
I think it's maybe part of almost like human nature, that we are very bad at giving away control, I think, because logically, there is no reason why, if you want to expose something to the outside world, communicating to something else inside of Kubernetes, there is no logical reason why Kubernetes wouldn't create a load balancer, assuming that there is an API to create it, assuming that we are talking about something dynamic, not physical. There is no logical reason why Kubernetes wouldn't do that, but I think that we are somehow afraid that we might lose control. I need to be the one who creates the load balancer because I'm in control, which is problematic because if you're in control, then you need to provide the same level of dynamism, if there is that word, and speed as Kubernetes does. For example, when your nodes are down and some new nodes are created, Kubernetes will reconfigure your load balancer, if that's needed. Now you can do it yourself as well, but then you need to be behind and doing the same thing that Kubernetes is doing, meaning monitoring what's going on and reacting to changes of the current state.
Would it be safe to say that if you are unwilling to give up control, you should not be using a system like this, whether it's Kubernetes or anything else, if you're unwilling to give up control?
Definitely. I wouldn't even say Kubernetes. I could apply the same thing to VMs. From the very beginning, what VMs allowed us to do is to have much more dynamic setting of everything. If you're using VM onprem, you could configure and you should configure VM to fail gracefully and recreate VM somewhere else. Disaster recovery and all that stuff. VMware does that for you. Now, whether you want to let it do it for you or no, it's a different question. But with Kubernetes, I think that we are just stepping up another layer up, that it's more dynamic. There is more need to give away control of over what you're doing to a machine, but it's not something that Kubernetes invented.
So you were talking about how using Crossplane you could use it to do everything effectively, replace the need for Terraform, CloudFormation, any of the other IAC type tools. Is that correct?
Correct. It's similar to Terraform that it comes with predefined modules and you have, I'm inventing now, you have a module or in case of Crossplane, you have a custom resource definition for creating, let's say DynamoDB, and then you can say, Hey, there is nothing available to create X, Y, Z, whatever else you need and then you create your own logic. You can plug it into doing theoretically anything you want. You just need to teach Kubernetes how to do additional stuff. In that aspect, it is the same as Terraform. Hey, if there is no plugin that does what you need it to do, the alternative is not to fall back to doing shell scripts. The alternative is to write the module, the plugin, whatever Terraform calls it, to do the features that you're missing or perform actions that it doesn't do right now.
So are you saying that Crossplane. This is where I'm a little confused. Are you saying Crossplane can replace Terraform as well as work with Terraform?
No, it can replace Terraform. I'm more referring that it's similar to Terraform in terms that it is based on some sort of modules or plug-in mechanism and then X types of resources or infrastructure pieces are supported and then some other things are not, and then you extend it to do things that are missing. I'm just making comparison with Terraform that they are very similar. I would almost say that it's same thing as Terraform just speaking Kubernetes API and being defined in Kubernetes as Kubernetes YAML custom resource definitions. So it's a different format, different API. The same logic, more or less.
Okay, but it also sounds like, well, no, it doesn't sound like. I was going to say it still sounds like Crossplane could drive or even let's ignore Crossplane for a second. Kube API could drive Terraform. no reason why it wouldn't work.
Yes. You could create some kind of translator to say Hey I wouldn't like to for anybody to start switching from Kubernetes YAML as format to define things to HCL but let's say that somebody could theoretically put a daemon inside of a cluster that runs Terraform and let's say updates definitions, reapplies stuff whenever there is a call to the API and the major work would be to make it translate Kubernetes type of custom resource definitions into Terraform definitions. HCL. I wouldn't like anybody to try to make Kubernetes speak HCL directly.
There's certain things you should do in life. That is not one of them. Let's get back to the concept of event. We've talked about this either on a previous episode and I believe we talked about it on the live streams. When you use kubectl or you're interacting with the API and you get a response code, all that response code tells you is was it accepted or not.
Exactly. It does say whether it's changed, created, or deleted, but I think that's very misleading because when you see in the output of Kubernetes when you do kubectl apply, when you see created or changed, that means nothing in a physical world. What that means is that Hey I acknowledge that I accepted your request and I changed, updated, deleted, or created something in etcd which is my internal database. When you see that created that does not mean that anything is created in a cluster. It just means it will result as operation ultimately one day maybe that will create something. You can interpret it as what you said. You just get acknowledgement that I understood what you might want.
In using your words, create, update, delete. etcd is the database, so the only acknowledgements you're getting is was there a record added, updated, or deleted within etcd.
And then it's the internals of the Kubernetes master plane to make those things so.
Exactly. Without executing additional commands, you have no idea whether your application is running, whether it's initializing, whether it's not even starting. You have no idea about any of those things. You can find out by running additional commands like kubectl rollout status, but just by applying something by telling Kubernetes, hey I want to do this, you just have that. I understood. Maybe. Go away type of stuff.
I got it. Check back with me if you want. That's all it's telling you.
Exactly. I got it. You are allowed to query me to find a runtime status.
Which is different than let's say either Terraform or CloudFormation because that's a little more synchronous.
Oh yeah. It's very different. First because basically when you execute terraform apply, it's synchronous. You get, Hey, I'm doing this. I'm doing that and so on and so forth and the process is finished on your laptop or in your terminal when the process is finished wherever you're running it. Even more complicated difference I think is that with Terraform it's not only synchronous but you define dependencies. You can say, Hey, create a control plane of my Kubernetes cluster first and then create worker nodes. If I would apply that logic to Kubernetes, if Kubernetes could create itself, it would be, hey, create worker nodes and control plane. Start in any order you want. That's not my concern. I will assume that if you try to create worker nodes before having control plane it will fail and then you will shut it down and you will try again. You will try again and again and again, but potentially, probably, but there is no ordering. Let's say that you have and I'm simplifying it, you have an application with two pods and you would like one pod to start before the other. No. That's not doable or maybe if it's doable, everything can be done, it's not the way how you're supposed to do it.
That takes me back to the Docker Compose where it had a dependency tree. With Docker Compose, certain things wouldn't come up unless it saw that the other thing was already running.
Yeah exactly. That also poses obvious problems because all that works when you design your stuff to work like that. It is unrealistic to expect that all the apps that we ever created in this world will be able to work like that. They cannot and we need to find workarounds around that system, but from Kubernetes perspective it's all asynchronous. It's all in random order.
It reminds me on when I started programming for the first time. What was it? Maybe BASIC or something like that. I don't know if you remember that when we had to write line numbers like 10 and then do this and 20 and then do this and if you want something between 20 and 30 you would write 25 or something like. You remember that, right? That was literally it needs to be step A step B step C step D. There is no step A and then B C D whenever you can. That was not an option or I missed it in those early days.
Is it that now we're having a hard time catching up to how life really is or some of us are in dealing with just eventing. Here's a message. The system acknowledges it received the message and then you go on about life.
Yes. That's how we operate. It's more that we understood that machines cannot operate that way, which is silly because machines are better at multitasking than we are.
Machines are capable of multitasking. Humans are not.
Exactly. Imagine if you would translate that to human behavior outside of software engineering, we would say, hey Darin, let me send you an email and then I have pending email to send to John but I'm first going to wait until you respond. Exactly. But that's exactly what we do when we design systems. I send this message and I'm waiting for the response before I do something else.
Is it wrong to wait for any response, even if it's just an acknowledgement?
Acknowledgement is a good thing. I answer to my emails very often with got it or something like that. I wouldn't say that people should wait until I say I got it or understood but it's good to receive acknowledgement. I'm talking now in real life. If you go back to software, systems, acknowledgement is very important because we need to know that my message was received. Even when you send email, you're going to get a response back if it couldn't reach the destination. It's just that with emails, we don't receive acknowledgement that the destination was reached, so it's kind of no news good news type of approach. Things might change in the future but right now I cannot imagine not receiving acknowledgement but once I do receive acknowledgement then I'm fine and usually and this is a difference between email. If I respond with received, it will still take anything between seconds, minutes, hours, sometimes days, but we receive acknowledgements instantly basically, so there is no good reason not to wait for acknowledgement. What is not instant is confirmation that the task is finished because that can literally take anything between milliseconds and weeks but acknowledgement that you received the message, that's milliseconds, if not less.
So as we continue on this thought process of events, you were poking around on Crossplane. It still gets back to the point that I probably still need Terraform or CloudFormation to get to the point to where I could use something like Crossplane.
That's a chicken and egg problem. Exactly. Now when I think about it actually it's not that much different from Terraform. You need to have Terraform running somewhere. It's not really running but CLI installed somewhere, on your laptop and I assume that very often in medium to big sized companies, it's not even your laptop. You usually have a server from which you would run Terraform commands. So you need to set up something. Now arguably in case of Crossplane, that setup is more complex because it's definitely harder to set up minimal Kubernetes with Crossplane running than install Terraform CLI. It is in a way chicken and egg problem. I could even argue if I use Crossplane to manage my infrastructure, then what is managing my infrastructure for Crossplane itself. Now fortunately, if you're talking about cloud, that's close to trivial now with Azure, Google, Amazon, so you could skip the rule to manage all infrastructure as code for that single, tiny, small, miniscule, cluster with
Why don't we end this one here and we're going to keep diving into eventing because eventing, if you haven't figured it out yet, is where everything already is. Whether you're doing it or not, doesn't matter. It's already here. I have a friend that has been doing nothing but async programming I'm going to call it specifically that which is eventing. Let's put it this way. Eventing is an implementation of async programming or is it the other way around. One is a subset or superset of the other depending on which way you want to go. He's been doing it for years. When I have conversations with him, it's really hard to figure out what the conversation is about.
So he's applying it to himself as well.
Sometimes, yes. If you're still thinking, hey, I need to wait for my 200 response, that might be true, but that 200 response probably does not mean what you think it means.
Yeah that would be 200 responses and acknowledgement that I received your request and response is my acknowledgement, not a confirmation that I finished whatever you wanted me to do Everybody's should always respond with 200 if everything is okay. The question is only whether 200 is acknowledgement or confirmation of termination of something.
Which then gets you to the point should it be 200 or one of the 200s and that's a different conversation that we will not go into. Now, if you send back a 500, that's actually also good as well.
Yeah, because then I know that there is no listener on the other end.
Yeah. Well, if I got a five, that means I'm probably going to redo a retry.
Yeah, sorry. I need to brush my HTTP response skills. Yes, 500 would be that.
I'd do a retry. If I got a four, I wouldn't do a retry, but I would send another message because that means access problems. If I got a three, I'm going to go yell at somebody because why am I being redirected
or why you're not following redirections?
I could follow a redirection, but I'd still should be yelling to somebody it's like, okay, what happened? All right. So let's stop here on that part of eventing and we will continue in next week's episode. More about eventing.
We hope this episode was helpful to you. If you want to discuss it or ask a question, please reach out to us. Our contact information and the link to the Slack workspace are at https://www.devopsparadox.com/contact. If you subscribe through Apple Podcasts, be sure to leave us a review there. That helps other people discover this podcast. Go sign up right now at https://www.devopsparadox.com/ to receive an email whenever we drop the latest episode. Thank you for listening to DevOps Paradox.