본 가이드는 jsonnet 핵심 가이드 및 실전 아키텍처의 핵심 개념, 실전 구성 명령어 및 아키텍처 베스트 프랙티스를 다룹니다. 클라우드 네이티브 및 인프라 엔지니어링 실무에 즉시 활용 가능하도록 체계적으로 정리했습니다.
📑 Table of Contents
Installation
jsonnet(c build or go build)jsonnet bundler— package manager
brew install jsonnet jsonnet-bundler
Set up
# initiate the package manager
jb init
# >> this will create jsonnetfile.json in your repository
# install k8s jsonnet lib
jb install github.com/jsonnet-libs/k8s-libsonnet/1.32@main
# after that you can use `jb install` to install all libs from jsonnetfile.json
your jsonnetfile.json should look like this
{
"version": 1,
"dependencies": [
{
"source": {
"git": {
"remote": "https://github.com/jsonnet-libs/k8s-libsonnet.git",
"subdir": "1.32" #kubernetes version (lib version)
}
},
"version": "main"
}
],
"legacyImports": true
}
and you will also have a new folder named vendor .
run it
you can use jsonnet to generate json output from jsonnet file
create hello.jsonnet file
// hello.jsonnet
{
hello: "jsonnet" // << jsonnet key doesn't have double quote ""
}
the run jsonnet hello.jsonnet , you will get
{
"hello": "jsonnet"
}
next, we will try using k8s jsonnet lib.
Get Supakorn Warodom’s stories in your inbox
Join Medium for free to get updates from this writer.
create deploy.jsonnet file
local k = import "github.com/jsonnet-libs/k8s-libsonnet/1.32/main.libsonnet";
k.apps.v1.deployment.new("hello-deployment", replicas=1, containers=[], podLabels={})
to generate the json output, you will have to use this command
jsonnet -J vendor deploy.jsonnet
# jsonnet -J <LibDirectory> <file>
# result
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "hello-deployment"
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"name": "hello-deployment"
}
},
"template": {
"metadata": {
"labels": {
"name": "hello-deployment"
}
},
"spec": {
"containers": [ ]
}
}
}
}
Merge syntax
basic
use + to merge jsonnet’s object.
let’s use ‘+’ to add labels.app: “hello” to metadata, spec.selector.matchLabels and spec.template.metadata
// deploy-merge.jsonnet
local k = import "github.com/jsonnet-libs/k8s-libsonnet/1.32/main.libsonnet";
k.apps.v1.deployment.new("hello-deployment", replicas=1, containers=[], podLabels={})
+{metadata: {
name: "hello-deployment",
labels: {app: "hello"}}}
+{spec: {
selector: {matchLabels: {app: "hello"}},
template: {metadata: {labels: {app: "hello"}}},
}}
the result will look like this
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"labels": {
"app": "hello"
},
"name": "hello-deployment"
},
"spec": {
"selector": {
"matchLabels": {
"app": "hello"
}
},
"template": {
"metadata": {
"labels": {
"app": "hello"
}
}
}
}
}
look carefully and you will see that spec.replicas and spec.template.spec is gone.
This is where you will need to use nested merge operator.
nested merge
the operator is +: .
// deploy-merge-nested.jsonnet
local k = import "github.com/jsonnet-libs/k8s-libsonnet/1.32/main.libsonnet";
k.apps.v1.deployment.new("hello-deployment", replicas=1, containers=[], podLabels={})
+{metadata+: {
// don't need to put `name: "hello-deployment"` here anymore
labels+: {app: "hello"}}}
+{spec+: {
selector+: {matchLabels+: {app: "hello"}},
template+: {metadata+: {labels+: {app: "hello"}}},
}}
result
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"labels": {
"app": "hello"
},
"name": "hello-deployment"
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app": "hello",
"name": "hello-deployment"
}
},
"template": {
"metadata": {
"labels": {
"app": "hello",
"name": "hello-deployment"
}
},
"spec": {
"containers": [ ]
}
}
}
}
k8s 라이브러리를 사용해서도 같은 작업을 할 수 있습니다. (제 생각에는) 대부분의 k8s 라이브러리 함수는 중첩 병합(nested merge) 연산자로 구현되어 있습니다.
Enter 키를 누르거나 이미지를 클릭하여 전체 화면으로 보세요.

그래서 이렇게 다시 쓸 수 있어요
local k = import "github.com/jsonnet-libs/k8s-libsonnet/1.32/main.libsonnet";
k.apps.v1.deployment.new("hello-deployment", replicas=1, containers=[], podLabels={})
+k.apps.v1.deployment.metadata.withNamespace("api")
+k.apps.v1.deployment.metadata.withLabels({app:"hello"})
+k.apps.v1.deployment.spec.selector.withMatchLabels({app:"hello"})
+k.apps.v1.deployment.spec.template.metadata.withLabels({app:"hello"})
Leave a Reply