0.container & docker
- resource의 격리
- 과거의 모노리틱한 구성일 경우, 2가지 서비스를 필요로 할시 2개의 서버를 만들게 된다. 그럼 서버를 2개를 사용하게되는데, 트래픽이 몰리는 시간과 아닌시간, 백업할 때 백업안할때, 등등의 이유로 전체 시간대비cpu resource 활용도가 매우 낮게된다. 하지만, 이런거 자체는 가상화 기술의 근본적이 이유이다.
- 물리적인 것을 논리적으로 바꾸는것 = emulation(4가지 cpu, memory, storage, network)
- virtual mechanie -> container로 변경된 이유는 resource overhead(vm을 구성하는데 있어서 hyperviser등을 구성하는데 resource가 들어간다) /// 성능 손실(i/o 등등)
- 항구에서 사용하는 컨터이너처럼 균일화된 상자로 내용물을 옮기는, 내용물에 구애받지않고, 어디서든지 서비스를 구성할수 있도록 만들고자 했기에 컨테이너라는 이름을 따왔다. 격리된 실행환경 구축 & 구축절차 간소화
모놀리틱 vs MSA(container사용이유)
- 모놀리틱은 기능들이 유기적으로 연결되어있기때문에, 하나의 기능 수정에 있어서, 그 외의 수정사항이 생길 수 있다.(변경 반영시간이 길다)
- MSA는 여러개의 서비스로 만들어서 그것들이 서로 통신하는 구조로 개발한다.(변경 반영시간이 짧다)
- msa로 가면서 배포의 가짓수가 많아지고, 그에따라서 배포를 해주는 tool의 필요성이 대두되게 되고, kube가 각광받게되었다.
container를 써서 여러개의 운영 app을 띄우는 이유
- 여러개의 app이 실행환경을 공유하게되고, 그것은 충돌을 발생시킬 수 있기때문에 실행환경을 격리해서 따로 구성해야된다.
- application관련된 것만 container로 격리시킨다.
- overlay구조
- kernel단 설정은 개별 container에서 진행할 수 없는것인가? - host에서 kernel관련 설정을 해준 host를 만들고, 추후 필요한경우 해당 node에 할당하여서 생성한다면 문제가 없다.
docker의 역할(container 생성자)
- 컨테이너 런타임 -> 컨테이너 생성
- 컨테이너 이미지 생성
- cncf - cloud native computing foundary (cloud native- container기반 cloud) -> kubernetes(조타수-컨테이너 기반의 것들을 배포 운영 관리하는 역할)
도커의 구조
- daemon
- client
- image (container를 만들때 구성요소를 모두 포함하고있는 존재)
- container (runnable instance = process, 격리된 process)
- registries(중앙 이미지 저장소)
- naming format 레지스트리/저장소/이미지/태크 ex) docker.io/takytaky/centos:7.4 + 레지스트리 주소는 생략되는 경우가 대부분(도커허브(도커에서 중앙관리하는 레지스트리)는 생략됨) + 저장소 명 library (docker cert, verify) docker cert는 저장소명이 생략된다. + 태그는 생략될시 최신버전으로 latest
도커 명령어
- docker로 시작
- container? image?관련된것은 docker다음
- 도커 명령이 이미지 찾아보기
- docker container run(create + start)
- docker container rm
- container를 배포하고 작동안한다고 수정하는 경우가 없고 삭제후 재배포하는 방식 사용
- container는 프로세스다. 그리고 1번 프로세스는 컨테이너의 생성이유이다.
- image는 파일이다.
- -i interactive(대화식) -t tty
- shell은 프롬프트로 명령어를 kernel로 전달하는 역할을 수행하고 그러한 현상을 대화식이라고한다(stdin표준입력, stdout표준출력, stderr표준오류)
- sudo terminal을 제공해줘라 - tty
- docker의 1번 프로세스가 /bin/bash일때, 도커 내부에서 exit를 하게되면 1번 프로세스인 bash process가 죽게되므로 docker도 죽게된다. 죽지않게 빠져나온다(detach= ctrl+p+q)
도커 이미지 생성 방식
- docker container commit -> 임시컨테이너를 만든다. & 내가 원하는걸 다 구축해놓는다 -> docker container commit -> 저장환경이 이미지화가 된다.
- docker image build -> docker file(내가 하려고하는 일들을 다 적어 놓는다) -> build -> 순서대로 진행이 된다.
1.k8s의 기본
- 여러대의 서버를 컴퓨터 하나인것처럼 운영하는 것
- node의 종류: master node- control plane(worker 에게 일을 시킴) & worker node 리소스를 제공하는 노드
- docker registry에 이미지를 업로드함
- yaml파일에 상세한 배포내용을 적어놓음 - 요구사항이 충족하는 node에 배포함
- 무슨기준으로 배포? 스케쥴링 -> node에 점수화를 시킴/ 점수기반으로 배포진행
- node가 고장날시 다른 node로 자동으로 넘어가는 기능을 제공
- EKS = amazon kube service
k8s 직접 구성하는 3가지 도구
- kubeadm
- kubespray
- rancher, 아하 렌쳐가 k8s를 구성하는 놈이였구나... 클러스터를 여러개 구성할때 좋음(gui 제공)
k8s 잡다한 것
- 모든 노드는 고유의 ip, hostname, mac address, product_uuid를 가지고 있어야함
- cgroup - control group, 하나의 서버에 여러개의 컨테이너가 올라가게된다면, 리소스 경합이 일어나게 되는데 그것을 결정하는 역할
- docker는 cgroupfs를 파일에 적어서 사용/ k8s는 systemd 사용 명령어를 줘서 사용(기능은 동일하지만 설정방식이 차이가 있음)
- 그렇기때문에 docker의 설정방식인 cgroupfs를 systemd방식으로 전환해야지 k8s에서 container runtime으로 docker사용가능
kubeadm 사용 정보 (kubeadm init)
- 노드를 컨트롤 플레인으로 초기화 하는 명령어
- 명령어가 실행된 노드가 마스터 노드가 됨
- 마스터노드 1개를 갖는 1노드의 클러스터가 구성됨
- worker node를 추가하는 과정이 필요 - kubeadm join
- token이 발행되는데, token이 인증되어야지만 cluster에 넣어주겠다는 의미의 토큰
- kubectl login
- pod network를 배포해야된다. network를 구성하기위해서 core dns가 필요하다. 근데 이걸 k8s에서 기본적으로 제공해주지않기때문에 이걸 구축하는걸 같이 설치해야됨
- pod의 위치가 달라지면? 그렇기때문에 cni overlay network를 구성, 물리네트워크를 가상화해서 구현하자.
k8s의 기본동작
- 책추천: kubenetes in action
- image를 registry에 등록
- 배포 명령어 실행
- master는 container runtime에게 내용전달 및 container runtime은 전달받은 내용을 실행
- master node에는 반드시 실행되어야하는 pod(필수 구성 pod)- etcd(상태, 정보 저장), controller() scheduler(최적의 노드 파악), apiserver(명령어를 수신하고 수행하는 핵심)
- worker node/ master node - kubelet
control plane(master node)
- etcd: ha를 제공하는 key-value 저장소 & 필요한 모든 데이터를 저장하는 데이터베이스의 역할
- kube-apiserver: 명령어는 모두 api서버로 전달, 요청의 유효성 검사(authentication, authorization)
- kube-scheduler: 실행될 노드를 결정하는 과정
- kube-controller-manager: pod를 관리하는 역할
- cloud-controller-manager: 클라우드에서 제공하는 나머지 다른 서비스와 연동해주는 역할
주요 컨포넌트 노드(모든 노드)
- kubelet: 쿠버네티스의 데몬- container가 아니라 에이전트 데몬(service) & 수신된 파드 스팩을 기반으로 container runtime에게 요청을 보냄
- kube-proxy: 네트워크 프록시- 서비스라는 타입의 프록시하는 역할
- container runtime: ex) docker
kubctl을 이용한 pod 생성 절차
- kubectl로 create pod api 호출(인증/인가)
- etcd에 pod관련된 내용들을 전부 저장(node name 제외, 아직 미선정- scheduler에서 선정)
- api서버가 scheduler에게 새로운 pod를 요청, schedular는 최적의 node계산
- api서버는 그내용을 다시 etcd에 저장
- api서버는 node의 kubelet에 전달
- kubelet은 container runtime을 실행
- 생성 성공 실패 여부를 리턴
- kubelet은 그 내용을 api서버에 보냄
- api서버는 etcd서버에 내용 작성
k8s component addon
- 네트워킹 애드온(cni)
- dns addon(core dns, object name->ip)
- 대시보드 애드온
- 컨테이너 리소스 모니터링(cncf 프로메테우스)
- 클러스터 레벨 로깅- elk efk
오브젝트와 컨트롤러
- 오브젝트: 파드, 서비스, 볼륨, 네임스페이스
- 컨트롤러: 오브젝트를 컨트롤하는 것
- status: 현재상태, spec: 원하는 상태(템플릿 파일로 적어놓는다(yaml))
네임스페이스
- 동일한 물리 클러스터를 기반으로 논리적으로 구분된 가상클러스터를 네임스페이스라고 한다.
- 논리적 가상클러스터는 물리적 위에 db라는 논리적 가상클러스터를 만들어서 접근 및 관리의 용이성을 주는 방식
- 기본생성 default(기본값), kube-system(운영관련된것들 자동으로)
2.파드
- 애플리케이션의 기본 실행 단위/ 배포할수 있는 가장 작은 단위
- 일반적으로 단일 컨테이너로 구성되어있음
- 동일한 실행 환경이 필요한 컨테이너는 가끔 2개 3개를 묶어서 파드로 배포함(동시실행 동시죽음, 개별 컨테이너 확장 불가, 동시 확장 필요)
- 2개가 들어가는 경우-> app은 1개 + app의 기능을 보조 및 강화하는 container인 경우가 많다 ex. sidecar pattern
파드 설정: liveness probe vs. readiness probe
- liveness- 파드의 컨테이너가 live하냐를 확인해보자
- readiness- 파드의 컨테이너가 ready상태인지 확인해보자
- 둘다 일정 명령어를 실행하고 그 결과값으로 활성여부를 판단한다.
- liveness는 설정 기본값이 true지만, readiness는 설정 기본값이 false이다. readiness의 경우 명령 실행 성공을 해야지만 올라간다.
- liveness는 실패시 죽이지만, readiness는 서비스에서 제외한다.
파드 설정: pod resource restrict
- 하나의 pod가 리소스를 독점하는걸 막기위해서 리소스를 할당해주는 것
- memory 2M 2,0000,0000 & 2Mi 2*2^20
- scheduler가 node를 결정할때 resource사용량을 실시간으로 파악하는건 아니고 etcd를 참조해서 결정한다.
- pod들이 node의 총 memory보다 많이쓰게된다면, out of memory현상이 생김
- 기준을 만족하는 node가 없다면, pending상태로 어디에도 올라가지 않게된다.
파드 특성: pause container
- 내가 파드를 생성하면 무조건 쌍으로 pause container가 생김
- 파드 내부의 컨테이너들에게 실행환경을 제공하는 역할
- 만약 container가 죽으면 ip를 반환하게 되는데, 재시작 될때 재할당하게 된다. 그럼 그때마다ip를 바꿔야될까?
- 그러한 실행환경 정보들을 들고있는데 pause container
파드 특성: init container
- init container는 내가 주 목적을 가진 container보다 먼저 실행되고 종료가 된다. 그후 주 목적 container가 pod에 올라간다.
- 그런 특성을 이용해서 프로그램과 데이터를 별도로 관리하기 위해서 이미지를 따로 생성할때 자주쓴다
- volume을 지정해서 그 내부에 자료를 저장하고, 그 volume을 다른 container가 mount해서 쓰는경우가 많다
파드 특성: static pod
- kube-api를 통하지않고 kubelet에서 직접 실행하는 파드
- 일반적으로 우리가 만드는거는 dynamic pod, 필요할때마다 생성 삭제하기때문에
- /etc/kubernetes/manifests가 기본경로에 yaml파일 4개가 있다. (필수 4개 pod- etcd, kube-apiserver, kube-scheduler, kube-controller)
- master node가 부팅할때 kubelet이 daemon으로 실행이 되는데, 그때 manifests를 읽고 그걸 container runtime에 보내고, 주기적으로 확인하고, 죽으면 재시작한다.
- 한마디로 k8s를 구성하는 필수 파드들이 static하게 선언되어있는걸 의미한다.
파드 특성: multi container pod design pattern
- 하나의 파드에 여러개의 컨테이너를 띄우는 경우
- sidecar pattern - log 수집의 목적이 많다.
- ambassador pattern - db와 연결할때 이것저것 변경 가능성이있는데, 외부와 중계를 하는 proxy역할을 하는것. 연결정보만 만드는 경우
- adapter pattern - pod외부에서 들어오는 데이터들의 전처리 작업들이 필요할때 사용하는 경우가 많다.
- 앱컨테이너의 목적과 변경을 줄이기위해서 생긴것이라고 볼 수 있다.
구분하는 꼬리표: label
- yaml의 name은 유일한데, 어디서? 범위는 namespace에서...
- label은 유일하지 않다. 중복허용
- 관리를 위해서 k/v를 내가 설정
- label의 목적은? 원하는 걸 선택하기위한 방법중 하나
- 내가 원하는 pod를 다중 선택, 범위는 namespace에서..., pod가 아니여도 label을 가질수는 있음
selector
- label을 선택하고 분류하기위해서 제공되는 기능
- node selector - scheduling을 임의로 해줄때 사용가능
애너테이션(주석,추가필요정보)
- 내가 추가한 정보외에도, 시스템에서 추가로 필요한 정보도 애너테이션에 저장된다.& 애너테이션도 k8s에서 정의된 것이 있다.
3.컨트롤러
레플리케이션 컨트롤러
- 이제는 안쓴다. k8s가 처음 만들어졌을때 쓰던 컨트롤러
- 등호기반 셀렉터
- rolling update
레플리카셋이 레플리케이션 컨트롤러를 대신하기 시작함
- 일정수의 pod를 유지함
- 등호기반 셀렉터 + 집합 기반 셀렉터
- rolling update 지원 안함 > 기존pod 전부 삭제후 새로운 이미지 배포 (+deployment가 이기능을 지원해줌)
- 3가지로 구성-
-
- replicas(pod를 몇개만들지)
-
- label selector(어떤 pod가 3개로 유지될것인지, 그걸 라벨을 통해서 확인함)
-
- template(metadata에 label정보를 줘야된다. 왜냐면 그걸로 몇개있는지 세기때문에,이미지 및 세부사항들, pod와 관련된 모든 변수들 가능)
- 레플리카셋의 metadata, spec도 적고, 그걸로 생성되는 pod의 metadata, spec도 적어놔야된다.
- config에서 metadata와 spec의 주인이 누군지 명심해야된다.
- 이름은 알아서 5개문자를 뒤에 붙여서 생성해줌
deployment 컨트롤러
- 레플리카셋을 만들고 관리하는 역할을 하는게 디플로이먼트
- 배포와 관련된 역할을 주로 담당하게 된다.
- 배포를 하게되면, 디플로이먼트는 레플리카셋을 새로 만든다. 그럼 새로운 레플리카셋이 새로운 파드를 만들고 기존 레플리카셋은 하나씩 지운다. 새로운 레플리카셋에서 1개가 생기면 기존 레플리카셋에서 1개사 삭제된다. 재배포를 rolling update하는 방식
- 레플리카는 생성시에는 하위 pod들을 구분하는데 고유값을 우리가 입력한 라벨을 제외하고 쓰지않지만, 생성이 되는순간 자신이 만든 pod들을 구분하기위한 해시값이 들어가 있다.
- 이러한 구분값들은 동일한 라벨을 가지는 레플리카들이 서로의 pod를 구분하기 위해서 쓰고있다.
- kubectl edit으로 내역 수정가능 -> etcd의 정보를 조회후 수정하는 기능
- yaml파일을 업데이트하고 apply로 적용하는 방식을 많이 쓰는듯
- helm은 이러한 yaml파일들이 많아지고 그에따라서 버전관리들을 하는경우 git처럼 도와주는 역할을 하는게 helm의 역할이다.
- 업데이트 방식이 rollingupdate의 경우, 업데이트중 서비스끼리의 버전이 섞이는 문제가 생긴다.
- 업데이트 방식이 recreate의 경우, 동시에 죽고 동시에 새로 만든다, 업데이트 총 시간이 짧다, downtime이 생긴다
- 블루그린 배포
- 블루- OLD VERSION
- 그린- NEW VERSION
- 한번에 그린을 블루수만큼 띄워놓고, 한번에 교체하는 롤링업데이트 방식
- 서비스를 이용해서 SELECTOR LABEL을 이용해서 한번에 쫙
- 카나리 배포
- (인디케이터) 보초병으로 먼저 업데이트해보고 이상없으면 업데이트를 결정하는 방식
데몬셋 컨트롤러
- 실행할 파드의 총숫자를 지정하지 않고, 모든 클러스트 노드에 하나씩 실행하는걸 목적으로 하는 컨트롤러
- 노드마다 log정보를 모으거나 고르게 분포해야되는 경우 사용하게된다.
- 마스터 노드에는 taint라는 제약이 걸려있고, 그 제약에 따라서 마스터노드에는 실행되지 않는다. 그 제약은 toleration으로 해제할수있다.
- 업데이트 전략- rollingupdate, ondelete
- 데몬셋은 surge를 허용하지않기 때문에 제거하고 새로만드는 방식으로 업데이트
- ondelete -> 수동을 삭제하면 새로운 파드를 데몬셋이 생성한다. 반수동 느낌
잡 컨트롤러
- 실행후 종료되는 성격을 가진 pod를 생성하는 방식
크론잡 컨트롤러
- 지정한 시간에 단일/반복으로 잡을 실행하는 것
- schedule: "*/1 * * * *"
- 분 시간 날짜 월 요일
- 12월 25일 오전 9시 정각
- 0 9 25 12 *
- 매일 오전 9시 정각
- 0 9 * * *
- 5분마다 반복
- */5 * * * *
- concurrency policy 크론잡이 끝나기전에 새로운 잡이 실행될때 2개가 동시에 생성되게 되는데 그걸 어떻게 처리할것인가에대한 변수
스테이트풀셋 컨트롤러
- 볼륨과의 연동이 되어있음
- 앞에서 했던 배포하던 pod및 기능들은 stateless한 애들이였다. 하지만 stateful한 애들은 어떻게 생성할 것인가.
- 동일한걸 복원하더라도 이전 파드의 정보에 영향받지않는다= stateless
- 동일한걸 복원할때 이전 파드와 동일하게 만든다. 이름등등 = stateful
- 생성도 순서대로 삭제는 역순으로 step이란게 존재한다.
- 레플리카에서 pv를 별도로 만드는 방식은 레플리카set을 1개로 설정하고 각각을 만든다. ? 너무 비효율적?
- 지속적으로 분리된 pv를 사용하고싶을때
- 특정 파드를 지정해서 연결하고 싶을때
스테이트풀셋 업데이트
- 부분 업데이트가 가능하다. rollingupdate: partition:1로 바꾸면 파드번호가 1이상인것만
4.서비스
- pod는 일회용이기때문에,업데이트같은 상황은 삭제후 재생성하는 방식을 채택하는 등 일회용성으로 사용된다.
- 서비스는 고정ip를 제공을 한다 -> pod처럼 자동으로 바뀌지않는다.
- 고정되어 있는 연결다리의 역할을 하는게 서비스의 목적이다.
- pod가 죽었을때 자동으로 새로 생긴 pod로 연결해준다.(포워딩)
- 트래픽 분산(로드밸런싱)
- 클라이언트가 pod를 신경쓰지않고 작업할 수 있도록 도와주는 역할
- 서비스는 프로세스가 아니고, 그렇기에 pod로 배포되지 않는다.
- 하나의 규칙이다.
서비스 종류: cluster ip
- 고정 ip로 클러스터 내부용 통신에 쓰이는 서비스
- 어떤애들로 트래픽을 보내줄지, 라벨링으로 결정한다.(selector로 결정)
- port: service client port/ target port: backend(pod container) port
- pod들을 cluster ip로 묶어주는 역할을 하는 서비스
- cluster node의 kernel- iptables, netfilter에 적용되어서 nat가 설정되지만, 이건 클러스터 내부의 통신에서만 작동된다.
서비스 종류: node port
- 클러스터 내부뿐만 아니라 외부에서 들어오는것도 받아주는 서비스
- 각각의 노드의 외부로 노출되는 ip에 port를 매핑해서, 그 port로 들어오면 그걸 pod로 연결해준다.
- 클러스트의 어느 노드의 ip여도 상관없다.(모든 노드에 동시 적용)
서비스 종류: loadbalancer
- 노드들의 앞단에 로드를 밸런싱해주기위해 추가하는 서비스(노드를 10개면 10개 번갈아가면서 직접 쏠수는 없잖아)
- 주로 클라우드환경에서 사용됨/ 온프레미스는 l4스위치가 대신하는경우가 많음
- ex. metalLB
- 실제 node의 ip와 port를 외부에 공개하기 싫을때 대표성 ip를 가진 loadbalancer로 대체한다.
서비스 종류: headless
- headless서비스는 CLUSTER IP로 실행하면 된다.
- 왜냐하면 내부 CORE DNS기 때문에 외부에서 참조할 일이 없기때문이다.
- 통신관련된걸 모아놓은 이미지 image nicolaka/netshoot
- iptables 모드 -> 각 노드의 커널에 IPTAGEBLES규칙을 넣기만 하는것: 그렇기때문에 분산알고리즘을 지원하지않고 랜덤으로 작동함
- 그래서 나온게 ipvs모드: role값이 해시값을 저장됨 & ipvs커널 모듈이 있어야된다.
5.ingress (인그레스)
- service + alpha
- l7역할을 하게된다.
- 외부에서 내부로 접근을 어떻게 처리할 지 정의해둔 규칙
- 인그레스는 인그레스(rule이 정의되어있음)+ 인그레스 컨트롤러(rule기반으로 처리)
- 인그레스 컨트롤러는 프로세스다.
- 인그레스는 룰이다.
- 공식지원 컨트롤러는 2가지가 있다. ingress-gce, ingress-nginx
- 인그레스 어노테이션은 인그레스 컨트롤러 기능을 명명하는데 사용된다.
- 인그레스와 인그레스 컨트롤러는 따로 생성해줘야된다. 한번에 생성되는거 x
- 외부요청을 받을 서비스
6.volume
- 컨테이너의 특징
- OVERLAY2로 구성되어 있다.
- OVERLAYED FILE SYSTEM
- 레이어가 2개짜리이다.
-
- lowerDir/image layer(a b c d 이렇게 들어가 있음) 2. upperDir/container layer(1위에 올라가있음, )
- 그 레이어 2개를 겹쳐서 보여줌, lowerdir은 readonly, upperdir은 r/w가능
- 새로운 뭔가를 만든다면 그건 layer2에 올라감/ a를 수정한다면, copy on write방식으로 layer2에 새롭게 복사하고 수정한다.
- merge를 하는 과정에서 변경된 애는 layer2에서 읽게됨.
- 삭제하는 것도 layer2에서 삭제한것처럼 보이게 하자를 입력해놓고 merge하는 과정에서 삭제된것처럼 보여줌
- 이미지를 노드 위에 파드/ 컨테이너끼리 공유해서 쓰기때문에 이미지를 저장해놓고 그것은 image layer가됨, 그리고 그걸 공유해서 container를 생성하는데, 수정사항은 layer2 container layer에서만 생기기때문에 효율성이 증가함
- 근데 파드를 지울때 파드가 가지고있는 자료도 다 날아가게됨. 그렇기때문에 볼륨을 연결해서 필요한 정보를 영구적으로 저장할 수 있도록 함
볼륨 플러그인 종류
- temporary - emptyDir 일시적으로 데이터를 저장하고 삭제하는 캐시성
- local - hostpath 워커 노드의 로컬 디스크에 저장하는 방식- 대신 워커가뜬곳에 저장하기때문에, 추후 워커의 노드가 다른 노드로 스케줄되면 없어지기때문에 관리가 필요하다.
- network storage - nfs- nfs서버/iscsi- iscsi 서버에 볼륨 마운트/secret- etcd에 쓰겠다/ glusterfs- 오픈소스 스토리지
- cloud provider support plugin - gce, aws ebs, azuredisk
볼륨설정: emptyDir
- memory에 마운트 됨, 속도가 좋음
볼륨설정: hostPath
- pod가 삭제되더라도 내용은 삭제되지 않음
- 볼륨을 붙일 위치
스토리지 기술과 파드 분리의 필요
- 인프라에대한 지식없이 스토리지-파드 합쳐진 걸 쓰기 어렵다.
분리하기위한 도구: pv 퍼시스턴트 볼륨
- 물리적으로 볼륨을 붙인뒤에, 쿠버네티스에 볼륨이 있다고 알려준다. 그걸하는 오브젝트가 pv다.
분리하기위한 도구: pvc 퍼시스턴트 볼륨 클레임
- 요구사항을 정의하고 요청하는것, 그걸하는 오브젝트가 pvc다
- pv를 만들면 그 pvc에 자동으로 바인딩 된다.
- 그리고 그 pvc를 pod생성시 요구사항에 넣는다. 그럼 pod는 자동으로 할당된 pv를 선택하게 된다. 바인딩 되어있기때문에.
pv와 pvc의 라이플 사이클
-
- 프로비저닝- 디스크공간을 확보후, pv를 만드는 단계
- 정적프로비저닝: 미리 할당해놓는것, 물리적인 스토리지의 용량과는 별도로 딱 이만큼만 써라-> 저장용량의 한계가 있는경우(온프레미스)
- 동적프로비저닝: pvc를 받으면, 그때 pv를 만드는 것 -> 디스크용량의 한계가 없는 경우(provisioner라는 서비스가 하나 있어야된다.)
-
- 바인딩- 요구사항을 만족하는 pv가 있으면 연결, 없으면 무한대기 & 1:n바인딩 불가능
-
- 사용(using)- pvc를 이용하여서 파드를 만드는 과정
- 삭제는 생성순서의 역순으로 진행됨.
-
- 반환(reclaim) - 정책 3가지 : retain, delete, recycle
- recycle: 한번사용됐던애를 다른 pvc가 들어오면 재 할당해준다.(EOS,저장공간을 다시사용함에 따라서 전 POD에서 만들어놓은게 그대로 보임)
- delete: 동적프로비저닝에서 주로씀, 요구사항이 제거되면, 자동으로 삭제해주겠다. 자동생성 자동삭제
- retain: 사용후 그대로 남아있게하겠다. released상태로 변환된다 = 재사용 불가, 재사용하고싶다면 관리자에 의한 수동 초기화 필요
- 초기화과정: pv삭제(정의 삭제), 스토리지 남은 데이터 직접 처리(삭제 or 그대로 남겨둔다), pv재생성
- access mode
- 1.readwriteOnce- 하나의 노드에서만 읽고 쓰기가 가능하게 마운트한다(하나의 pod가아니라)
- 2.readonlymany- 여러개의 pod(node)에서 동시에 읽기만 가능하게 마운트한다
- 3.readwritemany- 여러개의 node에서 동시에 쓰기 읽기가능, 동시제어가능한 스토리지여야된다. 지원하는 스토리지(nfs)
스토리지 클래스
- 물리적인 장치의 종류와 타입별로 스토리지 클래스를 미리 정해놓고, 추후에 지정해서 사용하는 방식
7.컨피그맵과 시크릿
- 두개는 거의 비슷하지만, 저장방식의 차이, 저장하는 데이터타입의 차이
- 컨피그맵은 일반적인 pod등의 정보, 시크릿은 암호화해야되는 정보 암호키등등
- 컨피그맵이 많이 사용됨
컨피그맵
- 변수 아니면 파일
- 응용프로그램이 사용할 변수들을 etcd에 저장한다.
- 변수를 사용하는 방식
- 1.pod가 생성되는 node에 init container든지 모든지 사용해서 local volume에 정보를 넣어둔다
- 2.etcd에 저장을 해서 pod가 etcd를 참조해서 생성할 수 있다.
- 공통으로 사용할수 있도록 하는걸 컨피그 맵에 넣어둔다.
- 하지만 용량적 제한이 있기때문에 변수 설정파일들 정도가 가능하다
- etcd kv형태로 자료를 저장
- 생성하는 방식이 yaml파일 사용하는 방법, kubectl create로 직접 생성하는 방법이 있다.
- 직접생성시 옵션이 fromfile로하면 파일내용자체가 하나의 value로 들어가고 fromfileenv로 하면 각각의 내용이 파일로 저장되어서 key value개별항목으로 저장된다.
시크릿
- 위의 정보를 암호화해서 저장해놓은것
8.파드 스케줄링
- 노드 필터링 -> 노드 스코어링
- 필터링: request resource만큼 없는 경우/ 마스터(taint)는 거르고/ node의 status가 ready가 아닌경우
- 스코어링: 필요이미지가 이미 노드에 존재/ 가용자원이 많을 수록 -> 합산점수 높은순으로
9.taint & toleration, cordon & drain
- taint- 일반적인 놈들은 못쓰게,(key=value:effect형식으로 작성)
- effect타입 -> noexecute-> 미리생성된 애들도 toleration조건에 안맞으면 삭제/ noschedule-> 이미생성된 애들은 그냥두고 추가적인 애들만 toleration조건 판별/ preferNoSchedule-> 가능한 안하겠다. 스코어 0.1점이라고 생각
- toleration- 내가 지정한 놈들은 쓸수 있게
- cordon - 특정노드에 있는 파드를 모두 옮기거나, 더이상 추가되지않도록 하는것. 잠깐 노드를 잠구는 역할
- cordon으로 잠그고 uncordon으로 연다
- drain - 실행되고 있는 파드를 모두 삭제해서 비우자. drain을 하면 자동적으로 cordon으로 걸어잠구고 삭제하는 과정 -> 삭제하면 controller에의해서 자동으로 다른곳으로 생겼다
- drain이후 작업끝나면 uncordon해야된다.
- drain으로 죽지않는 daemonset이나 개별적으로 배포가된애들은 재생성 등등 이 되지않기때문에, 무시하거나 그냥 두거나 해야된다.
10.인증과 권한
- authentication -> authorization순서로 진행
- 권한:sa- service account- namespace에 종속적
롤과 클러스터롤
- role: namespace에 종속된 놈- default namespace에 pod를 조회하는 권한/ 생성하는 권한
- cluster role: 모든 네임스페이스
- pv는 네임스페이스에 종속되지않는다.
- node는 네임스페이스에 종속되지 않는다.
- namespace항목에 false로 되어있으면, namespace에 종속되지않는 놈들 = cluster role로 권한 지정
- resource: 대상에 대한 것(kubectl api-resource의 첫번째 name항목)
- verbs: 행위에 대한 것
- apigroup - apiversion에서 /앞에만 버전만있다? 생략가능
- 롤과 클러스터롤은 namespace항목 유무만빼고 같음
롤바인딩
- 계정과 롤을 바인딩해준다
11.HPA 오토 스케일링
- 자동으로 POD의 수를 조절하는것
- 대상 파드의 개수 = 현재 파드의 CPU사용량 총합/ 목표 CPU사용률 을 올림한값 (목표 CPU사용률이 넘지않도록 평균사용률이 넘으면 새롭게 파드를 만들어 주는것)
- 쿠버네티스는 성능 매트릭을 수집하는 기능이 기본적으로 없다
- metrics-server라는 pod를 사용
'인프라' 카테고리의 다른 글
리눅스 smp cpu affinity와 numa설정 (0) | 2022.09.19 |
---|