[CKAD] Kubernetes Certificate Application Developer(CKAD) with Tests 학습노트(3/)
Labels and Selectors
자원에 레이블로 메타 정보를 추가하고 해당 메타 정보를 이용하여 자원을 선택한다. 이를 통하여 deployment 등을 생성할 때, deployment에 속한 pod를 생성하는데, deployment의 selector는 고유한 pod 그룹을 선택할 수 있도록 레이블과 셀렉터를 선택하여야 한다.
rolingupdate
배포를 업데이트할 뿐만 아니라 롤백할 수도 있음
kubectl rollout undo deployment/<deploymentname>
deployment 생명주기
# 생성k create -f <deployment yaml file name># 확인k get deployment <deployment># 업데이트k apply -f <filename>k set image deployment/<deploymentname> <podname>=<imagename># 상태k rollout status deployment/<deploymentname>k rollout history deployment/<deploymentname># 롤백k rollout undo deployment/<deploymentname>
rollout에 대한 revision을 기록하고 과거 버전으로 회귀할 수 있다.
JOB AND Job Schedule
DemonSet
데몬이다. 데몬셋-pod로 구성됨. 아래와 같은 용도로 사용 된다.
- 스토리지 데몬
- 로그 수집 데몬
- 노드 모니터링 데몬
Replicaset
파드의 복제 세트.replicaset-pod로 구성됨
Cronjob
리눅스 크론잡과 같음. 리소스에 대한 매니페스트로 생성할 때 제공하는 이름. 이름의 최대 길이는 52자
- 최대 이름의 길이는 63자이나 크론잡 컨트롤러가 11자를 추가하므로 52자 맥스
ReplicationController
뭐지? 잘 모르겠다. pod 복제를 유지해주기 위한 셋인듯 하지만... 실제로는 deployment(with replicaset) 구성으로 사용하므로 거의 사용하지 않는다.
Replicaset
Deployment에 거의 종속하여 사용하게 된다.
StatefulSet
개별 pod의 고유성 보증을 위하여 제공
서비스 및 네트워킹
!! 이제 네트워킹으로 간다. 노출된다. 야호 !!
service
아래와 같은 형식의 서비스가 제공된다.
- clusterip : 클러스터 내부에서 사용되는 아이피
- nodeport : 고정 포트를 외부로 노출시킨다
- loadbalancer : 클라우드 공급자의 로드밸런서를 사용하여 오픈하며, clusterip, nodeport가 자동으로 설정된다.
- externalname : 외부 노출 이름
nodeport
클러스터 외부로 내부 서비스를 오픈. 특정 포트에 오픈하여 서비스를 진행한다. 잘하자.
외부 ip
클러스터 노드의 아이피가 외부로 노출되는 ip인 경우 externalip를 걸어서 클러스터 밖에서 클러스터에 접근을 진행할 수 있다. worker-1의 ip가 192.168.60.100이고 노드포트를 30007로 노출한 경우, 192.168.60.100:30007로 접근할 수 있다.
쿠버네티스 네트워크
컨테이너를 제공하는 여러 개발자 또는 팀에서 포트를 조정하는 것은 규모면에서 매우 어려우며, 사용자가 제어할 수 없는 클러스터 수준의 문제에 노출된다. 쿠버네티스는 파드가 배치된 호스트와는 무관하게 다른 파드와 통신할 수 있다고 가정한다. 쿠버네티스는 모든 파드에게 자체 클러스터-프라이빗 IP 주소를 제공하기 때문에 파드간에 명시적으로 링크를 만들거나 컨테이너 포트를 호스트 포트에 매핑 할 필요가 없다. 이것은 파드 내의 컨테이너는 모두 로컬호스트에서 서로의 포트에 도달할 수 있으며 클러스터의 모든 파드는 NAT 없이 서로를 볼 수 있다는 의미이다. 이 문서의 나머지 부분에서는 이러한 네트워킹 모델에서 신뢰할 수 있는 서비스를 실행하는 방법에 대해 자세히 설명할 것이다.
dns
내부 서비스들이 dns로 활성화되어 있다.
coredns
------------여기까지 네트워크
스토리지
컨테이너는 휘방성의 임시 파일 시스템을 가지므로, 이를 저장할 수 있는 시스템 구성이 필요하다
컨피그맵
구성 데이터를 파드에 주입하는 방법. 파드에 configMap:으로 마운팅하며 개별 값이 path라는 파일명으로 마운팅된다.
apiVersion: v1kind: ConfigMapmetadata:name: special-confignamespace: defaultdata:SPECIAL_LEVEL: verySPECIAL_TYPE: charm---apiVersion: v1kind: Podmetadata:name: dapi-test-podspec:containers:- name: test-containerimage: k8s.gcr.io/busyboxcommand: [ "/bin/sh","-c","cat /etc/config/keys" ]volumeMounts:- name: config-volumemountPath: /etc/config# SPECIAL_LEVEL이라는 컨피그맵의 값이 /etc/config/keys파일에 적힌다.volumes:- name: config-volumeconfigMap:name: special-configitems:- key: SPECIAL_LEVELpath: keys # 파일명이 keysrestartPolicy: Never
emptyDir
pod에서 임시 디렉토리를 생성하여 파드를 생성한다.
퍼시스턴트 볼륨과 퍼시스턴트 볼륨 클레임
퍼시스턴트 볼륨 : 프로비저닝한 클러스터의 스토리지 퍼시스턴트 볼륨 클레임 : 스토리지에 대한 요청
셀렉터
클래스
스토리지클래스네임 ??뭐지?
pvc는 반드시 클래스를 요청할 필요는 없다.
바인딩 할 수 있다.
맥에서 pvc오류
맥에서 storageclassname을 manual로 등록할 경우 정상 동작하지 않는다. 이를 해결하기 위하여
- storageclassname을 hostpath를 사용
- 별도의 storageclassname을 yaml로 생성한 후 사용 하여야 한다.
project
레지스트리 등록
docker run --name mirror-registry -p 52500:5000 \-v /opt/registry/data:/var/lib/registry:z \-v /opt/registry/auth:/auth:z \-e "REGISTRY_AUTH=htpasswd" \-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \-v /opt/registry/certs:/certs:z \-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \-e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true \-d docker.io/library/registry:2
로컬 레지스트리에 도커 이미지 올리기
이미지를 약간 조작 후 docker run --name snow-nginx nginx docker commit -m "snow nginx" snow-nginx snow-nginx:01
태그를 달고 docker tag snow-nginx:0.1 localhost:52500/snow-nginx:0.1
푸쉬를 하자 docker push localhost:52500/snow-nginx:01
설치 후 레지스트리 내의 레파지토리 확인
아래와 같이 컬을 날려보면 현재 구성되어 있는 전체 레파지토리 정보를 가져올 수 있다.
$ curl -u bipaadm:bipaadm -k https://localhost:52500/v2/_catalog{"repositories":["snow-nginx"]}
간단한 pod를 만들어서 상태 확인
로컬 레지스트리에 신규 등록한 경로를 image 경로에 넣어두고 실행해보면
apiVersion: v1kind: Podmetadata:name: myapp-podlabels:app: myapptype: front-endspec:containers:- name: nginx-containerimage: localhost:52500/snownginx:01
아래와 같은 정보를 던져준다.
% k describe pod myapp-podName: myapp-podNamespace: default...Containers:nginx-container:Container ID: docker://7c88c7f6f5fcae8a6b571c877f2f8c2d1b0a5b1fbf6cb507224f244007ad56bdImage: localhost:52500/snownginx:01Image ID: docker-pullable://localhost:52500/snownginx@sha256:6b83def3f1adba23a370dd8a386798536e6db6a541eb418fbb2b232e237ee38cEvents:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 9m9s default-scheduler Successfully assigned default/myapp-pod to docker-desktopNormal Pulled 9m8s kubelet Container image "localhost:52500/snownginx:01" already present on machineNormal Created 9m8s kubelet Created container nginx-containerNormal Started 9m8s kubelet Started container nginx-container
쿠버네티스의 리소스 단위
cpu : 0.1 memory : e, p, t, g, M, k m(millis) disk :
request와 limit이 있으나... 어느경우나 비슷하게 request는 크게 중요하게 걸지 않는다. 워밍업 자원이 용도인듯? 현업에서도 limit 위주로 많이 건다고 한다.
리소스쿼터
리소스에 대한 쿼터 제한을 둘 수 있다. 예를 들어, 1팀과 2팀이 네임스페이스별로 자원을 활용한다고하면, 두 팀에 동일량의 CPU와 memory를 준다. 신규 파드 생성시 자원을 쿼터보다 많이 사용하면 pod가 생성이 되지 않는다.
$ k get resourcequota -o yamlapiVersion: v1items:- apiVersion: v1kind: ResourceQuotametadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","kind":"ResourceQuota","metadata":{"annotations":{},"name":"mem-cpu-demo","namespace":"default"},"spec":{"hard":{"limits.cpu":"2","limits.memory":"2Gi","requests.cpu":"1","requests.memory":"1Gi"}}}creationTimestamp: "2023-04-27T08:14:44Z"name: mem-cpu-demonamespace: defaultresourceVersion: "511240"uid: f901588c-78f6-40f2-a21b-796a79c52466spec:hard:limits.cpu: "2"limits.memory: 2Girequests.cpu: "1"requests.memory: 1Gistatus:hard:limits.cpu: "2"limits.memory: 2Girequests.cpu: "1"requests.memory: 1Giused:limits.cpu: 500mlimits.memory: 128Mirequests.cpu: 250mrequests.memory: 64Mikind: Listmetadata:resourceVersion: ""
태스크
파드와 컨테이너 설정
label
노드별로 별도의 레이블을 설정할 수 있다.
대규모 설계에 대한 제안
적당한 사이징에 대한 제안. 노드당 파드 수 등
실습
서버 웹사이트를 쿠버네티스 기반 인프라로 마이그레이션
kubectl config set-context --current --namespace=<namespacename>
과제 내용은 다음과 같다.
Docker Build [ image명 교육생 영문 이니셜 ] -> taroguru/kjh:latest
Docker images docker.hub 등록 -> https://hub.docker.com/repository/docker/taroguru/kjh/general
kubenertes deployment Application 등록
taroguru@taroguruui-MacBookAir ~ % k get deploymentNAME READY UP-TO-DATE AVAILABLE AGEhomework-deployment 1/1 1 1 10m
apiVersion: apps/v1kind: Deploymentmetadata:name: homework-deploymentlabels:app: homeworkspec:replicas: 1selector:matchLabels:app: homeworktemplate:metadata:labels:app: homeworkspec:containers:- name: tomcat-boardimage: taroguru/kjh:latestports:- containerPort: 8080
- Service 구성 [ NodePort ]
taroguru@taroguruui-MacBookAir study % k get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhomework-service NodePort 10.109.155.191 <none> 8080:30880/TCP 145m
apiVersion: v1kind: Servicemetadata:name: homework-servicespec:type: NodePortselector:app: homeworkports:- port: 8080targetPort: 8080nodePort: 30880
- 결과물 UI