이 문서에서는 구조적 인증을 사용하여 Azure Kubernetes Service (AKS) 컨트롤 플레인 인증을 위해 GitHub 및 Google Identity 외부 ID 공급자를 구성하는 방법을 보여 줍니다. JWT(JSON Web Token) 인증자를 만들고, 클레임 유효성 검사 및 매핑을 구성하고, 인증 흐름을 테스트하는 방법을 알아봅니다.
중요합니다
AKS 미리 보기 기능은 셀프 서비스에서 사용할 수 있습니다(옵트인 방식). 미리 보기는 "있는 그대로" 및 "사용 가능한 상태로" 제공되며 서비스 수준 계약 및 제한적 보증에서 제외됩니다. AKS 미리 보기의 일부는 고객 지원팀에서 최선을 다해 지원합니다. 따라서 이러한 기능은 프로덕션 용도로 사용할 수 없습니다. 자세한 내용은 다음 지원 문서를 참조하세요.
필수 조건
- 외부 ID 공급자를 사용하여 AKS에 인증하기 위한 개념적 개요 를 읽어보십시오.
Azure Cloud Shell Bash 환경을 사용합니다. 자세한 내용은 Azure Cloud Shell 시작하기를 참조하시기 바랍니다.
CLI 참조 명령을 로컬에서 실행하려면 Azure CLI를 설치하십시오. Windows 또는 macOS에서 실행하는 경우 Docker 컨테이너에서 Azure CLI 실행하는 것이 좋습니다. 자세한 내용은 Docker 컨테이너에서 Azure CLI 실행하는 방법 참조하세요.
로컬 설치를 사용하는 경우 az login 명령을 사용하여 Azure CLI 로그인합니다. 인증 프로세스를 완료하려면 터미널에 표시되는 단계를 수행합니다. 다른 로그인 옵션은 Azure CLI 사용하여 Azure 인증을 참조하세요.
메시지가 표시되면 처음 사용할 때 Azure CLI 확장을 설치합니다. 확장에 대한 자세한 내용은
Azure CLI 참조하세요. az version을 실행하여 설치된 버전과 관련 종속 라이브러리를 확인합니다. 최신 버전으로 업그레이드하려면 az upgrade를 실행합니다.
이 문서에는 Azure CLI 버전 2.77.0 이상이 필요합니다. Azure Cloud Shell 사용하는 경우 최신 버전이 이미 설치되어 있습니다. 로컬 컴퓨터에 Azure CLI 설치하거나 업데이트하려면
Azure CLI 참조하세요.구조적 인증 기능을 사용하려면
aks-previewAzure CLI 확장 버전 18.0.0b41 이상을 설치해야 합니다.아직
aks-preview확장을 갖고 있지 않다면,az extension add명령을 사용하여 이 확장을 설치하세요.az extension add --name aks-preview이미
aks-preview확장이 있다면, 업데이트하여 이 확장이az extension update명령을 사용하여 최신 버전이 있는지 확인하게 하세요.az extension update --name aks-preview확인 명령
az extension show을 사용하여 확장aks-preview의 필요한 버전이 있는지 확인하십시오.az extension show --name aks-preview --query version
Kubernetes 버전 1.30 이상을 실행하는 AKS 클러스터입니다. AKS 클러스터를 만들려면 Azure CLI 사용하여 Azure Kubernetes Service (AKS) 클러스터 배포를 참조하세요.
kubectlKubernetes 클러스터와 상호 작용하는 명령줄 도구입니다. Azure Cloud Shell 사용하는 경우kubectl이미 설치되어 있습니다.kubectl을/를 로컬에 설치하려면az aks install-cli명령을 사용하세요.az aks install-cliOIDC(OpenID Connect)를 지원하는 외부 ID 공급자입니다.
클러스터 노드에서 ID 공급자로의 네트워크 연결
플러그 인을
kubelogin사용하려는 경우 kubelogin 설치 가이드의 지침에 따라 설치합니다.
환경 변수 설정
리소스 그룹 및 클러스터 이름에 대해 다음 환경 변수를 설정합니다.
export RESOURCE_GROUP="<your-resource-group-name>" export CLUSTER_NAME="<your-cluster-name>"
JWTAuthenticatorPreview 기능 등록
JWTAuthenticatorPreview기능을az feature register명령을 사용하여 등록합니다.az feature register --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService명령을 사용하여 기능의 등록 상태를 확인합니다
az feature show.az feature show --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService상태가
Registered로 표시되면,Microsoft.ContainerService리소스 공급자 등록을az provider register명령을 사용하여 새로 고치십시오.az provider register --namespace Microsoft.ContainerService
GitHub Actions OIDC 인증 설정
GitHub Actions 워크플로에 필요한 권한이 있는지 확인합니다.
워크플로 파일에서
id-token: write사용 권한을 구성합니다. 다음은 그 예입니다.permissions: id-token: write contents: readOIDC 토큰 액세스에 적절한 리포지토리 및 조직 설정을 설정합니다. 토큰 사용에 대한 리포지토리 OIDC 설정 및 조직 보안 정책을 구성합니다.
Google Identity OAuth 2.0 인증 설정
- Google 클라우드 콘솔로 이동합니다.
- 프로젝트를 만들거나 선택합니다.
- OAuth 2.0 자격 증명을 만듭니다.
- 나중에 사용할 수 있는 클라이언트 ID 및 클라이언트 암호를 기록해 둡니다.
GitHub Actions OIDC에 대한 JWT 인증자 구성 만들기
다음 구성으로 명명된
jwt-config.json파일을 만듭니다.{ "issuer": { "url": "https://token.actions.githubusercontent.com", "audiences": [ "my-api" ] }, "claimValidationRules": [ { "expression": "has(claims.sub)", "message": "must have sub claim" } ], "claimMappings": { "username": { "expression": "'aks:jwt:github:' + claims.sub" } }, "userValidationRules": [ { "expression": "has(user.username)", "message": "must have username" }, { "expression": "!user.username.startsWith('aks:jwt:github:system')", "message": "username must not start with 'aks:jwt:github:system'" } ] }
Google ID에 대한 JWT 인증자 구성 만들기
다음 구성으로 명명된
jwt-config.json파일을 만듭니다.{ "issuer": { "url": "https://accounts.google.com", "audiences": [ "your-client-id.apps.googleusercontent.com" ] }, "claimValidationRules": [ { "expression": "has(claims.sub)", "message": "must have sub claim" } ], "claimMappings": { "username": { "expression": "'aks:jwt:google:' + claims.sub" }, "groups": { "expression": "has(claims.groups) ? claims.groups.split(',').map(g, 'aks:jwt:' + g) : []" } }, "userValidationRules": [ { "expression": "has(user.username)", "message": "must have username" }, { "expression": "!user.username.startsWith('aks:jwt:google:system')", "message": "username must not start with 'aks:jwt:google:system'" } ] }
JWT 인증자 구성 요소
JWT 인증자 구성에는 다음과 같은 주요 요소가 issuerclaimValidationRulesclaimMappingsuserValidationRules포함됩니다. 각 요소는 AKS가 외부 ID 공급자에서 JWT 토큰의 유효성을 검사하고 처리하는 방법을 정의하는 특정 용도로 사용됩니다.
발급자 구성
issuer 구성의 주요 요소에 대해 다음 표에서는 설명합니다.
| 발급자 구성 요소 | 설명 |
|---|---|
url |
JWT의 iss 클레임과 일치해야 하는 OIDC 발급자 URL입니다. |
audiences |
JWT가 발급될 대상으로 지정된 그룹의 목록입니다(aud 클레임에 대해 확인됨). |
클레임 유효성 검사 규칙 구성
claimValidationRules 구성의 주요 요소에 대해 다음 표에서는 설명합니다.
| 클레임 유효성 검사 규칙 요소 | 설명 |
|---|---|
expression |
JWT 클레임에 적용할 유효성 검사 논리를 정의하는 CEL 식입니다. 토큰이 허용되려면 표현식이 true로 평가되어야 합니다. |
message |
유효성 검사 규칙이 실패하면 오류 메시지가 반환됩니다. |
클레임 매핑 구성
claimMappings 구성의 주요 요소에 대해 다음 표에서는 설명합니다.
| 클레임 매핑 요소 | 설명 |
|---|---|
username |
JWT 클레임에서 Kubernetes 사용자 이름을 생성하는 방법을 정의하는 CEL 식입니다.
다른 인증 방법과의 aks:jwt: 충돌을 방지하려면 접두사를 포함해야 합니다. |
groups |
JWT 클레임에서 Kubernetes 그룹 멤버 자격을 생성하는 방법을 정의하는 CEL 식입니다.
다른 인증 방법과의 aks:jwt: 충돌을 방지하려면 접두사를 포함해야 합니다. |
uid |
사용자에 대한 고유 식별자를 정의하는 선택적 CEL 식입니다. |
extra |
CEL 식으로 정의된 추가 사용자 특성의 선택적 맵입니다. |
사용자 유효성 검사 규칙 구성
userValidationRules 구성의 주요 요소에 대해 다음 표에서는 설명합니다.
| 사용자 유효성 검사 규칙 요소 | 설명 |
|---|---|
expression |
최종 매핑된 사용자 정보에 적용할 추가 유효성 검사 논리를 정의하는 CEL 식입니다. 사용자가 수락되려면 식이 true로 평가되어야 합니다. |
message |
사용자 유효성 검사 규칙이 실패하면 오류 메시지가 반환됩니다. |
JWT 인증자 만들기
명령을 사용하여 AKS 클러스터에 JWT 인증자를 추가합니다
az aks jwtauthenticator add.az aks jwtauthenticator add \ --resource-group $RESOURCE_GROUP \ --cluster-name $CLUSTER_NAME \ --name external-auth \ --config-file jwt-config.json
JWT 인증자 관리
모든 JWT 인증자 나열
명령을 사용하여 클러스터의 모든 JWT 인증자를 나열합니다
az aks jwtauthenticator list.az aks jwtauthenticator list \ --resource-group $RESOURCE_GROUP \ --cluster-name $CLUSTER_NAME
특정 JWT 인증자에 대한 세부 정보 가져오기
명령을 사용하여
az aks jwtauthenticator show특정 JWT 인증자에 대한 세부 정보를 가져옵니다.az aks jwtauthenticator show \ --resource-group $RESOURCE_GROUP \ --cluster-name $CLUSTER_NAME \ --name external-auth
인증을 위해 GitHub Actions OIDC 설정
환경 변수를 만들고 GitHub 리포지토리에서 다음과 같은 필수 리포지토리 비밀을 설정합니다.
-
AKS_SERVER_URL: AKS 클러스터의 API 서버 URL입니다. -
AKS_CA_DATA: AKS 클러스터에 대한 Base64로 인코딩된 인증 기관 데이터입니다.
-
OIDC 토큰을 가져와 AKS 클러스터로 인증하는 데 사용하는 워크플로를 만듭니다. 다음 예제 워크플로는 클러스터에서 실행되는 모든 Pod를 가져옵니다.
비고
대상 그룹 값
my-api은 JWT 인증자 구성에 구성된 대상과 일치해야 합니다.name: AKS Access with GitHub OIDC on: workflow_dispatch: push: branches: [main] permissions: id-token: write contents: read jobs: aks-access: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install kubectl uses: azure/setup-kubectl@v3 with: version: 'latest' - name: Get GitHub OIDC token id: get_token run: | TOKEN=$(curl -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \ "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=my-api" | \ jq -r '.value') echo "::add-mask::$TOKEN" echo "oidc_token=$TOKEN" >> $GITHUB_OUTPUT - name: Create kubeconfig with OIDC token run: | cat <<EOF > kubeconfig apiVersion: v1 kind: Config clusters: - cluster: certificate-authority-data: ${{ secrets.AKS_CA_DATA }} server: ${{ secrets.AKS_SERVER_URL }} name: aks-cluster contexts: - context: cluster: aks-cluster user: github-oidc-user name: aks-context current-context: aks-context users: - name: github-oidc-user user: token: ${{ steps.get_token.outputs.oidc_token }} EOF - name: List all pods in the cluster run: | export KUBECONFIG=./kubeconfig kubectl get pods --all-namespaces
JWT 인증자 구성에 대한 클러스터 정보 가져오기
명령을 사용하여 클러스터에 대한 API 서버 URL을 가져옵니다
az aks show.az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "fqdn" -o tsv | \ awk '{print "https://" $0 ":443"}'명령을 사용하여
az aks get-credentials클러스터에 대한 base64로 인코딩된 인증 기관 데이터를 가져옵니다.# Get CA data (base64 encoded) az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --file - --format exec | \ grep certificate-authority-data | awk '{print $2}'
인증을 위해 Google Identity OAuth 2.0 설정
플러그 인을 사용하거나 정적 토큰을 kubelogin 직접 사용하여 Google ID 인증을 설정할 수 있습니다.
kubeconfig 파일에 새 사용자 컨텍스트를 추가합니다. 다음은 그 예입니다.
users: - name: external-user user: exec: apiVersion: client.authentication.k8s.io/v1beta1 command: kubectl args: - oidc-login - get-token - --oidc-issuer-url=https://accounts.google.com - --oidc-client-id=your-client-id.apps.googleusercontent.com - --oidc-client-secret=your-client-secret
인증 테스트
메인 브랜치로 푸시하거나 리포지토리의 Actions 탭에서 수동으로 트리거하여 워크플로를 트리거합니다.
작업 탭에서 워크플로 실행을 모니터링하여 인증이 작동하는지 확인합니다.
RBAC(Role-Based Access Control) 구성 전에 처음 설치할 예상 출력:
Error from server (Forbidden): nodes is forbidden: User "aks:jwt:github:your-sub" cannot list resource "nodes" in API group "" at the cluster scope이 오류는 인증에 성공했지만 권한 부여가 없음을 나타냅니다.
kubectl get nodes명령의--user플래그를 사용하여 Google ID 인증을 위해 만든 사용자 컨텍스트를 지정하고 인증을 테스트합니다. 다음은 그 예입니다.kubectl get nodes --user external-userRBAC(Role-Based Access Control) 구성 전에 처음 설치할 예상 출력:
Error from server (Forbidden): nodes is forbidden: User "aks:jwt:google:your-subject" cannot list resource "nodes" in API group "" at the cluster scope이 오류는 인증에 성공했지만 권한 부여가 없음을 나타냅니다.
Kubernetes 역할 기반 접근 제어(RBAC) 구성
외부 사용자에 대한 적절한 RBAC 바인딩을 만들고 클러스터 관리자 자격 증명을 사용하여 이러한 구성을 적용합니다.
외부 사용자에 대한 RBAC 바인딩을 구성하기 위해 명명된
rbac-config.yaml파일을 만듭니다. 다음은 그 예입니다.apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-user-role rules: - apiGroups: [""] resources: ["pods", "services", "nodes"] verbs: ["get", "list"] - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-user-binding subjects: - kind: User # This matches the username expression in claim mappings for GitHub; example of GitHub subject is "repo:<organization-name>/<repository-name>:ref:refs/heads/main" name: aks:jwt:github:your-github-sub apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: external-user-role apiGroup: rbac.authorization.k8s.io다음 명령을 사용하여 RBAC 구성을 적용합니다.
kubectl applykubectl apply -f rbac-config.yaml
외부 사용자에 대한 RBAC 바인딩을 구성하기 위해 명명된
rbac-config.yaml파일을 만듭니다. 다음은 그 예입니다.apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-user-role rules: - apiGroups: [""] resources: ["pods", "services", "nodes"] verbs: ["get", "list"] - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-user-binding subjects: - kind: User # This matches the username expression in claim mappings for Google name: aks:jwt:google:your-subject-claim apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: external-user-role apiGroup: rbac.authorization.k8s.io다음 명령을 사용하여 RBAC 구성을 적용합니다.
kubectl applykubectl apply -f rbac-config.yaml
RBAC를 사용하여 액세스 확인
외부 사용자가
kubectl get nodes및kubectl get pods명령과 함께--user플래그를 사용하여 구성한 RBAC 권한에 따라 이제 리소스에 액세스할 수 있는지 확인합니다. 다음은 그 예입니다.kubectl get nodes --user external-user kubectl get pods --user external-user
JWT 인증자 제거
JWT 인증자가 더 이상 필요하지 않은 경우 명령을 사용하여
az aks jwtauthenticator deleteAKS 클러스터에서 제거합니다.az aks jwtauthenticator delete \ --resource-group $RESOURCE_GROUP \ --cluster-name $CLUSTER_NAME \ --name external-auth