Reading Kube Secrets from Java Program - java

I'm working on a library to read secrets from a given directory that I've got easily up and running with Docker Swarm by using the /run/secrets directory as the defined place to read secrets from. I'd like to do the same for a Kubernetes deployment but looking online I see many guides that advise using various Kubernetes APIs and libraries. Is it possible to simply read from disk as it is with Docker Swarm? If so, what is the directory that these are stored in?

Please read the documentation
I see 2 practical ways to access the k8s secrets:
Mount the secret as a file
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
Expose the secret as an environmental variable
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password

Related

Kubernetes deployment error with Java/Micronaut: ERR_CONNECTION_REFUSED

I am trying to deploy an app having 3 services - frontend (Angular), backend 1 (Java/Micronaut), and backend 2 (Java/Micronaut).
My frontend works properly but the Java apps are not working.
Sometimes, I observed it started after 20 min. of deploying a Java app, but this time it does not work even after 1 hr.
Deployment, pod service - all are in running state in Kubernetes, but when I try to hit the URL I see below error:
deployment.yaml for java app
apiVersion: apps/v1
kind: Deployment
metadata:
name: authentication-deploy
labels:
name: authentication-deploy
app: supply-chain-app
spec:
replicas: 1
selector:
matchLabels:
name: authentication-pod
app: supply-chain-app
template:
metadata:
name: authentication-pod
labels:
name: authentication-pod
app: supply-chain-app
spec:
containers:
- name: authentication
image: cawishika/authentication-service:1.1
ports:
- containerPort: 80
service.yaml for java app
apiVersion: v1
kind: Service
metadata:
name: authentication-service
labels:
name: authentication-service
app: supply-chain-app
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30006
selector:
name: authentication-pod
app: supply-chain-app
Docker file
FROM adoptopenjdk/openjdk11:latest
EXPOSE 8002
ADD target/authentication-service-0.1.jar authentication-service-0.1.jar
ENTRYPOINT ["java", "-jar", "/authentication-service-0.1.jar"]
kubectl logs podname
Your Dockerfile is exposing port 8002 (EXPOSE 8002), but your app is started on port 8080.
Additionally, your Kubernetes configuration is pointing to port 80 of your pod.
You should set it so that all three configurations use the same port.

Not able to access placeholder, which is added as secret and the secret is mounted as volume rather than environment variable

My password placeholder in Application.yaml in spring boot project:
password: {DB_PASSWORD}
My secret file:
apiVersion: v1
data:
DB_PASSWORD: QXBwX3NhXzA1X2pzZHVlbmRfMzIx
kind: Secret
type: Opaque
metadata:
name: test-secret
My Deployment config file part:
spec:
containers:
- envFrom:
- configMapRef:
name: gb-svc-rpt-dtld-cc
image: >-
artifactory.global.standardchartered.com/colt/gb-svc-reports-dataloader-cc/gb-svc-reports-dataloader-cc-develop#sha256:c8b7e210c18556155d8314eb41965fac57c1c9560078e3f14bf7407dbde564fb
imagePullPolicy: Always
name: gb-svc-rpt-dtld-cc
ports:
- containerPort: 8819
protocol: TCP
volumeMounts:
- mountPath: /etc/secret
name: secret-test
volumes:
- name: secret-test
secret:
defaultMode: 420
secretName: test-secret
I'm able to see the secrets added in /etc/secret path also. But it is not getting referred in placeholders and getting error while server startup.
Could not resolve placeholder 'DB_PASSWORD' in value "${DB_PASSWORD}"
Note: Same code works if i add the secret as environment variable in deployment config
As I understand from your question you are trying to mount secret to a pod as an environment variable. In kubernetes secrets are able to mount as a volume (which you did in the attached code) and as env variable (as you like to do)
For that you should use:
spec:
containers:
- env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
key: DB_PASSWORD
name: test-secret
image: "fedora:29"
name: my_app

