[쿠버네티스] 쿠버네티스 시작

gununoo·2022년 9월 1일
12

Kuberbetes

목록 보기
1/10
post-thumbnail
  • Terraform vs Vagarant
    • terraform을 vagrant 보다 많이 쓰는 추세이다.
    • terraform(IaC) + ansible 조합을 많이 쓴다.
  • provision, container, container orchestation
    • provision(IaC): Terraform, Heat(Openstack), CloudFormation(AWS)
    • container: Docker
    • container orchestration: Swarm mode(Docker only), kubernetes
  • Helm(헬름)
    • k8s 환경에서 pod, 서비스, configmap, secret, PV/PVC 등을 하나 하나 설치하는 방법이 아닌 일종의 패키지 형식으로 간단히 설치하는 방법을 제공한다,
    • CentOS에서 패키지를 손쉽게 dnf 또는 yum을 이용하여 배포하는 것과 비슷한 원리이다.
    • yaml파일을 작성해서 배포하는 것보다 훨씬 간단하다.
    • 헬름을 이용한 패키지 설치
  • Legacy Data Center Architecture vs SDDC(VCS)
    • 예전에는 서버와 스위치가 하나에 하나씩 선으로 연결되어 있었다.
    • stp(spanning tree protocol)에서 frame loop 문제가 발생하면 loop가 만들어진 선을 제거하는 방식으로 해결했다.
    • 요즘은 Fabric 방식으로 구성하여, 이러한 문제가 해결되었다.

이미지 출처: https://www.fujitsu.com/sk/Images/ds_brocade_vdx_6940_ap.pdf

Kubernetes Architecture

이미지 출처: https://mohan08p.medium.com/simplified-kubernetes-architecture-3febe12480eb

마스터 노드

  • kubectl
    • 클러스터에 명령을 내림.
  • API 서버
    • 클러스터의 중심 역할을 함.
    • 전체 클러스터를 관리하고 모니터링 함.
    • developer, etcd(key value store), contollers, scheduler, kubelet과 통신함.
    • Kubelet과 표준 인터페이스(CRI)로 통신함.
  • etcd
    • 노드들의 정보와 상태를 확인할 수 있다.
    • 분산 코디네이터 역할을 한다.
  • 컨트롤러 매니저
    • 클러스터의 오브젝트 상태를 관리함.
  • 스케줄러
    • pod를 어떤 워커 노드에 생성할지 결정함.

워커 노드

  • kubelet
    • 컨테이너 런타임에게 pod의 구성 내용 전달함.
    • API 서버와 표준 인터페이스(CRI)로 통신함.
  • 컨테이너 런타임
    • pod를 생성함
  • pod
    • 한 개 이상의 컨테이너의 조합
    • 애플리케이션 배포의 최소 단위
    • 일반적으로는 한 개의 주 컨테이너와 다른 한 개의 보조 컨테이너로 연결된다.
    • 보조 컨테이너는 side-car라고 부르며 주로 주 컨테이너를 모니터링하거나 로그 수집 등에 활용된다.
    • pod 내의 컨테이너는 별도의 노드로 분리되지 않는다.
    • pod는 언제라도 죽을 수 있음 ex) rolling update

기타 구성 요소

  • 네트워크 플러그인
    • 클러스터의 통신을 위한 외부 플러그인.
    • Calico(칼리코), Flannel(플래널), WeaveNet(위브넷) 등을 주로 씀.
    • Calico(칼리코): 포드 간 통신을 위한 오버레이 모듈
  • Network proxy
    • pod는 외부와 직접 통신하지 않는다.
    • pod는 network proxy(kube-proxy)를 통해 외부와 통신한다.
  • CoreDNS
    • 노드 내의 CoreDNS는 각 pod 별로 이름을 부여하고 해당 이름에 대한 IP 정보를 매핑하여 보관한다.
    • pod 간 통신 시 각 pod의 IP 정보를 확인할 필요 없이 이름으로 접속할 수 있게 된다.
  • CRI(Container Runtime Interface)
    • 쿠버네티스에서 만든 컨테이너 런타임 인터페이스
    • 초기 쿠버네티스는 컨테이너를 실행하기 위해 도커를 사용하였는데 이는 쿠버네티스 클러스터 워커 노드의 에이전트인 Kubelet 소스코드 내부에 통합되어 있었음.
    • 이처럼 통합된 프로세스는 상당한 유지보수 오버헤드를 발생시켰음.
    • 이러한 문제를 해결하기 위해 쿠버네티스는 CRI를 만들어 명확하게 정의된 추상화 계층을 제공함으로써 개발자가 컨테이너 런타임 구축에 집중할 수 있게 하였음.

출처: https://www.samsungsds.com/kr/insights/docker.html

Container vs Pod

컨테이너(런타임) --배포--> 1 컨테이너 -> 1 애플리케이션 -> 컨테이너 하나 당 namespace(작업 공간)가 한 개 만들어진다. 따라서 각각 CPU와 RAM을 할당할 수 있다.
Pod(k8s) --> 1개 이상의 컨테이너가 그룹으로 묶인다. 만약 두 개의 컨테이너가 포함된 Pod가 있다면 namespcae(작업 공간)는 1개이며 따라서 하나의 CPU, RAM, NIC(IP)를 두 컨테이너가 공유한다.

GCP에서 Kubernetes Engine 사용하기

GCP 구성

  • 새 프로젝트 생성
  • 프로젝트 이름 입력
  • 프로젝트 선택
  • API 및 서비스 사용 설정
  • kubernetes 검색
  • Kuberbetes Engine API 사용 클릭
  • 페이지 새로고침 하면 사용 설정 완료됨
  • kubernetes > 클러스터 클릭
  • 만들기 클릭
  • standard 선택
  • default-pool > 노드 선택
  • Docker가 설치된 Ubuntu 선택
  • e2-micro 선택
  • 무팅 디스크 크기 20GB로 설정
  • 클러스터 이름 mytestcluster로 설정
  • asia-northeast로 설정
  • 만들기 클릭


  • 쉘 활성화
  • 새 창에서 열기
  • 연결 선택
  • 명령줄 액세스
  • 승인
dlrjsdn0414@cloudshell:~ (rapa-0901-lgw)$ gcloud container clusters get-credentials mytestcluster --zone asia-northeast2-b --project rapa-0901-lgw
Fetching cluster endpoint and auth data.
kubeconfig entry generated for mytestcluster.
  • 노드 확인
dlrjsdn0414@cloudshell:~ (rapa-0901-lgw)$ kubectl get node
NAME                                           STATUS   ROLES    AGE   VERSION
gke-mytestcluster-default-pool-bd53b8ad-39ks   Ready    <none>   44m   v1.22.11-gke.400
gke-mytestcluster-default-pool-bd53b8ad-fk0z   Ready    <none>   44m   v1.22.11-gke.400
gke-mytestcluster-default-pool-bd53b8ad-ml13   Ready    <none>   44m   v1.22.11-gke.400
dlrjsdn0414@cloudshell:~ (rapa-0901-lgw)$ kubectl get node -o wide
NAME                                           STATUS   ROLES    AGE   VERSION            INTERNAL-IP   EXTERNAL-IP     OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
gke-mytestcluster-default-pool-bd53b8ad-39ks   Ready    <none>   44m   v1.22.11-gke.400   10.174.0.3    34.97.148.98    Ubuntu 20.04.4 LTS   5.4.0-1076-gke   docker://19.3.8
gke-mytestcluster-default-pool-bd53b8ad-fk0z   Ready    <none>   44m   v1.22.11-gke.400   10.174.0.2    34.97.134.126   Ubuntu 20.04.4 LTS   5.4.0-1076-gke   docker://19.3.8
gke-mytestcluster-default-pool-bd53b8ad-ml13   Ready    <none>   44m   v1.22.11-gke.400   10.174.0.4    34.97.70.91     Ubuntu 20.04.4 LTS   5.4.0-1076-gke   docker://19.3.8
  • yml 파일 생성
dlrjsdn0414@cloudshell:~ (rapa-0901-lgw)$ mkdir 0901 ; cd 0901
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ touch nginx-pod.yaml
  • 연결이 끊어진 경우
  • gcloud init
  • 계정 선택
  • 프로젝트 선택
  • 리전 및 Zone 선택 여부 선택
  • 클러스터 연결
