I have a kubernetes deployment using environment variables and I wonder how to set dynamic endpoints in it.
For the moment, I use
$ kubectl get ep rtspcroatia
NAME ENDPOINTS AGE
rtspcroatia 172.17.0.8:8554 3h33m
And copy/paste the endpoint's value in my deployment.yaml. For me, it's not the right way to do it, but I can't find another method..
Here is a part of my deployment.yaml :
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
io.kompose.service: person-cam0
name: person-cam0
spec:
template:
metadata:
labels:
io.kompose.service: person-cam0
spec:
containers:
- env:
- name: S2_LOGOS_INPUT_ADDRESS
value: rtsp://172.17.0.8:8554/live.sdp
image: ******************
name: person-cam0
EDIT : And the service of the rtsp container
apiVersion: v1
kind: Service
metadata:
labels:
io.kompose.service: rtspcroatia
name: rtspcroatia
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 8551
targetPort: 8554
selector:
io.kompose.service: rtspcroatia
Can you help me to have something like :
containers:
- env:
- name: S2_LOGOS_INPUT_ADDRESS
value: rtsp://$ENDPOINT_ADDR:$ENDPOINT_PORT/live.sdp
Thank you !
You could set dynamic ENDPOINTS values like "POD_IP:SERVICE_PORT" as shown on below sample yaml code.
containers:
- env:
- name: MY_ENDPOINT_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: S2_LOGOS_INPUT_ADDRESS
value: rtsp://$MY_ENDPOINT_IP:$RTSPCROATI_SERVICE_PORT/live.sdp
Related
I have a service running and attached to a pod. In the pod, I need to define env variable which has to point to itself. If I run locally, I would set path to localhost:8080 and it works. How can I set env variable to point to the service itself?
user#user % kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.96.116.26 129.153.28.245 8080:31495/TCP 21h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP,12250/TCP 5d18h
If the configuration is:
spec:
containers:
- name: myapp
image: path/to/imageregistry/image:v1.0.0-amd64
env:
- name: BASE_PATH
value: "129.153.28.245:8080"
App is working, in a sense that If I open in browser 129.153.28.245:8080/app/pages it will open the website. If I replace <EXTERTNAL-IP> with <CLUSTER-IP> it's not loading.
How to retrieve <EXTERTNAL-IP> from the service and put into env variable, something like:
env:
- name: BASE_PATH
value: "<EXTERNAL-IP-FROM-SERVICE-NAME>:8080"
or is there another and better approach to do that?
Here's the full Deployment and Service yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
selector:
matchLabels:
app: myapp
replicas: 1
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: xxx.ocir.io/xxxxxx/myrepo/myimage:v1.0.0-amd64
env:
- name: BASE_PATH
value: "129.153.28.245:8080"
ports:
- containerPort: 80
imagePullSecrets:
- name: ocirsecret
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: myapp
Exposing Pod and Cluster Vars to Containers
Let's say you need some data about the Pod or K8s environment in your application to add Pod information as metadata to logs. such as e.g.
Pod IP
Pod Namespace
Service Account of Pod
But how to access this information?
All Pod information can be made available in the config file
There are 2 ways to expose Pod fileds to a running Container:
Environment Variables
Volume Files
Environment Variable
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-env
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- name: log-sider
image: busybox
command: [ 'sh', '-c' ]
args:
- while true; do
echo sync app logs;
printenv POD_NAME POD_IP POD_SERVICE_ASCCOUNT;
sleep 20;
done;
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: POD_SERVICE_ASCCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
Source
database-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: postgres
name: postgres-db
spec:
replicas:
selector:
matchLabels:
app: postgres-db
template:
metadata:
labels:
app: postgres-db
spec:
containers:
- name: postgres-db
image: postgres:latest
ports:
- protocol: TCP
containerPort: 1234
env:
- name: POSTGRES_DB
value: "classroom"
- name: POSTGRES_USER
value: temp
- name: POSTGRES_PASSWORD
value: temp
database-service.yaml
apiVersion: v1
kind: Service
metadata:
name: database-service
spec:
selector:
app: postgres-db
ports:
- protocol: TCP
port: 1234
targetPort: 1234
I want to use this database-service url for other deployment so i tried to add it in configMap
my-configMap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: classroom-configmap
data:
database_url: database-service
[Not Working] Expected - database_url : database-service (will be replaced with corresponding service URL)
ERROR - Driver org.postgresql.Driver claims to not accept jdbcUrl, database-service
$ kubectl describe configmaps classroom-configmap
Output :
Name: classroom-configmap
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
database_url:
----
database-service
BinaryData
====
Events: <none>
According to the error you are having:
Driver org.postgresql.Driver claims to not accept jdbcUrl
It seems that there are a few issues with that URL, and a latest PSQL driver may complain.
jdbc:postgres: isn't right, use jdbc:postgresql:instead
Do not use jdbc:postgresql://<username>:<passwor>..., user parameters instead: jdbc:postgresql://<host>:<port>/<dbname>?user=<username>&password=<password>
In some cases you have to force SSL connection by adding sslmode=require parameter
updated my-configMap.yaml (database_url)
apiVersion: v1
kind: ConfigMap
metadata:
name: classroom-configmap
data:
database_url: jdbc:postgresql://database-service.default.svc.cluster.local:5432/classroom
expected URL - jdbc:{DATABASE}://{DATABASE_SERVICE with NAMESPACE}:{DATABASE_PORT}/{DATABASE_NAME}
DATABASE_SERVICE - database-service
NAMESPACE - default
DATABASE_SERVICE with NAMESPACE - database-service.default.svc.cluster.local
I have a mongo yaml and web-app(NodeJS) yaml set up like this:
mongo-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
mongo-url: mongo-service
mongo-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
type: Opaque
data:
mongo-user: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNzd29yZA==
mongo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-deployment
labels:
app: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
# blueprint for pods, creates pods with mongo:5.0 image
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:5.0
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-user
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
---
# kind: service
# name: any
# selector: select pods to forward the requests to
apiVersion: v1
kind: Service
metadata:
name: mongo-service
spec:
selector:
app: mongo
ports:
- protocol: TCP
port: 8080
targetPort: 27017
and the webapp.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
labels:
app: webapp
spec:
replicas: 1
selector:
matchLabels:
app: webapp
# blueprint for pods, creates pods with mongo:5.0 image
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nanajanashia/k8s-demo-app:v1.0
ports:
- containerPort: 3000
env:
- name: USER_NAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-user
- name: USER_PWD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
- name: DB_URL
valueFrom:
configMapKeyRef:
name: mongo-config
key: mongo-url
---
# kind: service
# name: any
# selector: select pods to forward the requests to
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
# default ClusterIP
# nodeport = external service
type: NodePort
selector:
app: webapp
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30100
I ran the commands for each file
kubectl apply -f
i checked the status of the webapp which returned:
app listening on port 3000!
I got the IP address by
minikube ip
and the port was 30100
Why cannot not I access this web app?
I get a site cant be reached error.
If you are on Mac, check your minikube driver. I had to stop, delete minikube, then restart while specifying the hyperkit driver like so.
minikube stop
minikube delete
docker start --vm-driver=hyperkit
The information listed here is pretty useful too.
I have an angular app and some node containers for backend, in my deployment file, how i can get container backed for connect my front end.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: container_imaer_backend
env:
- name: IP_BACKEND
value: here_i_need_my_container_ip_pod
ports:
- containerPort: 80
protocol: TCP
I would recommend instead of using the IP to use the DNS Name there's more info here: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
But basically it's http://metadata-name.namespace.svc.cluster.local so in the case for that deployment it's http://frontend.default.svc.cluster.local
It's better this way because the local IP address can change.
You could use Pod field values for environment(ref: here). That way you can set POD IP in environment variable.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql
name: mysql
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: root
- name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
ports:
- containerPort: 3306
name: mysql
protocol: TCP
volumeMounts:
- mountPath: /var/lib/mysql
name: data
volumes:
- name: data
emptyDir: {}
Currently my pods are all named "some-deployment-foo-bar" which does not help me track down issues when an error is reported with just the hostname.
So I want "$POD_NAMESPACE.$POD_NAME" as hostname.
I tried pod.beta.kubernetes.io/hostname: "foo" but that only sets an absolute name ... and subdomain did not work ...
The only other solution I saw was using a wrapper script that modifies the hostname and then executes the actual command ... which is pretty hacky and adds overhead ot every container.
Any way of doing this nicely?
current config is:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: foo
labels:
project: foo
spec:
selector:
matchLabels:
project: foo
template:
metadata:
name: foo
labels:
project: foo
spec:
containers:
- image: busybox
name: foo
PodSpec has a subdomain field, which can be used to specify the Pod’s subdomain. This field value takes precedence over the pod.beta.kubernetes.io/subdomain annotation value.
There is more information here, below is an example.
apiVersion: v1
kind: Service
metadata:
name: default-subdomain
spec:
selector:
name: busybox
clusterIP: None
ports:
- name: foo # Actually, no port is needed.
port: 1234
targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1
subdomain: default-subdomain
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox
---
apiVersion: v1
kind: Pod
metadata:
name: busybox2
labels:
name: busybox
spec:
hostname: busybox-2
subdomain: default-subdomain
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox