diff --git a/README.md b/README.md index f61e15e..56114cb 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,11 @@ -# k8sgpt - -
-AI Powered Kubernetes debugging for SRE, Platform and DevOps teams. -
- - - -## 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 has SRE experience codified into it's analyzers and helps to pull out the most relevent information to enrich it with AI. + + ## Usage diff --git a/pkg/analyzer/events.go b/pkg/analyzer/events.go new file mode 100644 index 0000000..ec93074 --- /dev/null +++ b/pkg/analyzer/events.go @@ -0,0 +1,33 @@ +package analyzer + +import ( + "context" + + "github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func FetchLatestPodEvent(ctx context.Context, kubernetesClient *kubernetes.Client, pod *v1.Pod) (*v1.Event, error) { + + // get the list of events + events, err := kubernetesClient.GetClient().CoreV1().Events(pod.Namespace).List(ctx, + metav1.ListOptions{ + FieldSelector: "involvedObject.name=" + pod.Name, + }) + + if err != nil { + return nil, err + } + // find most recent event + var latestEvent *v1.Event + for _, event := range events.Items { + if latestEvent == nil { + latestEvent = &event + } + if event.LastTimestamp.After(latestEvent.LastTimestamp.Time) { + latestEvent = &event + } + } + return latestEvent, nil +} diff --git a/pkg/analyzer/podAnalyzer.go b/pkg/analyzer/podAnalyzer.go index 886f350..f562c03 100644 --- a/pkg/analyzer/podAnalyzer.go +++ b/pkg/analyzer/podAnalyzer.go @@ -46,6 +46,19 @@ func AnalyzePod(ctx context.Context, client *kubernetes.Client, aiClient *ai.Cli failureDetails = append(failureDetails, containerStatus.State.Waiting.Message) brokenPods[fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)] = failureDetails } + // This represents a container that is still being created or blocked due to conditions such as OOMKilled + if containerStatus.State.Waiting.Reason == "ContainerCreating" && pod.Status.Phase == "Pending" { + + // parse the event log and append details + evt, err := FetchLatestPodEvent(ctx, client, &pod) + if err != nil { + continue + } + if evt.Reason == "FailedCreatePodSandBox" { + failureDetails = append(failureDetails, evt.Message) + brokenPods[fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)] = failureDetails + } + } } } @@ -96,6 +109,8 @@ func AnalyzePod(ctx context.Context, client *kubernetes.Client, aiClient *ai.Cli return err } } + + color.Green(response) } }