How to get de pods on a running state - kubernetes

I'm trying to set up Cassandra on a Kubernetes cluster made of three virtual machines using two different files (Deployment and Service). In order to do this I use the command
kubectl create -f file.yaml
The service file works perfectly but when I start the other one with three replicas, the state of the pods is CrashLoopBackOff instead of running.
The configuration of the deployment file is the following
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: cassandra
labels:
app: cassandra
spec:
replicas: 3
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
containers:
- name: cassandra
image: gcr.io/google_containers/cassandra:v5
ports:
- containerPort: 9042
And this is the service file
apiVersion: v1
kind: Service
metadata:
labels:
app: cassandra
name: cassandra
spec:
type: NodePort
ports:
- port: 9042
selector:
app: cassandra
I appreciate any help on this.

You shouldnt be using Deployment for running stateful applications. StatefulSets are recommended for running databases like cassandra.
follow the below link for reference --> https://kubernetes.io/docs/tutorials/stateful-application/cassandra/

Related

What is the URL to this Kubernetes service/pod/docker thing

I need to hard code the address of a couchDB instance to another server in my kubernetes cluster. I'm not super familiar with kubernetes but I know that IP will change each time the cluster is rebuilt or the pod is rebuilt. So I can't use that.
What is the URL to this kubernetes service/what should I hard code into my Server Docker Image so it will alway find the CouchDB server in the system. I think it will be in this format
<service-name>.<namespace>.svc.cluster.local:<service-port>
# YAML for launching the server
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kino-couch
labels:
app: kino-couch
spec:
serviceName: orderer
# Single instance of the Orderer Pod is needed
replicas: 1
selector:
matchLabels:
app: kino-couch
template:
metadata:
labels:
app: kino-couch
spec:
containers:
- name: kino-couch
ports:
- containerPort: 5984
# Image used
image: dpacchain/development:dpaccouch
If "wget 172.17.0.2:5984" works what should "172.17.0.2" be replaced with
The following is not correct
wget kino-couch-0.couch-service.default.svc.cluster.local:5984
wget kino-couch-0.couch-service.default.svc.cluster.local:5984
wget kino-couch-0.kino-couch.default.svc.cluster.local:5984
wget kino-couch-0.kino-couchdb.default.svc.cluster.local:5984
wget kino-couch-0.kino-couchdb.svc.cluster.local:5984
For StatefulSet you need to create a Headless service to be responsible for the network identity of the Pods proving stable DNS entries. Notice clusterIP: None in below example.
apiVersion: v1
kind: Service
metadata:
name: couch-service
labels:
app: kino-couch
spec:
ports:
- port: 5984
clusterIP: None
selector:
app: kino-couch
The statefulset need to refer to the above service in serviceName. So the statefulset yaml would look like below
# YAML for launching the server
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kino-couch
labels:
app: kino-couch
spec:
serviceName: couch-service
# Single instance of the Orderer Pod is needed
replicas: 1
selector:
matchLabels:
app: kino-couch
template:
metadata:
labels:
app: kino-couch
spec:
containers:
- name: kino-couch
ports:
- containerPort: 5984
# Image used
image: dpacchain/development:dpaccouch
Then as a client you can access it using couch-service.<namespace>.svc.cluster.local:5984 to connect to a any of the CouchDB pods.
If you want to connect to a specific pod then use kino-couch-0.couch-service.<namespace>.svc.cluster.local:5984. This is typically needed for connecting the couchDB pods between themselves to create a cluster.

Kubernetes connect service and deployment

I am wondering what to specify in a separate deployment in order to have it access a DB deployment/service. Here is the DB deployment/service:
apiVersion: v1
kind: Service
metadata:
name: oracle-db
labels:
app: oracle-db
spec:
ports:
- name: oracle-db
port: 1521
protocol: TCP
targetPort: 1521
selector:
app: oracle-db
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: oracle-db-depl
labels:
app: oracle-db
spec:
selector:
matchLabels:
app: oracle-db
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: oracle-db
spec:
containers:
- name: oracle-db
image: oracledb:latest
imagePullPolicy: Always
ports:
- containerPort: 1521
env:
...
How exactly do I specify the connection in the separate deployment? Do I specify the oracle-db service name somewhere? So far I specify a containerPort in the container.
If the other app deployment is in the same namespace you can refer to the oracle service by oracle-db. Here is an example of a word-press application using oracle.
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: oracle-db
ports:
- containerPort: 80
name: wordpress
As you can see oracle service is being referred by oracle-db as an environment variable.
If the service is in different namespace than the app deployment then you can refer to it as oracle-db.namespacename.svc.cluster.local
https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/
Services in Kubernetes are an "abstract way to expose an application running on a set of Pods as a network service." (k8s documentation)
You can access your pod by its IP and port that Kubernetes have given to it, but that's not a good practice as the Pods can die and another one will be created (if controlled by a Deployment/ReplicaSet). When the new one is created, a new IP will be used, and everything on your app will start to fail.
To solve this you can expose your Pod using a Service (as you already have done), and use service-name:service-port assigned to the Service to access your Pod. In this case, even if the Pod dies and a new one is created, Kubernetes will keep forwarding the traffic to the right Pod.

How to create multiple instances of Mediawiki in a Kubernetes Cluster

