일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 피카푸클램핑도봉산
- k8sgpt
- api-key
- kubernetes-ai
- 쿠버네티스보안
- 피카푸글램핑
- 도봉산글램핑
- 피카푸캠핑도봉산
- virt-manager
- GPU
- IT
- k8s
- 캠핑
- 쿠버네티스
- kube-ai
- kub-ai
- 티스토리챌린지
- POD
- 글램핑
- mac터널링
- 파드
- 쿠버네티스기초
- 오블완
- 입문용칼
- karpor
- AI
- macos 터널링
- 입문나이프
- kubernetes
- KVM
- Today
- Total
마구잡
kubernetes AI - K8sGPT 활용 (with: Ollama-AI, Google Gemini) 본문
K8sGPT란?
K8sGPT는 Kubernetes 클러스터의 문제를 AI를 활용해 자동으로 분석하고 설명하는 오픈소스 도구이다.
기존 Kubernetes 운영에서 발생하는 문제를 사람이 직접 로그와 이벤트를 분석하여 해결해야 했다면, K8sGPT는 이를 AI를 활용해 자동으로 진단하고 해결 방안을 제안한다.
로컬 LLM에서 K8sGPT로 쿠버네티스 AIOps 실행하기 (2) | 요즘IT
앞서 K8sGPT를 통한 쿠버네티스 AIOps의 가능성 1부에서는 K8sGPT에서 지난 1년간 보여준 변화를 소개했습니다. 이번 글에서는 공개된 AI 제공자를 사용하는 게 아닌 ‘나만의 AI 제공자를 사용하는 법
yozm.wishket.com
추가적으로 쿠버네티스 엠버서더 조훈 님의 글이 잘 정리되어있어 해당 글 링크 첨부드립니다.
( 공식 사이트에서 발췌한 내용을 기반으로 작성하였으나, 명확하지 않은 부분은 경험을 토대로 작성하였습니다.
이는 정확한 정보가 아닐 수 있음을 알려드립니다. )
공식 사이트
K8sGPT
Kubernetes SRE superpowers with AI
k8sgpt.ai
( 광고 클릭은 큰 힘이 됩니다! )
K8sGPT를 사용하는 이유
K8sGPT는 Kubernetes 클러스터의 문제를 AI로 자동 분석하고 설명하는 오픈소스 도구다.
기존에는 운영자가 직접 로그와 이벤트를 분석해야 했지만, K8sGPT는 이를 자동화해 엔지니어의 부담을 줄인다.
Kubernetes 클러스터 운영 중 CrashLoopBackOff, ImagePullBackOff, OOMKilled 같은 오류가 발생하면 빠른 원인 파악이 쉽지 않다. K8sGPT는 AI 기반 분석을 통해 이러한 문제를 신속하게 진단하고 해결책을 제시해 운영 효율성을 높인다.

장점
- Kubernetes 클러스터의 문제를 분석하여 원인과 해결책을 자연어(사람의 언어)로 제공
- Pod, Deployment, Node 등의 상태를 점검하고 자동으로 이슈를 감지
- DevOps 및 SRE 엔지니어의 운영 부담 감소 (비용 감소)
다만 실제 몇 번 사용해 본 입장으로 가독성이 그리 좋지 않으며 인과성을 확실하게 판단하기엔 무리가 있다.
이는 아래에서 자세하게 다룬다.
단점
- AI가 제공하는 분석 결과가 항상 정확하지 않음
- 외부 AI API를 사용할 시 추가적인 비용이 발생 (무료로 사용이 가능하긴 하나 프라이빗 클러스터에는 적합하지 않음)
- 외부 AI를 사용 시 정보 노출 우려가 있음
- 로컬 AI 사용시 모델 적합성들 판단해야 하며, 빠른 처리를 위해선 결국 GPU 카드가 필요함 (비용증가)
- AI가 분석하지만, 해결책을 적용하려면 결국 Kubernetes 개념을 이해해야 함
K8sGPT Install
다양한 환경에서 설치를 지원하며 이는 공식 Docs에 친절히 설명되어 있다.
GitHub - k8sgpt-ai/k8sgpt: Giving Kubernetes Superpowers to everyone
Giving Kubernetes Superpowers to everyone. Contribute to k8sgpt-ai/k8sgpt development by creating an account on GitHub.
github.com
본 환경은 Redhat8에서 진행한다.
1. CLI 명령어로 설치
sudo rpm -ivh https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.48/k8sgpt_amd64.rpm
Retrieving https://github.com/k8sgpt-ai/k8sgpt/releases/download/v0.3.48/k8sgpt_amd64.rpm
Verifying... ################################# [100%]
Preparing... ################################# [100%]
file /usr/bin/k8sgpt from install of k8sgpt-0.3.48-1.x86_64 conflicts with file from package k8sgpt-0.3.37-1.x86_64
2. 설치 확인
k8sgpt
Kubernetes debugging powered by AI
Usage:
k8sgpt [command]
Available Commands:
analyze This command will find problems within your Kubernetes cluster
auth Authenticate with your chosen backend
cache For working with the cache the results of an analysis
completion Generate the autocompletion script for the specified shell
filters Manage filters for analyzing Kubernetes resources
generate Generate Key for your chosen backend (opens browser)
help Help about any command
integration Integrate another tool into K8sGPT
serve Runs k8sgpt as a server
version Print the version number of k8sgpt
Flags:
--config string Default config file (/root/.config/k8sgpt/k8sgpt.yaml)
-h, --help help for k8sgpt
--kubeconfig string Path to a kubeconfig. Only required if out-of-cluster.
--kubecontext string Kubernetes context to use. Only required if out-of-cluster.
Use "k8sgpt [command] --help" for more information about a command.
위에서 보듯 K8sGPT 설치 자체는 간단하다.
3. K8sGPT 실행
k8sgpt analyze
AI Provider: AI not used; --explain not set
0: Service build/java-app-service()
- Error: Service has no endpoints, expected label app=java-app
... 중략
30: ValidatingWebhookConfgiguration /validation.webhook.serving.knative.dev()
- Error: Service webhook not found as mapped to by Validating Webhook validation.webhook.serving.knative.dev
아직 AI를 사용하지 않은 상태에서 클러스터의 문제점을 파악한다.
현재 본인의 클러스터는 테스트베드여서 아주 많은 문제점들이 나온다.
외부 AI 사용하기 - Gemini
K8sGPT의 메인 기능은 Kubernetes 클러스터의 문제를 AI로 자동 분석하고 설명하는 능력이다.
이때 필연적으로 사용되어야 하는 게 AI 모델이다, 이때 운영자는 두 가지 선택을 할 수 있다.
1. 퍼블릭한 AI API를 사용한다.
2. 로컬에서 사용하는 AI를 사용하거나 만든다
아래 사용가능한 AI 목록부터 확인해 본다.
k8sgpt auth list
Default:
> openai
Active:
> localai
> google
> googlevertexai
Unused:
> openai
> azureopenai
> cohere
> amazonbedrock
> amazonsagemaker
> noopai
> huggingface
> oci
현재 auth list엔 여러 AI가 존재한다.
이번에는 Google의 Gemini를 사용해 본다.
Gemini API key 발급
K8sGPT의 메인 기능은 Kubernetes 클러스터의 문제를 AI로 자동 분석하고 설명하는 능력이다.
이때 필연적으로 사용되어야 하는 게 AI 모델이다.
K8sGPT의 기본 모델은 open-ai를 사용한다, 다만 무료로 거의 사용할 수 없기에 가장 만만한 Gemini를 사용한다.
Gemini Developer API 가격 책정 | Gemini API | Google AI for Developers
Gemini Developer API 가격 책정
ai.google.dev
1. API key 발급 or 가져오기
https://aistudio.google.com/app/u/1/apikey
로그인 - Google 계정
이메일 또는 휴대전화
accounts.google.com

2. auth 등록
k8sgpt auth add --backend google --model gemini-1.5-flash --password "발급받은 API"
2-1. 이미 google이 지정되어 등록이 안된다면 update 명령어로 수정이 가능하다.
k8sgpt auth update --backend google --model gemini-1.5-flash --password "발급받은 API"
3. Interactive 모드로 사용해 보기
k8sgpt analyze --explain --interactive --backend=google
Interactive mode enabled [type exit to close.]
Input text: 한국말로 현재 클러스터의 문제를 설명해줄래?
현재 Kubernetes 클러스터에는 여러 가지 문제가 발생하고 있습니다. 주요 문제는 다음과 같습니다.
1. **저장소 클래스 누락:** `이름 가림` PersistentVolumeClaim은 "nfs-client-115"라는 저장소 클래스를 찾을 수 없습니다. NFS 클라이언트를 설정하고 해당 저장소 클래스를 생성해야 합니다.
2. **Pod와 Service 매칭 문제:** `java-app-service` Service는 `app=java-app` 라벨을 가진 Pod를 찾을 수 없습니다. Pod에 올바른 라벨이 지정되었는지, 그리고 Service의 selector가 Pod의 라벨과 일치하는지 확인해야 합니다.
... 중략
6. **MutatingWebhookConfiguration 및 ValidatingWebhookConfiguration 문제 (15개 이상):** 다수의 MutatingWebhookConfiguration과 ValidatingWebhookConfiguration이 `kserve`, `istio`, `knative`, `kubeflow` 등의 구성요소에 필요한 서비스를 찾을 수 없습니다. 이러한 서비스들이 올바르게 배포되고, Webhook 설정에서 서비스 이름과 네임스페이스가 정확한지 확인해야 합니다. 대부분 `kserve-webhook-server-service`, `istiod`, `eventing-webhook`, `domainmapping-webhook`, `katib-controller`, `admission-webhook-service`, `cache-server` 등의 서비스 관련 문제입니다.
요약하자면, 클러스터의 여러 구성 요소 (저장소, 서비스, Pod, Ingress, Webhook) 간의 설정 오류와 일부 구성 요소의 배포 또는 설정 문제로 인해 클러스터가 제대로 작동하지 않고 있습니다. 위에 제시된 각 문제에 대한 해결책을 따라 문제를 해결해야 합니다. 특히, 다수의 Webhook 관련 문제는 Knative, Istio, KServe, Kubefow 등의 설치 및 구성 상태를 점검해야 함을 시사합니다.
Input text: 해결 방법을 한국말로 알려줘
제공된 로그에는 Kubernetes 클러스터에서 다양한 구성 요소와 관련된 31개의 에러가 나타나고 있습니다. 각 에러와 해결 방법을 한국어로 요약하면 다음과 같습니다. 에러 메시지의 색상 코드는 생략했습니다.
**0. PersistentVolumeClaim (이름가림): StorageClass "nfs-client-115" 없음**
* **문제:** PersistentVolumeClaim이 필요로 하는 StorageClass "nfs-client-115"가 존재하지 않습니다.
* **해결책:**
1. 설정 파일에서 StorageClass 이름이 정확한지 확인합니다.
2. "nfs-client-115" StorageClass가 없다면 생성합니다.
3. Kubernetes 클러스터가 기본 저장소 제공자에 연결하는 데 필요한 드라이버와 권한을 가지고 있는지 확인합니다.
**1. Service (java-app-service): 엔드포인트 없음**
* **문제:** Service가 `app=java-app` 라벨을 가진 Pod를 찾을 수 없습니다.
* **해결책:**
1. `kubectl describe svc <service-name>` 명령어로 Service의 선택자를 확인합니다.
2. `kubectl get pods --show-labels` 명령어로 Pod 라벨을 확인합니다.
3. Pod 라벨이 Service 선택자와 일치하는지 확인합니다.
4. 필요하다면 Pod를 재시작합니다.
... 중략
전반적으로 이 문제들은 Kubernetes 구성 요소들의 상호 의존성 문제와 구성 오류로 인해 발생합니다. 각 에러 메시지에 제시된 명령어들을 사용하여 문제의 원인을 정확히 파악하고 해결해야 합니다. 특히, 8번부터 21번, 23번부터 30번까지의 에러들은 Knative, Istio, Kubeflow 등의 서비스들이 제대로 설치 및 구성되었는지 확인하는 것이 중요합니다. 필요하다면 해당 서비스들의 문서를 참고하여 문제 해결을 진행해야 합니다.
필터를 활용해 리소스를 지정하거나 네임스페이스를 지정할 수 있다.
k8sgpt analyze -e -f Pod -b google -n open-webui -l Korean
AI Provider: google
No problems detected
Ollama, Open Web-UI 사용
Google Gemini로 준수한 답변을 받아낼 수 있었다.
그러나 서두에서의 언급처럼 외부 AI를 사용하게 되면 정보유출 및 가격정책에 의한 제약사항이 생기기 마련이다.
이때 우리는 로컬 AI를 사용하여 문제를 해결할 수 있다.
Ollama란?
Ollama는 로컬에서 다양한 오픈소스 LLM을 손쉽게 실행할 수 있도록 지원하는 도구다. Llama 3, Mistral, Gemma 등 다양한 모델을 지원하며, 모델의 가중치, 설정, 데이터셋을 하나의 패키지로 관리할 수 있다.
- 간편한 모델 실행 명령어 한 줄로 다양한 모델 실행 가능
- 로컬 환경에서 동작 인터넷 연결 없이 오프라인 실행 가능
- 빠른 모델 다운로드 및 관리 모델 실행과 관리가 쉽고 직관적
Ollama
Get up and running with large language models.
ollama.com
Open WebUI란?
Open WebUI는 웹 기반 인터페이스를 통해 로컬에서 LLM(대규모 언어 모델)을 실행하고 관리할 수 있도록 지원하는 오픈소스 플랫폼이다. 이를 통해 사용자는 복잡한 설정 없이도 웹 브라우저만으로 다양한 모델과 상호작용할 수 있다.
- 웹 기반 인터페이스 브라우저에서 직접 모델과 상호작용 가능
- 다양한 LLM 지원 여러 모델을 로컬에서 실행하고 관리 가능
- 다중 사용자 지원 여러 사용자가 동시에 접속하여 활용 가능
Open WebUI
Open WebUI Community is currently undergoing a major revamp to improve user experience and performance ✨
openwebui.com
Ollama & Open WebUI Install
쿠버네티스 클러스터 환경에서 설치하기 위해 helm을 통한 설치로 진행한다.
Open WebUI 차트 내 Ollama가 내장되어 있어 따로 Ollama 차트를 받을 필요는 없다.
추가적으로 본 글에선 GPU자원을 사용할 예정이고 web-ui는 metal-lb를 통해 loadBalancer 형태의 서비스로 만들 예정이다.
1. helm repo 추가 및 tgz 다운로드
helm repo add open-webui https://helm.openwebui.com
helm repo update
helm pull open-webui/open-webui
-rw-r--r--. 1 root root 313362 Feb 24 00:11 open-webui-5.19.0.tgz
2. tgz 압축해제 및 values.yaml 수정 (기본으로 아무 수정 없이 설치해도 괜찮습니다.)
tar -zxvf open-webui-5.19.0.tgz
cd open-webui
ls -alth
total 56K
drwxr-xr-x. 4 root root 179 Feb 24 00:18 .
drwxr-xr-x. 4 root root 57 Feb 24 00:16 ..
-rw-r--r--. 1 root root 8.9K Feb 19 02:05 values.yaml
drwxr-xr-x. 6 root root 62 Feb 18 19:49 charts
drwxr-xr-x. 2 root root 4.0K Feb 18 19:49 templates
-rw-r--r--. 1 root root 464 Feb 18 12:48 Chart.lock
-rw-r--r--. 1 root root 1.2K Feb 18 12:48 Chart.yaml
-rw-r--r--. 1 root root 381 Feb 18 12:48 .helmignore
-rw-r--r--. 1 root root 11K Feb 18 12:48 README.md
-rw-r--r--. 1 root root 799 Feb 18 12:48 README.md.gotmpl
-rw-r--r--. 1 root root 9.0K Feb 18 12:48 values-gke-min.yaml
vim values.yaml
2-1. values.yaml 전문 (StorageClass, GPU, Redis는 필수는 아닙니다.)
nameOverride: ""
namespaceOverride: ""
ollama:
enabled: true
fullnameOverride: "open-webui-ollama"
#gpu:
# enabled: true
# type: 'nvidia'
# number: 1
#models:
# pull:
# - llama3
# run:
# - llama3
#runtimeClassName: nvidia
#persistentVolume:
# enabled: true
# volumeName: "example-pre-existing-pv-created-by-smb-csi"
pipelines:
# -- Automatically install Pipelines chart to extend Open WebUI functionality using Pipelines: https://github.com/open-webui/pipelines
enabled: true
# -- This section can be used to pass required environment variables to your pipelines (e.g. Langfuse hostname)
extraEnvVars: []
tika:
# -- Automatically install Apache Tika to extend Open WebUI
enabled: false
# -- A list of Ollama API endpoints. These can be added in lieu of automatically installing the Ollama Helm chart, or in addition to it.
ollamaUrls: []
# -- Disables taking Ollama Urls from `ollamaUrls` list
ollamaUrlsFromExtraEnv: false
websocket:
# -- Enables websocket support in Open WebUI with env `ENABLE_WEBSOCKET_SUPPORT`
enabled: true
# -- Specifies the websocket manager to use with env `WEBSOCKET_MANAGER`: redis (default)
manager: redis
# -- Specifies the URL of the Redis instance for websocket communication. Template with `redis://[:<password>@]<hostname>:<port>/<db>`
url: redis://open-webui-redis:6379/0
# -- Deploys a redis
redis:
# -- Enable redis installation
enabled: true
# -- Redis name
name: open-webui-redis
# -- Redis labels
labels: {}
# -- Redis annotations
annotations: {}
# -- Redis pod
pods:
# -- Redis pod annotations
annotations: {}
# -- Redis image
image:
repository: redis
tag: 7.4.2-alpine3.21
pullPolicy: IfNotPresent
# -- Redis command (overrides default)
command: []
# -- Redis arguments (overrides default)
args: []
# -- Redis resources
resources: {}
# -- Redis service
service:
# -- Redis container/target port
containerPort: 6379
# -- Redis service type
type: ClusterIP
# -- Redis service labels
labels: {}
# -- Redis service annotations
annotations: {}
# -- Redis service port
port: 6379
# -- Redis service node port. Valid only when type is `NodePort`
nodePort: ""
# -- Deploys a Redis cluster with subchart 'redis' from bitnami
redis-cluster:
# -- Enable Redis installation
enabled: false
# -- Redis cluster name (recommended to be 'open-webui-redis')
# - In this case, redis url will be 'redis://open-webui-redis-master:6379/0' or 'redis://[:<password>@]open-webui-redis-master:6379/0'
fullnameOverride: open-webui-redis
# -- Redis Authentication
auth:
# -- Enable Redis authentication (disabled by default). For your security, we strongly suggest that you switch to 'auth.enabled=true'
enabled: false
# -- Replica configuration for the Redis cluster
replica:
# -- Number of Redis replica instances
replicaCount: 3
# -- Value of cluster domain
clusterDomain: cluster.local
annotations: {}
podAnnotations: {}
podLabels: {}
replicaCount: 1
# -- Strategy for updating the workload manager: deployment or statefulset
strategy: {}
# -- Open WebUI image tags can be found here: https://github.com/open-webui/open-webui
image:
repository: ghcr.io/open-webui/open-webui
tag: ""
pullPolicy: "IfNotPresent"
serviceAccount:
enable: true
name: ""
annotations: {}
automountServiceAccountToken: false
# -- Configure imagePullSecrets to use private registry
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry>
imagePullSecrets: []
# imagePullSecrets:
# - name: myRegistryKeySecretName
# -- Probe for liveness of the Open WebUI container
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes>
livenessProbe: {}
# livenessProbe:
# httpGet:
# path: /health
# port: http
# failureThreshold: 1
# periodSeconds: 10
# -- Probe for readiness of the Open WebUI container
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes>
readinessProbe: {}
# readinessProbe:
# httpGet:
# path: /health/db
# port: http
# failureThreshold: 1
# periodSeconds: 10
# -- Probe for startup of the Open WebUI container
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes>
startupProbe: {}
# startupProbe:
# httpGet:
# path: /health
# port: http
# initialDelaySeconds: 30
# periodSeconds: 5
# failureThreshold: 20
resources: {}
copyAppData:
resources: {}
managedCertificate:
enabled: false
name: "mydomain-chat-cert" # You can override this name if needed
domains:
- chat.example.com # update to your real domain
ingress:
enabled: false
class: ""
# -- Use appropriate annotations for your Ingress controller, e.g., for NGINX:
annotations: {}
# # Example for GKE Ingress
# kubernetes.io/ingress.class: "gce"
# kubernetes.io/ingress.global-static-ip-name: "open-webui-external-ip" # you need to create this address in GCP console
# # Force HTTP to redirect to HTTPS
# nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
# nginx.ingress.kubernetes.io/permanent-redirect: "https://chat.example.com"
# networking.gke.io/managed-certificates: "mydomain-chat-cert"
# # nginx.ingress.kubernetes.io/rewrite-target: /
host: "chat.example.com" # update to your real domain
additionalHosts: []
tls: false
existingSecret: ""
persistence:
enabled: true
size: 2Gi
# -- Use existingClaim if you want to re-use an existing Open WebUI PVC instead of creating a new one
existingClaim: ""
# -- Subdirectory of Open WebUI PVC to mount. Useful if root directory is not empty.
subPath: ""
# -- If using multiple replicas, you must update accessModes to ReadWriteMany
accessModes:
- ReadWriteOnce
storageClass: nfs-csi-115
selector: {}
annotations: {}
# -- Node labels for pod assignment.
nodeSelector: {}
# -- Tolerations for pod assignment
tolerations: []
# -- Affinity for pod assignment
affinity: {}
# -- Topology Spread Constraints for pod assignment
topologySpreadConstraints: []
# -- Service values to expose Open WebUI pods to cluster
service:
type: LoadBalancer
annotations: {}
port: 80
containerPort: 8080
nodePort: ""
labels: {}
loadBalancerClass: ""
# -- OpenAI base API URL to use. Defaults to the Pipelines service endpoint when Pipelines are enabled, and "https://api.openai.com/v1" if Pipelines are not enabled and this value is blank
openaiBaseApiUrl: "https://api.openai.com/v1"
# -- OpenAI base API URLs to use. Overwrites the value in openaiBaseApiUrl if set
openaiBaseApiUrls: []
# - "https://api.openai.com/v1"
# - "https://api.company.openai.com/v1"
# -- Env vars added to the Open WebUI deployment. Most up-to-date environment variables can be found here: https://docs.openwebui.com/getting-started/env-configuration/
extraEnvVars:
# -- Default API key value for Pipelines. Should be updated in a production deployment, or be changed to the required API key if not using Pipelines
- name: OPENAI_API_KEY
value: "0p3n-w3bu!"
# valueFrom:
# secretKeyRef:
# name: pipelines-api-key
# key: api-key
# - name: OPENAI_API_KEY
# valueFrom:
# secretKeyRef:
# name: openai-api-key
# key: api-key
# - name: OLLAMA_DEBUG
# value: "1"
# -- Configure container volume mounts
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/configure-volume-storage/>
volumeMounts:
initContainer: []
# - name: ""
# mountPath: ""
container: []
# - name: ""
# mountPath: ""
# -- Configure pod volumes
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/configure-volume-storage/>
volumes: []
# - name: ""
# configMap:
# name: ""
# - name: ""
# emptyDir: {}
# -- Configure pod security context
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-containe>
podSecurityContext:
{}
# fsGroupChangePolicy: Always
# sysctls: []
# supplementalGroups: []
# fsGroup: 1001
# -- Configure container security context
# ref: <https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-containe>
containerSecurityContext:
{}
# runAsUser: 1001
# runAsGroup: 1001
# runAsNonRoot: true
# privileged: false
# allowPrivilegeEscalation: false
# readOnlyRootFilesystem: false
# capabilities:
# drop:
# - ALL
# seccompProfile:
# type: "RuntimeDefault"
# -- Extra resources to deploy with Open WebUI
extraResources:
[]
# - apiVersion: v1
# kind: ConfigMap
# metadata:
# name: example-configmap
# data:
## example-key: example-value
3. GPU 자원 수정 (옵션)
vim charts/ollama/values.yaml
3-1. values.yaml 수정
# Default values for ollama-helm.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# -- Number of replicas
replicaCount: 1
# Knative configuration
knative:
# -- Enable Knative integration
enabled: false
# -- Knative service container concurrency
containerConcurrency: 0
# -- Knative service timeout seconds
timeoutSeconds: 300
# -- Knative service response start timeout seconds
responseStartTimeoutSeconds: 300
# -- Knative service idle timeout seconds
idleTimeoutSeconds: 300
# Docker image
image:
# -- Docker image registry
repository: ollama/ollama
# -- Docker pull policy
pullPolicy: IfNotPresent
# -- Docker image tag, overrides the image tag whose default is the chart appVersion.
tag: ""
# -- Docker registry secret names as an array
imagePullSecrets: []
# -- String to partially override template (will maintain the release name)
nameOverride: ""
# -- String to fully override template
fullnameOverride: ""
# -- String to fully override namespace
namespaceOverride: ""
# Ollama parameters
ollama:
fullnameOverride: "open-webui-ollama"
gpu:
enabled: true
type: 'nvidia'
number: 1
mig:
enabled: false
models:
# -- List of models to pull at container startup
# The more you add, the longer the container will take to start if models are not present
# pull:
# - llama2
# - mistral
pull: []
# -- List of models to load in memory at container startup
# run:
# - llama2
# - mistral
run: []
# -- List of models to create at container startup, there are two options
# 1. Create a raw model
# 2. Load a model from configMaps, configMaps must be created before and are loaded as volume in "/models" directory.
# create:
# - name: llama3.1-ctx32768
# configMapRef: my-configmap
# configMapKeyRef: configmap-key
# - name: llama3.1-ctx32768
# template: |
# FROM llama3.1
# PARAMETER num_ctx 32768
create: []
# -- Add insecure flag for pulling at container startup
insecure: false
# -- Override ollama-data volume mount path, default: "/root/.ollama"
mountPath: ""
# Service account
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
serviceAccount:
# -- Specifies whether a service account should be created
create: true
# -- Automatically mount a ServiceAccount's API credentials?
automount: true
# -- Annotations to add to the service account
annotations: {}
# -- The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
# -- Map of annotations to add to the pods
podAnnotations: {}
# -- Map of labels to add to the pods
podLabels: {}
# -- Pod Security Context
podSecurityContext: {}
# fsGroup: 2000
# -- Container Security Context
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
# -- Specify runtime class
runtimeClassName: ""
# Configure Service
service:
# -- Service type
type: ClusterIP
# -- Service port
port: 11434
# -- Service node port when service type is 'NodePort'
nodePort: 31434
# -- Load Balancer IP address
loadBalancerIP:
# -- Annotations to add to the service
annotations: {}
# Configure the ingress resource that allows you to access the
ingress:
# -- Enable ingress controller resource
enabled: false
# -- IngressClass that will be used to implement the Ingress (Kubernetes 1.18+)
className: ""
# -- Additional annotations for the Ingress resource.
annotations: {}
# kubernetes.io/ingress.class: traefik
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
# The list of hostnames to be covered with this ingress record.
hosts:
- host: ollama.local
paths:
- path: /
pathType: Prefix
# -- The tls configuration for hostnames to be covered with this ingress record.
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
# Configure resource requests and limits
# ref: http://kubernetes.io/docs/user-guide/compute-resources/
resources:
# -- Pod requests
requests: {}
# Memory request
# memory: 4096Mi
# CPU request
# cpu: 2000m
# -- Pod limit
limits: {}
# Memory limit
# memory: 8192Mi
# CPU limit
# cpu: 4000m
# Configure extra options for liveness probe
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes
livenessProbe:
# -- Enable livenessProbe
enabled: true
# -- Request path for livenessProbe
path: /
# -- Initial delay seconds for livenessProbe
initialDelaySeconds: 60
# -- Period seconds for livenessProbe
periodSeconds: 10
# -- Timeout seconds for livenessProbe
timeoutSeconds: 5
# -- Failure threshold for livenessProbe
failureThreshold: 6
# -- Success threshold for livenessProbe
successThreshold: 1
# Configure extra options for readiness probe
# ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes
readinessProbe:
# -- Enable readinessProbe
enabled: true
# -- Request path for readinessProbe
path: /
# -- Initial delay seconds for readinessProbe
initialDelaySeconds: 30
# -- Period seconds for readinessProbe
periodSeconds: 5
# -- Timeout seconds for readinessProbe
timeoutSeconds: 3
# -- Failure threshold for readinessProbe
failureThreshold: 6
# -- Success threshold for readinessProbe
successThreshold: 1
# Configure autoscaling
autoscaling:
# -- Enable autoscaling
enabled: false
# -- Number of minimum replicas
minReplicas: 1
# -- Number of maximum replicas
maxReplicas: 100
# -- CPU usage to target replica
targetCPUUtilizationPercentage: 80
# -- targetMemoryUtilizationPercentage: 80
# -- Additional volumes on the output Deployment definition.
volumes: []
# -- - name: foo
# secret:
# secretName: mysecret
# optional: false
# -- Additional volumeMounts on the output Deployment definition.
volumeMounts: []
# -- - name: foo
# mountPath: "/etc/foo"
# readOnly: true
# -- Additional arguments on the output Deployment definition.
extraArgs: []
# -- Additional environments variables on the output Deployment definition.
# For extra OLLAMA env, please refer to https://github.com/ollama/ollama/blob/main/envconfig/config.go
extraEnv: []
# - name: OLLAMA_DEBUG
# value: "1"
# -- Additionl environment variables from external sources (like ConfigMap)
extraEnvFrom: []
# - configMapRef:
# name: my-env-configmap
# Enable persistence using Persistent Volume Claims
# ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
persistentVolume:
# -- Enable persistence using PVC
enabled: true
# -- Ollama server data Persistent Volume access modes
# Must match those of existing PV or dynamic provisioner
# Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/
accessModes:
- ReadWriteOnce
# -- Ollama server data Persistent Volume annotations
annotations: {}
# -- If you'd like to bring your own PVC for persisting Ollama state, pass the name of the
# created + ready PVC here. If set, this Chart will not create the default PVC.
# Requires server.persistentVolume.enabled: true
existingClaim: ""
# -- Ollama server data Persistent Volume size
size: 30Gi
# -- Ollama server data Persistent Volume Storage Class
# If defined, storageClassName: <storageClass>
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default provisioner. (gp2 on AWS, standard on
# GKE, AWS & OpenStack)
storageClass: nfs-csi
# -- Ollama server data Persistent Volume Binding Mode
# If defined, volumeMode: <volumeMode>
# If empty (the default) or set to null, no volumeBindingMode spec is
# set, choosing the default mode.
volumeMode: ""
# -- Subdirectory of Ollama server data Persistent Volume to mount
# Useful if the volume's root directory is not empty
subPath: ""
# -- Pre-existing PV to attach this claim to
# Useful if a CSI auto-provisions a PV for you and you want to always
# reference the PV moving forward
volumeName: ""
# -- Node labels for pod assignment.
nodeSelector: {}
# -- Tolerations for pod assignment
tolerations: []
# -- Affinity for pod assignment
affinity: {}
# -- Lifecycle for pod assignment (override ollama.models startup pull/run)
lifecycle: {}
# How to replace existing pods
updateStrategy:
# -- Deployment strategy can be "Recreate" or "RollingUpdate". Default is Recreate
type: "Recreate"
# -- Topology Spread Constraints for pod assignment
topologySpreadConstraints: {}
# -- Init containers to add to the pod
initContainers: []
# - name: startup-tool
# image: alpine:3
# command: [sh, -c]
# args:
# - echo init
# -- Use the host’s ipc namespace.
hostIPC: false
# -- Use the host’s pid namespace
hostPID: false
# -- Use the host's network namespace.
hostNetwork: false
# -- Extra K8s manifests to deploy
extraObjects: []
# - apiVersion: v1
# kind: PersistentVolume
# metadata:
# name: aws-efs
# data:
# key: "value"
# - apiVersion: scheduling.k8s.io/v1
# kind: PriorityClass
# metadata:
# name: high-priority
# value: 1000000
# globalDefault: false
# description: "This priority class should be used for XYZ service pods only."
4. helm install
helm upgrade open-webui --install -f values.yaml -n open-webui .
kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/open-webui-0 1/1 Running 0 10m
pod/open-webui-ollama-668cd748c9-5hzs6 1/1 Running 0 4d22h
pod/open-webui-pipelines-78b44676f9-sllfx 1/1 Running 0 4d22h
pod/open-webui-redis-558f68d648-cb4kx 1/1 Running 0 10m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/open-webui LoadBalancer 10.107.214.125 192.168.60.117 80:32410/TCP 4d22h
service/open-webui-ollama ClusterIP 10.97.201.157 <none> 11434/TCP 4d22h
service/open-webui-pipelines ClusterIP 10.110.26.156 <none> 9099/TCP 4d22h
service/open-webui-redis ClusterIP 10.101.219.130 <none> 6379/TCP 10m
5. open webui 접속 (LoadBalancer가 아닐 시 NodePort로 접속)

5-1. 설정 -> 관리자 설정 -> 모델 -> 매니지 모델 -> 모델 다운로드 (옵션)

6. Open webui & Ollama 테스트

7. K8sGPT local-ai 연결
k8sgpt auth update --backend localai --baseurl http://Ollama-서비스-아이피:포트/v1 --model "다운 받은 모델"
k8sgpt auth update --backend localai --baseurl http://10.97.201.157:11434/v1 --model phi4
8. interactive 모드 모델 테스트
Input text: 안녕? 넌 한국말로 설명할 수 있어?
네, 물론입니다! 아래는 주어진 문서의 요약과 해결 방법을 한국어로 번역한 것입니다.
---
### 문제 요약
여러 개의 Validating Webhook 구성에서 서비스가 찾아지지 않는 오류가 발생하고 있습니다. 이 오류는 다양한 `kserve-webhook-server.validator`와 관련된 여러 유형의 리소스에 대해 반복적으로 나타납니다.
### 해결 방법
1. **서비스 존재 확인**:
- 각 오류 메시지에서 언급된 서비스가 실제로 존재하는지 Kubernetes YAML 파일이나 다른 수단을 통해 확인합니다.
... 중략
7. **로그 검사**:
- 문제가 지속되면 서비스와 웹훅의 로그를 확인하여 추가적인 오류 메시지나 단서를 찾습니다.
이러한 단계들을 통해 문제를 해결할 수 있기를 바랍니다. 추가적인 도움이 필요하면 언제든지 말씀해 주세요!
후기
이렇듯 local-ai를 연결하여 K8sGPT를 사용해 프라이빗 환경에서의 테스트가 정상적으로 종료되었다.
단점
로컬 모델이 가격적인 측면, 보안, 정보 유출 측면에서 유리해 보이긴 하나 이 또한 완벽하진 않다.
로컬 모델이 외부 AI만큼 빠르고 정확한 성능을 보여주기 위해선 GPU, RAM, SSD 등의 하드웨어적 자원이 충분히 받침 되어야 하며
AI 모델의 파인튜닝은 거의 필수적이다.
대규모 예산을 운용 가능한 회사는 문제없이 사용이 가능하지만, 작은 기업의 경우 하드웨어, AI 튜닝의 문제는 쉽게 해결하기 힘들다.
다만 작은 모델을 잘 튜닝하여 운영자에게 "도움" 정도를 줄 AI를 대시보드 상 녹여낸다면 꽤나 편리한 서비스가 될 것 같다.
잘못된 정보, 오류, 오타 등을 댓글로 알려주시면 감사하겠습니다.
'Kubernetes' 카테고리의 다른 글
Kubernetes-AI Karpor (with Ollama) (3) | 2025.03.13 |
---|---|
Kubernetes에서 변경 불가능한(Immutable) Pod란 (0) | 2025.03.10 |
Kubernetes Migrating a Calico cluster to Cilium (0) | 2025.01.06 |
Kubernetes OpenEBS LVM 사용하기 (0) | 2024.11.08 |
kubernetes kubelet 인증서 갱신 시점 (2) | 2024.10.29 |