avatarHarsh Manvar

Summary

The article outlines a method for enabling a Kubernetes service to route traffic to pods across two different namespaces using Endpoints and a service without a selector.

Abstract

The author discusses a Kubernetes networking scenario where a service in one namespace needs to direct traffic to pods in two other namespaces. Initially, the author considered using EndpointSlices but encountered issues as kube-proxy does not allow virtual IPs as destinations. The solution involved creating deployments and services in the target namespaces, followed by an Endpoints resource and a headless service in the main namespace. This setup allows for round-robin routing of requests from the main namespace to the services in the other two namespaces. The article provides a step-by-step guide, including YAML configurations and commands to test the setup using a curl pod.

Opinions

  • The author suggests that using EndpointSlices for cross-namespace service requests is problematic due to kube-proxy restrictions on virtual IPs.
  • The preferred approach, as demonstrated in the article, is to use a combination of Endpoints and a service without a selector to achieve the desired cross-namespace communication.
  • The author implies that the method described is effective, as evidenced by the successful round-robin routing of requests to services across different namespaces.
  • The use of a test curl pod to verify the functionality of the setup indicates the author's practical approach to validating Kubernetes networking configurations.
  • By encouraging readers to support the author by clicking the clap button and joining the FAUN Developer Community, the author seeks to engage with the community and share knowledge on similar topics.

Kubernetes service request across two namespaces

K8s service for selecting pods in two namespaces

Overview

I recently came across a networking requirement or communication scenario for Kubernetes POD from a friend. Whereas he wanted to deliver requests from a third namespace to any one of two Kubernetes namespaces.

At the first place, i suggested using the EndpointSlices. References to a group of network endpoints with IPv4, IPv6, or FQDN address types are contained in EndpointSlice.

But after a few tests, I ran into trouble, and my requests were not being reached to other namespaces. after carefully reading a few documents, understood the clusterIPs of other Kubernetes Services cannot be the endpoint IP addresses in Slices, since kube-proxy does not permit virtual IPs as a destination.

So further, i tried with the Endpoints. Created two deployments and services in test-1 & test-2 separate namespace so can get a response when test request.

Prerequisite :

  1. K8s cluster

Steps :

Let’s first create the necessary three namespaces

kubectl create ns test-1

kuebctl create ns test-2

kubectl create ns test-main

Create the deployments and services in test-1 & test-2 namespaces.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  namespace: test-1
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  namespace: test-1
  labels:
    run: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-app
  namespace: test-2
spec:
  selector:
    matchLabels:
      run: hello-app
  replicas: 1
  template:
    metadata:
      labels:
        run: hello-app
    spec:
      containers:
      - name: hello-app
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: hello-app
  namespace: test-2
  labels:
    run: hello-app
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    run: hello-app

Now let’s create the Endpoint resource & service without a selector.

apiVersion: v1
kind: Service
metadata:
  name: slice-svc
  namespace: test-main
spec:
  ports:
  - port: 80
    name: http
    targetPort: 80
  clusterIP: None
---
kind: Endpoints
apiVersion: v1
metadata:
  name: slice-svc
  namespace: test-main
subsets:
  - addresses:
      - ip: 10.8.4.49 #CluserIP of service nginx from namespace test-1
      - ip: 10.8.5.169 #CluserIP of service my-app from namespace test-2
    ports:
      - port: 80

apply all the YAML files and create all resources.

Note: Service IPs might get changed if you re-create the service.

Let’s now spawn up the test curl pod and hit the request to service inside test-main namespace to verify it’s routing the request to one of the other two namespaces.

kubectl run mycurlpod --image=curlimages/curl -i --tty -- sh

Now hit the curl curl http://slice-svc.test-main.svc.cluster.local

In the below output as you can verify slice-svc service in test-main namespace routing the request to other services across different namespaces in round robbing. The first one is the hello response from test-1 namespace while the second is the Nginx response from test-2 namespace.

👋 If you find this helpful, please click the clap 👏 button below a few times to show your support for the author 👇

🚀Join FAUN Developer Community & Get Similar Stories in your Inbox Each Week

Kubernetes
Kubernetes Cluster
Services
Microservices
K8s Networking
Recommended from ReadMedium