Skip to content

Commit 3c4de90

Browse files
authored
Merge pull request #8800 from sbueringer/pr-dump-kube-system-pods
🌱 test/e2e: also dump workload cluster kube-system pods
2 parents 8bf1f64 + e73b2b2 commit 3c4de90

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

controlplane/kubeadm/internal/controllers/status.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ func (r *KubeadmControlPlaneReconciler) updateStatus(ctx context.Context, kcp *c
6666
return nil
6767
}
6868

69-
machinesWithHealthAPIServer := ownedMachines.Filter(collections.HealthyAPIServer())
70-
lowestVersion := machinesWithHealthAPIServer.LowestVersion()
69+
machinesWithHealthyAPIServer := ownedMachines.Filter(collections.HealthyAPIServer())
70+
lowestVersion := machinesWithHealthyAPIServer.LowestVersion()
7171
if lowestVersion != nil {
7272
kcp.Status.Version = lowestVersion
7373
}

docs/book/src/developer/logging.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,28 +176,28 @@ In the Log browser the following queries can be used to browse logs by controlle
176176
Will return logs from the `capi-controller-manager` which are parsed in json. Passing the query through the json parser allows filtering by key-value pairs that are part of nested json objects. For example `.cluster.name` becomes `cluster_name`.
177177

178178
```
179-
{app="capi-controller-manager"} | json | cluster_name="my-cluster"
179+
{app="capi-controller-manager"} | json | Cluster_name="my-cluster"
180180
```
181181
Will return logs from the `capi-controller-manager` that are associated with the Cluster `my-cluster`.
182182
183183
```
184-
{app="capi-controller-manager"} | json | cluster_name="my-cluster" | v <= 2
184+
{app="capi-controller-manager"} | json | Cluster_name="my-cluster" | v <= 2
185185
```
186186
Will return logs from the `capi-controller-manager` that are associated with the Cluster `my-cluster` with log level <= 2.
187187
188188
```
189-
{app="capi-controller-manager"} | json | cluster_name="my-cluster" reconcileID="6f6ad971-bdb6-4fa3-b803-xxxxxxxxxxxx"
189+
{app="capi-controller-manager"} | json | Cluster_name="my-cluster" reconcileID="6f6ad971-bdb6-4fa3-b803-xxxxxxxxxxxx"
190190
```
191191
192192
Will return logs from the `capi-controller-manager`, associated with the Cluster `my-cluster` and the Reconcile ID `6f6ad971-bdb6-4fa3-b803-xxxxxxxxxxxx`. Each reconcile loop will have a unique Reconcile ID.
193193
194194
```
195-
{app="capi-controller-manager"} | json | cluster_name="my-cluster" reconcileID="6f6ad971-bdb6-4fa3-b803-ef81c5c8f9d0" controller="cluster" | line_format "{{ .msg }}"
195+
{app="capi-controller-manager"} | json | Cluster_name="my-cluster" reconcileID="6f6ad971-bdb6-4fa3-b803-ef81c5c8f9d0" controller="cluster" | line_format "{{ .msg }}"
196196
```
197197
Will return logs from the `capi-controller-manager`, associated with the Cluster `my-cluster` and the Reconcile ID `6f6ad971-bdb6-4fa3-b803-xxxxxxxxxxxx` it further selects only those logs which come from the Cluster controller. It will then format the logs so only the message is displayed.
198198
199199
```
200-
{app=~"capd-controller-manager|capi-kubeadm-bootstrap-controller-manager|capi-kubeadm-control-plane-controller-manager"} | json | cluster_name="my-cluster" machine_name="my-cluster-linux-worker-1" | line_format "{{.controller}} {{.msg}}"
200+
{app=~"capd-controller-manager|capi-kubeadm-bootstrap-controller-manager|capi-kubeadm-control-plane-controller-manager"} | json | Cluster_name="my-cluster" Machine_name="my-cluster-linux-worker-1" | line_format "{{.controller}} {{.msg}}"
201201
```
202202
203203
Will return the logs from four CAPI providers - the Core provider, Kubeadm Control Plane provider, Kubeadm Bootstrap provider and the Docker infrastructure provider. It filters by the cluster name and the machine name and then formats the log lines to show just the source controller and the message. This allows us to correlate logs and see actions taken by each of these four providers related to the machine `my-cluster-linux-worker-1`.

test/e2e/common.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/onsi/gomega/types"
2727
corev1 "k8s.io/api/core/v1"
2828
"k8s.io/klog/v2"
29+
"sigs.k8s.io/controller-runtime/pkg/client"
2930

3031
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3132
"sigs.k8s.io/cluster-api/test/framework"
@@ -78,6 +79,14 @@ func dumpSpecResourcesAndCleanup(ctx context.Context, specName string, clusterPr
7879
LogPath: filepath.Join(artifactFolder, "clusters", clusterProxy.GetName(), "resources"),
7980
})
8081

