diff --git a/charts/intel/README.md b/charts/intel/README.md index a0aa20f..7f79c32 100644 --- a/charts/intel/README.md +++ b/charts/intel/README.md @@ -53,6 +53,15 @@ The following table lists configurable parameters of the CodeTogether Intel char | `java.customCacerts.enabled` | Enables mounting a custom Java trust store (cacerts) | `false` | | `java.customCacerts.cacertsSecretName` | Name of the Kubernetes secret containing the `cacerts` file | `custom-java-cacerts` | | `java.customCacerts.trustStorePasswordKey` | (Optional) Key inside the Kubernetes secret containing the trust store password | `trustStorePassword` | +| `ai.mode` | AI integration mode: `bundled` (deploy AI container) or `external` (use external AI service) | `"bundled"` | +| `ai.provider` | AI provider (`openai` or custom) | `"openai"` | +| `ai.model` | AI model to use (`gpt-4-turbo`, `gpt-3.5-turbo`, etc.) | `"gpt-4-turbo"` | +| `ai.resources.cpu` | CPU allocation for AI container | `"2"` | +| `ai.resources.memory` | Memory allocation for AI container | `"4Gi"` | +| `ai.resources.gpu` | GPU support (future feature) | `false` | +| `ai.external.url` | URL for external AI service (if `mode: external`) | `""` | +| `ai.external.apiKeySecret.name` | Name of the Kubernetes secret containing the external AI API key | `"ai-secrets"` | +| `ai.external.apiKeySecret.key` | Key name in the Kubernetes secret containing the API key | `"external-ai-key"` | | `ingress.enabled` | Enables ingress controller resource | `true` | | `ingress.annotations` | Annotations for ingress | `{}` | | `ingress.tls.secretName` | TLS secret name for ingress | `codetogether-intel-tls` | @@ -107,6 +116,38 @@ If you prefer not to store the Cassandra password in values.yaml, you can store kubectl create secret generic cassandra-password-secret --from-literal=cassandraPassword='your-secure-cassandra-password' --namespace=codetogether-intel ``` +## AI Integration and API Key Security + +This chart supports an AI container for generating summaries. Users can choose between deploying an AI model inside the cluster (`bundled` mode) or connecting to an external AI service (`external` mode). + +### **Configuring AI Integration** +Modify the `values.yaml` file to set AI mode, provider, and resources: + +```bash +ai: + mode: "bundled" # Options: bundled | external + provider: "openai" # Can be "openai" or a custom provider + model: "gpt-4-turbo" + resources: + cpu: "2" + memory: "4Gi" + gpu: false + external: + url: "" # External AI service URL + apiKeySecret: + name: "ai-secrets" + key: "external-ai-key" +``` + +## AI Secrets + +To securely store API keys for AI integration, you can create a `secret` that contains the necessary authentication credentials: + +```bash +kubectl create secret generic ai-external-secret \ + --from-literal=api-key='your-external-ai-key' \ + --namespace= +``` ## Installing the Chart diff --git a/charts/intel/ollama/Dockerfile.ai b/charts/intel/ollama/Dockerfile.ai new file mode 100644 index 0000000..466edd9 --- /dev/null +++ b/charts/intel/ollama/Dockerfile.ai @@ -0,0 +1,19 @@ +# Use Ollama as the base image +FROM ollama/ollama + +# Define the models to be included +#ARG MODELS="qwen2.5-coder:3b" +ARG MODELS + +ENV OLLAMA_KEEP_ALIVE=24h + +# Pre-load the models at build time **directly in /root/.ollama** +RUN mkdir -p /root/.ollama && \ + ollama serve & server=$! ; \ + sleep 5 ; \ + for m in $MODELS ; do ollama pull $m ; done ; \ + kill $server + +CMD [ "serve" ] + + diff --git a/charts/intel/templates/deployment.yaml b/charts/intel/templates/deployment.yaml index dc46de4..0615be8 100644 --- a/charts/intel/templates/deployment.yaml +++ b/charts/intel/templates/deployment.yaml @@ -28,22 +28,57 @@ spec: {{- end }} serviceAccountName: {{ include "codetogether.serviceAccountName" . }} containers: + {{- if eq .Values.ai.mode "bundled" }} + - name: codetogether-llm + image: "{{ .Values.ai.image.repository }}:{{ .Values.ai.image.tag }}" + imagePullPolicy: Always + ports: + - name: ai + containerPort: 8000 + protocol: TCP + resources: + requests: + cpu: {{ .Values.ai.resources.requests.cpu | quote }} + memory: {{ .Values.ai.resources.requests.memory | quote }} + limits: + cpu: {{ .Values.ai.resources.limits.cpu | quote }} + memory: {{ .Values.ai.resources.limits.memory | quote }} + {{- end }} - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: >- - {{ .Values.image.repository }} - {{- if .Values.image.digest }}@{{ .Values.image.digest }} - {{- else }}:{{ .Values.image.tag | default .Chart.AppVersion }}{{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: + - name: AI_MODE + value: {{ .Values.ai.mode | quote }} + {{- if eq .Values.ai.mode "bundled" }} + - name: AI_BUNDLED_URL + value: "http://codetogether-llm:8000" + {{- end }} + {{- if eq .Values.ai.mode "external" }} + - name: AI_PROVIDER + valueFrom: + configMapKeyRef: + name: ai-config + key: ai_provider + - name: AI_EXTERNAL_URL + valueFrom: + configMapKeyRef: + name: ai-config + key: ai_url + - name: AI_EXTERNAL_API_KEY + valueFrom: + secretKeyRef: + name: ai-external-secret + key: api-key + {{- end }} # # Set CodeTogether runtime configuration # - name: CT_HQ_BASE_URL value: {{ .Values.codetogether.url | quote }} - - {{- if .Values.java.customCacerts.enabled }} + {{- if .Values.java.customCacerts.enabled }} - name: CT_TRUST_STORE value: -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts {{- end }} @@ -61,7 +96,7 @@ spec: secretKeyRef: name: {{ .Values.java.customCacerts.cacertsSecretName }} key: {{ .Values.java.customCacerts.trustStorePasswordKey }} - optional: true # Ensures the key is optional + optional: true {{- end }} volumeMounts: @@ -83,11 +118,15 @@ spec: protocol: TCP livenessProbe: + httpGet: + path: / + port: http initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} periodSeconds: {{ .Values.livenessProbe.periodSeconds }} timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} successThreshold: {{ .Values.livenessProbe.successThreshold }} failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + readinessProbe: httpGet: path: / port: http @@ -124,4 +163,4 @@ spec: {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} \ No newline at end of file diff --git a/charts/intel/templates/secrets.yaml b/charts/intel/templates/secrets.yaml new file mode 100644 index 0000000..5cdd56d --- /dev/null +++ b/charts/intel/templates/secrets.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: ai-secrets +type: Opaque +data: + openai-api-key: {{ .Values.ai.openai.api_key | b64enc }} + external-ai-key: {{ .Values.ai.external.api_key | b64enc }} diff --git a/charts/intel/values.yaml b/charts/intel/values.yaml index c33abdb..ac9227e 100644 --- a/charts/intel/values.yaml +++ b/charts/intel/values.yaml @@ -138,6 +138,23 @@ securityContext: {} # runAsNonRoot: true # runAsUser: 1000 +ai: + mode: "bundled" # Options: bundled | external + provider: "ollama" # No OpenAI dependency + resources: + requests: + cpu: "2" + memory: "4Gi" + gpu: false + limits: + cpu: "4" + memory: "8Gi" + gpu: false + image: + repository: registry.digitalocean.com/codetogether-registry/ai-summarization + tag: latest + + readinessProbe: initialDelaySeconds: 60 periodSeconds: 60