W15 Kubernetes 3/3
13주차부터 진행되었던 쿠버네티스의 학습 내역을 정리하였습니다.
시크릿(Secret)
- 컨피그맵과 유사한 키/값 저장소
- 데이터를 조금 더 안전하게 보관하기 위한 용도
- 특정 용도로 사용되는 시크릿 유형이 있음
시크릿 유형
- generic: 일반적인 시크릿의 유형. 컨피그맵과 유사한 유형
type: Opaque - docker-registry: 도커 로그인정보 저장
type: kubernetes.io/dockerconfigjson - tls: TLS 암호화를 하기 위한 키 저장소
type: kubernetes.io/tls - serviceAccount: 사용자가 임의로 지정할 수 있는 유형이 아님. 사용자 계정의 토큰 정보 저장
type: kubernetes.io/service-account-token
시크릿 리소스 생성
- 명령어를 사용하는 방법
kubectl create secret<시크릿이름> <값을 넣기="" 위한="" 내용=""> 값을>시크릿이름> - generic 타입의 시크릿 생성
생성: kubectl create secret generic mysecret –from-literal=key1=value1
확인1: kubectl describe secrets mysecret
확인2: kubectl get secrets mysecret -o yaml
- generic 타입의 시크릿 생성
- 오브젝트 파일을 사용하는 방법
시크릿으로 저장할 키의 값을 base4로 변환하여 입력apiVersion: v1 kind: Secret metadata: name: my-credential data: ID: dXNlcg== PW: UEBzc3cwcmQ=
시크릿 데이터 사용
-
환경변수 형태로 사용 (개별 키)
env: - name: ID valueFrom: secretKeyRef: name: <Secret이름> key: <Key이름>
apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: - name: secret-env-container image: ubuntu command: ["sleep", "infinity"] env: - name: ID valueFrom: secretKeyRef: name: my-credential key: ID - name: PW valueFrom: secretKeyRef: name: my-credential key: PW
-
환경변수 사용 (전체 키)
envFrom: - secretRef: name: <시크릿 이름>
apiVersion: v1 kind: Pod metadata: name: secret-env-pod spec: containers: - name: secret-env-container image: ubuntu command: ["sleep", "infinity"] envFrom: - secretRef: name: my-credential
-
시크릿을 볼륨으로 사용
spec: containers: ... volumeMounts: - name: <볼륨이름> mountPath: <마운트위치> volumes: - name: <볼륨이름> secret: name: <시크릿이름>
apiVersion: v1 kind: Pod metadata: name: secret-volumemount-pod spec: containers: - name: test-container image: ubuntu command: ["sleep", "infinity"] volumeMounts: - name: mycredvol mountPath: /tmp volumes: - name: mycredvol secret: secretName: mycredfile
BASE64 Encoding
Byte: 8bit = 2^8 = 256
A-Z, a-z, 0-9, !@#$%^&*()<>?”;
ASCII = American Standard Code for Information Interchange
Byte단위로 글자를 표기 - 모든 Byte의 값을 글자로 표현하지 못함
BASE64
- 2^6 만큼의 경우의 수를 가지는 단위로 글자를 표기
- A-Z(26) + a-z(26) + 0-9(10) + ‘+’ + ‘/’ = 64개
000000(A)
000001(B)
000010(C)
...
111110(+)
111111(/)
01010101 11110000 10101010
→ 010101 011111 000010 101010
ABC → QUJD
$ echo -n ABC | base64
소프트웨어 배포 전략/테스트 전략
배포 전략
- 재생성
- 현재 동작중인 인스턴스들을 모두 중지하고 새로운 인스턴스를 생성하여 배포
- 기존 동작중인 어플리케이션이 모두 중지되므로, 다운타임 발생
- 가장 단순한 배포방식
- 순차 배포
- 기존 어플리케이션과 새로운 버전의 어플리케이션을 함께 구동
- 재성성 배포 방식과 달리 서비스의 다운타임의 없게 하거나 최소화 할 수 있음
- 기존 어플리케이션과 신규 어플리케이션의 호환성을 고려
- 블루/그린 배포
- 기존 어플리케이션과 신규 어플리케이션의 리소스를 동시에 생성
- 기존 어플리케이션에서 신규 어플리케이션으로 한번에 이전 가능, 다운타임 없음
- 비용의 문제 고려가 필요 (동시에 기존/신규 어플리케이션 인프라 필요)
테스트 전략
- 카나리 테스트 : 새로운 어플리케이션을 테스트하기 위하여 테스트용 리소스를 일부만 배포하여 테스트
- A/B: 같은 요청에 대하여 A와 B로 나누어진 요청 처리를 하도록하여 정상 처리 여부 등을 확인
- 섀도우 테스트: 기존 서비스의 요청을 미러링 하여 테스트 리소스로 전달
디플로이먼트(Deployment)
- 컨트롤러의 유형 중 하나
- 레플리카셋의 상위 리소스 처럼 동작
디플로이먼트 - 레플리카셋 - 파드 - 업데이트 기능을 제공
레플리케이션 컨트롤러를 사용한 롤링업데이트(순차업데이트)
-
롤링업데이트를 위한 RC리소스 및 서비스 리소스 생성
apiVersion: v1 kind: ReplicationController metadata: name: rolling-update-rc spec: replicas: 3 selector: app: myapp template: metadata: labels: app: myapp spec: containers: - name: rolling-update-container image: misayo/myapp:1 ports: - containerPort: 80 protocol: TCP
apiVersion: v1 kind: Service metadata: name: rolling-update-service spec: selector: app: myapp ports: - targetPort: 80 port: 80
-
테스트 리소스 생성 후, 서비스를 통해 출력되는 http응답 및 파드 상태를 모니터링
watch -n 1 curl <서비스IP> watch -n 1 kubectl get pod서비스IP> -
레플리케이션 컨트롤러의 롤링업데이트 기능을 사용한 업데이트 수행 kubectl rolling-update <현재RC> <새로운RC> --image=misayo/myapp:2 (현재 1.21.12 버전에서는 더이상 rolling-update 서브커맨드 지원하지 않음)새로운RC>현재RC>
레플리케이션 컨트롤러의 롤링업데이트의 문제점
- 명령어에 의한 직접적인 업데이트 수행: 업데이트 중지 등의 문제가 발생할 수 있음. 명령의 오류 발생시 업데이트 불가
- 레이블 정보를 임의로 추가: 사용자에 의한 추가가 아닌 업데이트 작업에 의한 임의의 수정이 발생하여 문제가 될 수도 있음. (deployment 레이블 생성)
디플로이먼트 리소스
- 명령어의 지속적인 실행상태에 의한 업데이트가 아닌 리소스 차원의 업데이트 수행
- 리소스의 임의 변경 등이 필요하지 않음
디플로이먼트 리소스 테스트
-
디플로이먼트 리소스 생성
apiVersion: apps/v1 kind: Deployment metadata: name: rolling-update-deployment spec: selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: rolling-update-container image: misayo/myapp:1 ports: - containerPort: 80 protocol: TCP
apiVersion: v1 kind: Service metadata: name: rolling-update-service spec: selector: app: myapp ports: - targetPort: 80 port: 80
-
테스트 리소스 생성 후 확인
kubectl get deployments.apps rolling-update-deployment -o yamlspec: ... strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate ...
type: RollingUpdate / Recreate
-
기존 Deployment 리소스 삭제 후 재 생성
kubectl delete -f deployment.yaml
kubectl create -f deployment.yaml –record
kubectl rollout status deployment rolling-update-deployment
kubectl history status deployment rolling-update-deployment -
디플로이먼트 리소스에 대한 업데이트 수행
kubectl set image deployment rolling-update-deployment rolling-update-container=misayo/myapp:2
kubectl set image deployment <디플로이먼트이름> <컨테이너명>=<이미지>이미지>컨테이너명>디플로이먼트이름> -
업데이트 실행 후 상태 확인
kubectl rollout status deployment rolling-update-deployment
kubectl history status deployment rolling-update-deployment -
v2 → v3 업데이트 수행 (–record 포함)
kubectl set image deployment rolling-update-deployment rolling-update-container=misayo/myapp:3 –record -
업데이트 롤백 (undo)
kubectl rollout undo deployment rolling-update-deployment –to-revision=2
kubectl rollout undo deployment <디플로이먼트이름> --to-revision=<리비전번호>리비전번호>디플로이먼트이름> -
오브젝트 파일을 사용하여 리소스 업데이트
apiVersion: apps/v1 kind: Deployment metadata: name: rolling-update-deployment annotations: kubernetes.io/change-cause: Container Image set to misayo/myapp:3 spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: rolling-update-container image: misayo/myapp:3 ports: - containerPort: 80 protocol: TCP
스테이트풀셋(Stateful Set)
- 스테이트리스(Stateless)한 파드의 특성과 상반되는 특성을 가지는 파드를 제어하기 위한 컨트롤러
-
Pet Set ⇔ 가축
- 일반적인 복제본을 생성하는 컨트롤러 파드의 특성: Stateless
- 파드는 영속성을 고려하지 않음
- 데이터에 대한 보존에 대한 고려 필요
- 컨트롤러에 의해 생성된 각 파드는 역할이 동일
- 스테이트풀셋의 파드의 특성
- 영속성을 고려. 영속성이 보장되어야 함
- 파드별로 영구 볼륨을 할당 가능
- 컨트롤러에 의해 생성된 각 파드의 역할을 구분할 수 있음
스테이트풀셋에서 볼륨 사용
- 영구볼륨을 사용하는 것을 기본으로 전제
- 각 파드마다 별도로 PVC를 할당할 수 있음
- PVC를 생성하여 볼륨을 할당하기 위해서는 동적 PV할당을 제공하는 스토리지가 필요 (실습을 위해 rook storage 설치 필요, 13페이지)
- 스테이트풀셋은 반드시 헤드리스 서비스를 필요로 함
영구 볼륨을 사용하는 스테이트풀셋
스테이트풀셋 파드 업데이트
- 디플로이먼트 리소스와 유사하게 업데이트 기능을 제공
쿠버네티스의 스케줄러
-
실제 파드가 노드에 배치되기 위해 스케줄러가 파드의 노드 배치를 결정하고, API 서버를 통해 파드 배치
-
파드의 노드 배치에 영향을 주는 요소
- 노드 셀렉터
- 노드 네임
- 어피니티
- 테인트
- 톨러레이션
- 커든
- 드레인
참고> static pod (스태틱 파드)
- 스태틱 파드는 특정 노드의 kubelet에 의하여 실행되는 파드이므로, kube-scheduler에 의해서 배치되지 않고, 직접 노드에 실행됨
- /etc/kubernetes/manifest : 스태틱 파드의 오브젝트 파일 위치
- /var/lib/kubelet/config.yaml : 스태틱 파드를 실행하는 kubelet 설정(staticPodPath)
노드 셀렉터(Node Selector)
- 파드를 특정 노드를 지정하는 대신 레이블 정보에 따라 대상 노드를 탐색하여 배치할 수 있도록 지정하는 방식
- 파드의 정의에서 nodeSelector 항목을 생성하여 지정
- 레이블 정보를 사용: Node의 레이블 정보에 따라 지정
어피니티(Affinity)
- 끌림, 선호도
- 어피니티 종류
- 노드 어피니티
- 파드 어피니티
- 파드 어피니티
- 파드 안티어피니티
노드 어피니티
- Node Selector와 유사한 개념
- 노드 셀렉터와의 차이점
- 노드 셀렉터: 반드시 레이블 조건을 만족하여야 파드 배치
- 노드 어피니티: ‘선호도’를 지정하는 개념, 선호하지 않는 경우에도 파드 배치 가능
- 노드 어피니티 설명
- kubectl explain pod.spec.affinity
- kubectl explain pod.spec.affinity.nodeAffinity
- 주의: nodeSelectorTerms, matchExpressions 조건
- nodeSelectorTerms는 복수의 matchExpressions 조건을 포함(List)
- : matchExpression 항목 중 하나라도 만족하면 Selector에서 파드를 배치 (OR)
- matchExpressions는 복수의 세부 조건을 포함(key, operator, value)
- : 각 조건 항목을 모두 만족해야 조건 성립(AND)
- nodeSelectorTerms는 복수의 matchExpressions 조건을 포함(List)
matchExpressions 내 operator 항목
- Exist/DoesNotExist: 키 존재 유무 (value 항목이 필요하지 않음)
- In / NotIn : 집합성 기반 (value 항목을 List로 입력하고, 포함여부 확인)
- Gt(Greater Than), Lt(Less Than) : value 항목을 수치로 판단
preferredDuringSchedulingIgnoredDuringExecution 내 weight의 의미
- 가중치
- 1~100 사이의 수치를 지정
xxxxDuringSchedulingIgnored
- 스케줄링 시 어피니티 설정 반영
IgnoredDuringExecution
- 파드가 배치되어 실행된 이후에는 어피니티 설정 무시
파드 어피니티
- 파드에 대한 선호도를 지정
-
어피니티에 따라서 배치될 노드가 결정
- 파드 어피니티 설명
- kubectl explain pod.spec.affinity.podAffinity
- kubectl explain pod.spec.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution
- kubectl explain pod.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution
- topologyKey: 파드의 어피니티 설정에 따라 분리/결합시킬 때 기준이 되는 값
- (참고: kubectl get nodes –show-labels)
HPA(Horizontal Pod Autoscaler)
- 쿠버네티스 리소스 유형 중 하나
- HPA를 사용하기 위해서는 Metric 서버가 필요함
Metric Server
- 쿠버네티스 모니터링 아키텍처의 표준 모니터링 도구
- kubelet으로 수집된 파드 및 노드의 메트릭 정보를 API로 조회
- Metric Server는 데이터를 영구적으로 저장하지 않으며, 필요시 외부 스토리지를 사용하여 보관
Metric 서버 설치
- wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
components.yaml 파일 수정
- (Line 139)metric-server 디플로이먼트의 파드 템플릿의 args에 –kubelet-insecure-tls 추가
- (Line 100)metric-server 서비스 설정 변경
Metric 서버에 필요한 서비스 어카운트 권한 설정
Metric 서버 관련 리소스 생성
- kubectl create -f components.yaml -f metric-crb.yaml
Metric Server : 데이터 수집
Prometheus : 시계열 데이터 저장
Grafana : 대시보드 형태의 모니터링 환경 제공
파드에 대한 자원 할당 설정
- 최소요구치: 파드가 스케줄링 되기 위해서는 해당 노드에 지정한 만큼의 리소스가 할당이 가능하여야 함
- 한계치: 파드가 노드에서 실행될 때 사용할 수 있는 자원의 최대치
파드 부하 테스트
- 파드 쉘 연결
- kubectl exec -it resource-limit-pod – /bin/bash
- 연결 후 부하 발생 명령 실행
- sha256sum /dev/zero
- 발생한 부하에 따른 사용량 확인
- kubectl top node
- kubectl top pod
DoS / DDoS
DoS: Denial of Service
- 시스템 자원 고갈 (CPU, RAM)
- 네트워크 대역폭 고갈 (Bandwidth)
- 세션 고갈 (F5, TCP)
DDoS: Distributed DoS
DRDoS : Reflect 개념 추가
HPA 리소스
리소스 설명
kubectl explain horizontalpodautoscaler.spec
인증
인증/인가/어카운팅
- 인증(Authentication)
- 식별하기 위한 절차
- 적법한 사용자에 대하여 허가/부적법한 사용자에 대한 차단
- 인증 오류
- 1종 오류: False Negative. 적절한 사용자가 인증 실패
- 2종 오류: False Positive. 부적절한 사용자가 인증 성공
- 인가(Authorization)
- 인증된 사용자에게 적절한 권한을 부여
- 어카운팅(Accounting)
- 인증/인가를 통과한 사용자의 작업에 대한 기록, 관리
서비스어카운트(ServiceAccount)
- 인증/인가를 통과한 사용자의 작업에 대한 기록, 관리
- 쿠버네티스 클러스터 내 사용자 계정 리소스
- 네임스페이스 범위로 생성
- 사용자 계정 생성 시 사용자 계정의 인증정보를 포함하는 시크릿 리소스가 함께 생성
서비스어카운트 리소스 예시
apiVersion: v1
kind: ServiceAccount
metadata:
name: <계정이름>
namespace: default
명령을 사용한 서비스어카운트 리소스 생성
- kubectl create sa <계정이름>계정이름>
서비스어카운트와 함께 생성되는 시크릿 정보
- kubectl get secret
- <계정명>-token-<임의의5문자> 임의의5문자>계정명>
kubectl 명령어 실행 시 사용되는 사용자 계정의 정보
- ~/.kube/config
권한 부여
RBAC
- Role Based Access Control
- 일반적으로 쿠버네티스 클러스터 내에서 권한을 부여하기 위한 방식
- 역할 리소스 생성하여 적용 : 역할 바인딩
ABAC
- Attribute Based Access Control
- 권한 부여에 대한 내용을 API Server에 직접 설정
- API 서버에 직접 접근하여 설정 수정 / 설정을 반영하기 위하여 재시작
역할의 종류
- Role: 네임스페이스 단위로 범위가 제한된 권한 리소스
- ClusterRole: 전체 클러스터 단위가 범위인 권한 리소스(네임스페이스가 없음)
역할을 사용자에게 연결하기 위한 리소스의 종류
- RoleBinding: Role을 사용자에게 연결하기 위한 리소스
- ClusterRoleBinding: ClusterRole을 사용자에게 연결하기 위한 리소스
역할 리소스(Role)
- 특정 리소스에 대하여 허용할 권한을 명시하는 리소스
- verbs 항목
- create : 개체에 대한 생성 권한
- get : 특정 개체의 개별 정보 조회
- list : 개체의 목록 조회
- update : 개체에 대한 전체 내용 갱신 권한
- patch : 개체에 대한 일부 내용 수정 권한
- delete : 개별 개체 삭제 권한
- deletecollection : 다수 개체 삭제 권한
- watch : 개체가 사용하는 자원 개별 확인
역할 바인딩
- 역할 개체와 서비스어카운트/그룹을 연결하는 리소스
- roleRef: 역할 개체의 정보
- subject: 역할을 부여받을 대상의 정보
클러스터역할(ClusterRole)
- 네임스페이스 범위가 아닌 전체 클러스터 범위의 권한을 부여하는 역할
- 알려진 역할
- cluster-admin: 클러스터 전체에 대한 권한을 가지고 있는 역할
- admin: 역할/역할바인딩, 네임스페이스 기록권한을 가지고 있지 않고, 나머지권한을 가지고 있는 권한을 가지고 있는 클러스터역할
- edit: 대부분의 리소스에 대한 읽기/쓰기 권한
- view: 대부분의 리소스에 대한 읽기 권한
클러스터 역할 바인딩
- 클러스터 역할을 사용자 및 그룹에 연결하기 위한 리소스
Leave a comment