How can access running app in my computer localhost inside kubernetes pod? - docker

i have a question about kubernetes networking.
My working senario:
I have a Jenkins container my localhost and this container up and running. Inside Jenkins, i have a job. Access jenkins , i use "http://localhost:8080" url. (jenkins is not runing inside kubernetes)
My flask app, trigger the Jenkins job with this command:
#app.route("/create",methods=["GET","POST"])
def create():
if request.method =="POST":
dosya_adi=request.form["sendmail"]
server = jenkins.Jenkins('http://localhost:8080/', username='my-user-name', password='my-password')
server.build_job('jenkins_openvpn', {'FILE_NAME': dosya_adi}, token='my-token')
Then, i did Dockerize this flask app. My image name is: "jenkins-app"
If i run this command, everythings perfect:
docker run -it --network="host" --name=jenkins-app jenkins-app
But i want to do samething with kubernetes. For that i wrote this yml file.
apiVersion: v1
kind: Pod
metadata:
name: jenkins-pod
spec:
hostNetwork: true
containers:
- name: jenkins-app
image: jenkins-app:latest
imagePullPolicy: Never
ports:
- containerPort: 5000
With this yml file, i access the flask app using port 5000. While i want to trigger jenkins job, i get an error like this: requests.exceptions.ConnectionError
Would you suggest if there is a way to do this with Kubernetes?

I create an endpoint.yml file and add in this file below commands, this solve my problem:
apiVersion: v1
kind: Endpoints
metadata:
name: jenkins-server
subsets:
- addresses:
- ip: my-ps-ip
ports:
- port: 8080
Then, I change this line in my flask app like this:
server = jenkins.Jenkins('http://my-ps-ip:8080/', username='my-user-name', password='my-password')

