mirror of
https://github.com/k8sgpt-ai/k8sgpt.git
synced 2026-03-19 11:33:08 +00:00
Compare commits
25 Commits
feature/gh
...
v0.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35c8deee8b | ||
|
|
05d2aef48a | ||
|
|
e4f138dc00 | ||
|
|
917380435f | ||
|
|
5d956e209f | ||
|
|
f62a944941 | ||
|
|
935c4d2c15 | ||
|
|
a6d5132b8c | ||
|
|
b68895a7f1 | ||
|
|
3bd226fc3d | ||
|
|
0c8cbbbf1d | ||
|
|
d08831278e | ||
|
|
9409998884 | ||
|
|
105fe44680 | ||
|
|
7fea7d14a5 | ||
|
|
7c0bdab60e | ||
|
|
6d8b2fe39d | ||
|
|
6934e9c5fa | ||
|
|
e37dbc7909 | ||
|
|
a307c132b3 | ||
|
|
54d8d1cea1 | ||
|
|
dce276e509 | ||
|
|
7532fd26c2 | ||
|
|
6733680a94 | ||
|
|
8be2ba763e |
21
.github/pull_request_template.md
vendored
Normal file
21
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<!--
|
||||
Thanks for creating this pull request 🤗
|
||||
|
||||
Please make sure that the pull request is limited to one type (docs, feature, etc.) and keep it as small as possible. You can open multiple prs instead of opening a huge one.
|
||||
-->
|
||||
|
||||
<!-- If this pull request closes an issue, please mention the issue number below -->
|
||||
Closes # <!-- Issue # here -->
|
||||
|
||||
## 📑 Description
|
||||
<!-- Add a brief description of the pr -->
|
||||
|
||||
## ✅ Checks
|
||||
<!-- Make sure your pr passes the CI checks and do check the following fields as needed - -->
|
||||
- [ ] My pull request adheres to the code style of this project
|
||||
- [ ] My code requires changes to the documentation
|
||||
- [ ] I have updated the documentation as required
|
||||
- [ ] All the tests have passed
|
||||
|
||||
## ℹ Additional Information
|
||||
<!-- Any additional information like breaking changes, dependencies added, screenshots, comparisons between new and old behavior, etc. -->
|
||||
8
.github/workflows/release.yaml
vendored
8
.github/workflows/release.yaml
vendored
@@ -15,21 +15,21 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4
|
||||
with:
|
||||
go-version: '1.20'
|
||||
-
|
||||
name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --snapshot
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
5
CONTRIBUTING.md
Normal file
5
CONTRIBUTING.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Contributing
|
||||
|
||||
## Requirements
|
||||
|
||||
- Golang `1.20`
|
||||
21
LICENSE
21
LICENSE
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Alex Jones
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
39
README.md
39
README.md
@@ -6,51 +6,34 @@
|
||||
AI Powered Kubernetes debugging for SRE, Platform and DevOps teams.
|
||||
<br />
|
||||
|
||||
<img src="images/demo.gif" width=800px; />
|
||||
<img src="images/demo2.gif" width=650px; />
|
||||
|
||||
## What is k8sgpt?
|
||||
|
||||
`k8sgpt` is a tool for scanning your kubernetes clusters, diagnosing and triaging issues in simple english.
|
||||
It reduces the mystery of kubernetes and makes it easy to understand what is going on in your cluster.
|
||||
|
||||
It reduces the mystery of kubernetes and makes it easy to understand what is going on in your cluster.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
# Ensure KUBECONFIG env is set to an active Kubernetes cluster
|
||||
k8sgpt auth key <Your OpenAI key>
|
||||
|
||||
k8sgpt find problems --explain
|
||||
|
||||
```
|
||||
|
||||
### What about kubectl-ai?
|
||||
|
||||
The the kubectl-ai [project](https://github.com/sozercan/kubectl-ai) uses AI to create manifests and apply them to the cluster. It is not what we are trying to do here, it is focusing on writing YAML manifests.
|
||||
|
||||
K8sgpt is focused on triaging and diagnosing issues in your cluster. It is a tool for SRE, Platform & DevOps engineers to help them understand what is going on in their cluster. Cutting through the noise of logs and multiple tools to find the root cause of an issue.
|
||||
|
||||
|
||||
### Configuration
|
||||
|
||||
`k8sgpt` stores config data in `~/.k8sgpt` the data is stored in plain text, including your OpenAI key.
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
❯ k8sgpt find problems --explain
|
||||
default/deathstar-5b559d699b-d4jm7: Back-off pulling image "docker.io/cilium/starwaraaes"
|
||||
|
||||
|
||||
The Kubernetes error message: Back-off pulling image "docker.io/cilium/starwaraaes" means that the Kubernetes cluster is having trouble pulling the specified container image from the Docker registry.
|
||||
|
||||
To solve this issue, you can try the following:
|
||||
|
||||
1. Check if the specified image exists in the Docker registry by running the following command:
|
||||
|
||||
`docker pull docker.io/cilium/starwaraaes`
|
||||
|
||||
2. If the image exists, try pulling the image manually on the node where the container is trying to run. This can be done by running the following command:
|
||||
|
||||
`docker pull docker.io/cilium/starwaraaes`
|
||||
|
||||
3. If the image is not found in the Docker registry, check if the image name and tag are correct.
|
||||
|
||||
4. If the issue persists, check the Docker engine logs for any error messages that might provide more context on the issue.
|
||||
placed-application-demo/placed-application-demo-58469d688c-7wdps: 0/5 nodes are available: 5 node(s) were unschedulable. preemption: 0/5 nodes are available: 5 Preemption is not helpful for scheduling..
|
||||
|
||||
```
|
||||
### Community
|
||||
* Find us on [Slack](https://cloud-native.slack.com/channels/k8sgpt-ai)
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/pkg/analyzer"
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/pkg/client"
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/pkg/openai"
|
||||
"github.com/fatih/color"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ var problemsCmd = &cobra.Command{
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
// Initialise the openAI client
|
||||
openAIClient, err := openai.NewClient()
|
||||
openAIClient, err := ai.NewClient()
|
||||
if err != nil {
|
||||
color.Red("Error: %v", err)
|
||||
os.Exit(1)
|
||||
@@ -34,9 +34,12 @@ var problemsCmd = &cobra.Command{
|
||||
|
||||
ctx := context.Background()
|
||||
// Get kubernetes client from viper
|
||||
client := viper.Get("kubernetesClient").(*client.Client)
|
||||
client := viper.Get("kubernetesClient").(*kubernetes.Client)
|
||||
|
||||
analyzer.RunAnalysis(ctx, client, openAIClient, explain)
|
||||
if err := analyzer.RunAnalysis(ctx, client, openAIClient, explain); err != nil {
|
||||
color.Red("Error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ package cmd
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/cmd/auth"
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/cmd/find"
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/pkg/client"
|
||||
"github.com/fatih/color"
|
||||
"github.com/k8sgpt-ai/k8sgpt/cmd/auth"
|
||||
"github.com/k8sgpt-ai/k8sgpt/cmd/find"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@@ -56,7 +56,7 @@ func init() {
|
||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
|
||||
//Initialise the kubeconfig
|
||||
kubernetesClient, err := client.NewClient(masterURL, kubeconfig)
|
||||
kubernetesClient, err := kubernetes.NewClient(masterURL, kubeconfig)
|
||||
if err != nil {
|
||||
color.Red("Error initialising kubernetes client: %v", err)
|
||||
}
|
||||
|
||||
4
go.mod
4
go.mod
@@ -1,11 +1,11 @@
|
||||
module github.com/cloud-native-skunkworks/k8sgpt
|
||||
module github.com/k8sgpt-ai/k8sgpt
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/briandowns/spinner v1.23.0
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/sashabaranov/go-openai v1.5.4
|
||||
github.com/sashabaranov/go-openai v1.5.5
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.15.0
|
||||
golang.org/x/term v0.6.0
|
||||
|
||||
2
go.sum
2
go.sum
@@ -210,6 +210,8 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sashabaranov/go-openai v1.5.4 h1:I2K7JMIx/EC/mwT2fbypBzJ3OtwKNxaFg4jf3KOvXuc=
|
||||
github.com/sashabaranov/go-openai v1.5.4/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/sashabaranov/go-openai v1.5.5 h1:VYdzEGVk4zV04ZNqNb1DT8w7JCzWM77h3h6pBH27B1k=
|
||||
github.com/sashabaranov/go-openai v1.5.5/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
|
||||
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||
|
||||
BIN
images/demo2.gif
Normal file
BIN
images/demo2.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
2
main.go
2
main.go
@@ -3,7 +3,7 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
|
||||
*/
|
||||
package main
|
||||
|
||||
import "github.com/cloud-native-skunkworks/k8sgpt/cmd"
|
||||
import "github.com/k8sgpt-ai/k8sgpt/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package openai
|
||||
package ai
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -2,25 +2,25 @@ package analyzer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
"github.com/cloud-native-skunkworks/k8sgpt/pkg/client"
|
||||
ai "github.com/cloud-native-skunkworks/k8sgpt/pkg/openai"
|
||||
"github.com/fatih/color"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/ai"
|
||||
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
|
||||
"github.com/spf13/viper"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func RunAnalysis(ctx context.Context, client *client.Client, openAIClient *ai.Client, explain bool) {
|
||||
func RunAnalysis(ctx context.Context, client *kubernetes.Client, aiClient *ai.Client, explain bool) error {
|
||||
|
||||
// search all namespaces for pods that are not running
|
||||
list, err := client.GetClient().CoreV1().Pods("").List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
color.Red("Error: %v", err)
|
||||
os.Exit(1)
|
||||
return err
|
||||
}
|
||||
|
||||
var brokenPods = map[string][]string{}
|
||||
@@ -52,21 +52,53 @@ func RunAnalysis(ctx context.Context, client *client.Client, openAIClient *ai.Cl
|
||||
}
|
||||
|
||||
}
|
||||
for key, value := range brokenPods {
|
||||
fmt.Printf("%s: %s\n", color.YellowString(key), color.RedString(value[0]))
|
||||
|
||||
count := 0
|
||||
for key, value := range brokenPods {
|
||||
fmt.Printf("%s: %s: %s\n", color.CyanString("%d", count), color.YellowString(key), color.RedString(value[0]))
|
||||
count++
|
||||
if explain {
|
||||
s := spinner.New(spinner.CharSets[35], 100*time.Millisecond) // Build our new spinner
|
||||
s.Start()
|
||||
|
||||
response, err := openAIClient.GetCompletion(ctx, strings.Join(value, " "))
|
||||
s.Stop()
|
||||
if err != nil {
|
||||
color.Red("Error: %v", err)
|
||||
return
|
||||
inputValue := strings.Join(value, " ")
|
||||
|
||||
// Check for cached data
|
||||
sEnc := base64.StdEncoding.EncodeToString([]byte(inputValue))
|
||||
// find in viper cache
|
||||
if viper.IsSet(sEnc) {
|
||||
s.Stop()
|
||||
// retrieve data from cache
|
||||
response := viper.GetString(sEnc)
|
||||
if response == "" {
|
||||
color.Red("error retrieving cached data")
|
||||
continue
|
||||
}
|
||||
output, err := base64.StdEncoding.DecodeString(response)
|
||||
if err != nil {
|
||||
color.Red("error decoding cached data: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
color.Green(string(output))
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", color.GreenString(response))
|
||||
response, err := aiClient.GetCompletion(ctx, inputValue)
|
||||
s.Stop()
|
||||
if err != nil {
|
||||
color.Red("error getting completion: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !viper.IsSet(sEnc) {
|
||||
viper.Set(sEnc, base64.StdEncoding.EncodeToString([]byte(response)))
|
||||
if err := viper.WriteConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package client
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
18
renovate.json
Normal file
18
renovate.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base",
|
||||
"helpers:pinGitHubActionDigests"
|
||||
],
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"matchCurrentVersion": "!/^0/",
|
||||
"automerge": true
|
||||
},
|
||||
{
|
||||
"matchManagers": ["github-actions"],
|
||||
"automerge": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user