brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Jun 10. 2023

EKS 8탄-15. EKS 자동화- ACK-15/17

EKS 8탄 - 7주차

목표

EKS에서 AWS리소스를 만들수 있는 ACK 이해하자.

ACK 알아보자 = AWS Controllers for Kubernetes = 쿠버네티스용 Cloudformation,테라폼?

Flux CD로 Git허브의 자원을 EKS에 배포해보자~

Flux CD를 알아보자 = git을 소스로  쿠버네티스에 배포하는 툴이다.



이론 1시간

실습 1시간

이론 1시간 설명후 바로 실습 진행합니다.



<1> EKS에서 AWS리소스를 만들수 있는 ACK

<2> EKS 생성, # ExternalDNS  , # (선택) kube-ops-view 설치

<3> 프로메테우스,그라파나 ALB

<4> ACK 개요 - aws서비스 리소스를 k8s에서 직접 정의

<5> ACK S3 Controller 설치 with Helm - 실습1

<6> IRSA 생성 - 권장 정책 AmazonS3FullAccess

<7> S3 버킷 생성, 업데이트, 삭제

<8> ACK EC2-Controller 설치 - 실습2

<9> VPC, Subnet 생성 및 삭제

<10> Create a VPC Workflow - 실습3

<11> 퍼블릭 서브넷에 인스턴스 생성

<12> 프라이빗 서브넷에 인스턴스 생성 (선택)

<13> RDS 생성 - 실습4 (선택)

<14> RDS for MariaDB 생성 및 삭제 

<15> 개인 정리




<1> EKS에서 AWS리소스를 만들수 있는 ACK


ACK는 쿠버네티스를 통한 자동화툴이다.

2023년 12월 현재 아직은 모든 리소스를 만들수 있지는 않다.

따라서 코드로 모든것을 관리할수 있는 수준은 아니다. 50점.

하지만, 일부 AWS리소스를 잘 만들수 있다. 

1회성으로 AWS리소스 VPC,S3,EC2를 빠르게 만들떄 사용하면 좋을거 같다.



1

ACK ??

kubectl로 AWS 자원 VPC, s3, vpc , ec2등을 만들어보자.








<2> EKS 생성, # ExternalDNS  , # (선택) kube-ops-view 설치


1

준비 ?


aws console접속

https://console.aws.amazon.com/



서울리전

Stack name

myeks



EC2 키페어 , 액세스/시크릿키 필요

ec2-keypair = aws-topas3-06-26-seoul

access-key / secret-key  = aws-topas3-06-26-iam 


route53에 설정된 도메인도 1개 필요




cloudformation 


//  디폴트로 생성한다.

// 노드수를 줄이면 에러가 난다.



30분 걸림


우선 쿠버네티스 배포부터~  타이머 

https://vclock.kr/timer/#countdown=00:02:00&enabled=0&seconds=0&sound=xylophone&loop=1




2

(선택) CLI 로 생성시


# YAML 파일 다운로드

curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick6.yaml


# CloudFormation 스택 배포

예시) aws cloudformation deploy --template-file eks-oneclick6.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


# CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력

aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text


# 작업용 EC2 SSH 접속

ssh -i ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)



3

bastion-ec2 에 로그온해서 master, node 서버들이 만들어지는지 모니터링 하자.


# 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




4

5분후 - 콘솔에서 생성 확인

ec2 생성확인 , ec2 생성하고 3분후에 노드들 사용이 가능하다.

(노드 서버 생성 3분후 노드로  kubectl 명령어로 조회가 가능하다.)


while true ; do kubectl get nodes ;echo "-----------";date; sleep 2 ;done



5

# default 네임스페이스 적용

kubectl ns default



6

다른 터미널에서 모니터링 

watch -d kubectl get ing,svc,pods -A



# (옵션) context 이름 변경

NICK=<각자 자신의 닉네임>

NICK= topasvga

kubectl ctx

kubectl config rename-context admin@myeks.ap-northeast-2.eksctl.io $NICK



7

# ExternalDNS  , # (선택) kube-ops-view 설치


https://brunch.co.kr/@topasvga/3241





MyDomain=<자신의 도메인>

echo "export MyDomain=<자신의 도메인>" >> /etc/profile

masterseo1.link


MyDomain=taeho11.co.kr

echo "export MyDomain=taeho11.co.kr" >> /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

# (선택) kube-ops-view 설치


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 env.TZ="Asia/Seoul" --namespace kube-system


kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'


kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"


echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"



9

# 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



10

# 노드 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



11

# 노드 보안그룹 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



12

ssh ec2-user@$N3





<3> 프로메테우스,그라파나 ALB


뒤에서 Weave GitOps  대시보드도 같은 ALB 사용한다.

필수로 만들자 ~

External DNS도 설치하자.

Cube Opsview도 설치하자.


https://brunch.co.kr/@topasvga/3241



1

# 사용 리전의 인증서 ARN 확인

CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`

echo $CERT_ARN



2

# repo 추가

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts




3

# 파라미터 파일 생성


cat <<EOT > 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



4

# 배포


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

// ALB ADDRSS가 확인 되어야 한다!!



Every 2.0s: kubectl get ing,svc,pods -A                                                                                                                                                      Wed Jun 28 17:16:37 2023

NAMESPACE    NAME                                                         CLASS   HOSTS                      ADDRESS                                                        PORTS   AGE


monitoring   ingress.networking.k8s.io/kube-prometheus-stack-grafana      alb     grafana.taeho11.co.kr      myeks-ingress-alb-781305233.ap-northeast-2.elb.amazonaws.com   80      88s


monitoring   ingress.networking.k8s.io/kube-prometheus-stack-prometheus   alb     prometheus.taeho11.co.kr   myeks-ingress-alb-781305233.ap-northeast-2.elb.amazonaws.com   80      88s

NAMESPACE     NAME                                   



6

# Metrics-server 배포


kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml




7

도메인으로 접속하라.

ALB로는 접속 안된다.


grafana.taeho11.co.kr


prometheus.taeho11.co.kr






<4> ACK 개요 - aws서비스 리소스를 k8s에서 직접 정의


AWS Controllers for Kubernetes (ACK) 

Kubernetes에서 AWS 서비스를 직접 관리할 수 있는 새로운 도구입니다.

ACK로 쿠버네티스에 익숙한 사용자가 AWS 리소스를 kubectl로 만들게 지원한다.

2023년 6월 현재 몇몇 생성기능은 제공하나 서비스로 사용할 만큼 모두 개발되진 않았다.


1

ACK로 쿠버네티스에 익숙한 사용자가 AWS 리소스를 kubectl로 만들게 지원한다.

쿠버네티스에는 익숙한데 AWS에 익숙한 엔지니어가 있는경우.

사용자는 kubectl (쿠버네티스 api) 를 사용하여 AWS S3 버킷을 생성 할 수 있다.

쿠버네티스 api 는 ack-s3-controller 에 요청을 전달하고, ack-s3-controller(IRSA)이 AWS S3 API 를 통해 버킷을 생성하게 됩니다

aws서비스 리소스를 k8s에서 직접 정의하고 사용 할 수 있음

아직은 상용으로 사용하기에는 20% 부족하다.

참고로 테스트해보자.



2

ACK 작동 방식


1) 아티팩트 모음(바이너리, 컨테이너 이미지, Helm 차트 등)을 생성하고 유지 관리

2) 설치 및 구성할 하나 이상의 ACK 컨트롤러를 선택

3) AWS 리소스를 나타내는 사용자 지정 리소스 (Kubernetes)를 생성

4) 3단계에서 정의한 사용자 지정 리소스를 기반으로 컨트롤러는 AWS API를 사용하여 기본 AWS 리소스를 생성, 업데이트 또는 삭제합니다.


출처

https://aws.amazon.com/ko/blogs/containers/aws-controllers-for-kubernetes-ack/



각 서비스별 컨트롤러가 필요하다.

ack-s3-controller  , ack-rds-controller 등이 설정을 반영하여 AWS에 배포한다.

권한 IRSA는 필요하다.




3

지원되는 AWS  서비스들

GA된 서비스들만 이용하세요.  17개. EKS도 GA되어 있음

프리뷰(평가판)은 조금 있다가. 10개.


참고 사이트

https://aws-controllers-k8s.github.io/community/docs/community/services/

https://www.megazone.com/techblog_aws-controllers-for-kubernetes-ack/



4

순서?

컨트롤러 생성 -  AWS 현재 상태가 원하는 상태와 같은지 확인하는 컨트롤러.

IRSA 권한 생성

S3 리소스 생성




<5> ACK S3 Controller 설치 with Helm - 실습1


Helm을 통해 관리한다.


1

자료

https://aws-controllers-k8s.github.io/community/docs/user-docs/install/


AWS Controllers for Kubernetes (ACK)  최근 버전으로 AWS 저장소에서 다운 받아서 진행하는 것이다.

https://gallery.ecr.aws/aws-controllers-k8s


https://github.com/aws-controllers-k8s/s3-controller



2

# 서비스명 변수 지정

cd

export SERVICE=s3


# helm 차트 다운로드

기본 버지니아라 다운받아 수정함.


#aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws



export RELEASE_VERSION=$(curl -sL https://api.github.com/repos/aws-controllers-k8s/$SERVICE-controller/releases/latest | grep '"tag_name":' | cut -d'"' -f4 | cut -c 2-)


helm pull oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart --version=$RELEASE_VERSION


tar xzvf $SERVICE-chart-$RELEASE_VERSION.tgz



# helm chart 확인

tree ~/$SERVICE-chart


// CRD = 사용자 리소스 정의 = CustomResourceDefinition



# ACK S3 Controller 설치 ?

# ack-sysetm 네임스페이스에  설치한다.


export ACK_SYSTEM_NAMESPACE=ack-system

export AWS_REGION=ap-northeast-2


helm install --create-namespace -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller --set aws.region="$AWS_REGION" ~/$SERVICE-chart





3

# 설치 확인


핼름 차트 확인

helm list --namespace $ACK_SYSTEM_NAMESPACE

----------------------------------------------------------------------------

NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION

ack-s3-controller       ack-system      1               2023-06-26 17:49:51.891502178 +0900 KST deployed        s3-chart-1.0.4  1.0.4



파드 확인= 컨트롤러 

kubectl -n ack-system get pods

-----------------------------------------------------------------------------

NAME                                          READY   STATUS    RESTARTS   AGE

ack-s3-controller-s3-chart-7c55c6657d-pntsv   1/1     Running   0          3m55s




crd도 설치된다.

kubectl get crd | grep $SERVICE

buckets.s3.services.k8s.aws                  2022-04-24T13:24:00Z



전체 보기

디플로이먼트, 리플리카세트, 파드

kubectl get all -n ack-system

(aws-topas3-06-26-iam@myeks:default) [root@myeks-bastion ~]# kubectl get all -n ack-system


NAME                                              READY   STATUS    RESTARTS   AGE

pod/ack-s3-controller-s3-chart-7c55c6657d-pntsv   1/1     Running   0          5m25s


NAME                                         READY   UP-TO-DATE   AVAILABLE   AGE

deployment.apps/ack-s3-controller-s3-chart   1/1     1            1           5m25s


NAME                                                    DESIRED   CURRENT   READY   AGE

replicaset.apps/ack-s3-controller-s3-chart-7c55c6657d   1         1         1       5m25s





kubectl describe sa -n ack-system ack-s3-controller


확인해보면 권한은 없다.

IRSA권한이 필요하다. 추가 하자.





<6> IRSA 생성 - 권장 정책 AmazonS3FullAccess


쿠버네티스 Pod등에서 명령을 내리려면 IRSA가 필요하다.


1

# 서비스 어카운트도 만들고 , role 도 추가한다.

# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account


eksctl create iamserviceaccount --name ack-$SERVICE-controller --namespace ack-system --cluster $CLUSTER_NAME --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3FullAccess`].Arn' --output text) --override-existing-serviceaccounts --approve


//   --override-existing-serviceaccounts   기존에 서비스 어카운트가 있더라도 겹쳐쓴다.


(1분)




2

# 확인 >> 웹 관리 콘솔에서 CloudFormation Stack >> IAM Role 확인



