kubernetes

gosu·2024년 1월 12일
0
post-custom-banner

kubernetes ✍️

  • 조타; 키잡이(helmsman)나 파일럿을 뜻하는 그리스어에서 유래

  • aks : azure kubernetes service
  • eks : aws kubernetes service

  • 실습 환경 : minikube
  • kubernetes 설정하는거 하루종일 걸리는데 좀 간편하게 실습 가능하다
  • 한 대 컴퓨터안에 마스터, 노드 구조로 되어있는 심플한 구조
  • 원래는 서브넷 쪼개고 컴퓨터를 네트워크로 묶고 어쩌구.. 해야함

  • master / node 구조
  • 사람은 kubectl란 cli 환경을 통해 master과만 통신함. 그럼 master가 알아서 node 관리해주는 구조로 되어있다.

minikube 설치

  1. curl로 minikube 다운로드 및 설치
curl -LO https://storage.googleapis.com/minikube/releases/v1.22.0/minikube-linux-amd64 
sudo install minikube-linux-amd64 /usr/local/bin/minikube
  1. 설치 확인
minikube --help
  1. kubectl 설치
curl -LO https://dl.k8s.io/release/v1.22.1/bin/linux/amd64/kubectl 
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
  1. kubectl 설치 확인
kubectl --help

minikube 시작하기

  1. 미니쿠베 시작하기
$ minikube start --driver=docker
😄  minikube v1.22.0 on Ubuntu 20.04
✨  Using the docker driver based on user configuration

💣  Exiting due to PROVIDER_DOCKER_NEWGRP: "docker version --format -" exit status 1: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
💡  Suggestion: Add your user to the 'docker' group: 'sudo usermod -aG docker $USER && newgrp docker'
📘  Documentation: https://docs.docker.com/engine/install/linux-postinstall/

1-2. 트러블 슈팅1

  • docker 권한 줘야한다.
sudo usermod -aG docker $USER
newgrp docker
minikube start --driver=docker
  • 다음 명령어로 docker에 대한 권한을 받으면 정상적으로 실행 가능하다.
$ sudo usermod -aG docker $USER
rp docker
$ newgrp docker
$ minikube start --driver=docker
😄  minikube v1.22.0 on Ubuntu 20.04
✨  Using the docker driver based on user configuration
🎉  minikube 1.32.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.32.0
💡  To disable this notice, run: 'minikube config set WantUpdateNotification false'

👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
💾  Downloading Kubernetes v1.21.2 preload ...
    > preloaded-images-k8s-v11-v1...: 502.14 MiB / 502.14 MiB  100.00% 29.21 Mi
    > gcr.io/k8s-minikube/kicbase...: 361.08 MiB / 361.09 MiB  100.00% 15.39 Mi
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.21.2 on Docker 20.10.7 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

1-3. 트러블슈팅2. 컴퓨터 사양을 늘려보자

  • 램 8기가 -> 램 16기가
  • 중지 -> 크기 -> d4s3 (램16기가) -> 크기 조정

  1. minikube 시스템 상태 확인
$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

2-1. kubectl 시스템의 구성 확인

  • 쿠버네티스 자체도 다 도커 컨테이너 환경으로 되어있다.
$ kubectl get pod -n kube-system
NAME                               READY   STATUS    RESTARTS   AGE
coredns-558bd4d5db-d4ff9           1/1     Running   1          41m
etcd-minikube                      1/1     Running   1          41m
kube-apiserver-minikube            1/1     Running   1          41m
kube-controller-manager-minikube   1/1     Running   1          41m
kube-proxy-d4vk9                   1/1     Running   1          41m
kube-scheduler-minikube            1/1     Running   1          41m
storage-provisioner                1/1     Running   2          41m
  1. minikube 삭제
minikube delete 

pod

  • 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위를 말함
  • https://kubernetes.io/ko/docs/concepts/workloads/pods/
  • pod 단위로 스케줄링, 로드밸런싱, 스케일링 등의 관리 작업을 수행합니다.
  • pod는 container를 감싼 개념이라고 생각하면 된다.

pod 생성

  1. pod.yaml 생성
  • vi pod.yaml
apiVersion: v1 # kubernetes resource 의 API Version 
kind: Pod # kubernetes resource name 
metadata: # 메타데이터 : name, namespace, labels, annotations 등을 포함 
  name: counter 
spec: # 메인 파트 : resource 의 desired state 를 명시 
  containers: 
  - name: count # container 의 이름 
    image: busybox # container 의 image 
    args: [/bin/sh, -c, 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done'] # 해당 image 의 entrypoint 의 args 로 입력하고 싶은 부분 
  1. pod.yaml의 명세를 통해 pod 생성
  • kubectl apply
$ kubectl apply -f pod.yaml
pod/counter created 

pod 조회

  1. pod get pod 확인
$ kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
counter   1/1     Running   0          6m56s
  • -A 옵션으로 kube-system이 실행시키고 있는 pod의 목록 확인도 가능하다
$ kubectl get pod -A
NAMESPACE     NAME                               READY   STATUS    RESTARTS   AGE
default       counter                            1/1     Running   0          10m
kube-system   coredns-558bd4d5db-d4ff9           1/1     Running   1          85m
kube-system   etcd-minikube                      1/1     Running   1          86m
kube-system   kube-apiserver-minikube            1/1     Running   1          86m
kube-system   kube-controller-manager-minikube   1/1     Running   1          86m
kube-system   kube-proxy-d4vk9                   1/1     Running   1          85m
kube-system   kube-scheduler-minikube            1/1     Running   1          86m
kube-system   storage-provisioner                1/1     Running   2          86m
  • kubectl get pod [pod 이름]
    • 특정 pod 이름의 pod를 조회할 수 있다
$ kubectl get pod counter
NAME      READY   STATUS    RESTARTS   AGE
counter   1/1     Running   0          11m
  • kubectl get pod -o wide
    • 더 자세하게 확인 가능하다. ip 정보 확인 가능
$ kubectl get pod -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
counter   1/1     Running   0          13m   172.17.0.3   minikube   <none>           <none>
  • kubectl get pod -o yaml --> a.yaml
    • pod의 정보를 yaml로 출력하기
$ cat a.yaml
apiVersion: v1
items:
- apiVersion: v1
  kind: Pod
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"counter","namespace":"default"},"spec":{"containers":[{"args":["/bin/sh","-c","i=0; while true; do echo \"$i: $(date)\"; i=$((i+1)); sleep 1; done"],"image":"busybox","name":"count"}]}}
  • kubectl get pod -w
    • 실시간 모니터링 가능
$ kubectl get pod -w
NAME      READY   STATUS    RESTARTS   AGE
counter   1/1     Running   0          135m
  • kubectl logs [pod 이름]
  • kubectl logs [pod 이름] -f # 실시간 로그 확인
$ kubectl logs counter
0: Fri Jan 12 02:34:36 UTC 2024
1: Fri Jan 12 02:34:37 UTC 2024
2: Fri Jan 12 02:34:38 UTC 2024
3: Fri Jan 12 02:34:39 UTC 2024
4: Fri Jan 12 02:34:40 UTC 2024
5: Fri Jan 12 02:34:41 UTC 2024
6: Fri Jan 12 02:34:42 UTC 2024

pod 안으로 들어가기

  • 만약 counter pod에 bash 쉘이 있다면 /bin/bash로 접속 가능
kubectl exec -it counter /bin/bash

pod 삭제

  • kubectl delete pod [pod-name]
  • kubectl delete -f [yaml-파일-경로]
$ kubectl delete pod counter
pod "counter" deleted

deployment

  • Deployment는 Pod와 Replicaset에 대한 관리를 제공하는 단위입니다.
  • https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/
  • 관리라는 의미는 Self-healing, Scaling, Rollout(무중단 업데이트)와 같은 기능을 포함합니다.
  • Deployment는 pod를 감싼 개념이라고 생각할 수 있습니다.
    • pod를 Deployment로 배포함으로써 여러 개로 복제된 Pod, 여러 버전의 Pod를 안전하게 관리할 수 있습니다.

deployment 생성

  • vi deployment.yaml
apiVersion: apps/v1 # kubernetes resource 의 API Version 
kind: Deployment # kubernetes resource name 
metadata: # 메타데이터 : name, namespace, labels, annotations 등을 포함 
  name: nginx-deployment 
  labels: 
    app: nginx 
spec: # 메인 파트 : resource 의 desired state 를 명시 
  replicas: 3 # 동일한 template 의 pod 을 3 개 복제본으로 생성합니다. 
  selector: 
    matchLabels: 
      app: nginx 
  template: # Pod 의 template 을 의미합니다. 
    metadata: 
      labels: 
        app: nginx 
    spec: 
      containers: 
      - name: nginx # container 의 이름 
        image: nginx:1.14.2 # container 의 image 
        ports: 
        - containerPort: 80 # container 의 내부 Port 
  • replicas : 3 : pod의 갯수를 3으로 지정하겠다. 복제본 3개가 생성되어서 가용성이 증가함.

  • kubectl apply -f deployment.yaml

$ kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created

deployment 조회

  • kubectl get deployment
$ kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           2m39s
  • kubectl get pods
    • pod 3개가 복제되어 생긴 것을 확인할 수 있다
$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-66b6c48dd5-45xkd   1/1     Running   0          5m19s
nginx-deployment-66b6c48dd5-5zvll   1/1     Running   0          5m19s
nginx-deployment-66b6c48dd5-s8mtq   1/1     Running   0          5m19s

auto-healing

  • pod를 하나 삭제시켜보자
    • auto-healing 기능으로 pod가 삭제되면 새로운 pod를 만들어준다.
$ kubectl delete pod nginx-deployment-66b6c48dd5-s8mtq
pod "nginx-deployment-66b6c48dd5-s8mtq" deleted

$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-66b6c48dd5-45xkd   1/1     Running   0          8m16s
nginx-deployment-66b6c48dd5-5zvll   1/1     Running   0          8m16s
nginx-deployment-66b6c48dd5-btwqc   1/1     Running   0          22s

pod scaling (갯수 늘리기)

  • kubectl scale [deployment 이름] --replicas=[늘릴 갯수]
$ kubectl scale deployment/nginx-deployment --replicas=5
deployment.apps/nginx-deployment scaled
$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-66b6c48dd5-45xkd   1/1     Running   0          11m
nginx-deployment-66b6c48dd5-5zvll   1/1     Running   0          11m
nginx-deployment-66b6c48dd5-btwqc   1/1     Running   0          3m57s
nginx-deployment-66b6c48dd5-m76j8   1/1     Running   0          3s
nginx-deployment-66b6c48dd5-n5ffh   1/1     Running   0          3s

deployment 삭제

  • kubectl delete deployment [deployment-name]
$ kubectl delete -f deployment.yaml
deployment.apps "nginx-deployment" deleted

Service

  • Service는 쿠버네티스에 배포한 어플리케이션(Pod)을 외부에서 접근하기 쉽게 추상화한 리소스입니다.
  • https://kubernetes.io/ko/docs/concepts/services-networking/service/
  • Pod는 ip를 할당받고 생성되지만, 언제든지 죽었다가 다시 살아날 수 있으며, 그 과정에서 ip는 항상 재할당받기에 고정된 ip로 원하는 pod에 접근할 수는 없습니다.
  • 따라서 클러스터 외부 혹은 내부에서 Pod에 접근할 때는, Pod의 ip가 아닌 Service를 통해서 접근하는 방식을 거칩니다.
  • Service는 고정된 ip를 가지며, Service는 하나 혹은 여러 개의 Pod과 매칭됩니다.
  • 따라서 클라이언트가 Service의 주소로 접근하면, 실제로는 Service에 매칭된 Pod에 접근할 수 있게 됩니다.

Service 생성 전 사전 지식

  • vi deployment2.yaml
  • kubectl apply -f deployment2.yaml
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: nginx-deployment 
  labels: 
    app: nginx 
