Tanka est un outil CLI de configuration Kubernetes développé par Grafana Labs, basé sur Jsonnet. Il organise les manifests Kubernetes en environments (un dossier par environnement cible), chacun défini par un main.jsonnet et un fichier spec.json (URL du cluster). Tanka utilise jb (jsonnet-bundler) comme gestionnaire de paquets Jsonnet. L'approche diffère de Helm (pas de templates Go) et de Kustomize (pas de YAML brut) : Jsonnet est un langage de configuration à part entière, turing-complet, avec imports, fonctions, mixins et bibliothèques réutilisables. Grafana Labs l'utilise en production pour tous ses déploiements.
Informations essentielles
Origine : Grafana Labs · Licence : Apache 2.0 · Architectures : x86_64, ARM64
Liens : Site officiel · Documentation · GitHub · Releases
Support : Maintenu par Grafana Labs. Utilisé en production chez Grafana.
Stack par défaut
| Composant | Valeur |
|---|---|
| Langage | Jsonnet |
| Package manager | jb (jsonnet-bundler) |
| Structure | environments/<env>/main.jsonnet + spec.json |
| Bibliothèques | k8s-libsonnet (bindings K8s), kube-libsonnet, bibliothèques communautaires |
| Commandes | tk apply, tk diff, tk show, tk export |
Prérequis
| Ressource | Valeur |
|---|---|
| kubectl | Configuré avec accès cluster |
| jb | jsonnet-bundler (gestionnaire de paquets Jsonnet) |
Installation
# tk CLI - binaire Linux
TK_VERSION=$(curl -s "https://api.github.com/repos/grafana/tanka/releases/latest" \
| grep '"tag_name"' | sed 's/.*"v\([^"]*\)".*/\1/')
curl -Lo tk "https://github.com/grafana/tanka/releases/download/v${TK_VERSION}/tk-linux-amd64"
chmod +x tk && sudo mv tk /usr/local/bin/
# Homebrew
brew install tanka
# jsonnet-bundler (gestionnaire de paquets)
go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest
tk --version
Initialiser un projet
mkdir my-k8s-config && cd my-k8s-config
# Initialiser le projet Tanka
tk init
# Structure créée :
# ├── environments/
# │ └── default/
# │ ├── main.jsonnet # Point d'entrée
# │ └── spec.json # URL du cluster
# ├── lib/ # Bibliothèques locales
# ├── vendor/ # Bibliothèques importées via jb
# └── jsonnetfile.json # Dépendances (comme package.json)
# Installer les bindings K8s (k8s-libsonnet)
jb install github.com/jsonnet-libs/k8s-libsonnet/1.29@main
Configurer un environment
// environments/production/spec.json
{
"apiVersion": "tanka.dev/v1alpha1",
"kind": "Environment",
"metadata": {
"name": "production"
},
"spec": {
"apiServer": "https://my-cluster.example.com",
"namespace": "production",
"resourceDefaults": {},
"expectVersions": {}
}
}
Écrire des manifests en Jsonnet
// environments/production/main.jsonnet
local k = import 'github.com/jsonnet-libs/k8s-libsonnet/1.29/main.libsonnet';
local deployment = k.apps.v1.deployment;
local container = k.core.v1.container;
local containerPort = k.core.v1.containerPort;
local service = k.core.v1.service;
// Définir un Deployment
local myApp = deployment.new(
name='my-app',
replicas=3,
containers=[
container.new('my-app', 'ghcr.io/org/my-app:1.0.0')
+ container.withPorts([containerPort.newNamed(8080, 'http')])
+ container.resources.withRequests({ cpu: '250m', memory: '256Mi' })
+ container.resources.withLimits({ cpu: '500m', memory: '512Mi' }),
]
);
// Définir un Service
local myService = service.new(
'my-app',
{ app: 'my-app' },
[{ port: 80, targetPort: 8080 }]
);
// Exporter les ressources (Tanka les applique toutes)
{
deployment: myApp,
service: myService,
}
Bibliothèques réutilisables
// lib/webapp.libsonnet - construct réutilisable
local k = import 'github.com/jsonnet-libs/k8s-libsonnet/1.29/main.libsonnet';
{
new(name, image, replicas=2):: {
local deployment = k.apps.v1.deployment,
local container = k.core.v1.container,
deployment: deployment.new(name, replicas, [
container.new(name, image)
+ container.withPorts([{ containerPort: 8080 }])
]),
service: k.core.v1.service.new(
name, { app: name }, [{ port: 80, targetPort: 8080 }]
),
},
}
// environments/production/main.jsonnet
local webapp = import '../../lib/webapp.libsonnet';
{
frontend: webapp.new('frontend', 'ghcr.io/org/frontend:1.0', replicas=3),
backend: webapp.new('backend', 'ghcr.io/org/backend:2.0', replicas=5),
}
Commandes principales
# Prévisualiser les manifests générés (YAML)
tk show environments/production
# Diff entre l'état Git et le cluster
tk diff environments/production
# Appliquer sur le cluster
tk apply environments/production
# Exporter le YAML dans un dossier (pour GitOps pull-based)
tk export dist/ environments/production
# Lister les environments
tk env list
Mise à jour
# Binaire
curl -Lo tk "https://github.com/grafana/tanka/releases/latest/download/tk-linux-amd64"
chmod +x tk && sudo mv tk /usr/local/bin/
# Homebrew
brew upgrade tanka
Troubleshooting
# Erreur de syntaxe Jsonnet
tk show environments/production 2>&1
# Le message d'erreur indique le fichier et la ligne
# Vérifier les imports disponibles
ls vendor/
# Mettre à jour les dépendances jb
jb update
# Diff vide mais apply échoue
# Vérifier les droits RBAC kubectl
# Déboguer la valeur d'une variable Jsonnet
tk eval environments/production -e 'std.extVar("tanka.dev/environment")'
Ressources
- Site officiel : https://tanka.dev
- Documentation : https://tanka.dev/docs/
- GitHub : https://github.com/grafana/tanka
- k8s-libsonnet : https://github.com/jsonnet-libs/k8s-libsonnet
- jsonnet-bundler : https://github.com/jsonnet-bundler/jsonnet-bundler
- Releases : https://github.com/grafana/tanka/releases