송신자 → 수신자에게 ‘ABC’ 문장을 다음과 같은 규칙을 사용하여 전송한다 가정을 한다.
이 경우 “ABC” 문자열을 구성하는 ‘0x41,0x42,0x43’ 값은 각각 0x44, 0x45, 0x46으로 변환되어 “DEF”로 전송된다.
이 규칙을 사전에 알고 있는 수신측에서는 바이트 열에 각각 3씩 빼서 원래의 ‘ABC’ 문자열을 복원한다.
이러한 전송과정과 수신과정에서 사용되는 변환 규칙인 “각 문자의 ASCII 코드 값에 x씩 더하여 전송한다”의 개념을 암호 알고리즘이라고 하며 ‘x=3” 를 키 값
# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/myeks-6week.yaml
CLUSTER_NAME=myeks
SSHKEYNAME=<SSH 키 페이 이름>
MYACCESSKEY=<IAM Uesr 액세스 키>
MYSECRETKEY=<IAM Uesr 시크릿 키>
# CloudFormation 스택 배포
aws cloudformation deploy --template-file myeks-6week.yaml --stack-name $CLUSTER_NAME --parameter-overrides KeyName=$SSHKEYNAME SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=$MYACCESSKEY MyIamUserSecretAccessKey=$MYSECRETKEY ClusterBaseName=$CLUSTER_NAME --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력
aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text
# 변수 지정
CLUSTER_NAME=myeks
SSHKEYNAME=bocopile-key
#
eksctl get cluster
# kubeconfig 생성
aws sts get-caller-identity --query Arn
aws eks update-kubeconfig --name myeks --user-alias <위 출력된 자격증명 사용자>
*aws eks update-kubeconfig --name myeks --user-alias bocopile*
#
kubectl ns default
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
kubectl get pod -A
kubectl get pdb -n kube-system
# EC2 공인 IP 변수 지정
export N1=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=myeks-ng1-Node" "Name=availability-zone,Values=ap-northeast-2a" --query 'Reservations[*].Instances[*].PublicIpAddress' --output text)
export N2=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=myeks-ng1-Node" "Name=availability-zone,Values=ap-northeast-2b" --query 'Reservations[*].Instances[*].PublicIpAddress' --output text)
export N3=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=myeks-ng1-Node" "Name=availability-zone,Values=ap-northeast-2c" --query 'Reservations[*].Instances[*].PublicIpAddress' --output text)
echo $N1, $N2, $N3
# *remoteAccess* 포함된 보안그룹 ID
aws ec2 describe-security-groups --filters "Name=group-name,Values=*remoteAccess*" | jq
export MNSGID=$(aws ec2 describe-security-groups --filters "Name=group-name,Values=*remoteAccess*" --query 'SecurityGroups[*].GroupId' --output text)
# 해당 보안그룹 inbound 에 자신의 집 공인 IP 룰 추가
aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr $(curl -s ipinfo.io/ip)/32
# 해당 보안그룹 inbound 에 운영서버 내부 IP 룰 추가
aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr 172.20.1.100/32
aws ec2 authorize-security-group-ingress --group-id $MNSGID --protocol '-1' --cidr 172.20.1.200/32
# 워커 노드 SSH 접속
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh -o StrictHostKeyChecking=no ec2-user@$i hostname; echo; done
워커 노드가 접속 되는것을 확인

# default 네임스페이스 적용
kubectl ns default
# 환경변수 정보 확인
export | egrep 'ACCOUNT|AWS_|CLUSTER|KUBERNETES|VPC|Subnet'
export | egrep 'ACCOUNT|AWS_|CLUSTER|KUBERNETES|VPC|Subnet' | egrep -v 'KEY'
# krew 플러그인 확인 : 보안 관련 플러그인 다수 설치
kubectl krew list
# 인스턴스 정보 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{InstanceID:InstanceId, PublicIPAdd:PublicIpAddress, PrivateIPAdd:PrivateIpAddress, InstanceName:Tags[?Key=='Name']|[0].Value, Status:State.Name}" --filters Name=instance-state-name,Values=running --output table
# 노드 IP 확인 및 PrivateIP 변수 지정
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
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
echo "export N3=$N3" >> /etc/profile
echo $N1, $N2, $N3
# 노드 IP 로 ping 테스트
for i in $N1 $N2 $N3; do echo ">> node $i <<"; ping -c 1 $i ; echo; done
운영서버 1에서 각 노드로 접근이 되는 것을 확인

