Search code examples
gokuberneteskubernetes-helmkubernetes-ingress

Load balancing K8s Pods with operator-framework


I built a simple operator, by tweaking the memcached example. The only major difference is that I need two docker images in my pods. Got the deployment running. My test.yaml used to deploy with kubectl.

apiVersion: "cache.example.com/v1alpha1"
kind: "Memcached"
metadata:
  name: "solar-demo"
spec:
  size: 3
  group: cache.example.com
  names:
    kind: Memcached
    listKind: MemcachedList
    plural: solar-demos
    singular: solar-demo
  scope: Namespaced
  version: v1alpha1

I am still missing one piece though - load-balancing part. Currently, under Docker we are using the nginx image working as a reverse-proxy configured as:

upstream api_microservice {
  server api:3000;
}
upstream solar-svc_microservice {
  server solar-svc:3001;
}
server {
  listen $NGINX_PORT default;

  location /city {
    proxy_pass http://api_microservice;
  }

  location /solar {
    proxy_pass http://solar-svc_microservice;
  }

  root /html;
  location / {
    try_files /$uri /$uri/index.html /$uri.html /index.html=404;
  }
}

I want my cluster to expose the port 8080 and forward to ports 3000 and 3001 to my images running inside Pods.

My deployment:

dep := &appsv1.Deployment{
    TypeMeta: metav1.TypeMeta{
        APIVersion: "apps/v1",
        Kind:       "Deployment",
    },
    ObjectMeta: metav1.ObjectMeta{
        Name:      m.Name,
        Namespace: m.Namespace,
    },
    Spec: appsv1.DeploymentSpec{
        Replicas: &replicas,
        Selector: &metav1.LabelSelector{
            MatchLabels: ls,
        },
        Template: v1.PodTemplateSpec{
            ObjectMeta: metav1.ObjectMeta{
                Labels: ls,
            },
            Spec: v1.PodSpec{
                Containers: []v1.Container{
                    {
                        Image:   "shmukler/docker_solar-svc",
                        Name:    "solar-svc",
                        Command: []string{"npm", "run", "start-solar-svc"},
                        Ports: []v1.ContainerPort{{
                            ContainerPort: 3001,
                            Name:          "solar-svc",
                        }},
                    },
                    {
                        Image:   "shmukler/docker_solar-api",
                        Name:    "api",
                        Command: []string{"npm", "run", "start-api"},
                        Ports: []v1.ContainerPort{{
                            ContainerPort: 3000,
                            Name:          "solar-api",
                        }},
                    },
                },
            },
        },
    }

What do I need to add have ingress or something running in front of my pods?

Thank you


Solution

  • What do I need to add have ingress or something running in front of my pods?

    Yes, Ingress is designed for that kind of tasks.

    Ingress has a path-based routing, which will be able to set up the same configuration as you mentioned in your example with Nginx. Moreover, one of the most popular implementations of Ingress is Nginx as a proxy.

    Ingress is basically a set of rules that allows traffic, otherwise dropped or forwarded elsewhere, to reach the cluster services.
    Here is an example of an Ingress configuration:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-app
    spec:
      rules:
      - host: '' # Empty value means ‘any host’
        http:
          paths:
          - path: /city
            backend:
              serviceName: myapp
              servicePort: 3000
          - path: /solar
            backend:
              serviceName: myapp
              servicePort: 3001
    

    Also, because a Pod is not a static thing, you should create a Service object which will be a static entry point of your application for Ingress.

    Here is an example of the Service:

    kind: Service
    apiVersion: v1
    metadata:
      name: myapp
    spec:
      selector:
        app: "NAME_OF_YOUR_DEPLOYMENT"
      ports:
      - name: city
        protocol: TCP
        port: 3000
        targetPort: 3000
      - name: solar
        protocol: TCP
        port: 3001
        targetPort: 3001