March 01, 2021
며칠 전 일이었습니다. 저희 팀은 이전에도 말했던 것처럼 off-the-shelf는 Helm으로 배포하고 있었습니다. 그런데 이번에 Helm과 함께 배포해야만 하는 resource가 생겼습니다. 일종의 extension이라고 생각하시면 좋을 것 같습니다. 이를 해결하기 위해 리드님께서 추가적인 Helm chart를 만드셨고, 값의 유효성을 검증하는 기능을 제게 맡기셨습니다. 저는 template을 아래와 같이 수정하고 기분 좋게 퇴근했습니다.
# 지정한 namespace가 kube-system인 경우 fail하도록 함
{{ if (eq .Values.namespace "kube-system") }}
{{ fail "Invalid namespace" }}
{{ end }}
apiVersion: v1
kind: ConfigMap
...
그리고 다음 날 제 commit은 리드님의 피드백과 함께 역사속으로 사라지게 됩니다. 문제는 무엇이었을까요?
Proposal: chart values schema에서 Helm v3에 들어갈 기능으로 values.schema
가 제안됩니다.
The chart values are pretty free-form, which is nice as it presents a very low barrier to entry. However, it would be nice if chart authors had a means to validate the values against a schema. (…)
이러한 schema는 아래와 같은 형태로 작성됩니다. 여기에서 value의 자료형, 범위 등이 정의됩니다.
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"image": {
"description": "Container Image",
"properties": {
"repo": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"type": "object"
},
"name": {
"description": "Service name",
"type": "string"
},
"port": {
"description": "Port",
"minimum": 0,
"type": "integer"
},
"protocol": {
"type": "string"
}
},
"required": [
"protocol",
"port"
],
"title": "Values",
"type": "object"
}
그리고 이러한 schema는
helm install
helm upgrade
helm lint
helm template
와 같은 명령어를 사용할 때 자동으로 이용되며 유효성을 검증해줍니다.
이렇게 schema를 활용하는 것이 template에서 직접 유효성을 검증하는 방법보다 더 좋은 이유는 다음과 같습니다.
정리하면, 명령적으로 구현하는 것과 선언적으로 구현하는 것의 차이로도 볼 수 있겠습니다.
제가 생각하는 Kubernetes의 가장 큰 장점 중 하나는 바로 ‘선언적’이라는 것입니다. 창세기처럼 ‘Pod이 있을지어다’라고 선언하면 그 과정을 구구절절 설명할 필요 없이 Pod이 하나 생깁니다. Helm v3에서 schema가 생긴 이유도 이와 비슷할 것이라고 생각합니다. ‘필요한 value는 무엇이고, 그 type은 어떠하다’고 schema를 통해 선언하는 것으로 Helm은 value의 존재와 type을 보장합니다.
이번 작업에 앞서 저는 Helm에 schema라는 기능이 있는 지 알지 못하고 있었습니다. 하지만 만약 제가 ‘validation logic을 작성한다’는 작업의 의미에 대해 깊이 고민해봤더라면, 아마 제 스스로 schema에 대한 니즈가 생겼을 것이고 혹시 이런 기능이 있는 지 검색해보고 찾아 사용했을 것입니다. 관성에 매몰되어 일의 본질을 생각하지 못한 점이 이번 작업에서 가장 아쉽습니다. 다음부터는 같은 실수를 반복하지 않도록 신중하게 일의 의미를 생각해보고자 합니다.