[그림 한장] Kubernetes CI/CD 에서는 이러한 구성이 어떤 의미가 있는지 설명하지 않았다. 이번 기회에 부연해본다. 우선 그림을 보며 흐름을 되짚어보자.
- 소스코드를 변경한다. 변경사항이 들어오면 GitHub는 CI 서비스에 이벤트를 보내고 빌드가 시작된다.
- Docker Hub를 이용하든 Travis-CI / Jenkins를 이용하든 최종 산출물인 도커 이미지는 Docker Hub에 모인다.
- 새 도커 이미지가 들어오면 Docker Hub는 미리 정의한 웹 후크 주소에 이벤트를 보낸다.
- Keel은 도커 허브의 이벤트를 받으면 이를 K8s 내의 배포 정책과 대조한다. 그리고 배포 정책에 부합하는 이벤트인 경우에 배포를 진행한다.
- 설정에 따라서는 Keel이 배포를 하기 전에 Slack 등을 통해 관리자의 승인을 받을 수도 있다.
이러한 배포 방법은 흔하지는 않다. 보통은 CI 서비스가 배포까지 책임진다. 그러나 전자가 후자에 비해 여러 면에서 낫다고 본다.
- CI 서비스가 배포를 책임지는 경우 보안 관제가 다소 까다롭다. 우선 CI 서비스가 외부에 있는 경우에 배포 권한을 외부에 노출해야 한다. 외부 서비스가 침해 당하면 우리의 서비스도 함께 무너질 수 있다.
- 위의 경우와 같은 맥락인데 CI 서비스가 배포를 책임지는 경우는 계정이 한 곳에서 있지 않기 때문에 관리하기 쉽지 않다. 어디어디에서 해당 계정을 이용하는지 정확히 모르면 배포 계정의 암호를 정기적으로 변경하기 힘들다.
- K8s의 배포를 Jenkins 등이 책임지는 경우,
deployment.yaml
파일 등을 CI 서버에 둬야 한다. yaml 파일을 Git 등으로 관리하는 경우에 어느 쪽이든 변경사항이 생기면 다른 한쪽에 이를 반영해야 하는 번거로움을 감수해야 한다.
반면 이 글에서 추천하는 배포 방식은 와와 같은 문제가 전혀 없다. 배포는 K8s 안에 구성한 keel이 담당한다. keel은 K8s 안에 있기 때문에 밖으로 Credential을 노출할 필요가 없다. 또한 keel은 service account의 권한을 이용하기 때문에 별도의 Credential을 생성하고 관리할 필요가 없다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka
spec:
replicas: 3
template:
metadata:
labels:
app: kafka
keel.sh/policy: major
keel.sh/trigger: http
# approvals required to proceed with an update if the value is 1
keel.sh/approvals: “1”
spec:
containers:
- name: broker
image: solsson/kafka:1.0.1
이와 더불어 배포 정책이 여러 곳에 분산되지 않고 한 곳에 모인다는 장점도 있다. 예를 들어 Kafka의 배포 정책은 kafka-statefulset.yaml
파일에 Annotation으로 정의한다. 그러므로 Kafka의 구성 정보는 한 곳에 온전히 집중된다. 애플리케이션 서비스의 구성과 배포 정보를 한 눈에 파악할 수 있다.
부연
완전히 자동화된 배포(keel.sh/approvals: “0”
)는 가급적 Staging에서만 이용하는 편이 좋다. 실 서비스 환경에서는 사람의 명시적인 개입이 있는 편이 낫다. 그래야 예기치 않은 일이 발생했을 때 조기에 대응할 수 있다.
Author Details
Kubernetes, DevSecOps, AWS, 클라우드 보안, 클라우드 비용관리, SaaS 의 활용과 내재화 등 소프트웨어 개발 전반에 도움이 필요하다면 도움을 요청하세요. 지인이라면 가볍게 도와드리겠습니다. 전문적인 도움이 필요하다면 저의 현업에 방해가 되지 않는 선에서 협의가능합니다.