eksctl get iamserviceaccount --cluster $CLUSTER_NAME

NAMESPACE       NAME                            ROLE ARN

ack-system      ack-s3-controller  arn:aws:iam::eks-addon-iamserviceaccount-ack-sys-Role1

kube-system     aws-load-balancer-controller    arn:aws:ia-role



# Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod.


kubectl get sa -n ack-system

NAME                SECRETS   AGE

ack-s3-controller   0         12m

default             0         12m




kubectl describe sa ack-$SERVICE-controller -n ack-system


// Annotartions에 iamserviceaccout-ack-sys-Role1이 들어감.

Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::319485572629:role/eksctl-myeks-addon-iamserviceaccount-ack-sys-Role1-I3NSG2Z9L5ZB

                     meta.helm.sh/release-name: ack-s3-controller

                     meta.helm.sh/release-namespace: ack-system





3

# Restart ACK service controller deployment using the following commands.

재시작해서 배포한다.

파드 1개가 업데이트 됨.


kubectl -n ack-system rollout restart deploy ack-$SERVICE-controller-$SERVICE-chart

deployment.apps/ack-s3-controller-s3-chart restarted



4

# IRSA 적용으로 Env, Volume 추가 확인

kubectl describe pod -n ack-system -l k8s-app=$SERVICE-chart





<7> S3 버킷 생성, 업데이트, 삭제


컨트롤러와 권한(IRSA)이 필요하다~


1

# [터미널1] 

모니터링

# 기존 s3 버킷 존재


watch -d aws s3 ls

2023-06-22 10:25:12 cf-templates-1geibglsenwfm-ap-northeast-2

2023-06-26 16:40:08 cf-templates-1geibglsenwfm-us-east-1



2

# S3 버킷 생성을 위한 설정 파일 생성

// 유일해야 하는 버킷이라 이름을  어카운트 id 를 가지고 작업 한다.


export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)

export BUCKET_NAME=my-ack-s3-bucket-$AWS_ACCOUNT_ID



3

read -r -d '' BUCKET_MANIFEST <<EOF

apiVersion: s3.services.k8s.aws/v1alpha1

kind: Bucket

metadata:

  name: $BUCKET_NAME

spec:

  name: $BUCKET_NAME

EOF


echo "${BUCKET_MANIFEST}" > bucket.yaml

cat bucket.yaml | yh



4

# S3 버킷 생성


kubectl create -f bucket.yaml

2023-06-26 18:11:18 my-ack-s3-bucket-319485572629



bucket.s3.services.k8s.aws/my-ack-s3-bucket-<my account id> created



5

// 콘솔에서 확인하자.



6

# S3 버킷명 확인

aws s3 ls



# kubectl로 확인 가능하다 !!!


kubectl get buckets

NAME                            AGE

my-ack-s3-bucket-319485572629   66s




kubectl describe bucket/$BUCKET_NAME | head -6

Name:         my-ack-s3-bucket-<my account id>

Namespace:    default

Labels:       <none>

Annotations:  <none>

API Version:  s3.services.k8s.aws/v1alpha1

Kind:         Bucket



aws s3 ls | grep $BUCKET_NAME

2023-06-26 18:11:18 my-ack-s3-bucket-319485572629





7

# S3 버킷 업데이트 : 태그 정보 입력


read -r -d '' BUCKET_MANIFEST <<EOF

apiVersion: s3.services.k8s.aws/v1alpha1

kind: Bucket

metadata:

  name: $BUCKET_NAME

spec:

  name: $BUCKET_NAME

  tagging:

    tagSet:

    - key: myTagKey

      value: myTagValue

EOF


echo "${BUCKET_MANIFEST}" > bucket.yaml



8

콘솔에서  S3 태그 확인

태그가 2개 있다.



# S3 버킷 설정 업데이트 실행 :

kubectl apply -f bucket.yaml



# S3 버킷 업데이트 확인 

tag를 추가한다.

경고 나오는건 무시해도 된다.

콘솔에서 태그 추가 확인하자.

태그 같은 필요한 부분만 추가 가능하다.



kubectl describe bucket/$BUCKET_NAME | grep Spec: -A5

Spec:

  Name:  my-ack-s3-bucket-<my account id>

  Tagging:

    Tag Set:

      Key:    myTagKey

      Value:  myTagValue




9

# S3 버킷 삭제

# kubectl로 삭제가 가능하다.


kubectl delete -f bucket.yaml

bucket.s3.services.k8s.aws "my-ack-s3-bucket-319485572629" deleted




# verify the bucket no longer exists

kubectl get bucket/$BUCKET_NAME

aws s3 ls | grep $BUCKET_NAME



10

삭제

https://aws-controllers-k8s.github.io/community/docs/user-docs/cleanup/



컨트롤러 삭제


# helm uninstall

export SERVICE=s3

helm uninstall -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller


(aws-topas3-06-26-iam@myeks:default) [root@myeks-bastion ~]# k get ns

NAME              STATUS   AGE

ack-system        Active   26m

default           Active   72m

kube-node-lease   Active   72m

kube-public       Active   72m

kube-system       Active   72m



# ACK S3 Controller 관련 crd 삭제

kubectl delete -f ~/$SERVICE-chart/crds


# IRSA 삭제

eksctl delete iamserviceaccount --cluster myeks --name ack-$SERVICE-controller --namespace ack-system



# namespace 삭제 >> ACK 모든 실습 후 삭제

kubectl delete namespace $ACK_K8S_NAMESPACE





<8> ACK EC2-Controller 설치 - 실습2



EC2-컨트롤러 생성

IRSA 권한 생성

VPC, Subnet 생성



1

ACK EC2-Controller 설치 with Helm

https://aws-controllers-k8s.github.io/community/docs/tutorials/ec2-example/


https://gallery.ecr.aws/aws-controllers-k8s/ec2-chart


https://github.com/aws-controllers-k8s/ec2-controller



2


# 서비스명 변수 지정 및 helm 차트 다운로드


export SERVICE=ec2


