Wie kann ich Protokolle der Amazon-EKS-Steuerebene von CloudWatch Logs abrufen?

Lesedauer: 6 Minute
0

Ich behebe ein Problem mit dem Amazon Elastic Kubernetes Service (Amazon EKS) und muss Protokolle von den Komponenten sammeln, die auf der EKS-Steuerebene ausgeführt werden.

Kurzbeschreibung

Um die Protokolle in Amazon CloudWatch Logs anzuzeigen, müssen Sie die Protokollierung der Amazon-EKS-Steuerebene aktivieren. Die Protokolle der EKS-Steuerebene finden Sie in der Protokollgruppe /aws/eks/cluster-name/cluster. Weitere Informationen finden Sie unter Protokolle der Cluster-Steuerebene anzeigen.

Hinweis: Ersetzen Sie cluster_name durch Ihren Clusternamen.

Sie können CloudWatch Logs Insights verwenden, um die Protokolldaten der EKS-Steuerebene zu durchsuchen. Weitere Informationen finden Sie unter Analysieren von Protokolldaten mit CloudWatch Insights.

Wichtig: Sie können Protokollereignisse in CloudWatch Logs erst anzeigen, nachdem Sie die Protokollierung der Steuerebene in einem Cluster aktiviert haben. Bevor Sie einen Zeitraum für die Ausführung von Abfragen in CloudWatch Logs Insights auswählen, stellen Sie sicher, dass Sie die Protokollierung der Steuerebene aktiviert haben.

Auflösung

Durchsuchen von CloudWatch Insights

  1. Öffnen Sie die CloudWatch-Konsole.
  2. Wählen Sie im Navigationsbereich Logs und dann Log Insights aus.
  3. Wählen Sie im Menü log group(s) (Protokollgruppe(n)) auswählen die Cluster-Protokollgruppe aus, die Sie abfragen möchten.
  4. Wählen Sie Run (Ausführen), um die Ergebnisse anzuzeigen.

Hinweis: Um die Ergebnisse als CSV-Datei zu exportieren oder die Ergebnisse in die Zwischenablage zu kopieren, wählen Sie Export results (Ergebnisse exportieren). Sie können die Beispielabfrage ändern, um Daten für einen bestimmten Anwendungsfall abzurufen. Siehe diese Beispielabfragen für gängige EKS-Anwendungsfälle.

Beispielabfragen für gängige EKS-Anwendungsfälle

Um den Cluster-Ersteller zu finden, suchen Sie nach der IAM-Entität, die dem kubernetes-admin-Benutzer zugeordnet ist.

Abfrage:

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

Beispielausgabe:

@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"

In dieser Ausgabe wird der IAM-Benutzer arn:aws:iam: :12345678910: user/awscli dem Benutzer kubernetes-admin zugeordnet.

Um Anfragen zu finden, die ein bestimmter Benutzer ausgeführt hat, suchen Sie nach Vorgängen, die der kubernetes-admin-Benutzer ausgeführt hat.

Beispielabfrage:

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

Beispielausgabe:

@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""}...}"

Um API-Aufrufe zu finden, die ein bestimmter UserAgent ausgeführt hat, können Sie diese Beispielabfrage verwenden:

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)/

Verkürzte Beispielausgabe:

@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""...}"

Um mutierende Änderungen an der aws-auth ConfigMap zu finden, können Sie diese Beispielabfrage verwenden:

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

Verkürzte Beispielausgabe:

@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"" }

Um Anfragen zu finden, die abgelehnt wurden, können Sie diese Beispielabfrage verwenden:

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

Beispielausgabe:

@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"

Um den Knoten zu finden, auf dem ein Pod geplant war, fragen Sie die kube-Scheduler-Protokolle ab.

Beispielabfrage:

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

Beispielausgabe:

@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"

In dieser Beispielausgabe wurde Pod aws-6799fc88d8-jqc2r auf dem Knoten ip-192-168-66-187.eu-west-1.compute.internal geplant.

Um HTTP-5xx-Serverfehler für Kubernetes-API-Serveranforderungen zu finden, können Sie diese Beispielabfrage verwenden:

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

Verkürzte Beispielausgabe:

@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},..."}}"

Um eine CronJob-Aktivierung zu beheben, suchen Sie nach API-Aufrufen, die der cronjob-Controller getätigt hat.

Beispielabfrage:

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

Verkürzte Beispielausgabe:

{ "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" } } }

In dieser Beispielausgabe wird der Hello-Auftrag im Standard-Namespace jede Minute ausgeführt und wurde zuletzt um 2021-08-09T07:19:00Z geplant.

Um API-Aufrufe zu finden, die der replicaset-Controller ausgeführt hat, können Sie diese Beispielabfrage verwenden:

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

Beispielausgabe:

@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

Um Vorgänge zu finden, die mit einer Kubernetes-Ressource ausgeführt werden, können Sie diese Beispielabfrage verwenden:

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

Die vorangegangene Beispielanfrage filtert delete-API-Aufrufe im Standard-Namespace für Pod my-App.

Verkürzte Beispielausgabe:

@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""},
..."

Um eine Anzahl von HTTP-Antwortcodes für Aufrufe an den Kubernetes-API-Server abzurufen, können Sie diese Beispielabfrage verwenden:

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

Beispielausgabe:

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

Um Änderungen zu finden, die an DaemonSets/Addons im kube-system-Namespace vorgenommen werden, können Sie diese Beispielabfrage verwenden:

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

Beispielausgabe:

{ "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": "" } }

In dieser Beispielausgabe verwendete der kubernetes-admin-Benutzer kubectl v1.22.2, um das aws-node-DaemonSet zu patchen.

Um den Benutzer zu finden, der einen Knoten gelöscht hat, können Sie diese Beispielabfrage verwenden:

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

Verkürzte Beispielausgabe:

@logStream,@timestamp,@message
kube-apiserver-audit-e503271cd443efdbd2050ae8ca0794eb,2022-03-25 07:26:55.661,"{"kind":"Event","verb":"delete","user":{"username":"kubernetes-admin","groups":["system:masters","system:authenticated"],"arn":["arn:aws:iam::1234567890:user/awscli"],"canonicalArn":["arn:aws:iam::1234567890:user/awscli"],"sessionName":[""]}},"sourceIPs":["1.2.3.4"],"userAgent":"kubectl/v1.21.5 (darwin/amd64) kubernetes/c285e78","objectRef":{"resource":"nodes","name":"ip-192-168-37-22.eu-west-1.compute.internal","apiVersion":"v1"},"responseStatus":{"metadata":{},"status":"Success","code":200},"requestObject":{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"},"responseObject":{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Success","details":{"name":"ip-192-168-37-22.eu-west-1.compute.internal","kind":"nodes","uid":"518ba070-154e-4400-883a-77a44a075bd0"}},"requestReceivedTimestamp":"2022-03-25T07:26:55.355378Z",}}"

AWS OFFICIAL
AWS OFFICIALAktualisiert vor einem Jahr