Kustomize traverses a Kubernetes manifest to add, remove or update configuration options without forking. It is available both as a standalone binary and as a native feature of
https://kustomize.io/kubectl
.
Install
https://kubectl.docs.kubernetes.io/installation/kustomize/
Option 1 – homebrew
brew install kustomize
Option 2
https://github.com/kubernetes-sigs/kustomize/releases
wget https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv4.5.5/kustomize_v4.5.5_linux_amd64.tar.gz
tar zxf kustomize_v4.5.5_linux_amd64.tar.gz
rm kustomize_v4.5.5_linux_amd64.tar.gz
sudo mv kustomize /usr/local/bin
Alias
vi ~/.zshrc alias
ku="/usr/local/bin/kustomize"
source ~/.zshrc
Basic Demo
Create kustomize-demo directory.
mkdir kustomize-demo && cd kustomize-demo
Create deployment.
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
EOF
Create a new kustomization detecting and adding all resources within the current directory.
kustomize create --autodetect
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
Build.
Nothing has changed.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
Add namespace.
kustomize edit set namespace itsmetommy
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
namespace: itsmetommy
Build.
Namespace is added.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: itsmetommy
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
Add label.
kustomize edit set label env:dev
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
namespace: itsmetommy
commonLabels:
env: dev
Build.
Label added.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: dev
name: nginx
namespace: itsmetommy
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: dev
template:
metadata:
labels:
app: nginx
env: dev
spec:
containers:
- image: nginx
name: nginx
Add image.
kustomize edit set image nginx=nginx:1.21.6
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
namespace: itsmetommy
commonLabels:
env: dev
images:
- name: nginx
newName: nginx
newTag: 1.21.6
Build.
Image added.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: dev
name: nginx
namespace: itsmetommy
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: dev
template:
metadata:
labels:
app: nginx
env: dev
spec:
containers:
- image: nginx:1.21.6
name: nginx
Create deployment.
# Option 1 - use kustomize
kustomize build | kubectl apply -f -
# Option 2 - use kubectl
kubectl apply -k .
Clean up.
# Option 1 - use kustomize
kustomize build | kubectl delete -f -
# Option 2 - use kubectl
kubectl delete -k .
Standard Structure
Feel free to clone the git repo.
git clone https://github.com/itsmetommy/kustomize.git
Create a kustomize structure with best practices in mind using a base and overlays directory.
Create directories.
{
mkdir -p kustomize-demo-best-practices/base
mkdir kustomize-demo-best-practices/overlays
mkdir kustomize-demo-best-practices/overlays/dev
mkdir kustomize-demo-best-practices/overlays/prod
mkdir kustomize-demo-best-practices/overlays/staging
cd kustomize-demo-best-practices/base
}
Create base files.
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
EOF
Create a new kustomization detecting and adding all resources within the current directory.
kustomize create --autodetect
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
Build.
Nothing has changed.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
cd into the overlays/dev directory.
cd ../overlays/dev
Create kustomization.yaml and include all files within the base directory.
Technically, you can create the kustomization.yaml file manually, but I am using kustomize commands so that you better understand your options.
kustomize create --resources ../../base
Add label env: dev.
kustomize edit set label env:dev
Add namesuffix.
kustomize edit set namesuffix -- -dev
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
commonLabels:
env: dev
nameSuffix: -dev
Build.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: dev
name: nginx-dev
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: dev
template:
metadata:
labels:
app: nginx
env: dev
spec:
containers:
- image: nginx
cd into the overlays/prod directory.
cd ../prod
Create kustomization.yaml and include all files within the base directory.
kustomize create --resources ../../base
Add label env: prod.
kustomize edit set label env:prod
Add namesuffix.
kustomize edit set namesuffix -- -prod
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
commonLabels:
env: prod
nameSuffix: -prod
Build.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: prod
name: nginx-prod
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: prod
template:
metadata:
labels:
app: nginx
env: prod
spec:
containers:
- image: nginx
name: nginx
cd into the overlays/staging directory.
cd ../staging
Create kustomization.yaml and include all files within the base directory.
kustomize create --resources ../../base
Add label env: staging.
kustomize edit set label env:staging
Add namesuffix.
kustomize edit set namesuffix -- -staging
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
commonLabels:
env: staging
nameSuffix: -staging
Build.
kustomize build
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: staging
name: nginx-staging
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: staging
template:
metadata:
labels:
app: nginx
env: staging
spec:
containers:
- image: nginx
name: nginx
cd back into the main directory.
cd ../..
Build each environment from the base directory.
kustomize build overlays/dev
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: dev
name: nginx-dev
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: dev
template:
metadata:
labels:
app: nginx
env: dev
spec:
containers:
- image: nginx
name: nginx
kustomize build overlays/prod
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: prod
name: nginx-prod
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: prod
template:
metadata:
labels:
app: nginx
env: prod
spec:
containers:
- image: nginx
name: nginx
kustomize build overlays/staging
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: staging
name: nginx-staging
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: staging
template:
metadata:
labels:
app: nginx
env: staging
spec:
containers:
- image: nginx
name: nginx
Add service.yaml to the base kustomization.yaml file.
cd base
Create a base service.
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- port: 80
protocol: TCP
targetPort: 80
EOF
kustomize edit add resource service.yaml
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
Add service-patch.yaml to each environment.
cd ..
Create a dev service with a ClusterIP.
cat <<EOF > overlays/dev/service-patch.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
EOF
Create a prod service with a LoadBalancer.
cat <<EOF > overlays/prod/service-patch.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
type: LoadBalancer
EOF
Create a staging service with a NodePort.
cat <<EOF > overlays/staging/service-patch.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
protocol: TCP
nodePort: 30080
targetPort: 80
type: NodePort
EOF
Add service-patch.yaml within patches to each kustomization.yaml file per environment.
cat <<EOF >> overlays/dev/kustomization.yaml
patches:
- service-patch.yaml
EOF
cat <<EOF >> overlays/prod/kustomization.yaml
patches:
- service-patch.yaml
EOF
cat <<EOF >> overlays/staging/kustomization.yaml
patches:
- service-patch.yaml
EOF
Build each environment.
kustomize build overlays/dev
apiVersion: v1
kind: Service
metadata:
labels:
env: dev
name: nginx-dev
spec:
selector:
env: dev
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: dev
name: nginx-dev
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: dev
template:
metadata:
labels:
app: nginx
env: dev
spec:
containers:
- image: nginx
name: nginx
kustomize build overlays/prod
apiVersion: v1
kind: Service
metadata:
labels:
env: prod
name: nginx-prod
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
env: prod
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: prod
name: nginx-prod
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: prod
template:
metadata:
labels:
app: nginx
env: prod
spec:
containers:
- image: nginx
name: nginx
kustomize build overlays/staging
apiVersion: v1
kind: Service
metadata:
labels:
env: staging
name: nginx-staging
spec:
ports:
- nodePort: 30080
port: 80
protocol: TCP
targetPort: 80
selector:
env: staging
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: staging
name: nginx-staging
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: staging
template:
metadata:
labels:
app: nginx
env: staging
spec:
containers:
- image: nginx
name: nginx
From here, you can apply whichever environment you want.
{
kustomize build overlays/dev | kubectl apply -f -
kustomize build overlays/prod | kubectl apply -f -
kustomize build overlays/staging | kubectl apply -f -
}
kubectl get svc,deploy -l app=nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx-dev ClusterIP 10.96.196.237 <none> 80/TCP 33s
service/nginx-prod LoadBalancer 10.111.58.56 localhost 80:31018/TCP 61m
service/nginx-staging NodePort 10.96.11.203 <none> 80:30080/TCP 61m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-dev 1/1 1 1 61m
deployment.apps/nginx-prod 1/1 1 1 61m
deployment.apps/nginx-staging 1/1 1 1 61m
Directory tree.
tree
.
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── dev
│ ├── kustomization.yaml
│ └── service-patch.yaml
├── prod
│ ├── kustomization.yaml
│ └── service-patch.yaml
└── staging
├── kustomization.yaml
└── service-patch.yaml
5 directories, 9 files
Clean up.
{
kustomize build overlays/dev | kubectl delete -f -
kustomize build overlays/prod | kubectl delete -f -
kustomize build overlays/staging | kubectl delete -f -
}
There’s more to kustomize, but this should get you started.
e.g.
Create a kustomization.yaml file with the basic apiVersion and kind.
kustomize init
cat kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
Different ways to deploy.
# Option 1 - use kustomize
kustomize build | kubectl apply -f -
# Option 2 - use kubectl
kubectl apply -k .