# EC2 인스턴스 모니터링 while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --output text | sort; echo "------------------------------" ;date; sleep 3; done (노드 서버 생성 2분후 노드로 kubectl 명령어로 조회가 가능하다.) while true ; do kubectl get nodes ;echo "-----------";date; sleep 2 ;done 콘솔에서 생성 확인 ec2 생성확인 노드 서버 생성 3분후에 노드로 kubectl 명령어로 조회가 가능하다. 3 (선택) CLI로 구축하기 # YAML 파일 다운로드 curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick5.yaml # CloudFormation 스택 배포 예시) aws cloudformation deploy --template-file eks-oneclick5.yaml --stack-name myeks --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' ClusterBaseName=myeks --region ap-northeast-2 4 CloudFormation 내용은? bastion ec2 2대를 만든다. 1대는 관리자용 1대는 신규 입사자용 6 기본설정 # default 네임스페이스 적용 kubectl ns default 7 # ExternalDNS MyDomain=<자신의 도메인> echo "export MyDomain=<자신의 도메인>" >> /etc/profile MyDomain=masterseo1.link echo "export MyDomain=masterseo1.link" >> /etc/profile MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text) echo $MyDomain, $MyDnzHostedZoneId curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f - 8 # AWS LB Controller helm repo add eks https://aws.github.io/eks-charts helm repo update 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 9 # 노드 IP 확인 및 PrivateIP 변수 지정 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 # 노드 보안그룹 ID 확인 NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values='*ng1*' --query "SecurityGroups[*].[GroupId]" --output text) aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.0/24 # 워커 노드 SSH 접속 for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done ssh ec2-user@$node $N1 ssh ec2-user@$node $N2 ssh ec2-user@$node $N3 <2> 프로메테우스 & 그라파나 설치(선택) // 여기서는 사용하지 않는다. 설치 안해도 된다. admin / prom-operator 1 대시보드 추천 15757 17900 15172 2 보안관련해 모니터링 시 사용 - 이번 실습에는 사용하지 않음. # 사용 리전의 인증서 ARN 확인 CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text` echo $CERT_ARN 3 # repo 추가 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts 4 # 파라미터 파일 생성 cat < monitor-values.yaml prometheus: prometheusSpec: podMonitorSelectorNilUsesHelmValues: false serviceMonitorSelectorNilUsesHelmValues: false retention: 5d retentionSize: "10GiB" 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 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' defaultRules: create: false kubeControllerManager: enabled: false kubeEtcd: enabled: false kubeScheduler: enabled: false alertmanager: enabled: false EOT # 배포 kubectl create ns monitoring helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.27.2 --set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' -f monitor-values.yaml --namespace monitoring 5 # Metrics-server 배포 kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 6 k get ingress -A (admin@myeks:default) [root@myeks-bastion ~]# k get ingress -A NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE monitoring kube-prometheus-stack-grafana alb grafana.masterseo1.link myeks-ingress-alb-879031103.ap-northeast-2.elb.amazonaws.com 80 15m monitoring kube-prometheus-stack-prometheus alb prometheus.masterseo1.link myeks-ingress-alb-879031103.ap-northeast-2.elb.amazonaws.com 80 15m 7 https://grafana.masterseo1.link/dashboards <3> EKS 인증/인가 기본 지식 1 .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을 사용하려면 여러 개의 콘텍스트 중 하나를 선택. 인증 관련 내용이 들어가 있다. cat .kube/config apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUtLS0tCg== server: https://192.168.100.10:6443 name: kubernetes contexts: - context: cluster: kubernetes namespace: default user: kubernetes-admin name: admin@k8s current-context: admin@k8s kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: Ka1gvQnZmaXc9PQ0FURS0tLS0tCg== client-key-data: LS0tLS1CRUdJTiBSQkFBS0NBUUVBbnZ5= 2 기본은 알아야 한다. 롤, 롤바인딩등 이해하자. https://brunch.co.kr/@topasvga/1877 실습 4-8. EKS보안-AWS인증, 인가 아래 내용은 주말 EKS 스터디하며 , 해당 내용을 참고하여 작성되었습니다. 인증은 로그인이다. 인가는 권한이다. 로그인이 되었다고, 다 사용할 수 있는 건 아니다. 권한이 이어야 한다. CLI로 brunch.co.kr/@topasvga/1877 https://brunch.co.kr/@topasvga/1878 실습4-9. K8S 인증,인가 아래 내용은 주말 EKS 스터디 하며 , 해당 내용을 참고하여 작성 되었습니다. 쿠버네티스 인증,인가에 대해 알아보자 <1> 쿠버네티스 인증,인가에 대해 알아보자 <2> K8S API 접근 <3> 네임 스페이 brunch.co.kr/@topasvga/1878 <4> EKS 인증/인가 1 사용자/애플리케이션 -> k8s 사용 시 ? 인증은 AWS IAM 사용 (쿠버네티스것은 사용하지 않음) 인가는 K8S RBAC 사용한다. // RBAC(Role-Based Access Control)란? RBAC는 역할에 따라 해당 역할이 할수 있는 권한을 제공하는것이다. 2 krew로 rbac관련 툴 설치하자. # 설치 kubectl krew install access-matrix rbac-tool rbac-view rolesum # Show an RBAC access matrix for server resources kubectl access-matrix # Review access to cluster-scoped resources kubectl access-matrix --namespace default # Review access to namespaced resources in 'default' # RBAC Lookup by subject (user/group/serviceaccount) name kubectl rbac-tool lookup # system:masters에 대해 알아보기 정보를 볼수 있는 명령어. cluster-admin role을 볼수 있다고 나온다. kubectl rbac-tool lookup system:masters SUBJECT | SUBJECT TYPE | SCOPE | NAMESPACE | ROLE +----------------+--------------+-------------+-----------+---------------+ system:masters | Group | ClusterRole | | cluster-admin kubectl rbac-tool lookup system:nodes # eks:node-bootstrapper kubectl rbac-tool lookup system:bootstrappers # eks:node-bootstrapper kubectl describe ClusterRole eks:node-bootstrapper # RBAC List Policy Rules For subject (user/group/serviceaccount) name kubectl rbac-tool policy-rules kubectl rbac-tool policy-rules -e '^system:.*' # Generate ClusterRole with all available permissions from the target cluster kubectl rbac-tool show # Shows the subject for the current context with which one authenticates with the cluster kubectl rbac-tool whoami {Username: "kubernetes-admin", UID: "aws-iam-authenticator:911283.....:AIDA5ILF2FJ......", Groups: ["system:masters", "system:authenticated"], Extra: {accessKeyId: ["AKIA5ILF2FJ....."], arn: ["arn:aws:iam::911283....:user/admin"], canonicalArn: ["arn:aws:iam::911283....:user/admin"], principalId: ["AIDA5ILF2FJ....."], sessionName: [""]}} # Summarize RBAC roles for subjects : ServiceAccount(default), User, Group kubectl rolesum -h kubectl rolesum aws-node -n kube-system kubectl rolesum -k User system:kube-proxy kubectl rolesum -k Group system:masters (admin@myeks:default) [root@myeks-bastion ~]# kubectl rolesum -k Group system:masters -------------------------------------------------- Group: system:masters Policies: • [CRB] */cluster-admin ⟶ [CR] */cluster-admin Resource Name Exclude Verbs G L W C U P D DC *.* [*] [-] [-] ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ # [터미널1] A tool to visualize your RBAC permissions kubectl rbac-view ---------------------------------------------------------------------- INFO[0000] Getting K8s client INFO[0000] serving RBAC View and http://localhost:8800 ## 이후 해당 작업용PC 공인 IP:8800 웹 접속 echo -e "RBAC View Web http://$(curl -s ipinfo.io/ip):8800" RBAC View Web http://43.201.29.88:8800 <5> Amazon EKS 인증 인가 순서 https://youtu.be/bksogA-WXv8?t=669 https://youtu.be/bksogA-WXv8?t=669 순서 ? 1 kubectl 명령을 내리면 ? k get nodes 2 사용자가 EKS클러스터에 접근해 놓은 설정 즉, 사용자의 Kubeconfig설정 정보에 정의된 AWS Get-Tocken명령을 통해 AWS EKS Endpoint로 요청을 하게 된다. 응답으로 토큰 값이 전달 된다. EKS get-tocken = EKS Service endpoint(STS)에 토큰 요청 한다. 3 Pre-Signed URL 을 Bearer Tocken으로 컨트롤 플레인 API Server에 날린다. Bearer Tocken = 인증 타입으로 JWT 혹은 OAuth에 대한 토큰을 사용한다. (RFC 6750) basic인증 타입은 사용자 아이디와 암호를 base64 인코딩한 값을 토큰으로 사용한다. 4 API를 통해 Token Review 를 통해 Webhook 으로 전달 되고, AWS IAM 인증으로 처리한다. aws-iam-authenticator server EKS에서 '사용자 인증을 통합'하기위해 IAM인증으로 처리한다. sts GetCallerIdentity 요청 한다. 응답은 허락 한다. IAM은 인증만 있다. 5 인가는 쿠버네티스의 RBAC에서 처리해야 한다. IAM user나 Role을 쿠버네티스의 User나 Group으로 매핑하는 Config MAP인 'AWS Auth Config'에서 처리한다. 그룹을 봐서 처리한다. 6 IAM role과 매핑된 IAM-admin이라는 username과 System:master라고 하는 그룹을 리턴한다. K8S RBAC으로 인가를 처리한다. Authorization (인가) <6> kubectl 명령 → aws eks get-token 과정 보기 (선택) 1 kubectl 명령 → aws eks get-token -> EKS Service endpoint(STS)에 토큰 요청 2 AWS CLI 버전 1.16.156 이상에서는 별도 aws-iam-authenticator 설치 없이 aws eks get-token으로 사용 가능 https://docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html 3 # sts caller id의 ARN 확인 aws sts get-caller-identity --query Arn "arn:aws:iam::<자신의 Account ID>:user/admin" 4 # kubeconfig 정보 확인 cat ~/.kube/config | yh ... - name: admin@myeks.ap-northeast-2.eksctl.io user: exec: apiVersion: client.authentication.k8s.io/v1beta1 args: - eks - get-token - --output - json - --cluster-name - myeks - --region - ap-northeast-2 command: aws env: - name: AWS_STS_REGIONAL_ENDPOINTS value: regional interactiveMode: IfAvailable provideClusterInfo: false # Get a token for authentication with an Amazon EKS cluster. 토큰을 요청한다. # This can be used as an alternative to the aws-iam-authenticator. 예전 버전 사용시 방법. aws eks get-token help 5 STS (Security Token Service) 토근을 받아온다!! 임시 보관이다. 장기 보관이 아니다. cloudtail에 로그가 남는다. # 임시 보안 자격 증명(토큰)을 요청 : expirationTimestamp 시간경과 시 토큰 재발급됨 aws eks get-token --cluster-name $CLUSTER_NAME | jq aws eks get-token --cluster-name $CLUSTER_NAME | jq -r '.status.token' 6 토큰 내용을 확인 가능하다. pre-signed URL이라고 하는데 디버그 사이트에서 내용 확인 가능하다. 토큰을 넣어서 payload 부분 확인하자. https://jwt.io/ 5 payload 부분을 디코드하면 ? https://url-decode.com/ 내용 ? action = GetcallerIdentity 등이 있다. 6 EKS API에게 전달 한다. 사용자에 대한 인증처리를 webhook 으로 요청한다. kubectl api-resources | grep authentication Token Reviews ? 사용자에 대한 인증을 처리할수 있다. Webhook token authenticator 은 aws-iam-authenticator 를 사용 한다. Cloudtrail 가면 GetCallerIdentity 사용 확인 가능. https://ap-northeast-2.console.aws.amazon.com/cloudtrail/home?region=ap-northeast-2#/events?EventName=GetCallerIdentity 7 AWS STS 가 AWS IAM 서비스 이다. 사용자 유저가 맞는지 문의한다. 맞다고 응답을 한다. 인증 완료. User/role에 대한 ARN반환을 한다. 8 이제 인가 처리를 해야 한다. aws-auth컨피그맵에서 IAM사용자, 역할ARN, K8S오브젝트 권한 확인한후 K8S 인가 허가를 하면 동작한다. # Webhook api 리소스 확인 kubectl api-resources | grep Webhook mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration // validatingwebhookconfigurations 에서 통과를 한다. 9 # validatingwebhookconfigurations 리소스 확인 kubectl get validatingwebhookconfigurations NAME WEBHOOKS AGE eks-aws-auth-configmap-validation-webhook 1 50m vpc-resource-validating-webhook 2 50m aws-load-balancer-webhook 3 8m27s // eks-aws-auth-configmap-validation-webhook 이 있다. 10 // aws-auth-configmap 안에 내용이 kubectl get validatingwebhookconfigurations eks-aws-auth-configmap-validation-webhook -o yaml | kubectl neat | yh # aws-auth 컨피그맵 확인 kubectl get cm -n kube-system aws-auth -o yaml | kubectl neat | yh apiVersion: v1 kind: ConfigMap metadata: name: aws-auth namespace: kube-system data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::91128.....:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1OS1WSTV0YB9X username: system:node:{{EC2PrivateDNSName}} 11 # 아래 생략(추정), ARN은 EKS를 설치한 IAM User 만약 있을경우 실수로 삭제 시 복구 불가능하여 생략 됨. mapUsers: | - groups: - system:masters userarn: arn:aws:iam::111122223333:user/admin username: kubernetes-admin 12 # EKS 설치한 IAM User 정보 >> system:authenticated는 어떤 방식으로 추가가 되었는지 궁금??? kubectl rbac-tool whoami 그룹의 권한을 확인한다!! {Username: "kubernetes-admin", UID: "aws-iam-authenticator:9112834...:AIDA5ILF2FJIR2.....", Groups: ["system:masters", "system:authenticated"], ... 13 # 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 14 # system:masters 그룹이 사용 가능한 클러스터 롤 확인 : cluster-admin kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin Name: cluster-admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: cluster-admin Subjects: Kind Name Namespace ---- ---- --------- Group system:masters 15 # cluster-admin 의 PolicyRule 확인 : 모든 리소스 사용 가능! kubectl describe clusterrole cluster-admin Name: cluster-admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- *.* [] [] [*] [*] [] [*] 16 # 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 <7> 예제 - 새로 입사한 개발자가 사용하도록 제공하자 1 [myeks-bastion] testuser 사용자 생성 aws iam create-user --user-name testuser 2 # 사용자에게 프로그래밍 방식 액세스 권한 부여 aws iam create-access-key --user-name testuser { "AccessKey": { "UserName": "testuser", "AccessKeyId": "AKIA5ILF2##", "Status": "Active", "SecretAccessKey": "TxhhwsU8##", "CreateDate": "2023-05-23T07:40:09+00:00" } } // accesskey 와 secret key를 메모 한다. 3 # testuser 사용자에 정책을 추가 - admin 권한 추가한다. aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser 4 확인 # get-caller-identity 확인 aws sts get-caller-identity --query Arn "arn:aws:iam::476286675138:user/admin" 5 # 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 ---------------------------------------------------------------------- | DescribeInstances | +---------------------+-----------------+-----------------+----------+ | InstanceName | PrivateIPAdd | PublicIPAdd | Status | +---------------------+-----------------+-----------------+----------+ | myeks-ng1-Node | 192.168.3.249 | 52.79.228.63 | running | | myeks-ng1-Node | 192.168.2.164 | 15.164.240.22 | running | | myeks-bastion-EC2 | 192.168.1.100 | 43.201.29.88 | running | | myeks-bastion-EC2-2| 192.168.1.200 | 43.201.147.2 | running | | myeks-ng1-Node | 192.168.1.121 | 3.36.73.51 | running | +---------------------+-----------------+-----------------+----------+ 6 2번 서버에 로그온 하자 ~ [myeks-bastion-2] testuser 자격증명 설정 및 확인 # get-caller-identity 확인 >> 왜 안될까요? aws sts get-caller-identity --query Arn 7 # testuser 자격증명 설정 방금 위에서 만든 키를 입력한다. aws configure AWS Access Key ID [None]: AKIA5ILF2F... AWS Secret Access Key [None]: ePpXdhA3cP.... Default region name [None]: ap-northeast-2 # get-caller-identity 확인 aws sts get-caller-identity --query Arn "arn:aws:iam::476286675138:user/testuser" 8 # kubectl 시도 >> testuser도 AdministratorAccess 권한을 가지고 있는데, 실패 이유는? kubectl get node -v6 ls ~/.kube 인증 정보가 없다. 4 test user를 그룹으로 매핑해야 한다!!! 클러스터 롤을 사용할수 있도록 하는 것이다. 5 1번 EC2에서 권한을 추가해준다. [myeks-bastion] testuser에 system:masters 그룹 부여로 EKS 관리자 수준 권한 설정 # 방안1 : eksctl 사용 >> iamidentitymapping 실행 시 aws-auth 컨피그맵 작성해줌 # Creates a mapping from IAM role or user to Kubernetes user and groups. # 그룹을 매핑한다. aws-auth 설정을 해야 한다. eksctl create iamidentitymapping --cluster $CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::$ACCOUNT_ID:user/testuser // testuser를 쿠버네티스의 group system:masters 와 매핑하라~ arn은 위와 같다. 6 잘 설정 되었는지 configmap 확인해보자~ 여기에 설정된 role을 사용할수 있다. kubectl get cm -n kube-system aws-auth -o yaml | kubectl neat | yh admin@myeks:default) [root@myeks-bastion ~]# kubectl get cm -n kube-system aws-auth -o yaml | kubectl neat | yh apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::476286675138:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1GEQ51CT063N2 username: system:node:{{EC2PrivateDNSName}} mapUsers: | - groups: - system:masters userarn: arn:aws:iam::476286675138:user/testuser username: testuser kind: ConfigMap metadata: name: aws-auth namespace: kube-system (선택) # 방안2 : 아래 edit로 mapUsers 내용 직접 추가! kubectl edit cm -n kube-system aws-auth --- apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ username: system:node:{{EC2PrivateDNSName}} mapUsers: | - groups: - system:masters userarn: arn:aws:iam::911283464785:user/testuser username: testuser ... # 확인 : 기존에 있는 role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-YYYYY 는 어떤 역할/동작을 하는 걸까요? eksctl get iamidentitymapping --cluster $CLUSTER_NAME ARN USERNAME GROUPS ACCOUNT arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes arn:aws:iam::911283464785:user/testuser testuser system:masters 7 2번 서버에서 업데이트 해서 파일을 만든다. testuser가 사용해야 하는 파일이다. [myeks-bastion-2] testuser kubeconfig 생성 및 kubectl 사용 확인 # testuser kubeconfig 생성 >> aws eks update-kubeconfig 실행이 가능한 이유는? 설정 후 약간의 적용 시간 필요 aws eks update-kubeconfig --name $CLUSTER_NAME --user-alias testuser ------------------------------------------- Added new context testuser to /home/ec2-user/.kube/config // 혹 아래와 같은 에러가 뜨면 aws configure가 제대로 안된것이다. 설정 파일을 지우고 다시 설정하자. 에러 내용 Unable to parse config file: /root/.aws/credentials rm -rf /root/.aws/credentials aws configure 6 # 첫번째 bastic ec2의 config와 비교해보자 cat ~/.kube/config | yh - context: cluster: arn:aws:eks:ap-northeast-2:476286675138:cluster/myeks user: testuser name: testuser current-context: testuser kind: Config preferences: {} users: - name: testuser user: exec: apiVersion: client.authentication.k8s.io/v1beta1 args: - --region - ap-northeast-2 - eks - get-token - --cluster-name - myeks - --output - json command: aws 7 [myeks-bastion-2] 에서 신규 개발자가 확인 # kubectl 사용 확인 kubectl ns default kubectl get node -v6 -------------------------------------------------------------------------- NAME STATUS ROLES AGE VERSION ip-192-168-1-121.ap-northeast-2.compute.internal Ready 131m v1.24.13-eks-0a21954 ip-192-168-2-164.ap-northeast-2.compute.internal Ready 131m v1.24.13-eks-0a21954 ip-192-168-3-249.ap-northeast-2.compute.internal Ready 131m v1.24.13-eks-0a21954 잘 된다. 8 (기타) # rbac-tool 후 확인? >> 기존 계정과 비교해보자 >> system:authenticated 는 system:masters 설정 시 따라온다. kubectl krew install rbac-tool && kubectl rbac-tool whoami {Username: "testuser", UID: "aws-iam-authenticator:911283464785:AIDA5ILF2FJIV65KG6RBM", Groups: ["system:masters", "system:authenticated"], Extra: {accessKeyId: ["AKIA5ILF2FJIZJUZSG4D"], arn: ["arn:aws:iam::911283464785:user/testuser"], canonicalArn: ["arn:aws:iam::911283464785:user/testuser"], ... 9 (선택) 권한 조정해 테스트해볼까? [myeks-bastion] testuser 의 Group 변경(system:masters → system:authenticated)으로 RBAC 동작 확인 10 (선택) # 방안2 : 아래 edit로 mapUsers 내용 직접 수정 system:authenticated kubectl edit cm -n kube-system aws-auth ... # 확인 eksctl get iamidentitymapping --cluster $CLUSTER_NAME // system:authenticated 로 변경됨. [myeks-bastion-2] testuser kubectl 사용 확인 # 시도 kubectl get node -v6 안됨. api 리소스를 볼수 있는 권한은 있다. kubectl api-resources -v5 이건 됨. // IAM의 인증은 처리 되었지만, RBAC에서 차단된것이다. 11 퇴사 했을 경우 ? [myeks-bastion]에서 # 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 | yh EKS 설치하는 사용자는 기본으로 권한이 들어간다. auth 설정에서는 보안상 12 [myeks-bastion-2] testuser kubectl 사용 확인 # 시도 kubectl get node -v6 kubectl api-resources -v5 둘다 안됨. 13 config 샘플 https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html <8> 노드에 매핑될 롤 확인과 의미 노드가 사용하는 EC2 인스턴스 프로파일이 매핑되어져 있어 되는 것이다. 1 # 노드에 호스트이름 확인 for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done 2 # 노드에 STS ARN 정보 확인 : Role 뒤에 인스턴스 ID! 노드에서 자격 증명이 된다 !!! 왜? 노드가 사용하는 EC2 인스턴스 프로파일이 매핑되어져 있어 되는 것이다. for node in $N1 $N2 $N3; do ssh ec2-user@$node aws sts get-caller-identity --query Arn; done "arn:aws:sts::911283464785:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ/i-07c9162ed08d23e6f" "arn:aws:sts::911283464785:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ/i-00d9d24c0af0d6815" "arn:aws:sts::911283464785:assumed-role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-LHQ7DWHQQRZJ/i-031e672f89572abe8" 3 # aws-auth 컨피그맵 확인 >> system:nodes 와 system:bootstrappers 의 권한은 어떤게 있는지 찾아보세요! # username 확인! 인스턴스 ID? EC2PrivateDNSName? kubectl describe configmap -n kube-system aws-auth ... mapRoles: ---- - groups: - system:nodes - system:bootstrappers rolearn: arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng-f6c38e4-NodeInstanceRole-1OU85W3LXHPB2 username: system:node:{{EC2PrivateDNSName}} ... # Get IAM identity mapping(s) eksctl get iamidentitymapping --cluster $CLUSTER_NAME ARN USERNAME GROUPS ACCOUNT arn:aws:iam::911283464785:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1OS1WSTV0YB9X system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes ... AWS자격 증명을 가진 사용자가, 쿠버네티스 리소스를 사용할떄 사용하는 것이다. 4 별도의 자격 증명 없이도 노드에서 사용 가능하다. iamidentitymapping ? AWS 자격증명을 가진 사용자가 쿠버네티스의 리소스를 쓸때 매핑되는 것이다. <9> 샘플 테스트 파드에서도 된다 ! 노드에 권한이 부여 되어 있어서 가능한것이다. https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-docker.html https://hub.docker.com/r/amazon/aws-cli 1 pod 2개 생성 pod에서 자격증명 안했는데 되는 이유? 2 # awscli 파드 생성 cat <> 별도 IAM 자격 증명이 없는데 어떻게 가능한 것일까요? 노드에 권한이 부여 되어 있어서 가능한것이다. # > 최소권한부여 필요!!! >>> 보안이 허술한 아무 컨테이너나 탈취 시, IMDS로 해당 노드의 IAM Role 사용 가능! pod에서 된다. pod에 자격증명을 안했는데 된다. kubectl exec -it $APODNAME1 -- aws ec2 describe-instances --region ap-northeast-2 --output table --no-cli-pager kubectl exec -it $APODNAME2 -- aws ec2 describe-vpcs --region ap-northeast-2 --output table --no-cli-pager 6 # EC2 메타데이터 확인 : IDMSv1은 Disable, IDMSv2 활성화 상태, IAM Role - 링크 kubectl exec -it $APODNAME1 -- bash 7 ----------------------------------- 아래부터는 파드에 bash shell 에서 실행 curl -s http://169.254.169.254/ -v ... 8 # Token 요청 curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" ; echo curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" ; echo # Token을 이용한 IMDSv2 사용 TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") echo $TOKEN curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/ ; echo curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/ ; echo curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/ ; echo 9 # 위에서 출력된 IAM Role을 아래 입력 후 확인 curl -s -H "X-aws-ec2-metadata-token: $TOKEN" –v http://169.254.169.254/latest/meta-data/iam/security-credentials/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1DC6Y2GRDAJHK { "Code" : "Success", "LastUpdated" : "2023-05-27T05:08:07Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIA52IYJHP", "SecretAccessKey" : "rkeeMrjCpiB4h+9XJ", "Token" : "IQoJb3JB2AOL4iA3TTuK+U2o+pHWEHRQOVh3p4=", "Expiration" : "2023-05-27T11:09:07Z" } ## 출력된 정보는 AWS API를 사용할 수 있는 어느곳에서든지 Expiration 되기전까지 사용 가능 10 해당 정책(권한)을 사용하게 된다!! 보안에 주의. access , secret가 노출 됨. POD가 노드에 있는 역할을 다 쓸수 있다. 11 # 파드에서 나오기 exit 12 콘솔에서 확인 노드에 있는 역할울 파드에서 사용할수 있게 된다. IMDS 취약점은 노드의 정책 권한을 파드도 다 사용할수 있게 되어 취약해진다.