Deploy on Kubernetes
This guide gives an outline of how to deploy Enterprise OPA in Kubernetes. There are a number of adjustments you may wish to consider for your own deployment:
- Setting memory and CPU requests for the Enterprise OPA container. These values will depend on your data and throughput requirements.
- Adjustments to the example configuration file included here as a secret to load bundles over the Bundle Service API.
- Creating an Ingress resource to expose the Enterprise OPA API.
- Deploying
kube-mgmt
to load Kubernetes data or policies inConfigMap
resources into Enterprise OPA.
1. Create a namespace
This guide uses an example namespace named eopa
. This is optional, but will require updates to the following YAML files.
apiVersion: v1
kind: Namespace
metadata:
name: eopa
2. Store the license in a secret
This is a required step. This secret is used in the Enterprise OPA pods to enable them to start.
apiVersion: v1
kind: Secret
metadata:
name: enterprise-opa-license
namespace: eopa
type: Opaque
stringData:
license: "..." # <-- set license key here
If you are storing your Enterprise OPA license key in HashiCorp Vault, you can skip this step and instead use the Enterprise OPA configuration file.
3. Create the configuration file
Create a ConfigMap
for configuration. This will be loaded into the Enterprise OPA pods via a volume mount.
apiVersion: v1
kind: ConfigMap
metadata:
name: enterprise-opa-config
namespace: eopa
data:
config.yaml: |
services:
example:
url: https://bundles.example.com/
bundles:
example:
service: example
resource: bundles/example.tar.gz
If you're providing anything sensitive in your Enterprise OPA configuration—like tokens or private keys—don't place them in the config map directly. Instead, use HashiCorp Vault, environment variable substitution or in a file via the --set-file
override for eopa run
.
4. Create the deployment
Finally, we can run Enterprise OPA by creating a Deployment resource.
This Deployment makes reference the Enterprise OPA image hosted on the GitHub Container Registry. If this is inaccessible from your cluster, you will need to push a copy of the image to a registry that is accessible and update the image name in the Deployment's Pod spec.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: enterprise-opa
namespace: eopa
name: enterprise-opa
spec:
replicas: 1
selector:
matchLabels:
app: enterprise-opa
template:
metadata:
labels:
app: enterprise-opa
name: enterprise-opa
spec:
containers:
- name: enterprise-opa
# Update this to the desired version
image: # docker pull ghcr.io/styrainc/enterprise-opa:$VERSION
args:
- "run"
- "--server"
- "--addr=0.0.0.0:8181"
- "--config-file=/etc/config/config.yaml"
env:
- name: EOPA_LICENSE_KEY
valueFrom:
secretKeyRef:
name: enterprise-opa-license
key: license
volumeMounts:
- name: config
mountPath: /etc/config
readinessProbe:
httpGet:
path: /health
scheme: HTTP
port: 8181
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
scheme: HTTP
port: 8181
initialDelaySeconds: 3
periodSeconds: 5
volumes:
- name: config
configMap:
name: enterprise-opa-config
items:
- key: "config.yaml"
path: "config.yaml"
5. Access the Enterprise OPA API
Connecting to the Enterprise OPA API using kubectl port-forward
This method is only really suitable for local testing.
First, run the following command to forward port 8181 on your local machine to the Enterprise OPA API:
kubectl -n eopa port-forward deployment/enterprise-opa 8181
Forwarding from 127.0.0.1:8181 -> 8181
Forwarding from [::1]:8181 -> 8181
Next, in another terminal, run the following command to test the connection:
curl --silent localhost:8181/v1/data/system/version?pretty=true
{
"result": {
"build_commit": "779a6b0b33fcaf1fc47b42728a610dba7dc5dcac",
"build_hostname": "github.actions.local",
"build_timestamp": "2023-02-03T22:52:03Z",
"version": "0.48.0"
}
}
Connecting to the Enterprise OPA API using a Service & Ingress
This method is more suitable in the following scenarios:
- You want to run Enterprise OPA in production and have other services in the cluster that depend on it.
- When benchmarking Enterprise OPA from within the cluster.
First, create a Service resource. This will give Enterprise OPA a record in the Kubernetes DNS and make it accessible from other pods in the cluster at enterprise-opa.eopa.svc.cluster.local:8181
.
kind: Service
apiVersion: v1
metadata:
name: enterprise-opa
namespace: eopa
spec:
selector:
app: enterprise-opa
ports:
- port: 8181
Optionally, create an Ingress resource to allow the Enterprise OPA instances to be accessed from another location.
You will need to update the host
field to hostname you wish to use.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: enterprise-opa
namespace: eopa
spec:
rules:
- host: enterprise-opa.example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: enterprise-opa
port:
number: 8181
Next, in another terminal, run the following command to test the connection:
curl enterprise-opa.example.com/v1/data/system/version?pretty=true
{
"result": {
"build_commit": "779a6b0b33fcaf1fc47b42728a610dba7dc5dcac",
"build_hostname": "github.actions.local",
"build_timestamp": "2023-02-03T22:52:03Z",
"version": "0.48.0"
}
}