dlrjsdn0414@cloudshell:~ (rapa-0901-lgw)$ gcloud container clusters get-credentials mytestcluster --zone asia-northeast2-b --project rapa-0901-lgw
Fetching cluster endpoint and auth data.
kubeconfig entry generated for mytestcluster.

Deployment, ReplicaSet, Pod

  • Deployment
    • 롤링 업데이트와 같은 버전 관리를 한다.
  • ReplicaSet
    • 고정된 수의 pod를 유지한다.
    • label 이름과 pod의 개수를 확인한다.
  • Pod
    • label 이름을 가지고 있다.

실습 1 - pod 배포

  • pod 생성 명령어
kubectl run nginx-pod \
--image=nginx 

외부에서 해당 애플리케이션을 즉시 노출시킬 수 없다. 이를 위해서는 별도의 service object를 이용해야 하며 service의 type으로는 clusterIP, nodePort, LoadBalancer(일반적으로 퍼블릭 클라우드에서 활용할 수 있음, on-premise에서는 metallb를 이용하여 환경 구성 가능함)가 있다.

  • 첫 번째 pod 만들기
    포드를 만들기 위해서는 k8s에서 제공하는 다양한 오브젝트 중 pod를 호출해야 한다. 이를 api를 통해 연결하여 생성할 수 있다.
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl api-resources 
# 이름                             단축 명령어                                         공유 여부
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
...
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
...

k8s는 namespace에 속하는 오브젝트와, namespace를 공유하는 오브젝트가 있다.

persistentvolumeclaims -> 특정 namespace에 속한다.
persistentvolumes(영구 볼륨) -> 특정 namespace에 속하지 않고, namespace를 공유한다.

  • Pod 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl api-resources | grep Pod
pods                              po           v1                                     true         Pod
podtemplates                                   v1                                     true         PodTemplate
horizontalpodautoscalers          hpa          autoscaling/v1                         true         HorizontalPodAutoscaler
pods                                           metrics.k8s.io/v1beta1                 true         PodMetrics
poddisruptionbudgets              pdb          policy/v1                              true         PodDisruptionBudget
podsecuritypolicies               psp          policy/v1beta1                         false        PodSecurityPolicy
  • 클러스터에 참여 중인 노드 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get node
NAME                                           STATUS   ROLES    AGE    VERSION
gke-mytestcluster-default-pool-bd53b8ad-39ks   Ready    <none>   144m   v1.22.11-gke.400
gke-mytestcluster-default-pool-bd53b8ad-fk0z   Ready    <none>   144m   v1.22.11-gke.400
gke-mytestcluster-default-pool-bd53b8ad-ml13   Ready    <none>   144m   v1.22.11-gke.400
  • namespace 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get ns
NAME              STATUS   AGE
default           Active   146m
kube-node-lease   Active   146m
kube-public       Active   146m
kube-system       Active   146m
  • default namespace에 속한 pod 보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
No resources found in default namespace.
  • kube-system에 속한 pod 보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod --namespace kube-system
NAME                                                      READY   STATUS    RESTARTS   AGE
event-exporter-gke-5479fd58c8-vjj5d                       2/2     Running   0          146m
fluentbit-gke-kvt88                                       2/2     Running   0          146m
fluentbit-gke-m7lps                                       2/2     Running   0          146m
fluentbit-gke-qnssh                                       2/2     Running   0          146m
gke-metrics-agent-4s9hw                                   1/1     Running   0          146m
gke-metrics-agent-bl4j5                                   1/1     Running   0          146m
gke-metrics-agent-kjspq                                   1/1     Running   0          146m
konnectivity-agent-55846698cd-cgd7c                       1/1     Running   0          146m
konnectivity-agent-55846698cd-h5sww                       1/1     Running   0          144m
konnectivity-agent-55846698cd-q64mr                       1/1     Running   0          144m
konnectivity-agent-autoscaler-555f599d94-5sm9w            1/1     Running   0          146m
kube-dns-85df8994db-54h4c                                 4/4     Running   0          143m
kube-dns-85df8994db-thhmq                                 4/4     Running   0          146m
kube-dns-autoscaler-f4d55555-q5hcr                        1/1     Running   0          146m
kube-proxy-gke-mytestcluster-default-pool-bd53b8ad-39ks   1/1     Running   0          145m
kube-proxy-gke-mytestcluster-default-pool-bd53b8ad-fk0z   1/1     Running   0          145m
kube-proxy-gke-mytestcluster-default-pool-bd53b8ad-ml13   1/1     Running   0          145m
l7-default-backend-69fb9fd9f9-p4hgs                       1/1     Running   0          146m
metrics-server-v0.4.5-fb4c49dd6-qz9zj                     2/2     Running   0          142m
pdcsi-node-ckvng                                          2/2     Running   0          146m
pdcsi-node-srq7x                                          2/2     Running   0          146m
pdcsi-node-sxvll                                          2/2     Running   0          146m

dns는 3개 있음 -> worker node가 사용
kube-proxy는 3개 있음 -> worker node가 사용
metrics-server는 1개 있음 -> master node가 사용

  • yaml 파일 작성
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ vi nginx-pod.yaml
apiVersion: v1
kind:Pod
metadata:
  name: my-nginx-pod
spec:
  containers:
  - name: my-nginx-ctn
    image: nginx:latest
    ports:
    - containerPort: 80
      protocol: TCP 

kind: Pod

  • docker login
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ptah0414
Password:
WARNING! Your password will be stored unencrypted in /home/dlrjsdn0414/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
  • 배포
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f nginx-pod.yaml
pod/my-nginx-pod created

kubectl apply -f nginx-pod.yaml

  • 배포 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME           READY   STATUS              RESTARTS   AGE
my-nginx-pod   0/1     ContainerCreating   0          12s
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP          NODE                                           NOMINATED NODE   READINESS GATES
my-nginx-pod   1/1     Running   0          98s   10.96.1.7   gke-mytestcluster-default-pool-bd53b8ad-39ks   <none>           <none>
  • pod 상세 정보 확인 (describe)
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl describe pod my-nginx-pod
Name:         my-nginx-pod
Namespace:    default
Priority:     0
Node:         gke-mytestcluster-default-pool-bd53b8ad-39ks/10.174.0.3
Start Time:   Thu, 01 Sep 2022 05:15:31 +0000
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.96.1.7
IPs:
  IP:  10.96.1.7
Containers:
  my-nginx-ctn:
    Container ID:   docker://1fe10b5bc2b0aede3e9d4691e363e82aa4497f8bff13f4dd1d3202a017821d7d
    Image:          nginx:latest
    Image ID:       docker-pullable://nginx@sha256:b95a99feebf7797479e0c5eb5ec0bdfa5d9f504bc94da550c2f58e839ea6914f
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Thu, 01 Sep 2022 05:15:48 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-qb5tt (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-qb5tt:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m49s  default-scheduler  Successfully assigned default/my-nginx-pod to gke-mytestcluster-default-pool-bd53b8ad-39ks
  Normal  Pulling    2m47s  kubelet            Pulling image "nginx:latest"
  Normal  Pulled     2m33s  kubelet            Successfully pulled image "nginx:latest" in 13.991675178s
  Normal  Created    2m32s  kubelet            Created container my-nginx-ctn
  Normal  Started    2m32s  kubelet            Started container my-nginx-ctn
  • nginx 컨테이너 접속
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl exec -it \
> my-nginx-pod -- bash
root@my-nginx-pod:/#   
  • nginx에서 localhost 접속
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>

-> nginx가 호스팅된다.

  • centos 컨테이너 추가
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

kind: Pod

  • 재배포
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete -f nginx-pod.yaml
pod "my-nginx-pod" deleted
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f nginx-pod.yaml
pod/my-nginx-pod created
  • 배포 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
my-nginx-pod   2/2     Running   0          66s

-> 컨테이너 2개 실행 중

  • centos 컨테이너 접속
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl exec -it my-nginx-pod \
> -c my-centos-ctn -- bash
[root@my-nginx-pod /]#
  • centos에서 localhost 접속
[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>
[root@my-nginx-pod /]#

centos에서 localhost:80에 접속을 하면 같은 pod 내에 존재하는 nginx 컨테이너(80 포트)에 접속된다. 같은 작업 공간 내에서 NIC 자원을 공유한다.

  • nginx-pod 제거
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete -f nginx-pod.yaml
pod "my-nginx-pod" deleted

실습 2 - ReplicaSet 배포

  • nginx-rs.yaml 작성
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ vi nginx-rs.yaml
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
  • 배포
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f nginx-rs.yaml
replicaset.apps/replicaset-nginx created
  • 배포 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
replicaset-nginx   3         3         1       7s

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
replicaset-nginx-7qhwf   0/1     ContainerCreating   0          10s
replicaset-nginx-bz2fb   0/1     ContainerCreating   0          10s
replicaset-nginx-t2fkc   1/1     Running             0          10s

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod -o wide
NAME                     READY   STATUS              RESTARTS   AGE   IP          NODE                                           NOMINATED NODE   READINESS GATES
replicaset-nginx-7qhwf   0/1     ContainerCreating   0          14s   <none>      gke-mytestcluster-default-pool-bd53b8ad-fk0z   <none>           <none>
replicaset-nginx-bz2fb   0/1     ContainerCreating   0          14s   <none>      gke-mytestcluster-default-pool-bd53b8ad-ml13   <none>           <none>
replicaset-nginx-t2fkc   1/1     Running             0          14s   10.96.1.9   gke-mytestcluster-default-pool-bd53b8ad-39ks   <none>           <none>

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod --show-labels
NAME                     READY   STATUS    RESTARTS   AGE   LABELS
replicaset-nginx-7qhwf   1/1     Running   0          54s   app=my-nginx-pods-label
replicaset-nginx-bz2fb   1/1     Running   0          54s   app=my-nginx-pods-label
replicaset-nginx-t2fkc   1/1     Running   0          54s   app=my-nginx-pods-label
  • 컨테이너 삭제해보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-7qhwf   1/1     Running   0          2m5s
replicaset-nginx-bz2fb   1/1     Running   0          2m5s
replicaset-nginx-t2fkc   1/1     Running   0          2m5s

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete pod replicaset-nginx-7qhwf
pod "replicaset-nginx-7qhwf" deleted
  • pod 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-bz2fb   1/1     Running   0          2m48s
replicaset-nginx-mt74s   1/1     Running   0          21s
replicaset-nginx-t2fkc   1/1     Running   0          2m48s

-> 컨테이너가 재생성되었음

  • 가장 마지막에 생성된 컨테이너 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl edit pod replicaset-nginx-mt74s
  • label 주석처리하기
  • pod 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-4q9k6   1/1     Running   0          5s
replicaset-nginx-bz2fb   1/1     Running   0          5m19s
replicaset-nginx-mt74s   1/1     Running   0          2m52s
replicaset-nginx-t2fkc   1/1     Running   0          5m19s

-> label이 제거되었으므로, 컨테이너가 새로 생성되었음

  • pod 삭제 후 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-4q9k6   1/1     Running   0          5s
replicaset-nginx-bz2fb   1/1     Running   0          5m19s
replicaset-nginx-mt74s   1/1     Running   0          2m52s
replicaset-nginx-t2fkc   1/1     Running   0          5m19s
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete -f nginx-rs.yaml
replicaset.apps "replicaset-nginx" deleted
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-mt74s   1/1     Running   0          3m25s

-> label이 제거된 컨테이너는 지워지지 않았음

  • 제거되지 않은 pod 제거
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete pod replicaset-nginx-mt74s
pod "replicaset-nginx-mt74s" deleted
  • yaml 수정
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ vi nginx-rs.yaml
  • replica 5로 수정
spec:
  replicas: 5
  • 배포 및 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f nginx-rs.yaml
replicaset.apps/replicaset-nginx created

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
replicaset-nginx-596kc   1/1     Running   0          66s
replicaset-nginx-8lsnq   1/1     Running   0          66s
replicaset-nginx-lsqsb   1/1     Running   0          66s
replicaset-nginx-n9tpw   1/1     Running   0          66s
replicaset-nginx-ttqdr   1/1     Running   0          66s
  • pod 제거
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete -f nginx-rs.yaml
replicaset.apps "replicaset-nginx" deleted

실습 3 - Deployment 배포

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ cp nginx-rs.yaml nginx-deploy.yaml
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ vi nginx-deploy.yaml
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
  • 배포
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f nginx-deploy.yaml
deployment.apps/deploy-nginx created
  • 배포 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get deploy,rs,pod
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-nginx   3/3     3            3           76s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-nginx-7f797dbc66   3         3         3       76s

NAME                                READY   STATUS    RESTARTS   AGE
pod/deploy-nginx-7f797dbc66-8pcnr   1/1     Running   0          76s
pod/deploy-nginx-7f797dbc66-b9947   1/1     Running   0          76s
pod/deploy-nginx-7f797dbc66-nbp65   1/1     Running   0          76s
  • 라벨 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get rs --show-labels
NAME                      DESIRED   CURRENT   READY   AGE     LABELS
deploy-nginx-7f797dbc66   3         3         3       2m37s   app=my-nginx-pods-label,pod-template-hash=7f797dbc66

-> my-nginx-pods-label라고 label을 지정했었음
-> label 뒷 부분의 pod-template-hash=7f797dbc66은 replicaset의 id임

  • rollout history 보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl rollout history deploy deploy-nginx
deployment.apps/deploy-nginx
REVISION  CHANGE-CAUSE
1         <none>

-> 최초 배포인 1번 상태임

  • deploy-nginx pod의 nginx 컨테이너의 image를 httpd로 변경할 것임
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl set image \
> deploy deploy-nginx \ # deploy의 이름: deploy-nginx 
> nginx=httpd:latest # [컨테이너 이름]=[이미지 이름]
deployment.apps/deploy-nginx image updated
  • 배포 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
deploy-nginx-586b998bb6-c6s6f   1/1     Running   0          70s
deploy-nginx-586b998bb6-fdm9x   1/1     Running   0          64s
deploy-nginx-586b998bb6-sw9vr   1/1     Running   0          78s
  • pod 접속
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl exec -it \
> deploy-nginx-586b998bb6-c6s6f -- bash
root@deploy-nginx-586b998bb6-c6s6f:/usr/local/apache2#
root@deploy-nginx-586b998bb6-c6s6f:/usr/local/apache2# cat htdocs/index.html
<html><body><h1>It works!</h1></body></html>

-> 컨테이너가 apache2 이미지로 변경되었음

  • rollout history 보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl rollout history deploy deploy-nginx
deployment.apps/deploy-nginx
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

-> 2번으로 변경되었음

  • 최초 배포(1)로 rollback하기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl rollout undo deploy deploy-nginx \
> --to-revision=1
deployment.apps/deploy-nginx rolled back
  • replicaset 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get rs --show-labels
NAME                      DESIRED   CURRENT   READY   AGE     LABELS
deploy-nginx-586b998bb6   0         0         0       6m59s   app=my-nginx-pods-label,pod-template-hash=586b998bb6
deploy-nginx-7f797dbc66   3         3         3       13m     app=my-nginx-pods-label,pod-template-hash=7f797dbc66

-> 최초 배포(1)로 rollback 되었음
-> deploy를 이용하면 하위에 있는 replicaset이 생성된다. 우리는 두 replicaset의 정보를 확인해서 둘 다 동일한 라벨이 있다는 것을 확인할 수 있다. 만약 rs에서 개수를 6개로 늘린다면(최초 배포는 3개) 신규 이미지를 활용한 pod만 6개로 3개가 추가 된다.
deployment는 이미지의 버전 관리가 가능하여 기존 버전에서 생성된 pod들과 신규 이미지에서 생성된 pod를 구분하기 위하여 추가적인 label을 자동 생성한 뒤, 이를 pod에 붙여준다. 이를 통해 기존 pod와 신규 pod를 구분할 수 있다.

deployment는 버전 관리를 위해 라벨을 자동으로 추가 부착한다.

  • pod 접속
NAME                                READY   STATUS    RESTARTS   AGE
pod/deploy-nginx-7f797dbc66-66nbr   1/1     Running   0          11m
pod/deploy-nginx-7f797dbc66-69d85   1/1     Running   0          11m
pod/deploy-nginx-7f797dbc66-x7z9j   1/1     Running   0          11m

dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl exec -it \
> pod/deploy-nginx-7f797dbc66-66nbr -- bash
  • localhost 접속
root@deploy-nginx-7f797dbc66-66nbr:/# curl 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>
root@deploy-nginx-7f797dbc66-66nbr:/#

-> nginx로 rollback 되었음


실습 4 - LoadBalancer Service 배포

  • 기존 deploy 삭제
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete -f nginx-deploy.yaml
deployment.apps "deploy-nginx" deleted
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get deploy,pod
No resources found in default namespace.
  • yaml 편집
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ touch service.yaml
apiVersion: v1 
kind: Service
metadata:
  name: my-nginx-lb 
spec:
  type: LoadBalancer
  ports:
    - port: 80 # LB의 포트 
      targetPort: 80 # pod의 포트 
      protocol: TCP
  selector:
    app: my-nginx-pods-label 

kind: Service

  • 서비스 배포 (loadbalancer)
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f service.yaml
service/my-nginx-lb created
  • 서비스 배포 확인
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get svc
NAME          TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes    ClusterIP      10.100.0.1     <none>        443/TCP        5h44m
my-nginx-lb   LoadBalancer   10.100.5.213   <pending>     80:30479/TCP   48s
  • 잠시 기다리면 IP 주소가 있음
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl get svc
NAME          TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
kubernetes    ClusterIP      10.100.0.1     <none>         443/TCP        5h44m
my-nginx-lb   LoadBalancer   10.100.5.213   34.97.133.36   80:30479/TCP   59s
  • deploy 배포 (nginx)
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl apply -f nginx-deploy.yaml
deployment.apps/deploy-nginx created
  • 이미지 httpd로 변경해보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl set image deploy deploy-nginx nginx=httpd:latest
deployment.apps/deploy-nginx image updated

-> httpd로 이미지가 변경되었음

  • rollback 해보기
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl rollout undo \
> deploy deploy-nginx \
> --to-revision=1
deployment.apps/deploy-nginx rolled back
  • loadbalancer 접속

-> nginx로 rollback 되었음


  • 서비스, deploy, pod 모두 제거
dlrjsdn0414@cloudshell:~/0901 (rapa-0901-lgw)$ kubectl delete deploy,pod,svc --all
deployment.apps "deploy-nginx" deleted
pod "deploy-nginx-7f797dbc66-2ggwr" deleted
pod "deploy-nginx-7f797dbc66-w876n" deleted
pod "deploy-nginx-7f797dbc66-xpbjm" deleted
service "kubernetes" deleted
service "my-nginx-lb" deleted

object의 서비스: pod를 외부로 노출시키고 외부에서 연결이 가능하도록 하기 위한 오브젝트로써 다음과 같은 3가지를 이용한다.
1. cluster ip: 노드(가상머신) 밖으로 노출은 안 된다.
2. node port: 서비스의 특정 포트와 pod를 연결하여 외부로부터 연결 가능
3. load balancer: 로드밸런서를 이용하여 pod와 연결(L4)

L7 LoadBalancer와 같은 기능은 ingress 오브젝트에서 제공된다.

이미지 출처: https://subicura.com/k8s/guide/ingress.html#ingress-%E1%84%86%E1%85%A1%E1%86%AB%E1%84%83%E1%85%B3%E1%86%AF%E1%84%80%E1%85%B5


  • manifest file
    쿠버네티스에서는 모든 오브젝트(Pod, Replicaset, Deployment, service, configmap/secret, ingress, pv, pvc... )는 yml 파일 형태로 작성하여 배포가 가능하다. 이를 manifest file이라 부른다. 물론 명령을 통해서도 배포는 가능하다. 하지만 재사용 등을 고려했을 때 파일 작성을 추천한다.
    • create는 명령형 또는 파일을 불려와서 배포하는 방식으로도 가능하다.
    • apply는 파일을 이용한 배포에 활용된다.
profile
take a look

0개의 댓글