Skip to content

Improve the EKS detector #7502

Open
Open
@bodgit

Description

@bodgit

Description

The current EKS detector has a few shortcomings as referenced in #1856 and #6309 that require it to be configured with some sort of additional permissions before it can work at all.

  1. Access to the kube-system/aws-auth ConfigMap. This is the "am I in/on EKS?" test. It's problematic in that it's granting access to possibly one of the most critical ConfigMaps in the cluster, but also that it is deprecated; AWS are pushing folk to use an alternative method for linking IAM principals to K8S RBAC.
  2. Access to the amazon-cloudwatch/cluster-info ConfigMap. This how the cluster name is discerned. This is only present if you've deployed the Cloudwatch exporter, which isn't mandatory.

There's also a bug in that, possibly since dockershim was removed and containerd is the default container runtime on EKS, the container ID cannot be discerned by just looking at /proc/self/cgroup and/or /proc/self/mountinfo.

The "am I in/on EKS?" test can actually be fixed by directly connecting to the API endpoint and inspecting the TLS certificate; on EKS, there will be an Amazon-specific FQDN listed as one of the Subject Alternative Names, of the form <id>.xxx.<region>.eks.amazonaws.com for an IPv4 cluster, (there are similar patterns for IPv6 clusters and those in the GovCloud and China regions). This also gives you the AWS region for free as it's part of the FQDN.

To work out the cluster name, there is no way to do this (AFAIK) without granting some sort of additional permissions. The simplest way I can see is to run the Pod using an AWS principal that grants eks:ListClusters. If you have only one EKS cluster in your AWS account then that is your cluster. If you have multiple EKS clusters in the same AWS account, then additionally granting eks:DescribeCluster specifically on the one necessary cluster is also required; the endpoint of the matching cluster will have the same FQDN that you extracted from the certificate above. By doing this, you also get access to the AWS account ID extracted either from the eks:DescribeCluster output or the IAM principal you're authenticated to AWS as.

This could also be worked out by allowing the Pod to describe itself using the K8S API, find the Node it's running on, then describe that Node, which might have a label on it with the cluster name, (eksctl-managed cluster nodes often have this), or using the Node details to then try and find the underlying EC2 instance using ec2:DescribeInstances and looking at the tags for a well known tag that provides the cluster name.

I've seen proposals that rely on direct access to the EC2 instance metadata however it is considered best practices to block access to this from Pods as it gives the Pod access to whatever IAM policies are assigned to the Node.

For discerning the container ID, there doesn't seem to be a way now from within a Pod. You can get the ID by describing the Pod using the K8S API, the ID is shown there. I've also found it might be possible to write an NRI plugin for containerd that automatically modifies a container at creation time with the ID added as either an environment variable, or possibly even an additional volume mount with a file containing the ID. It would then be a case of extending the detector to look for this addition in some well-defined location(s).

I have a detector written that uses the above approach for finding everything, (apart from the container ID), which I'd be happy to contribute, maybe as a v2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions