# How can I install Okteto in a k3s airgapped cluster

**URL:** https://community.okteto.com/t/how-can-i-install-okteto-in-a-k3s-airgapped-cluster/1341
**Category:** How Do I?
**Created:** [November 12, 2024, 11:54am UTC](https://community.okteto.com/t/how-can-i-install-okteto-in-a-k3s-airgapped-cluster/1341 "2024-11-12T11:54:24Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![mario](https://sea1.discourse-cdn.com/flex019/user_avatar/community.okteto.com/mario/32/292_2.png) [@mario](https://community.okteto.com/u/mario)
#### Post date: [November 12, 2024, 11:54am UTC](https://community.okteto.com/t/how-can-i-install-okteto-in-a-k3s-airgapped-cluster/1341/1 "2024-11-12T11:54:24Z")

</div>

I want to use Okteto in an airgapped environment with a k3s cluster. How can I do the full process?

---

<div class="post-metadata">

### Author: ![mario](https://sea1.discourse-cdn.com/flex019/user_avatar/community.okteto.com/mario/32/292_2.png) [@mario](https://community.okteto.com/u/mario)
#### Post date: [November 12, 2024, 11:54am UTC](https://community.okteto.com/t/how-can-i-install-okteto-in-a-k3s-airgapped-cluster/1341/2 "2024-11-12T11:54:29Z")

</div>

> You can find our official instructions on [how to install Okteto in Air-Gapped environments here](https://www.okteto.com/docs/self-hosted/manage/air-gapped/).

Air-Gapped installations are only supported on Okteto’s `Enterprise` tier. If you need help, don’t hesitate to contact us via your sales contact or [our support channels](https://support.okteto.com).

## Install k3s

If you don’t have a **k3s** cluster already installed, follow these steps to install it. This guide is for _Ubuntu_

1. Installation: `curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -`  
We are going to disable **traefik** , which comes by default and we are going to use nginx controller from Okteto.  
If you already have it installed in your cluster with **traefik** you can disable it editing k3s configuration file (usually located at `/etc/rancher/k3s/config.yaml` or `/etc/k3s/config.yaml`.

```auto
 disable:
    - traefik

```

Run the command below to restart k3s and apply the configuration change.

```auto
$ sudo systemctl restart k3s

```

1. Check status: `systemctl status k3s`  
This should show status as `active (running)`

2. Check that your cluster is healthy with kubectl: `sudo kubectl get all -n kube-system`

To avoid any warnings, we recommend that you copy `/etc/rancher/k3s/k3s.yaml` to your $HOME directory and set read-only permissions:

```auto
sudo cp /etc/rancher/k3s/k3s.yaml $HOME/kubeconfig
sudo chown $USER:$USER $HOME/kubeconfig
chmod 400 $HOME/kubeconfig

```

## Okteto Container Images

The images used by Okteto are listed [in our documentation](https://www.okteto.com/docs/self-hosted/manage/air-gapped/#step-2-set-up-a-private-registry-for-required-images). By default, kubernetes will pull the images from Dockerhub during installation.

For air-gapped installations, you need to make the images available to your cluster. We recommend the following approaches for k3s-based installations:

### Copy them to the VM and use them with Local Registry

The main benefit of this approach is that you don’t need to change the container images or the helm configuration values.

For this approach, you need to:

1. Pull all the images from a computer with access to the internet
2. Export them as a tar file
3. Copy them to the air-gapped VM
4. Load them using `ctr`

You’ll need to do this for every image and every node on your cluster. For example, to do this for the okteto/backend:1.27.1 image, you’ll need to run the commands below:

```auto
docker save okteto/backend:1.27.1 -o okteto-backend.tar
scp okteto-backend.tar user@air-gappedvm:/home/user
ssh user@air-gappedvm 
sudo ctr -n k8s.io images import okteto-backend.tar
sudo k3s crictl images

```

A second approach is to use an OCI private registry, such as ECR/GCR/Harbor. This is recommended if you already have a private registry available, and your K3S cluster can access it within the air-gapped network.

In this scenario, you’ll need to perform the following action on each image used by Okteto:

1. Pull the image
2. Tag the image to match your private registry
3. Push the image to your private registry

For example, to do this for the okteto/backend:1.27.1 image, you’ll need to run the commands below to push it to registry “[registry.example.com](http://registry.example.com)”

```auto
docker pull okteto/backend:1.27.1
docker tag okteto/backend:1.27.1 registry.example.com/okteto/backend:1.27.1
docker push registry.example.com/okteto/backend:1.27.1

```

If you using this approach, you will need to update your helm configuration file with the URL of your registry. More information on this [is available here](https://www.okteto.com/docs/self-hosted/manage/air-gapped/#step-3-update-helm-configuration).

## Install Okteto

Follow our installation guide for DNS and certificates in [Okteto docs](https://www.okteto.com/docs/)

In addition to the images of your registry (in case you need to add them), you also need to set the values listed below on your helm configuration file.

```auto
license: provided by Okteto sales
subdomain: your domain
telemetry:
  enabled: false

```

The default installation of Okteto includes a load balancer (this is used to expose the web UI, API, and development environment endpoints to your users). K3S doesn’t come with a native LB, but a few options exist. Each of them will require you to apply extra configuration for your helm configuration file:

### Use [MetalLB](https://kubevirt.io/2022/Virtual-Machines-with-MetalLB.html)

If you are using MetalLB (or if you have a single VM), you need to change the service type of the `ingress-nginx` controller to NodePort

```auto
ingress-nginx:
  enabled: true
  controller:
    service:
      type: NodePort

```

### Use the `VM internal IP`

If you prefer to use the VM’s internal IP, you need to set it as the `externalIPs` of the `ingress-nginx` controller’s service.

```auto
ingress-nginx:
  controller:
    service:
      externalIPs:
      - 10.132.0.2 (example)

```

Now you have everything ready to install Okteto!! [Download our Helm chart](https://artifacthub.io/packages/helm/okteto/okteto), decompress it, upload it to the machine with access to your cluster, and execute the command below.

```auto
helm upgrade --install okteto ./okteto -f config.yaml --namespace okteto --create-namespace

```

## Extra DNS configuration\*

Okteto requires you to create a wildcard DNS entry to map the load balancer’s IP to the subdomain that you are using.

If you are in an air-gapped environment and cannot create wildcard DNS entries, you can instead create the following separate entries. All of them should point to the IP of the ingress-nginx controller in the okteto namespace:

- `okteto.subdomain`
- `buildkit.subdomain`
- `kubernetes.subdomain`
- `registry.subdomain`

# We are here to help

Air-gapped installations can be complicated. If you need help, don’t hesitate to contact us via your sales contact or [our support channels](https://support.okteto.com). We are here to help!
