Kubernetes: Cannot VolumeMount emptydir within init container - kubernetes

I am trying to make use of amazon/aws-cli docker image for downloading all files from s3 bucket through initcontainer and mount the same volume to the main container.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test-deployment
name: test-deployment
spec:
replicas: 1
selector:
matchLabels:
app: test-deployment
template:
metadata:
labels:
app: test-deployment
spec:
securityContext:
fsGroup: 2000
serviceAccountName: "s3-sa" #Name of the SA we ‘re using
automountServiceAccountToken: true
initContainers:
- name: data-extension
image: amazon/aws-cli
volumeMounts:
- name: data
mountPath: /data
command:
- aws s3 sync s3://some-bucket/ /data
containers:
- image: amazon/aws-cli
name: aws
command: ["sleep","10000"]
volumeMounts:
- name: data
mountPath: "/data"
volumes:
- name: data
emptyDir: {}
But it does not seems working. It is causing init container to crashbackloop.
error:
Error: failed to start container "data-extension": Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "aws s3 sync s3://some-bucket/ /data": stat aws s3 sync s3://some-bucket/ /data: no such file or directory: unknown

Your command needs update:
...
command:
- "aws"
- "s3"
- "sync"
- "s3://some-bucket/"
- "/data"
...

Related

deploying wazuh-manager and replace ossec.conf after pods running - kubernetes

I'm deploying wazuh-manager on my kubernetes cluster and I need to disabled some security check features from the ossec.conf and I'm trying to copy the config-map ossec.conf(my setup) with the one from the wazuh-manager image but if I'm creating the "volume mount" on /var/ossec/etc/ossec.conf" it will delete everything from the /var/ossec/etc/(when wazuh-manager pods is deployed it will copy all files that this manager needs).
So, I'm thinking to create a new volume mount "/wazuh/ossec.conf" with "lifecycle poststart sleep > exec command "cp /wazuh/ossec.conf > /var/ossec/etc/ " but I'm getting an error that "cannot find /var/ossec/etc/".
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: wazuh-manager
labels:
node-type: master
spec:
replicas: 1
selector:
matchLabels:
appComponent: wazuh-manager
node-type: master
serviceName: wazuh
template:
metadata:
labels:
appComponent: wazuh-manager
node-type: master
name: wazuh-manager
spec:
volumes:
- name: ossec-conf
configMap:
name: ossec-config
containers:
- name: wazuh-manager
image: wazuh-manager4.8
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "cp /wazuh/ossec.conf >/var/ossec/etc/ossec.conf"]
resources:
securityContext:
capabilities:
add: ["SYS_CHROOT"]
volumeMounts:
- name: ossec-conf
mountPath: /wazuh/ossec.conf
subPath: master.conf
readOnly: true
ports:
- containerPort: 8855
name: registration
volumeClaimTemplates:
- metadata:
name: wazuh-disk
spec:
accessModes: ReadWriteOnce
storageClassName: wazuh-csi-disk
resources:
requests:
storage: 50
error:
$ kubectl get pods -n wazuh
wazuh-1670333556-0 0/1 PostStartHookError: command '/bin/sh -c cp /wazuh/ossec.conf > /var/ossec/etc/ossec.conf' exited with 1: /bin/sh: /var/ossec/etc/ossec.conf: No such file or directory...
Within the wazuh-kubernetes repository you have a file for each of the Wazuh manager cluster nodes:
wazuh/wazuh_managers/wazuh_conf/master.conf for the Wazuh Manager master node.
wazuh/wazuh_managers/wazuh_conf/worker.conf for the Wazuh Manager worker node.
With these files, in the Kustomization.yml script, configmaps are created:
configMapGenerator:
-name: indexer-conf
files:
- indexer_stack/wazuh-indexer/indexer_conf/opensearch.yml
- indexer_stack/wazuh-indexer/indexer_conf/internal_users.yml
-name: wazuh-conf
files:
-wazuh_managers/wazuh_conf/master.conf
-wazuh_managers/wazuh_conf/worker.conf
-name: dashboard-conf
files:
- indexer_stack/wazuh-dashboard/dashboard_conf/opensearch_dashboards.yml
Then, in the deployment manifest, they are mounted to persist the configurations in the ossec.conf file of each cluster node:
wazuh/wazuh_managers/wazuh-master-sts.yaml:
...
specification:
volumes:
-name:config
configMap:
name: wazuh-conf
...
volumeMounts:
-name:config
mountPath: /wazuh-config-mount/etc/ossec.conf
subPath: master.conf
...
It should be noted that the configuration files that you need to copy into the /var/ossec/ directory must be mounted on the /wazuh-config-mount/ directory and then the Wazuh Manager image entrypoint takes care of copying it to its location at the start of the container. As an example, the configmap is mounted to /wazuh-config-mount/etc/ossec.conf and then copied to /var/ossec/etc/ossec.conf at startup.