export RELEASE_VERSION=$(curl -sL https://api.github.com/repos/aws-controllers-k8s/$SERVICE-controller/releases/latest | grep '"tag_name":' | cut -d'"' -f4 | cut -c 2-)


helm pull oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart --version=$RELEASE_VERSION


tar xzvf $SERVICE-chart-$RELEASE_VERSION.tgz




# helm chart 확인

tree ~/$SERVICE-chart


/root/ec2-chart

├── Chart.yaml

├── crds

│   ├── ec2.services.k8s.aws_dhcpoptions.yaml

│   ├── ec2.services.k8s.aws_elasticipaddresses.yaml

│   ├── ec2.services.k8s.aws_instances.yaml

│   ├── ec2.services.k8s.aws_internetgateways.yaml

│   ├── ec2.services.k8s.aws_natgateways.yaml

│   ├── ec2.services.k8s.aws_routetables.yaml

│   ├── ec2.services.k8s.aws_securitygroups.yaml

│   ├── ec2.services.k8s.aws_subnets.yaml

│   ├── ec2.services.k8s.aws_transitgateways.yaml

│   ├── ec2.services.k8s.aws_vpcendpoints.yaml

│   ├── ec2.services.k8s.aws_vpcs.yaml

│   ├── services.k8s.aws_adoptedresources.yaml

│   └── services.k8s.aws_fieldexports.yaml

├── templates

│   ├── cluster-role-binding.yaml

│   ├── cluster-role-controller.yaml

│   ├── deployment.yaml

│   ├── _helpers.tpl

│   ├── metrics-service.yaml

│   ├── NOTES.txt

│   ├── role-reader.yaml

│   ├── role-writer.yaml

│   └── service-account.yaml

├── values.schema.json

└── values.yaml






# ACK EC2-Controller 설치

pod 1개 생성 된다.


export ACK_SYSTEM_NAMESPACE=ack-system

export AWS_REGION=ap-northeast-2


helm install -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller --set aws.region="$AWS_REGION" ~/$SERVICE-chart



# 설치 확인

helm list --namespace $ACK_SYSTEM_NAMESPACE


NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION

ack-ec2-controller      ack-system      1               2023-06-26 18:25:00.433253595 +0900 KST deployed        ec2-chart-1.0.3 1.0.3





kubectl -n $ACK_SYSTEM_NAMESPACE get pods -l "app.kubernetes.io/instance=ack-$SERVICE-controller"

NAME                                            READY   STATUS    RESTARTS   AGE

ack-ec2-controller-ec2-chart-777567ff4c-dt75z   1/1     Running   0          31s






kubectl get crd | grep $SERVICE

dhcpoptions.ec2.services.k8s.aws             2023-05-30T12:45:13Z

elasticipaddresses.ec2.services.k8s.aws      2023-05-30T12:45:13Z

instances.ec2.services.k8s.aws               2023-05-30T12:45:13Z

internetgateways.ec2.services.k8s.aws        2023-05-30T12:45:13Z

natgateways.ec2.services.k8s.aws             2023-05-30T12:45:13Z

routetables.ec2.services.k8s.aws             2023-05-30T12:45:13Z

securitygroups.ec2.services.k8s.aws          2023-05-30T12:45:13Z

subnets.ec2.services.k8s.aws                 2023-05-30T12:45:13Z

transitgateways.ec2.services.k8s.aws         2023-05-30T12:45:13Z

vpcendpoints.ec2.services.k8s.aws            2023-05-30T12:45:13Z

vpcs.ec2.services.k8s.aws                    2023-05-30T12:45:13Z




3

IRSA 설정 : 권장 정책 AmazonEC2FullAccess

https://github.com/aws-controllers-k8s/ec2-controller/blob/main/config/iam/recommended-policy-arn



4

#  권한은 쿠버네티스에서 준다. eksctl로  준다

# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account

# 서비스 어카운트 있어서 겹쳐쓴다.

# AmazonEC2FullAccess 권한을 부여한다.


eksctl create iamserviceaccount --name ack-$SERVICE-controller --namespace $ACK_SYSTEM_NAMESPACE --cluster $CLUSTER_NAME --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonEC2FullAccess`].Arn' --output text) --override-existing-serviceaccounts --approve


(2분)



5

# 확인 >> 웹 관리 콘솔에서 CloudFormation Stack >> IAM Role 확인

eksctl get iamserviceaccount --cluster $CLUSTER_NAME


NAMESPACE       NAME                            ROLE ARN

ack-system      ack-ec2-controller              arn:aws:iam::319485572629:role/eksctl-myeks-addon-iamserviceaccount-ack-sys-Role1-U05F7WBBV0W6

kube-system     aws-load-balancer-controller    arn:aws:iam::319485572629:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-EA69JDYBCQOZ



6

# Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod.

서비스 어카운트 확인


kubectl get sa -n $ACK_SYSTEM_NAMESPACE

NAME                 SECRETS   AGE

ack-ec2-controller   0         3m19s

default              0         38m



7

kubectl describe sa ack-$SERVICE-controller -n $ACK_SYSTEM_NAMESPACE


# Restart ACK service controller deployment using the following commands.

# 재시작해서 파드 업데이트함


kubectl -n $ACK_SYSTEM_NAMESPACE rollout restart deploy ack-$SERVICE-controller-$SERVICE-chart

deployment.apps/ack-ec2-controller-ec2-chart restarted



8

# IRSA 적용으로 Env, Volume 추가 확인

kubectl describe pod -n $ACK_SYSTEM_NAMESPACE -l k8s-app=$SERVICE-chart





<9> VPC, Subnet 생성 및 삭제


// VPC도 만들수 있다. 그러나 만들 일은 별로 없다.


1

https://aws-controllers-k8s.github.io/community/docs/tutorials/ec2-example/#optional-create-a-vpc-and-subnet



2

# [터미널1] 모니터링

while true; do aws ec2 describe-vpcs --query 'Vpcs[*].{VPCId:VpcId, CidrBlock:CidrBlock}' --output text; echo "-----"; sleep 2; done



3

# VPC 생성


cat << EOF > vpc.yaml

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: VPC

metadata:

  name: vpc-tutorial-test

spec:

  cidrBlocks: 

  - 10.0.0.0/16

  enableDNSSupport: true

  enableDNSHostnames: true

EOF


kubectl apply -f vpc.yaml



vpc.ec2.services.k8s.aws/vpc-tutorial-test created




4

# VPC 생성 확인

# kubectl 로 확인 가능하다.


kubectl get vpcs

NAME                ID                      STATE

vpc-tutorial-test   vpc-0d3ae140cc3058357   available



kubectl describe vpcs

aws ec2 describe-vpcs --query 'Vpcs[*].{VPCId:VpcId, CidrBlock:CidrBlock}' --output text




5

# [터미널1] 모니터링  = 서브넷 모니터링 


VPCID=$(kubectl get vpcs vpc-tutorial-test -o jsonpath={.status.vpcID})

while true; do aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --query 'Subnets[*].{SubnetId:SubnetId, CidrBlock:CidrBlock}' --output text; echo "-----"; sleep 1 ; done



6

# 서브넷 생성


VPCID=$(kubectl get vpcs vpc-tutorial-test -o jsonpath={.status.vpcID})


cat <<EOF > subnet.yaml

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: Subnet

metadata:

  name: subnet-tutorial-test

spec:

  cidrBlock: 10.0.0.0/20

  vpcID: $VPCID

EOF


kubectl apply -f subnet.yaml



7

# 서브넷 생성 확인


kubectl get subnets


kubectl describe subnets

aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --query 'Subnets[*].{SubnetId:SubnetId, CidrBlock:CidrBlock}' --output text




8

# 리소스 삭제


kubectl delete -f subnet.yaml && kubectl delete -f vpc.yaml





<10>  Create a VPC Workflow - 실습3


1

Create a VPC Workflow : VPC, Subnet, SG, RT, EIP, IGW, NATGW, Instance 생성



아래 링크의 vpc-workflow.yaml 파일을 사용한다.


https://aws-controllers-k8s.github.io/community/docs/tutorials/ec2-example/#create-a-vpc-workflow

  

    1 VPC

    1 Instance

    1 Internet Gateway

    1 NAT Gateways

    1 Elastic IPs

    2 Route Tables

    2 Subnets (1 Public; 1 Private)

    1 Security Group  




내용


cat <<EOF > vpc-workflow.yaml

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: VPC

metadata:

  name: tutorial-vpc

spec:

  cidrBlocks: 

  - 10.0.0.0/16

  enableDNSSupport: true

  enableDNSHostnames: true

  tags:

    - key: name

      value: vpc-tutorial

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: InternetGateway

metadata:

  name: tutorial-igw

spec:

  vpcRef:

    from:

      name: tutorial-vpc

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: NATGateway

metadata:

  name: tutorial-natgateway1

spec:

  subnetRef:

    from:

      name: tutorial-public-subnet1

  allocationRef:

    from:

      name: tutorial-eip1

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: ElasticIPAddress

metadata:

  name: tutorial-eip1

spec:

  tags:

    - key: name

      value: eip-tutorial

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: RouteTable

metadata:

  name: tutorial-public-route-table

spec:

  vpcRef:

    from:

      name: tutorial-vpc

  routes:

  - destinationCIDRBlock: 0.0.0.0/0

    gatewayRef:

      from:

        name: tutorial-igw

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: RouteTable

metadata:

  name: tutorial-private-route-table-az1

spec:

  vpcRef:

    from:

      name: tutorial-vpc

  routes:

  - destinationCIDRBlock: 0.0.0.0/0

    natGatewayRef:

      from:

        name: tutorial-natgateway1

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: Subnet

metadata:

  name: tutorial-public-subnet1

spec:

  availabilityZone: ap-northeast-2a

  cidrBlock: 10.0.0.0/20

  mapPublicIPOnLaunch: true

  vpcRef:

    from:

      name: tutorial-vpc

  routeTableRefs:

  - from:

      name: tutorial-public-route-table

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: Subnet

metadata:

  name: tutorial-private-subnet1

spec:

  availabilityZone: ap-northeast-2a

  cidrBlock: 10.0.128.0/20

  vpcRef:

    from:

      name: tutorial-vpc

  routeTableRefs:

  - from:

      name: tutorial-private-route-table-az1

---

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: SecurityGroup

metadata:

  name: tutorial-security-group

spec:

  description: "ack security group"

  name: tutorial-sg

  vpcRef:

     from:

       name: tutorial-vpc

  ingressRules:

    - ipProtocol: tcp

      fromPort: 22

      toPort: 22

      ipRanges:

        - cidrIP: "0.0.0.0/0"

          description: "ingress"

EOF





2


# VPC 환경 생성

kubectl apply -f vpc-workflow.yaml





# [터미널1] 

NATGW 생성 완료 후 

tutorial-private-route-table-az1 라우팅 테이블 ID가 확인되고 

그후 tutorial-private-subnet1 서브넷ID가 확인됨 > 5분 정도 시간 소요


watch -d kubectl get routetables,subnet



# VPC 환경 생성 확인

kubectl describe vpcs

kubectl describe internetgateways

kubectl describe routetables

kubectl describe natgateways

kubectl describe elasticipaddresses

kubectl describe securitygroups



# 배포 도중 2개의 서브넷 상태 정보 비교 해보자

프라이빗은 오래 걸린다.

nat만들고 올라온다.



kubectl describe subnets

...

Status:

  Conditions:

    Last Transition Time:  2023-06-04T02:15:25Z

    Message:               Reference resolution failed

    Reason:                the referenced resource is not synced yet. resource:RouteTable, namespace:default, name:tutorial-private-route-table-az1

    Status:                Unknown

    Type:                  ACK.ReferencesResolved

...

Status:

  Ack Resource Metadata:

    Arn:                       arn:aws:ec2:ap-northeast-2:911283464785:subnet/subnet-0f5ae09e5d680030a

    Owner Account ID:          911283464785

    Region:                    ap-northeast-2

  Available IP Address Count:  4091

  Conditions:

    Last Transition Time:           2023-06-04T02:14:45Z

    Status:                         True

    Type:                           ACK.ReferencesResolved

    Last Transition Time:           2023-06-04T02:14:45Z

    Message:                        Resource synced successfully

    Reason:

    Status:                         True

    Type:                           ACK.ResourceSynced

...



https://www.eksworkshop.com/docs/automation/controlplanes/ack/provision-resources/





<11>퍼블릭 서브넷에 인스턴스 생성


1

# public 서브넷 ID 확인


PUBSUB1=$(kubectl get subnets tutorial-public-subnet1 -o jsonpath={.status.subnetID})

echo $PUBSUB1



# 보안그룹 ID 확인


TSG=$(kubectl get securitygroups tutorial-security-group -o jsonpath={.status.id})

echo $TSG



2

# Amazon Linux 2 최신 AMI ID 확인


AL2AMI=$(aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" --query 'Images[0].ImageId' --output text)

echo $AL2AMI



# 각자 자신의 SSH 키페어 이름 변수 지정

MYKEYPAIR=<각자 자신의 SSH 키페어 이름>


MYKEYPAIR=0607-2



# 변수 확인 > 특히 서브넷 ID가 확인되었는지 꼭 확인하자!

echo $PUBSUB1 , $TSG , $AL2AMI , $MYKEYPAIR




3

# [터미널1] 모니터링


while true; do 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; date ; sleep 2 ; done


Sun Jun 11 12:44:04 KST 2023

-----------------------------------------------------------------

|                       DescribeInstances                       |

+----------------+-----------------+-----------------+----------+

|  InstanceName  |  PrivateIPAdd   |   PublicIPAdd   | Status   |

+----------------+-----------------+-----------------+----------+

|  myeks-ng1-Node|  192.168.3.130  |  43.201.30.111  |  running |

|  myeks-ng1-Node|  192.168.2.149  |  3.35.232.130   |  running |

|  myeks-bastion |  192.168.1.100  |  13.125.192.78  |  running |

|  myeks-ng1-Node|  192.168.1.171  |  3.34.131.209   |  running |

+----------------+-----------------+-----------------+----------+

Sun Jun 11 12:44:06 KST 2023




4

# public 서브넷에 인스턴스 생성


cat <<EOF > tutorial-bastion-host.yaml

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: Instance

metadata:

  name: tutorial-bastion-host

spec:

  imageID: $AL2AMI # AL2 AMI ID - ap-northeast-2

  instanceType: t3.medium

  subnetID: $PUBSUB1

  securityGroupIDs:

  - $TSG

  keyName: $MYKEYPAIR

  tags:

    - key: producer

      value: ack

EOF

kubectl apply -f tutorial-bastion-host.yaml


(바로 생성됨)



# 인스턴스 생성 확인

kubectl get instance


kubectl describe instance


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




5

public 서브넷에 인스턴스 접속



ssh -i <자신의 키페어파일> ec2-user@<public 서브넷에 인스턴스 퍼블릭IP>

------

# public 서브넷에 인스턴스 접속 후 외부 인터넷 통신 여부 확인 

ping -c 2 8.8.8.8

exit

// 안됨. 정상임.  이그레스 룰이 없어 그렇다. 아래 만들자.



6

// egress 룰이 없어서 만든다.

보안 그룹 정책 수정 : egress 규칙 추가


cat <<EOF > modify-sg.yaml

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: SecurityGroup

metadata:

  name: tutorial-security-group

spec:

  description: "ack security group"

  name: tutorial-sg

  vpcRef:

     from:

       name: tutorial-vpc

  ingressRules:

    - ipProtocol: tcp

      fromPort: 22

      toPort: 22

      ipRanges:

        - cidrIP: "0.0.0.0/0"

          description: "ingress"

  egressRules:

    - ipProtocol: '-1'

      ipRanges:

        - cidrIP: "0.0.0.0/0"

          description: "egress"

EOF

kubectl apply -f modify-sg.yaml


# 변경 확인 >> 보안그룹에 아웃바운드 규칙 확인

kubectl logs -n $ACK_SYSTEM_NAMESPACE -l k8s-app=ec2-chart -f




7

public 서브넷에 인스턴스 접속 후 외부 인터넷 통신 확인


curl ipinfo.io/ip ; echo 





<12> 프라이빗 서브넷에 인스턴스 생성 (선택)



1

# private 서브넷 ID 확인 >> NATGW 생성 완료 후 RT/SubnetID가 확인되어 다소 시간 필요함


PRISUB1=$(kubectl get subnets tutorial-private-subnet1 -o jsonpath={.status.subnetID})

echo $PRISUB1


# 변수 확인 > 특히 private 서브넷 ID가 확인되었는지 꼭 확인하자!

echo $PRISUB1 , $TSG , $AL2AMI , $MYKEYPAIR



2

# private 서브넷에 인스턴스 생성


cat <<EOF > tutorial-instance-private.yaml

apiVersion: ec2.services.k8s.aws/v1alpha1

kind: Instance

metadata:

  name: tutorial-instance-private

spec:

  imageID: $AL2AMI # AL2 AMI ID - ap-northeast-2

  instanceType: t3.medium

  subnetID: $PRISUB1

  securityGroupIDs:

  - $TSG

  keyName: $MYKEYPAIR

  tags:

    - key: producer

      value: ack

EOF

kubectl apply -f tutorial-instance-private.yaml



3

# 인스턴스 생성 확인

kubectl get instance


kubectl describe instance


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



4

public 서브넷에 인스턴스에 SSH 터널링 설정


ssh -i <자신의 키페어파일> -L <자신의 임의 로컬 포트>:<private 서브넷의 인스턴스의 private ip 주소>:22 ec2-user@<public 서브넷에 인스턴스 퍼블릭IP> -v


ssh -i ~/.ssh/kp-gasida.pem -L 9999:10.0.129.196:22 ec2-user@3.34.96.12 -v

접속 후 그냥 두기

// -L은 로컬이다.




5

자신의 임의 로컬 포트로 SSH 접속 시, private 서브넷에 인스턴스 접속됨


ssh -i <자신의 키페어파일> -p <자신의 임의 로컬 포트> ec2-user@localhost

ssh -i ~/.ssh/kp-gasida.pem -p 9999 ec2-user@localhost

---

# IP 및 네트워크 정보 확인

ip -c addr

sudo ss -tnp

ping -c 2 8.8.8.8

curl ipinfo.io/ip ; echo # 출력되는 공인IP는 무엇인가?

NAT IP




6

실습 후 리소스 삭제


1) 퍼블릭 프라이빗 인스턴스 삭제


kubectl delete -f tutorial-bastion-host.yaml && kubectl delete -f tutorial-instance-private.yaml



2) 네트워크 삭제


kubectl delete -f vpc-workflow.yaml  # vpc 관련 모든 리소스들 삭제에는 다소 시간이 소요됨





<13> RDS 생성 - 실습4 (선택)


RDS 생성에 15분 정도 걸림


1

지원 엔진 ?

Aurora(MySQL & PostgreSQL), RDS for PostgreSQL, RDS for MySQL, RDS for MariaDB, RDS for Oracle, RDS for SQL Server



2

ACK RDS Controller 설치 with Helm


https://aws-controllers-k8s.github.io/community/docs/tutorials/rds-example/


https://gallery.ecr.aws/aws-controllers-k8s


https://github.com/aws-controllers-k8s/rds-controller



3

# 서비스명 변수 지정 및 helm 차트 다운로드

export SERVICE=rds

export RELEASE_VERSION=$(curl -sL https://api.github.com/repos/aws-controllers-k8s/$SERVICE-controller/releases/latest | grep '"tag_name":' | cut -d'"' -f4 | cut -c 2-)


helm pull oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart --version=$RELEASE_VERSION


tar xzvf $SERVICE-chart-$RELEASE_VERSION.tgz



# helm chart 확인

tree ~/$SERVICE-chart


# ACK EC2-Controller 설치

export ACK_SYSTEM_NAMESPACE=ack-system

export AWS_REGION=ap-northeast-2


helm install -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller --set aws.region="$AWS_REGION" ~/$SERVICE-chart



# 설치 확인

helm list --namespace $ACK_SYSTEM_NAMESPACE


kubectl -n $ACK_SYSTEM_NAMESPACE get pods -l "app.kubernetes.io/instance=ack-$SERVICE-controller"


kubectl get crd | grep $SERVICE




4

IRSA 설정 : 권장 정책 AmazonRDSFullAccess

https://github.com/aws-controllers-k8s/rds-controller/blob/main/config/iam/recommended-policy-arn


# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account


eksctl create iamserviceaccount --name ack-$SERVICE-controller --namespace $ACK_SYSTEM_NAMESPACE --cluster $CLUSTER_NAME --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonRDSFullAccess`].Arn' --output text) --override-existing-serviceaccounts --approve



