📌 EBS (Elastic Block Store)
✅ EBS(Block) - 하드웨어(디스크)
-> 블록 스토리지 서비스: 데이터를 블록 단위로 저장하는 방식임. 하드 드라이브와 비슷한 개념
-> EC2 인스턴스와 함께 사용되며, EC2에서 실행되는 애플리케이션의 데이터를 저장하는 데 사용됨
-> 단일 EC2 인스턴스에 연결(attach)돼서 동작하고, 데이터베이스, 로그 파일 등을 저장하는 데 적합함
-> 파일 시스템이 구성이 안되어있음
특정 노드(attach 된)에 존재하는 pod만 접근 가능함
주요 특징:
- 지속적 저장: EC2가 종료돼도 데이터가 유지됨.
- 성능 최적화: IOPS, 처리량, 지연 시간을 설정하여 성능을 조정할 수 있어.
- 확장성: 스냅샷을 통해 데이터 백업 및 복원 가능.
📌 EFS (Elastic File System)
✅ EFS는 파일 스토리지 서비스
- EFS는 파일 시스템으로, 여러 EC2 인스턴스나 컨테이너에서 동시에 파일을 공유할 수 있음
- NFS 프로토콜을 사용해서, 네트워크를 통해 파일 시스템을 공유하고 확장 가능한 장소를 제공함
-> 다수의 인스턴스에서 접근 가능
여러 노드에 존재하는 다수의 pod들이 접근 가능함
-> 그래서 EKS환경에서 동적 프로비저닝을 할 때는 이걸 사용해야 됨
주요 특징:
- 파일 시스템: 여러 EC2 인스턴스나 애플리케이션에서 공유된 파일 시스템을 사용.
- 자동 확장: 사용량에 따라 자동으로 용량을 확장함.
- NFS 호환: NFS 프로토콜을 지원해, Linux와 다른 시스템에서 쉽게 연결 가능.
📌 NFS (Network File System)
✅ NFS는 네트워크를 통한 파일 시스템 공유 프로토콜
- NFS는 파일 시스템을 네트워크를 통해 공유할 수 있게 해주는 프로토콜
- 여러 컴퓨터나 서버에서 파일을 공유하거나 접근할 수 있도록 돕는 기술
주요 특징:
- 파일 공유: 여러 시스템이 동일한 파일 시스템을 사용하도록 만들어 줌.
- 유연성: 다양한 시스템에서 접근할 수 있기 때문에, 여러 서버 간 파일 공유 시 유용.
- 로컬 파일 시스템처럼 사용할 수 있지만, 네트워크를 통해 접근함.
여기서 EFS와 NFS가 밀접한 관련이 있는데 어떤 관련일까?
- EFS는 NFS을 기반으로 AWS에서 제공되는 파일 시스템 서비스로, 여러 서버가 동일한 파일 시스템에 접근할 수 있게 해 줌
📌 EKS (Elastic Kubernetes Service)
EKS는 Kubernetes 관리형 서비스
- Kubernetes는 컨테이너화된 애플리케이션을 관리하는 오케스트레이션 툴인데, EKS는 이 Kubernetes 클러스터를 AWS에서 관리해주는 서비스임
- 자동화된 클러스터 관리를 제공하며, 컨테이너화된 애플리케이션의 배포와 관리를 쉽게 만들어줌
주요 특징:
- 관리형 서비스: Kubernetes 클러스터의 설치, 유지보수, 업그레이드를 AWS가 대신해줌.
- 확장성: EKS는 자동으로 컨테이너를 확장하고, 애플리케이션의 부하에 맞춰 인프라를 관리해.
- 보안: IAM과 연동되어 사용자 권한을 세밀하게 설정할 수 있음.
서비스 설명 연관성
EBS | EC2 인스턴스에 블록 스토리지 제공 | EC2와 연동, EKS에서도 사용 가능 |
EKS | Kubernetes 클러스터 관리 서비스 | EBS와 연결 가능, EFS도 연결 가능 |
EFS | 여러 인스턴스에서 파일 시스템 공유 | NFS 프로토콜 기반, EKS와 EC2에서 사용 |
NFS | 네트워크를 통한 파일 시스템 공유 | EFS는 NFS를 기반으로 작동 |
📌EKS 환경에서 동적 프로비저닝
CSI(Container Stroage Interface) = 다이나믹 프로비저닝을 위한 애드온
ALB 생성을 위한 LB controller를 설치했던 것과 유사함
export CLUSTER_NAME=<본인꺼>
export ACCOUNT_ID=<본인꺼>
export VPC_ID=<본인꺼>
export REGION=ap-northeast-2
export ROLE_NAME=AmazonEKS_EFS_CSI_DriverRole
OIDC 활성화
eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve

- 원래 있는 정책을 사용할 예정
eksctl create iamserviceaccount \
--name efs-csi-controller-sa \
--namespace kube-system \
--cluster $CLUSTER_NAME \
--role-name $ROLE_NAME \
--role-only \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
--approve
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
- IRSA = ROLE_NAME = AmazonEKS_EFS_CSI_DriverRole 생성
- IAM SA = efs-csi-controller-sa 생성
- 정책은 이미 존재하는 관리형 정책 = AmazonEFSCSIDriverPolicy

kubectl get sa -n kube-system | grep -i efs-csi-controller-sa
- 스택 충돌이 발생해서 안 생길 수도 있으니 만약에 생성이 안된다면 지우기
- 그래도 안 생김
롤만 잘 만들어졌는지 확인?
role only로 해서 sa는 안 만들어진 상태임
정책 편집


- 정책을 편집할 필요는 없고, 이런 것도 있구나라고 생각하면 될 듯
애드온 설치
eksctl create addon --cluster $CLUSTER_NAME --name aws-efs-csi-driver --version latest \
--service-account-role-arn arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME --force


- 생성이 잘 된 걸 확인할 수 있음
vi sc.yml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-0983c418c25220e37 #<자신의 efs 아이디>
directoryPerms: "700"
kubectl apply -f sc.yml
vi pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: efs-claim-1
spec:
accessModes:
- ReadWriteMany
storageClassName: efs-sc
resources:
requests:
storage: 5Mi

RDS의 인증정보
- pod에서 불러온 시크릿 생성

- 데이터베이스가 없으면 생성이 안되기 때문에 생성해 주자







- 내가 생성한 시크릿

시크릿 CSI 드라이버 설치
OIDC 활성화
eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
IAM SA생성
eksctl create iamserviceaccount --name secret-sa --region=$REGION --cluster $CLUSTER_NAME --attach-policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite --approve --override-existing-serviceaccounts

헬름으로 시크릿 CSI 드라이버를 설치
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
kube-system에 릴리스 생성
helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver
ASCP(AWS Secrets and Configuration Provider) 설치
- aws의 시크릿을 eks의 시크릿처럼 쓸 수 있게 만들어줌
ASCP를 위한 헬름 레포 추가
helm repo add aws-secrets-manager https://aws.github.io/secrets-store-csi-driver-provider-aws
ASCP 릴리스 생성
helm install -n kube-system secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws
SecretProviderClass 생성

- 보안 암호 ARN을 넣어주면 됨
vi spc.yml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secrets
spec:
provider: aws
parameters:
objects: |
- objectName: "<내 시크릿의 ARN>"
# metadata.name: aws-secrets 이거는 나중에 파드 정의시 SecretProviderClass를 명시할때 쓰이는 이름.

pod 공간 부족으로 안 생길 수도 있으니 파드를 늘려줌
eksctl scale nodegroup --cluster rapa --name mycng --nodes 4 --nodes-max 4
ArgoCD(Continuous Deployment)
- k8s환경에서 CD를 하기 위한 툴
- CNCF에서 강추하는 CD툴
ArgoCD 설치
네임 스페이스 생성
kubectl create ns argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml


LoadBalancer로 타입변경
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

- 서비스 타입이 잘 바뀐 걸 확인할 수 있음
만약에 안 바뀐다면 용량이슈가 있을 수 있으니
eksctl scale nodegroup --cluster <클러스터이름> --name <노드그룹이름> --nodes <변경할노드수> --nodes-max <변경할최대노드수>
node의 상을 늘려주면 됨. 한 4개 정도
주소 확인
kubectl get svc -n argocd | grep -i argocd-server

초기 패스워드 조회
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo






- 그리고 다시 로그인해주기
vi argo-svc.yml
apiVersion: v1
kind: Service
metadata:
name: svc-ip
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
- 누구는 annotation 안 붙이고, classic으로 생성됨
-> LB Controller가 설치 안된 경우
- LB Controller가 설치되어 있다면 기본 ELB가 NLB였던 걸로 기억
-> 따라서 LBC가 설치되어 있는 사람은 NLB가 생성되면서 annotation 설정이 없었으면 private 서브넷이니까 internal로 생성됐을 것
-> 그런 경우엔 annotation에서 그냥 internet-facing으로 하면 됨
내가 배포할 deployment는 github의 레포에 둘 예정
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-dep
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-con
image: oolralra/ipnginx
kubectl delete svc --all
kubectl delete deploy --all


- deployment 파일을 생성.
- (강사님 이미지)


- argoCD가 모니터링할 레포의 파일
ArgoCD에서 위 레포를 모니터링하도록 설정




- 위의 내 주소 넣어주기
- connect 해주고
레포를 등록했다면, 이번에는 앱을 띄우면 됨



create 해주면 네임스페이가 잘 배포된 걸 확인할 수 있음




- rev(=revision number는 1)
- rs의 레플리카수는 1

