Kubernetes: Configure Deployment to mount directory from local Kubernetes host? - kubernetes

I need to provide access to the file /var/docker.sock on the Kubernetes host (actually, a GKE instance) to a container running on that host.
To do this I'd like to mount the directory into the container, by configuring the mount in the deployment.yaml for the container deployment.
How would I specify this in the deployment configuration?
Here is the current configuration, I have for the deployment:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: appd-sa-agent
spec:
replicas: 1
template:
metadata:
labels:
run: appd-sa-agent
spec:
containers:
- name: appd-sa-agent
image: docker.io/archbungle/appd-sa-agent:latest
ports:
- containerPort: 443
env:
- name: APPD_HOST
value: "https://graffiti201707132327203.saas.appdynamics.com"
How would I specify mounting the localhost file path to a directory mountpoint on the container?
Thanks!
T.

You need to define a hostPath volume.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: appd-sa-agent
spec:
replicas: 1
template:
metadata:
labels:
run: appd-sa-agent
spec:
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
containers:
- name: appd-sa-agent
image: docker.io/archbungle/appd-sa-agent:latest
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
ports:
- containerPort: 443
env:
- name: APPD_HOST
value: "https://graffiti201707132327203.saas.appdynamics.com"

you need to use the hostPath option. Here is the sample yaml file.
https://kubernetes.io/docs/concepts/storage/volumes/#hostpath

Related

NFS mount within K8s pods failing

I am trying to get NFS share mounted into a k8s pod but its failing with the below error
mount.nfs: rpc.statd is not running but is required for remote locking. mount.nfs: Either use '-o nolock' to keep locks local, or start statd.
I tried to start rpcbind using CMD command in docker container that also did not work.
My deployment yaml is as below
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
selector:
matchLabels:
app: nfs-client-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-provisioner
- name: NFS_SERVER
value: NFS SERVER PATH
- name: NFS_PATH
value: /filesharepath
volumes:
- name: nfs-client-root
nfs:
server: <NFS IP>
path: /filesharepath
I saw in github that there is an identical issue which says rpcbind needs to be on the base system.
https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/224
Please assist.

kubernetes Deployment PodName setting

apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
labels:
app: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
name: test
labels:
app: test
spec:
containers:
- name: server
image: test_ml_server:2.3
ports:
- containerPort: 8080
volumeMounts:
- name: hostpath-vol-testserver
mountPath: /app/test/api
# env:
# - name: POD_NAME
# valueFrom:
# fieldRef:
# fieldPath: template.metadata.name
- name: testdb
image: test_db:1.4
ports:
- name: testdb
containerPort: 1433
volumeMounts:
- name: hostpath-vol-testdb
mountPath: /var/opt/mssql/data
# env:
# - name: POD_NAME
# valueFrom:
# fieldRef:
# fieldPath: template.metadata.name
volumes:
- name: hostpath-vol-testserver
hostPath:
path: /usr/testhostpath/testserver
- name: hostpath-vol-testdb
hostPath:
path: /usr/testhostpath/testdb
I want to set the name of the pod Because it communicates internally based on the name of the pod
but when a pod is created, it cannot be used because the variable name is appended to the end.
How can I set the pod name?
It's better if you use, statefulset instead of deployment. Statefulset's pod name will be like <statefulsetName-0>,<statefulsetName-1>... And you will need a clusterIP service. with which you can bound your pods. see the doc for more details. Ref
apiVersion: v1
kind: Service
metadata:
name: test-svc
labels:
app: test
spec:
ports:
- port: 8080
name: web
clusterIP: None
selector:
app: test
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: test-StatefulSet
labels:
app: test
spec:
replicas: 1
serviceName: test-svc
selector:
matchLabels:
app: test
template:
metadata:
name: test
labels:
app: test
spec:
containers:
- name: server
image: test_ml_server:2.3
ports:
- containerPort: 8080
volumeMounts:
- name: hostpath-vol-testserver
mountPath: /app/test/api
- name: testdb
image: test_db:1.4
ports:
- name: testdb
containerPort: 1433
volumeMounts:
- name: hostpath-vol-testdb
mountPath: /var/opt/mssql/data
volumes:
- name: hostpath-vol-testserver
hostPath:
path: /usr/testhostpath/testserver
- name: hostpath-vol-testdb
hostPath:
path: /usr/testhostpath/testdb
Here, The pod name will be like this test-StatefulSet-0.
if you are using the kind: Deployment it won't be possible ideally in this scenario you can use kind: Statefulset.
Instead of POD to POD communication, you can use the Kubernetes service for communication.
Still, statefulset manage the pod name in the sequence
statefulsetname - 0
statefulsetname - 1
statefulsetname - 2
You can't.
It is the property of the pods of a Deployment that they do not have an identity associated with them.
You could have a look at Statefulset instead of a Deployment if you want the pods to have a state.
From the docs:
Like a Deployment, a StatefulSet manages Pods that are based on an
identical container spec. Unlike a Deployment, a StatefulSet maintains
a sticky identity for each of their Pods. These pods are created from
the same spec, but are not interchangeable: each has a persistent
identifier that it maintains across any rescheduling.
So, if you have a Statefulset object named myapp with two replicas, the pods will be named as myapp-0 and myapp-1.