# 실습 완료 후 삭제 할 것!
cat << EOF >> ~/.zshrc
# eksworkshop
export CLUSTER_NAME=myeks
export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" --query 'Vpcs[*].VpcId' --output text)
export PubSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet2" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet3=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-Vpc1PublicSubnet3" --query "Subnets[0].[SubnetId]" --output text)
export N1=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node" "Name=availability-zone,Values=ap-northeast-2a" --query 'Reservations[*].Instances[*].PublicIpAddress' --output text)
export N2=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node" "Name=availability-zone,Values=ap-northeast-2b" --query 'Reservations[*].Instances[*].PublicIpAddress' --output text)
export N3=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node" "Name=availability-zone,Values=ap-northeast-2c" --query 'Reservations[*].Instances[*].PublicIpAddress' --output text)
export CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text)
MyDomain=bocopile.com # 각자 자신의 도메인 이름 입력
MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "$MyDomain." --query "HostedZones[0].Id" --output text)
EOF
# [신규 터미널] 확인
echo $CLUSTER_NAME $VPCID $PubSubnet1 $PubSubnet2 $PubSubnet3
echo $N1 $N2 $N3 $MyDomain $MyDnzHostedZoneId
tail -n 15 ~/.zshrc
해당 파라미터 조회 되는 것을 확인

helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
echo $MyDomain
curl -s https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml | MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst | kubectl apply -f -
# gp3 스토리지 클래스 생성
cat <<EOF | kubectl apply -f -
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp3
annotations:
storageclass.kubernetes.io/is-default-class: "true"
allowVolumeExpansion: true
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
allowAutoIOPSPerGBIncrease: 'true'
encrypted: 'true'
fsType: xfs # 기본값이 ext4
EOF
kubectl get sc
gp3 StorageClass 생성 및 Default 설정이 완료된 것을 확인

helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=ClusterIP --set env.TZ="Asia/Seoul" --namespace kube-system
# kube-ops-view Ingress 설정
## group 설정으로 1대의 ALB를 여러개의 Ingress에서 공용 사용
echo $CERT_ARN
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/load-balancer-name: $CLUSTER_NAME-ingress-alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/target-type: ip
labels:
app.kubernetes.io/name: kubeopsview
name: kubeopsview
namespace: kube-system
spec:
ingressClassName: alb
rules:
- host: kubeopsview.$MyDomain
http:
paths:
- backend:
service:
name: kube-ops-view
port:
number: 8080 # name: http
path: /
pathType: Prefix
EOF
kubectl get pods -n kube-system
kubectl get ingress,svc,ep -n kube-system
open "https://kubeopsview.$MyDomain/#scale=1.5" # macOS
kubeopsview 접근 되는 것을 확인

# repo 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# 파라미터 파일 생성 : PV/PVC(AWS EBS) 삭제에 불편하니, 4주차 실습과 다르게 PV/PVC 미사용
cat <<EOT > monitor-values.yaml
prometheus:
prometheusSpec:
scrapeInterval: "15s"
evaluationInterval: "15s"
podMonitorSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
# Enable vertical pod autoscaler support for prometheus-operator
verticalPodAutoscaler:
enabled: true
ingress:
enabled: true
ingressClassName: alb
hosts:
- prometheus.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
defaultDashboardsEnabled: false
ingress:
enabled: true
ingressClassName: alb
hosts:
- grafana.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
alertmanager:
enabled: false
defaultRules:
create: false
kubeControllerManager:
enabled: false
kubeEtcd:
enabled: false
kubeScheduler:
enabled: false
prometheus-windows-exporter:
prometheus:
monitor:
enabled: false
EOT
cat monitor-values.yaml
# helm 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 69.3.1 \
-f monitor-values.yaml --create-namespace --namespace monitoring
# helm 확인
helm get values -n monitoring kube-prometheus-stack
# PV 사용하지 않음
kubectl get pv,pvc -A
kubectl df-pv

# 프로메테우스 웹 접속
echo -e "https://prometheus.$MyDomain"
open "https://prometheus.$MyDomain" # macOS
# 그라파나 웹 접속 : admin / prom-operator
echo -e "https://grafana.$MyDomain"
open "https://grafana.$MyDomain" # macOS
프로메테우스 및 그라파나 사이트 접속 되는 것을 확인



