- 쿠버네티스는 서비스이다
- pod를 생성하고 pod 안에 컨테이너가 들어간다.
- pod는 쿠버네티스에서 가장 작은 단위이며 여러개의 컨테이너를 가질수 있다. (pod - 1개 이상의 컨테이너으 집합)
- service라는 오브젝트를 생성해야한다.
cluster-ip node port Load Balance
완전 관리형 서비스
- EKS, AKS, GKE
- 프로비저닝 하는데 관여할 필요가 없다.
- k8s 환경에서 pod, service, 컨피그맵, 시크릿,PV/PVC 등을 하나하나 설치하는 방법이 아닌 일종의 패키지 형식으로 간단히 설치하는 방법을 제공한다
- 마치 centos에서 패키지를 쉽게 dnf 혹은 yum을 이용하여 배포하는 것과 비슷한 원리이다.
swarm mode -> manager(manager), worker1 ~ worker3(worker) k8s -> master,worker1~3(node라고도 부름)
- 프로젝트 생성
- api 및 서비스 사용 설정
- 쿠버네티스 엔진 사용
- 클러스터 생성하기
- 이미지는 Docker가 설치된 Ubuntu 사용
- 머신 유형은 가장 작은 유형으로 사용 및 디스트 20GB
- 클러스터 이름 설정 및 리전은 사용이 가장 적은 일본으로 설정
- gke는 기본 버전 사용
- 클러스터 생성
- cloud shall 활성화
- 클러스터 활성화 하기
- 사용 노드 확인
kubectl get nodes
- 사용 노드 상세 확인 (클러스트에 참여중인 노드)
kubectl get nodes -o wide
- pod 배포 yml 파일 작성
touch nginx-pod.yml
cat nginx-pod.yml apiVersion: v1 kind: Pod metadata: name: my-nginx-pod spec: containers: - name: my-nginx-ctn image: nginx:latest ports: - containerPort: 80 protocol: TCP
- 도커 허브 로그인
docker login
- pod 생성
kubectl apply -f nginx-pod.yml
- 생성 확인
kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-pod 1/1 Running 0 34s
- pod 정보 확인
kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-pod 1/1 Running 0 102s 10.48.1.4 gke-mytestcluster-default-pool-7dfd7e7a-23mb <none> <none>
- 상세 정보 확인
kubectl describe pod (파드 명)
- 쉘로 연결하기
kubectl exec -it my-nginx-pod -- bash
- 1개의 파드에 컨테이너 두개 배포
cat nginx-pod.yml apiVersion: v1 kind: Pod metadata: name: my-nginx-pod spec: containers: - name: my-nginx-ctn image: nginx:latest ports: - containerPort: 80 protocol: TCP - name: my-centos-ctn image: centos command: ["tail"] #ENTRYPOINT args: ["-f", "/dev/null"] #CMD
- pod 확인
kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-pod 2/2 Running 0 36s
- nginx 쉘 접속하기
kubectl exec -it my-nginx-pod -c my-centos-ctn -- bash [root@my-nginx-pod /]#
- localhost curl 해보기 -> nginx로 접속이 된다.
[root@my-nginx-pod /]# curl http://localhost <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
레플리카셋 사용하기
- 레플리카셋 yml 파일 작석
cat nginx-rs.yml apiVersion: apps/v1 kind: ReplicaSet metadata: name: replicaset-nginx spec: replicas: 3 selector: matchLabels: app: my-nginx-pods-label template: metadata: name: my-nginx-pod labels: app: my-nginx-pods-label spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
- 컨테이너 배포
kubectl apply -f nginx-rs.yml
- 파일 확인
kubectl get rs NAME DESIRED CURRENT READY AGE replicaset-nginx 3 3 1 10s
kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS my-nginx-pod 2/2 Running 0 61m <none> replicaset-nginx-4pt4c 1/1 Running 0 2m5s app=my-nginx-pods-label replicaset-nginx-bxfxc 1/1 Running 0 2m5s app=my-nginx-pods-label replicaset-nginx-l88sp 1/1 Running 0 2m5s app=my-nginx-pods-label
- 삭제하기
kubectl delete -f nginx-rs.yml
kubetcl delete pod my-nginx-pod
deployment를 이용하여 포드 배포하기
cat nginx-dm.yml apiVersion: apps/v1 kind: Deployment metadata: name: deploy-nginx spec: replicas: 3 selector: matchLabels: app: my-nginx-pods-label template: metadata: name: my-nginx-pod labels: app: my-nginx-pods-label spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
kubectl apply -f nginx-dm.yml
- nginx 이미지를 httpd 최신 버전으로 변경
kubectl set image deploy deploy-nginx nginx=httpd:latest
- 업데이트 확인
kubectl exec -it deploy-nginx-586b998bb6-h6nsz -- bash root@deploy-nginx-586b998bb6-h6nsz:/usr/local/apache2#
- 업데이트 확인 목록
kubectl rollout history deploy deploy-nginx deployment.apps/deploy-nginx deployment.apps/deploy-nginx REVISION CHANGE-CAUSE 1 <none> -> 최초배포(nginx) 2 <none> -> 이미지 업데이트
- 롤백하기
kubectl rollout undo deploy deploy-nginx --to-revision=1 deployment.apps/deploy-nginx rolled back
- deploy를 이용하면 하위에 있는 replicaset이 생성된다.
- 우리는 두 레플리카셋의 정보를 확인해서 둘다 동일한 라벨이 있다는 것을 확인할 수 있다.
- 만약 rs에서 개수를 늘린다면(최초배포3) 6개로 늘린다면 신규 이미지를 활용한 포드만 6개로 3개가 추가된다.
결론
- deployment 는 이미지의 버전관리가 가능하여 기존버전에서 생성된 포드들과 신규이미지에서 생성된 포드를 구분하기 위하여 추가적인 라벨을 자동생성한 뒤, 이를 포드에붙여준다. 이를 통해 기존포드와 신규포드를 구분할 수 있다.
버전 관리
- 버전 관리를 위해서는 파일 수정은 하지 말것
- 아래 방법과 같이 새로운 이미지를 지정하여 deploy를 업데이트 시킨다.
kubectl set image deploy deploy-nginx nginx=httpd:latest kubectl rollout undo deploy my-nginx-deployment --to-revison=1 <-- 최초상태로 복귀
LB 구성
cat service.yaml apiVersion: v1 kind: Service metadata: name: my-nginx-lb spec: type: LoadBalancer ports: - port: 80 targetPort: 80 protocol: TCP selector: app: my-nginx-pods-label
- 컨테이너 배포
kubectl apply -f nginx-dm.yml deployment.apps/deploy-nginx created
- 이미지 변경
kubectl set image deploy deploy-nginx nginx=httpd:latest
모두 삭제
kubectl delete deploy,pod,svc --all
- 재 로그인
gcloud init
- 컨테이너 배포
kubectl run nginx-pod --image=nginx
외부에서 해당 애플리케이션을 즉시 노출 시킬수 없다. 이를 위해서는 별도의 service objerct를 이용해야 하며 service의 type으로는 clusterip, nodePort, LoadBalancer(일반적으로 퍼블릭 클라우드에서 활용할 수 있음, on-premise에서는 MetalLB를 이용하여 환경 구성 가능하다)
pod 만들기
- 포트를 만들기 위해서는 k8s에서 제공하는 다양한 오브젝트 중 pod를 호출해야 한다.
- 이를 api를 통해 연결하여 생성할 수 있다.
리소스 정보 확인, 각 오브젝트에 대한 정보 확인 가능
kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 true Binding
- k8s는 네임스페이스에 속하는 오브젝트와 공유되는 오브젝트가 있다.
persistentvolumeclaims pvc v1 true PersistentVolumeClaim persistentvolumes pv v1 false PersistentVolume (영구볼륨)
오브젝트에서 말하는 서비스
- object에서 말하는 서비스는 웹서비스 이런 것이 아니라 포드를 외부로 노출시키고 외부에서 연결이 가능하도록 하기 위한 오브젝트로써 다음과 같은 3가지를 이용한다.
1. cluster ip -> 노드(가상머신) 밖으로 노출은 안된다 2. node poet -> 서비스의 특정 포트와 포드를 연결하여 외부로 부터 연결 가능 3. load balancer -> 로드밸런서를 이용하여 포트와 연결(L4)
- L7 LB와 같은 기능은 ingress 오브젝트에서 제곻된다
- 큐브렛은 명령을 런타임에게 전달하고 런타임은 파드를 생성한다. pod는 직접 외부로 나갈수 없기 때문에 외부 통신을 하기 위해서 network proxy를 이용한다. 이때 network proxy가 대신 나가 외부와 통신한다.
- 큐브렛이 런타임에게 전달해 컨테이너가 생성되면 큐브렛은 API에게 결과ㅏ
를 전달한다.kubectl
- 쿠버네티스 클러스터에 명령을 내리는 역할
- 다른 구성 요소들과 다르게 바로 실행되는 명령 형태인 바이너리로 배포되어 마스터 노드에 있을 필요는 없지만 API와 주로 통신한다.
API 서버
- 쿠버네티스 클러스의 중심 역할을 하는 통로
- 주로 상태 값을 저장하는 etcd와 통신
- API 서버를 중심에 두고 통신하므로 API 서버의 역할이 매우 중요하다.
etcd
- 구성 요소들의 상태 값이 모두 저장되는 곳
- 관리자가 모든 보고 내용을 기록하는 노트와 같은 곳
- etcd 정보가 백업되어 있다면 장애 상황에서도 클러스터 복구 가능
컨트롤 매니저
- 쿠버네티스 클러스터의 오브젝트 상태를 관리
- 상태체크와 복구는 컨트롤러 매니저에 속한 노드 컨트롤러에서 이루어진다.
- 리플리카셋 컨트롤러, 엔드포인트 컨트롤러
스케줄러
- 노드의 상태와 자원, 레이블, 요구 조건 등을 고려해 파드를 어떤 워커 노드에 생성할 것인지를 결정하고 할당한다.
- 파드를 조건에 맞는 워커 노드에 지정하고, 파드가 워커 노드에 할당되는 일정을 관리하는 역할을 담당한다.
워커 노드
kubelet
- 파드의 구성 내용을 받아서 컨테이너 런타임으로 전달하고 파드안의 컨테이너들이 정상적으로 작동하는지 모니터링한다.
컨테이너 런타임
- 파드를 이루는 컨테이너의 실행을 담당한다.
- 파드 안에서 다양한 종류의 컨테이너가 문제 없이 작동하게 하는 표준 인터페이스이다.
pod(파드)
- 한개 이상의 컨테이너의 조합
- 애플리케이션 배포의 최소 단위
- 일반적으로는 한개의 주 컨테이너와 다른 한개의 보조 컨테이너로 연결된다.
- 보조 컨테이너는 side-car이라고 부르며 주로 주 컨테이너를 모니터링하거나 로그 수집등에 활용된다
- 포드 내의 컨테이너는 별도의 노드로 분리되지 않는다.
CoreDNS
- 노드 내에 있는 CoreDNS는 각 포트별로 이름을 부여하고 해당 이름에 대한 IP 정보를 매핑하여 보관한다.
- 따라서 포드간 통신시 각 포드의 IP정보를 확인할 필요없이 도메인 이름으로 접속할 수 있게 된다.
네트워크 플러그인
- 쿠버네티스 클러스터의 통신을 위해서 네트워크 플러그인을 선택하고 구성해야 한다.
- 네트워크 플러그인은 일반적으로 CNI로 구성한다.
- k8s에서는 모든 오브젝트(Pod, Replicaset, Deployment, service, configmap/secret, ingress,pv,pvc..)는 yml 파일 형태로 작성하여 배포가 가능하다. 이를 "매니페스트 파일"이라 부른다. 물론 명령을 통해서도 배포는 가능하다. 하지만 재사용 등을 고려했을때 파일 작성을 추천한다.
명령어
create
- 명령형으로 또는 파일을 불러와서 배포하는 형으로도 가능하다.
apply
- 파일을 이용한 배포에 활용된다.
- 도커와 k8s의 차이라는 질문은
docker swarm과 k8s의 차이이인지
컨테이너와 파드의 차이인지를 명확히 이해해야한다.
container (런타임) --> 컨테이너 -> | 애플리케이션
pod (k8s) --> 1개 이상의 컨테이너가 그룹으로 묶인다.