쿠버네티스 기본 개념에 대해 알아보려고 한다.

 

Pod

쿠버네티스 노드는 여러 Pod로 구성될 수 있고, 각 Pod는 여러 Container를 가질 수 있다.

@cloudshell:~ (proud-curve)$ kubectl explain pods
KIND:       Pod
VERSION:    v1

DESCRIPTION:
    Pod is a collection of containers that can run on a host. This resource is
    created by clients and scheduled onto hosts.
    
FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <PodSpec>
    Specification of the desired behavior of the pod. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

  status        <PodStatus>
    Most recently observed status of the pod. This data may not be up to date.
    Populated by the system. Read-only. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

 

한 Pod에 있는 컨테이너들은 리소스를 공유하고 같은 Pod에 있는 컨테이너들은 내부 IP를 통해 통신한다.

 

1. get pods를 통해 pod 리스트를 확인할 수 있다.

@cloudshell:~ (proud-curve)$ kubectl get pods
NAME                                  READY   STATUS    RESTARTS   AGE
hello-world-rest-api-8c7449fd-f7lh2   1/1     Running   0          16h
@cloudshell:~ (proud-curve)$ kubectl get pods -o wide
NAME                                  READY   STATUS    RESTARTS   AGE   IP          NODE                                                 NOMINATED NODE   READINESS GATES
hello-world-rest-api-8c7449fd-f7lh2   1/1     Running   0          16h   10.44.1.5   gke-in28minutes-cluster-default-pool-24f9f7fb-xq70   <none>           <none>

 

 

2. 특정 pod에 대해 상세 조회를 하려면 1번 단계에서 확인한 pod name을 이용해서 kubectl describe pod를 하면 된다.

@cloudshell:~ (proud-curve)$ kubectl describe pod hello-world-rest-api-8c7449fd-f7lh2
Name:             hello-world-rest-api-8c7449fd-f7lh2
Namespace:        default
Priority:         0
Service Account:  default
Node:             gke-in28minutes-cluster-default-pool-24f9f7fb-xq70/10.128.0.7
Start Time:       Sun, 16 Feb 2025 03:44:56 +0000
Labels:           app=hello-world-rest-api
                  pod-template-hash=8c7449fd
Annotations:      cloud.google.com/cluster_autoscaler_unhelpable_since: 2025-02-15T13:37:43+0000
                  cloud.google.com/cluster_autoscaler_unhelpable_until: Inf
Status:           Running
IP:               10.44.1.5
IPs:
  IP:           10.44.1.5