출처 : https://kubetm.github.io/k8s/07-intermediate-basic-resource/authentication/
출처 : https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/
요청을 보낸 사용자가 신뢰 할수 있는지 확인
출처 : https://kubetm.github.io/k8s/07-intermediate-basic-resource/authentication
사용자가 해당 요청을 수행할 권한이 있는지를 확인
출처 : https://kubetm.github.io/k8s/07-intermediate-basic-resource/authentication
| 비교 항목 | RBAC | ABAC |
|---|---|---|
| 접근 제어 기준 | 역할 (Role) | 속성 (Attributes) |
| 유연성 | 중간 (고정된 역할 기반) | 매우 높음 (다양한 조건에서 적용 가능) |
| 정책 적용 방식 | Role, RoleBinding / ClusterRole, ClusterRoleBinding 을 사용 | JSON 파일 등으로 정의 |
| 적용 예시 | 특정 사용자 그룹에 대한 리소스 접근 허용 | 특정 네트워크 대역에서만 허용 |
검증이 끝난 요청을 etcd에 저장 하고 클러스터에 반영
clusters : kubectl이 사용할 k8s API 서버의 접속 정보 목록, 원격의 k8s API 서버의 주소를 추가해 사용 가능
users : k8s API 서버에 접속하기 위한 사용자 인증 정보 목록 (SA의 Token, 인증서 데이터 등)
context : Cluster 항목과 users 항목에 정의된 값을 조합해 최종적으로 사용할 k8s 클러스터 정보
예시
cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJTHROY2RXbnUvSm93RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TlRBek1UUXdNak0yTWpKYUZ3MHpOVEF6TVRJd01qUXhNakphTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUN0dExRSFliYlM1bmhYcUQrenF6eWMybHFENlo4c2IreWJmaFp1OVFYVWNRSHVRYnpiU1hjTWxiVXEKUlJtNFplbWJRMFFDZDEyRlU1QTR0TjY0ZmJtclh0TjNpNVI5MmNyUUZRY2dXQW9zbXNFTHhiUUNIT3h5V2ptbApTVTlhR0JqaVo5d2l6UnlFaU81a3Y5dVdsMzA1SzF0M0p5MFdUOTkxV2cyRzhzSUJFM1cxdXc3UHdzOFVKR09ICkdzVjdMc1ZpYWdmdFcrQUpSTW0wTlFGWlVaT25RVUM1WE5rMHB1OE5wNWY4SUg5MVhUaHpkbDdqanM5T3JiQ2EKVHdsZ3dXVDIzODJBSWJDQlZQM0J4K0tRN05VaTNPSk5uVUw5ZlVSTW56dnNFWUE2MzYyRFJEcmF4Z1ZBdUQydgpGS0pCajI1VzYrajM5MEhqcDFPWWhuTzB1RDBwQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSdExEaW9WZzJtWm9pcUkzUExWMHdRR1JrRGpUQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQkVKY3I1QmxyRQozY25TTWQxTnE3bGtFSm1zV2VVWFhZcVBlYU0yNVNsd1RSNDlobVJoazJ2N0xyTFV6MlovTTNQc2JJUVNqeEYyCkQzeHcxcHM1RDhNUmU0VHhpazVXU3pqQjVCZVhUVGVkeXh5cS8rQ2dhbFV0WTdiekdwL1krYzhGdVRKMmxvWm4KOEZjaHI2UHJEdFdITkd4KzNvTE5ZSkRuOUdkalI2RTB4YWE4aWsyL1dzU3ZBeUZkblJ1UzM3ZENrMklzTHdNbApHUDV1cjlHVEtZazROU3V0aEpSakt3MVJxMW1YMU1PUG9TUk9ZNlpiVllQdWFRNGY3WkxtWXNlVnNxcmxnL0ZZClI4TlF4c0JCcjNVODUzU28wN2l1R21PRGVOYU9uUVJlTHplNzhLdTV1cW5WMnpLTnk1ZjB2dWU0WjRCdTMyb0IKQVc2RXhPb0xUR05VCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
server: https://D4B86138FEDFFE355BF3A3AEF71AD927.sk1.ap-northeast-2.eks.amazonaws.com
name: arn:aws:eks:ap-northeast-2:867344478065:cluster/myeks
contexts:
- context:
cluster: arn:aws:eks:ap-northeast-2:867344478065:cluster/myeks
namespace: default
user: bocopile
name: bocopile
current-context: bocopile
kind: Config
preferences: {}
users:
- name: bocopile
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- ap-northeast-2
- eks
- get-token
- --cluster-name
- myeks
- --output
- json
command: aws
env: null
interactiveMode: IfAvailable
provideClusterInfo: false
- name: bocopile@bocopile-karpenter-demo.ap-northeast-2.eksctl.io
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- eks
- get-token
- --output
- json
- --cluster-name
- bocopile-karpenter-demo
- --region
- ap-northeast-2
command: aws
env:
- name: AWS_STS_REGIONAL_ENDPOINTS
value: regional
interactiveMode: IfAvailable
kubectl create namespace dev-team
kubectl create ns infra-team
kubectl get ns

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 -n infra-team

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.31.4
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.31.4
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
kubectl get pod -A

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

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


