쿠버네티스(k8s)에 대하여 - 9.1 (helm, GKE)

양승현·2022년 9월 2일
0

kubernetes

목록 보기
4/18

k8s

  • 쿠버네티스는 서비스이다
  • 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라고도 부름)

GKE 실습하기

  • 프로젝트 생성
  • 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

  • 재 로그인
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의 차이는?

  • 도커와 k8s의 차이라는 질문은
    docker swarm과 k8s의 차이이인지
    컨테이너와 파드의 차이인지를 명확히 이해해야한다.
    container (런타임) --> 컨테이너 -> | 애플리케이션
    pod (k8s) --> 1개 이상의 컨테이너가 그룹으로 묶인다.

0개의 댓글