Why should I specify service before deployment in a single Kubernetes configuration file?

5/18/2018

I'm trying to understand why kubernetes docs recommend to specify service before deployment in one configuration file:

The resources will be created in the order they appear in the file. Therefore, it’s best to specify the service first, since that will ensure the scheduler can spread the pods associated with the service as they are created by the controller(s), such as Deployment.

Does it mean spread pods between kubernetes cluster nodes?

I tested with the following configuration where a deployment is located before a service and pods are distributed between nods without any issues.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: incorrect-order
  namespace: test
spec:
  selector:
    matchLabels:
      app: incorrect-order
  replicas: 2
  template:
    metadata:
      labels:
        app: incorrect-order
    spec:
      containers:
      - name: incorrect-order
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: incorrect-order
  namespace: test
  labels:
    app: incorrect-order
spec:
  type: NodePort
  ports:
  - port: 80
  selector:
    app: incorrect-order

Another explanation is that some environment variables with service URL will not be set for pods in this case. However it also works ok in case a configuration is inside one file like the example above.

Could you please explain why it is better to specify service before the deployment in case of one configuration file? Or may be it is some outdated recommendation.

-- yuppie-flu
kubectl
kubernetes

2 Answers

5/25/2018

If you use DNS as service discovery, the order of creation doesn't matter.

In case of Environment Vars (the second way K8S offers service discovery) the order matters, because once that vars are passed to the starting pod, they cannot be modified later if the service definition changes.

So if your service is deployed before you start your pod, the service envvars are injected inside the linked pod.

If you create a Pod/Deployment resource with labels, this resource will be exposed through a service once this last is created (with proper selector to indicate what resource to expose).

-- Nicola Ben
Source: StackOverflow

8/28/2018

You are correct in that it effects the spread among the worker nodes.

Deployments without a Service will simply be scheduled onto the nodes with the least cpu/memory allocation. For instance, a brand new and empty node will get all new pods from a new deployment.

With a Deployment that also has a service the Scheduler tries to spread the pods between nodes, disregarding the cpu/memory load (within limits), to help the Service survive better.

It puzzles me that a Deployment on it's own doesn't cause a optimal spread but it doesn't, not yet at least.

-- Andreas Wederbrand
Source: StackOverflow