NHN Cloud의 쿠버네티스 서비스
Cloud Native의 도입 배경
- 클라우드 플랫폼 비즈니스가 확대됨에 따라 애플리케이션 간의 협업과 통합의 중요성이 필요
- 비즈니스 변화에 신속한 대응 체계가 필요
- 새로운 요구사항에 대해 빠르게 대응하면서 유연하고 신속한 확장성이 요구
- 장애를 사전에 예방하고 발생시 신속히 대응할 수 있는 능력이 중요
Cloud Native 4대 요소
CI/CD
: 개발-운영간 업무 속도의 증가MSA
: 서비스 안정성, 스케일링 용이성 개선Container
: IT 이식성과 유연성 확보DevOps
: App 서비스 개선 속도 증가
클라우드 네이티브를 적용하기 좋은 서비스
- 변화가 많은 서비스 중심을 우선적으로 검토
- 정부내지원 서비스: 업무 변화가 적음 (적용 불필요)
- 공통기술 서비스: 시스템 연계성이 매우 높음 (적용 어려움)
- 대국민 서비스: 업무 변화가 많음, 특수성에 따른 부하가 높 음 (적용 유리)
NKS 특징
NHN Cloud 서비스를 통해 Cloud Native 핵심 기술인 컨테이너 오케스트레이션할 수 있도록 지원하는 서비스
주요기능
- NHN Cloud에 최적화된 Kubernetes 클러스터 생성 관리
- Kubernetes 클러스터 웹 콘솔 제어 기능 제공
- kubectl config 설정 파일(yaml) 파일 제공 및 연동
- NHN Cloud Web Console을 통해 편리한 가용성 관리 지원
- 빠른 Kubernetes 최신 버전 제공
서비스 대상
- 애플리케이션을 컨테이너화하여 서비스하는 사용자
- 컨테이너화된 애플리케이션을 서비스할 때 컨테이너 오케스트레이션이 필요한 사용자
NCR (NHN Container Registry) 특징
Docker 컨테이너 이미지를 쉽고 안전하게 저장, 관리하고 배포할 수 있는 컨테이너 레지스트리 서비스이며 NCR 서비스는 NKS와 연동해 사용자의 애플리케이션을 손쉽게 컨테이너 환경으로 구축할 수 있다.
주요 기능
- Docker 이미지 매니페스트 v2 호환으로 Docker 명령줄 도구 지원
- HTTPS 암호화, NHN Cloud 인증 및 권한 관리를 통한 보안성 강화
- NHN Cloud Object Storage를 기반으로 확장성 및 안정성 제공
- 웹 콘솔을 통한 레지스트리 관리
구성 요소
- 레지스트리: 컨테이너 이미지 보관, 관리 단위
- 이미지: 아티팩트들의 집합
- 아티팩트: 하나 이상의 레이어를 가지는 특정 컨테이너 이미지 빌드를 의미
- 태그: 아티팩트를 구분하기 위한 일종의 식별자
NHN Container Service NCS 특징
- NHN Container Service (NCS)는 컨테이너를 구동하는 환경을 제공하는 서비스
- VM 인스턴스, Kubernetes와 같은 컨테이너 실행 환경을 구성하지 않아도 이 서비스를 이용하여 컨테이너 실행 가능
컨테이너 배경
Immutable (불변) Infrastructure 패러다임
- OS와 서비스 환경(런타임, 코드 등)을 분리하고 한 번 설정한 이미지(환경 요소 등)는 변경하지 않는다는 개념
- 서비스 환경을 이미지로 생성하고 이를 배포하는 방식
3가지 장점
- 관리 편의성: 이미지만 관리하면 되고 버전 관리를 활용 가능
- 테스트: 개발 환경과 운영 환경이 동일하게 구성
- 휴대성: OS와 서비스 환경을 분리하여 가벼움
컨테이너
호스트 OS 상에 논리적인 구획(컨테이너)을 만들고 어플리케이션을 작동시키기 위해 필요한 라이브러리, 애플리케이션 등을 하나로 모아 하나의 Image로 만든 후 가상화하여 운용하는 것
컨테이너 운영의 고민
배포관리
: 어떤 컨테이너를 어느 호스트에 배치하여 구동시킬 것이며 한정된 자원으로 최적의 스케줄링을 구성할 방안은 ?제어 및 모니터링
: 구동 중인 각 컨테이너들의 상태를 어떻게 추적하고 관리할 것인가 ?스케일링
: 수시로 변화하는 운영 상황과 사용량 규모에 어떻게 대응할 것인가 ?네트워킹
: 운영되는 인스턴스 및 컨테이너들을 어떻게 상호 연결할 것인가 ?
이러한 고민들을 해결할 컨테이너 운영의 현실적인 해결방안은 컨테이너 오케스트레이션이다.
컨테이너 오케스트레이션이란 ?
대규모 컨테이너들이 안정적으로 운영될 수 있도록 관리의 복잡성을 줄여주고 이를 자동화하는 것
컨테이너 운영의 현실적 해결방안
- 여러 컨테이너의 배포 프로세스를 최적화
- 컨테이너 자동 배치 및 복제
- 컨테이너 그룹에 대한 로드 밸런싱
- 컨테이너 장애 복구
- 클러스터 외부에 서비스 노출
- 컨테이너 추가 또는 제거로 확장 및 축소
- 컨테이너 서비스간의 인터페이스를 통한 연결 및 네트워크 포트 노출 제어
컨테이너 관리의 필요성
- 필요한 컴퓨팅 자원을 즉시 제공
- 이미지 기반 구성, 배포 효율화, 개발환경과 운영환경의 일관성 있는 구성
- 업그레이드 또는 패치 시 다운타임 최소화
- 비정상 애플리케이션 및 장애 발생 시 정상 서버 노드 자동 재배치
- 애플리케이션 단위 오토스케일링
- 멀티 / 하이브리드 클라우드 기반 운영
서비스 디스커버리와 로드 밸런싱
- 쿠버네티스는 DNS 이름을 사용하거나 자체 IP 주소를 사용하여 컨테이너를 클러스터 내부에서 노출
- 컨테이너에 대한 트래픽이 많으면 쿠버네티스는 네트워크 트래픽을 로드밸런싱하여 컨테이너를 안정적으로 운영 가능
스토리지 오케스트레이션
- 쿠버네티스를 사용하면 로컬 저장소, 공용 클라우드 공급자 등과 같이 원하는 저장소 시스템을 자동 탑재 가능
자동화된 롤아웃과 롤백
- 쿠버네티스에 배포된 컨테이너의 원하는 상태를 서술할 수 있으며 현재 상태를 원하는 상태로 설정값으로 변경 가능
- 쿠버네티스를 자동화해서 배포용 신규 컨테이너를 만들고 기존 컨테이너를 제거 후 모든 리소스를 새로운 컨테이너에 적용하는 동작 가능
자동화된 빈 패킹
- 컨테이너화된 작업을 실행하는데 사용할 수 있는 쿠버네티스 클러스터 노드를 제공
- 각 컨테이너가 필요로 하는 CPU와 메모리(RAM)를 쿠버네티스에게 지시 후 컨테이너를 노드 에 맞추어서 리소스를 최적화되도록 지원
자동화된 복구
- 쿠버네티스는 실패한 컨테이너를 다시 시작하고, 컨테이너를 교체하며, '사용자 정의 상태 검사'에 응답하지 않는 컨테이너를 대체(BackGround 작업)
시크릿과 구성 관리
- 쿠버네티스를 사용하면 암호, OAuth 토큰 및 SSH 키와 같은 중요한 정보를 저장하고 관리 가능
- 컨테이너 이미지를 재구성하지 않고 스택 구성에 시크릿을 노출하지 않고도 시크릿 및 애플리케이션 구성을 배포 및 업데이트 가능
쿠버네티스 작업 단위 구성
- Cluster: 컨테이너로 구성된 애플리케이션을 실행하는 노드의 집합
- 컨테이너화된 애플리케이션을 기동
- Master Node + Worker Node로 구성됨
- Node: 노드는 쿠버네티스의 작업 장비 (Worker Machine)
- 쿠버네티스의 실제 동작 머신 (VM 인스턴스 또는 물리장비)
- 노드는 Pod들을 구동하기 위해 필요한 서비스들을 가짐
- 마스터 Node에 의해 관리
- Container Runtime Interface, kubelet, kube-proxy가 포함
- Deployment: 일반적으로 로컬 상태가 없는 파드를 실행하여 복제된 애플리케이션을 관리하는 API 오브젝트
- Replication Controller와 ReplicaSet의 추상화 개념
- ReplicaSet을 Rolling-update 하기 위해 deployment를 통해 사용
- Pod: 가장 작고 단순한 쿠버네티스 오브젝트, 파드는 사용자 클러스터에서 동작하는 컨테이너의 집합
- 쿠버네티스의 최소 단위 객체
- 클러스터상에서 동작하는 컨테이너의 집합을 단일 프라이머리 컨테이너를 구동하기 위해 셋업
오브젝트 특징 (Service)
- 여러 Pod를 서비스하면서 이를 로드밸런싱하여 하나의 IP와 포트로 묶어 서비스 제공
- Pod의 목록 지정 시 IP 주소를 유연하게 선택하기 위해 라벨(label)과 라벨 셀렉터(label selector) 활용
내/외부 통신을 위한 Service 종류
- ClusterIP: CNI Plugin에서 할당하는 IP 주소를 활용하여 Pod에 접근할 수 있도록 함
- NodePort: Worker Node의 IP, Port와 연계하여 노드 수준에서 접근할 수 있도록 함.(Private Zone 통신에 활용 가능)
- LoadBalancer: Public IP를 할당하여 CSP(NHN Cloud) Load Balancer와 연계하여 외부 통신이 가능하도록 함 (DMZ Zone 통신에 활용 가능)
오브젝트 특징 (Namespace)
- 한 쿠버네티스 클러스터 내의 논리적 분리 단위
- Pod, Service 등은 Namespace 별로 생성, 관리 가능, 사용자 권한 역시 구별하여 부여 가능
- 사용자별로 접근권한 제어 가능
- 리소스 할당량(Quota) 지정 가능
- 리소스 나누어 관리 가능(Pod, Service 등)
- 논리적 분리 단위로 물리적, 기타 장치를 통해 환경을 분리한 것은 아님 (다른 Namespace간 통신 가능)
- 보안이 높은 수준의 운영을 위해서는 쿠버네티스 클러스터 자체를 분리하는 것을 권장
오브젝트 특징 (Controller)
- 기본 오브젝트들을 생성하고 이를 관리하는 역할을 수행
- Replication Controller (RC), Replication Set(RS), Daemon Set, Job, Stateful Set, Deployment
- Controller에 묶인 Object의 경우 Controller 삭제 시 전체 영향을 받음에 주의
ReplicaSet (RS)
- Replication Controller의 발전된 형태
- 집합 기반의 Selector를 지원(보다 포괄적인 Replication 관리 가능, 범위 지정)
- Pod를 관리해주는 역할, 지정된 숫자로 Pod를 기동, 관리하는 역할
- Replica 수, Pod Selector, Pod Template 3가지 구성
- Replica 수: RC에 의해서 관리되는 Pod의 수를 유지하도록 함
- Pod Selector: 라벨 기반 RC가 관리한 Pod를 호출하는 데 사용
- Pod Template: Pod 추가 기동 시 어떻게 pod를 만들지 pod에 대한 정보(도커 이미지, 포트, 라벨 등) 정보 정의
- NKS에서 제공하는 노드는 최대 10개
- 다운타임 없이 쿠버네티스 버전업 및 노드 추가 가능
- 단계별로 버전업 권고
- 쿠버네티스 버전업은 마스터 노드부터 업그레이드 후에 워커 노드 업그레이드
- 만약 마스터 노드보다 먼저 워커 노드를 최신 업그레이드할 경우 마스터 노드가 워커 노드를 인지하지 못하는 에러가 발생할 수도 있음
- kubectl로 로드밸런성 생성 및 삭제 시 콘솔에서도 생성 및 삭제 확인 가능
- NKS 클러스터 - 노드 목록 - 노드 추가를 통해 노드 추가 가능
초기 구성
- NKS 클러스터 생성, 노드 2개
- 클러스터 생성 후 워커 노드를 인스턴스 화면에서 확인하기 전까지 약간의 딜레이
- 동일한 가용 영역에 Management 인스턴스 생성 (Ubuntu)
- Management 인스턴스에 SSH 접속
- Management 인스턴스에 기본 Tool 설치
- kubectl, ca-certificates curl gnupg lsb-release, docker
- NCR 생성
kubeconfig 다운로드 / 생성된 NKS 클러스터 Config 적용
Management 인스턴스 SSH -> ROOT 사용자 전환 -> mkdir .kube -> vi .kube/config에 다운받은 kubeconfig 파일 붙여넣기
NCR로 이동 -> 생성한 레지스트리 클릭 -> 기본 정보: Docker 접근 명령어 (docker login ncr-uri
)
API Access Key, Secret Key 발급 후 활성화
Username에 발급 받은 Access Key 입력, Password에 발급 받은 Secret Key 입력
Docker Hub에서 nginx 이미지 다운로드
컨테이너 실행시 ID를 "cont_nginx"로 지정한 뒤 nginx image로 생성 후 백그라운드(-d 옵션)로 실행
docker run -d --name=cont-nginx nginx:latest
cont-nginx의 로컬 네트워크 주소 확인
docker inspect cont-nginx | grep IPAddress
nginx 구동 확인
curl 172.17.0.2
현재 상태를 이미지로 저장
docker commit 컨테이너명 NCRURI/PATH/이미지명
docker commit cont-nginx 18cb105b-kr2-registry.container.nhncloud.com/nhn-ncr/nhn-nginx:1.0
로컬 이미지 확인
docker images
NCR에 이미지 푸시
docker push [REPO명]:TAG
docker push 18cb105b-kr2-registry.container.nhncloud.com/nhn-ncr/nhn-nginx:1.0
컨테이너 로컬로 복사
docker cp 소스 데스티네이션
docker cp cont-nginx:/usr/share/nginx/html/index.html ./index.html
index.html 파일 수정 (Welcome to NHN 2.0!으로 변경)
vi index.html
로컬에서 컨테이너로 복사
docker cp ./index.html cont-nginx:/usr/share/nginx/html/index.html
현재 상태를 2.0 태그로 이미지 생성
docker commit cont-nginx 18cb105b-kr2-registry.container.nhncloud.com/nhn-ncr/nhn-nginx:2.0
2.0 이미지를 latest로 태그
docker tag 18cb105b-kr2-registry.container.nhncloud.com/nhn-ncr/nhn-nginx:2.0 18cb105b-kr2-registry.container.nhncloud.com/nhn-ncr/nhn-nginx:latest
latest 태그 이미지 NCR에 푸시
docker push 18cb105b-kr2-registry.container.nhncloud.com/nhn-ncr/nhn-nginx:latest
Private Registry 이미지를 받기 위한 인증 secrets 생성
kubectl create secret generic regcred --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
k get secrets
vi deploy-nginx.yaml
vi deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nhn-nginx-deployment
labels:
app: nhn-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nhn-nginx
template:
metadata:
labels:
app: nhn-nginx
spec:
containers:
- name: nhn-webserver
image: [사용자 NCR URI]/nhn-nginx:0.1
ports:
- containerPort: 80
imagePullSecrets:
- name: regcred
생성한 yaml 파일 적용 및 확인
k apply -f deploy-nginx.yaml
k get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nhn-nginx-deployment 3/3 3 3
세 개의 파드가 어느 노드에 생성되었는지 확인
k get pods -o wide
k get pods
NAME READY STATUS RESTARTS AGE
nhn-nginx-deployment-58876fbbb7-55kc6 1/1 Running 0 5m25s
nhn-nginx-deployment-58876fbbb7-7f72s 1/1 Running 0 5m25s
nhn-nginx-deployment-58876fbbb7-frcjp 1/1 Running 0 5m25s
pod 삭제
k delete pods nhn-nginx-deployment-58876fbbb7-frcjp
곧바로 pod 재생성하는지 확인
k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nhn-nginx-deployment-58876fbbb7-55kc6 1/1 Running 0 6m4s 10.100.83.12 nhn-nks-default-worker-node-1 <none> <none>
nhn-nginx-deployment-58876fbbb7-7f72s 1/1 Running 0 6m4s 10.100.33.3 nhn-nks-default-worker-node-0 <none> <none>
nhn-nginx-deployment-58876fbbb7-jf6n8 1/1 Running 0 6s 10.100.33.5 nhn-nks-default-worker-node-0 <none> <none>
외부에서 웹서버로 접근하도록 확인하기
k get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nhn-nginx-deployment 3/3 3 3 8m45s
로드밸런서 생성
k expose deployment nhn-nginx-deployment --port=80 --target-port=80 --type=LoadBalancer
샹성된 로드밸런서 확인
k get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 105m
nhn-nginx-deployment LoadBalancer 10.254.196.164 133.186.203.58 80:30008/TCP 37s
접속 확인
디플로이먼트 수정
k edit deployments.apps nhn-nginx-deployment
이미지 2.0으로 수정 및 pod 3개에서 5개로 수정
접속 확인
rollout 상태 확인
k rollout status deployment nhn-nginx-deployment
deployment "nhn-nginx-deployment" successfully rolled out
rollout 과정 확인
k describe deployments.apps nhn-nginx-deployment
rollout history 확인
k rollout history deployment nhn-nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
rollout 주석 달기 (CHANGE-CAUSE)
k annotate deployment/nhn-nginx-deployment kubernetes.io/change-cause='Version Latest Change'
history 주석 확인
k rollout history deployment nhn-nginx-deployment deployment.apps/nhn-nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 Version Latest Change
리비전 1로 원복
kubectl rollout undo deployment/nhn-nginx-deployment --to-revision=1
접속 확인
rollout 주석 달기
kubectl annotate deployment/nhn-nginx-deployment kubernetes.io/change-cause='Rollback to 1.0'
주석 확인
k rollout history deployment nhn-nginx-deployment deployment.apps/nhn-nginx-deployment
REVISION CHANGE-CAUSE
2 Version Latest Change
3 Rollback to 1.0