Oracle Container Engine for Kubernetes Installation
Prerequisites
- Oracle Cloud Shell (Bash) with the environment variable
ENVSUBSTset to the path of anenvsubstinstallation (Oracle Cloud Shell does not allow root/sudo package installation). - kubectl with the correct context selected, pointing to the OKE cluster where Luna will be deployed.
The cluster name passed to the deploy script must match the OKE cluster name in the active kubectl context; otherwise, the deploy script will exit with an error. - Helm: the Kubernetes package manager
- cmctl: the cert-manager command-line utility
- An existing OKE cluster with at least 2 nodes (required for Luna webhook replica availability), with cluster autoscaling disabled.
Step 1 (Optional): Install NVIDIA GPU driver
If you plan to run GPU workloads, install the NVIDIA device plugin:
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.17.0/deployments/static/nvidia-device-plugin.yml
Step 2: Deploy Luna
Luna requires cert-manager to be installed/running in the cluster.
The deploy script will detect an existing cert-manager installation and install it into the cert-manager namespace if it is not already present.
By default, the script will use the namespace "elotl" and the release name "elotl-luna" for deployment. However, you can override these defaults using the --namespace and --helm-release-name options, respectively.
Luna supports two authentication methods for OCI API access:
- OCI config file mounted into the Luna manager pod
- Instance principal
The default authentication method uses an OCI config file mounted into the Luna node manager. To use this method, set up API keys for oracleidentitycloudservice/<account> and validate that access using ~/.oci/config with key ~/.oci/oci.pem works.
Note
In~/.oci/config, setkey_fileusing a~home-relative path (for example,key_file=~/.oci/oci.pem) so it resolves correctly when mounted into the pod.
Luna provisions and manages only the nodes it creates. Existing nodes in the cluster are not modified or removed.
You can then run the following command to deploy Luna into your OKE cluster:
./deploy.sh \
--cluster-ocid <cluster-ocid> \
--config-file-full-path <config-file-full-path> \
--pem-file-full-path <pem-file-full-path> \
[--helm-release-name <release-name>] \
[--namespace <namespace>] \
[--additional-helm-values "<additional-helm-values>"]
To instead use the instance principal authentication method, set up an instance principal with sufficient service permissions. Information on configuring the instance principal is given in the section "Configuring an Instance Principal for Luna Use" below. For this method, deploy using the following:
./deploy.sh --cluster-ocid <cluster-ocid> \
--use-instance-principal \
[--helm-release-name <release-name>] \
[--namespace <namespace>] \
[--additional-helm-values "<additional-helm-values>"]
This command generates:
<oke-cluster-name>_values.yaml<oke-cluster-name>_<helm-release-name>_values_full.yaml
These files are useful to retain as a reference or backup for future upgrades.
Step 3: Verify Luna installation
Run:
kubectl get all -n elotl
Sample Output
NAME READY STATUS RESTARTS AGE
pod/elotl-luna-manager-6bd7f4674d-cxwz6 1/1 Running 0 2m39s
pod/elotl-luna-webhook-7fcf5998b6-ltrd6 1/1 Running 0 2m39s
pod/elotl-luna-webhook-7fcf5998b6-svr6b 1/1 Running 0 2m39s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/elotl-luna-manager ClusterIP x.x.x.x <none> 9090/TCP 2m39s
service/elotl-luna-webhook ClusterIP x.x.x.x <none> 8443/TCP 2m39s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/elotl-luna-manager 1/1 1 1 2m39s
deployment.apps/elotl-luna-webhook 2/2 2 2 2m39s
NAME DESIRED CURRENT READY AGE
replicaset.apps/elotl-luna-manager-6bd7f4674d 1 1 1 2m39s
replicaset.apps/elotl-luna-webhook-7fcf5998b6 2 2 2 2m39s
Step 4: Test Luna functionality
Follow the tutorial to validate the value provided by Luna.
Step 5: Observe pod placement and node scaling
While testing, observe pod scheduling, dynamic node creation, and removal:
kubectl get pods --selector=elotl-luna=true -o wide -w
kubectl get nodes -w
Upgrade
When running the upgrade command described below, set <retained-values-file> to <retained-path>/<cluster-name>_<helm_release_name>_values_full.yaml.
To upgrade an existing Luna deployment, run:
helm upgrade elotl-luna <chart-path> --wait --namespace=<cluster-namespace> --values=<retained-values-file> <additional-helm-values(optional)>
For example, to upgrade my-cluster from luna-v1.5.1 to luna-v1.5.2 and set an additional helm value binPackingNodeCpu=2, run:
helm upgrade elotl-luna ./elotl-luna-v1.5.2.tgz --wait --namespace=elotl --values=../../luna-v1.5.2/oke/my-cluster_values.yaml --set binPackingNodeCpu=2
And validate the upgrade as follows:
helm ls -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
elotl-luna elotl 4 2026-01-14 14:15:30.686251 -0700 PDT deployed elotl-luna-v1.5.2 v1.5.2
Cleanup
Warning
Uninstalling Luna without first removing the pods Luna placed on Luna-managed nodes may result in orphaned nodes.
We recommend deleting all pods running on Luna-managed nodes before uninstalling Luna to avoid leaving orphaned nodes behind.
To remove Luna manager’s Helm chart run the following:
helm uninstall elotl-luna --namespace=elotl
kubectl delete namespace elotl
If Luna is uninstalled before all Luna-allocated nodes have been scaled down and removed, finalizers may remain on those nodes and prevent deletion. If this occurs, follow the finalizer cleanup instructions
If Luna created a node pool that was not removed before Luna was uninstalled, you may want to delete it manually.
Configuring an Instance Principal for Luna Use
Luna can use an OCI instance principal to authenticate with the Oracle Cloud Infrastructure APIs and manage compute resources in your OKE cluster. General background on instance principals is available in the OCI documentation: https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm
The example below illustrates one approach to configuring an instance principal for Luna. For production environments, policies should be scoped as narrowly as possible to follow the principle of least privilege.
Example configuration
Create a dynamic group in the default domain that includes the compute instances on which Luna may run.
For example:
Any {instance.id = 'ocid1.instance.oc1...', instance.id = 'ocid1.instance.oc1...'}
- Create a tenancy- or compartment-level policy that grants the dynamic group permission to manage the required OCI resources.
For example
Allow dynamic-group luna-dyn-group to manage all-resources in tenancy
Note This policy is intentionally broad for illustration purposes. In practice, you should restrict permissions to the minimum set of resources and compartments required for Luna to operate.