| 명칭 | 권한 |
|---|---|
| * | 모든 권한 |
| create | 생성 |
| delete | 삭제 |
| get | 조회 |
| list | 목록 조회 |
| patch | 일부 업데이트 |
| update | 업데이트 |
| watch | 변경 감지 |
# 각각 네임스페이스내의 모든 권한에 대한 롤 생성
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: role-dev-team
namespace: dev-team
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
EOF
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: role-infra-team
namespace: infra-team
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
EOF
kubectl get roles -n dev-team
kubectl get roles -n infra-team
kubectl get roles -n dev-team -o yaml
kubectl get roles -n infra-team -o yaml


cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: roleB-dev-team
namespace: dev-team
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role-dev-team
subjects:
- kind: ServiceAccount
name: dev-k8s
namespace: dev-team
EOF
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: roleB-infra-team
namespace: infra-team
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role-infra-team
subjects:
- kind: ServiceAccount
name: infra-k8s
namespace: infra-team
EOF
kubectl get rolebindings -n dev-team
kubectl get rolebindings -n infra-team
kubectl get rolebindings -n dev-team -o yaml
kubectl get rolebindings -n infra-team -o yaml
kubectl describe rolebindings roleB-dev-team -n dev-team
kubectl describe rolebindings roleB-infra-team -n infra-team



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 pods -n kube-system -v=6
k1 get nodes
k1 get nodes -v=6
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 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
k2 auth can-i get pods



k1 auth can-i get pods
k2 auth can-i get pods

kubectl delete ns dev-team infra-team
kubectl krew install access-matrix rbac-tool ~~rbac-view~~ rolesum whoami
kubectl whoami

kubectl access-matrix # Review access to cluster-scoped resources
kubectl access-matrix --namespace default # Review access to namespaced resources in 'default'

kubectl rbac-tool lookup
kubectl rbac-tool lookup system:masters


kubectl rbac-tool lookup system:nodes # eks:node-bootstrapper
kubectl rbac-tool lookup system:bootstrappers # eks:node-bootstrapper
kubectl describe ClusterRole eks:node-bootstrappe

kubectl rbac-tool policy-rules
kubectl rbac-tool policy-rules -e '^system:.*'
kubectl rbac-tool policy-rules -e '^system:authenticated'


kubectl rbac-tool whoami

kubectl rolesum aws-node -n kube-system # sa
kubectl rolesum -k User system:kube-proxy # user
kubectl rolesum -k Group system:masters # group
kubectl rolesum -k Group system:nodes
kubectl rolesum -k Group system:authenticated


# EC2에서 실행할 것
echo -e "RBAC View Web http://$(curl -s ipinfo.io/ip):8800"
kubectl rbac-view


| 약어 | Verbs | 설명 |
|---|---|---|
| G | Get | 리소스를 조회할 수 있음 (get) |
| L | List | 리소스를 목록으로 나열할 수 있음 (list) |
| W | Watch | 리소스를 감시할 수 있음 (watch) |
| C | Create | 새 리소스를 생성할 수 있음 (create) |
| U | Update | 기존 리소스를 수정할 수 있음 (update) |
| P | Patch | 리소스의 일부를 패치할 수 있음 (patch) |
| D | Delete | 리소스를 삭제할 수 있음 (delete) |
| DC | Delete Collection | 리소스의 컬렉션(여러 개)을 삭제할 수 있음 (deletecollection) |
출처 : https://devlos.tistory.com/75/
kubectl 명령 → aws eks get-token → STS에 토큰 요청 → 응답값 디코드
# sts caller id의 ARN 확인
aws sts get-caller-identity --query Arn
# 조회 결과
"arn:aws:iam::867344478065:user/bocopile"
# kubeconfig 정보 확인
cat ~/.kube/config
# 조회 결과
- name: bocopile@bocopile-karpenter-demo.ap-northeast-2.eksctl.io
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- eks
- get-token
- --output
- json
- --cluster-name
- bocopile-karpenter-demo
- --region
- ap-northeast-2
command: aws
env:
- name: AWS_STS_REGIONAL_ENDPOINTS
value: regional
interactiveMode: IfAvailable
provideClusterInfo: false
#임시 보안 자격 증명(토큰)을 요청 : expirationTimestamp 시간경과 시 토큰 재발급됨
aws eks get-token --cluster-name $CLUSTER_NAME | jq
aws eks get-token --cluster-name $CLUSTER_NAME | jq -r '.status.token'
aws eks get-token --cluster-name $CLUSTER_NAME --debug | jq