First you expose your Jenkins server:
kubectl expose pod jenkins-pod --port=8080 --target-port 5000
Then you check the existence of the service:
kubectl get svc jenkins-pod -o yaml
Use it for your Flask app to connect to your Jenkins server via this service:
... jenkins.Jenkins('http://jenkins-pod.default.svc.cluster.local:8080/...'
Note the assumption is you run everything in default namespace, otherwise change the "default" to your namespace.

Related

Debugging NodeJs app running inside pod on Kind (Kubernetes in docker) cluster

I am running a kubernetes cluster with Kind configured as shown bellow:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: ${ingress_http_port}
protocol: TCP
- containerPort: 443
hostPort: ${ingress_https_port}
protocol: TCP
networking:
kubeProxyMode: "ipvs"
The cluster is running inside the kind-control-plane docker container:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53d9511b8282 kindest/node:v1.21.1 "/usr/local/bin/entr…" 5 hours ago Up 5 hours 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 127.0.0.1:41393->6443/tcp kind-control-plane
I have also successfully deployed a deployment running a nodeJs application inside a pod and i have already exposed a service to access the app through an ingress controller and everything works as expected:
apiVersion: v1
kind: Service
metadata:
name: application-deployment
spec:
ports:
- name: http
port: 3000
protocol: TCP
selector:
app: application-deployment
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: application-deployment
spec:
rules:
- http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: application-deployment
port:
number: 3000
I am using the WebStorm IDE to develop the application running inside the pod and i am trying to configure a remote debugger to connect to the application inside the Kind cluster. I know how to configure a debugger running inside a docker container but i dont know how to run a debugger inside a kubernetes pod running in a docker container.
I have already tried to configure it through WebStrom with the settings bellow:
And these are the settings under the Docker container settings label:
Any suggestions or workarounds in order to accomplish this would be more than appreciated.
Thank you in advance!
Finally I managed to connect the remote debugger by following the steps described bellow:
Start the node process inside the pod with the --inspect-brk arg in order to be able to attach a debugger. (E.g. node --inspect-brk --loader ts-node/esm src/server.ts)
Then I forwarded the debug port from the pod to my local computer by running the command kubectl port-forward deploy/application-deployment 9229:9229
Finally I created an Attach to Node.js/Chrome run/debug configuration on WebStorm instead of the Node.js configuration as I tried on the beginning and everything worked like a charm.
This linked helped me configure the described solution.

How do i translate a docker command with -p 80:80 to kubernetes yaml

docker run -it -p 80:80 con-1
docker run -it -p hostport:containerport
Lets say i have this yaml definition, does below where it says 80 ports -> containerPort: 80 sufficent? In other words how do i account for -p 80:80 the hostport and container port in kubernetes yaml definition?
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Exposing ports of applications with k8s is different than exposing it with docker.
For pods, spec.containers.ports field isn't used to expose ports. It mostly used for documenting purpouses and also to name ports so that you can reference them later in service object's target-port with their name, and not a number (https://stackoverflow.com/a/65270688/12201084).
So how do we expose pods to the outside?
It's done with service objects. There are 4 types of service: ClusterIP, NodePort, LoadBalancer and ExternalName.
They are all well explained in k8s documentation so I am not going to explain it here. Check out K8s docs on types of servies
Assuming you know what type you want to use you can now use kubectl to create this service:
kubectl expose pod <pod-name> --port <port> --target-port <targetport> --type <type>
kubectl expose deployment <pod-name> --port <port> --target-port <targetport> --type <type>
Where:
--port - is used to pecify the port on whihc you want to expose the application
--target-port - is used to specify the port on which the applciation is running
--type - is used to specify the type of service
With docker you would use -p <port>:<target-port>
OK, but maybe you don't want to use kubeclt to create a service and you would like to keep the service in git or whatever as a yaml file. You can check out the examples in k8s docs, copy it and write you own yaml or do the following:
$ kubectl expose pod my-svc --port 80 --dry-run=client -oyaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
run: my-svc
name: my-svc
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: my-svc
status:
loadBalancer: {}
Note: notice that if you don't pass a value for --target-port it defaults to the same value as --port
Also notice the selector filed, that has the same values as the labels on a pod. It will forward the traffic to every pod with this label (within the namespace).
Now, if you don't pass the value for --type, it defaults to ClisterIP so it means the service will be accessible only from within the cluster.
If you want to access the pod/application from the outside, you need to use either NodePort or LoadBalancer.
Nodeport opens some random port on every node and connecting to this port will forward the packets to the pod. The problem is that you can't just pick any port to open, and often you dont even get to pick the port at all (it's randomly assigned).
In case of type LoadBalancer you can use whateever port you'd like, but you need to run in cloud and use cloud provisioner to create and configure external loadbalancer for you and point it to your pod. If you are running on bare-metal you can use projects like MetalLB to make use of LoadBalancer type.
To summarize, exposing containers with docker is totally different than exposing them with kubernetes. Don't assume k8s will work the same way the docker works just with different notation, because it won't.
Read the docs and blogs about k8s services and learn how they work.

How to route test traffic through kubernetes cluster (minikube)?

I have a minikube cluster with two pods (with ubuntu containers). What I need to do is route test traffic from one port to another through this minikube cluster. This traffic should be sent through these two pods like in the picture. I am a beginner in this Kubernetes stuff so I really don't know how to do this and which way to go... Please, help me or give me some hints.
I am working on ubuntu server ver. 18.04.
enter image description here
I agree with an answer provided by #Harsh Manvar and I would also like to expand a little bit on this topic.
There already is an answer with a similar setup. I encourage you to check it out:
Stackoverflow.com: Questions: How to access a service from other machine in LAN
There are different drivers that could be used to run your minikube. They will have differences when it comes to dealing with inbound traffic. I missed the part that was telling about the driver used in the setup (comment). If it's the Docker shown in the tags, you could follow below example.
Example
Steps:
Spawn nginx-one and nginx-two Deployments to imitate Pods from the image
Create a service that will be used to send traffic from nginx-one to nginx-two
Create a service that will allow you to connect to nginx-one from LAN
Test the setup
Spawn nginx-one and nginx-two Deployments to imitate Pods from the image
You can use following definitions to spawn two Deployments where each one will have a single Pod:
nginx-one.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-one
spec:
selector:
matchLabels:
app: nginx-one
replicas: 1
template:
metadata:
labels:
app: nginx-one
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
nginx-two.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-two
spec:
selector:
matchLabels:
app: nginx-two
replicas: 1
template:
metadata:
labels:
app: nginx-two
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Create a service that will be used to send traffic from nginx-one to nginx-two
You will need to use a Service to send the traffic from nginx-one to nginx-two. Example of such Service could be following:
apiVersion: v1
kind: Service
metadata:
name: nginx-two-service
spec:
type: ClusterIP # could be changed to NodePort
selector:
app: nginx-two # IMPORTANT
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
After applying this definition you will be able to send the traffic to nginx-two by using the service name (nginx-two-service)
A side note!
You can use the IP of the Pod without the Service but this is not a recommended way.
Create a service that will allow you to connect to nginx-one from LAN
Assuming that you want to expose your minikube instance to LAN with Docker driver you will need to create a service and expose it. Example of such setup could be the following:
apiVersion: v1
kind: Service
metadata:
name: nginx-one-service
spec:
type: ClusterIP # could be changed to NodePort
selector:
app: nginx-one # IMPORTANT
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
You will also need to run:
$ kubectl port-forward --address 0.0.0.0 service/nginx-one-service 8000:80
Above command (ran on your minikube host!) will expose your nginx-one-service to be available on LAN. It will map port 8000 on the machine that ran this command to the port 80 of this service. You can check it by executing from another machine at LAN:
curl IP_ADDRESS_OF_MINIKUBE_HOST:8000
A side note!
You will need root access to have your inbound traffic enter on ports lesser than 1024.
Test the setup
You will need to check if there is a communication between the objects as shown in below "connection diagram".
PC -> nginx-one -> nginx-two -> example.com
The testing methodology could be following:
PC -> nginx-one:
Run on a machine in your LAN:
curl MINIKUBE_IP_ADDRESS:8000
nginx-one -> nginx-two:
Exec into your nginx-one Pod and run command:
$ kubectl exec -it NGINX_POD_ONE_NAME -- /bin/bash
$ curl nginx-two-service
nginx-two -> example.com:
Exec into your nginx-two Pod and run command:
$ kubectl exec -it NGINX_POD_TWO_NAME -- /bin/bash
$ curl example.com
If you completed above steps you can swap nginx Pods for your own software.
Additional notes and resources:
I encourage you to check kubeadm as it's the tool to create your own Kubernetes clusters:
Kubernetes.io: Docs: Setup: Production environment: Tools: Kubeadm: Create cluster kubeadm
As you said:
I am a beginner in this Kubernetes stuff so I really don't know how to do this and which way to go... Please, help me or give me some hints.
You could check following links for more resources:
Kubernetes.io
Kubernetes: Docs: Concepts: Workloads: Controllers: Deployment
Kubernetes.io: Docs: Concepts: Services networking: Service
There are multiple options you can follow:
As you have two PODs you can expose one via service,
so service-1 is exposed and sending traffic to POD-1
POD-1 will send a request to service-2 of Kubernetes
This way traffic will get forwarded to POD-2 and from there it will Go out of cluster
There is also a container to container communication possibility if you can run both applications in a single POD.
POD-1 to POD-2 communication you can use the service option or POD URI.

kubectl no matches for kind Service in version apps/v1

I'm new to Kubernetes. I'm making my first ever attempt to deploy an application to Kubernetes and expose it to the public. However, when I try and deploy my configuration, I get this error:
error: unable to recognize "deployment.yml": no matches for kind "Service" in version "apps/v1"
So, let's run through the details.
I'm on Ubuntu 18.04. I'm using MiniKube with VirtualBox as the HyperVisor driver. Here is all the version info:
MiniKube = v1.11.0
VirtualBox = 6.1.0
Kubectl = Client Version 1.18.3, Server Version 1.18.3
The app I'm trying to deploy is a super-simple express.js app that returns Hello World on request.
const express = require('express');
const app = express();
app.get('/hello', (req, res) => res.send('Hello World'));
app.listen(3000, () => console.log('Running'));
I have a build script I've used for deploying express apps to docker before that zips up all the source files. Then I've got my Dockerfile:
FROM node:12.16.1
WORKDIR /usr/src/app
COPY ./build/TestServer-*.zip ./TestServer.zip
RUN unzip TestServer.zip
RUN yarn
CMD ["yarn", "start"]
So now I run some commands. eval $(minikube docker-env) makes me use MiniKube's docker environment so I don't need to deploy this container to the cloud. docker build -t testserver:v1 . builds and tags the container.
Now, let's go to my deployment.yml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: testserver
spec:
replicas: 1
selector:
matchLabels:
app: testserver
template:
metadata:
labels:
app: testserver
spec:
containers:
- name: testserver
image: testserver:v1
ports:
- containerPort: 3000
env:
imagePullPolicy: Never
---
apiVersion: apps/v1
kind: Service
metadata:
name: testserver
spec:
selector:
app: testserver
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
I'm trying to create a deployment with a pod and a service to expose it. I'm sure there are various issues in here, this is the newest part to me and I'm still trying to learn and understand the spec. However, the problem I'm asking for help with occurs when I try to use this config. I run the create command, and get the error.
kubectl create -f deployment.yml
deployment.apps/testserver created
error: unable to recognize "deployment.yml": no matches for kind "Service" in version "apps/v1"
The result of this is I see my app listed as a deployment and as a pod, but the service part has failed. I've been scouring the internet for documentation on why this is happening, but I've got nothing.
A service is of apiVersion: v1 instead of apiVersion: apps/v1 (like a deployment). You can check it in the official docs. You also need to use a Service of type NodePort (or ClusterIP) if you want to expose your deployment. Type LoadBalancer will not work in minikube. This is mostly used in k8s clusters managed in the cloud where a service of type LoadBalancer will create a loadbalancer (like an ALB in AWS).
To check the apigroup of a resource you can use: kubectl api-resources

how to restart jenkins service inside pod in kubernetes cluster

I have created a kubernetes cluster and deployed jenkins by following file
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins-ci
spec:
replicas: 1
template:
metadata:
labels:
run: jenkins-ci
spec:
containers:
- name: jenkins-ci
image: jenkins:2.32.2
ports:
- containerPort: 8080
and service by
apiVersion: v1
kind: Service
metadata:
name: jenkins-cli-lb
spec:
type: NodePort
ports:
# the port that this service should serve on
- port: 8080
nodePort: 30000
# label keys and values that must match in order to receive traffic for this service
selector:
run: jenkins-ci
Now i can access jenkins UI in my browser without any problems. My issue I came into situation in which need to restart jenkins service manually??
Just kubectl delete pods -l run=jenkins-ci - Will delete all pods with this label (your jenkins containers).
Since they are under Deployment, it will re-create the containers. Network routing will be adjusted automatically (again because of the label selector).
See https://kubernetes.io/docs/reference/kubectl/cheatsheet/
You can use command below to enter the pod container.
$ kubectl exec -it kubernetes pod -- /bin/bash
After apply service Jenkins restart command.
For more details please refer :how to restart service inside pod in kubernetes cluster.

Resources