I came across Skaffold, trying to streamline local Docker image development. We basically want to be able to quickly iterate on an image and deploy it using an existing stable helm chart version.
In the documentation it says:
https://github.com/GoogleContainerTools/skaffold#installation
- Docker image registry. Your docker client should be configured to push to an external docker image repository. If you're using a minikube or Docker for Desktop cluster, you can skip this requirement.
However, when I'm trying to run the example examples/helm-deployment
it actually tries to connect to a registry:
$ skaffold dev
...
The push refers to repository [docker.io/library/skaffold-helm]
b3fb485368bf: Preparing
6f67560e4591: Preparing
d626a8ad97a1: Preparing
WARN[0012] run: build: build step: running push: denied: requested access to the resource is denied
Do I always need a registry, even using Minikube and Skaffold?
With skaffold, you don't need any registry if you want to deploy to minikube. By default, it seamlessly puts the image to minikube without any external registry involved.
Consider the following deployment.yaml
file:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: petstore-frontend
labels:
app: petstore
tier: frontend
spec:
replicas: 1
selector:
matchLabels:
app: petstore
tier: frontend
template:
metadata:
labels:
app: foo
tier: frontend
spec:
containers:
- name: frontend
image: petstore/frontend
imagePullPolicy: Always
ports:
- containerPort: 80
Note that image
field does not contain any tag, because skaffold will inject one for you.
The minimal skaffold.yaml
file would look like this:
apiVersion: skaffold/v1alpha2
kind: Config
profiles:
- name: minikube
build:
artifacts:
- imageName: petstore/frontend
deploy:
manifests:
- deployment.yaml
Here, imageName
should match the image
field value from deployment.yaml
file.
Now you can just run skaffold run -p minikube
and it will build your image, put it to minikube and apply the deployment.
However, when deploying via Helm charts, there are the small but important things you also need to specify.
Consider the following deployment.yaml
template (I've omited some fields for brevity):
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: {{ template "petstore-frontend.fullname" . }}
labels:
# <labels>
spec:
replicas: 1
selector:
matchLabels:
# <labels>
template:
metadata:
labels:
# <labels>
spec:
containers:
- name: {{ template "petstore-frontend.name" . }}
image: {{ .Values.image.repository }}{{ if .Values.image.tag }}:{{ .Values.image.tag }}{{ end }}
imagePullPolicy: Always
ports:
- containerPort: 80
It is important to have a possibility to specify image without any tag, so skaffold can inject it for you.
Then a skaffold.yaml
file would look like this:
apiVersion: skaffold/v1alpha2
kind: Config
profiles:
- name: minikube
build:
artifacts:
- imageName: petstore/frontend
deploy:
helm:
releases:
- name: petstore-frontend
chartPath: charts/petstore-frontend
values:
"image.repository": petstore/frontend
setValues:
"image.tag": ""
Here, image.repository
should be exactly the same as imageName
in artifacts
section, and also image.tag
is set an empty string to, as it was said above, allow skaffold to inject it.
In conclusion, it is worth to mention that skaffold is still in alpha, so the API may change, and maybe that "tricks" won't be needed anymore. Still, skaffold already provides much convenience for rapid application development and deployment.
I hope this helps.
No, you don't need an external registry.
With following command, you should be able to use docker on your host mac/linux machine talking to the docker daemon inside the minikube VM:
eval $(minikube docker-env)
And the image is created in the minikube directly when docker build
.