kubectl의 Client-Go 라이브러리는 Pre-Signed URL을 Bearer Token으로 EKS API Cluster Endpoint로 요청을 보냄
# aws eks get-token --cluster-name $CLUSTER_NAME --debug | jq 출력 내용 아래 부분 확인
DEBUG - Endpoint provider result: https://sts.ap-northeast-2.amazonaws.com
Action=GetCallerIdentity&
Version=2011-06-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKIA5ILF.../20230525/ap-northeast-2/sts/aws4_request&
X-Amz-Date=20230525T120720Z&
X-Amz-Expires=60&
X-Amz-SignedHeaders=host;x-k8s-aws-id&
X-Amz-Signature=6e09b846da702767f38c78831986cb558.....
EKS API는 Token Review 를 Webhook token authenticator에 요청 ⇒ (STS GetCallerIdentity 호출) AWS IAM 해당 호출 인증 완료 후 User/Role에 대한 ARN 반환
# tokenreviews api 리소스 확인
kubectl api-resources | grep authentication
# List the fields for supported resources.
kubectl explain tokenreviews


[ConfigMap 방식] 이제 쿠버네티스 RBAC 인가를 처리
# aws-auth 컨피그맵 확인 : 현재는 IAM access entry 방식 우선 적용으로 아래 출력 내용과 다를 수 있습니다.
kubectl get cm -n kube-system aws-auth -o yaml
# EKS 설치한 IAM User 정보
kubectl rbac-tool whoami

# system:masters , system:authenticated 그룹의 정보 확인
kubectl rbac-tool lookup system:masters
kubectl rbac-tool lookup system:authenticated
kubectl rolesum -k Group system:masters
kubectl rolesum -k Group system:authenticated
# system:masters 그룹이 사용 가능한 클러스터 롤 확인 : cluster-admin
kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin

# cluster-admin 의 PolicyRule 확인 : 모든 리소스 사용 가능!
kubectl describe clusterrole cluster-admin
# system:authenticated 그룹이 사용 가능한 클러스터 롤 확인
kubectl describe ClusterRole system:discovery
kubectl describe ClusterRole system:public-info-viewer
kubectl describe ClusterRole system:basic-user
kubectl describe ClusterRole eks:podsecuritypolicy:privileged


인증은 AWS IAM, 인가는 K8S RBAC에서 처리

출처 : https://docs.aws.amazon.com/eks/latest/userguide/cluster-auth.html
# testuser 사용자 생성
aws iam create-user --user-name testuser
# 사용자에게 프로그래밍 방식 액세스 권한 부여
aws iam create-access-key --user-name testuser
# testuser 사용자에 정책을 추가
aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser

aws sts get-caller-identity --query Arn 
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 
# 아래 실습 진행을 위해, kind(k8s) 삭제
~~~~kind delete cluster --name myk8s
mv ~/.kube/config ~/.kube/config.oldaws sts get-caller-identity --query Arn 
aws configureaws sts get-caller-identity --query Arn 
kubectl get node -v6
is ~/.kube
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
eksctl create iamidentitymapping --cluster $CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::$ACCOUNT_ID:user/testuserkubectl get cm -n kube-system aws-auth -o yaml
eksctl get iamidentitymapping --cluster $CLUSTER_NAME 
CLUSTER_NAME=myeks
aws eks update-kubeconfig --name $CLUSTER_NAME --user-alias testuser
cat ~/.kube/config 
kubectl ns default
kubectl get node -v6 
kubectl rbac-tool whoami 
kubectl edit cm -n kube-system aws-auth
eksctl get iamidentitymapping --cluster $CLUSTER_NAME 
kubectl get node -v6
kubectl api-resources -v5

