Could two cluster IP services be connected in Kubernetes?

4/8/2020

The situation is that I want to connect two cluster IP services that are inside a tenant which already has Traefik as NodePort so that any of these two services can be a LoadBalancer because the NodePort is used by Traefik.

The two services I am trying to connect work as follows. The first one, which I called "Master", will receive a post from the client with a text and will call the other service, called "slave", which will add some text ("Hola Patri") to the text sent by the client. The two services are flask services defined by the app.py in the Docker image. You can see the app.py for both images below:

master/app.py

from flask import Flask, request
import requests                                                                                                                                                                                                                                                                                                                                                       

app = Flask(__name__)                                                              

@app.route("/", methods = ['GET', 'POST'])                                                 

def put(): 
    if request.method == 'POST':                                                    
        text = request.get_data()  
        r = requests.post("http://slave:5001",data=text)   
        result = r.text
        return result                                                        

if __name__ == '__main__':                                                         
    app.run(host="0.0.0.0", port=5000, debug=True)        

slave/app.py

from flask import Flask, request                                                                                                                                                                                                                                                                                                                                                       

app = Flask(__name__)                                                              

@app.route("/", methods = ['GET', 'POST'])                                                 

def put(): 
    if request.method == 'POST':                                                    
        text = request.get_data()
        #text = request.data
        texto_final = str(text) + 'Hola Patri'                                                      
        return texto_final                                                     

if __name__ == '__main__':                                                         
    app.run(host="0.0.0.0", port=5001, debug=True)   

The configuration of the deployments and the services are defined in two yamls: master_src.yaml and slave_src.yaml.

master_src.yaml

kind: Namespace
apiVersion: v1
metadata:
  name: innovation
  labels:
    name: innovation

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: master
  namespace: innovation
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      securityContext:
        runAsUser: 1000
        fsGroup: 1000            
      containers:
      - name: master
        imagePullPolicy: Always
        securityContext:
            runAsUser: 1000
            runAsNonRoot: true
        image: reg-dhc.app.corpintra.net/galiani/innovation:mastertest
        ports:
        - protocol: TCP
          containerPort: 5000
      imagePullSecrets:
        - name: galiani-innovation-pull-secret

---
apiVersion: v1
kind: Service
metadata:
  name: master
  namespace: innovation
spec:
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 5000
  selector:
    app: myapp

slave_src.yaml

kind: Namespace
apiVersion: v1
metadata:
  name: innovation
  labels:
    name: innovation

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: slave
  namespace: innovation
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      securityContext:
        runAsUser: 1000
        fsGroup: 1000  
      containers:
      - name: slave
        imagePullPolicy: Always
        securityContext:
            runAsUser: 1000
            runAsNonRoot: true
        image: reg-dhc.app.corpintra.net/galiani/innovation:slavetest
        ports:
        - protocol: TCP
          containerPort: 5001
      imagePullSecrets:
        - name: galiani-innovation-pull-secret

---
apiVersion: v1
kind: Service
metadata:
  name: slave
  namespace: innovation
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 5001
    targetPort: 5001

I have also created a network policy to allow the traffic between the two services. The yaml used to define the network policy is the following.

networkpolicy_src.yaml

kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
  name: ingress-to-all
  namespace: innovation
spec:
  podSelector:
    matchLabels:
      app: myapp
  ingress: 
  - from:
    - podSelector:
        matchLabels:
          app: myapp
    ports:
      - port: 5000
        protocol: TCP
      - port: 5001
        protocol: TCP
  policyTypes:
  - Ingress

The connection between the master service and the slave service is not working. I can access to the master and slave independently. Nevertheless, when I try to make a POST to the master (using curl) and it should connect to the slave, I get the following error:

curl: (52) Empty reply from server

Thank you for your help in advance!


For the new question I have regarding the connection using traefik. Here is the yaml of the trafik ingress:

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress-innovation
  namespace: innovation
  annotations:
    traefik.frontend.rule.type: PathPrefixStrip
spec:  
  rules:
  - http:
      paths:
      - path: /master
        backend:
          serviceName: master
          servicePort: 5000
      - path: /slave
        backend:
          serviceName: slave
          servicePort: 5001

I have also corrected the networkpolicy yaml and now it is:

kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
  name: master-to-slave
  namespace: innovation
spec:
  podSelector:
    matchLabels:
      app: app-slave
  ingress:
    - ports:
      - port: 5000
        protocol: TCP
      - port: 5001
        protocol: TCP
    - from:
      - namespaceSelector:
          matchLabels:
            app: app-master

Thanks again for your help!

-- pquinta
kubernetes
kubernetes-networkpolicy
kubernetes-service
traefik

1 Answer

4/8/2020

The problem could be having same label app: myapp for both master and slave. Change the label to app: master for master deployment and service and app: slave for slave deployment and service.

-- Arghya Sadhu
Source: StackOverflow