- 현재 replicas: 1인데 이걸 바꿔보자
- 말하고자 하는 포인트는, 결국 github 레포의 매니페스트를 수정하면, 그걸 모니터링하고 있는 argoCD가 자동으로(=Continuous) 그 수정된 사항을 반영시켜줌

- 2로 변경 후 apply

- 물론 자동으로 반영을 해주긴 하지만 10분 정도까지 걸릴 수 있기 때문에
sync를 눌러주면 즉시 반영됨
애플리케이션이 업데이트 됐다고 가정을 해보자
앱 업데이트(CD 관점)
CI
1. 프로그래밍 언어로 짜인 코드를 수정
2. 새로 앱빌드
3. 새로 컨테이너이미지 빌드 = 이미지의 태그가 변경이 됐다는 뜻함.
4. 그렇다면 이미지의 태그가 변경이 됐다는 사실을 어디에 명시? => 매니페스트 파일에 명시
CD
5. argoCD가 이를 인지해서 자동으로 apply를 해준다.
oolralra/ipnginx:latest 가 배포가 되어있는 상태 = 이미 만들어져 있는 구버전의 앱
oolralra/ipnginx:2 => 새로 업데이트된 앱. (hnginx) 호스트네임을 호출하는 앱


- rs가 두 개 => 기존 rs가 남아있음

- 새로 생성된 파드는 당연히 oolralra/ipnginx:2 라는 이미지로 구성되어있음. 즉 앱이 업데이트가 됐다는 의미임


- 아까는 ip주소가 나왔는데 지금은 호스트네임을 반환하는 것을 확인할 수 있음


- 기존이미지로 돌아간 상태.

- 다시 ipnginx로 돌아온 걸 확인할 수 있음

다시 SYNC를 클릭하면 전 상태로 돌아가는 걸 확인할 수 있음
argoCD의 장점
1. 설치가 쉽다
2. CD구성도 쉽다
3. 편리하게 버전 업데이트 및 롤백도 가능함
4. 시각화
실습 1)
ECR이나 도커허브를 통해 앱을 업데이트해보세요.
<여러분들 ECR이나 허브주소>/web-argo:1 은
nginx를 기반으로 'CD is difficult'라는 내용을 배포
<여러분들 ECR이나 허브주소>/web-argo:2 는
nginx를 기반으로 'CD is easy'라는 내용을 배포하는 이미지 일 때
github/<본인아이디>/web-argo 라는 레포에 매니페스트를 등록해 두고 매니페스트의 이미지를 web-argo:1에서 web-argo:2로 변경했을 때 10분 정도 대기후 자동으로 앱이 변경되는지 확인해 보세요.
디렉토리 구조
web-argo/
├── Dockerfile
└── index.html
web-argo:1 만들고 빌드 푸시 후, 다시 내용만 변경해서 빌드 후
<!-- index.html -->
<h1>CD is difficult</h1>
web-argo:2
<!-- index.html -->
<h1>CD is easy</h1>
Dockerfile 예시
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
이미지 빌드 & 푸시
# difficult 버전
docker build -t choyunji/web-argo:1 .
docker push choyunji/web-argo:1
# easy 버전 (index.html 수정 후 다시 빌드)
# index.html 내용 변경 후 ↓
docker build -t choyunji/web-argo:2 .
docker push choyunji/web-argo:2
위에 방식처럼 deployment 디렉토리를 생성하고


근데 잘못 만들고 다시 빌드랑 푸시를 했을 때
kubectl get pod
NAME READY STATUS RESTARTS AGE
web-argo-7d57c787fd-nnb5l 1/1 Running 0 21m
web-dep-555c7f6b5b-g5n78 1/1 Running 0 62m
web-dep-555c7f6b5b-wtl8s 1/1 Running 0 62m
-> 전에 잘못 만든 거 푸시했을 때 web-argo를 지우고 다시 해야 됨
-> 그래야 변경된 내용이 다시 반영됨
kubectl delete pod web-argo-7d57c787fd-nnb5l
#pod "web-argo-7d57c787fd-nnb5l" deleted
-> 지우면 자동으로 다시 생성됨
kubectl get pod
NAME READY STATUS RESTARTS AGE
web-argo-7d57c787fd-nnb5l 1/1 Running 0 21m
web-dep-555c7f6b5b-g5n78 1/1 Running 0 62m
web-dep-555c7f6b5b-wtl8s 1/1 Running 0 62m
-> 바로 다시 생성된 걸 볼 수 있음
curl k8s-default-svcip-1db558bd67-2c2a46f438a8d8bd.elb.ap-northeast-2.amazonaws.com
#<h1>CD is difficult<h1>
-> 결과가 잘 나오는 걸 확인 할 수 있음

변경한 후



'AWS Cloud School 8기 > CICD' 카테고리의 다른 글
[CI/CD] Github-action을 통한 CI/CD (1) | 2025.05.11 |
---|