Prometheus 및 Prometheus Operator를 기반으로 하는 전체 클러스터 모니터링 스택에 대한 예제 구성을 제공
여러 Prometheus 및 Alertmanager 인스턴스의 배포, 노드 메트릭 수집을 위한 node_exporter와 같은 메트릭 내보내기, Prometheus를 다양한 메트릭 엔드포인트에 연결하는 스크랩 대상 구성, 클러스터의 잠재적인 문제 알림을 위한 예제 경고 규칙이 포함
- Thanos Ruler : Thanos에 의해 연동된 모든 프로메테우스의 룰을 정의하고 처리.
- Thanos Compactor : 수집된 데이터를 기준에 따라 장기 보관용 데이터로 변환
3. Prometheus Agent 모드(Prometheus Remote Write)
- Remote Write : Prometheus에서 수집한 모든 지표 또는 일부 지표를 원격 위치로 전달(스트리밍)
Cortex, Thanos, OpenTelemetry 및 Amazon, Google, Grafana, Logz.io 등과 같은 클라우드 서비스는 모두 원격 쓰기를 통한 데이터 수집을 지원하게 됨
안정적이고 효율적인 Remote Write 구현 :안정적이고 확장 가능한WAL(write-ahead-log)구현. 내부 대기열, 샤딩, 스마트 백오프 등을 추가
- Prometheus Agent 모드
프로메테우스 v2.32.0 버전 이상에서 사용 가능
프로메테우스 서버에 내장되어 --enable-feature=agent 플래그 설정 변경으로 사용가능
에이전트 모드는 원격 쓰기 사용 사례에 대해 Prometheus를 최적화
쿼리, 경고 및 로컬 스토리지를 비활성화하고 이를 사용자 정의된 TSDB WAL로 대체(스크래핑 로직, 서비스 검색 및 관련 구성과 같은 다른 모든 것은 동일하게 유지)
장점
효율성 : agetn TSDB WAL은 성공적인 쓰기 직후 데이터를 제거함. remote endpoint 에 도달할 수 없는 경우에는 remote endpoint이 다시 온라인 상태가 될 때까지 데이터를 디스크에 임시로 유지(서버 모드 설정과 동일). 즉agent 모드는 일반 Prometheus 서버가 유사한 상황에서 사용하는 리소스의 일부만 사용하게 됨.
확장 가능성 : 메트릭 대상의 양과 대상이 노출하는 메트릭의 수를 기반으로 자동 확장이 가능해야 함. 서버 모드의 Prometheus에서는 수집된 모든 것이 한곳에 있는 그대로 유지되어야 하고(stateful) 모든 인스턴스(예: Thanos Query 또는 Promxy)에서 모든 샘플을 집계할 수 있는 전역 보기 쿼리가 필요하게 됨. agent 모드는 검색, 스크래핑 및 원격 쓰기를 별도의 마이크로 서비스로 이동하여 수집에만 집중된 운영 모델이 가능함.(stateless) Prometheus 기반 스크래핑의 손쉬운 수평적 자동 확장 기능을 활성화하여 지표 대상의 동적 변화에 반응 가능.
4번 명령어 플래그 : terraform apply -var “filename=/root/cats.txt”
Resource Dependencies
Implicit Dependency : 암묵적으로 다른 리소스의 속성을 가져다 쓰는경우. 먼저 지워야한다.($resource_type.resource_name.attribute)
Explicit Dependency : depends on으로 명시적으로 기술한 경우 (왜 이걸 쓰는지 확인 필요)
Output Variables
output 블럭 사용
output “변수명” { value = variable_value …. }
$ terraform output 으로 모든 output 변수를 확인할 수 있다. $ terraform output 변수명 으로 해당 변수명에 대한 값을 확인할 수 있다.
앤서블이나 쉘 스크립트에서 사용가능하다.
Terraform state
terraform init : plugin 받는다
terraform plan :
terraform apply :
terraform.tfstate : 테라폼 스테이트 파일. apply 명령어로 생성됨. json 데이터 구조. 테라폼 명령어로 생성된 모든 인프라가 적혀 있음. single source of truth 로 사용됨 plan 시 tfstate 파일과 비교해서 작성하게 됨
tfstate 파일 사용 – 종속관계 파악 : 리소스들간의 종속성을 파악하여, 생성/삭제 시 디펜던시가 있는 리소스 먼저 삭제한다. – 성능 : tfstate 파일을 직접 사용할 뿐만 아니라 캐싱 처리도 해둠. 대규모 인프라를 사용하는 곳에서는 매번 tfstate 파일을 refresh 하면 시간이 많이 걸리기 때문에 terraform plan –refresh=false와 같은 명령어로 캐시에서도 사용가능함 – Collaboration : 팀으로 일하는 경우 terraform.tfstate 파일을 팀원간에 공유하여 remote state로 관리한다.
tfstate 고려할점 – state 파일은 민감한 정보를 포함한 인프라의 모든 정보를 다 담고 있다. DB라면 비밀번호도 가지고 있다. – state 파일은 안전한 스토리지에 저장해두어야 한다. – tf 파일은 깃헙 정도면 되지만, state 파일은 S3나 gcp bucket 같은 안전한곳에 보관한다. – tfstate 파일을 직접 건드리지 않는다.
terraform 명령어
– terraform validate : tf 파일이 유효한지 확인한다. – terraform fmt : tf파일을 보기 좋은 형태(cannonical format)로 변경해준다. – terraform show : 생성된 인프라의 모든 정보를 다 보여준다.(-json 플래그로 json 형태로 표시가능) – terraform providers : provider 정보를 다 보여준다. – terraform output : 결과로 생성되는 변수를 다 보여준다. – terraform refresh : 테라폼으로 만든 인프라를 수동으로 수정한 경우, tfstate 파일을 현재 상태에 맞도록 수정한다. – terraform graph : apt install graphviz -y 설치하여 terraform graph | dot -Tsvg > graph.svg 로 파일 생성 후 파일 열면, 리소스 간의 형태를 그래프형태로 볼수 있다.
Mutalbe vs Immutable Infrastructure
테라폼은 왜 인프라를 다 부셨다가 다시 만들까? 서버의 버전을 올린다고 생각해보면, 서버 여러대를 운영할 경우 기존 서버를 업그레이드 하는 건 업그레이드 과정에서 여러가지 이슈가 발생할 수 있다.(configuration drift) 서버들이 운영 중에 미묘하게 차이가 날 수 있다.
따라서 버전이 올라간 서버를 새로 만들고, 오래된 버전의 서버를 폐기한다. -> Immutable Infrastructure 버전을 올린 서버에 문제가 생긴 경우, 다시 이전 버전의 서버를 살린다. 인프라 스트럭처에 버저닝을 하는건 롤백도 쉽고, 운영도 쉽다.
EC2에서 이중화한 서버의 경우 시간대는 KST나 UTC로 맞추었지만, date를 찍어보면 2~3분 정도 시간차이가 발생하는걸 확인할 수 있다.
이런 경우 발생한 로그를 추적하기에도 어려움이 있기 때문에 시간을 동일하게 맞추어 주는 작업이 필요하다.
Amazon Time Sync Service를 사용하면 손쉽게 적용 가능하다.
아래와 같은 명령어를 입력하여 서버에 적용하면 서버간 시간대가 초 단위까지 일치하는 것을 확인할 수 있다.
$ sudo apt update
$ sudo apt install chrony
$ sudo vi /etc/chrony/chrony.conf
#server나 pool 문 앞에 아래 내용 추가
server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4
#chrony 서비스 재시작
$ sudo /etc/init.d/chrony restart
#동기화 확인
$ chronyc sources -v
#동기화 지표 확인
$ chronyc tracking
dump용 EC2 : postgreSQL client 버전 12 이상이 설치되어 있는 서버. source RDS와 target RDS에 접속가능해야 한다.
DUMP 수행
postgreSQL RDS는 rdsadmin 이 소유하고 있는 database가 있는데 이건 RDS 생성시 만들었던 master 계정이 권한이 없기 때문에 덤프를 뜨는게 불가능하다. postgreSQL 12버전 이상을 사용하면 특정 database를 제외하고 덤프를 뜰 수 있다.(–exclude-database 옵션)
덤프를 뜨기전, master 계정이 database에 권한을 가지고 있는지, tablespace 소유 여부를 확인한다.
# postgreSQL 접속
$ psql --host=(source RDS Endpoint) --port=(source RDS port) --username=(master 계정) --password
# db list 조회
> \l
# 사용자 권한 조회
> \du
# table space 조회
> \db
# master 계정 소유로 table space 변경
> ALTER TABLESPACE (tablespace 명) OWNER TO (master 계정);
# master 계정에게 db 권한 부여
> GRANT (db명) TO (master 계정);
master계정에게 권한이 부여되었다면, 아래 명령어로 rdsadmin이 소유한 database는 제외하고 dump를 뜬다. –no-role-passwords 옵션을 사용하여 super_user 권한이 없는 계정으로 dump를 뜬다. 복원 후 사용자 비밀번호는 다시 지정한다.
# target RDS 연결
$ psql --host=(target RDS Endpoint) --port=(target RDS port) --username=(master 계정) --password
# 사용자 정보 변경
> ALTER ROLE (사용자명) WITH LOGIN;
> ALTER USER (사용자명) WITH PASSWORD '(비밀번호)';
40 GB 데이터 베이스 기준으로 dump 뜨는데 30분, restore하는데 20분이 수행되었다.
pg_dump의 경우 table space 및 사용자의 권한은 복사되지 않고, 데이터 베이스 별로 덤프를 떠서 복원해야 하기 때문에 RDS 전체 데이터를 백업해야 하는 경우에는 pg_dumpall 이 더 빠르고 정확하고 편하다.
누구나 아는 그 강의를 신청하였습니다. 개인적으로 영어를 듣기에 힘이 들어 kodekloud 에서 제공해주는 실습 위주로 공부하였습니다. 직접 명령어를 치며 개념을 익히는 방안으로 수행하니 지루하지 않게 공부할 수 있었습니다. 이론을 제대로 듣지 않았던 만큼 실습을 3번정도 돌며 공부했습니다.
Kubernetes in Action
어려운 개념은 잘 정리된 블로그를 참고하셔도 되지만, 책을 보고 싶은 분은 이 책을 보시면 됩니다. 두께가 상당한 만큼 기본 개념들에 대한 설명이 자세하게 잘 나와 있습니다. 모르는 부분 위주로 찾아서 읽었습니다.
시험 대비
시험 보기 전 다른 분들의 후기를 많이 찾아봤습니다. 저는 k8s cluster 업데이트, kubelet 트러블 슈팅, etcd 백업 및 복구 문제가 어려운 난이도의 문제였는데 거의 비슷하게 나오는것 같으니 이정도는 꼭 미리 보고 가셨으면 좋겠습니다.
시험 볼때 사용중인 클러스터를 매 문제마다 변경해야 합니다. 이부분에 가장 실수가 많을것 같습니다. 문제 풀 때 클러스터를 꼼꼼히 확인 하셔야 합니다.
2시간이라서 시간이 부족할까 걱정했는데 의외로 시간은 많이 남았습니다. 어려운 문제만 잘 확인하고 가신다면 그렇게 어려운 시험은 아닌 것 같습니다.
참고가능한 명령어
공부하면서 사용했던 명령어들입니다. 주로 KodeKloud 의 실습 문제들에 활용이 가능합니다. 좋은 결과 있으시길 바랍니다.
alias 사용
https://kubernetes.io/ko/docs/reference/kubectl/cheatsheet/
alias k='kubectl'
interactive 명령어 사용
#create taint
kubectl taint nodes node01 spray=mortein:NoSchedule
#untaint
kubectl taint nodes master node-role.kubernetes.io/master:NoSchedule-
#node info
kubectl get pods -o wide
#노드한테 label 추가
kubectl label node node01 color=blue
#create deployment
kubectl create deployment blue --image=nginx
kubectl scale deployment blue --replicas=6
#create static pod
kubectl run --restart=Never --image=busybox static-busybox --dry-run=client -o yaml --command -- sleep 1000 > /etc/kubernetes/manifests/static-busybox.yaml
#multi scheduler
netstat -natulp | grep 10251 ~ 10253까지 찾아서 안쓰는걸로 port 지정
#log
kubectl logs -f pod이름 (container 이름)
# exec pod
kubectl -n elastic-stack exec -it app cat /log/app.log'
# config view
kubectl config view --kubeconfig my-kube-config
# 현재 컨텍스트(접속 매개 변수)를 선택
kubectl config use-context
# change current context
kubectl config --kubeconfig=/root/my-kube-config use-context research
# get role
kubectl get roles
# user check
kubectl get pods --as dev-user
# get count
kubectl get clusterroles --no-headers | wc -l
# confirm auth
k auth can-i list nodes --as michelle
# edit deployment
kubectl edit deployment
#api resource 확인
kubectl api-resources
network 영역
#network
cat /etc/network/interfaces #network interface 확인가능
# get mac address
arp node01
# route table 확인
ip route
#port 확인
netstat -nplt
netstat -anp | grep scheduler
netstat -anp | grep etcd
# CNI plugin 확인
ls /etc/cni/net.d/
# network ip range
ip addr