I´m about to deploy multiple Mediawiki instances on my Kubernetes-cluster.
In my case the YAML deploymentfile for the DB (MySQL) works as it supposed to do, the deploymentfile for Mediawiki deploys as many pods as expected, but I can´t access them from outside of the cluster even if I create a Service for this case.
If I try to create one single Mediawiki pod and a service to access it from outside of the cluster it works as it should. If I try to create a deploymentfile for Mediawiki equal to the one for MySQL it does creates the pods and the requiered service but it´s not accessible from the externel-IP assigned to it.
My deploymentfile for Mediawiki:
apiVersion: v1
kind: Service
metadata:
name: mediawiki-service
labels:
name: mediawiki-service
app: mediawiki
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
name: mediawiki-pod
app: mediawiki
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mediawiki
spec:
replicas: 6
selector:
matchLabels:
app: mediawiki
strategy:
type: Recreate
template:
metadata:
labels:
app: mediawiki
spec:
containers:
- image: mediawiki
name: mediawiki
ports:
- containerPort: 80
name: mediawiki
This is the pod-definition file:
apiVersion: v1
kind: Pod
metadata:
name: mediawiki-pod
labels:
name: mediawiki-pod
app: mediawiki
spec:
containers:
- name: mediawiki
image: mediawiki
ports:
- containerPort: 80
This is the service-definition file:
apiVersion: v1
kind: Service
metadata:
name: mediawiki-service
labels:
name: mediawiki-service
app: mediawiki
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
name: mediawiki-pod
The accual resault should be that I can deploy multiple instances of Mediawiki on my cluster and can access them from outside with the externel-IP.
If you look at kubectl describe service mediawiki-service in both scenarios, I expect you will see that in the single-pod case, there is an Endpoints: list that includes a single IP address (the pod's, but that's an implementation detail) but in the deployment case, it says <none>.
Your Service only matches pods that have both name and app labels:
apiVersion: v1
kind: Service
spec:
selector:
name: mediawiki-pod
app: mediawiki
But the pods deployed by your deployment only have app labels:
apiVersion: apps/v1
kind: Deployment
spec:
template:
metadata:
labels:
app: mediawiki
So at that specific point (the labels inside the template for the deployment; also adding them at the top level doesn't hurt, but this embedded point is what's important) you need to add the second label name: mediawiki-pod.
If you want to deploy multiple instances of some piece of software on Kubernetes cluster it's good idea to check out if there is a helm chart for it.
In your case the answer is positive - there is a stable helm chart for Mediawiki.
Creating multiple instances is as easy as creating multiple releases, for example:
helm install --name wiki1 stable/mediawiki
helm install --name wiki2 stable/mediawiki
helm install --name wiki3 stable/mediawiki
To use Helm you have to install it on your local machine and on k8s cluster - following the quick start guide will be enough.

Grafana is not working on kubernetes cluster while using k8s Service

I am trying to setup a very simple monitoring cluster for my k8s cluster. I have successfully created prometheus pod and is running fine.
When I tried to create grafana pod the same way, its not accessible through the node port.
My Grafana deploy file is-
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grafana-deployment
namespace: monitoring
spec:
replicas: 1
template:
metadata:
labels:
app: grafana-server
spec:
containers:
- name: grafana
image: grafana/grafana:5.1.0
ports:
- containerPort: 3000
And Service File is --
apiVersion: v1
kind: Service
metadata:
name: grafana-service
namespace: monitoring
spec:
selector:
app: grafana-server
type: NodePort
ports:
- port: 3000
targetPort: 3000
Note- When I am creating a simple docker container on the same host using same image, its working fine.
I have come to know that my servers provider had not enabled these ports (like grafana-3000, kibana-5601). Never thought of this since i am using these servers from quite a long time and never faced such blocker. They implemented these rules recently.
Well, after some port approvals, I tried the same config again and it worked like a charm.

How to expose an "election-based master and secondaries" service outside Kubernetes cluster?

I've been trying to implement a service inside Kubernetes where each Pod needs to be accessible from outside the Cluster.
The topology of my service is simple: 3 members, one of them acting as master at any time (election based); writes go to primary; reads go to secondaries. This is MongoDB replica set by the way.
They work with no issues inside the Kubernetes cluster, but from outside the only thing I have is a NodePort service type that load balances incoming connections to one of them, but I need to access each on of them, separately, depending on what I want to do from my client (write or read).
What kind of Kubernetes resource should I use to give individual access to each one of the members of my service?
In order to access every pod from outside you can create a separate service for each pod and use NodePort type.
Because Service uses selectors to get to available backends, you can create just one Service for a master:
apiVersion: v1
kind: Service
metadata:
name: my-master
labels:
run: my-master
spec:
type: NodePort
ports:
- port: #your-external-port
targetPort: #your-port-exposed-in-pod
protocol: TCP
selector:
run: my-master
-------------
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-master
spec:
selector:
matchLabels:
run: my-master
replicas: 1
template:
metadata:
labels:
run: my-master
spec:
containers:
- name: mongomaster
image: yourcoolimage:lates
ports:
- containerPort: #your-port-exposed-in-pod
Also, you can use one Service for all your read-only replicas and this service will balance requests between all of them.
apiVersion: v1
kind: Service
metadata:
name: my-replicas
labels:
run: my-replicas
spec:
type: LoadBalancer
ports:
- port: #your-external-port
targetPort: #your-port-exposed-in-pod
protocol: TCP
selector:
run: my-replicas
---------
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-replicas
spec:
selector:
matchLabels:
run: my-replicas
replicas: 2
template:
metadata:
labels:
run: my-replicas
spec:
containers:
- name: mongoreplica
image: yourcoolimage:lates
ports:
- containerPort: #your-port-exposed-in-pod
I also suggest you do not expose Pod outside of your network because of security reasons. It would be better to create strict firewall rules to restrict any unexpected connections.