Resources

Kelly O'Briant | Remote Content Execution with RStudio Connect and Kubernetes | RStudio (2022)

This summer the Posit Connect team will announce a feature which has been over two years in the making: “Remote” off-host content execution with launcher in Kubernetes. We have been quietly beta testing the Launcher feature with select partners and customers for several months while we prepare for the public announcement. This talk will highlight why someone might want to use this new execution mode with Connect, show just how seamless it is to get everything configured in a fresh environment on EKS, and finally set some critical context for what publishers and administrators should expect by addressing the anticipated FAQs. Talk materials are available at https://kelly.quarto.pub/rstudioconf-talk-2022/ Session: Data science in production

Oct 24, 2022
19 min

image: thumbnail.jpg

Transcript#

This transcript was generated automatically and may contain errors.

Apologies, I do have COVID right now, which is why I can't join you in person. And so I am congested, and I will try not to cough into the mic, and I'll speak fully and as loudly as I can.

So, I wanted to show you, or talk about the breadth of what REST can do and support because it is getting quite complex, and that's one of my favorite things to do at conferences, talk about what you're doing with Connect, what workflows you're building out, what things you're creating, and this diagram just represents some of what those things could be, but interacting with Connect should be quite simple. It shouldn't be complex.

Essentially, what you're doing is creating something in R or Python, you're publishing that thing to Connect, and then you're letting Connect take over it, executing that thing for you and whoever else you share that thing with.

Under the hood, Connect allows you to do some really cool stuff. You can run multiple versions of R and Python. You can now run multiple versions of Quarto as well on the single server, and your applications, your documents, your APIs, everything that you create and publish to Connect, all of those things are sandboxed apart from one another so that you can run those different versions of packages for all of your content.

Fundamentally, though, if you're using Connect today, all of the content you publish there, all of it runs using these local processes on the same host or container as the Connect server. That's what I want to draw your attention to because this talk is what comes next for Connect here. It's about our next evolution for content execution and our story there.

Announcing off-host content execution

Today, we're really excited to announce off-post content execution for Connect on Kubernetes. This feature will be in beta for now, but if you are a Connect admin, we would love for you to give it a try and we'll see what beta means in a bit.

Let's talk about what this means for you. In this world, when you're running off-post content execution, now instead of using local processes to run all of your content items in the same place on the Connect server, Kubernetes is used to execute your content. All of your jobs are external to the container that's running that Connect server.

I want to pause here and make sure that if you are a data scientist or a Connect publisher in the audience today, you should know that I am not here to tell you that you need to run home and learn how to containerize your applications or teach yourself Kubernetes. Our goal is not to take away the simplicity of that publishing user experience like I talked about at the beginning of this presentation.

In fact, the publishing user experience should not change remarkably so if you are running off-post content execution. Instead of tell you, let me show you what that looks like.

In fact, the publishing user experience should not change remarkably so if you are running off-post content execution.

Publisher experience demo

If you come over here to the documentation page in the Connect dashboard and you scroll down to where you used to see all of the versions of R, Python, Quarto that are available on your server. If you're running off-post execution, you'll now see a list or a set of execution images. These are going to show you the options that you have as a publisher for what sorts of environments that can be used to build and execute your content.

You can choose to target a specific one of these images if you're publishing or you can let Connect just pick for you as a version matching algorithm just like it picked for you when you do publishing today.

All right, so I'm going to run through a quick GitBack publishing demo here just to show you what this looks like from the user experience perspective. With GitBack publishing, in addition to all the other publishing methods, this really shouldn't change very much.

I'm going to grab a URL here, drop it in. This is my repo. I'm going to select a branch and then select the application in my repo that I want, give it a title, app1.

And when I hit deploy, again, because I haven't specifically told Connect which execution image that I want to use to build and execute this piece of content, it's just going to find one that runs R4-1 for me. When I open it up here, I will be able to see my content item and it will use that same execution image.

Now, you will notice a little bit of delay here when you launch an application in off-host execution mode. And some of that has to do maybe sometimes with pulling down that execution image, but a lot of the cost is wrapped up in job spawning and process startup. So there is a little bit more of a delay, but again, if you wanted to work around that, you have the same tools as you do with local execution where you can set the minimum processes. You want to have one always available if this is a particularly important app that needs to come up very quickly for your users.

Now, let's see which content execution image Connect actually picked for me. And I'm going to bump up here so you can see, scroll down, you'll see you have a new piece of metadata here at the bottom of the content info pane. And this just lists the image that got used for our last execution.

If I wasn't intending to target that image, then I would need to go back and regenerate the manifest file and specify a new image parameter. And this is all described in the user guide here. So you can see how you can add the image that you're looking for specifically if you are generating a manifest.

You can also use the deploy app, deploy API, deploy doc, deploy site functions from RSConnect and similar functions exist for RSConnect Python as well. If there isn't an image that matches the version of our Python that you need, you'll get the same type of deployment error as you would today using local execution with local processes if there isn't a version of our Python on your server that's available.

All right, so hopefully that has reasonably convinced you that the user experience isn't going to change remarkably, although you can now target images if you want to do that. We don't yet have support for push button publishing or targeting specific images, but that is on our roadmap. So look out for that if you're interested.

Administrator setup and installation

All right, so now that I've gone through that, I want to switch gears and talk more directly to maybe the administrator persona about what this looks like. So let's talk about off-host execution from that angle.

