¿Cómo puedo recuperar los registros del plano de control de Amazon EKS de Amazon CloudWatch Logs?

Última actualización: 12-11-2021

Estoy solucionando un problema de Amazon Elastic Kubernetes Service (Amazon EKS) y necesito recopilar registros de los componentes que se ejecutan en el plano de control de EKS.

Descripción corta

Para ver los registros en Amazon CloudWatch Logs, debe habilitar el registro del plano de control de Amazon EKS. Puede encontrar los registros del plano de control de EKS en el grupo de registros /aws/eks/cluster-name/cluster. Para obtener más información, consulte Visualización de registros del plano de control del clúster.

Nota: Sustituya cluster_name por el nombre de su clúster.

Puede usar CloudWatch Logs Insights para buscar en los datos de registro del plano de control de EKS. Para obtener más información, consulte Análisis de datos de registro con CloudWatch Insights.

Importante: Puede ver los eventos de registro en CloudWatch Logs solo después de habilitar el registro del plano de control en un clúster. Antes de seleccionar un intervalo de tiempo para ejecutar consultas en CloudWatch Logs Insights, compruebe que habilitó el registro del plano de control.

Resolución

Buscar en CloudWatch Insights

1.    Abra la consola de CloudWatch Logs Insights.

2.    En el menú de grupos de registros, seleccione el grupo de registros del clúster que desea consultar.

3.    Elija Run query (Ejecutar consulta) para ver los resultados.

Nota: Para exportar los resultados como un archivo.csv o copiar los resultados en el portapapeles, elija Export results (Exportar resultados). Puede cambiar la consulta de muestra para obtener datos de un caso de uso específico. Consulte las siguientes consultas de ejemplo para casos de uso comunes de EKS.

Consultas de ejemplo para casos de uso comunes de EKS

Para encontrar el creador del clúster, busque la entidad de IAM asignada al usuario kubernetes-admin.

Consulta:

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

Salida de ejemplo:

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

En la salida anterior, el usuario de IAM arn:aws:iam::12345678910:user/awscli se asigna al usuario kubernetes-admin.

Para encontrar las solicitudes que realizó un usuario específico, busque las operaciones que realizó el usuario kubernetes-admin.

Consulta de ejemplo:

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

Salida de ejemplo:

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

Para encontrar las llamadas a la API que realizó un userAgent específico, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo abreviada:

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

Para buscar los cambios mutantes realizados en aws-auth ConfigMap, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo abreviada:

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

Para buscar solicitudes que se denegaron, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo:

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

Para encontrar el nodo en el que se programó un pod, consulte los registros de kube-scheduler.

Consulta de ejemplo:

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

Salida de ejemplo:

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

En el ejemplo anterior, el pod aws-6799fc88d8-jqc2r se programó en el nodo ip-192-168-66-187.eu-west-1.compute.internal.

Para encontrar errores del servidor HTTP 5xx para las solicitudes del servidor de la API de Kubernetes, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo abreviada:

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

Para solucionar problemas de activación de CronJob, busque las llamadas a la API que realizó el controlador cronjob-controller.

Consulta de ejemplo:

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

Salida de ejemplo abreviada:

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

En la salida del ejemplo anterior, el trabajo hello en el espacio de nombres predeterminado se ejecuta cada minuto y se programó por última vez el 2021-09-08T 07:19:00 Z.

Para encontrar las llamadas a la API que realizó replicaset-controller, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo:

@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

Para buscar operaciones que se realicen en un recurso de Kubernetes, puede usar la siguiente consulta de ejemplo:

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

En el ejemplo anterior, se filtra la consulta para eliminar llamadas a la API en el espacio de nombres predeterminado para el pod my-app.

Salida de ejemplo abreviada:

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

Para recuperar un recuento de códigos de respuesta HTTP para las llamadas realizadas al servidor de la API de Kubernetes, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo:

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

Para encontrar los cambios que se realizan en daemonsets/addons en el espacio de nombres kube-system, puede usar la siguiente consulta de ejemplo:

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

Salida de ejemplo:

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

En el resultado del ejemplo anterior, el usuario kubernetes-admin usó kubectl v1.22.2 para aplicar parches al DaemonSet aws-node.


¿Le resultó útil este artículo?


¿Necesita asistencia técnica o con la facturación?