Study_note
AEWS Study 6 주차 (Security, irsa 인증 과정 실습) 본문
이어서 6주차 Security을 정리해본다.
마찬가지로 구축 내용은 스킵하고 그 외 자세한 내용을 정리한다
---
K8S(API 접근) 인증/인가 소개
인증(Authentication)
- X.509 Client Certs : kubeconfig 에 CA crt(발급 기관 인증서) , Client crt(클라이언트 인증서) , Client key(클라이언트 개인키) 를 통해 인증
- kubectl : 여러 클러스터(kubeconfig)를 관리 가능 - contexts 에 클러스터와 유저 및 인증서/키 참고
- Service Account : 기본 서비스 어카운트(default) - 시크릿(CA crt 와 token)
**인가(Authorization)**
- 인가 방식 : RBAC(Role, RoleBinding), ABAC, Webhook, Node Authorization
- RBAC : 역할 기반의 권한 관리, 사용자와 역할을 별개로 선언 후 두가지를 조합(binding)해서 사용자에게 권한을 부여하여 kubectl or API로 관리 가능
- Namespace/Cluster - Role/ClusterRole, RoleBinding/ClusterRoleBinding, Service Account
- Role(롤) - (RoleBinding 롤 바인딩) - Service Account(서비스 어카운트) : 롤 바인딩은 롤과 서비스 어카운트를 연결
- Role(네임스페이스내 자원의 권한) vs ClusterRole(클러스터 수준의 자원의 권한)
이번 스터디에서 정리를 해줘서 한번더 글을 써본다.
.kube/config 파일 내용
- clusters : kubectl 이 사용할 쿠버네티스 API 서버의 접속 정보 목록. 원격의 쿠버네티스 API 서버의 주소를 추가해 사용 가능
- users : 쿠버네티스의 API 서버에 접속하기 위한 사용자 인증 정보 목록. (서비스 어카운트의 토큰, 혹은 인증서의 데이터 등)
- contexts : cluster 항목과 users 항목에 정의된 값을 조합해 최종적으로 사용할 쿠버네티스 클러스터의 정보(컨텍스트)를 설정.
- 예를 들어 clusters 항목에 클러스터 A,B 가 정의돼 있고, users 항목에 사용자 a,b 가 정의돼 있다면 cluster A + user a 를 조합해, 'cluster A 에 user a 로 인증해 쿠버네티스를 사용한다' 라는 새로운 컨텍스트를 정의할 수 있습니다.
- kubectl 을 사용하려면 여러 개의 컨텍스트 중 하나를 선택.
그럼 EKS에서는 인증, 인가는 어떻게 될까?
이것또한 예전에 글을 작성했지만 이번 기회에 더 디테일하게 작성해본다.
아래 3개의 그림을 확인하면 어떻게 인증, 인가가 적용되는지 확인 가능하다.
실습은 다음과 같다.
우선 rbac에 관한 여러 플러그인들을 소개 시켜주셔 이것부터 설치하고 작업한다.
#kubernetes 클러스터에 대해 어떤 액세스 권한이 있는지 확인 가능
kubectl access-matrix -n default
# rbac권한 및 적용되는 대상들을 검색 가능하다
kubectl rbac-tool
#rbac 시각화 플러그인
kubectl rbac-view
1. EKS Cluster 접근 권한을 부여한 PC에서 kubectl 명령어를 입력한다.
2. kubeconfig 내 정의된 eks get-token 명령어를 실행하여 STS(Security Token Service)로 요청을 전달한다.
3. STS로부터 Base64로 인코딩된 토큰 값을 응답으로 전달 받는다.
- 토큰 값을 디코딩하면 STS getCallerIdentity API를 호출하는 Pre-Signed URL임을 알 수 있다. 아래서 확인 가능
- https://jwt.io/
4. kubectl의 Client-Go 라이브러리가 Pre-Signed URL을 Bearer Token으로 EKS Cluster Endpoint를 통해 API 서버로 요청을 전송한다.
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins
(K8S 클러스터와 상호작용하기 위한 공식 Go 라이브러리, kubectl은 Client-Go를 내부적으로 사용하여 K8S 클러스터와 상호작용한다.)
5. EKS API는 Token Review 를 Webhook token authenticator에 요청 ⇒ (STS GetCallerIdentity 호출) AWS IAM 해당 호출 인증 완료 후 User/Role에 대한 ARN 반환
6. 해당 IAM User/Role 확인이 되면 k8s aws-auth configmap에서 mapping 정보를 확인하게 됩니다.
aws-auth 컨피그맵에 'IAM 사용자, 역할 arm, K8S 오브젝트' 로 권한 확인 후 k8s 인가 허가가 되면 최종적으로 동작 실행을 합니다.
아래 처럼 권한이 할당된것을 확인 가능하다
IRSA
EC2 Instance Profile : 사용하기 편하지만, 해당 노드 내에 배포된 모든 파드가 동일한 권한을 갖게 되므로, 최소 권한 부여 원칙을 위배하여 보안상 권고하지 않는다 -> IRSA 권장
그럼 IRSA가 무엇인가
AWS에서는 파드별로 사용하는 Sevice Account마다 서로 다른 IAM Role의 매핑이 가능한 IRSA를 제공한다.
EX) IRSA 권한이 할당된 A 파드는 S3 접근 가능하지만 IRSA 권한이 할당되지 않은 B 파드는 S3에 접근 불가
테스트
SA가 없는 파드, SA가 있는 파드, IRSA가 할당 된 파드에 따른 권한 테스트
SA가 없는 파드
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: eks-iam-test1
spec:
containers:
- name: my-aws-cli
image: amazon/aws-cli:latest
args: ['s3', 'ls']
restartPolicy: Never
automountServiceAccountToken: false
EOF
아래와 같이 권한이 없어서 Access Denied
sa가 있는 파드 또한 sa 토큰은 확인이 되지만 access denied가 발생한다
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: eks-iam-test2
spec:
containers:
- name: my-aws-cli
image: amazon/aws-cli:latest
command: ['sleep', '36000']
restartPolicy: Never
EOF
아래와 같이 SA 토큰 값을 디코딩하면 아래와 같은 내용을 확인할 수 있다.
- projectedServiceAccountToken 기능으로 토큰에 aud, exp 항목 추가
- iss는 EKS OpenID Connect Provide주소로 작성되어있다.
- 즉, K8S가 발급한 토큰의 유효성 검증은 EKS IdP에서 수행한다.
- iss: 토큰 발행자
- sub: 사용자를 구분하기 위한 유니크한 구분자
- email: 사용자의 이메일
- iat: 토큰이 발행되는 시간을 Unix time으로 표기한 것
- exp: 토큰이 만료되는 시간을 Unix time으로 표기한 것
- aud: ID Token이 어떤 Client를 위해 발급된 것인지
IRSA 생성
eksctl create iamserviceaccount \
--name my-sa \
--namespace default \
--cluster $CLUSTER_NAME \
--approve \
--attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3ReadOnlyAccess`].Arn' --output text)
IRSA가 할당된 파드 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: eks-iam-test3
spec:
serviceAccountName: my-sa
containers:
- name: my-aws-cli
image: amazon/aws-cli:latest
command: ['sleep', '36000']
restartPolicy: Never
EOF
파드 확인해 보면 아래와 같이 env, volume이 생성되었다
위와 같이 access denied 되지않고 접근 가능하다.
Pod Identity Webhook은 mutating webhook을 통해 Env, Volume 값을 추가한다고 한다
irsa를 통해 생성된 볼륨 중 aws-iam-token은 JWT 토큰이 담겨져있고, exp, aud 속성이 추가되어 있다
참조
https://kubetm.github.io/k8s/07-intermediate-basic-resource/authentication/
'Terraform' 카테고리의 다른 글
Kubernetes OpenInfra Community Day 2023 발표 후기 (0) | 2023.07.05 |
---|---|
AEWS Study 7 주차 (EKS Automation, ack, flux argo) (2) | 2023.06.11 |
AEWS Study 5 주차 (Autoscailing, hpa, keda, karpenter) (1) | 2023.05.28 |
[Terraform] EKS 및 addon, helm, controller 등 생성 (0) | 2023.05.25 |
AEWS Study 3 주차 (스토리지) (0) | 2023.05.11 |