Skaffold, by default, leaves your Kubernetes cluster littered with resources every time you stop its dev loop.
Let’s see Skaffold in action, cleaning up after itself. Imagine you have a simple Kubernetes deployment and service managed by Skaffold.
# skaffold.yaml
apiVersion: skaffold/v2beta29
kind: Config
deploy:
kubectl:
manifests:
- k8s/*.yaml
build:
local: {}
profiles:
- name: dev
deploy:
kubectl:
manifests:
- k8s/*.yaml
dev:
sync:
manual: {}
autoDeploy: false
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
ports:
- containerPort: 80
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
When you run skaffold dev --profile dev, Skaffold deploys these resources. Now, if you hit Ctrl+C without any specific cleanup configuration, you’ll find my-app deployment and my-app-service still sitting in your Kubernetes cluster.
To fix this, you need to tell Skaffold how to clean up. This is done within the deploy section of your skaffold.yaml. The key is the cleanup field.
Here’s how you’d configure Skaffold to clean up the resources defined in k8s/*.yaml when the dev loop ends:
# skaffold.yaml
apiVersion: skaffold/v2beta29
kind: Config
deploy:
kubectl:
manifests:
- k8s/*.yaml
# Add this section for cleanup
cleanup:
command: ["kubectl", "delete", "--ignore-not-found", "-f", "k8s/"]
build:
local: {}
profiles:
- name: dev
deploy:
kubectl:
manifests:
- k8s/*.yaml
cleanup:
command: ["kubectl", "delete", "--ignore-not-found", "-f", "k8s/"]
dev:
sync:
manual: {}
autoDeploy: false
Now, when you run skaffold dev --profile dev and then press Ctrl+C, Skaffold will execute the specified kubectl delete command against the files in the k8s/ directory. The --ignore-not-found flag is crucial; it prevents Skaffold from erroring out if a resource it’s trying to delete no longer exists (which can happen in complex scenarios or if you manually deleted something).
This cleanup.command is executed after Skaffold stops its watch and build/deploy loops. It’s a direct instruction to your Kubernetes cluster to remove the resources that Skaffold previously applied. The magic is that Skaffold is simply orchestrating the execution of standard Kubernetes tooling for you, making the development loop cleaner.
The cleanup directive can be more granular. Instead of pointing to a directory, you can specify individual manifests:
# skaffold.yaml
apiVersion: skaffold/v2beta29
kind: Config
deploy:
kubectl:
manifests:
- k8s/deployment.yaml
- k8s/service.yaml
cleanup:
command: ["kubectl", "delete", "--ignore-not-found", "-f", "k8s/deployment.yaml", "-f", "k8s/service.yaml"]
# ... rest of the config
This achieves the same outcome for this simple example but gives you finer control if your manifests list is complex and you only want specific items cleaned up.
You can also use Skaffold’s built-in Helm support for cleanup. If you deploy using Helm, Skaffold can leverage Helm’s uninstall capabilities.
# skaffold.yaml
apiVersion: skaffold/v2beta29
kind: Config
deploy:
helm:
releases:
- name: my-app-release
chartPath: ./charts/my-app
cleanup:
command: ["helm", "uninstall", "my-app-release"]
# ... rest of the config
In this Helm example, Skaffold will execute helm uninstall my-app-release upon exiting the dev loop. This is generally preferred when using Helm as it respects Helm’s release management.
The cleanup mechanism is powerful because it abstracts away the manual kubectl delete or helm uninstall commands. Skaffold tracks what it deployed and can then execute your defined cleanup commands. This is particularly useful in CI/CD pipelines where you might want to deploy ephemeral environments and ensure they are torn down cleanly.
One subtlety is that the cleanup.command is executed in the context of your Skaffold configuration. If you have specific kubeContext or namespace settings in your skaffold.yaml, the cleanup command will run against that context. This ensures that resources are deleted from the correct Kubernetes cluster and namespace without you having to manually specify them in the command itself.
The next thing you’ll likely encounter is managing secrets and configuration maps that Skaffold might also deploy and that you’ll want to clean up, or understanding how to configure different cleanup strategies per profile.