Install in air-gapped environments
Install Solo Enterprise for kgateway in an air-gapped environment.
You can install Solo Enterprise for kgateway in an air-gapped environment, such as an on-premises datacenter, a cluster that runs on an intranet or private network only, or other disconnected environments, by mirroring container images and Helm charts to a private registry.
Before you begin
Your environment must have the following components for an air-gapped installation.
- Connected device: A machine that can reach the public internet and pull images and Helm charts from public registries.
- Disconnected device: A machine in a private network or on-premises datacenter that can access the Kubernetes cluster where you install Solo Enterprise for kgateway.
- Private registry: A registry that both devices can reach, such as Sonatype Nexus Repository or JFrog Artifactory. When setting up your private registry, consider the following:
- Registry credentials in the cluster: You might need to configure image pull secrets in Kubernetes, such as a global image pull secret in OpenShift.
- Allowed access to public registries: If your registry synchronizes content from upstream sources, allow access to the following common domains:
us-docker.pkg.dev/solo-public/enterprise-kgatewaygcr.io/gloo-meshdocker.io
The following CLIs must be available for this workflow. If your environment blocks public downloads, follow each CLI’s documentation for an air-gapped installation method.
- On the disconnected device, install
kubectl, the Kubernetes command line tool. Download thekubectlversion that is within one minor version of the Kubernetes cluster you plan to use. - On the disconnected device, install
helm, the Kubernetes package manager, to customize multiple settings in the Solo Enterprise for kgateway installation. - On the connected device, install either
craneorskopeoto copy multi-architecture images from the public registries to your private registry.
- On the disconnected device, install
Step 1: Mirror images from a connected device to your private registry
On a connected device that can reach both the public registries and your private registry, mirror the necessary images for Solo Enterprise for kgateway directly between registries. This workflow preserves multi-architecture image indexes for supported images. The following images are supported for version 2.2.0:
| Component | Registry | Repository | Tag |
|---|---|---|---|
| Controller | us-docker.pkg.dev/solo-public/enterprise-kgateway | enterprise-kgateway-controller | 2.2.0 |
| Envoy wrapper (data plane) | us-docker.pkg.dev/solo-public/enterprise-kgateway | envoy-wrapper | 2.2.0 |
| ExtAuth | gcr.io/gloo-mesh | ext-auth-service | 0.81.1 |
| ExtCache | docker.ioh | redis | 7.2.13-alpine |
| RateLimiter | gcr.io/gloo-mesh | rate-limiter | 0.18.6 |
| WAF | us-docker.pkg.dev/solo-public/enterprise-kgateway | waf-server | 2.2.0 |
| Portal controller | us-docker.pkg.dev/solo-public/enterprise-kgateway | portal-controller | 2.2.0 |
| Portal web server | us-docker.pkg.dev/solo-public/enterprise-kgateway | portal-web-server | 2.2.0 |
Set the versions that you want to install.
export KGATEWAY_VERSION=2.2.0 export EXTAUTH_VERSION=0.81.1 export EXTCACHE_VERSION=7.2.13-alpine export RATELIMITER_VERSION=0.18.6Set the image locations.
export KGATEWAY_CONTROLLER_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/enterprise-kgateway-controller:$KGATEWAY_VERSION export ENVOY_WRAPPER_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/envoy-wrapper:$KGATEWAY_VERSION export EXTAUTH_IMG=gcr.io/gloo-mesh/ext-auth-service:$EXTAUTH_VERSION export EXTCACHE_IMG=docker.io/redis:$EXTCACHE_VERSION export RATELIMITER_IMG=gcr.io/gloo-mesh/rate-limiter:$RATELIMITER_VERSION export WAF_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/waf-server:$KGATEWAY_VERSION export PORTAL_CONTROLLER_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/portal-controller:$KGATEWAY_VERSION export PORTAL_WEBSERVER_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/portal-web-server:$KGATEWAY_VERSIONSet your private registry details.
export PRIVATE_REGISTRY=<registry.example.com> export PRIVATE_REPOSITORY=<enterprise-kgateway>Set the image locations in your private registry.
export KGATEWAY_CONTROLLER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/enterprise-kgateway-controller:$KGATEWAY_VERSION export ENVOY_WRAPPER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/envoy-wrapper:$KGATEWAY_VERSION export EXTAUTH_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/ext-auth-service:$EXTAUTH_VERSION export EXTCACHE_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/redis:$EXTCACHE_VERSION export RATELIMITER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/rate-limiter:$RATELIMITER_VERSION export WAF_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/waf-server:$KGATEWAY_VERSION export PORTAL_CONTROLLER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/portal-controller:$KGATEWAY_VERSION export PORTAL_WEBSERVER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/portal-web-server:$KGATEWAY_VERSIONCopy the images to your registry. If you do not want to use external auth, rate limiting, or Redis cache, the WAF server, or Portal, you can omit those images.
skopeocommands:skopeo copy --all docker://$KGATEWAY_CONTROLLER_IMG docker://$KGATEWAY_CONTROLLER_PRIVATE skopeo copy --all docker://$ENVOY_WRAPPER_IMG docker://$ENVOY_WRAPPER_PRIVATE skopeo copy --all docker://$EXTAUTH_IMG docker://$EXTAUTH_PRIVATE skopeo copy --all docker://$EXTCACHE_IMG docker://$EXTCACHE_PRIVATE skopeo copy --all docker://$RATELIMITER_IMG docker://$RATELIMITER_PRIVATE skopeo copy --all docker://$WAF_IMG docker://$WAF_PRIVATE skopeo copy --all docker://$PORTAL_CONTROLLER_IMG docker://$PORTAL_CONTROLLER_PRIVATE skopeo copy --all docker://$PORTAL_WEBSERVER_IMG docker://$PORTAL_WEBSERVER_PRIVATEcranecommands:crane copy $KGATEWAY_CONTROLLER_IMG $KGATEWAY_CONTROLLER_PRIVATE crane copy $ENVOY_WRAPPER_IMG $ENVOY_WRAPPER_PRIVATE crane copy $EXTAUTH_IMG $EXTAUTH_PRIVATE crane copy $EXTCACHE_IMG $EXTCACHE_PRIVATE crane copy $RATELIMITER_IMG $RATELIMITER_PRIVATE crane copy $WAF_IMG $WAF_PRIVATE crane copy $PORTAL_CONTROLLER_IMG $PORTAL_CONTROLLER_PRIVATE crane copy $PORTAL_WEBSERVER_IMG $PORTAL_WEBSERVER_PRIVATE
Step 2: Configure the disconnected cluster
If you have not already, create the
kgateway-systemnamespace in your Kubernetes cluster.kubectl create namespace kgateway-systemIf your private registry requires authentication, create an image pull secret.
kubectl create secret docker-registry private-registry-credentials \ --docker-server=$PRIVATE_REGISTRY \ --docker-username=<username> \ --docker-password=<password> \ --docker-email=<email> \ -n kgateway-systemCreate an
EnterpriseKgatewayParametersresource that configures the container images to be used and points to the images in the private registry. You can optionally update the resource limits and requests for the shared extensions as shown here.kubectl apply -f- <<EOF apiVersion: enterprisekgateway.solo.io/v1alpha1 kind: EnterpriseKgatewayParameters metadata: name: shared-ent-kgateway-parameters namespace: kgateway-system spec: kube: envoyContainer: image: pullPolicy: IfNotPresent registry: $PRIVATE_REGISTRY repository: $PRIVATE_REPOSITORY/envoy-wrapper tag: $KGATEWAY_VERSION sharedExtensions: extCache: enabled: true container: image: pullPolicy: IfNotPresent registry: $PRIVATE_REGISTRY repository: $PRIVATE_REPOSITORY/redis tag: $EXTCACHE_VERSION extauth: enabled: true container: image: pullPolicy: IfNotPresent registry: $PRIVATE_REGISTRY repository: $PRIVATE_REPOSITORY/ext-auth-service tag: $EXTAUTH_VERSION ratelimiter: enabled: true container: image: pullPolicy: IfNotPresent registry: $PRIVATE_REGISTRY repository: $PRIVATE_REPOSITORY/rate-limiter tag: $RATELIMITER_VERSION waf: enabled: true container: image: pullPolicy: IfNotPresent registry: $PRIVATE_REGISTRY repository: $PRIVATE_REPOSITORY/waf-server tag: $KGATEWAY_VERSION EOF
Optional: Update resource limits and requests
The default shared extension deployments include reasonable resource allocations, as well as Prometheus metrics endpoints and health checks as described in the following table. If you notice performance issues with the external auth or rate limiter services, check the resource usage and adjust as necessary.
| Service | CPU/Memory Requests | CPU/Memory Limits | Default Metrics Port |
|---|---|---|---|
| ext-auth-service | 100m CPU, 128Mi memory | 500m CPU, 256Mi memory | 9091 |
| rate-limiter | 100m CPU, 128Mi memory | 500m CPU, 256Mi memory | 9091 |
| ext-cache | 256m CPU, 512Mi memory | Not specified, as the resources depend on your usage | N/A |
Update the resource limits and requests as follows:
kubectl apply -f- <<EOF
apiVersion: enterprisekgateway.solo.io/v1alpha1
kind: EnterpriseKgatewayParameters
metadata:
name: shared-ent-kgateway-parameters
namespace: kgateway-system
spec:
kube:
envoyContainer:
image:
pullPolicy: IfNotPresent
registry: $PRIVATE_REGISTRY
repository: $PRIVATE_REPOSITORY/envoy-wrapper
tag: $KGATEWAY_VERSION
sharedExtensions:
extCache:
enabled: true
container:
image:
pullPolicy: IfNotPresent
registry: $PRIVATE_REGISTRY
repository: $PRIVATE_REPOSITORY/redis
tag: $EXTCACHE_VERSION
resources:
requests:
cpu: 256m
memory: 512Mi
limits:
cpu: 1000m
memory: 2048Mi
extauth:
enabled: true
container:
image:
pullPolicy: IfNotPresent
registry: $PRIVATE_REGISTRY
repository: $PRIVATE_REPOSITORY/ext-auth-service
tag: $EXTAUTH_VERSION
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 750m
memory: 512Mi
ratelimiter:
enabled: true
container:
image:
pullPolicy: IfNotPresent
registry: $PRIVATE_REGISTRY
repository: $PRIVATE_REPOSITORY/rate-limiter
tag: $RATELIMITER_VERSION
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 750m
memory: 512Mi
waf:
enabled: true
container:
image:
pullPolicy: IfNotPresent
registry: $PRIVATE_REGISTRY
repository: $PRIVATE_REPOSITORY/waf-server
tag: $KGATEWAY_VERSION
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 750m
memory: 512Mi
EOFStep 3: Install Solo Enterprise for kgateway
Create a Helm values file that references the private registry and the
EnterpriseKgatewayParametersresource.cat > enterprise-kgateway/values.yaml <<EOF image: registry: $PRIVATE_REGISTRY/$PRIVATE_REPOSITORY tag: "$KGATEWAY_VERSION" pullPolicy: IfNotPresent gatewayClassParametersRefs: enterprise-kgateway: group: enterprisekgateway.solo.io kind: EnterpriseKgatewayParameters name: shared-ent-kgateway-parameters namespace: kgateway-system EOFFollow the Helm installation guide and include the values file that you created. If your disconnected device cannot access public Helm registries, follow the steps in the next section.
Optional: Mirror Helm charts to a private registry
If your disconnected device cannot access public Helm registries, first mirror the charts from the connected device before installing with Helm.
Pull the main and CRD Helm charts on the connected device.
helm pull oci://us-docker.pkg.dev/solo-public/enterprise-kgateway/charts/enterprise-kgateway --version $KGATEWAY_VERSION helm pull oci://us-docker.pkg.dev/solo-public/enterprise-kgateway/charts/enterprise-kgateway-crds --version $KGATEWAY_VERSIONPush the charts to your private registry.
helm push enterprise-kgateway-$KGATEWAY_VERSION.tgz oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helm helm push enterprise-kgateway-crds-$KGATEWAY_VERSION.tgz oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helmInstall the charts from the private registry.
helm upgrade -i enterprise-kgateway-crds oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helm/enterprise-kgateway-crds \ --version $KGATEWAY_VERSION \ -n kgateway-system helm upgrade -i enterprise-kgateway oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helm/enterprise-kgateway \ --version $KGATEWAY_VERSION \ -n kgateway-system \ -f values.yaml
Optional: Install Portal from the private registry
If you use Solo Enterprise for kgateway Portal, mirror the Portal images and point the Portal installation at your private registry. Portal includes two images, both tagged with the Solo Enterprise for kgateway version ($KGATEWAY_VERSION): the portal-controller that runs in the control plane, and the portal-web-server that backs each portal. For more information about installing Portal, see the Portal setup guide.
| Component | Registry | Repository | Tag |
|---|---|---|---|
| Portal controller | us-docker.pkg.dev/solo-public/enterprise-kgateway | portal-controller | 2.2.0 |
| Portal web server | us-docker.pkg.dev/solo-public/enterprise-kgateway | portal-web-server | 2.2.0 |
On the connected device, set the Portal image locations. The Portal images use the same
$KGATEWAY_VERSIONtag that you set earlier.export PORTAL_CONTROLLER_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/portal-controller:$KGATEWAY_VERSION export PORTAL_WEB_SERVER_IMG=us-docker.pkg.dev/solo-public/enterprise-kgateway/portal-web-server:$KGATEWAY_VERSION export PORTAL_CONTROLLER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/portal-controller:$KGATEWAY_VERSION export PORTAL_WEB_SERVER_PRIVATE=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/portal-web-server:$KGATEWAY_VERSIONCopy the Portal images to your private registry.
skopeocommands:skopeo copy --all docker://$PORTAL_CONTROLLER_IMG docker://$PORTAL_CONTROLLER_PRIVATE skopeo copy --all docker://$PORTAL_WEB_SERVER_IMG docker://$PORTAL_WEB_SERVER_PRIVATEcranecommands:crane copy $PORTAL_CONTROLLER_IMG $PORTAL_CONTROLLER_PRIVATE crane copy $PORTAL_WEB_SERVER_IMG $PORTAL_WEB_SERVER_PRIVATEIf your disconnected device cannot reach public Helm registries, mirror the Portal Helm charts to your private registry, following the same steps as the main charts.
helm pull oci://us-docker.pkg.dev/solo-public/enterprise-kgateway/charts/portal-crds --version $KGATEWAY_VERSION helm pull oci://us-docker.pkg.dev/solo-public/enterprise-kgateway/charts/portal --version $KGATEWAY_VERSION helm push portal-crds-$KGATEWAY_VERSION.tgz oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helm helm push portal-$KGATEWAY_VERSION.tgz oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helmOn the disconnected device, set your Portal license key and install the Portal controller from your private registry. The
image.registryandimage.tagvalues point theportal-controllerimage at your private registry.export PORTAL_LICENSE_KEY=<portal-license-key> helm upgrade -i portal-crds oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helm/portal-crds \ --version $KGATEWAY_VERSION \ --namespace portal-system \ --create-namespace helm upgrade -i portal oci://$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY/helm/portal \ --version $KGATEWAY_VERSION \ --namespace portal-system \ --set licensing.licenseKey=$PORTAL_LICENSE_KEY \ --set image.registry=$PRIVATE_REGISTRY/$PRIVATE_REPOSITORY \ --set image.tag=$KGATEWAY_VERSION \ --set imagePullSecrets[0].name=private-registry-credentialsWhen you create a
PortalParametersresource, override the portal web server image in thespec.webServer.container.imagefield so that each portal web server pulls theportal-web-serverimage from your private registry. Create the resource in the namespace where you create your portals, such asdefault.Copy the image pull secret for your private registry to the namespace of your portal web server, such as
default.kubectl create secret docker-registry private-registry-credentials \ --docker-server=$PRIVATE_REGISTRY \ --docker-username=<username> \ --docker-password=<password> \ --docker-email=<email> \ -n defaultCreate the portal web server with a
deploymentOverlaysetting for the image server, which applies a strategic merge patch to the generated web server Deployment.kubectl apply -f- <<EOF apiVersion: portal.solo.io/v1alpha1 kind: PortalParameters metadata: name: portal-params namespace: default spec: webServer: container: image: pullPolicy: IfNotPresent registry: $PRIVATE_REGISTRY repository: $PRIVATE_REPOSITORY/portal-web-server tag: $KGATEWAY_VERSION deploymentOverlay: spec: template: spec: imagePullSecrets: - name: private-registry-credentials store: memory: {} EOF
Step 4: Verify images
After you complete the Helm installation, confirm that workloads pull the expected images and that no image pull errors occurred.
kubectl get deploy -n kgateway-system -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .spec.template.spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'
kubectl get pods -n kgateway-system -o wide
kubectl get events -n kgateway-system --field-selector reason=FailedExpected output:
enterprise-kgateway-controller registry.example.com/enterprise-kgateway/enterprise-kgateway-controller:2.2.0
http registry.example.com/enterprise-kgateway/envoy-wrapper:2.2.0
ext-auth-service-enterprise-kgateway registry.example.com/enterprise-kgateway/ext-auth-service:0.81.1
ext-cache-enterprise-kgateway registry.example.com/enterprise-kgateway/redis:7.2.13-alpine
rate-limiter-enterprise-kgateway registry.example.com/enterprise-kgateway/rate-limiter:0.18.6
waf-server-enterprise-kgateway registry.example.com/enterprise-kgateway/waf-server:2.2.0http gateway proxy, ext-auth-service, rate-limiter, and ext-cache are created only after you deploy a Gateway resource in your environment. For more information, see the Get started guide.