How can I mount a docker config file with Skaffold?

I want to use the Prometheus image to deploy a container as part of the local deployment. Usually one has to run the container with volume and bind-mount to get the configuration file (prometheus.yml) into the container:
docker run \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
How can I achieve this with Kubernetes when using Skaffold?
Your Kubernetes configuration will be something like this,
You can specify the port number and volume mounts. The important sections for mounting are volumeMounts and volumes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-prom
spec:
selector:
matchLabels:
app: my-prom
template:
metadata:
labels:
app: my-prom
spec:
containers:
- name: my-prom
image: prometheus:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 9090
volumeMounts:
- name: prom-config
mountPath: /path/to/prometheus.yml
volumes:
- name: prom-config
hostPath:
path: /etc/prometheus/prometheus.yml
---
apiVersion: v1
kind: Service
metadata:
name: my-prom
spec:
selector:
app: my-prom
ports:
- port: 9090
targetPort: 9090
save the Kubernetes config file in a folder and add below config to skaffold.yaml with the path to K8s config file,
deploy:
kubectl:
manifests:
- k8s/*.yaml

unable to mount a specific directory from couchdb pod kubernetes

Hi I am trying to mount a directory from pod where couchdb is running . directory is /opt/couchdb/data and for mounting in kubernetes I am using this config for deployment .
apiVersion: v1
kind: Service
metadata:
name: couchdb0-peer0org1
spec:
ports:
- port: 5984
targetPort: 5984
type: NodePort
selector:
app: couchdb0-peer0org1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: couchdb0-peer0org1
spec:
selector:
matchLabels:
app: couchdb0-peer0org1
strategy:
type: Recreate
template:
metadata:
labels:
app: couchdb0-peer0org1
spec:
containers:
- image: hyperledger/fabric-couchdb
imagePullPolicy: IfNotPresent
name: couchdb0
env:
- name: COUCHDB_USER
value: admin
- name: COUCHDB_PASSWORD
value: admin
ports:
- containerPort: 5984
name: couchdb0
volumeMounts:
- name: datacouchdbpeer0org1
mountPath: /opt/couchdb/data
subPath: couchdb0
volumes:
- name: datacouchdbpeer0org1
persistentVolumeClaim:
claimName: worker1-incoming-volumeclaim
so by applying this deployments . I always gets result for the pods .
couchdb0-peer0org1-b89b984cf-7gjfq 0/1 CrashLoopBackOff 1 9s
couchdb0-peer0org2-86f558f6bb-jzrwf 0/1 CrashLoopBackOff 1 9s
But now the strange thing if I changed mounted directory from /opt/couchdb/data to /var/lib/couchdb then it works fine . But the issue is that I have to store the data for couchdb database in statefull manner .
Edit your /etc/exports with following content
"path/exported/directory *(rw,sync,no_subtree_check,no_root_squash)"
and then restart NFS server:
sudo /etc/init.d/nfs-kernel-server restart*
no_root_squash is used, remote root users are able to change any file on the shared file. This a quick solution but have some security concerns

Kubernetes unknown field "volumes"

I am trying to deploy a simple nginx in kubernetes using hostvolumes. I use the next yaml:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: webserver
spec:
replicas: 1
template:
metadata:
labels:
app: webserver
spec:
containers:
- name: webserver
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: hostvol
mountPath: /usr/share/nginx/html
volumes:
- name: hostvol
hostPath:
path: /home/docker/vol
When I deploy it kubectl create -f webserver.yaml, it throws the next error:
error: error validating "webserver.yaml": error validating data: ValidationError(Deployment.spec.template): unknown field "volumes" in io.k8s.api.core.v1.PodTemplateSpec; if you choose to ignore these errors, turn validation off with --validate=false
I believe you have the wrong indentation. The volumes key should be at the same level as containers.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: webserver
spec:
replicas: 1
template:
metadata:
labels:
app: webserver
spec:
containers:
- name: webserver
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: hostvol
mountPath: /usr/share/nginx/html
volumes:
- name: hostvol
hostPath:
path: /home/docker/vol
Look at this wordpress example from the documentation to see how it's done.