Comment puis-je récupérer les journaux du plan de contrôle Amazon EKS à partir d'Amazon CloudWatch Logs ?

Date de la dernière mise à jour : 12/11/2021

Je dépanne un problème lié à Amazon Elastic Kubernetes Service (Amazon EKS) et je dois collecter les journaux des composants qui s'exécutent sur le plan de contrôle EKS.

Brève description

Pour afficher les journaux dans Amazon CloudWatch Logs, vous devez activer la journalisation du plan de contrôle Amazon EKS. Vous trouverez les journaux du plan de contrôle EKS dans le groupe de journaux /aws/eks/nom-cluster/cluster. Pour plus d'informations, consultez la section Affichage des journaux du plan de contrôle du cluster.

Remarque : Remplacez cluster name par le nom de votre cluster.

Vous pouvez utiliser CloudWatch Logs Insights pour effectuer des recherches dans les données de journal du plan de contrôle EKS. Pour plus d'informations, consultez la section Analyse des données de journaux avec CloudWatch Insights.

Important : Vous pouvez afficher les événements de journaux dans CloudWatch Logs uniquement après avoir activé la journalisation du plan de contrôle dans un cluster. Avant de sélectionner une plage de temps pour exécuter des requêtes dans CloudWatch Logs Insights, vérifiez que vous avez activé la journalisation du plan de contrôle.

Résolution

Rechercher dans CloudWatch Insights

1.    Ouvrez la console CloudWatch Logs Insights.

2.    Dans le menu Groupe(s) de journaux, sélectionnez le groupe de journaux de cluster que vous souhaitez interroger.

3.    Choisissez Exécuter la requête pour afficher les résultats.

Remarque : Pour exporter les résultats sous forme de fichier .csv ou copier les résultats dans le presse-papiers, choisissez Exporter les résultats. Vous pouvez modifier l'exemple de requête pour obtenir des données pour un cas d'utilisation spécifique. Consultez les exemples de requêtes suivants pour les cas d'utilisation EKS courants.

Exemples de requêtes pour les cas d'utilisation EKS courants

Pour trouver le créateur du cluster, recherchez l'entité IAM mappée à l'utilisateur kubernetes-admin.

Requête :

fields @logStream, @timestamp, @message
| sort @timestamp desc
| filter @logStream like /authenticator/
| filter @message like "username=kubernetes-admin"
| limit 50

Exemple de sortie :

@logStream, @timestamp @message
authenticator-71976 ca11bea5d3083393f7d32dab75b,2021-08-11-10:09:49.020,"time=""2021-08-11T10:09:43Z"" level=info msg=""access granted"" arn=""arn:aws:iam::12345678910:user/awscli"" client=""127.0.0.1:51326"" groups=""[system:masters]"" method=POST path=/authenticate sts=sts.eu-west-1.amazonaws.com uid=""heptio-authenticator-aws:12345678910:ABCDEFGHIJKLMNOP"" username=kubernetes-admin"

Dans la sortie précédente, l'utilisateur IAM arn:aws:iam::12345678910:user/awscli est mappé à l'utilisateur kubernetes-admin.

Pour rechercher les requêtes effectuées par un utilisateur spécifique, recherchez les opérations effectuées par l'utilisateur kubernetes-admin.

Exemple de requête :

fields @logStream, @timestamp, @message
| filter @logStream like /^kube-apiserver-audit/
| filter strcontains(user.username,"kubernetes-admin")
| sort @timestamp desc
| limit 50

Exemple de sortie :