Controlled By:  ReplicaSet/hello-world-rest-api-8c7449fd
Containers:
  hello-world-rest-api:
    Container ID:   containerd://a5f84557e8c2e25fe5ba0e04bcabac8f9b77cbfbb491b98846169c71687f5c1e
    Image:          in28min/hello-world-rest-api:0.0.1.RELEASE
    Image ID:       docker.io/in28min/hello-world-rest-api@sha256:00469c343814aabe56ad1034427f546d43bafaaa11208a1eb0720993743f72be
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 16 Feb 2025 03:45:15 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-d2tdw (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-d2tdw:
    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:                      <none>

 

여기에서 Labels에 있는 이름이 중요하다. 나중에 리플리카셋이나 서비스 등으로 Pod을 묶을 때 쓰일 수 있다. 그리고 Annotation은 Pod에 대한 메타 정보이다.

 

 

 

Replicaset

리플리카셋은 Pod를 모니터링 하고 있다가 필요한 Pod 수보다 줄어들게 되면 다시 Pod를 생성한다. 특정 수 이상의 Pod이 실행되도록 만들어준다.

@cloudshell:~ (proud-curve)$ kubectl explain replicaset
GROUP:      apps
KIND:       ReplicaSet
VERSION:    v1

DESCRIPTION:
    ReplicaSet ensures that a specified number of pod replicas are running at
    any given time.
    
FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>
    If the Labels of a ReplicaSet are empty, they are defaulted to be the same
    as the Pod(s) that the ReplicaSet manages. Standard object's metadata. More
    info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <ReplicaSetSpec>
    Spec defines the specification of the desired behavior of the ReplicaSet.
    More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

  status        <ReplicaSetStatus>
    Status is the most recently observed status of the ReplicaSet. This data may
    be out of date by some window of time. Populated by the system. Read-only.
    More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

 

 

1. 리플리카셋 리스트를 여러 명령어로 조회할 수 있다.

@cloudshell:~ (proud-curve)$ kubectl get replicasets
NAME                            DESIRED   CURRENT   READY   AGE
hello-world-rest-api-8c7449fd   1         1         1       17h
@cloudshell:~ (proud-curve)$ kubectl get replicaset
NAME                            DESIRED   CURRENT   READY   AGE
hello-world-rest-api-8c7449fd   1         1         1       17h
@cloudshell:~ (proud-curve)$ kubectl get rs
NAME                            DESIRED   CURRENT   READY   AGE
hello-world-rest-api-8c7449fd   1         1         1       17h

 

 

2. Pod을 삭제하면 다른 이름으로 자동으로 Pod이 생성되는 것을 확인할 수 있는데, 이 역할을 하는 것이 Replicaset이라고 할 수 있다.

@cloudshell:~ (proud-curve)$ kubectl get pods
NAME                                  READY   STATUS    RESTARTS   AGE
hello-world-rest-api-8c7449fd-f7lh2   1/1     Running   0          17h
@cloudshell:~ (proud-curve)$ kubectl delete pod hello-world-rest-api-8c7449fd-f7lh2
pod "hello-world-rest-api-8c7449fd-f7lh2" deleted
@cloudshell:~ (proud-curve)$ kubectl get pods
NAME                                  READY   STATUS    RESTARTS   AGE
hello-world-rest-api-8c7449fd-bw2hn   1/1     Running   0          5s

 

 

3. pod을 3개로 늘려보자. 인스턴스가 3개로 늘어났다고 볼 수 있다.

@cloudshell:~ (proud-curve)$ kubectl scale deployment hello-world-rest-api --replicas=3
deployment.apps/hello-world-rest-api scaled
@cloudshell:~ (proud-curve)$ kubectl get pods
NAME                                  READY   STATUS              RESTARTS   AGE
hello-world-rest-api-8c7449fd-bw2hn   1/1     Running             0          5m47s
hello-world-rest-api-8c7449fd-fzg7d   0/1     ContainerCreating   0          4s
hello-world-rest-api-8c7449fd-mgg96   0/1     ContainerCreating   0          4s
@cloudshell:~ (proud-curve-451012-r7)$ kubectl get rs
NAME                            DESIRED   CURRENT   READY   AGE
hello-world-rest-api-8c7449fd   3         3         3       17h

 

 

4. Pod이 3개로 늘어나고 나서 hello-world 서비스를 브라우저로 접근하면 Pod가 돌아가면서 동작하여 서비스가 됨을 알 수 있다.

 

 

5. kubectl scale deployment를 통해 내부적으로 어떤 동작이 있었는지 보기 위해 event를 확인해보면 pod 2개가 추가로 생성된 것을 확인할 수 있다.

@cloudshell:~ (proud-curve)$ kubectl get events --sort-by=.metadata.creationTimestamp
LAST SEEN   TYPE     REASON              OBJECT                                     MESSAGE
17m         Normal   Scheduled           pod/hello-world-rest-api-8c7449fd-bw2hn    Successfully assigned default/hello-world-rest-api-8c7449fd-bw2hn to gke-in28minutes-cluster-default-pool-24f9f7fb-xq70
17m         Normal   Killing             pod/hello-world-rest-api-8c7449fd-f7lh2    Stopping container hello-world-rest-api
17m         Normal   SuccessfulCreate    replicaset/hello-world-rest-api-8c7449fd   Created pod: hello-world-rest-api-8c7449fd-bw2hn
17m         Normal   Pulled              pod/hello-world-rest-api-8c7449fd-bw2hn    Container image "in28min/hello-world-rest-api:0.0.1.RELEASE" already present on machine
17m         Normal   Created             pod/hello-world-rest-api-8c7449fd-bw2hn    Created container hello-world-rest-api
17m         Normal   Started             pod/hello-world-rest-api-8c7449fd-bw2hn    Started container hello-world-rest-api
12m         Normal   SuccessfulCreate    replicaset/hello-world-rest-api-8c7449fd   Created pod: hello-world-rest-api-8c7449fd-fzg7d
12m         Normal   ScalingReplicaSet   deployment/hello-world-rest-api            Scaled up replica set hello-world-rest-api-8c7449fd to 3 from 1
12m         Normal   Scheduled           pod/hello-world-rest-api-8c7449fd-fzg7d    Successfully assigned default/hello-world-rest-api-8c7449fd-fzg7d to gke-in28minutes-cluster-default-pool-24f9f7fb-vzdc
12m         Normal   Scheduled           pod/hello-world-rest-api-8c7449fd-mgg96    Successfully assigned default/hello-world-rest-api-8c7449fd-mgg96 to gke-in28minutes-cluster-default-pool-24f9f7fb-6q96
12m         Normal   SuccessfulCreate    replicaset/hello-world-rest-api-8c7449fd   Created pod: hello-world-rest-api-8c7449fd-mgg96
12m         Normal   Pulling             pod/hello-world-rest-api-8c7449fd-fzg7d    Pulling image "in28min/hello-world-rest-api:0.0.1.RELEASE"
12m         Normal   Pulling             pod/hello-world-rest-api-8c7449fd-mgg96    Pulling image "in28min/hello-world-rest-api:0.0.1.RELEASE"
12m         Normal   Created             pod/hello-world-rest-api-8c7449fd-fzg7d    Created container hello-world-rest-api
12m         Normal   Started             pod/hello-world-rest-api-8c7449fd-mgg96    Started container hello-world-rest-api
12m         Normal   Created             pod/hello-world-rest-api-8c7449fd-mgg96    Created container hello-world-rest-api
12m         Normal   Pulled              pod/hello-world-rest-api-8c7449fd-mgg96    Successfully pulled image "in28min/hello-world-rest-api:0.0.1.RELEASE" in 3.116s (3.116s including waiting). Image size: 88504325 bytes.
12m         Normal   Started             pod/hello-world-rest-api-8c7449fd-fzg7d    Started container hello-world-rest-api
12m         Normal   Pulled              pod/hello-world-rest-api-8c7449fd-fzg7d    Successfully pulled image "in28min/hello-world-rest-api:0.0.1.RELEASE" in 3.163s (3.163s including waiting). Image size: 88504325 bytes.

 

 

Deployment

다운타임 없이 새로운 버전을 배포할 수 있도록 Pod와 Replicaset의 배포를 관리한다.

@cloudshell:~ (proud-curve)$ kubectl explain deployment
GROUP:      apps
KIND:       Deployment
VERSION:    v1

DESCRIPTION:
    Deployment enables declarative updates for Pods and ReplicaSets.
    
FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <DeploymentSpec>
    Specification of the desired behavior of the Deployment.

  status        <DeploymentStatus>
    Most recently observed status of the Deployment.

 

 

1. 애플리케이션 도커 이미지를 변경한다.

@cloudshell:~ (proud-curve)$ kubectl get rs -o wide
NAME                            DESIRED   CURRENT   READY   AGE   CONTAINERS             IMAGES                                       SELECTOR
hello-world-rest-api-8c7449fd   3         3         3       17h   hello-world-rest-api   in28min/hello-world-rest-api:0.0.1.RELEASE   app=hello-world-rest-api,pod-template-hash=8c7449fd
@cloudshell:~ (proud-curve)$ kubectl set image deployment hello-world-rest-api hello-world-rest-api=in28min/hello-world-rest-api:0.0.2.RELEASE
deployment.apps/hello-world-rest-api image updated

 

 

2. 이미지 변경을 하게 되면 애플리케이션 버전2로 deployment 된 것인데, 이 과정에서 replicaset은 새로운 이름으로 생성이 되고 pod도 새 버전의 애플리케이션을 위한 pod이 구성된다.

@cloudshell:~ (proud-curve)$ kubectl get rs -o wide
NAME                             DESIRED   CURRENT   READY   AGE   CONTAINERS             IMAGES                                       SELECTOR
hello-world-rest-api-89b8d4c97   3         3         3       25s   hello-world-rest-api   in28min/hello-world-rest-api:0.0.2.RELEASE   app=hello-world-rest-api,pod-template-hash=89b8d4c97
hello-world-rest-api-8c7449fd    0         0         0       18h   hello-world-rest-api   in28min/hello-world-rest-api:0.0.1.RELEASE   app=hello-world-rest-api,pod-template-hash=8c7449fd
@cloudshell:~ (proud-curve)$ kubectl get pods -o wide
NAME                                   READY   STATUS    RESTARTS   AGE   IP          NODE                                                 NOMINATED NODE   READINESS GATES
hello-world-rest-api-89b8d4c97-6l564   1/1     Running   0          44s   10.44.1.9   gke-in28minutes-cluster-default-pool-24f9f7fb-xq70   <none>           <none>
hello-world-rest-api-89b8d4c97-6w9w5   1/1     Running   0          41s   10.44.2.8   gke-in28minutes-cluster-default-pool-24f9f7fb-6q96   <none>           <none>
hello-world-rest-api-89b8d4c97-m88z8   1/1     Running   0          39s   10.44.0.8   gke-in28minutes-cluster-default-pool-24f9f7fb-vzdc   <none>           <none>

 

 

3. 내부적으로 일어난 동작을 보면 새로운 relicaset을 먼저 생성한 후 pod 1개를 먼저 생성하여 image를 내려받아 컨테이너를 실행하고 기존 replicaset의 개수를 2로 줄이면서 기존 container를 중지하고 pod을 삭제한다. 이 작업을 replicas 개수만큼 3번만큼 진행하여 기존 relicaset에서 실행되던 pod을 순차적으로 신규 relicaset으로 이관되게 된다. 롤링 업데이트 전략이 적용된 예시이다.

@cloudshell:~ (proud-curve)$ kubectl get events --sort-by=.metadata.creationTimestamp
LAST SEEN   TYPE     REASON              OBJECT                                      MESSAGE
...
6m36s       Normal   SuccessfulCreate    replicaset/hello-world-rest-api-89b8d4c97   Created pod: hello-world-rest-api-89b8d4c97-6l564
6m35s       Normal   Scheduled           pod/hello-world-rest-api-89b8d4c97-6l564    Successfully assigned default/hello-world-rest-api-89b8d4c97-6l564 to gke-in28minutes-cluster-default-pool-24f9f7fb-xq70
6m36s       Normal   ScalingReplicaSet   deployment/hello-world-rest-api             Scaled up replica set hello-world-rest-api-89b8d4c97 to 1
6m35s       Normal   Pulling             pod/hello-world-rest-api-89b8d4c97-6l564    Pulling image "in28min/hello-world-rest-api:0.0.2.RELEASE"
6m34s       Normal   Started             pod/hello-world-rest-api-89b8d4c97-6l564    Started container hello-world-rest-api
6m34s       Normal   Created             pod/hello-world-rest-api-89b8d4c97-6l564    Created container hello-world-rest-api
6m34s       Normal   Pulled              pod/hello-world-rest-api-89b8d4c97-6l564    Successfully pulled image "in28min/hello-world-rest-api:0.0.2.RELEASE" in 1.45s (1.45s including waiting). Image size: 88504316 bytes.
6m33s       Normal   Pulling             pod/hello-world-rest-api-89b8d4c97-6w9w5    Pulling image "in28min/hello-world-rest-api:0.0.2.RELEASE"
6m33s       Normal   ScalingReplicaSet   deployment/hello-world-rest-api             Scaled down replica set hello-world-rest-api-8c7449fd to 2 from 3
6m33s       Normal   Killing             pod/hello-world-rest-api-8c7449fd-bw2hn     Stopping container hello-world-rest-api
6m33s       Normal   SuccessfulDelete    replicaset/hello-world-rest-api-8c7449fd    Deleted pod: hello-world-rest-api-8c7449fd-bw2hn
6m33s       Normal   Scheduled           pod/hello-world-rest-api-89b8d4c97-6w9w5    Successfully assigned default/hello-world-rest-api-89b8d4c97-6w9w5 to gke-in28minutes-cluster-default-pool-24f9f7fb-6q96
6m33s       Normal   ScalingReplicaSet   deployment/hello-world-rest-api             Scaled up replica set hello-world-rest-api-89b8d4c97 to 2 from 1
6m33s       Normal   SuccessfulCreate    replicaset/hello-world-rest-api-89b8d4c97   Created pod: hello-world-rest-api-89b8d4c97-6w9w5
6m32s       Normal   Started             pod/hello-world-rest-api-89b8d4c97-6w9w5    Started container hello-world-rest-api
6m32s       Normal   Created             pod/hello-world-rest-api-89b8d4c97-6w9w5    Created container hello-world-rest-api
6m32s       Normal   Pulled              pod/hello-world-rest-api-89b8d4c97-6w9w5    Successfully pulled image "in28min/hello-world-rest-api:0.0.2.RELEASE" in 879ms (879ms including waiting). Image size: 88504316 bytes.
6m31s       Normal   Scheduled           pod/hello-world-rest-api-89b8d4c97-m88z8    Successfully assigned default/hello-world-rest-api-89b8d4c97-m88z8 to gke-in28minutes-cluster-default-pool-24f9f7fb-vzdc
6m31s       Normal   Pulling             pod/hello-world-rest-api-89b8d4c97-m88z8    Pulling image "in28min/hello-world-rest-api:0.0.2.RELEASE"
6m31s       Normal   SuccessfulDelete    replicaset/hello-world-rest-api-8c7449fd    Deleted pod: hello-world-rest-api-8c7449fd-mgg96
6m31s       Normal   Killing             pod/hello-world-rest-api-8c7449fd-mgg96     Stopping container hello-world-rest-api
6m31s       Normal   SuccessfulCreate    replicaset/hello-world-rest-api-89b8d4c97   Created pod: hello-world-rest-api-89b8d4c97-m88z8
6m31s       Normal   ScalingReplicaSet   deployment/hello-world-rest-api             Scaled down replica set hello-world-rest-api-8c7449fd to 1 from 2
6m31s       Normal   ScalingReplicaSet   deployment/hello-world-rest-api             Scaled up replica set hello-world-rest-api-89b8d4c97 to 3 from 2
6m30s       Normal   Started             pod/hello-world-rest-api-89b8d4c97-m88z8    Started container hello-world-rest-api
6m30s       Normal   Pulled              pod/hello-world-rest-api-89b8d4c97-m88z8    Successfully pulled image "in28min/hello-world-rest-api:0.0.2.RELEASE" in 856ms (856ms including waiting). Image size: 88504316 bytes.
6m30s       Normal   Created             pod/hello-world-rest-api-89b8d4c97-m88z8    Created container hello-world-rest-api
6m29s       Normal   Killing             pod/hello-world-rest-api-8c7449fd-fzg7d     Stopping container hello-world-rest-api
6m29s       Normal   SuccessfulDelete    replicaset/hello-world-rest-api-8c7449fd    Deleted pod: hello-world-rest-api-8c7449fd-fzg7d
6m29s       Normal   ScalingReplicaSet   deployment/hello-world-rest-api             Scaled down replica set hello-world-rest-api-8c7449fd to 0 from 1

anaconda는 데이터 사이언스, 머신 러닝과 AI에 활용할 수 있는 여러 패키지를 찾고 설치할 수 있게 도와주는 파이썬 배포판 플랫폼으로 오픈소스이다. 설치를 하면 command line 도구와 GUI로 된 Anaconda Navigator를 이용하여 환경과  패키지를 관리할 수 있다.
 
1. https://www.anaconda.com/download 접속하여 설치 파일을 다운로드 한다. 이때 가입 폼이 있지만 Skip registration을 클릭하여 굳이 가입하지 않고도 다운로드가 가능하다.

anaconda download

 
 
2. OS에 따라 설치 파일이 다르고, Mac의 경우 인텔 칩이냐 애플 실리콘 칩이냐 그리고 GUI가 있는 installer인지 command line installer인지 선택하여 설치 파일을 다운로드 할 수 있다. 설치 편의성을 위해 Graphical Installer를 다운로드 하였다.

anaconda installation on mac

 
 
3. Graphical Installer는 .pkg 파일이 다운로드 되니 더블 클릭하여 일반적인 맥용 설치 파일처럼 동의하고 패스워드 넣고 설치하면 된다. 설치를 하면 command line interface인 conda와 데스크탑 애플리케이션인 Anaconda Navigator를 이용하여 개발 환경과 패키지를 관리할 수 있다.

anaconda distribution Graphical installer

 
 
4. 설치 후에 터미널에서 conda 명령어를 사용할 수 있다. 그런데 설치가 다 되었음에도 명령어를 인식하지 못할 수도 있다.

lazy@MacBook-M1-Pro ~ % conda 
zsh: command not found: conda

 
이런 경우, 공식 가이드 문서 troubleshooting(https://docs.anaconda.com/reference/troubleshooting/#conda-command-not-found-on-macos-linux)에 보면 몇 가지 원인과 해결 방법을 안내해 둔 내용을 참고하여 조치를 해보면 된다. 그 중 가장 손쉽게 해볼 수 있으면서도 유력한 원인은 anaconda 설치 후 shell을 새로 실행하지 않았기 때문이다.

Conda: command not found on macOS

 
shell을 새로 열어 which conda를 해보거나 conda list와 같은 명령어를 터미널에서 실행했을 때 동작하는 것을 확인할 수 있다.

(base) lazy@MacBook-M1-Pro ~ % which conda
conda () {
	\local cmd="${1-__missing__}"
	case "$cmd" in
		(activate | deactivate) __conda_activate "$@" ;;
		(install | update | upgrade | remove | uninstall) __conda_exe "$@" || \return
			__conda_reactivate ;;
		(*) __conda_exe "$@" ;;
	esac
}
(base) lazy@MacBook-M1-Pro ~ % conda list
# packages in environment at /opt/anaconda3:
#
# Name                    Version                   Build  Channel
_anaconda_depends         2024.10         py312_openblas_0

 
 단, 기본 터미널 쉘에서 conda가 활성화되는 것을 방지하기 위해서는 아래 conda config를 설정해야 한다.

(base) lazy@MacBook-M1-Pro ~ % conda config --set auto_activate_base false

GKE 클러스터를 생성했다면, 이미 개발한 애플리케이션을 클러스터에 간단하게 배치하는 방법을 구글 클라우드 쉘을 이용하여 진행해보려고 한다.

GKE(구글 쿠버네티스 엔진) 클러스터 생성

Udemy의 'Spring Boot Java Microservices를 활용한 Kubernetes 초심자용 강의 - GKE, AWS, EKS, Azure AKS를 중심으로 다루기' 강의를 들으면서 이해하거나 기억해야 할 내용을 간략하게 정리한 것이다. 강의에 나온

lazytechlog.tistory.com

 
 
1. 클라우드 쉘을 통해 구글 쿠버네티스 클러스터에 연결한다. Clusters 메뉴에서 클러스터 이름을 클릭하고 들어가서, 오른쪽 상단의 Activate Cloud Shell을 클릭하면 하단에 클라우드 쉘이 뜬다. 처음 activate할 때는 약간의 로딩 시간이 걸린다.

GKE - Activate Cloud Shell

 
 
2. 하단에 뜬 터미널을 사용하기 편하게 다른 창으로 열어주는 것이 좋다. 하단의 터미널 오른쪽 상단에 있는 Open in new window 아이콘을 클릭한다. 새 창으로 터미널이 정상적으로 뜨면 하단의 터미널은 오른쪽 상단의 X 아이콘을 클릭하여 닫아준다.

Google Cloud Shell

 
 
3. 클라우드 쉘로 Cluster에 연결하기 위해서 클러스터 이름을 클릭 후 보이는 화면에서 상단에 있는 CONNECT 메뉴를 클릭한다. command line 오른쪽에 있는 복사 아이콘을 클릭하여 2번 단계에서 오픈한 새 창에 뜬 shell에 붙여넣기를 한다.
 
gcloud 명령어는 클러스터 이름과 zone, 그리고 project id를 명시하여 연결하도록 되어 있다.

GKE - Connect to the cluster

 
project id는 Google Cloud 오른쪽에 있는 프로젝트 이름을 클릭하면 뜨는 프로젝트 리스트 팝업창에서 확인할 수 있다.

 
 
4. 앞선 과정이 모두 선행되어 cloud shell에서 cluster에 연결이 된 상태여야 다음의 과정을 진행할 수 있다. 클라우드 쉘에서는 이미 설치되어 있는 kubectl 쿠버네티스 명령어를 사용하여 클라우드 클러스터와 상호작용할 수 있다. kubectl 버전을 확인해보자.

@cloudshell:~ (proud-curve)$ kubectl version
Client Version: v1.31.5
Kustomize Version: v5.4.2
Server Version: v1.31.5-gke.1023000

 
여기서 Server 버전은 연결되어 있는 클러스터 머신의 버전으로서 클러스터 생성 시 지정한 타겟 버전과 동일하다.
 
5. kubectl을 이용하여 이미 개발되어 있는 간단한 애플리케이션을 배포해보겠다. 애플리케이션은 docker hub에 있는 image(https://hub.docker.com/r/in28min/hello-world-rest-api/tags)를 이용하기 때문에 별도로 개발할 필요는 없다. image 이름과 버전을 지정하여 kubectl create deployment를 하면 배포가 된다.
 

kubectl create deployment hello-world-rest-api --image=in28min/hello-world-rest-api:0.0.1.RELEASE

 
 
6. 배포한 deployment를 외부 서비스로 노출한다.

kubectl expose deployment hello-world-rest-api --type=LoadBalancer --port=8080

 
 
7. 이제 이 서비스를 browser를 통해 확인할 수 있다. 외부 접속을 위한 정보를 확인하기 위해 Networking > Gateways, Services & Ingress 메뉴를 클릭한 후 오른쪽 페이지에서 SERVICES 탭을 클릭하면 서비스 리스트를 확인할 수 있다. Endpoints에 있는 URL로 배포한 애플리케이션에 접근할 수 있다.

GKE - Gateways, Services & Ingress

 
 
8. 7번 단계에서 확인한 {Endpoint}/hello-world-bean 주소를 browser에서 실행하면 간단한 hello world 메시지를 확인할 수 있다.

 

+ Recent posts