# 확인 >> 웹 관리 콘솔에서 CloudFormation Stack >> IAM Role 확인

eksctl get iamserviceaccount --cluster $CLUSTER_NAME


# Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod.

kubectl get sa -n $ACK_SYSTEM_NAMESPACE

kubectl describe sa ack-$SERVICE-controller -n $ACK_SYSTEM_NAMESPACE


# Restart ACK service controller deployment using the following commands.

kubectl -n $ACK_SYSTEM_NAMESPACE rollout restart deploy ack-$SERVICE-controller-$SERVICE-chart


# IRSA 적용으로 Env, Volume 추가 확인

kubectl describe pod -n $ACK_SYSTEM_NAMESPACE -l k8s-app=$SERVICE-chart

...




<14> RDS for MariaDB 생성 및 삭제 (선택)


RDS 생성에 15분 정도 걸림


1

https://aws-controllers-k8s.github.io/community/docs/tutorials/rds-example/



2

# DB 암호를 위한 secret 생성

RDS_INSTANCE_NAME="<your instance name>"

RDS_INSTANCE_PASSWORD="<your instance password>"



RDS_INSTANCE_NAME=myrds

RDS_INSTANCE_PASSWORD=qwe12345


kubectl create secret generic "${RDS_INSTANCE_NAME}-password" --from-literal=password="${RDS_INSTANCE_PASSWORD}"

// 시크릭을 만든다.



# 확인

kubectl get secret $RDS_INSTANCE_NAME-password


3

# [터미널1] 모니터링

RDS_INSTANCE_NAME=myrds

watch -d "kubectl describe dbinstance "${RDS_INSTANCE_NAME}" | grep 'Db Instance Status'"



4

# RDS 배포 생성 :

15분 이내 시간 소요 >> 보안그룹, 서브넷 등 필요한 옵션들은 추가해서 설정해보자!


cat <<EOF > rds-mariadb.yaml

apiVersion: rds.services.k8s.aws/v1alpha1

kind: DBInstance

metadata:

  name: "${RDS_INSTANCE_NAME}"

spec:

  allocatedStorage: 20

  dbInstanceClass: db.t4g.micro

  dbInstanceIdentifier: "${RDS_INSTANCE_NAME}"

  engine: mariadb

  engineVersion: "10.6"

  masterUsername: "admin"

  masterUserPassword:

    namespace: default

    name: "${RDS_INSTANCE_NAME}-password"

    key: password

EOF

kubectl apply -f rds-mariadb.yaml



(5분 걸림)


콘솔에서 만들어 지는지 확인하자~~~



https://vclock.kr/timer/#countdown=00:02:00&enabled=0&seconds=0&sound=xylophone&loop=1



5

# 생성 확인


kubectl get dbinstances  ${RDS_INSTANCE_NAME}


kubectl describe dbinstance "${RDS_INSTANCE_NAME}"


aws rds describe-db-instances --db-instance-identifier $RDS_INSTANCE_NAME | jq


kubectl describe dbinstance "${RDS_INSTANCE_NAME}" | grep 'Db Instance Status'

  Db Instance Status:         creating


kubectl describe dbinstance "${RDS_INSTANCE_NAME}" | grep 'Db Instance Status'

  Db Instance Status:         backing-up


kubectl describe dbinstance "${RDS_INSTANCE_NAME}" | grep 'Db Instance Status'

  Db Instance Status:         available



# 생성 완료 대기 : for 지정 상태가 완료되면 정상 종료됨


kubectl wait dbinstances ${RDS_INSTANCE_NAME} --for=condition=ACK.ResourceSynced --timeout=15m

dbinstance.rds.services.k8s.aws/myrds condition met


6

console에 접속해 확인.


생성 DB는 퍼블릭에 배포되었다.

디폴트는 퍼블릭에서 허용하도록 되어 있다.




7

MariaDB 접속

https://aws-controllers-k8s.github.io/community/docs/tutorials/rds-example/#connect-to-database-instances


https://www.eksworkshop.com/docs/automation/controlplanes/ack/configure-application/




8

RDS 상태 정보를 가져오는법 ?

fieldexport를 제공한다.


앤드포인트를 알아야 한다.

파드가 접속해야 한다.

fieldexport 로 앤드포인트를  확인한다~~



fieldexport 생성 :


# 상태 정보 확인 : address 와 port 정보 


kubectl get dbinstances myrds -o jsonpath={.status.endpoint} | jq

{

  "address": "myrds.cb79jlim4dyq.ap-northeast-2.rds.amazonaws.com",

  "hostedZoneID": "ZLA2NUCOLGUUR",

  "port": 3306

}



# 상태 정보 확인 : masterUsername 확인


kubectl get dbinstances myrds -o jsonpath={.spec.masterUsername} ; echo




# 컨피그맵 확인


kubectl get cm myrds-conn-cm -o yaml | kubectl neat | yh

apiVersion: v1

data:

  default.myrds-host: myrds.cb79jlim4dyq.ap-northeast-2.rds.amazonaws.com

  default.myrds-port: "3306"

  default.myrds-user: admin

kind: ConfigMap

metadata:

  name: myrds-conn-cm

  namespace: default


# fieldexport 정보 확인

kubectl get crd | grep fieldexport

kubectl get fieldexport

kubectl get fieldexport myrds-host -o yaml | k neat | yh




9

RDS 사용하는 파드를 생성 ?


환경변수를 알수 있다.



APP_NAMESPACE=default


cat <<EOF > rds-pods.yaml

apiVersion: v1

kind: Pod

metadata:

  name: app

  namespace: ${APP_NAMESPACE}

spec:

  containers:

   - image: busybox

     name: myapp

     command:

        - sleep

        - "3600"

     imagePullPolicy: IfNotPresent

     env:

      - name: DBHOST

        valueFrom:

         configMapKeyRef:

          name: ${RDS_INSTANCE_CONN_CM}

          key: "${APP_NAMESPACE}.${RDS_INSTANCE_NAME}-host"

      - name: DBPORT

        valueFrom:

         configMapKeyRef:

          name: ${RDS_INSTANCE_CONN_CM}

          key: "${APP_NAMESPACE}.${RDS_INSTANCE_NAME}-port"

      - name: DBUSER

        valueFrom:

         configMapKeyRef:

          name: ${RDS_INSTANCE_CONN_CM}

          key: "${APP_NAMESPACE}.${RDS_INSTANCE_NAME}-user"

      - name: DBPASSWORD

        valueFrom:

          secretKeyRef:

           name: "${RDS_INSTANCE_NAME}-password"

           key: password

EOF

kubectl apply -f rds-pods.yaml



10

# 생성 확인

kubectl get pod app



# 파드의 환경 변수 확인

kubectl exec -it app -- env | grep DB


DBHOST=myrds.cb79jlim4dyq.ap-northeast-2.rds.amazonaws.com

DBPORT=3306

DBUSER=admin

DBPASSWORD=qwe12345


프로그램 짤때 엔드포인트를 확인할수 있다.





11

RDS 의 master 암호를 변경해보고 확인!




12

# [터미널]

watch -d "kubectl get dbinstance; echo; kubectl get cm myrds-conn-cm -o yaml | kubectl neat"




# 콘솔에서 DB 식별자를 업데이트 >> 어떤 현상이 발생하는가?


kubectl patch dbinstance myrds --type=merge -p '{"spec":{"dbInstanceIdentifier":"studyend"}}'


// 콘솔에서 변경해도 DB 상태 정보가 깨진다.  관리가 안된다.

// DB서버가 새로 생성 된다.

// ACK 아직은 사용이 힘듬 ?




# 확인

kubectl get dbinstance myrds

kubectl describe dbinstance myrds





13

최종적으로 변경된 status 정보가 반영되었는지 확인해보자.

자동으로 동적으로 변경이 된다.

pod로 배포한것이다.



# 상태 정보 확인 : address 변경 확인!


kubectl get dbinstances myrds -o jsonpath={.status.endpoint} | jq

{

  "address": "studyend.cb79jlim4dyq.ap-northeast-2.rds.amazonaws.com",

  "hostedZoneID": "ZLA2NUCOLGUUR",

  "port": 3306

}



# 파드의 환경 변수 확인 

>> 파드의 경우 환경 변수 env로 정보를 주입했기 때문에 변경된 정보를 확인 할 수 없다


kubectl exec -it app -- env | grep DB

DBHOST=myrds.cb79jlim4dyq.ap-northeast-2.rds.amazonaws.com

DBPORT=3306

DBUSER=admin

DBPASSWORD=qwe12345




14

# 파드 삭제 후 재생성 후 확인

kubectl delete pod app && kubectl apply -f rds-pods.yaml



# 파드의 환경 변수 확인 >> 변경 정보 확인!

# 즉 deployments, daemonsets, statefulsets 의 경우 rollout 으로 env 변경 적용을 할 수 는 있겠다!


kubectl exec -it app -- env | grep DB

DBHOST=studyend.cb79jlim4dyq.ap-northeast-2.rds.amazonaws.com

DBPORT=3306

DBUSER=admin

DBPASSWORD=qwe12345




15

RDS 삭제 > AWS 웹 관리콘솔에서 myrds 는 직접 삭제 할 것


# 파드 삭제

kubectl delete pod app


# RDS 삭제 

kubectl delete -f rds-mariadb.yaml




16


console에서 확인







<15> 개인 정리


// 콘솔에서 변경해도 DB 상태 정보가 깨진다.  관리가 안된다.

// DB서버가 새로 생성 된다.

// ACK 아직은 사용이 힘듬 ?




다음

https://brunch.co.kr/@topasvga/3308


전체 보기

https://brunch.co.kr/@topasvga/3217


본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9 dfa44 a27 ff431 dafdd2 edacc8 a1863  

계속 테스트하며  내용과 설명이 업데이트됩니다.



감사합니다.


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari