Here's my dents in the universe

누군가 나에게 쿠버네티스를 이렇게 설명해줬더라면


새로운 형식으로 튜토리얼을 작성해보았다. 먼저 대상에 대한 심적 표상을 그리고(이게 무엇인지, 어떻게 동작하는지), 이후에 사용하는 방법을 제안하는 식이다. 심적 표상을 그리지 않고, 곧장 how로 접근하면 결국 아무것도 기억에 남지 않더라. 새로운 형식의 튜토리얼을 제안해본다.

k8s, 이런게 있습니다

k8s는 컨테이너 상태 오케스트레이션 툴입니다.

k8s는 사람이 직접 해야했던 컨테이너 오케스트레이션 기능을 wrapping해서 제공하는 툴입니다. 유저는 yaml 파일을 작성하는 것으로 이 오케스트레이션을 지휘할 수 있습니다. 인간의 오케스트레이션 수고를 덜어주는 것이죠.

Pod는 ‘파드’, ‘팟’ 으로 읽힙니다. 이 글에서는 ‘팟’으로 부르겠습니다. 팟은 컨테이너와 미묘하게 다르지만, 툴의 기본이 되는 atomic한 단위라는 점에서 비슷합니다. 아래 글은 팟=컨테이너라고 생각하며 읽으셔도 무방합니다.

k8s, 이렇게 동작합니다

도커가 작동하는 하나의 단위가 ‘컨테이너’였듯이, k8s는 ‘팟’이라는 단위로 작동합니다. k8s는 팟의 상태를 관리합니다. k8s가 유저의 어떤 요구를 어떻게 해결하고 있는지 케이스별로 살펴보면서, k8s의 동작에 대한 심적표상을 그려보겠습니다.

팟이 잘 살아있는지 자동으로 확인하고 죽으면 다시 띄워줄 수 없을까?

팟의 개수를 간편하게 관리할 수는 없을까?

팟이 죽었을 때 알아서 복구되게 할 수는 없을까?

여러 개의 팟을 롤링 업데이트하려는데 간편하게 할 수 없을까?

여러 팟 간의 로드밸런싱을 편하게 할 수 없을까?

웹 서비스의 여러 기능들이 서로 다른 service object로 묶여있다. 유저가 사용하기 좋게 도메인을 나눌 수는 없을까?

k8s, 이렇게 쓰면 됩니다

기본적인 개념들

kubectl 커맨드 종류

가장 자주 사용하는 4가지만 설명하겠습니다. 나머지는 하나씩 찾아보세요!

yaml 파일 읽고 쓰는 법

아래는 아키텍쳐 구성 중 가장 많이 쓰이는 Deployment와 Service object의 YAML 명세를 예시로 구성해보았습니다. K8S에 대한 100번의 설명보다, YAML 파일을 보는 것이 (개인적으로는) 더 많은 도움이 되었습니다. 궁금할만한 부분마다 주석을 달아놓았으니 확인해보세요 :)

apiVersion: apps/v1          # Deployment라는 Object의 버전입니다. 다른 버전을 사용하면 Object를 찾을 수 없다는 에러가 발생합니다.
kind: Deployment             # 사용하려는 object입니다.
metadata:                    # Object에 대한 메타 정보입니다. 
  name: wordpress-mysql
  labels:
    app: wordpress           # 사용자가 정할 수 있는 key-value값입니다. hello-world라고 적어도 무방합니다.
spec:
  replicas: 4                # replicaset을 이용해 4개의 pod를 유지합니다.
  selector:                  # deployment는 다음 라벨과 일치하는 팟을 찾아 지속적으로 배포합니다.
    matchLabels:
      app: wordpress
      tier: mysql
  template:                  # 위와 일치하는 라벨을 가진 팟이 없으면 아래 템플릿을 보고 새로운 팟을 생성합니다.
    metadata:                # 여기부터 아래는 팟에 대한 명세입니다.
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:             # 이 팟은 다음과 같은 컨테이너를 가졌습니다. (yaml에 대한 설명)
        - image: mysql:5.6
          name: mysql
          env:                # 이 컨테이너 내부에서 사용할 환경변수를 지정할 수 있습니다. 역시나 key-value입니다.
            - name: MYSQL_ROOT_PASSWORD
              value: password
          ports:
            - containerPort: 3307 # 컨테이너가 외부로 노출하는 포트입니다.
              name: mysql
          resources:
            limits:
              memory: "1024Mi"
              cpu: "1000m"     # 최대 CPU의 1 core를 사용할 수 있음

---
apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306              # 서비스 오브젝트가 외부로 공개할 포트번호입니다. 
      targetPort: 3307        # 서비스 오브젝트가 타겟으로 하는 팟의 포트입니다. 생략하면 spec.ports.port와 같은 값이 default로 들어갑니다.
  selector:                   # 아래 라벨과 일치하는 팟을 찾습니다.
    app: wordpress
    tier: mysql