container level securityContext fsGroup

I'm trying to play with single pod multi container scenario.
The problem is one of my container (directus) is a node app that run as user 'node' with uid 1000
First try, I use hostpath as storage back end. With this, I need to change the host's directory mode with chmod manualy.
Now, I'm trying using longhorn.
And basicaly I don't want to change a host directory mod/ownership each time i deploy this deployment.
Here is my manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: lh-directus
namespace: lh-directus
spec:
replicas: 1
selector:
matchLabels:
app: lh-directus
template:
metadata:
labels:
app: lh-directus
spec:
nodeSelector:
kubernetes.io/os: linux
isGeneralDeployment: "true"
volumes:
- name: lh-directus-uploads-volume
persistentVolumeClaim:
claimName: lh-directus-uploads-pvc
- name: lh-directus-dbdata-volume
persistentVolumeClaim:
claimName: lh-directus-dbdata-pvc
containers:
# Redis Cache
- name: redis
image: redis:6
# Database
- name: database
image: postgres:12
volumeMounts:
- name: lh-directus-dbdata-volume
mountPath: /var/lib/postgresql/data
# Directus
- name: directus
image: directus/directus:latest
securityContext:
fsGroup: 1000
volumeMounts:
- name: lh-directus-uploads-volume
mountPath: /directus/uploads
When I Appy the manifest, I got error
error: error validating "lh-directus.yaml": error validating data: ValidationError(Deployment.spec.template.spec.containers[2].securityContext): unknown field "fsGroup" in io.k8s.api.core.v1.SecurityContext; if you choose to ignore these errors, turn validation off with --validate=false
I reads about initContainer ....
But Kindly please tell me how to fix this problem without initContainer and without manualy set/change host's path ownership/mod.
Sincerely
-bino-

How to concatenate secret files mounted in a volume in kubernetes

I have several secrets that are mounted and need to be read as a properties file. It seems kubernetes can't mount them as a single file so I'm trying to concatenate the files after the pod starts. I tried running a cat command in a postStart handler but it seems execute before the secrets are mounted as I get this error:
Error: failed to create containerd task: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "cat /properties/S3Secret /properties/S3Key >> /properties/dbPassword": stat cat /properties/S3Secret /properties/S3Key >> /properties/dbPassword: no such file or directory: unknown
Then here is the yaml.
apiVersion: apps/v1
kind: Deployment
metadata:
name: K8S_ID
spec:
selector:
matchLabels:
app: K8S_ID
replicas: 1
template:
metadata:
labels:
app: K8S_ID
spec:
containers:
- name: K8S_ID
image: IMAGE_NAME
ports:
- containerPort: 8080
env:
- name: PROPERTIES_FILE
value: "/properties/dbPassword"
volumeMounts:
- name: secret-properties
mountPath: "/properties"
lifecycle:
postStart:
exec:
command: ["cat /properties/S3Secret /properties/S3Key >> /properties/dbPassword"]
volumes:
- name: secret-properties
secret:
secretName: secret-properties
items:
- key: SECRET_ITEM
path: dbPassword
- key: S3Key
path: S3Key
- key: S3Secret
path: S3Secret
You need a shell session for your command like this:
...
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","cat /properties/S3Secret /properties/S3Key >> /properties/dbPassword"]
...

HDFS Namenode format issue with AWS EBS in EKS cluster

