si.mpli.st dev

Minku Lee

k3s 시리즈 - Kubernetes에서 쉽게 HTTPS 웹 서비스 돌리기

이전 글에서는 VPS 등의 서버 환경에 간단하게 k3s 클러스터를 설치하고, 원격으로 접속하는 방법에 대해 알아보았습니다. 클러스터를 설치되었으면 뭐라도 배포를 해 보아야겠죠? 이번 글에서는 Let’s Encrypt 인증서를 발급받기 위해 cert-manager를 설치하고, 간단한 웹 서비스를 돌려보는 과정을 살펴보겠습니다.

앞으로 진행할 튜토리얼은 k3s 클러스터를 이미 생성하고, kubectl로 접근할 수 있도록 설정한 것을 가정합니다. 혹시 아직 k3s를 설치하지 않으셨다면, 이전 글을 참고하셔서 쉽게 클러스터를 만들고 돌아와 주세요.

간단한 웹 서비스 실행

Kubernetes에서 웹 서비스를 돌리기 위해서는 크게 Deployment, Service, Ingress라는 세 종류의 리소스를 활용합니다. 이 세 가지 리소스에 대해서는 다음에 자세하게 다루기로 하고, 우선 이미 만들어진 예제 서비스를 활용하도록 하죠.

Host, Pod 정보를 보여주는 Inspekt 서비스

Inspekt는 제가 간단하게 만든, Kubernetes에 시험 삼아 올리기 좋은 웹 서비스입니다. Kubernetes의 Downward API를 이용하여 현재 구동되는 환경에 대한 몇 가지 정보를 보여주는데요, 디버그 및 테스트를 할 때 도움이 될 수 있습니다.

Inspekt를 다음 명령어를 이용해 클러스터에 올려봅시다. -kKustomize를 이용해 적용하라는 스위치입니다.

$ kubectl apply -k github.com/premist/inspekt 

Kustomize를 이용해 inspekt 설정 반영

정상적으로 Deployment와 Service가 생성되었으면, 아래 명령어로 상태를 확인할 수 있습니다.

# Deployment 상태 확인
$ kubectl describe deployment inspekt

# Service 상태 확인
$ kubectl describe service inspekt

Deployment가 정상적으로 생성되었다

이제 웹 서비스가 돌아가고 있지만, 아직 Ingress를 통해 외부로 노출되지는 않았기 때문에 직접 접속은 불가능합니다. kubectl port-forward 명령어를 이용해서 로컬에서 접속할 수 있도록 포트 포워딩을 설정해봅시다.

# 원격지 포트 8000를 로컬 포트 9000로 포워딩
$ kubectl port-forward deployment/inspekt-deployment 9000:8000

포트 포워딩 설정

포트 포워딩을 완료하였다면, 브라우저에서 inspekt 화면을 확인할 수 있습니다!

Inspekt 웹 페이지

cert-manager로 Let’s Encrypt 설정하기

서비스를 외부에 노출하기 전에, HTTPS 연결을 위해 인증서를 발급받아야 합니다. SSL/TLS 인증서를 직접 구입하여 사용할 수도 있지만, Let’s Encrypt를 사용하는 인증서 관리자인 cert-manager를 사용하면 무료로 인증서 발급이 가능하고 갱신 또한 자동으로 처리해줍니다.

다음 두 명령어를 실행하여 설치를 진행할 수 있습니다.

# cert-manager가 사용할 namespace 생성
$ kubectl create namespace cert-manager

# cert-manager가 사용하는 구성요소(CRD, ServiceAccount 등) 설치
$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v0.13.1/cert-manager.yaml

설치가 완료되었으면 cert-manager가 Let’s Encrypt를 이용하도록 설정을 해 주어야 합니다. 로컬에 letsencrypt.yaml 이라는 파일을 만들고 아래 내용을 붙여넣어 주세요. 예제 이메일 주소를 자신의 이메일로 변경하고, 저장합니다.

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    # 자신의 이메일 주소 입력
    email: user@example.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-account-key
    # 웹 서버를 이용하여 검증을 진행하는 http01 solver 사용 
    solvers:
    - http01:
        # k3s의 기본 Ingress 컨트롤러인 traefik을 사용하도록 설정
        ingress:
          class: traefik