# testuser IAM 맵핑 삭제
eksctl delete iamidentitymapping --cluster $CLUSTER_NAME --arn arn:aws:iam::$ACCOUNT_ID:user/testuser
# Get IAM identity mapping(s)
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
kubectl get cm -n kube-system aws-auth -o yaml
kubectl get node -v6
kubectl api-resources -v5
파드가 특정 IAM 역할로 Assume 할떄 토큰을 AWS에 전송하고, AWS는 토큰과 EKS IdP를 통해 해당 IAM 역할을 사용할수 있는지를 검증
출처 : https://github.com/awskrug/security-group/blob/main/files/AWSKRUG_2024_02_EKS_ROLE_MANAGEMENT.pdf
# 파드1 생성
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
terminationGracePeriodSeconds: 0
EOF
# 로그 확인
kubectl logs eks-iam-test1
# 파드1 삭제
kubectl delete pod eks-iam-test1
# 확인
kubectl get pod
kubectl describe pod


해당 내용은 Console에서도 확인이 가능하다 -link
kubectl delete pod eks-iam-test1
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
terminationGracePeriodSeconds: 0
EOF
kubectl get pod
kubectl exec -it eks-iam-test2 -- ls /var/run/secrets/kubernetes.io/serviceaccount
kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token ;echo

kubectl exec -it eks-iam-test2 -- aws s3 ls
권한이 존재하지 않아 다음과 같은 에러 발생

SA_TOKEN=$(kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo $SA_TOKEN

해당 값을 디코딩 할 경우 다음과 같은 데이터를 볼수 있다.


kubectl delete pod eks-iam-test2
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)
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl describe sa my-sa


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
terminationGracePeriodSeconds: 0
EOF
kubectl describe pod eks-iam-test
kubectl exec -it eks-iam-test3 -- ls /var/run/secrets/eks.amazonaws.com/serviceaccount
kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token ; echo

eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl exec -it eks-iam-test3 -- aws sts get-caller-identity --query Arn

kubectl get pod eks-iam-test3 -o json | jq -r '.spec.containers | .[].volumeMounts'c

kubectl get pod eks-iam-test3 -o json | jq -r '.spec.volumes[] | select(.name=="aws-iam-token")'
JWT 토큰이 담겨저 있고, exp, aud 속성이 추가 되어 있음

kubectl describe MutatingWebhookConfiguration pod-identity-webhook

IAM_TOKEN=$(kubectl exec -it eks-iam-test3 -- cat /var/run/secrets/eks.amazonaws.com/serviceaccount/token)
echo $IAM_TOKEN
JWT Token을 디코드 한 결과 Service Account my-sa 가 추가 되어 있음을 확인할수 있다.
{
"aud": [
"sts.amazonaws.com"
],
"exp": 1742121038,
"iat": 1742034638,
"iss": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/0A4C5694EDFA8ED215368B22641EDED6",
"jti": "bce359d1-431d-4ec6-969b-966900101e82",
"kubernetes.io": {
"namespace": "default",
"node": {
"name": "ip-192-168-3-242.ap-northeast-2.compute.internal",
"uid": "0b514978-b731-4492-9948-00fafcbea330"
},
"pod": {
"name": "eks-iam-test3",
"uid": "f26b44a2-f857-44c9-bde1-8069737d369f"
},
"serviceaccount": {
"name": "my-sa",
"uid": "595d5ce0-58e0-4212-9265-fea12b609836"
}
},
"nbf": 1742034638,
"sub": "system:serviceaccount:default:my-sa"
}
kubectl get pod eks-iam-test3 -o json | jq -r '.spec.containers | .[].env'

kubectl delete pod eks-iam-test3
eksctl delete iamserviceaccount --cluster $CLUSTER_NAME --name my-sa --namespace default
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl get sa
OWASP Kubernetes Top Ten 목록은 OWASP 재단이 주도하는 오픈 프로젝트로, 전 세계 보안 전문가, 개발자, 그리고 클라우드 네이티브 커뮤니티의 기여와 데이터를 기반으로 정한다.
다양한 조직의 실제 운영 경험, 보안 연구 결과, 커뮤니티 설문조사 및 취약점 분석 데이터를 종합해 가장 중요한 보안 리스크를 도출한다.