[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: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
SPECIAL_LEVEL: very
SPECIAL_TYPE: charm
---
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh","-c","cat /etc/config/keys" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
# SPECIAL_LEVEL이라는 컨피그맵의 값이 /etc/config/keys파일에 적힌다.
volumes:
- name: config-volume
configMap:
name: special-config
items:
- key: SPECIAL_LEVEL
path: keys # 파일명이 keys
restartPolicy: Never

emptyDir

pod에서 임시 디렉토리를 생성하여 파드를 생성한다.

퍼시스턴트 볼륨과 퍼시스턴트 볼륨 클레임

퍼시스턴트 볼륨 : 프로비저닝한 클러스터의 스토리지 퍼시스턴트 볼륨 클레임 : 스토리지에 대한 요청

셀렉터

클래스

스토리지클래스네임 ??뭐지?

pvc는 반드시 클래스를 요청할 필요는 없다.

바인딩 할 수 있다.

맥에서 pvc오류

맥에서 storageclassname을 manual로 등록할 경우 정상 동작하지 않는다. 이를 해결하기 위하여

  1. storageclassname을 hostpath를 사용
  2. 별도의 storageclassname을 yaml로 생성한 후 사용 하여야 한다.

https://julien-chen.medium.com/k8s-how-to-mount-local-directory-persistent-volume-to-kubernetes-pods-of-docker-desktop-for-mac-b72f3ca6b0dd

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: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: localhost:52500/snownginx:01

아래와 같은 정보를 던져준다.

% k describe pod myapp-pod
Name: myapp-pod
Namespace: default
...
Containers:
nginx-container:
Container ID: docker://7c88c7f6f5fcae8a6b571c877f2f8c2d1b0a5b1fbf6cb507224f244007ad56bd
Image: localhost:52500/snownginx:01
Image ID: docker-pullable://localhost:52500/snownginx@sha256:6b83def3f1adba23a370dd8a386798536e6db6a541eb418fbb2b232e237ee38c
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 9m9s default-scheduler Successfully assigned default/myapp-pod to docker-desktop
Normal Pulled 9m8s kubelet Container image "localhost:52500/snownginx:01" already present on machine
Normal Created 9m8s kubelet Created container nginx-container
Normal 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 yaml
apiVersion: v1
items:
- apiVersion: v1
kind: ResourceQuota
metadata:
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-demo
namespace: default
resourceVersion: "511240"
uid: f901588c-78f6-40f2-a21b-796a79c52466
spec:
hard:
limits.cpu: "2"
limits.memory: 2Gi
requests.cpu: "1"
requests.memory: 1Gi
status:
hard:
limits.cpu: "2"
limits.memory: 2Gi
requests.cpu: "1"
requests.memory: 1Gi
used:
limits.cpu: 500m
limits.memory: 128Mi
requests.cpu: 250m
requests.memory: 64Mi
kind: List
metadata:
resourceVersion: ""

태스크

파드와 컨테이너 설정

label

노드별로 별도의 레이블을 설정할 수 있다.

대규모 설계에 대한 제안

적당한 사이징에 대한 제안. 노드당 파드 수 등

실습

서버 웹사이트를 쿠버네티스 기반 인프라로 마이그레이션

kubectl config set-context --current --namespace=<namespacename>

과제 내용은 다음과 같다.

  1. Docker Build [ image명 교육생 영문 이니셜 ] -> taroguru/kjh:latest

  2. Docker images docker.hub 등록 -> https://hub.docker.com/repository/docker/taroguru/kjh/general

  3. kubenertes deployment Application 등록

taroguru@taroguruui-MacBookAir ~ % k get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
homework-deployment 1/1 1 1 10m
apiVersion: apps/v1
kind: Deployment
metadata:
name: homework-deployment
labels:
app: homework
spec:
replicas: 1
selector:
matchLabels:
app: homework
template:
metadata:
labels:
app: homework
spec:
containers:
- name: tomcat-board
image: taroguru/kjh:latest
ports:
- containerPort: 8080
  1. Service 구성 [ NodePort ]
taroguru@taroguruui-MacBookAir study % k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
homework-service NodePort 10.109.155.191 <none> 8080:30880/TCP 145m
apiVersion: v1
kind: Service
metadata:
name: homework-service
spec:
type: NodePort
selector:
app: homework
ports:
- port: 8080
targetPort: 8080
nodePort: 30880
  1. 결과물 UI