Kubernetes get pod's full name inside tomcat container in Java

Tried to get the pod name inside the Tomcat container at startup. Already exposed the pod's full name as an environment variable using the Kubernetes Downward API as below in search.yaml file ( only a portion of the file attached).
apiVersion: apps/v1
kind: Deployment
metadata:
name: search
namespace: dev
labels:
app: search
spec:
replicas: 1
selector:
matchLabels:
app: search
template:
metadata:
labels:
app: search
spec:
hostname: search-host
imagePullSecrets:
- name: regcred
containers:
- name: search-container
image: docker.test.net/search:develop-202104070845
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 8080
resources:
requests:
memory: "2048Mi"
cpu: "1"
limits:
memory: "2048Mi"
cpu: "2"
env:
- name: SERVER_GROUP
value: "SEARCH"
- name: MIN_TOMCAT_MEMORY
value: "512M"
- name: MAX_TOMCAT_MEMORY
value: "5596M"
- name: DOCKER_TIME_ZONE
value: "Asia/Colombo"
- name: AVAILABILITY_ZONE
value: "CMB"
After running the pod this environment variable is available in docker level.
Pod details
NAME READY STATUS RESTARTS AGE
search-56c9544d58-bqrxv 1/1 Running 0 4s
Pod environment variable for pod name
POD_NAME=search-56c9544d58-bqrxv
When accessed this as below in Tomcat container's java code in a jar called BootsTrap.jar and it returned as null.
String dockerPodName = System.getenv( "POD_NAME" );
Is it because the pod is not up and running before the tomcat container initialized or accessing the environment variable in Java is incorrect or is there another way of accessing pod's environment variable through java.
You are setting MY_POD_NAME as environment variable, but do the lookup for POD_NAME. Use the same name in the Java code and the deployment.
Note: Your YAML seems to have wrong indentation, I assume that this is just a copy-paste artifact. If that is not the case, it could lead to rejected changes of the deployment since the YAML is invalid.

setup ftp .ssh directory with public/private key info with docker

I have an helm-chart that references sftp key string:
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: PUBLIC_KEY
value: secretFromVault
- name: PRIVATE_KEY
value: secretFromVault
I have a DockerFile that sets up my user and creates an .ssh directory
RUN adduser -D -s /bin/bash -h /test_user test_user &&\
mkdir /test_user/.ssh/ &&\
chmod 700 /test_usr/.ssh/ &&
In this directory, I want to create the id_rsa file and input the private key string and create a knownhost file and input the reference of the public key so I can establishing remote connection target server?
How can I do this using dockerfile? Or is there a better way to do this? My sftp client code references these two files.
Instead of making your secrets as environment variable, you need to mount them as a file.
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
volumeMounts:
- name: keys
mountPath: /home/test_user/.ssh
subPath: id_rsa.pub
- name: keys
mountPath: /home/test_user/.ssh
subPath: id_rsa
volumes:
- name: keys
secret:
secretName: secretFromVault
defaultMode: 384
You will need to update the secret name from PUBLIC_KEY and PRIVATE_KEY to id_rsa.pub and id_rsa in this case.
You could add VOLUME /test_usr/.ssh to your Dockerfile and then mount a local directory to that volume. In the local directory you can generate the keys with ssh-keygen and the knownhosts if needed.

Programmatically get the name of the pod that a container belongs to in Kubernetes?

Is there a way to programmatically get the name of the pod that a container belongs to in Kubernetes? If so how? I'm using fabric8's java client but curl or something similar will be fine as well.
Note that I don't want to find the pod using a specific label since then (I assume) I may not always find the right pod if it's scaled with a replication controller.
You can tell Kubernetes to put the pod name in an environment variable of your choice using the downward API.
For example:
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
restartPolicy: Never
The pod name is written to /etc/hostname so it's possible to read it from there. In Java (which I'm using) you can also get the hostname (and thus the name of the pod) by calling System.getenv("HOSTNAME").

Categories