Now, if you are an admin, you should know that this functionality uses the same components if you're familiar with the RStudio Workbench product and its Studio Job Launcher components. But we're using that same paradigm, but bundling it with Kinect. So if you want to run off-host execution with Kinect, you're going to need to use a version of Kinect that has the Job Launcher bundled with it. So I recommend starting with the latest release of Kinect, which is our July edition that went out last week.

In addition to that, you're going to need to have, as always, a valid Kinect license and then database, and that'll be Postgres for this case, and then some shared file storage. It could be NFS or EFS, anything that's read-write-many. On the Kubernetes requirements side, you're going to need, of course, a working Kubernetes cluster. You're going to need the Kubernetes command line tool and also Helm version 3, which is the package manager for Kubernetes in this case. If you have all of those things, you're basically set up to go at this point.

And we have documentation for how to run through, install, and configure to get all the way to this point. But I've shown a lot of architecture diagrams at this point, and they're kind of not the best way to illustrate all of this. So because I'm remote and nobody is here to stop me, I thought it would be cool just to do a speedrun installation of all of this, see how far we can get, and show you just how fast and easy it is to get up and running.

Hopefully that will be what happens, will be fast and easy. I have cheated a little, as always, as any good speedrun installation does. I've already set up my Kubernetes cluster, get nodes, where they are, they're ready to go. And I've already set some environment variables. I set up my RStudio connect license key so that you can't see that, my key. And then I've also created a database password for my Postgres database.

I have the Kubernetes pool, kubectl, kubectl, whatever it's called there, installed, and Helm. That's all set up. And in this next section, we will Helm install all the things.

This is really just a talk subtitled A Love Letter to Helm, and Helm is really awesome, and we're excited to be able to install everything this way, because it makes the installation so simple. It makes it repeatable. You can update, you can roll back, and sort of stage your deployment, and I'll show you what some of that looks like here later.

And the first thing we'll need to do is pull down a bunch of Helm charts in order to do that, and update the Helm repo. So we provide a chart for installing RStudio connect here, so grab that, in addition to the one for Postgres and NFS, and it will update the repo. The Postgres and NFS charts are just sort of for illustrative purposes. We're assuming that most folks are going to bring their own Postgres and NFS or EFS, and we'd write many shared storage. But if you didn't have anything like that, or if you're doing the same sort of speedrun installation that I'm doing here, you can use these to get up and running really fast.

All right, so we've got all our charts ready to go, and the next thing we're going to do is create a namespace to install everything into, and this will just keep everything nice and sandboxed and tidy. I'm going to call this namespace RStudio connect.

And once we have that, and we've switched into it, we can now start Helm installing things. So the first one, I'll Helm install my Postgres chart. I'm actually using this Helm upgrade install command, which I just learned a couple weeks ago, which is really cool, because you can just run the same thing over and over again, and it upgrades it if it already exists. It installs it if it doesn't.

I'm going to do the same with my NFS server provisioner chart. Run that. All right, now, if I've done everything correct, I should be able to get some pods. Awesome, so I've got my NFS creating, my Postgres is running, and I'm good to go.

All right, now we're on to the Connect installation. So if you wanted to look at all of the default values that come with the RStudio Connect Helm chart, you can do a Helm show values on the Connect chart, and that'll just give you the whole list. There's quite a lot. I'm going to go ahead and skip that.

What we're going to do is overwrite some of those default values with a values.yaml file. So let's create that new file, and this first part is going to set the replicas, and then I'm going to configure shared storage here. So let me grab all that, dump that in. Connect needs shared storage, needs to be mounted in. You need to create a persistent volume claim and give it a name here, and this name is arbitrary, though it's used in a couple places here. So make sure if you change that, that you change it in all the places that it needs to be changed, and you're going to create a storage class for NFS, tell it how much storage you're requesting, and then finally, enable the launcher, and that's all there is to it.

So if I save out here, values.yaml, save, all right, now I am good to go. And from here, sort of your process for using Helm is to change this values.yaml file and then run this command here, Helm template the chart with your values file, and this sort of pattern, updating your values.yaml and then checking it on Helm template will show you like how your values file affects the template.

And that's sort of like what my buddy Cole and Helm wizard calls the bread and butter of using Helm. This is sort of the power, and it's also going to be really useful as we interact with you because you can send us your values.yaml file, and then we at our studio on the support side can run this same Helm template command and see exactly what you're saying, and see how your values.yaml file is going to interact with the template, so that's really useful.

The other section that we're going to want to add to this values.yaml file is some configuration for Connect itself. So this is where the things that you would traditionally put in your Go configuration file are going to get dumped instead. So we'll add that, and you'll see that we are adding a database configuration. We're saying it's going to be Postgres, and that'll overwrite the default of SQLite. I'm going to give it an address. And if you're using the Connect namespace, the RStudio-Connect namespace, that URL should be correct.

And then you're just going to provide the same persistent volume claim name for this new section of configuration for Connect launcher, and that should match what you had up here. So let's save that out. And now, if I did everything correct, we should be able to home install Connect. So let's give it a shot. Installing it now.

You're just out of time, unfortunately. Yeah, if you can wrap up in, like, 30 seconds, if we have the final thought as we sort of switch over. There's a couple of questions I saw folks ask on Slido. Please ask those at the open source lounge, and let's give Kelly a hand for the talk.

Yeah, thanks. I wanted to say thank you to the team, for sure. This project has come together over a while by a number of folks at our studio, the core team, as it is today. I want to say congratulations to Aaron and Bill, Chyda, Chris, Cole, David, and Jill. And thank you to all of the folks who helped us out during the private beta over the last year. It's been really great. So thank you.