How to mount a host volume in Kubernetes running on Docker Desktop (Windows 10) backed by WSL2? - windows

I've figured out the syntax to mount a volume (Kubernetes YAML):
apiVersion: v1
kind: Pod
metadata:
...
spec:
containers:
- name: php
volumeMounts:
- mountPath: /app/db_backups
name: db-backups
readOnly: true
volumes:
- hostPath:
path: /mnt/c/Users/Mark/PhpstormProjects/proj/db_backups
type: DirectoryOrCreate
name: db-backups
And the volume does show when I drop into a shell:
kubectl --context docker-desktop exec --stdin --tty deploy/app-deployment-development -cphp -nmyns -- /bin/bash
But the db_backups directory is empty, so I guess the volume is backed by nothing -- it's not finding the volume on my Windows host machine.
I've tried setting the host path like C:\Users\Mark\PhpstormProjects\proj\db_backups but if I do that then my Deployment fails with a CreateContainerError:
Error: Error response from daemon: invalid volume specification: 'C:\Users\Mark\PhpstormProjects\proj\db_backups:/app/db_backups:ro'
So I guess it doesn't like the Windows-style filepath.
So what then? If neither style of path works, how do I get it to mount?

From here it is clear that, for WSL2 we need to mention the specific path before we are actually giving the path we desired in the host machine.
In your file you are giving like path: /mnt/c/Users/Mark/PhpstormProjects/proj/db_backups but you need to mention the path like this path: /run/desktop/mnt/host/path_of_directory_in_local_machine. The key is we need to mention /run/desktop/mnt/host/ before we are going to give the actual path to the directory.
You gave the type: DirectoryOrCreate in the above file, so that is creating an empty directory in the path you mentioned. Because it is not actually going to your desired path.
So try with this
apiVersion: v1
kind: Pod
metadata:
...
spec:
containers:
- name: php
volumeMounts:
- mountPath: /app/db_backups
name: db-backups
readOnly: true
volumes:
- hostPath:
path: /run/desktop/mnt/host/c/Users/Mark/PhpstormProjects/proj/db_backups
#In my case tested with path: /run/desktop/mnt/host/d/K8-files/voldir
type: DirectoryOrCreate
name: db-backups
It worked in our case, we created a directory in 'd' drive so we used this path: /run/desktop/mnt/host/d/K8-files/voldir. So try giving /run/desktop/mnt/host/ before the actual path.
For more information refer this Link

Related

Restart pod without losing changes

I have 2 pods that are meant to send logs to Elastic search. Logs in /var/log/messages get sent but some reason service_name.log doesn't get sent - I think it is due to the configuration for Elastic search. There is a .conf file in these 2 pods that handle the connection to Elastic Search.
I want to make changes to test if this is indeed the issue. I am not sure if the changes take effect as soon as I edit the file. Is there a way to restart/update the pod without losing changes I might make to this file?
To store non-confidential data as a configuration file in a volume, you could use ConfigMaps.
Here is an example of a Pod that mounts a ConfigMap in a volume:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
configMap:
name: myconfigmap

Kubernetes how to correctly mount windows path in wsl2 backed environment

I have a local image that runs fine this way:
docker run -p 8080:8080 -v C:\Users\moritz\Downloads\1\imageService\examples1:/images -v C:\Users\moritz\entwicklung\projekte\imageCluster\logs:/logs imageservice
Now i want this to run as Kubernetes (using built in from Docker-for-Windows v1.19.7) deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: image-service
spec:
selector:
matchLabels:
app: image-service
template:
metadata:
labels:
app: image-service
spec:
containers:
- name: image-service
image: "imageservice"
resources:
limits:
cpu: "0.9"
memory: "1Gi"
ports:
- name: http
containerPort: 8080
volumeMounts:
- mountPath: /images
name: image-volume
- mountPath: /logs
name: log-volume
volumes:
- name: image-volume
hostPath:
path: "c:\\Users\\moritz\\Downloads\\1\\imageService\\examples1"
type: Directory
- name: log-volume
hostPath:
path: /mnt/c/Users/moritz/entwicklung/projekte/imageCluster/logs
type: Directory
As you see i tried different ways to set up my host path on windows machine but i always get:
Warning FailedMount 0s (x4 over 4s) kubelet MountVolume.SetUp failed for volume "log-volume" : hostPath type check failed: /mnt/c/Users/moritz/entwicklung/projekte/imageCluster/logs is not a directory
Warning FailedMount 0s (x4 over 4s) kubelet MountVolume.SetUp failed for volume "image-volume" : hostPath type check failed: c:\Users\moritz\Downloads\1\imageService\examples1 is not a directory
I also tried other variants (for both):
C:\Users\moritz\entwicklung\projekte\imageCluster\logs
C:/Users/moritz/entwicklung/projekte/imageCluster/logs
So how to correctly setup these windows host path. (The next step would be to set them as environment variable.)
Little update:
removing type: Directory helps to get rid of the error and pod is starting but the mounts are not working. If i "look" into container in /images i don't see the images i have on my host and i don't see any logs in log mount while in container /logs contains the expected files.
in meantime i also tried (no avail)
/host_mnt/c/...
/C/Users/...
//C/Users/...
As mentioned here, you can use below hostPath to make it work on wsl2.
// C:\someDir\volumeDir
hostPath:
path: /run/desktop/mnt/host/c/someDir/volumeDir
type: DirectoryOrCreate
There is also an example you can use.
apiVersion: v1
kind: Pod
metadata:
name: test-localpc
spec:
containers:
- name: test-webserver
image: ubuntu:latest
command: ["/bin/sh"]
args: ["-c", "apt-get update && apt-get install curl -y && sleep 600"]
volumeMounts:
- mountPath: /run/desktop/mnt/host/c/aaa
name: mydir
- mountPath: /run/desktop/mnt/host/c/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Ensure the file directory is created.
path: /run/desktop/mnt/host/c/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /run/desktop/mnt/host/c/aaa/1.txt
type: FileOrCreate

How to mount a volume from Kubernetes on a Windows host to a Linux pod

I am trying to mount a volume within a Kubernetes pod (running linux) to a host folder on Windows 10. The pod starts up without issue, however, the data in the volumes aren't being reflected within the Pod and data set in the Pod isn't being reflected on the Windows host.
Here is my persistent volume:
kind: PersistentVolume
apiVersion: v1
metadata:
name: "elastic-search-persistence"
labels:
volume: persistence
spec:
storageClassName: hostpath
capacity:
storage: 5Gi
accessmodes:
- ReadWriteMany
hostPath:
path: /c/temp/es
Here is my persistent claim:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: "elastic-search-persistence-claim"
spec:
storageClassName: hostpath
volumeName: "elastic-search-persistence"
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
And here is my Pod using the above persistent volumes...
apiVersion: v1
kind: Pod
metadata:
name: windows-volume-demo
spec:
containers:
- name: windows-volume-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: windows-volume-data-storage
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: true
volumes:
- name: windows-volume-data-storage
persistentVolumeClaim:
claimName: elastic-search-persistence-claim
I can start everything fine, however, when I create a file in my C:\temp\es folder on my Windows host, that file doesn't show inside the /data/demo folder in the Pod. And the reverse is also true. When I exec into the Pod and create a file in the /data/demo folder, it doesn't show in the C:\temp\es folder on the Windows host.
The folder/file privileges are wide open for the C:\temp folder and the C:\temp\es folder. I also tried exec-ing into the Pod and changing the write privs for the /data/demo folder to wide open -- all with no success.
This configuration works as expected on a Mac host (changing the volume paths for the host to a Mac folder). I suspect it is a privilege/permissions issue for Windows, but I am at a loss as to how to find/fix it.
Any help would be greatly appreciated.

minikube hostpath mount permissions

I'm trying to mount a local directory to be used by a container in kubernetes, but getting this error:
$ kubectl logs mysql-pd
chown: changing ownership of '/var/lib/mysql/': Input/output error
minikube version: v0.33.1
docker for mac version: 2.0.0.2 (30215)
Engine: 18.09.1
Kubernetes: v1.10.11
I'm starting up minikube with mounted directory:
minikube start --mount-string /Users/foo/mysql_data:/mysql_data --mount
deployment.yml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pd
spec:
containers:
- image: mysql:5.7
name: mysql-container
env:
- name: MYSQL_ROOT_PASSWORD
value: ""
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "yes"
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql"
name: host-mount
volumes:
- name: host-mount
hostPath:
path: "/mysql_data"
As #Matthew L Daniel mentioned in the comments, the main purpose of using hostPath is to mount a local folder from your machine which is hosting minikube inside to the nested Pod, therefore it's not necessary to mount local directory inside to minikube. Also, take a look at this article which explains some restrictions about host folder mounting for the particular VM driver in minikube.

Rebuild and Rerun Go application in Minikube

I'm building a micro service in Golang which is going to live in a Kubernetes cluster. I'm developing it and using Minikube to run a copy of the cluster locally.
The problem I ran into is that if I run my application inside of the container using go run main.go, I need to kill the pod for it to detect changes and update what is running.
I tried using a watcher for the binary so that the binary is updated on every save and a binary is running inside the pod, but even after compiling the new version, minikube is running the old one.
Any suggestion?
Here is my deployment file for running the MS locally:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
name: pokedex
name: pokedex
spec:
template:
metadata:
labels:
name: pokedex
spec:
volumes:
- name: source
hostPath:
path: *folder where source resides*
containers:
- name: pokedex
image: golang:1.8.5-jessie
workingDir: *folder where source resides*
command: ["./pokedex"] # Here I tried both the binary and go run main.go
ports:
- containerPort: 8080
name: go-server
protocol: TCP
volumeMounts:
- name: source
mountPath: /source
env:
- name: GOPATH
value: /source

Resources