Skip to content

Commit 7d26660

Browse files
Merge pull request #241 from cortexapps/worktree-kubernetes-agent-solution
feat: add kubernetes-agent solution (CX-41)
2 parents 2137d77 + 11d24fb commit 7d26660

21 files changed

Lines changed: 1826 additions & 0 deletions
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "Cortex Kubernetes Agent Demo",
3+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
4+
"features": {
5+
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
6+
"ghcr.io/devcontainers/features/sshd:1": {}
7+
},
8+
"onCreateCommand": "bash .devcontainer/kubernetes-agent/onCreate.sh",
9+
"remoteEnv": {
10+
"CORTEX_API_KEY": "${localEnv:CORTEX_API_KEY}",
11+
"GHCR_TOKEN": "${localEnv:GHCR_TOKEN}"
12+
},
13+
"postCreateMessage": "kind cluster is ready. Run cortex solutions post-install -s kubernetes-agent from your local machine."
14+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Log all output so failures are diagnosable: cat /tmp/onCreate.log
5+
exec > >(tee /tmp/onCreate.log) 2>&1
6+
7+
# Write a failure sentinel on non-zero exit so setup.py can detect it fast
8+
_on_exit() {
9+
local rc=$?
10+
if [[ $rc -ne 0 ]]; then
11+
echo "$rc" > /tmp/onCreate.failed
12+
fi
13+
}
14+
trap _on_exit EXIT
15+
16+
ARCH=$(uname -m)
17+
BIN_ARCH="amd64"
18+
[ "$ARCH" = "aarch64" ] && BIN_ARCH="arm64"
19+
20+
echo "==> Installing kubectl..."
21+
curl -Lo /tmp/kubectl "https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/${BIN_ARCH}/kubectl"
22+
sudo install -o root -g root -m 0755 /tmp/kubectl /usr/local/bin/kubectl
23+
24+
echo "==> Installing helm..."
25+
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
26+
sudo chmod a+rx /usr/local/bin/helm
27+
28+
echo "==> Installing kind..."
29+
curl -Lo /tmp/kind "https://kind.sigs.k8s.io/dl/latest/kind-linux-${BIN_ARCH}"
30+
sudo install -o root -g root -m 0755 /tmp/kind /usr/local/bin/kind
31+
32+
echo "==> Creating kind cluster 'cortex-demo'..."
33+
kind create cluster --name cortex-demo --wait 60s
34+
35+
echo "==> Verifying cluster..."
36+
kubectl cluster-info --context kind-cortex-demo
37+
38+
echo "==> Done."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Demo Kubernetes
4+
description: Demo entity for the Kubernetes agent integration
5+
x-cortex-tag: demo-kubernetes
6+
x-cortex-type: service
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Bundled copy of the Cortex k8s-agent helm chart for demo purposes.
2+
# This copy is not kept up-to-date. Once the chart is published to a
3+
# public helm repo, this bundle will be replaced with a helm repo reference.
4+
apiVersion: v2
5+
name: cortex-k8s-agent
6+
description: A Helm chart for deploying Cortex K8s agent in your cluster
7+
type: application
8+
version: 0.1.0
9+
appVersion: 1.16.0
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Cortex k8s Helm Chart
2+
3+
## Requirements
4+
* [Helm](https://helm.sh/docs/intro/install/)
5+
* A token for our package registry
6+
7+
## Process
8+
1. Generate a new Cortex API Key on the [API Keys Settings tab](https://app.getcortexapp.com/admin/settings/api-keys) in Cortex.
9+
- This will be used for the Cortex Kubernetes agent to communicate and push service information to Cortex backend without exposing your public API Key.
10+
2. Inside your Kubernetes cluster, run the following command to generate a Kubernetes secret for the Cortex API Key.
11+
`kubectl create secret generic cortex-key --from-literal api-key=YOUR_API_KEY`
12+
3. Run `kubectl create secret docker-registry cortex-docker-registry-secret --docker-server=ghcr.io --docker-username=$GITHUB_USERNAME --docker-password=$GITHUB_PASSWORD --docker-email=<doesn't matter>`
13+
4. Download the helm chart and inside the repository run the following command to install the agent in your cluster.
14+
`helm install YOUR_SELECTED_CHART_NAME .`
15+
16+
## Customization
17+
The helm chart make installation quick and simple, but if you want to customize any of the installation features for the Cortex agent you can do so by changing the following information in the `values.yaml` of the helm chart.
18+
### Service Account
19+
To authenticate the Cortex agent in your cluster and grant it access to service information, the agent needs its own service account. The helm chart by default creates a Service Account `cortex-service-account`, but you can customize the `name` and `namespace` of this Service Account. If you already have a Service Account that you want the Cortex agent to use, set `create: false` under `serviceAccount` and enter the `name` and `namespace` of the Service Account you wish to use.
20+
### Service
21+
The service type and port can be customized as well. For security, the agent uses a default `ClusterIP` service type that only allows the service to be accessed from within the cluster.
22+
### Resources
23+
By default, no resources are specified. While the Cortex Kubernetes agent is designed to be lightweight and minimize resource utilization, you have the option to add custom CPU limits and requests.
24+
### Base URL
25+
The Base URL defaults to that for the hosted version of Cortex. If you are using the on-prem version of Cortex, you should change the `app/baseUrl` value to the correct URL for your on-prem Cortex.
26+
27+
# Usage
28+
After installation, usage is very simple as no additional steps are required. The next time you go to create a new service in your Service Directory Homepage, you should see all of your Kubernetes services already added, ready for you to use in Cortex. If you do not want to import all of your Kubernetes discovered services, you can simply remove the ones you do not want to add. Removed services will still show up in the Kubernetes tab of Discovered Services if you want to go back and add them later.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "helm-chart.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "helm-chart.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "helm-chart.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "helm-chart.labels" -}}
37+
helm.sh/chart: {{ include "helm-chart.chart" . }}
38+
{{ include "helm-chart.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "helm-chart.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "helm-chart.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "helm-chart.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "helm-chart.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}
63+
64+
{{/*
65+
Create the namespace of the service account to use
66+
*/}}
67+
{{- define "helm-chart.serviceAccountNamespace" -}}
68+
{{- if .Values.serviceAccount.create }}
69+
{{- default (include "helm-chart.fullname" .) .Values.serviceAccount.namespace }}
70+
{{- else }}
71+
{{- default "default" .Values.serviceAccount.namespace }}
72+
{{- end }}
73+
{{- end }}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{{- if .Values.clusterRole.create -}}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRole
4+
metadata:
5+
name: {{ include "helm-chart.serviceAccountName" . }}
6+
rules:
7+
- apiGroups: ["apps", "argoproj.io", "batch"]
8+
resources: ["deployments", "services", "pods", "replicationcontrollers", "statefulsets", "rollouts", "cronjobs"]
9+
verbs: ["get", "watch", "list"]
10+
{{- end -}}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{{- if .Values.clusterRoleBinding.create -}}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRoleBinding
4+
metadata:
5+
name: {{ include "helm-chart.serviceAccountName" . }}
6+
subjects:
7+
- kind: ServiceAccount
8+
name: {{ include "helm-chart.serviceAccountName" . }}
9+
namespace: {{ include "helm-chart.serviceAccountNamespace" . }}
10+
roleRef:
11+
kind: ClusterRole
12+
name: {{ include "helm-chart.serviceAccountName" . }}
13+
apiGroup: rbac.authorization.k8s.io
14+
{{- end -}}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: {{ template "helm-chart.fullname" . }}-configmap
5+
data:
6+
SPRING_PROFILES_ACTIVE: prod
7+
BASE_URL: {{ required "Base URL must be defined." .Values.app.baseUrl }}
8+
{{ if .Values.app.clusterName }}CORTEX_CLUSTER: {{ .Values.app.clusterName }}{{ end }}
9+
{{ if .Values.app.namespace }}SELECTED_NAMESPACE: {{ .Values.app.namespace }}{{ end }}

0 commit comments

Comments
 (0)