@logStream,@timestamp,@message
kube-apiserver-audit-71976ca11bea5d3083393f7d32dab75b,2021-08-11 09:29:13.095,"{...""requestURI"":""/api/v1/namespaces/kube-system/endpoints?limit=500";","string""verb"":""list"",""user"":{""username"":""kubernetes-admin"",""uid"":""heptio-authenticator-aws:12345678910:ABCDEFGHIJKLMNOP"",""groups"":[""system:masters"",""system:authenticated""],""extra"":{""accessKeyId"":[""ABCDEFGHIJKLMNOP""],""arn"":[""arn:aws:iam::12345678910:user/awscli""],""canonicalArn"":[""arn:aws:iam::12345678910:user/awscli""],""sessionName"":[""""]}},""sourceIPs"":[""12.34.56.78""],""userAgent"":""kubectl/v1.22.0 (darwin/amd64) kubernetes/c2b5237"",""objectRef"":{""resource"":""endpoints"",""namespace"":""kube-system"",""apiVersion"":""v1""}...}"

Pour rechercher les appels d'API effectués par un userAgent spécifique, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, userAgent, verb, requestURI, @message
| filter @logStream like /kube-apiserver-audit/
| filter userAgent like /kubectl\/v1.22.0/
| sort @timestamp desc
| filter verb like /(get)/

Exemple de sortie raccourcie :

@logStream,@timestamp,userAgent,verb,requestURI,@message
kube-apiserver-audit-71976ca11bea5d3083393f7d32dab75b,2021-08-11 14:06:47.068,kubectl/v1.22.0 (darwin/amd64) kubernetes/c2b5237,get,/apis/metrics.k8s.io/v1beta1?timeout=32s,"{""kind"":""Event"",""apiVersion"":""audit.k8s.io/v1"",""level"":""Metadata"",""auditID"":""863d9353-61a2-4255-a243-afaeb9183524"",""stage"":""ResponseComplete"",""requestURI"":""/apis/metrics.k8s.io/v1beta1?timeout=32s"",""verb"":""get"",""user"":{""username"":""kubernetes-admin"",""uid"":""heptio-authenticator-aws:12345678910:AIDAUQGC5HFOHXON7M22F"",""groups"":[""system:masters"",""system:authenticated""],""extra"":{""accessKeyId"":[""ABCDEFGHIJKLMNOP""],""arn"":[""arn:aws:iam::12345678910:user/awscli""],""canonicalArn"":[""arn:aws:iam::12345678910:user/awscli""],""sourceIPs"":[""12.34.56.78""],""userAgent"":""kubectl/v1.22.0 (darwin/amd64) kubernetes/c2b5237""...}"

Pour rechercher les modifications mutantes apportées au ConfigMap aws-auth, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, @message
| filter @logStream like /^kube-apiserver-audit/
| filter requestURI like /\/api\/v1\/namespaces\/kube-system\/configmaps/
| filter objectRef.name = "aws-auth"
| filter verb like /(create|delete|patch)/
| sort @timestamp desc
| limit 50

Exemple de sortie raccourcie :

@logStream,@timestamp,@message
kube-apiserver-audit-f01c77ed8078a670a2eb63af6f127163,2021-10-27 05:43:01.850,{""kind"":""Event"",""apiVersion"":""audit.k8s.io/v1"",""level"":""RequestResponse"",""auditID"":""8f9a5a16-f115-4bb8-912f-ee2b1d737ff1"",""stage"":""ResponseComplete"",""requestURI"":""/api/v1/namespaces/kube-system/configmaps/aws-auth?timeout=19s"",""verb"":""patch"",""responseStatus"": {""metadata"": {},""code"": 200 },""requestObject"": {""data"": { contents of aws-auth ConfigMap } },""requestReceivedTimestamp"":""2021-10-27T05:43:01.033516Z"",""stageTimestamp"":""2021-10-27T05:43:01.042364Z"" }

Pour rechercher les demandes qui ont été refusées, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, @message
| filter @logStream like /^authenticator/
| filter @message like "denied"
| sort @timestamp desc
| limit 50

Exemple de sortie :

@logStream,@timestamp,@message
authenticator-8c0c570ea5676c62c44d98da6189a02b,2021-08-08 20:04:46.282,"time=""2021-08-08T20:04:44Z"" level=warning msg=""access denied"" client=""127.0.0.1:52856"" error=""sts getCallerIdentity failed: error from AWS (expected 200, got 403)"" method=POST path=/authenticate"

Pour trouver le nœud sur lequel un pod a été planifié, interrogez les journaux de kube-scheduler.

Exemple de requête :

fields @logStream, @timestamp, @message
| sort @timestamp desc
| filter @logStream like /kube-scheduler/
| filter @message like "aws-6799fc88d8-jqc2r"
| limit 50

Exemple de sortie :

@logStream,@timestamp,@message
kube-scheduler-bb3ea89d63fd2b9735ba06b144377db6,2021-08-15 12:19:43.000,"I0915 12:19:43.933124       1 scheduler.go:604] ""Successfully bound pod to node"" pod=""kube-system/aws-6799fc88d8-jqc2r"" node=""ip-192-168-66-187.eu-west-1.compute.internal"" evaluatedNodes=3 feasibleNodes=2"

Dans l'exemple de sortie précédent, le pod aws-6799fc88d8-jqc2r a été planifié sur le nœud ip-192-168-66-187.eu-west-1.compute.internal.

Pour rechercher les erreurs de serveur HTTP 5xx pour les requêtes au serveur de l'API Kubernetes, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, responseStatus.code, @message
| filter @logStream like /^kube-apiserver-audit/
| filter responseStatus.code >= 500
| limit 50

Exemple de sortie raccourcie :

@logStream,@timestamp,responseStatus.code,@message
kube-apiserver-audit-4d5145b53c40d10c276ad08fa36d1f11,2021-08-04 07:22:06.518,503,"...""requestURI"":""/apis/metrics.k8s.io/v1beta1?timeout=32s"",""verb"":""get"",""user"":{""username"":""system:serviceaccount:kube-system:resourcequota-controller"",""uid"":""36d9c3dd-f1fd-4cae-9266-900d64d6a754"",""groups"":[""system:serviceaccounts"",""system:serviceaccounts:kube-system"",""system:authenticated""]},""sourceIPs"":[""12.34.56.78""],""userAgent"":""kube-controller-manager/v1.21.2 (linux/amd64) kubernetes/d2965f0/system:serviceaccount:kube-system:resourcequota-controller"",""responseStatus"":{""metadata"":{},""code"":503},..."}}"

Pour résoudre les problèmes d'activation d'une tâche CronJob, recherchez les appels d'API effectués par le cronjob-controller.

Exemple de requête :

fields @logStream, @timestamp, @message
| filter @logStream like /kube-apiserver-audit/
| filter user.username like "system:serviceaccount:kube-system:cronjob-controller"
| display @logStream, @timestamp, @message, objectRef.namespace, objectRef.name
| sort @timestamp desc
| limit 50

Exemple de sortie raccourcie :

{ "kind": "Event", "apiVersion": "audit.k8s.io/v1", "objectRef": { "resource": "cronjobs", "namespace": "default", "name": "hello", "apiGroup": "batch", "apiVersion": "v1" }, "responseObject": { "kind": "CronJob", "apiVersion": "batch/v1", "spec": { "schedule": "*/1 * * * *" }, "status": { "lastScheduleTime": "2021-08-09T07:19:00Z" } } }

Dans l'exemple de sortie précédent, la tâche hello dans l'espace de noms default s'exécute toutes les minutes et a été planifiée pour la dernière fois à 2021-08-09T07:19:00Z.

Pour rechercher les appels d'API effectués par le replicaset-controller, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, @message
| filter @logStream like /kube-apiserver-audit/
| filter user.username like "system:serviceaccount:kube-system:replicaset-controller"
| display @logStream, @timestamp, requestURI, verb, user.username
| sort @timestamp desc
| limit 50

Exemple de sortie :

@logStream,@timestamp,requestURI,verb,user.username
kube-apiserver-audit-8c0c570ea5676c62c44d98da6189a02b,2021-08-10 17:13:53.281,/api/v1/namespaces/kube-system/pods,create,system:serviceaccount:kube-system:replicaset-controller
kube-apiserver-audit-4d5145b53c40d10c276ad08fa36d1f11,2021-08-04 0718:44.561,/apis/apps/v1/namespaces/kube-system/replicasets/coredns-6496b6c8b9/status,update,system:serviceaccount:kube-system:replicaset-controller

Pour rechercher les opérations effectuées sur une ressource Kubernetes, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, @message
| filter @logStream like /^kube-apiserver-audit/
| filter verb == "delete" and requestURI like "/api/v1/namespaces/default/pods/my-app"
| sort @timestamp desc
| limit 10

L'exemple précédent de requête filtre les appels d'API delete sur l'espace de noms default pour le pod my-app.

Exemple de sortie raccourcie :

@logStream,@timestamp,@message
kube-apiserver-audit-e7b3cb08c0296daf439493a6fc9aff8c,2021-08-11 14:09:47.813,"...""requestURI"":""/api/v1/namespaces/default/pods/my-app"",""verb"":""delete"",""user"":{""username""""kubernetes-admin"",""uid"":""heptio-authenticator-aws:12345678910:ABCDEFGHIJKLMNOP"",""groups"":[""system:masters"",""system:authenticated""],""extra"":{""accessKeyId"":[""ABCDEFGHIJKLMNOP""],""arn"":[""arn:aws:iam::12345678910:user/awscli""],""canonicalArn"":[""arn:aws:iam::12345678910:user/awscli""],""sessionName"":[""""]}},""sourceIPs"":[""12.34.56.78""],""userAgent"":""kubectl/v1.22.0 (darwin/amd64) kubernetes/c2b5237"",""objectRef"":{""resource"":""pods"",""namespace"":""default"",""name"":""my-app"",""apiVersion"":""v1""},""responseStatus"":{""metadata"":{},""code"":200},""requestObject"":{""kind"":""DeleteOptions"",""apiVersion"":""v1"",""propagationPolicy"":""Background""},
..."

Pour récupérer un nombre de codes de réponse HTTP pour les appels effectués vers le serveur de l'API Kubernetes, vous pouvez utiliser l'exemple de requête suivant :

fields @logStream, @timestamp, @message
| filter @logStream like /^kube-apiserver-audit/
| stats count(*) as count by responseStatus.code
| sort count desc

Exemple de sortie :

responseStatus.code,count
200,35066
201,525
403,125
404,116
101,2

Pour rechercher les modifications apportées aux DaemonSets/Addons dans l'espace de noms kube-system, vous pouvez utiliser l'exemple de requête suivant :

filter @logStream like /^kube-apiserver-audit/
| fields @logStream, @timestamp, @message
| filter verb like /(create|update|delete)/ and strcontains(requestURI,"/apis/apps/v1/namespaces/kube-system/daemonsets")
| sort @timestamp desc
| limit 50

Exemple de sortie :

{ "kind": "Event", "apiVersion": "audit.k8s.io/v1", "level": "RequestResponse", "auditID": "93e24148-0aa6-4166-8086-a689b0031612", "stage": "ResponseComplete", "requestURI": "/apis/apps/v1/namespaces/kube-system/daemonsets/aws-node?fieldManager=kubectl-set", "verb": "patch", "user": { "username": "kubernetes-admin", "groups": [ "system:masters", "system:authenticated" ] }, "userAgent": "kubectl/v1.22.2 (darwin/amd64) kubernetes/8b5a191", "objectRef": { "resource": "daemonsets", "namespace": "kube-system", "name": "aws-node", "apiGroup": "apps", "apiVersion": "v1" }, "requestObject": { "REDACTED": "REDACTED" }, "requestReceivedTimestamp": "2021-08-09T08:07:21.868376Z", "stageTimestamp": "2021-08-09T08:07:21.883489Z", "annotations": { "authorization.k8s.io/decision": "allow", "authorization.k8s.io/reason": "" } }

Dans l'exemple de sortie précédent, l'utilisateur kubernetes-admin a utilisé kubectl v1.22.2 pour corriger le DaemonSet aws-node.


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?