Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

Commit

Permalink
suggested fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
madhur-tandon committed Oct 21, 2022
1 parent 1f7fd4a commit fa0928b
Showing 1 changed file with 103 additions and 102 deletions.
205 changes: 103 additions & 102 deletions content/docs/user-guide/deploying/kubernetes.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
# Kubernetes

Deploy a model to a kubernetes cluster exposing its prediction endpoints through
To serve models in production in a scalable and failure-safe way, one needs something more than Heroku. [Kubernetes](https://kubernetes.io/docs/home/) is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications.

Below, we will deploy a model to a kubernetes cluster exposing its prediction endpoints through
a service.

## Preparation
## Requirements

```bash
pip install mlem[kubernetes]
# or
pip install kubernetes docker
```

### Preparation

- Make sure you have a Kubernetes cluster accessible, with the corresponding
kubeconfig file available.
Expand All @@ -13,13 +23,7 @@ a service.
- Nodes are accessible and reachable, with an external IP address (valid for a
NodePort service, more details to come below).

## Requirements

```bash
pip install mlem[kubernetes]
# or
pip install kubernetes docker
```
One can access a [basic](https://kubernetes.io/docs/tutorials/kubernetes-basics/) tutorial to learn about the above terms.

## Description

Expand All @@ -33,18 +37,33 @@ Once this is done, one can use the usual workflow of
[`mlem deployment run`](/doc/command-reference/deployment/run) to deploy on
Kubernetes.

<details>

### ⚙️ About which cluster to use

MLEM tries to find the kubeconfig file from the environment variable
`KUBECONFIG` or the default location `~/.kube/config`.

If you need to use another path, one can pass it with

`--conf kube_config_file_path=...`

</details>

<admon type="tip">

You can use [`mlem types deployment kubernetes`](/doc/command-reference/types)
to list all the configurable parameters.
You can use `mlem deploy run kubernetes -h` to list all the configurable parameters.

</admon>

Most of the configurable parameters in the list above come with sensible
defaults. But at the least, one needs to follow the structure given below:

```cli
$ mlem deployment run service_name --model model --env kubernetes --conf service_type=loadbalancer
$ mlem deployment run service_name \
--model model \
--env kubernetes \
--conf service_type=loadbalancer
⏳️ Loading model from model.mlem
💾 Saving deployment to service_name.mlem
Expand Down Expand Up @@ -83,8 +102,8 @@ One can check the docker image built via `docker image ls` which should give the
following output:

```
REPOSITORY TAG IMAGE ID CREATED SIZE
ml 4ee45dc33804b58ee2c7f2f6be447cda 16cf3d92492f 3 minutes ago 778MB
REPOSITORY TAG IMAGE ID CREATED SIZE
ml 4ee45dc33804b58ee2c7f2f6be447cda 16cf3d92492f 3 minutes ago 778MB
...
```

Expand All @@ -94,18 +113,18 @@ Pods created can be checked via `kubectl get pods -A` which should have a pod in
the `mlem` namespace present as shown below:

```
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6d4b75cb6d-xp68b 1/1 Running 7 (12m ago) 7d22h
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6d4b75cb6d-xp68b 1/1 Running 7 (12m ago) 7d22h
...
kube-system storage-provisioner 1/1 Running 59 (11m ago) 54d
mlem ml-cddbcc89b-zkfhx 1/1 Running 0 5m58s
kube-system storage-provisioner 1/1 Running 59 (11m ago) 54d
mlem ml-cddbcc89b-zkfhx 1/1 Running 0 5m58s
```

By default, all resources are created in the `mlem` namespace. This ofcourse is
configurable using `--conf namespace=prod` where `prod` is the desired namespace
name.

### Making predictions via mlem
### Making predictions via MLEM

One can of course use the
[`mlem deployment apply`](/doc/command-reference/deployment/apply) command to
Expand All @@ -125,22 +144,69 @@ A model can easily be undeployed using `mlem deploy remove service_name` which
will delete the `pods`, `services` and the `namespace` i.e. clear the resources
from the cluster. The docker image will still persist in the registry though.

<details>
## Swapping the model in deployment

### ⚙️ About which cluster to use
If you want to change the model that is currently under deployment, run

MLEM tries to find the kubeconfig file from the environment variable
`KUBECONFIG` or the default location `~/.kube/config`.
```cli
$ mlem deploy run service_name --model other-model
```

If you need to use another path, one can pass it with
This will build a new docker image corresponding to the `other-model` and will
terminate the existing pod and create a new one, thereby replacing it, without
downtime.

`--conf kube_config_file_path=...`
This can be seen below:

</details>
### Checking the docker images

```
REPOSITORY TAG IMAGE ID CREATED SIZE
ml d57e4cacec82ebd72572d434ec148f1d 9bacd4cd9cc0 11 minutes ago 2.66GB
ml 4ee45dc33804b58ee2c7f2f6be447cda 26cb86b55bc4 About an hour ago 778MB
...
```

Notice how a new docker image with the tag `d57e4cacec82ebd72572d434ec148f1d` is
built.

## Case Study: Using EKS cluster with ECR on AWS
### Checking the deployment process

The deployment to a cloud managed kubernetes cluster such as EKS is simple and
```
⏳️ Loading deployment from service_name.mlem
⏳️ Loading model from other-model.mlem
🛠 Creating docker image ml
🛠 Building MLEM wheel file...
💼 Adding model files...
🛠 Generating dockerfile...
💼 Adding sources...
💼 Generating requirements file...
🛠 Building docker ml:d57e4cacec82ebd72572d434ec148f1d...
✅ Built docker image ml:d57e4cacec82ebd72572d434ec148f1d
✅ Deployment ml is up in mlem namespace
```

Here, an existing deployment i.e. `service_name` is used but with a newer model.
Hence, details of registry need not be passed again. The contents of
`service_name` can be checked by inspecting the `service_name.mlem` file.

### Checking the kubernetes resources

We can see the existing pod being terminated and the new one running in its
place below:

```
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-pr8cn 1/1 Running 0 90m
...
kube-system kube-proxy-dfxsv 1/1 Running 0 90m
mlem ml-66b9588df5-wmc2v 1/1 Running 0 99s
mlem ml-cddbcc89b-zkfhx 1/1 Terminating 0 60m
```

## Example: Using EKS cluster with ECR on AWS

The deployment to a cloud managed kubernetes cluster such as [EKS](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html) is simple and
analogous to how it is done in the steps above for a local cluster (such as
minikube).

Expand All @@ -163,7 +229,7 @@ used.

</admon>

The popular docker registry choice to be used with EKS is ECR (Elastic Container
The popular docker registry choice to be used with EKS is [ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) (Elastic Container
Registry). Make sure the EKS cluster has at least read access to ECR.

### ECR
Expand All @@ -179,7 +245,13 @@ Provided that the default kubeconfig file (present at `~/.kube/config`) can
communicate with EKS, execute the following command:

```cli
$ mlem deploy run service_name --model model --env kubernetes --conf registry=ecr --conf registry.account=342840881361 --conf registry.region="us-east-1" --conf registry.host="342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier" --conf image_name=classifier --conf service_type=loadbalancer
$ mlem deploy run service_name \
--model model --env kubernetes \
--conf registry=ecr \
--conf registry.account=342840881361 \
--conf registry.region="us-east-1" \
--conf registry.host="342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier" \
--conf image_name=classifier --conf service_type=loadbalancer
⏳️ Loading model from model.mlem
💾 Saving deployment to service_name.mlem
Expand Down Expand Up @@ -278,9 +350,7 @@ $ mlem deployment apply service_name data --json
i.e. `mlem` knows how to calculate the externally reachable endpoint given the
service type.

### A note about NodePort Service

<admon type="info">
<admon type="info" title="A note about NodePort Service">

While the example discussed above deploys a LoadBalancer Service Type, but one
can also use NodePort (which is the default) OR via
Expand All @@ -295,72 +365,3 @@ This can be seen as the last rule being added below:
![alt text](/img/inbound.png)

</admon>

## Swapping the model in deployment

If you want to change the model that is currently under deployment, simply run

```cli
$ mlem deploy run service_name --model other-model
```

This will build a new docker image corresponding to the `other-model` and will
terminate the existing pod and create a new one, thereby replacing it, without
downtime.

This can be seen below:

### Checking the docker images

```
REPOSITORY TAG IMAGE ID CREATED SIZE
342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier d57e4cacec82ebd72572d434ec148f1d 9bacd4cd9cc0 11 minutes ago 2.66GB
342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier 4ee45dc33804b58ee2c7f2f6be447cda 26cb86b55bc4 About an hour ago 778MB
...
```

Notice how a new docker image with the tag `d57e4cacec82ebd72572d434ec148f1d` is
built.

### Checking the deployment process

```
⏳️ Loading deployment from service_name.mlem
⏳️ Loading model from other-model.mlem
🛠 Creating docker image classifier
🛠 Building MLEM wheel file...
💼 Adding model files...
🛠 Generating dockerfile...
💼 Adding sources...
💼 Generating requirements file...
🛠 Building docker image 342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier:d57e4cacec82ebd72572d434ec148f1d...
🗝 Logged in to remote registry at host 342840881361.dkr.ecr.us-east-1.amazonaws.com
✅ Built docker image 342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier:d57e4cacec82ebd72572d434ec148f1d
🔼 Pushing image 342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier:d57e4cacec82ebd72572d434ec148f1d to 342840881361.dkr.ecr.us-east-1.amazonaws.com
✅ Pushed image 342840881361.dkr.ecr.us-east-1.amazonaws.com/classifier:d57e4cacec82ebd72572d434ec148f1d to 342840881361.dkr.ecr.us-east-1.amazonaws.com
✅ Deployment classifier is up in mlem namespace
```

Here, an existing deployment i.e. `service_name` is used but with a newer model.
Hence, details of registry need not be passed again. The contents of
`service_name` can be checked by inspecting the `service_name.mlem` file.

### Checking the kubernetes resources

We can see the existing pod being terminated and the new one running in its
place below:

```
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system aws-node-pr8cn 1/1 Running 0 90m
...
kube-system kube-proxy-dfxsv 1/1 Running 0 90m
mlem classifier-66b9588df5-wmc2v 1/1 Running 0 99s
mlem classifier-687655f977-bm4w8 1/1 Terminating 0 60m
```

## Examples

```python

```

0 comments on commit fa0928b

Please sign in to comment.