82+
// If the cluster still exists, dump kube-system pods in the workload cluster before deleting the cluster.
83+
if err := clusterProxy.GetClient().Get(ctx, client.ObjectKeyFromObject(cluster), &clusterv1.Cluster{}); err == nil {
84+
framework.DumpKubeSystemPods(ctx, framework.DumpKubeSystemPodsInput{
85+
Lister: clusterProxy.GetWorkloadCluster(ctx, cluster.Namespace, cluster.Name).GetClient(),
86+
LogPath: filepath.Join(artifactFolder, "clusters", cluster.Name, "resources"),
87+
})
88+
}
89+
8190
if !skipCleanup {
8291
Byf("Deleting cluster %s", klog.KObj(cluster))
8392
// While https://github.com/kubernetes-sigs/cluster-api/issues/2955 is addressed in future iterations, there is a chance

test/framework/alltypes_helpers.go

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
. "github.com/onsi/ginkgo/v2"
2828
. "github.com/onsi/gomega"
29+
corev1 "k8s.io/api/core/v1"
2930
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3031
apierrors "k8s.io/apimachinery/pkg/api/errors"
3132
apimeta "k8s.io/apimachinery/pkg/api/meta"
@@ -49,7 +50,7 @@ type GetCAPIResourcesInput struct {
4950
// This list includes all the types belonging to CAPI providers.
5051
func GetCAPIResources(ctx context.Context, input GetCAPIResourcesInput) []*unstructured.Unstructured {
5152
Expect(ctx).NotTo(BeNil(), "ctx is required for GetCAPIResources")
52-
Expect(input.Lister).NotTo(BeNil(), "input.Deleter is required for GetCAPIResources")
53+
Expect(input.Lister).NotTo(BeNil(), "input.Lister is required for GetCAPIResources")
5354
Expect(input.Namespace).NotTo(BeEmpty(), "input.Namespace is required for GetCAPIResources")
5455

5556
types := getClusterAPITypes(ctx, input.Lister)
@@ -76,6 +77,34 @@ func GetCAPIResources(ctx context.Context, input GetCAPIResourcesInput) []*unstr
7677
return objList
7778
}
7879

80+
// GetKubeSystemPodsInput is the input for GetKubeSystemPods.
81+
type GetKubeSystemPodsInput struct {
82+
Lister Lister
83+
}
84+
85+
// GetKubeSystemPods reads all pods in the kube-system namespace.
86+
// Note: This function intentionally retrieves Pods as Unstructured, because we need the Pods
87+
// as Unstructured eventually.
88+
func GetKubeSystemPods(ctx context.Context, input GetKubeSystemPodsInput) []*unstructured.Unstructured {
89+
Expect(ctx).NotTo(BeNil(), "ctx is required for GetKubeSystemPods")
90+
Expect(input.Lister).NotTo(BeNil(), "input.Lister is required for GetKubeSystemPods")
91+
92+
podList := new(unstructured.UnstructuredList)
93+
podList.SetAPIVersion(corev1.SchemeGroupVersion.String())
94+
podList.SetKind("Pod")
95+
if err := input.Lister.List(ctx, podList, client.InNamespace(metav1.NamespaceSystem)); err != nil {
96+
Fail(fmt.Sprintf("failed to list Pods in kube-system: %v", err))
97+
}
98+
99+
objList := []*unstructured.Unstructured{}
100+
for i := range podList.Items {
101+
obj := podList.Items[i]
102+
objList = append(objList, &obj)
103+
}
104+
105+
return objList
106+
}
107+
79108
// getClusterAPITypes returns the list of TypeMeta to be considered for the move discovery phase.
80109
// This list includes all the types belonging to CAPI providers.
81110
func getClusterAPITypes(ctx context.Context, lister Lister) []metav1.TypeMeta {
@@ -115,7 +144,7 @@ type DumpAllResourcesInput struct {
115144
// This dump includes all the types belonging to CAPI providers.
116145
func DumpAllResources(ctx context.Context, input DumpAllResourcesInput) {
117146
Expect(ctx).NotTo(BeNil(), "ctx is required for DumpAllResources")
118-
Expect(input.Lister).NotTo(BeNil(), "input.Deleter is required for DumpAllResources")
147+
Expect(input.Lister).NotTo(BeNil(), "input.Lister is required for DumpAllResources")
119148
Expect(input.Namespace).NotTo(BeEmpty(), "input.Namespace is required for DumpAllResources")
120149

121150
resources := GetCAPIResources(ctx, GetCAPIResourcesInput{
@@ -129,6 +158,27 @@ func DumpAllResources(ctx context.Context, input DumpAllResourcesInput) {
129158
}
130159
}
131160

161+
// DumpKubeSystemPodsInput is the input for DumpKubeSystemPods.
162+
type DumpKubeSystemPodsInput struct {
163+
Lister Lister
164+
LogPath string
165+
}
166+
167+
// DumpKubeSystemPods dumps kube-system Pods to YAML.
168+
func DumpKubeSystemPods(ctx context.Context, input DumpKubeSystemPodsInput) {
169+
Expect(ctx).NotTo(BeNil(), "ctx is required for DumpAllResources")
170+
Expect(input.Lister).NotTo(BeNil(), "input.Lister is required for DumpAllResources")
171+
172+
resources := GetKubeSystemPods(ctx, GetKubeSystemPodsInput{
173+
Lister: input.Lister,
174+
})
175+
176+
for i := range resources {
177+
r := resources[i]
178+
dumpObject(r, input.LogPath)
179+
}
180+
}
181+
132182
func dumpObject(resource runtime.Object, logPath string) {
133183
resourceYAML, err := yaml.Marshal(resource)
134184
Expect(err).ToNot(HaveOccurred(), "Failed to marshal %s", resource.GetObjectKind().GroupVersionKind().String())

0 commit comments

Comments
 (0)