방금 만든 yaml을 클러스터에 적용하는 것으로 Let’s Encrypt 사용 준비가 완료됩니다.

$ kubectl apply -f letsencrypt.yaml

inspekt 웹 서비스에 Ingress 연결하기

이제 inspekt 웹 서비스를 외부에 노출할 준비가 모두 끝났습니다! 인증서 발급을 위해서는 올바른 도메인이 연결되어 있어야 하는데요, DNS 서비스에 들어가서 클러스터의 IP를 입력해줍니다.

DNS 설정

다음으로 Ingress 설정 파일을 작성해줍니다. 로컬에 ingress.yaml 이라는 파일을 만들고, 아래 내용을 붙여넣어주세요. spec.tls.hosts 에 앞에서 설정한 도메인을 입력해주기만 하면 됩니다.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: inspekt
  annotations:
    kubernetes.io/ingress.class: "traefik"
    cert-manager.io/cluster-issuer: "letsencrypt"
spec:
  tls:
  - hosts:
    - <여기에 설정한 도메인 입력>
    secretName: inspekt-tls
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: inspekt
          servicePort: http

방금 생성한 파일을 kubectl로 적용해줍시다.

Ingress 생성

위 Ingress를 적용하면 보이지 않는 곳에서 여러 가지 일이 일어나는데, 그 중 몇 가지를 추려보자면 다음과 같습니다.

  • k3s의 기본 Ingress 컨트롤러인 traefik이 주어진 규칙에 맞게 요청을 처리할 수 있도록 라우팅 설정을 업데이트합니다.
  • spec.tls.hosts 에 설정한 도메인에 대한 검증을 진행합니다. 검증에 필요한 웹 서버를 실행하고, 라우팅 설정을 업데이트합니다.
  • 인증서가 발행되면 spec.tls.secretName에서 지정한 secret에 저장합니다. secret이 존재하지 않으면, 새로 만들고 저장합니다.

Kubernetes의 이벤트 로그를 보면, 어떤 일이 일어나는지 조금 더 자세하게 알 수 있습니다.

# 최근 이벤트 보기
kubectl get events --sort-by=.metadata.creationTimestamp

인증서 발급에 관한 여러 이벤트

여기까지 모든 과정을 성공적으로 진행하셨다면, 지정한 도메인에서 inspekt 서비스에 접속할 수 있습니다! 🎉

HTTPS로 접속이 되는 것을 확인할 수 있다

마치며

이렇게 간단한 웹 서비스를 클러스터에 추가하고, Let’s Encrypt 사용을 설정하고, Ingress를 만들어 웹 서비스를 위한 Let’s Encrypt 인증서를 발급받는 과정까지 모두 살펴보았습니다. 기존의 서버 설정 과정과는 다른 방식에 생소할 수 있지만, 앞으로 배포하는 모든 웹 서비스에 대한 인증서를 자동으로 발급받을 수 있다는 점이 꽤나 매력적입니다. 그리고, 원하는 상태를 기술하므로써 설정을 할 수 있는, 서버의 선언적 관리(declarative management)를 할 수 있다는 점에서 오는 관리의 용이함 또한 빼놓을 수 없을 것입니다.

이 가이드를 보기 전에 Kubernetes를 사용해보지 않은 분이라면 Deployment, Ingress와 같은 여러 개념이 아직 잘 와닿지 않으실 텐데, 이에 대한 설명도 조만간 다룰 기회가 있으면 좋겠네요. 앞으로도 k3s 관련 글을 몇 편 더 올리려고 합니다. 궁금하신 주제가 있으면 이메일이나 트위터 등의 채널로 알려주세요.