[교육] PAAS 2일차
kubernetes
구성
- 설정파일을 다운로드 후 메모리 관련 약간 수정하여 구성 https://gitlab.com/junkoks/board/-/raw/main/Work.zip
쿠버네티스란
컨테이너화된 워크로드와 서비스를 관리하기 위하여 이식성있고, 확장가능한 오픈소스 플랫폼이다.
독립서버에서 하나의 애플리케이션
자원 효율적으로 관리 어려움
독립서버에서 복수의 애플리케이션
자원을 서로 잡아먹음
가상서버에서 하나의 애플리케이션
자원 관리 및 차단에 좋지만 OS자원 낭비 발생
컨테이너
운영체제 공유하고 개별 서비스는 고립됨
구성요소
마스터노드 워커노드
마스터 컴포넌트
cloud-controller-manager
- 컨트롤 플레인의 한 종류. 클라우드(aws, azure..)별 컨트롤 로직을 포함한다.
노드 컴포넌트
kubelet : 클러스터의 노드에서 실행되는 에이전트. 파드에서 컨테이너가 동작하도록 관리. 쿠버네티스를 통해 생성되지 않은 컨테이너는 관리하지 않는다(ex. docker run 등으로 수행 중인 컨테이너)
kubeproxy :
컨테이너 런타임 : 런타임
애드온
애드온은 쿠버네티스 리소스를 통하여 구현(데몬셋, 디플로이먼트)
- dns : 거의 기본적인 애드온
- 웹 UI
- 컨테이너 리소스 모니터링
- 클러스터 레벨 로깅
쿠버네티스 API
클러스터 아키텍처
노드 관리
각 노드에 대하여 스케줄링 가능/불가능 여부를 설정할 수 있다.
kubectl get nodeskubectl cordon node-1kubectl get nodeskubectl uncordon node-1
노드상태 kubectl get node
NAME STATUS ROLES AGE VERSIONdocker-desktop Ready control-plane 18d v1.25.4
컨트롤 플레인과 노드간의 통신
노드->컨트롤플레인
- 패턴 : 허브 앤 스포크 API 패턴.
컨트롤플레인->노드
- apiserver -> kubelet
- proxy -> node or pod
API 서버에서의 노드, 파드 및 서비스로의 통신
api->other component : http연결. 암호화되지 않음. https로 통신 가능하나 검증하지 않음
컨트롤러
컨테이너 런타임 인터페이스
이미지와 이미지 레지스트리
이미지 풀 정책
- imagepullpolicy
- always : 컨테이너를 기동할때 마다 땡겨서(이미지 다이제스트에 변경을 판단해서) 실행. 레지스트리에 연결되어 있는 경우 추천 옵션
- ifnotpresent : 없는 경우에만 땡김
- never : 안 땡겨온다. 이미지가 없으면 실행이 되지 않음
이미지풀백오프
imagepullbackoff -> waiting 제일 실패가 많은 상태. 뭔가 이미지를 가져올 수 있는 권한이 없거나, 이미지 이름이나 태그를 잘못 적었거나 등의 이유로 컨테이너 이미지를 가져올 수 없는 상태라 실행할 수 없음을 의미한다. 이미지를 가져오려고 재시도를 계속하는데 재시도마다 재시도 주기가 늘어나며 최대 주기는 300초(5분)으로 쿠버네티스 코드에 고정되어 있다.
워크로드
파드 : 가장 작은 컴퓨팅 단위. 컨테이너의 그룹. deployment등에 포함되어 있지 않을 경우 singleton pod라고 부른다.
nginx 예제
apiVersion: v1kind: Podmetadata:name: nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80
이것저것 클러스터 전체 내용 가져오기
kubectl get all -A
파드 템플릿
파드는 최소 수행 단위이므로 다른 리소스에 포함되어 배포될 수 있다. 아래 예제는 잡 내부에서 정의된 파드이다. 디플로이먼트, 데몬셋 등에 포함되어 함께 정의될 수 있다.
apiVersion: batch/v1kind: Jobmetadata:name: hellospec:template:# 여기서부터 파드 템플릿이다spec:containers:- name: helloimage: busyboxcommand: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']restartPolicy: OnFailure# 여기까지 파드 템플릿이다
파드의 수정
변화할 수 있는 값이 있고, 아닌 값이 있다. 아닌 값을 수정하려면 파드 삭제 후 재생성(kubectl apply -f pod.yaml --force)하여야 한다.
파드 네트워킹
각 파드에는 고유 ip가 할당된다.
컨테이너에 대한 특권모드
컨테이너 프로브
약간 하트비트. 주기적인 진단 수행. execaction tcpscoketaction httpgetaction
파드 라이프사이클(단계)
PodStatus. 상태 머신을 표현하도록 의도되지는 않았다.
- pending : 이미지 다운로드 등
- running : 하나의 파드라도 실행 성공 3.1. succeeded : 정상 종료 3.2. failed : 에러 종료
- unknown : pod의 상태를 얻을 수 없는 상태
파드는 자체적으로 자가 치유되지 않으며, deployment등의 자원을 통하여 스케줄링되고 자가 치유된다.
재시작 정책
restartpolicy
- never :
- always
- onfailure
최대 5분으로 제한되며(10초, 20초..). 컨테이너가 10분동안 아무 문제없이 실행되면 백오프 타이머 설정
pod의 컨디션
PodStatus. 다음과 같은 타입이 있다. ㄴㅅㅁ션 ㅣㅁㄴ세개ㅠ
Status
Conditions: Type Status # 컨디션의 이름. Initialized True # 모든 초기화 컨테이너가 완료 Ready False # 파드는 요청을 처리할 수 있음 ContainersReady False # 파드의 모든 컨테이너가 레디 PodScheduled True # 파드가 노드에 스케쥴
컨테이너 프로브
프로브 =진단. kubelet이 컨테이너가 살아있는지 체크하는 메커니즘
- exec : 컨테이너 내에서 명령 실행. return = 0 성공
- grpc : 원격 프로시져 호출. response.status = SERVING이면 성공
- httpGet : 200~3xx이면 성공
- tcpsocket : 포트가 활성화 = 성공
프로브 결과
- success : 컨테이너 진단 통과
- failure : 컨테이너 진단 실패
- unknown : 진단 자체가 실패
프로브 종류
- livenessprobe : 컨테이너가 동작중인지 체크
- readinessprobe : 요청 처리 준비중인지 체크
- startupprobe : 애플리케이션 시작 여부 체크
파드 종료
종료에 대한 디자인이 필요하다.
- 종료시 term 정송
- stopsignal값을 보고 유예 기간을 가짐
- kill 시그날이 나머지 프로세스 전체에 전송
- 파드가 api서버로부터 삭제
초기화 컨테이너
파드의 메인 컨테이너들이 실행되기전 실행되는 특수 컨테이너 유틸리티 혹은 설정 스크립트 등이 포함됨
apiVersion: v1kind: Podmetadata:name: myapp-podlabels:app: myappspec:containers:- name: myapp-containerimage: busybox:1.28command: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busybox:1.28command: ['sh', '-c', "until nslookup myservice.$(cat/var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local;do echo waiting for myservice; sleep 2; done"]- name: init-mydbimage: busybox:1.28command: ['sh', '-c', "until nslookup mydb.$(cat/var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local;do echo waiting for mydb; sleep 2; done"]
서비스 실행을 기다리고 있으므로 해당 서비스를 만들어보자.
apiVersion: v1kind: Servicemetadata:name: myservicespec:ports:- protocol: TCPport: 80targetPort: 9376---apiVersion: v1kind: Servicemetadata:name: mydbspec:ports:- protocol: TCPport: 80targetPort: 9377
initcontainer가 정상 종료 되면서(nslookup으로 목표한 서비스가 확인되면서) 메인 앱인 myapp-container가 실행됨을 확인할 수 있다.
init-myservice:...State: TerminatedReason: CompletedExit Code: 0Started: Fri, 21 Apr 2023 16:13:55 +0900Finished: Fri, 21 Apr 2023 16:21:39 +0900init-mydb:...State: TerminatedReason: CompletedExit Code: 0Started: Fri, 21 Apr 2023 16:21:40 +0900Finished: Fri, 21 Apr 2023 16:21:40 +0900myapp-container:...State: RunningStarted: Fri, 21 Apr 2023 16:21:41 +0900...Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 10m default-scheduler Successfully assigned default/myapp-pod to docker-desktopNormal Pulling 10m kubelet Pulling image "busybox:1.28"Normal Pulled 10m kubelet Successfully pulled image "busybox:1.28" in 4.087604418sNormal Created 10m kubelet Created container init-myserviceNormal Started 10m kubelet Started container init-myserviceNormal Pulled 2m29s kubelet Container image "busybox:1.28" already present on machineNormal Created 2m29s kubelet Created container init-mydbNormal Started 2m29s kubelet Started container init-mydbNormal Pulled 2m28s kubelet Container image "busybox:1.28" already present on machineNormal Created 2m28s kubelet Created container myapp-containerNormal Started 2m28s kubelet Started container myapp-container
deployment
배치다. 일반 용례
- replicaset을 롤아웃하는 deployment를 만든다.
apiVersion: apps/v1kind: Deploymentmetadata:name: nginx-deploymentlabels:app: nginxspec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80
롤아웃
deployment내의 pod를 업데이트시 한번에 쏵안하고 하나씩 갈아끼운다. 다음 명령을 확인해보면 롤아웃이 얼마나 되었는지 확인할 수 있다.
kubectl rollout status deployment <deploymentname>
replicaset
apiVersion: apps/v1kind: ReplicaSetmetadata:name: frontendlabels:app: guestbooktier: frontendspec:# modify replicas according to your casereplicas: 3selector:matchLabels:tier: frontendtemplate:metadata:labels:tier: frontendspec:containers:- name: php-redisimage: gcr.io/google_samples/gb-frontend:v3
다음 명령으로 디테일 확인 가능.
kubectl describe rs frontend
statefulset
상태저장 애플리케이션을 관리하는데 사용되는 워크로드 API 개체
유즈케이스
지속적인 스토리지 고유한 네트워크 식별자 배포 및 확장 롤링 업데이트
한계
- stateful은 삭제될때까지 pod ㅈㅇ료에 대한 보장을 제공하지 않음 -롤링 업데이트를 사용하는 경우 복구 또는 수동개입이 필요할 수 있음
apiVersion: v1kind: Servicemetadata:name: nginxlabels:app: nginxspec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx---apiVersion: apps/v1kind: StatefulSetmetadata:name: webspec:selector:matchLabels:app: nginx # has to match .spec.template.metadata.labelsserviceName: "nginx"replicas: 3 # by default is 1template:metadata:labels:app: nginx # has to match .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 10containers:- name: nginximage: k8s.gcr.io/echoserver-arm:1.8ports:- containerPort: 80name: web