노드 안에 pod가 들어간다. 노드가 VM 하나라고 보는 게 맞을 것 같다.
pod에 애플리케이션이 올라가는 거다.
컨테이너, VM?
애플리케이션과 해당 종속성을 어디에서나 실행할 수 있는 독립형 단위로 격리하는 것.
에너지 소비와 비용 효율성 측면에서 온프레미스보다 리소스를 효율적으로 사용할 수 있다.
VM?
말 그대로 실제 컴퓨터를 에뮬레이션한 것.
“하이퍼바이저”를 사용. 물리적 시스템 위에서 실행.
하이퍼바이저?
- 호스트 시스템에서 실행됨.
- 호스트 시스템은 VM에 CPU, RAM 등의 리소스를 제공함.
- 호스트 시스템이 VM별로 리소스를 조정해 주는 역할을 해준다는 뜻.
컨테이너?
VM이 하드웨어의 가상화라면 컨테이너는 운영 체제 수준의 가상화.
컨테이너는 호스트 시스템의 커널을 다른 컨테이너와 공유한다는 것이 중요.
이런 컨테이너를 만드는 가장 널리 퍼져있는 기술이 Docker이다.
- 편리하다.
- Docker 이미지를 이용하면 어디에서나 수정 없이 애플리케이션을 빠르게 구축하고 테스트할 수 있다.
- “한 번 구축하면 어디에서나 실행 가능”
- 속도
- 빠르고 가볍다.
- VM을 사용하면 매번 가상 운영체제를 부팅해야 하지만 Docker는 몇 초만에 생성하고 실행할 수 있다.
- Docker Hub
- Docker 이미지용 앱스토어 같은 곳이다.
- 다수의 이미 만들어진 이미지를 가져다 쓸 수 있다.
- 모듈성 및 확장성
- 애플리케이션의 기능을 개별 컨테이너로 쉽게 분리할 수 있다.
- 예를 들어 api용 컨테이너, postgresql용 컨테이너, redis용 컨테이너를 만들고 연결해서 더 큰 애플리케이션을 만들 수 있다.
도커 엔진
도커가 실행되는 계층.
컨테이너, 이미지, 빌드 등을 관리하는 경량 런타임 및 도구.
도커 클라이언트
도커의 최종 사용자로서 통신하는 것. UI라고 생각하면 됨.
도커 클라이언트는 도커 데몬에 명령을 전달함.
도커 데몬
컨테이너 구축, 실행, 배포와 같이 도커 클라이언트에 전송된 명령을 실제로 실행하는 것.
사용자가 직접 데몬과 통신할 수는 없음.
도커 클라이언트와 통신을 하고 도커 클라이언트는 호스트 시스템 또는 다른 시스템에서 실행될 수 있고 그 클라이언트가 호스트 시스템에 있는 도커 데몬과 통신하게 됨.
도커파일 (Dockerfile)
도커 이미지를 빌드하기 위한 지침을 작성하는 곳.
소프트웨어 패키지 설치, 노출 포트 지정, 환경 변수 전달 등을 작성.
Dockerfile 설정 이후에는 docker build 명령어를 통해 이미지를 빌드할 수 있음.
도커 이미지
도커파일에 작성된 명령들은 이미지 파일 내부의 레이어로 분리됨.
이 레이어 시스템 때문에 새 컨테이너를 생성, 실행할 때 가볍고 빠르게 됨.
전체 파일 세트를 복제하는 것이 아니라 변경된 레이어에 대해서만 업데이트를 전파함.
볼륨
컨테이너가 생성될 때 초기화되는 컨테이너의 데이터 부분.
이 데이터 볼륨은 Union File System과 별개이다.
컨테이너를 파괴, 업데이트 ,재구축 하여도 데이터 볼륨은 그대로 유지된다.
따라서 이 볼륨을 여러 컨테이너 간에 공유할 수 있다.
도커 컨테이너
애플리케이션을 실행하는 데 필요한 모든 것이 포함된 상자.
EKS 클러스터 만들기
- 쿠버 컨트롤 플레인 구성하거나 유지할 필요없이 AWS에서 쿠버를 쉽게 실행할 수 있는 관리형 서비스
- AWS가 쿠버 마스터 노드를 관리해줌.
- api-server, etcd 등 스스로 관리할 필요가 없음.
- worker node는 private VPC 안에 위치함.
- 네트워크 문제를 간단하게 해결가능 함.
- VPC CNI를 사용하여 원래처럼 같은 VPC 내에 pod를 넣고 쓸 수 있음.
- 대신 ENI 갯수에 따라서 생성할 수 있는 최대 pod의 수가 제한됨.
- eks 생성하는 방법은 console, IaC, eksctl이 있다.
- console은 웹페이지를 통해서 만드는 것이다. 대신 변경에 대한 추적을 하기가 힘듬.
- eksctl을 사용하는 경우 eks-cluster.yaml 같은 설정 파일을 통해서 배포를 할 수 있기 때문에 추적은 용이함.
- IaC 도구를 사용한다면?
- Terraform이나 AWS CDK 등으로 다른 AWS 도구를 다르는 방법과 통합적으로 사용할 수 있다는 장점이 있긴 함.
- CDK는 AWS에 대한 높은 추상화가 되어 있고 자신에게 편한 프로그래밍 언어를 이용하여 제어할 수 있게 해줌.
- 하지만 가장 많이 쓰이는 건 Terraform이다.
Terraform EKS Module로 클러스터 생성하기
brew install tfenv
tfenv list-remote
tfenv install latest
- admin 이라는 이름의 AdministratorAccess 권한을 가진 IAM 유저를 생성한다.
- Access Key를 생성한다.
- aws CLI v2를 이용하여 iterm에 profile을 설정해준다.
- aws configure —profile vpc이름
- aws sts get-caller-identity —profile vpc이름 을 이용하여 현재 설정된 프로파일을 확인할 수 있다.
일단 NHN도 테라폼 가이드가 있긴 하다. 강의처럼 NKS를 테라폼으로 구성할 수 있는지 확인해봐야 겠음.
쿠버 클러스터 인가 체계는 RBAC
인증은 IAM
kubernetes 오브젝트
- 오브젝트의 기본 정보와 의도한 상태를 기술한 오브젝트 spec을 제시
- 오브젝트 생성을 위한 k8s API 요청은 JSON 형식 정보를 포함.
- 보통은 .yaml 파일로 kubectl에 제공
- kubectl은 API 요청이 이루어질 때, yaml을 json 형식으로 변환하여 전달함.
kubectl apply -f deployment.yaml
같은 형식으로 사용. (선언적 형태. 과거 내역이 남아서 관리에 용의. 멱등성도 있음.)
YAML의 기본 구조
- apiVersion(string)
- kind (string)
- metadata (dictionary)
- spec (dictionary)
- status (dictionary)
- 사람이 관리하는 게 아니고 쿠버가 알아서 작성.
- 오브젝트의 실제 상태를 기술
- 쿠버 컨트롤 플레인은 오브젝트의 실제 상태를 의도한 상태에 일치시키기 위한 방향으로 동작.
Node(Worker node)
- 워크로드가 돌아가는 컨테이너를 배치하는 물리(가상) 머신
- 컨트롤 플레인에 의해 관리됨
- 일반적인 운영환경에서는 multi node로 운영
- 각 노드는 kubelet / container-runtime / kube-proxy 가 포함됨.
- cordon, drain 등의 명령어
Namespace
- 동일 물리 클러스터를 기반으로 하는 복수의 가상 클러스터를 지원하는 개념.
- 클러스터를 논리적으로 나누고 액세스를 제한하여 리소스를 생성, 관리
- 논리적으로 구분이 되지만 격리가 되는 것은 아님.
- 격리를 위해서는 network policy 등 다른 오브젝트를 추가로 사용 해야 함.
Pod
- 최소단위 쿠버 객체
- docker 컨테이너와는 조금 다르게, pod는 하나 이상의 컨테이너를 포함 가능.
- 애플리케이션 컨테이너(하나 또는 다수), 스토리지, 네트워크 등의 정보를 포함.
- MSA 구조 하에서는 decoupling이 원칙이므로 한 파드에 하나의 컨테이너만 있는 게 일반적임. (하나의 컨테이너는 하나의 목적만을 갖는다.)
- 하지만 A 라는 컨테이너의 서브처리를 위한 용도로 B 컨테이너가 있는 경우와 같은 상황이 있을 수 있기 때문에 한 파드 안에 여러 컨테이너를 생성할 수 있긴 함. (Sidecar, Adapter, Ambassador 구조 등)
- 용례
- taint, affinity, toleration을 이용해서 특정 노드에 들어가도록, 들어가지 않도록 할 수 있다.
- resources 옵션을 줘서 사용량을 제한해 주어야 한다. 값이 없으면 무제한이 된다.
k run nginx2 --image-nginx --dry-run=client -o yaml > pod.yaml
이런식으로 베이스 파일의 야믈 파일을 만들어낼 수도 있음.- Pod에 레이블을 지정할 수도 있음.
- k label pods 파드이름 key=value (대신 이렇게 하면 코드로 남는게 아니라서 IaC에 위배되므로 코드를 고치고 apply해서 반영하는 게 좋음.)
Replicaset
- pod의 레플리카를 생성하고 지정한 pod 수를 유지하는 리소스
- 기존의 replicaset controller에서 replicaset으로 변경
Deployment
- 복제된 애플리케이션을 관리하는 오브젝트
- 롤링 업데이트, 롤백 등을 구현할 수 있게 해줌.
- 따라서 가장 권장하는 컨테이너 기동 방법이 됨.
- 배포 전략
- recreate (다운타임이 있어서 잘 못씀)
- rollingupdate
- maxUnavailable
- maxSurge
- % 또는 절대값으로 설정 가능.
Daemonset
- 모니터링용 하는 실행하거나 노드를 모니터링 클러스터의 각 노드에 pod을 하나씩 띄울 때 사용.
- 로그수집기를 실행하거나 노드를 모니터링 하는 모니터링용 데몬 등. 클러스터 전체에 항상 실행시켜 두어야 하는 pod을 실행하는데 사용
- kube-proxy, fluent-bit 등…
- ** kind에 이름을 적을 때는 DaemonSet 처럼 무조건 파스칼 케이스로 적어야 한다.
Service
- pod 집합과 같은 어플리케이션에 접근 경로나 Service Discovery를 제공
- Pod를 외부 네트워크에 연결하고, pod로의 연결을 로드밸런싱하는 네트워크 오브젝트.
- 하나의 MS 단위
- pod의 label Selector를 통해 정의.
- 타입
- ClusterIP
- k8s 클러스터 내부에서만 통신이 가능한 Internal network 가상 IP가 할당
- service - pod 간 통신은 kube-proxy가 담당
- 서비스 디버깅이나 테스트시 보통 사용.
- Nodeport
- NAT를 이용해 클러스터 내 Node의 고정된 port를 갖는 IP로 service를 노출
- 클러스터 외부에서 접근은 <NodeIP>:<NodePort>
- Port 사용범위: 30000 ~ 32767
- Loadbalancer
- 클라우드 공급자의 로드밸런서를 이용해 service를 외부로 노출
- 외부 로드밸런서를 사용하기 때문에 SPOF에 강함.
- L4, L7 레이어를 통해 service 노출
Ingress
- Service type은 아니지만 Service 앞에서 Smart router 및 entry point 역할을 하는 오브젝트
- 외부에서 접근 가능한 URL, LB, SSL Termination 등을 통해 Service에 대한 HTTP 기반 접근을 제공
- 클러스터에 하나 이상의 실행 중인 Ingress Controller가 필요. (aws-lb-controller, nginx ingress)
- 필요성?
- nodePort는 30000 이상의 포트 넘버를 클라이언트가 기억해야 함.
- 따라서 일반적으로는 proxy를 두고 80 → 3xxxx로 포워딩 해주는 방식으로 제공.
- Ingress가 결국 스마트 라우터의 역할을 해준다고 볼 수 있음.
HPA
- horizontal pod autoscaler
- scale out 도구라고 생각하면 됨
VPA
- vertical pod autoscaler
- 컨테이너에 할당하는 CPU/메모리 리소스의 할당을 자동으로 스케일링 해주는 오브젝트
- 서비스 적용 전 pod resource request에 어떤 값이 적정한지 명확하지 않을 때 유용
- VPA > HPA > CA 순으로 스케일링 동작
- 하지만 VPA는 EKS가 지원하지도 않고 HPA와 같이 사용하면 충돌한다. 안쓰는 것 추천.
환경 변수
- env-pod.yaml 만들고 apply -f env-pod.yaml
configmap
- 워크로드에 필요한 설정 정보를 key-value 형태로 저장할 수 있는 데이터 오브젝트
- 간단한 환경변수 부터 nginx.conf와 같은 설정 파일도 저장 가능
volume
- 스토리지 볼륨을 추상화하여 pod와 느슨하게 결합시킨 리소스
- 오브젝트의 형태가 아닌 pod 내에서 정의
- 볼륨 플러그인
Persistnet Volume
- 추상화된 가상의 volume 오브젝트로, 별도로 정의 및 생성하여 pod와 연결
Persistent Volume Claim (PVC)
- PV를 요청하는 오브젝트
- 용량, label 등을 기반으로 PV에 대한 요청이 들어오면 스케줄러가 현재 가지고 있는 PV에서 적당한 볼륨을 할당
ServiceAccount
- 사람이 아닌, machine이 사용하는 account (프로메테우스, 젠킨스 등)
- Pod 내 프로세스에 identity를 제공
- 모든 namespace는 default service account가 있으며, 기본 k8s api를 사용할 수 있는 제한된 권한을 제공
K9s
- kubectl 대신 사용할 수 있는 터미널 기반 UI 유틸리티
LENS
- kubectl 대신 사용할 수 있는 Desktop App
kubectx & kubens
- kubectx: kubectl의 컨텍스트 간의 전환을 도와주는 도구
- kubens: k8s 네임스페이스 간에 쉽게 전환하고 kubectl에 맞게 구성하는 도구
- 개발 클러스터에 적용할 내용을 운영에 적용해버린다든가 하는 문제를 해결해 줄 수 있음.
Karpenter
- 운영 부담 절감
- 신속한 Node 추가와 제거
- 자동 Node 롤링
- 다양한 인스턴스 타입을 쉽게 적용
- 빠른 버전 업그레이드
Karpenter 컴포넌트
- Karpenter Pod
- Controller: pod 상태를 감시하고 Node를 확장 및 축소하는 주요 역할
- Webhook: Provisioner CRD에 대한 유효성 검사 및 기본값을 지정
- Provisioner CRD(Custom Resource Definition)
- Karpenter에 의해 생성되는 Node와 Pod에 대한 제약조건을 지정하는 template
ECR
- 도커 허브처럼 어디서나 애플리케이션 이미지 및 아티팩트를 안정적으로 배포할 수 있도록 호스팅을 제공하는 완전관리형 컨테이너 레지스트리
레지스트리
- 각 AWS 계정마다 제공되어 하나 이상의 레포지토리를 생성하고 이미지를 저장할 수 있는 공간
Repository
- 도커 이미지, OCI 이미지 및 OCI 호환 아티팩트를 저장
사용자 권한 토큰
- 클라이언트가 ECR 레지스트리에 AWS 사용자로서 인증을 하고 이미지를 푸시 및 가져올 수 있는 토큰
레포지토리 정책
- 레포지토리 및 레포지토리 내 이미지에 대한 액세스를 제어
수명 주기 정책
- 레포지토리에 있는 이미지의 수명 주기를 관리 (시간, 개수 기준)
이미지 스캔
- 컨테이너 이미지의 소프트웨어 취약성을 식별
교차 리전 및 교차 계정 복제
풀스루 캐시 규칙
- 프라이빗 레지스트리에 원격 퍼블릭 레지스트리의 레포를 캐시하는 방법을 제공
Kubecost
- k8s 환경에 대한 비용분석뿐 아니라 비용 최적화, 성능관리, Alert를 제공하는 FinOps 솔루션
- Dashboard 현태로 구성되어 가시성을 제공
- 비용구분, 비용 모니터링, 비용 최적화 인사이트, 예산 설정 및 알람 기능 등
- (무료 버전도 있음)
AWS LB Controller 구성
- Ingress를 다뤄줄 컨트롤러 구성
- kubectl, eksctl을 사용하여 설치하거나 terraform module을 사용하여 설치하는 방법이 있음.
생성할 자원
- OIDC - terraform eks 모듈에서 enable_irsa = true로 자동생성
Cert-manager 설치
- k8s 오브젝트로 생성
Controller가 사용할 IAM policy & IAM role 생성 (terraform 이용)
Controller의 ServiceAccount 생성
Controller 배포
어플리케이션을 도커 이미지로 만들기
dockerfile 작성
이미지 빌드 시 ECR에 로그인 하고 이미지를 푸시하면 되는데 M1 이상의 ARM 아키텍쳐의 경우
export DOCKER_DEFAULT_PLATFORM=linux/amd64
를 추가해줘야 정상동작시킬 수 있다.왜냐면 EC2는 linux/amd64 (x86 아키텍처로 동작하고 있기 때문이다.
로컬 이미지 테스트 후 manifest 작성
manifest 레포에는 namesapce, deployment, service, ingress 가 포함된다.
Gitops 파이프라인
개발자
- 저장소에 푸시
- 깃 액션으로 ECR에 이미지 빌드해서 업로드
데브옵스
- k8s 리소스 생성 및 면경
- 인프라 레포에 푸시
- ArgoCD 등 gitOps 도구로 EKS에 앱 배포.
- 이 때 ECR에 올라간 이미지로 pod 기동
Github Action 구성 사전 작업
- 깃 액션이 ECR 접근에 사용할 IAM User를 Terraform으로 생성
- 테라폼으로 사용하기 위해 IAM User의 credential 생성 발금, github PAT 생성 후 Github Action의 Repository secrets에 저장.
ArgoCD
- GitOps스타일의 배포를 지원하는 CD 도구
- 원하는 설정 사항을 변경하여 Git에 푸시하면 쿠버네티스 클러스터의 상태가 Git에 정의된 상태로 동기화
- 지정한 대상 환경에 애플리케이션을 원하는 상태로 sync
cli 설치
brew tap argoproj/tap
brew install argoproj/tap/argocd
기본 설정은 ClusterIP로 되어 있는데 우리는 외부에서도 적용이 가능해야 되기 때문에 LoadBalancer 타입으로 변경해주어야 한다.
EKS 어플리케이션 운영
서비스 스케일링 메커니즘
- 메트릭 서버 구성
- HPA todtjd
- pod에 request resource 추가
- karpenter 구성
- 부하테스트
CI/CD
- 배포 과정을 자동화하여 더욱 짧은 주기로 배포
- 투명성, 책임성
- 장애 발생시: 뭐 건든거 있나요? 누가 했나요?
- 롤백 또는 핫픽스 (휴가 중에 전화…?)
- 자동화
- 코드 품질 보장
- PR로 협업시 approve 최소 조건으로 사용 가능
- 개발 → 운영 환경으로 원활한 전환
- 협업 효율성의 향상
CI
- 지속적 통합 (Continuous Integration)
- 여러 개발자의 코드 변경 사항을 공유 저장소에 지속적으로 통합하는 것
- 개발 프로세스 초기에 오류와 충돌을 미리 발견하기 위한 것.
- 멀티 아키텍쳐에 대한 고려도 필요해졌다.
CD
- Continuous Delivery / Deployment
- CI 프로세스에서 성공적으로 빌드/테스트/검증된 후 코드 변경 사항을 운영환경으로 자동 전달하는 것을 포함
다양한 배포 방식
- all at once
- blue-green
- rolling
- canary
안정성 때문에 이런 방식들이 생겨남.
선행 작업: DB, Network, Policy (infra)
스테이징 환경이 있는 경우 스테이징이 성공한 경우 라우팅만 바꿔서 서비스를 변경한다. (그린: 이전, 블루: 새)
하지만, 이런 경우 기존 서비스가 IP table을 가진 경우 라우팅을 바꿨는데도 이전 로드밸런서에 접근하는 경우도 생김.
이런 문제를 해결하기 위해 기존 그린의 로드밸런서의 타겟그룹만 스테이징의 파드에 꼽는 방법도 있음…
하지만 이미 구조만 봐도 불편함.
그리고 서버를 두 벌 둬야 되기 때문에 비용이 최소 두 배가 됨.
그래서 요즘은 rolling 배포를 많이 함.
서버를 여러 인스턴스로 붙여놨다가 몇 개씩 끊어내고 새 걸로 교체하는 과정.
하지만 이 케이스에서는 새로 올리는 버전이 구버전과 완전히 호환이 되어야 함…
이를 거의 모두 해결한 게 canary 방식.
트래픽의 퍼센트를 조정해서 점진적으로 서버를 이전함.
대신 그만큼 복잡하기 때문에 모든 CI/CD 과정이 자동화가 되어 있어야 활용이 가능함.
이제는 데브옵스를 넘어서 DevSecOps를 해야 한다.
- Dev
- planning → creation → verifying → building → packaging
- Sec
- scan → analyze → remediate → monitor
- Ops
- release → deploy → operate → monitoring
DataOps, MLOps, AIOps, ITOps 등 복잡한 개념들이 등장하고 있음.
DevSecOps의 로드맵
Github action
- 제공 형태: self-hosted, github-hosted
- YAML 형태로 작성
- 기본경로: .github/workflows/*.yml
구성요소
- Workflow: 하나 이상의 잡으로 구성된 프로세스
- Event: workflow를 동작시키는 trigger
- Job: 동일한 runner에서 실행되는 step의 모음
- Action: Custom application
- Artifact: 작업 완료 후 보관하는 결과물
- Cache: 자주 사용되는 패키지나 툴
자기 랩탑의 pub key와 인스턴스의 pub key를 깃 레포에 등록해줘야 함.