- 도서 시작하세요!도커/쿠버네티스의 2부 쿠버네티스 요약
- 기타 쿠버네티스를 위해 필요하다고 생각되는 내용은 중간중간 추가 정리
쿠버네티스 장점
쿠버네티스 단점
(추후정리)
1) 자체 서버 환경(On-premise)에 쿠버네티스 설치
쿠버네티스를 포함한 모든 인프라를 직접 관리해야 함.
쿠버네티스 및 서버 인프라를 세밀한 뿐까지 설정해 원하는 대로 구성할 수 있다는 것이 장점. 모든 관리를 직접 도맡아 해야 하므로 운영 및 유지보수가 복잡해질 수 있는것이 단점.
자체 서버 환경에서는 kubespray, kubeadm 등의 도구를 이용해 쿠버네티스 설치 가능
2) 클라우드 플랫폼에서 쿠버네티스 설치
클라우드 플랫폼의 서버 인스턴스만을 사용해 쿠버네티스를 설치하는 경우를 의미ㅏㅎ며 서버, 네트워크 등 인프라에 대한 관리는 AWS, GCP 와 같은 클라우드 제공자에게 맡기되, 쿠버네티스의 설치 및 관리는 직접 수행.
kubesparay, kubeadm, kops 등의 설치 도구를 이용 가능.
3) 쿠버네티스 자체를 클라우드 서비스로서 사용
AWS 의 EKS, GKE 등의 매니지드 서비스를 이용해 쿠버네티스를 사용. 쿠버네티스의 설치 및 관리까지 클라우드 제공자가 담당하므로 쿠버네티스 관리 및 유지보수의 비용이 줄어줄게 됨.
EKS, GKE 와 같은 매니지도 서비스를 사용하면 별도로 쿠버네티스를 설치할 필요 없이 실제 서비스 환경을 구성할 수 있다는 장점이 있음. (클라우드 플랫폼 Lock in side effect 를 고려해야 함)
쿠버네티스의 기능이 매우 빠르게 업데잍 되기 때문에 사소한 버전 차이로 인해 쿠버네티스의 사용 방법이나 기능이 달라질 수 있음.
너무 최신 버전이거나 너무 예전 버전을 사용하지 않는 것이 좋음.
쿠버네티스의 특징
1) 모든 리소스는 오브젝트 형태로 관리된다.
ex) 컨테이너의 집합(pods), 컨테이너의 집합을 관리하는 컨트롤러(Replica Set), 사용자(Service Account), 노드(Node) 까지 하나의 오브젝트로 사용할 수 있다.
// 오브젝트 리스트 보기
$ kubectl api-resources
// 특정 오브젝트의 설명
$ kubectl explain pod
2) 쿠버네티스는 명령어로도 사용할 수 있지만, YAML 파일을 더 많이 사용한다.
3) 쿠버네티스는 여러 개의 컴포넌틀 구성돼 있다.
$ kubectl apply -f [YAML_FILE_NAME]
$ kubectl get [OBJ_NAME]
$ kubectl get pods
$ kubectl describe pods [POD_NAME]
$ kubectl exec -it [POD_NAME] bash
// -c 옵션을 통해 특정 컨테이너 지정 가능
$ kubectl exec -it [POD_NAME] -c [CONTAINER_NAME] bash
$ kubectl logs [POD_NAME]
$ kubectl delete -f [YAML_FILE_NAME]
or
$ kubectl delete pod [POD_NAME]
쿠버네티스가 포드를 사용하는 이유 중 하나는 여러 리눅스 네임스페이스를 공유하는 여러 컨테이너들을 추상화된 집합으로 사용하기 위해서이다.
일례로 특정 포드 내의 사이드카 컨테이너에서 localhost 로 다른 컨테이너에 접근 가능하다. 이는 포드 내의 컨테이너들이 네트워크 네임스페이스 등과 같은 리눅스 네임스페이스를 공유해 사용하기 때문이다.
네임스페이스는 컨테이너의 고유한 네트워크 환경을 제공해주는 역할을 담당한다.
쿠버네티스의 포드는 도커에서 컨테이너 네트워크 타입을 통해 네트워크 네임스페이스를 컨테이너 간에 공유해 사용할 수 있도록 설정하여 여러 개의 컨테이너가 동일한 네트워크 환경을 갖는 네임스페이스 공유 개념을 사용한다.
레플리카셋은 사용자 대신 포들르 관리해준다...
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: [REPLICASET_NAME]
spec:
replicas: 3
selector:
matchLabels:
app: [app_NAME]
template:
.
.
.
replicas: 생성할 포드의 갯수
template: 포드를 생성할 때 사용할 템플릿 정의
레플리카셋 생성
$ kubectl apply -f [YAML_FILE_NAME]
최초 설정된 포드의 갯수를 늘리는 등의 작업을 진행 한 후 기존에 생성된 리플리카셋을 삭제하거나 할 필요 없이 kubectl apply -f 명령어로 yaml 파일을 쿠버네티스에 적용한다.
레플리카셋 삭제
$ kubectl delete rs replicaset-nginx
레플리카셋은 포드와 느슨한 연결을 유지하고 있으며 이러한 연결은 레플리카셋 정의 중 label selector 를 이용해 이뤄진다.
레플리카셋은 라벨 셀렉터의 라벨을 가지는 포드를 replicas 개수만큼 생성한다.
즉 spec.selector.matchLabels.app 항목의 라벨과 일치하는 template.labels.app 이 spec.replicas 의 갯수만큼 작성되어야 한다.
만약 숫자만큼 작성되지 않으면 포드를 정의하는 포드 템플릿 항목의 내용으로 포드를 생성한다.
레플리카셋은 포드를 생성하는 것이 아닌 일정 개수의 포드를 유지하는 것이다.
포드가 설정된 갯수보다 적은면 더 생성, 설정도니 갯수보다 많으면 포들르 삭제한다.
레플리케이션 컨트롤러는 이전 버전의 쿠버네티스에서 사용됨. (deprecated)
실제 쿠버네티스 운영 환경에서 레플리카셋을 YAML 파일에서 사용하는 경우는 거의 없다. 대부분 레플리카셋과 포드의 정보를 정의하는 Deployment 라는 이름의 오브젝트를 YAML 파일에 정의하여 사용한다.
Deployment 는 레플리카셋의 상위 오브젝트
Deployment 를 생성하면 해당 디플로이먼트에 대응하는 레플리카셋도 함께 생성된다.
Deployment 를 삭제하면 레플리카셋과 포드 또한 삭제된다.
$ kubectl get deployment
애플리케이션의 업데이트와 배포를 더욱 편하게 만들기 위함.
리비전을 남겨 롤백을 가능하게 해주고, 무중단 서비스를 위해 포드의 롤링 업데이트 전략을 지정
$ kubectl set image
$ kubeclt set image deployment [DEPLOYMENT_NAME] [CONTAINER_NAME]=[CONTAINER_VERSION] --record
위와 같이 진행 하거나 kubectl edit 명령어를 사용
혹은 YAML 파일을 직접 수정해 image 항목을 [CONTAINER_NAME]:[CONTAINER_VERSION] 으로 변경한 다음 kubectl apply -f 명령어로 적용
$ kubectl rollout history deployment my-nginx-deployment
$ kubectl rollout undo deployment my-nginx-deployment --to-revision=1
$ kubectl delete deployment,pod,rs --all
여러 개의 디플로이먼트를 하나의 완벽한 애플리케이션으로 연동하기 위해 포드 IP 가 아닌, 서로를 발견 할 수 있는 방법이 필요함.
서비스라고 부르는 별도의 쿠버네티스 오브젝트 생성을 통해 진행
$ kubectl get pods -o wide
쿠버네티스의 서비스는 포드에 어떻게 접근할 것이냐에 따라 종류가 여러개로 세분화 돼 있기 때문에 목적에 맞는 적절한 서비스의 종류를 선택해야 한다.
효율적으로 애플리케이션을 관리하기 위해 자주 Namespace, configMap, Secret 이 주로 사용된다.
$ kubectl get namespaces(ns)
// 모든 네임스페이스의 리소스를 확인
# kubectl get --all-namespaces
$ kubectl create namespace [NAMESPACE_NAME]
$ kubectl get pods --namespace default
# kubectl delete namespace production
별도로 네임스페이스를 생성하지 않았더라도 기본적으로 3개의 네임스페이스가 존재한다.
default, kube-public, kube-system
default 는 쿠버테니스를 설치하면 자도응로 설정되는 네임스페이스로, kubectl 명령어로 쿠버네티스 리소스를 사용할 때는 기본적으로 default 네임스페이스를 사용하게 된다.
네임스페이스 활용
1) 클러스터를 여러명이 동시에 사용해야 하는 경우 사용자마다 네임스페이스를 별도로 생성
2) 용도에 따라 네임스페이스를 여러 개 만들어 특정 목적의 디플로이먼트, 서비스를 운영
모니터링, 로드 밸런싱 인그레스 등의 특정 목적을 위한 용도로 별도 네임스페이스를 생성하여 사용 경우가 많음.
네임스페이스에 종속되지 않는 오브젝트
포드, 서비스, 레플리카셋, 디플로이먼트와 같이 네임스페이스 단위로 구분할 수 있는 오브젝는 '오브젝트가 네임스페이스 속한다(namespaced) 라고 표현한다.
// 네임 스페이스에 속하는 오브젝트 종류 확인
$ kubectl api-resources --namespaced=true
// 네임 스페이스에 혹하지 않는 오브젝트 종류 확인
# kubectl api-resources --namespaced=false
nodes 는 쿠버네티스의 오브젝트 중 하나이지만, 네임스페이스에 속하지 않는 대표적인 오브젝이다. 쿠버네티스 클러스터에서 사용되는 저수준의 오브젝트이며, 네임스페이스에 의해 구분되지 않는다.
시크릿은 SSH 키, 비밀번호 등과 같이 민감한 정보를 저장하기 위한 용도로 사용되며, 네임스페이스에 종속되는 쿠버네티스 오브젝트이다.
$ kubectl create secret generic my-password --from-literal password=1q2w3e4r
$ kubectl get secrets
$ kubectl describe secret my-password
$ kubectl get secret my-password -o yaml
쿠버네티스의 오브젝트 중 하나인 ServiceAccount 에 의해 네임스페이스별로 default-token-xxx 시크릿이 자동으로 생성되어 있다.
시크릿에 저장할 때, 쿠버네티스가 기본적으로 base64로 값을 인코딩 한다.
시크릿은 사용 용도에 따라 여러 종류를 설정 할 수 있으며, 비공개 레지스트리에 접근할 때 사용하는 인증 설정 시크릿을 예로 설명한다.
쿠버네티스에서는 docker login 명령어 대신 레지스트리의 인증 정보를 저장하는 별도의 시크릿을 생성해 사용한다.
레지스트리 인증을 위해 시크릿을 생성하는 2가지 방법
1) docker login 명령어로 로그인에 성공했을 때 도커 엔진이 자동으로 생성하는 ~/.docekr/config.json 파일을 사용(인증정보가 포함되어있음)
$ kubectl create secret generic [REGISTRY_NAME] \
--from-file=.dockerconfigjson=/root/.docker/config.json \
--type=kubernetees.io/dockerconfigjson
2) 시크릿을 생성하는 명령어에서 직접 로그인 인증 정보를 명시
$ kubectl create secret docker-registry [REGISTRY-NAME] \
--docker-username=[USER_NAME] \
--docker-password=[PASSWORD] \
--docker-server=[DOCKERSERVER_DOMAIN] <-- 사설 레지스트리 설정 옵션
TLS 연결에 사용되는 공개키, 비밀키 등을 쿠버네티스에 자체적으로 저장할 수 있도록 tls 타입을 지원
인그레스트래픽은 외부에서 서버로 유입되는 트래픽을 의미하며, 인그레스 네트워크는 인그레스 트래픽을 처리하기 위한 네트워크를 의미 한다.
인그레스 오브젝트의 기본적인 기능
1) 외부 요청의 라우팅: 특정 경로로 들어온 요청을 어떠한 서비스로 전달할지 정의하는 라우팅 규칙 설정
2) 가상 호스트 기반의 요청 처리: 같은 IP에 대해 다른 도메인 이름으로 요청이 도착했을 때, 어떻게 처리할 것인지 정의 가능
3) SSL/TLS 보안 연결 처리: 여러 개의 서비스로 요청을 라우팅할 때, 보안 연결을 위한 인증서를 쉽게 적용 가능
인그레스의 기능은 위 기능으로 제한되는것이 아닌 인그레스의 요청을 처리할 서버로 무엇을 선택하느냐에 따라 기능은 조금씩 달라진다.
인그레스는 라우팅 정의나 보안 연결 등과 같은 세부 설정은 서비스와 디플로이먼특 아닌 인그레스에 의해 수행되며 각 디플로이먼트에 대해 일일이 설정을 적용할 필요 없이 하나의 설정 지점에서 처리 규칙을 정의하기만 하면 된다.
즉 외부 요청에 대한 처리 규칙을 쿠버네티스 자체의 기능으로 편리하게 관리할 수 있는 것이 인그레이스의 핵심이다.
LB 의단점?
로드 밸런서는 서비스당 하나의 IP 주소만 처리할 수 있습니다.
클러스터에서 여러 서비스를 실행하는 경우 각 서비스에 대한 로드 밸런서가 있어야 합니다.
모든 서비스에 대해 로드 밸런서를 보유하는 것은 비용이 많이 들 수 있습니다.
Ingress 오브젝트의 기본적인 기능
1) 외부 요청의 라우팅
2) 가상 호스트 기반의 요청 처리
3) SSl/TLS 보안 처리
위 기능 외에도 인그레스를 어덯게 사용하느냐에 따라 다양한 기능을 사용할 수 있다.
외부 요청에 대한 처리 규칙을 쿠버네티스 자체의 기능으로 편리하게 관리할 수 있다는 것이 인그레스의 핵심이다.
인그레스의 는 단지 요청을 처리하는 규칙을 정의하는 선언적인 오브젝트일 뿐, 외부 요청을 받아들일 수 있는 실제 서버가 아니기 때문에 인그레스 컨트롤러 라고 하는 특수한 서버에 적용해야 규칙을 사용 가능하다.
실제 외부 요청을 받아들이는 것 또한 인그레스 컨트롤러 서버이며, 이 서버가 인그레스 규칙을 로드해 사용한다.
$ kubectl get ingress
or
$ kubectl get ing
$ kubectl apply -f \ https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.35.0/deploy/static/provider/aws/deploy.yaml
$ kubectl get pods,deployment -n ingress-nginx
$ kubectl get svc -n ingress-nginx
인그레스 사용 방법/절차
1) 공식 깃허브에서 제공되는 YAML 파일로 Nginx 인그레스 컨트롤러를 생성한다.
2) Nginx 인그레스 컨트롤러를 외부로 노출하기 위한 서비스를 생성한다.
3) 요청 처리 규칙을 정의하는 인그레스 오브젝트를 생성한다.
4) Nginx 인그레스 컨트롤러로 들어온 요청은 인그레스 규칙에 따라 적절한 서비스로 전달된다.
쿠버네티스의 API 에는 특정 오브젝트의 상태가 변화하는 것을 확인할 수 있는 Watch API 가 있으며 인그레스 컨트롤러 또한 인그레스 리소스에 대해 Watch API 를 사용한다. 리소슷에서 생성, 삭제, 수정 등의 이벤트가 발생했을 때 이를 알려주는 기능으로 kubectl get 명령어에서도 -w 옵션을 붙여 사용 가능하다.
# 포드에 변화가 생기면 콘솔에 표시 $ kubectl get pods -w
인그레스는 일종의 GW 역할을 수행하는데 인그레스 컨트롤러 지점에서 인증서를 적용해 두면 요청이 전달되는 애플리케이션에 대해 모두 인증서 처리를 할 수 있다.
직접 서명한 루트 인증서를 통해 Nginx 인그레스 컨트롤러에 적용 가능하다.
(인증서를 통한 보안 연결 기능을 제공)
$ openssl req -x509 -nodes -days 365 -newekey rsa:2048 \
-keyout tls.key -out tls.crt -subj "/CN=[PUBLIC_DOAMIN]/0=[KEY?]
$ ls
tls.crt tls.key
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
spec:
tls:
- hosts:
- alicek106.example.com
secretName: tls-secret
rules:
-hosts: alicek106.example.com
// -k 옵션은 신뢰할 수 없는 인증서로 보안 연결을 하기 위함
$ curl https://alicek106.example.com/echo-hostname -k
하나의 쿠버네티스에서 여러개의 인그레스 컨트롤러를 사용하는것이 가능
Nginx 인그레스 컨트롤러는 기본적으로 nginx 라는 이름의 클래스를 가지고 있으며,
이 설정을 변경하여 여러 개의 Nginx 인그레스 컨트롤러를 사용 하거나 인그레스 규칙을 선택적으로 적용할 수도 있다.
참고자료
용찬호, 『시작하세요!도커/쿠버네티스: 친절한 설명으로 쉽게 이해하는 컨테이너 관리』, 위키북스(2020)