Cloud-Native Data Warehouses: A Gentle Intro to Running ClickHouse® on Kubernetes

Recorded: Thursday, July 22nd
Presenters: Robert Hodges, CEO, Altinity
This introductory webinar, presented by Altinity CEO Robert Hodges, explains how to run ClickHouse on Kubernetes from the ground up. The first half covers what Kubernetes actually is: a container orchestrator, an infrastructure-as-code platform, a cluster manager, and an automation endpoint. Hodges walks through the core resource types, including services, stateful sets, pods, persistent volume claims, and persistent volumes, then shows how a YAML specification is applied with kubectl so that Kubernetes can adjust reality to match what you asked for.
The second half turns to ClickHouse itself, a fast open-source SQL data warehouse that stores data in columns, compresses heavily, vectorizes execution with SIMD instructions, and scales out through sharding and replication. Because a production ClickHouse cluster is a complex distributed application, Hodges introduces the Altinity Kubernetes Operator for ClickHouse, which consumes a single, relatively simple resource file and produces a best-practice deployment.
Through live demos, the webinar shows how to deploy ZooKeeper, install the operator, bring up a cluster, inspect the generated configuration, and then scale replicas, add a user, and upgrade the ClickHouse version with no downtime. The key takeaway is that the operator turns an otherwise painful collection of resources into a few lines of configuration that Kubernetes keeps in sync for you.
Here are the slides:
Key Moments (Timestamps)
Key moments generated with AI assistance.
- 0:05 – Welcome and webinar housekeeping
- 1:26 – Speaker background and Altinity overview
- 3:29 – What Kubernetes is and does
- 7:14 – Distributed applications and resource types
- 11:04 – From YAML specification to running cluster
- 13:02 – Demo: deploying ZooKeeper with kubectl
- 19:14 – Where to run Kubernetes clusters
- 20:48 – What ClickHouse is as a data warehouse
- 23:15 – Why ClickHouse needs an operator
- 25:33 – Installing the operator and deploying a cluster
- 30:31 – Inside the resource file and pod templates
- 33:13 – Basic operations and scaling the cluster
- 38:18 – Demo: storage, access, and a live upgrade
- 43:27 – Documentation, closing, and Q&A
Webinar Transcript
0:05 — Introduction, Housekeeping, and Speaker Background
Robert Hodges: Welcome everybody. Today we’ll be talking about cloud-native data warehouses, and specifically introducing you to running ClickHouse on Kubernetes. My name is Robert Hodges and I’ll be your presenter today in this webinar.
Before we dive too deeply into the content, I’d like to let you know about a few things that will help you enjoy this more. First of all, this webinar, as you probably just heard, is being recorded, so we’ll publish links to everybody who’s signed up. You don’t have to scribble notes frantically. We’ll get you the recording link as well as a link to the slides that you can keep for your records.
Second, if you have questions, feel free to put them into the question and answer box. I can answer them in passing during the talk or at the end, as the case may be. Or you can throw them in chat. It’s not super busy today, so either way works. Any question is fair game, about Kubernetes, about ClickHouse, whatever.
With that, let’s dive in. Let me just check that we’ve got audio working. If somebody can confirm in chat that you can hear audio correctly and see the slides, that would be very helpful. Meanwhile, I’m going to go ahead and dive in.
A little bit about my background. My name is Robert Hodges and I’m the CEO of Altinity, so I run the business. But more importantly, I’ve been working on database services since 1983. I started with something called M204, and I’ve worked with about 20 different databases, of which ClickHouse is the last one.
I’ve also done work at VMware for a few years, where I worked on virtualization and security. It was at VMware, actually, that I was first introduced to Kubernetes, back in 2018. I’ve been using it ever since, and we’ve made a pretty major investment in it at Altinity.
As for a little bit about Altinity itself, we’re an enterprise provider for ClickHouse. Our goal is that if you are building analytic applications on ClickHouse, we’re here to help. We do everything that’s necessary to get your apps up and running, all the way from training and initial design to 24×7 support to operating it in the cloud.
What’s most relevant to this talk is that we’re the implementers of the Altinity Kubernetes Operator for ClickHouse and have a lot of expertise running Kubernetes. In fact, our whole cloud service runs on it, so we’re quite familiar with it and big fans.
With that, let’s dive into this. This is an intro talk. What we’re doing here is assuming that you’ve heard of Kubernetes but don’t necessarily know that much about it, and that you’re perhaps familiar with ClickHouse and you’d like to try running it on Kubernetes. The idea with this talk is to give you all the information you need to do that, to jump in and begin trying it out. So let’s talk for a little bit about what exactly Kubernetes is.
3:29 — What Kubernetes Is and Does
Robert Hodges: If you read the articles on the web, there’s just a lot of hype around Kubernetes. Sometimes I’ve even heard people call it the new Linux. That’s not very helpful. What Kubernetes actually is, is an open source platform that does a number of things, depending on what you’re interested in.
First and foremost, it’s what we call an orchestrator for container-based apps. A container is something like Docker, although there are other kinds. It’s a way of packaging software, specifically processes, and running a bunch of them together. Kubernetes is designed to take these applications that consist of containers, deploy them, and manage them.
The second thing Kubernetes is, from another angle, is that it’s defined through what we call infrastructure as code. When you want to define one of these applications, you give a specification that says what you’d like to see, and then Kubernetes makes it so. We’ll see examples of that as we go along.
The third thing is that Kubernetes is a great cluster manager. You can take a bunch of storage, compute, and network resources, glom them together in a Kubernetes cluster, and then start piling applications on. Kubernetes will take care of ensuring that the application resources are deployed in some rational way across all your underlying infrastructure.
Finally, you can see Kubernetes as an endpoint for automation, specifically for CI/CD pipelines. The deployment process can be automated to the max. If you have CI/CD running off your GitHub repo or your GitLab repos, you can actually have pipelines which push stuff all the way into Kubernetes and get the applications deployed to your users. So it’s a lot of things simultaneously.
What I’d like to do now is talk a little bit about what it actually does when it’s managing applications. When you use Kubernetes, it’s going to present to you this appearance of a big cluster that’s divided into things called namespaces. For example, every Kubernetes cluster has a namespace called kube-system, and that’s the namespace where all the resources that run Kubernetes itself actually run. There’s another namespace that comes up by default. It’s called default, and that’s where your resources are going to be allocated if you don’t ask for a particular namespace. Finally, you can make namespaces of your own.
The namespaces are really just a way of partitioning the different applications and having them run in different areas so that they don’t interfere with each other and you can keep track of them. There is also some ability to limit the connectivity between namespaces, to have different security in different namespaces, and so on. It’s actually not all that different from the notion of databases that we have within a SQL server.
What happens is that Kubernetes takes these resources in the namespace and maps them to the physical infrastructure, which is one or more servers connected by networking, shown here as the green arrows, with storage accessible. These are the three key things that Kubernetes is going to build on.
7:14 — Distributed Applications and Kubernetes Resources
Robert Hodges: We need to have a way of defining a distributed application using Kubernetes. Let’s take a typical example of a simple application. This actually turns out to be ZooKeeper, but it could be any of a number of distributed applications that have storage attached to each of the processes. What you’ll typically find in ZooKeeper is that it likes to run three nodes. You have three processes, they each have their own storage, they’re talking to each other and replicating, and then they have a load balancer in front of them. When people want to find ZooKeeper, they come to the IP address of the load balancer, the traffic gets routed to one of those processes, and they get the request served.
So that is the distributed application. What we need to do in Kubernetes is define resources that will allow Kubernetes to understand what it needs to do to make that application a reality.
If we have that application and we go look at what we’re going to find in resources, we’re going to see these things called services, stateful sets, pods, persistent volume claims, and persistent volumes. Let’s walk through what each of these is. Excuse me, I need to take a drink of water.
At the top we have this thing called a stateful set. This is a construct in Kubernetes that’s used to manage applications that consist of one or more processes with attached storage. What it does is take care of making sure that those containers have a rational, predictable name. It also ensures that when these pods come up, they get correctly attached to storage, and if the pod gets restarted, it finds the storage it was using previously and connects to it again. So this is the overall manager for things.
The pods themselves are just containers. Typically, and in the example I’m using today, they’re Docker containers, but they could be other types. There are a number of other types of containers you can use. Docker, at least for us, is by far the most common.
Then there are these things called persistent volume claims. A persistent volume claim is a request to have a certain amount of storage, like “hey, give me 25 gigs of storage on Amazon EBS.” That maps to an actual allocation of storage, which we call a persistent volume. By creating the persistent volume claim, Kubernetes has a controller that sees this and is going to go ahead and actually tell EBS to allocate the storage.
Finally, the service defines a load balancer which you can connect to, and then it will route traffic into one of the pods. There are also many other types of resources. I’ll give one example here. Config maps are a way of passing configuration data into Kubernetes and into the applications, so that they can find out things like “what’s my name?” and what parameters are necessary for the process to start correctly. There are many other resources besides that, but we won’t talk about them too much today.
11:04 — From Specification to Running Cluster
Robert Hodges: The question is, how does Kubernetes get from some list of resources that defines a useful application to actually having them out in Kubernetes running as something that you can connect to and use?
The way you do it is you put the specification for the Kubernetes resources in a YAML file. Here, as a simple example, I call it some-file.yaml. This is a specification. When we talk about infrastructure as code, this is a piece of YAML code that defines what you would like to see inside Kubernetes.
Then what you’re going to do is run a program called kubectl. This is a standard command line client that just takes that file and sends it to Kubernetes. Within Kubernetes itself, there’s a series of controllers which are basically watching for different types of resource requests. Kubernetes will process this file and send the resource requests that are in the file out to the appropriate controllers.
What each of those controllers does, for the resources it’s managing, is go out into Kubernetes itself and do what I call adjusting reality. It’s going to say, “if they’re asking for something and I don’t see it existing, I’m going to make it. If they’re asking for something and what I see is a little bit different than what they’re asking for, I’m going to change it so that Kubernetes matches the reality.” That’s basically how the application is created. The specification file just tells what you want, and then Kubernetes makes it so.
13:02 — Demo: Deploying ZooKeeper, and Where to Run Kubernetes
Robert Hodges: Rather than going more deeply into these pictures, it’s simpler to stop and show how this actually works. Let me pause my share to move something around and adjust the screen. All right, let’s re-share.
What I’m going to do is show you an example of one of these specifications. I’m going to show you a specification for creating a ZooKeeper application. This just has one node. I want to keep it a little simpler than that picture I showed you. Let’s go in and look at it.
What you basically see in the specification is requests that define a bunch of different kinds of resources. For example, a service resource, as I mentioned, is a load balancer. This is defining a load balancer that clients can use to connect into an arbitrary ZooKeeper instance. There’s another thing called a headless service. This defines a resource that can be used to address individual ZooKeeper instances.
Then there’s a very important resource, which is the stateful set. That’s defining this application that has state attached to it, and this becomes quite complex. It does things like tell how we want this updated, gives details that are helpful for things like Prometheus for monitoring, and says how to distribute the pods so that they don’t all go down if a machine goes down. It goes on for quite some distance, even including the command, in this case, to start ZooKeeper. So this is a fairly complex specification that somebody has taken a bunch of care to develop.
We can go ahead and run that quite simply. Actually, I need to clean something up first. Before I run this, I want to make sure that things are fully cleaned. This actually shows you how you get rid of resources. If I have a particular type of resource, in fact this turns out to be a ClickHouse cluster, I’m just going to delete it. I’m going to make sure there’s nothing going on inside the namespace where I’m going to load this ZooKeeper.
Looking at the namespace, it looks like we didn’t clean up fully before starting this, so let’s fix that quickly. We’re going to delete the ZooKeeper namespace, and as these resources clear out, we’ll be able to make something new. You can see up here our cluster is gone.
The thing about Kubernetes, and this is actually the dark side of Kubernetes, is that it’s really easy to delete stuff. As you’re working with Kubernetes, it’s fairly important to keep track of what you’re doing and put in an appropriate guard rail so you don’t delete things by accident. There are also a number of tricks you can use to protect things like storage. We’ll talk about that as we go further.
Here we go. We’re ready to apply that ZooKeeper definition. I’m going to run a script that will do this, because it will create the namespace and also run the file. We create the namespace, which is where the application is going to live, and then we run kubectl apply -f, which says “pump that file up to Kubernetes and make it so.” When this happens, we can then run kubectl get all -n zk to tell it which namespace we’re going to look at all the stuff running there. And there’s ZooKeeper, up and running. It’s as simple as that.
That’s a basic demo of how you create things in Kubernetes. You just load this file and then Kubernetes goes ahead and makes whatever’s in that definition happen on the infrastructure that Kubernetes is running on.
If we come back and look at the entities that were defined in that file, we see that the entities with the dashed lines are the network resources, there in green. The things related to the processes are in orange, and storage is in blue. What we end up allocating in Kubernetes, in this case minikube, is a load balancer, a Docker container that’s running, and it’s going to be attached to some storage. This all happened just by loading that file. It looks like a lot of resources, but as the applications get larger, these resources are just all the little bits that you need to build distributed applications.
Speaking of minikube, it’s worth talking about ways to run Kubernetes and where you can run ClickHouse clusters. The basic answer is pretty much everywhere. In development environments, I typically run minikube. There are many other things people use, but minikube is fairly straightforward to run on Linux in particular, so it’s great for development and testing.
If you want to run a self-managed Kubernetes, for example on your own hardware or up in the cloud, two popular ways are a tool called kops and another called Rancher. These take care of setting up Kubernetes and getting it ready for use. Finally, for people running in the cloud, it’s very popular to have what’s called managed Kubernetes, where you call a service like Amazon EKS. You can either go through the UI for Amazon, or you can use Terraform, and you can set up Kubernetes clusters which are then managed automatically by the EKS service. Every major cloud has one of these. Google has GKE, Azure has AKS, there are also services on DigitalOcean, there’s Tanzu for VMware, and many other providers for this.
That’s all we have to say about Kubernetes.
20:48 — What ClickHouse Is
Robert Hodges: What we want to do now is shift to discussing how to run ClickHouse on Kubernetes. Just in case you need it, here’s a quick introduction to ClickHouse.
ClickHouse is a data warehouse. In fact, it’s a SQL data warehouse, so it understands SQL. In many ways, when you first start it up, it looks a bit like running MySQL. There are some superficial similarities between the two SQL dialects. Like MySQL, it’s very portable. It runs pretty much everywhere. Interestingly enough, it can run on anything. It can run on an Android phone, it can run as a container, it can run on a VM, it can run in rack gear. It doesn’t really matter. The only key thing you want is that you should have Linux if you’re running it in production.
Another way ClickHouse is similar to MySQL is that it’s open source. In this case it’s Apache 2.0, so it means you can take it and use it pretty much anywhere you want. You can bundle it in software you’re shipping, so it can be used for any business purpose that interests you.
Where it departs from MySQL is the actual data warehouse features. For example, we store data in columns and with very high rates of compression. This is similar to products like Snowflake, Redshift, or Vertica. We also have very good parallelization of execution, so we can spread queries across multiple nodes. Moreover, within single nodes, the queries are vectorized, which means they’re broken up into pieces and farmed out to individual CPUs. We use what are called SIMD instructions, single instruction multiple data, which allow us to do things like calculating aggregates four or eight at a time using specialized registers.
ClickHouse also has built-in sharding and replication, so you can create shards and have replicas. We’ll show you how to do this, and it scales extraordinarily well. If you build your application and use ClickHouse effectively, you can basically get linear scaling as you add resources, and this will work out to tens of petabytes. So it’s a very powerful data warehouse, probably the best open source SQL data warehouse that’s ever been developed, and it is very popular at this point.
23:15 — Why ClickHouse Needs an Operator
Robert Hodges: There’s just one problem. What I just described is an effectively quite complicated distributed application, particularly because we have a lot of shards, we potentially have a lot of replicas, and we also have ZooKeeper out there, which at least in the current version of ClickHouse is necessary to keep the replicas in sync.
What you end up having to do, if you were going to just use a file like what we showed a few minutes ago, is you would actually have to have an extraordinary number of resources. Moreover, you’d have to be constantly changing them every time your usage changed and you decided to add more resources, for example to scale the service. That would be really painful. You’ve seen that file. It’s not a pretty sight.
Fortunately, there’s a solution, and it’s something called an operator. This is a relatively new feature of Kubernetes. It first appeared a few years ago. What an operator does is allow you to define new types of resources in Kubernetes. So we developed the Altinity Kubernetes Operator for ClickHouse. What it does is consume a resource definition for ClickHouse that’s just a single file, relatively simple. When it comes in, Kubernetes will send it to the Altinity Operator, which will look at it and then go through this process again of adjusting reality, defining the underlying Kubernetes resources that are necessary to create the cluster.
That gets what we call a best-practice deployment, where it sets up a ClickHouse, does the configuration files, which are relatively complex, helps you ensure that you get the right amount of storage, and so on. It provides monitoring and a bunch of stuff that’s necessary to really run ClickHouse, particularly in production on Kubernetes. This all happens from a single file.
25:33 — Installing the Operator and Deploying a Cluster
Robert Hodges: In order to use this, the first thing we need to do is install the operator itself. This shows the commands. It’s really simple. We’ll apply them in a second, and by default we put it in kube-system along with all the other system resources for Kubernetes itself.
The second thing we need to do, because we depend on ZooKeeper, is install ZooKeeper itself. We don’t have to do that right now because I just did it a minute ago, but this shows you the commands to install a development version of ZooKeeper. By the way, if you’re thinking about repeating this at home, and I hope you will, this is a dev-test environment that we’re creating here. It uses one ZooKeeper node. In a real production environment you would always have three ZooKeepers. That’s the recommended number. You might have five, but you would certainly not have one, because if it goes down, ClickHouse replication will stop working.
Rather than diving into the details of the specification we use to define ClickHouse, it’s simpler to show you how it works. Let’s go in and actually bring up a data warehouse. We’ll put away the slides. The first thing I’d like to do is run those commands to install the operator, just in case it’s not installed.
What I did was pull down the definition of the operator. It’s just a wget. I’m running on Ubuntu here, so all my nice Linux commands work. I do the wget, I pull the file, and then I run kubectl apply -f, which simply applies this file. If you look at the details, this has a bunch of information defining the operator, what sort of energy it manages, and a bunch of things that allow Kubernetes to understand how to fit it into the API. Once it’s running, within a few seconds it’ll pull that container and deploy it. In fact, we can see that within two seconds this is up and running. It might have been there already, in which case Kubernetes is just checking to make sure it’s in the state we asked for. So there it is. That’s all there is to installing an operator. In this particular case, it’s a total of two commands.
We don’t need to do ZooKeeper because it’s already out there, but what we’d like to do is install our cluster. Before we do that, let’s do an ls. Here’s our cluster.yaml file. You saw that complex cluster for ZooKeeper, which was already less complex than ClickHouse. Let’s look at the configuration here. It’s relatively simple. We define this thing called a ClickHouse installation. We’ll talk more about this. We have a little bit of information about what the cluster should look like, where to find ZooKeeper because we’re going to connect to it, and we’re also going to have some templates which define what kind of pods we want to start, for example the version as well as storage. We’ll look at the details of that in a few minutes back in the slides, but this is relatively simple, with very little to fill out to get a working cluster.
Let’s go ahead and apply that. I’m going to run a script again just to make sure I get everything. We’re going to install the ClickHouse cluster. It’s relatively simple. It’s just going to run kubectl apply -f. What we can see is the pods starting up from the stateful set in the default namespace, which is where it’s running. So we’ve already got one of the ClickHouses up and running. A second one is now running but not fully ready, so we should see that. Moreover, if we look down below, we see the storage requests have been made, and we’ll have storage attached as well. At this point we’ve got a cluster up and running and we’re ready to log in and talk to it. But what I’d first like to do is show you a few details about how we got there.
30:31 — Inside the Resource File and Pod Templates
Robert Hodges: Let’s pull the slides back up and look in more detail at what’s in that resource file. If you’re going to run Kubernetes yourself, you’re going to need to fill this out. We have examples that you can use, but this will give you the highlights.
First of all, as I mentioned, the resource type is ClickHouse installation. This arrow is pointing at the name of it. This says that when Kubernetes sees this, it knows that this needs to be handed over to the operator to figure out what to do with it. It’s got a name so that it’s unique and distinguishes it from other clusters you may be running.
Within the configuration, we can define a specific cluster. I call this one “demo,” and I asked for two shards with one replica each. Then you see I have a couple of references to these things called templates, one to tell me how to find the ClickHouse executable, and the second one to get some persistent storage. We’ll look at that in just a second. Finally, I have a section to tell me how to find ZooKeeper, because ClickHouse will need to know its name so that it can put that in the configuration files.
Under the templates, we see the further definitions. First of all, the pod. This is saying, “I want to run ClickHouse, I want to run version 21.6.” This is the Docker server that comes off the community builds, which are created by Yandex, so it comes off their Docker Hub repo. Then we have what I call volume claim templates. As you can see down at the bottom, this is going to ask for storage. We use the same syntax here as you do in a normal Kubernetes volume claim. Give it a name, say how much we want, the access mode read-write-once. That just says this is not going to be shared. It’s not a distributed file system shared by a bunch of pods. It’s just used by one pod.
Finally, a very useful property here called a reclaim policy. This says, “if I delete the cluster, don’t delete the underlying storage, because maybe I did it by accident and I’d really like to get it back.” So this is useful to help protect your storage from fat fingers. These definitions, these few lines of code, were sufficient to get me a fully configured ClickHouse server with a couple of shards in it, up and running.
33:13 — Basic Operations and Improving the Cluster
Robert Hodges: When you actually create a ClickHouse cluster, what I recommend doing is some basic operations so that you can make sure it’s in good state, check into it, and then make it available externally.
First things first, I always go and check the persistent volumes to make sure it really has storage. We can repeat this when we get back out to the demo environment. Second, you can get into it quite easily. We’ll show this shortly. You can use the kubectl exec command. That’s a way of getting in and directly talking to one of the ClickHouse instances. Finally, if you’re using minikube, what we commonly do is what’s called port forwarding, where we expose that service for ClickHouse. It’s called clickhouse-on-kubernetes, and we expose it on port 9000. This allows clients outside of Kubernetes to connect to it and use it. These are three things you’ll do when you get set up, and at that point you’re ready to start playing around with ClickHouse and developing applications.
Here’s what we’ve created. We saw this in the kubectl commands where we’re getting the resources and showing what’s going on. We have ZooKeeper, which we set up at the beginning in its own zk namespace. In the default namespace, we’ve got ClickHouse running version 21.6, and we don’t have any replicas. We’ve only got a couple of shards.
So here’s a question. How can we make it better? I’m going to show you three ways you can improve this. The first is that we could add more replicas. The second is that we could change the version. The third is that we could add a user, which wasn’t easy to put in this picture, so I didn’t do it, but I will show you how to do it in the configuration file. Let’s walk through the different ways we can do this.
First, increasing the number of replicas. All you have to do is go into the specification file and change the number of shards and the count of replicas. That’s it. They will pop up and start to run. As soon as the operator reads this, it will create additional nodes until the shard and replica count is fulfilled. If you decrease it, by the way, it will remove replicas, so you can scale down as well as scale up.
Another thing we can do, as I mentioned, is add a user. This is an example of adding a user which is able to do what is called RBAC management, role-based access control, or SQL role management. I call it “root.” It’s got a SHA-256 password. If you’re familiar with defining users in XML, this basically will fill out an XML file so that we can get into the server and do additional SQL operations to create the rest of the accounts. So that’s how we define a user.
The final thing is how we change the ClickHouse version. Very simple. All we have to do is change the pod version, and voila, when it sees this file it’ll pull the appropriate pod. So these are simple ways that you can improve your ClickHouse cluster using the specification file.
It’s finally worth talking about what actually happens when that file is processed. When we have a file that has any of these changes, you load the file using kubectl apply -f as we showed before. The operator gets the file forwarded by Kubernetes, goes out and looks at the resources, and then comes up with a plan for doing the upgrade. Let’s say we had four pods already, with two shards and two replicas, and we asked to change the version. What the operator will do is go around and restart each of the pods in turn to bring it up with the new version. Or we could have increased the memory, the CPU, or other resources available to the pod. The key thing here is the operator does this sequentially. The idea is to make changes to the cluster which do not cause your applications to go down, because we do things one at a time, and at any given time only one replica is down.
38:18 — Demo: Storage, Access, and a Live Upgrade
Robert Hodges: That’s the process. Let’s illustrate this as a demo. Let me go in and show a few of the commands I mentioned. For example, checking for storage. We can run the kubectl get pv command. That shows our persistent volumes across the entire system. Here we see a persistent volume, and it’s bound. We can see that’s actually the name of the request, but we can easily track which pods they belong to. This is good, and we see that they’ve got 10 gigs allocated. We feel good because we know that if we’re putting data into it, it’s not going to ephemeral storage and it won’t disappear when the pod goes away.
Getting into the pod, let’s use kubectl exec. Let’s get our pod name first, since we have to give our pod name. Let’s copy that in. We’re going to use bash and go straight in. We’re now inside the pod and we can have a look around. We can see that we’re in the ClickHouse server directory. If you’re familiar with ClickHouse, you can make sure that all the configuration files are done correctly. Take it from me, they generally are.
One other side effect of this: if you’re just learning Kubernetes, or more to the point if you’re just learning ClickHouse, this is a really great way to see how to configure a ClickHouse server properly. You can bring it up on Kubernetes, the files are all generated for you, and if you then want to go install on VMs, you can use those as examples that you can copy and then set up ClickHouse in other locations.
Finally, we can get into the ClickHouse server itself with clickhouse-client. We come up and we’re running. We can see it’s version 21.6. Let’s confirm that. There it is, it’s 21.6, that’s the actual build.
The final thing is port forwarding. I have the port forwarding command and a script. There it is. This is just an example of how to port forward. I’m going to run that, and at this point I can connect from the command line. This should work. I’ve remapped the port a little bit to avoid colliding with another ClickHouse server. Okay, in we go. I just connected in from an external client. At this point you’re set up and ready to do development.
Let’s do the last part of the demo, which is to demonstrate how the upgrade works. We’ll quit out of this. What I’d like to do is a quick diff of the cluster.yaml file we installed and the new one we’re going to install. In this case we’re just going to add replicas. Let’s diff those two files so you can see the change. It’s really simple. We just changed the replica count.
Now we’re going to apply the new file. We just run the command for that. There it is. It’s as simple as kubectl apply -f and the name of the new file. Then, if we go over and look on our display on the upper left, we’re going to start to see new entities emerging. For example, the print may be a bit small, but you can see there’s a new pod coming up. There’s also a new persistent volume claim, which is going to allocate storage as soon as that pod is up and running. We expect to see another replica coming up. There it is, container creating, and we see a corresponding persistent volume request.
That’s an example of how to do the upgrades. It’s very simple. This is a very powerful way of organizing these things that works very well, particularly as you get large production systems. In fact, we have customers that run these, we ourselves run our entire cloud service on it, and many of our customers run on Kubernetes. In some cases they’re running on clusters that contain 50 to 100 nodes. These are major systems. With that, we’re done with the demo. Let’s go back and conclude the talk.
43:27 — Documentation, Closing, and Q&A
Robert Hodges: Here’s how to get more information. This will get you started. You can go and look at the code for the Altinity Kubernetes Operator. Just Google that, or when you get these slides, the link will take you to the GitHub project. We also have Altinity documentation at docs.altinity.com. There is documentation for how to install the operator and bring up clusters in Kubernetes. There are also community docs for ClickHouse itself, which are quite extensive and are basically the reference document for ClickHouse and the SQL dialect it uses. Finally, there’s the Altinity blog. We write constantly about ClickHouse-related topics, including how to run it on Kubernetes, but you’ll find all kinds of things there, everything from BI tools to how to manage storage to tricks with new SQL features.
With that, we are complete. I’ll leave you with a few links. You can get to ClickHouse on GitHub, shown here. Our Altinity website is at altinity.com. If you want to find out about the cloud, it’s pretty easy. If you don’t want to bother with running ClickHouse itself in Kubernetes, you can let us do it. We’re happy to do that.
Since we’re on the topic of things you can find on the website, we have a bunch of job descriptions. We’re hiring and actively looking for experts in Kubernetes and cloud technology, ClickHouse itself, and other areas. So thank you very much. I hope this talk has been useful. I’ll open it up for questions and hang around to answer them. Otherwise we’ll conclude the webinar. Feel free to post questions in the question box if you have them. Let me have a quick check to see if we’ve got any that have queued up. I don’t see any open questions right now.
For those of you watching this later in the recorded version, we’re doing this in July, right in the middle of vacation, so it’s a bit of a quiet time for webinars. I don’t see any questions coming up, so thank you all very much for attending. I hope this has been useful. Please do contact us at Altinity if you’d like to look into this further. Have a great time running ClickHouse on Kubernetes. Thank you very much and have a great day.
FAQ
What is Kubernetes, in simple terms? Kubernetes is an open source platform that acts as an orchestrator for container-based applications. It deploys and manages containers, lets you define applications as code through specifications, manages clusters of compute, storage, and network resources, and serves as an automation endpoint for CI/CD pipelines. You describe what you want in a file, and Kubernetes works to make reality match that description.
Why does running ClickHouse on Kubernetes usually require ZooKeeper? In the version of ClickHouse discussed in this webinar, ZooKeeper coordinates replication and keeps replicas in sync. For development and testing you can run a single ZooKeeper node, but a production deployment should always use a ZooKeeper ensemble of at least three nodes. With only one node, a failure would stop ClickHouse replication from working.
What does the Altinity Kubernetes Operator for ClickHouse actually do? The operator lets you define a ClickHouse cluster with a single, relatively simple resource file. Kubernetes hands that file to the operator, which then creates and adjusts all the underlying resources needed for a best-practice deployment, including configuration files, storage, and monitoring. This replaces the large, hard-to-maintain set of raw resources you would otherwise have to manage by hand.
How do you scale a ClickHouse cluster or upgrade its version on Kubernetes? You edit the specification file. To scale, you change the shard and replica counts, and the operator adds or removes nodes to match. To upgrade, you change the pod version. When you reapply the file, the operator builds an upgrade plan and restarts pods sequentially, keeping only one replica down at a time so that your applications stay available.
Where can you run Kubernetes to host ClickHouse? Practically anywhere. For development and testing, minikube is a common and straightforward choice on Linux. For self-managed clusters on your own hardware or in the cloud, tools like kops and Rancher are popular. For managed Kubernetes in the cloud, every major provider offers a service, such as Amazon EKS, Google GKE, and Azure AKS, with other options including DigitalOcean and VMware Tanzu.
Why is ClickHouse considered a fast data warehouse? ClickHouse stores data in columns with high compression, parallelizes query execution across nodes, and vectorizes execution within a node using SIMD CPU instructions to process multiple values at once. Combined with built-in sharding and replication, this lets it scale roughly linearly into the tens of petabytes while remaining open source under the Apache 2.0 license.
© 2026 Altinity, Inc. All rights reserved. Altinity®, Altinity.Cloud®, and Altinity Stable® are registered trademarks of Altinity, Inc. ClickHouse® is a registered trademark of ClickHouse, Inc. Altinity is not affiliated with or associated with ClickHouse, Inc. Kubernetes, MySQL, and PostgreSQL are trademarks and property of their respective owners.
ClickHouse® is a registered trademark of ClickHouse, Inc.; Altinity is not affiliated with or associated with ClickHouse, Inc.