I have EKS cluster with EBS storage class/volume. I have elasticsearch cluster running fine with this EBS storage (as persistent volume/pvc).
I am trying to deploy hdfs namenode image (bde2020/hadoop-namenode) using statefulset, but it gives me below error always:
2020-05-09 08:59:02,400 INFO util.GSet: capacity = 2^15 = 32768 entries
2020-05-09 08:59:02,415 INFO common.Storage: Lock on /hadoop/dfs/name/in_use.lock acquired by nodename 87#hdfs-name-0.hdfs-name.pulse.svc.cluster.local
2020-05-09 08:59:02,417 WARN namenode.FSNamesystem: Encountered exception loading fsimage
java.io.IOException: NameNode is not formatted.
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:252)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFSImage(FSNamesystem.java:1105)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:720)
at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:648)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:710)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:953)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:926)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1692)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1759)
I checked run.sh of this iameg and it does seem to be formatting namenode if dir is empty. But this does not work in may case (with EBS as PVC). Any help would be very appreciated.
My deployment yml is:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: hdfs-name
labels:
component: hdfs-name
spec:
serviceName: hdfs-name
replicas: 1
selector:
matchLabels:
component: hdfs-name
template:
metadata:
labels:
component: hdfs-name
spec:
containers:
- name: hdfs-name
image: bde2020/hadoop-namenode
env:
- name: CLUSTER_NAME
value: hdfs-k8s
ports:
- containerPort: 8020
name: nn-rpc
- containerPort: 50070
name: nn-web
volumeMounts:
- name: hdfs-name-pv-claim
mountPath: /hadoop/dfs/name
volumeClaimTemplates:
- metadata:
name: hdfs-name-pv-claim
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: ebs
resources:
requests:
storage: 1Gi
With ebs storage class, lost+found folder is created automatically. Due to this, namenode format does not occur.
Having initcontainer to delete the lost+found folder seems to work.
initContainers:
- name: delete-lost-found
image: busybox
command: ["sh", "-c", "rm -rf /hadoop/dfs/name/lost+found"]
volumeMounts:
- name: hdfs-name-pv-claim
mountPath: /hadoop/dfs/name

k8s initContainer mountPath does not exist after kubectl pod deployment

Below is deployment yaml, after deployment, I could access the pod
and I can see the mountPath "/usr/share/nginx/html", but I could not find
"/work-dir" which should be created by initContainer.
Could someone explain me the reason?
Thanks and Rgds
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: workdir
mountPath: /usr/share/nginx/html
# These containers are run during pod initialization
initContainers:
- name: install
image: busybox
command:
- wget
- "-O"
- "/work-dir/index.html"
- http://kubernetes.io
volumeMounts:
- name: workdir
mountPath: "/work-dir"
dnsPolicy: Default
volumes:
- name: workdir
emptyDir: {}
The volume at "/work-dir" is mounted by the init container and the "/work-dir" location only exists in the init container. When the init container completes, its file system is gone so the "/work-dir" directory in that init container is "gone". The application (nginx) container mounts the same volume, too, (albeit at a different location) providing mechanism for the two containers to share its content.
Per the docs:
Init containers can run with a different view of the filesystem than
app containers in the same Pod.
The volume mount with a PVC allows you to share the contents of /work-dir/ and /use/share/nginx/html/ but it does not mean the nginx container will have the /work-dir folder. Given this, you may think that you could just mount the path / which would allow you to share all folders underneath. However, a mountPath does not work for /.
So, how do you solve your problem? You could have another pod mount /work-dir/ in case you actually need the folder. Here is an example (pvc and deployment with mounts):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-fs-pvc
namespace: default
labels:
mojix.service: default-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: shared-fs
labels:
mojix.service: shared-fs
spec:
replicas: 1
selector:
matchLabels:
mojix.service: shared-fs
template:
metadata:
creationTimestamp: null
labels:
mojix.service: shared-fs
spec:
terminationGracePeriodSeconds: 3
containers:
- name: nginx-c
image: nginx:latest
volumeMounts:
- name: shared-fs-volume
mountPath: /var/www/static/
- name: alpine-c
image: alpine:latest
command: ["/bin/sleep", "10000s"]
lifecycle:
postStart:
exec:
command: ["/bin/mkdir", "-p", "/work-dir"]
volumeMounts:
- name: shared-fs-volume
mountPath: /work-dir/
volumes:
- name: shared-fs-volume
persistentVolumeClaim:
claimName: shared-fs-pvc