외부 OIDC 공급자로 사용자에게 Kubernetes 액세스 권한 부여
외부 OIDC 공급자로 사용자에게 Kubernetes 액세스 권한 부여
OpenID Connect(OIDC) ID 공급자를 사용해 사용자를 Amazon EKS 클러스터에 인증하는 방법을 설명합니다.
출처: 문서
본문
Amazon EKS는 사용자를 클러스터에 인증하는 방법으로 OpenID Connect(OIDC) ID 공급자 사용을 지원합니다. OIDC ID 공급자는 AWS Identity and Access Management(IAM)와 함께 사용하거나 대신 사용할 수 있습니다. IAM 사용에 대한 자세한 내용은 "IAM 사용자 및 역할에게 Kubernetes API 액세스 권한 부여"를 참고하세요. 클러스터에 대한 인증을 구성한 후에는 Kubernetes roles와 clusterroles를 생성해 역할에 권한을 할당하고, Kubernetes rolebindings와 clusterrolebindings로 역할을 ID에 바인딩할 수 있습니다. 자세한 내용은 Kubernetes 문서의 "RBAC 인증 사용"을 참고하세요.
Kubernetes는 OIDC ID 공급자를 제공하지 않습니다. 기존의 공개 OIDC ID 공급자를 사용하거나 자체 ID 공급자를 실행할 수 있습니다. 인증된 공급자 목록은 OpenID 사이트의 "OpenID Certification"을 참고하세요.
OIDC ID 공급자의 발급자 URL(issuer URL)은 Amazon EKS가 서명 키를 검색할 수 있도록 공개적으로 액세스 가능해야 합니다. Amazon EKS는 자체 서명 인증서를 사용하는 OIDC ID 공급자를 지원하지 않습니다.
클러스터에 노드를 가입시키는 데 여전히 IAM 인증이 필요하므로, 클러스터에 대한 IAM 인증을 비활성화할 수 없습니다.
Amazon EKS 클러스터는 OIDC ID 공급자 사용자가 아닌 AWS IAM 보안 주체가 여전히 생성해야 합니다. 그 이유는 클러스터 생성자가 Kubernetes API가 아닌 Amazon EKS API와 상호작용하기 때문입니다.
OIDC ID 공급자로 인증된 사용자는 컨트롤 플레인에서 CloudWatch 로그가 켜져 있으면 클러스터의 감사 로그에 나열됩니다. 자세한 내용은 "컨트롤 플레인 로그 활성화 또는 비활성화"를 참고하세요.
OIDC 공급자의 계정으로 AWS Management Console에 로그인할 수 없습니다. AWS Identity and Access Management 계정으로 AWS Management Console에 로그인해야만 AWS Management Console에서 Kubernetes 리소스를 볼 수 있습니다.
클러스터에 연결할 수 있는 OIDC ID 공급자의 수는 클러스터의 Kubernetes 버전에 따라 다릅니다. Kubernetes 버전 1.32 이상을 실행하는 클러스터에서는 최대 10개의 OIDC ID 공급자를 연결할 수 있습니다. 모든 OIDC 공급자 구성의 총 크기는 12KB 미만이어야 합니다. 1.32보다 이전 버전을 실행하는 클러스터에서는 OIDC ID 공급자를 하나만 연결할 수 있습니다.
발급자 URL(issuerUrl)과 이름(name)은 클러스터에 연결된 모든 OIDC ID 공급자에서 고유해야 합니다. 동일한 공급자를 두 번 이상 연결할 수 없습니다.
OIDC ID 공급자 연결은 클러스터 업데이트입니다. 클러스터는 UPDATING 상태가 되며, 변경 사항이 클러스터의 API 서버에 완전히 적용되는 데 몇 분이 걸릴 수 있습니다. 업데이트 진행 상황은 DescribeUpdate 작업으로 추적할 수 있습니다.
참고: 컨트롤 플레인은 발급자 URL에서 공급자의 서명 키를 가져오므로, 발급자는 컨트롤 플레인에서 도달 가능해야 합니다. 클러스터가 고객 라우팅 컨트롤 플레인 이그레스(
controlPlaneEgressMode=CUSTOMER_ROUTED)를 사용한다면, VPC에 구성한 이그레스 경로를 통해 발급자 엔드포인트에 도달할 수 있는지 확인하세요. 자세한 내용은 "컨트롤 플레인 이그레스 라우팅 구성"을 참고하세요.
OIDC ID 공급자 연결
OIDC ID 공급자를 클러스터에 연결하려면 먼저 공급자에서 다음 정보가 필요합니다.
- 발급자 URL - API 서버가 토큰 검증을 위한 공개 서명 키를 검색할 수 있게 해주는 OIDC ID 공급자의 URL. URL은
https://로 시작해야 하며, 공급자의 OIDC ID 토큰에 있는iss클레임과 일치해야 합니다. OIDC 표준에 따라 경로 구성 요소는 허용되지만 쿼리 매개변수는 허용되지 않습니다. 일반적으로 URL은https://server.example.org나https://example.com같은 호스트 이름만으로 구성됩니다. 이 URL은.well-known/openid-configuration아래의 레벨을 가리켜야 하며 인터넷을 통해 공개적으로 액세스 가능해야 합니다. 발급자 URL은 클러스터에 연결된 모든 OIDC ID 공급자에서 고유해야 합니다. - 클라이언트 ID(오디언스라고도 함) - OIDC ID 공급자에 인증 요청을 하는 클라이언트 애플리케이션의 ID.
eksctl 또는 AWS Management Console을 사용해 ID 공급자를 연결할 수 있습니다.
eksctl을 사용해 ID 공급자 연결
associate-identity-provider.yaml이라는 파일을 다음 내용으로 생성합니다. 예제 값을 자신의 값으로 바꾸세요. identityProviders 섹션의 값은 OIDC ID 공급자에서 가져옵니다. identityProviders 아래의 name, type, issuerUrl, clientId 설정에만 값이 필요합니다.
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: my-cluster
region: your-region-code
identityProviders:
- name: my-provider
type: oidc
issuerUrl: https://example.com
clientId: kubernetes
usernameClaim: email
usernamePrefix: my-username-prefix
groupsClaim: my-claim
groupsPrefix: my-groups-prefix
requiredClaims:
string: string
tags:
env: dev
중요:
groupsPrefix나usernamePrefix에system:또는 해당 문자열의 일부를 지정하지 마세요.
공급자를 생성합니다.
eksctl associate identityprovider -f associate-identity-provider.yaml
kubectl로 클러스터와 OIDC ID 공급자를 사용하려면 Kubernetes 문서의 "kubectl 사용"을 참고하세요.
AWS 콘솔을 사용해 ID 공급자 연결
- Amazon EKS 콘솔을 엽니다.
- 클러스터를 선택한 다음 Access 탭을 선택합니다.
- OIDC Identity Providers 섹션에서 Associate Identity Provider를 선택합니다.
- Associate OIDC Identity Provider 페이지에서 다음 옵션을 입력하거나 선택한 다음 Associate를 선택합니다.
- Name - 공급자의 고유한 이름을 입력합니다.
- Issuer URL - 공급자의 URL을 입력합니다. 이 URL은 인터넷을 통해 접근 가능해야 합니다.
- Client ID - OIDC ID 공급자의 클라이언트 ID(오디언스라고도 함)를 입력합니다.
- Username claim - 사용자 이름으로 사용할 클레임을 입력합니다.
- Groups claim - 사용자의 그룹으로 사용할 클레임을 입력합니다.
- (선택 사항) Advanced options를 선택하고 다음 정보를 입력하거나 선택합니다.
- Username prefix – 사용자 이름 클레임 앞에 붙일 접두사를 입력합니다. 이 접두사는 기존 이름과의 충돌을 방지하기 위해 사용자 이름 클레임 앞에 추가됩니다. 값을 제공하지 않고 사용자 이름이
email이외의 값이라면 접두사는 기본적으로 Issuer URL 값이 됩니다.-값을 사용해 모든 접두사 추가를 비활성화할 수 있습니다.system:또는 해당 문자열의 일부를 지정하지 마세요. - Groups prefix – 그룹 클레임 앞에 붙일 접두사를 입력합니다. 이 접두사는 기존 이름(예:
system:groups)과의 충돌을 방지하기 위해 그룹 클레임 앞에 추가됩니다. 예를 들어oidc:값은oidc:engineering,oidc:infra같은 그룹 이름을 만듭니다.system:또는 해당 문자열의 일부를 지정하지 마세요. - Required claims – Add claim을 선택하고 클라이언트 ID 토큰에서 필요한 클레임을 설명하는 키-값 쌍을 하나 이상 입력합니다. 쌍은 ID 토큰에서 필요한 클레임을 설명합니다. 설정하면 각 클레임이 일치하는 값으로 ID 토큰에 존재하는지 확인됩니다.
- Username prefix – 사용자 이름 클레임 앞에 붙일 접두사를 입력합니다. 이 접두사는 기존 이름과의 충돌을 방지하기 위해 사용자 이름 클레임 앞에 추가됩니다. 값을 제공하지 않고 사용자 이름이
kubectl로 클러스터와 OIDC ID 공급자를 사용하려면 Kubernetes 문서의 "kubectl 사용"을 참고하세요.
여러 ID 공급자를 위한 모범 사례
- 사용자 이름 및 그룹 접두사 사용: 각 OIDC ID 공급자에 사용자 이름 접두사(
usernamePrefix)와 그룹 접두사(groupsPrefix)를 설정해 서로 다른 공급자의 ID가 겹칠 가능성을 줄이세요. 접두사를 사용하지 않는다면 공급자별로 고유한 사용자 이름 및 그룹 클레임을 사용하세요. 두 방식 모두 두 공급자가 동일한 Kubernetes 사용자 이름이나 그룹 이름을 만들 수 없도록 보장합니다. - 토큰 클레임 검증: 필수 클레임(
requiredClaims)을 사용해 ID 토큰에 반드시 존재해야 하는 키-값 쌍을 지정하면, 클러스터는 승인한 토큰만 수락합니다. - 각 토큰의 클레임 제한: 클러스터에 필요한 클레임만 포함한 토큰을 발급하도록 ID 공급자를 구성하세요. 클레임을 제한하면 토큰이 유출되어도 노출되는 정보가 줄어듭니다.
IAM 정책 예제
OIDC ID 공급자가 클러스터에 연결되는 것을 방지하려면 다음 IAM 정책을 생성해 Amazon EKS 관리자의 IAM 계정에 연결하세요. 자세한 내용은 IAM 사용 설명서의 "IAM 정책 생성" 및 "IAM ID 권한 추가", Service Authorization Reference의 "Actions"를 참고하세요.
{
"Version":"2012-10-17",
"Statement": [
{
"Sid": "denyOIDC",
"Effect": "Deny",
"Action": [
"eks:AssociateIdentityProviderConfig"
],
"Resource": "arn:aws:eks:us-west-2:111122223333:cluster/*"
},
{
"Sid": "eksAdmin",
"Effect": "Allow",
"Action": [
"eks:*"
],
"Resource": "*"
}
]
}
다음 예제 정책은 clientID가 kubernetes이고 issuerUrl이 https://cognito-idp.us-west-2.amazonaws.com/*일 때 OIDC ID 공급자 연결을 허용합니다.
{
"Version":"2012-10-17",
"Statement": [
{
"Sid": "AllowCognitoOnly",
"Effect": "Deny",
"Action": "eks:AssociateIdentityProviderConfig",
"Resource": "arn:aws:eks:us-west-2:111122223333:cluster/my-instance",
"Condition": {
"StringNotLikeIfExists": {
"eks:issuerUrl": "https://cognito-idp.us-west-2.amazonaws.com/*"
}
}
},
{
"Sid": "DenyOtherClients",
"Effect": "Deny",
"Action": "eks:AssociateIdentityProviderConfig",
"Resource": "arn:aws:eks:us-west-2:111122223333:cluster/my-instance",
"Condition": {
"StringNotEquals": {
"eks:clientId": "kubernetes"
}
}
},
{
"Sid": "AllowOthers",
"Effect": "Allow",
"Action": "eks:*",
"Resource": "*"
}
]
}