[AWS] EKS Automation- 7주차 - ACK RDS생성
2023.06.07 - [클라우드/AWS] - [AWS] EKS Automation- 7주차 - ACK S3 생성
2023.06.07 - [클라우드/AWS] - [AWS] EKS Automation- 7주차 - ACK EC2, VPC생성
ACK를 사용하여 RDS를 생성하고 삭제해보도록하자. 내용은 위와 동일하다.
RDS : 지원 엔진 - Aurora(MySQL & PostgreSQL), RDS for PostgreSQL, RDS for MySQL, RDS for MariaDB, RDS for Oracle, RDS for SQL Server
컨트롤러 설치 -참조( 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)
# 서비스명 변수 지정 및 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
IRSA 설정 - 참조 (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
...
RDS 생성 -참조 (https://aws-controllers-k8s.github.io/community/docs/tutorials/rds-example/)
# 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
# [터미널1] 모니터링
RDS_INSTANCE_NAME=myrds
watch -d "kubectl describe dbinstance "${RDS_INSTANCE_NAME}" | grep 'Db Instance Status'"
# 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
# 생성 확인
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
RDS 접속 - 참조 (https://www.eksworkshop.com/docs/automation/controlplanes/ack/configure-application, https://aws-controllers-k8s.github.io/community/docs/tutorials/rds-example/#connect-to-database-instances)
- MariaDB 접속 - 링크 FieldExport
- fieldexport 생성 : 아래 코드 블록 복붙!
RDS_INSTANCE_CONN_CM="${RDS_INSTANCE_NAME}-conn-cm"
cat <<EOF > rds-field-exports.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ${RDS_INSTANCE_CONN_CM}
data: {}
---
apiVersion: services.k8s.aws/v1alpha1
kind: FieldExport
metadata:
name: ${RDS_INSTANCE_NAME}-host
spec:
to:
name: ${RDS_INSTANCE_CONN_CM}
kind: configmap
from:
path: ".status.endpoint.address"
resource:
group: rds.services.k8s.aws
kind: DBInstance
name: ${RDS_INSTANCE_NAME}
---
apiVersion: services.k8s.aws/v1alpha1
kind: FieldExport
metadata:
name: ${RDS_INSTANCE_NAME}-port
spec:
to:
name: ${RDS_INSTANCE_CONN_CM}
kind: configmap
from:
path: ".status.endpoint.port"
resource:
group: rds.services.k8s.aws
kind: DBInstance
name: ${RDS_INSTANCE_NAME}
---
apiVersion: services.k8s.aws/v1alpha1
kind: FieldExport
metadata:
name: ${RDS_INSTANCE_NAME}-user
spec:
to:
name: ${RDS_INSTANCE_CONN_CM}
kind: configmap
from:
path: ".spec.masterUsername"
resource:
group: rds.services.k8s.aws
kind: DBInstance
name: ${RDS_INSTANCE_NAME}
EOF
kubectl apply -f rds-field-exports.yaml
# 상태 정보 확인 : 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
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
# 생성 확인
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
암호 변경해보기
# [터미널]
watch -d "kubectl get dbinstance; echo; kubectl get cm myrds-conn-cm -o yaml | kubectl neat"
# 아래 처럼 RDS 에서 직접 변경 할 경우 rds controller 를 별도 추적을 하지 않아서, k8s 상태와 aws 상태 정보가 깨져버럼
# DB 식별자 변경 : studyend
aws rds modify-db-instance --db-instance-identifier $RDS_INSTANCE_NAME --new-db-instance-identifier studyend --apply-immediately
# DB 식별자를 업데이트 >> 어떤 현상이 발생하는가?
kubectl patch dbinstance myrds --type=merge -p '{"spec":{"dbInstanceIdentifier":"studyend"}}'
# 확인
kubectl get dbinstance myrds
kubectl describe dbinstance myrds
결과 신규로 생성됨
# 상태 정보 확인 : 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
# 파드 삭제 후 재생성 후 확인
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
# 상태 정보 확인 : 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
삭제 - AWS 웹 관리콘솔에서 myrds 는 직접 삭제 할 것