spec: 
  replicas: 3 
  selector: 
    matchLabels: 
      app: nginx 
  template: 
    metadata: 
      labels: 
        app: nginx 
    spec: 
      containers: 
      - name: nginx 
        image: nginx:1.14.2 
        ports: 
        - containerPort: 80

pod의 ip로 접속해보기

  • kubectl get pod -o wide
    • 172.17.0.4 ip 주소로 접속해보자
$ kubectl get pod -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
nginx-deployment-66b6c48dd5-8frt4   1/1     Running   0          67s   172.17.0.4   minikube   <none>           <none>
nginx-deployment-66b6c48dd5-mwrcc   1/1     Running   0          67s   172.17.0.5   minikube   <none>           <none>
nginx-deployment-66b6c48dd5-xkmwd   1/1     Running   0          67s   172.17.0.3   minikube   <none>           <none>
  • curl -X GET [ip주소] -vvv
    • 통신 안되는 것을 확인할 수 있다.
$ curl -X GET 172.17.0.4 -vvv
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 172.17.0.4:80...
* TCP_NODELAY set
* connect to 172.17.0.4 port 80 failed: No route to host
* Failed to connect to 172.17.0.4 port 80: No route to host
* Closing connection 0
curl: (7) Failed to connect to 172.17.0.4 port 80: No route to host

minikube ssh

  • minikube의 라우터로 적속하는 명령어이다
$ minikube ssh
docker@minikube:~$
  • 여기서 172.17.0.4로 접속해보자
    • minikube의 라우터 안으로 들어간 후 사설망의 172.17.0.4로 접속하니, 다음과 같이 응답을 받는 것을 볼 수 있다.
docker@minikube:~$ curl -X GET 172.17.0.4 -vvv
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 172.17.0.4:80...
* TCP_NODELAY set
* Connected to 172.17.0.4 (172.17.0.4) port 80 (#0)
> GET / HTTP/1.1
> Host: 172.17.0.4
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK

Service 생성

  • vi service.yaml
apiVersion: v1 
kind: Service 
metadata: 
  name: my-nginx 
  labels: 
    run: my-nginx 
spec: 
  type: NodePort # Service 의 Type 을 명시하는 부분입니다. 자세한 설명은 추후 말씀드리겠습니다. 
  ports: 
  - port: 80 
    protocol: TCP 
  selector: # 아래 label 을 가진 Pod 을 매핑하는 부분입니다. 
    app: nginx  
  • kubectl apply -f service.yaml
$ kubectl apply -f service.yaml
service/my-nginx created

service 조회

  • kubectl get service
$ kubectl get service
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        4h40m
my-nginx     NodePort    10.104.175.251   <none>        80:32528/TCP   2m7s
  • 다음과 같이 30842 포트가 외부와 연결되었다.
  • 그러나 클라우드 환경에서 진행하므로, 보안상 방화벽으로 막혀있어서 안됨.. (실습종료)

ip network 지식 👍

private network(사설망)

  • private network : 일반적으로 192.~으로 시작하는 주소들을 묶는 것을 private network라고 한다.
  • 사설망은 192.168.0.2, 192.168.0.3 ... 과 같이 192.~ 로 되어있다
  • 공유기 = Gateway(NAT) = 라우터 : 192.168.0.1을 주소로 가진다
  • 공유기는 192.~로 되어있는 주소들 각각을 연결해 181.227.3.33과 같은 주소를 변환해 인터넷에 접속한다.

이와 같은 사설망 개념은 쿠버네티스에서도 적용된다

  • 도커 : 각각의 컴퓨터 192.168.0.2, 192.168.0.3, ...
  • 쿠버네티스 : 각각의 컴퓨터를 묶어 라우팅 해주는 역할을 한다. 192.168.0.1

16 bit vs 20 bit

  • 16 bit : 192.168.0.0 ~ 192.~
  • 20 bit : 172.16.0.0 ~ 172.~ (쿠버네티스가 채택함 ✅)

쿠버네티스는 사설망에 있다

  • 그래서 나중에 인터넷에 연결하려면 사설망과 공용망 주소를 연결해주는 세팅이 필요하다.
profile
개발자 블로그 ^0^
post-custom-banner

0개의 댓글