Como posso recuperar os logs do ambiente de gerenciamento do Amazon EKS no Amazon CloudWatch Logs?

Última atualização em: 2021-11-12

Estou solucionando um problema com o Amazon Elastic Kubernetes Service (Amazon EKS) e preciso coletar logs dos componentes que são executados no ambiente de gerenciamento do EKS.

Breve descrição

Para visualizar os logs no Amazon CloudWatch Logs, você deve habilitar o registro em log do ambiente de gerenciamento do Amazon EKS. Você pode encontrar os logs do ambiente de gerenciamento do EKS no grupo de logs /aws/eks/cluster-name/cluster. Para obter mais informações, consulte Visualizar logs do ambiente de gerenciamento do cluster.

Observação: substitua nome do cluster pelo nome do seu cluster.

Você pode usar o CloudWatch Logs Insights para pesquisar os dados de log do ambiente de gerenciamento do EKS. Para obter mais informações, consulte Analisar dados de log com o CloudWatch Insights.

Importante: apenas será possível visualizar eventos de log no CloudWatch Logs depois que você habilitar o registro em log do ambiente de gerenciamento em um cluster. Antes de selecionar um intervalo de tempo para executar consultas no CloudWatch Logs Insights, verifique se você habilitou o registro em log do ambiente de gerenciamento.

Resolução

Pesquisar o CloudWatch Insights

1.    Abra o console do CloudWatch Logs Insights.

2.    No menu de grupo(s) de log, selecione o grupo de logs do cluster que você deseja consultar.

3.    Escolha Run query (Executar consulta) para ver os resultados.

Observação: para exportar os resultados como um arquivo .csv ou copiar os resultados para a área de transferência, escolha Export results (Exportar resultados). Você pode alterar a consulta de amostra para obter dados de um caso de uso específico. Veja os seguintes exemplos de consultas para casos de uso comuns do EKS.

Exemplos de consultas para casos de uso comuns do EKS

Para encontrar o criador do cluster, procure a entidade do IAM mapeada para o usuário kubernetes-admin.

Consulta:

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

Saída de exemplo:

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

Na saída anterior, o usuário do IAM arn:aws:iam::12345678910:user/awscli é mapeado para o usuário kubernetes-admin.

Para encontrar solicitações que um usuário específico realizou, procure as operações que o usuário kubernetes-admin.

Consulta de exemplo:

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

Saída de exemplo:

@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 chamadas de API feitas por um userAgent específico, você pode usar a seguinte consulta de exemplo:

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

Saída de exemplo 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 encontrar alterações mutantes feitas no ConfigMap aws-auth, você pode usar a seguinte consulta de exemplo:

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

Saída de exemplo 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 localizar solicitações que foram negadas, você pode usar a seguinte consulta de exemplo:

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

Saída de exemplo:

@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 o nó no qual um pod foi agendado, consulte os logs de kube-scheduler.

Consulta de exemplo:

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

Saída de exemplo:

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

No exemplo de saída anterior, o pod aws-6799fc88d8-jqc2r foi agendado no nó ip-192-168-66-187.eu-west-1.compute.internal.

Para encontrar erros de servidor HTTP 5xx para solicitações de servidor da API Kubernetes, use a seguinte consulta de exemplo:

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

Saída de exemplo 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 uma ativação de CronJob, procure chamadas de API feitas por cronjob-controller.

Consulta de exemplo:

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

Saída de exemplo 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" } } }

No exemplo de saída anterior, o trabalho hello no namespace default é executado a cada minuto e foi agendado pela última vez em 2021-08-09T07:19:00Z.

Para localizar chamadas de API feitas por replicaset-controller, você pode usar o seguinte exemplo de consulta:

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

Saída de exemplo:

@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 localizar operações feitas em um recurso do Kubernetes, você pode usar a seguinte consulta de exemplo:

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

O exemplo anterior de filtros de consulta para chamadas de API delete no namespace default do pod my-app.

Saída de exemplo 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 uma contagem de códigos de resposta HTTP para chamadas feitas ao servidor de APIs do Kubernetes, você pode usar a seguinte consulta de exemplo:

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

Saída de exemplo:

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

Para localizar alterações feitas em DaemonSets/addons no namespace kube-system, você pode usar a seguinte consulta de exemplo:

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

Saída de exemplo:

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

No exemplo de saída anterior, o usuário kubernetes-admin usou kubectl v1.22.2 para corrigir o DaemonSet aws-node.


Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?