Kubernetes에서는 API 통신을 위하여 인증(Authentication), 인가/권한(Authorization), Admission Control(승인제어) 단계를 거치게 된다.
인증(Authentication): Kubernetes를 사용하는 사용자가 검증된 사용자인지를 확인하는 절차
- User Account: Kubernetes를 사용하는 사용자 계정 ex) AWS 로그인 계정 - Service Account: Pod에서 실행되는 프로세스에 대한 식별자를 제공 / Namespace로 구분 ex) AWS IAM
인가/권한(Authorization): 사용자 행위에 대해서 권한이 있는지를 확인하는 절차 / RBAC기반으로 동작
- User Account 별 Role/Rolebinding / Cluster Role/ Cluster Rolebinding - Service Account 별로 Role/Rolebinding / Cluster Role/Cluster Rolebinding
Admission Control(승인제어): API 요청 검증 / API 요청에 대한 특정 기능을 제한 / 변경(ResourceQuota, LimitRange)
Service Account 실습 시나리오
서비스 어카운트(Service Account, SA)를 생성 : dev-k8s, infra-k8s
서비스 어카운트 별 Pod 생성 및 권한 Test
서비스 어카운트 별 권한(Role, 인가)생성 : dev-k8s(dev-team 네임스페이스 내 모든 동작) , infra-k8s(dev-team 네임스페이스 내 모든 동작)
SA 를 지정하여 권한에 대한 테스트를 진행
1. 네임스페이스와 서비스 어카운트 생성 후 확인
# 네임스페이스(Namespace, NS) 생성 및 확인
kubectl create namespace dev-team
kubectl create ns infra-team
# 네임스페이스 확인
kubectl get ns
# 네임스페이스에 각각 서비스 어카운트 생성 : serviceaccounts 약자(=sa)
kubectl create sa dev-k8s -n dev-team
kubectl create sa infra-k8s -n infra-team
# 서비스 어카운트 정보 확인
kubectl get sa -n dev-team
kubectl get sa dev-k8s -n dev-team -o yaml | yh
kubectl get sa -n infra-team
kubectl get sa infra-k8s -n infra-team -o yaml | yh
2. 서비스 어카운트 별 Pod 생성 및 권한 Test
# 각각 네임스피이스에 kubectl 파드 생성 - 컨테이너이미지
# docker run --rm --name kubectl -v /path/to/your/kube/config:/.kube/config bitnami/kubectl:latest
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: dev-kubectl
namespace: dev-team
spec:
serviceAccountName: dev-k8s
containers:
- name: kubectl-pod
image: bitnami/kubectl:1.28.5
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: infra-kubectl
namespace: infra-team
spec:
serviceAccountName: infra-k8s
containers:
- name: kubectl-pod
image: bitnami/kubectl:1.28.5
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 확인
kubectl get pod -A
kubectl get pod -o dev-kubectl -n dev-team -o yaml
serviceAccount: dev-k8s
...
kubectl get pod -o infra-kubectl -n infra-team -o yaml
serviceAccount: infra-k8s
...
# 파드에 기본 적용되는 서비스 어카운트(토큰) 정보 확인
kubectl exec -it dev-kubectl -n dev-team -- ls /run/secrets/kubernetes.io/serviceaccount
kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/token
kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/namespace
kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/ca.crt
# 각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용
alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'
alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'
# 권한 테스트
k1 get pods # kubectl exec -it dev-kubectl -n dev-team -- kubectl get pods 와 동일한 실행 명령이다!
k1 run nginx --image nginx:1.20-alpine
k1 get pods -n kube-system
k2 get pods # kubectl exec -it infra-kubectl -n infra-team -- kubectl get pods 와 동일한 실행 명령이다!
k2 run nginx --image nginx:1.20-alpine
k2 get pods -n kube-system
# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
no
3. 서비스 어카운트 별 권한(Role, 인가)생성 : dev-k8s(dev-team 네임스페이스 내 모든 동작) , infra-k8s(dev-team 네임스페이스 내 모든 동작)
# 각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용
alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'
alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'
# 권한 테스트
k1 get pods
k1 run nginx --image nginx:1.20-alpine
k1 get pods
k1 delete pods nginx
k1 get pods -n kube-system
k1 get nodes
k2 get pods
k2 run nginx --image nginx:1.20-alpine
k2 get pods
k2 delete pods nginx
k2 get pods -n kube-system
k2 get nodes
# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
yes
EKS 인증/인가
AWS EKS의 경우 사용자 인증은 AWS IAM / 인가는 K8S의 RBAC을 사용
EKS 인증/인가 세부 과정
1.EKS Service endpoint(STS)에 토큰 요청
2. 전달받은 토큰을 Bearer Token 형식으로 EKS API Cluster EndPoint에 인증 요청
3.EKS API는 Token Review 를 Webhook token authenticator에 요청 ⇒ (STS GetCallerIdentity 호출) AWS IAM 해당 호출 인증 완료 후 User/Role에 대한 ARN 반환
3.쿠버네티스 RBAC 인가를 처리
실습 - myeks-bastion-2에 burst사용자 생성
1. burst 사용자 생성(Bastion1 서버 실행)
# 사용자 생성
aws iam create-user --user-name burst
# 사용자에게 프로그래밍 방식 액세스 권한 부여
aws iam create-access-key --user-name burst
# 사용자에 정책을 추가
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name burst
# get-caller-identity 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::590183955668:user/yjsong"
kubectl whoami
"arn:aws:iam::590183955668:user/yjsong"
# EC2 IP 확인 : myeks-bastion-EC2-2 PublicIPAdd 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table
2. burst 유저 자격증명 설정 및 확인 (Bastion2 서버 실행)
# get-caller-identity 확인 >> 왜 안될까요?
aws sts get-caller-identity --query Arn
# testuser 자격증명 설정
aws configure
AWS Access Key ID [None]: My-Access-Key
AWS Secret Access Key [None]: My-Secret-Key
Default region name [None]: ap-northeast-2
# get-caller-identity 확인
aws sts get-caller-identity --query Arn
# kubectl 시도 >> testuser도 AdministratorAccess 권한을 가지고 있는데, 실패 이유는?
kubectl get node -v6
ls ~/.kube
3. burst에 system:masters 그룹 부여로 EKS 관리자 수준 권한 설정 (Bastion1 서버 실행)
4. burst kubeconfig 생성 및 kubectl 사용 확인 (Bastion2 서버 실행)
# burst kubeconfig 생성 >> aws eks update-kubeconfig 실행이 가능한 이유는?, 3번 설정 후 약간의 적용 시간 필요
aws eks update-kubeconfig --name $CLUSTER_NAME --user-alias burst
# kubectl 사용 확인
kubectl ns default
kubectl get node -v6
EKS 신규기능 access management controls
aws-auth configmap 잘못 수정 시 Node전체에 장애가 발생 할 수 있음
이를 보안하기 위해 신규 기능인 access management controls 기능이 추가
기존 복잡하고 configmap을 통한 사용자 관리를 보다 쉽게 제어 및 컨트롤 할 수 있는 장점이 있음
기본 인증모드는 EKS API 및 ConfigMap으로 설정되어 있으나 정책 중복 시 EKS API가 우선되며, ConfigMap은 무시됨
실습 - EKS access management controls
1. EKS 인증방식을 EKS API모드로 변경
# EKS API 액세스모드로 변경
aws eks update-cluster-config --name $CLUSTER_NAME --access-config authenticationMode=API
# List all access policies : 클러스터 액세스 관리를 위해 지원되는 액세스 정책
## AmazonEKSClusterAdminPolicy – 클러스터 관리자
## AmazonEKSAdminPolicy – 관리자
## AmazonEKSEditPolicy – 편집
## AmazonEKSViewPolicy – 보기
aws eks list-access-policies | jq
aws eks list-access-entries --cluster-name $CLUSTER_NAME | jq