Skip to content

Instantly share code, notes, and snippets.

@mpl
Forked from jbdoumenjou/README.md
Last active November 4, 2019 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpl/f8e0dee9afc0b5decb641ca5224e17ee to your computer and use it in GitHub Desktop.
Save mpl/f8e0dee9afc0b5decb641ca5224e17ee to your computer and use it in GitHub Desktop.
k8s crd services

Purpose

This gist contains examples of yaml configurations for the service load balancing in the k8s crd provider.

Goal

The goal is to expose:

  • a "user friendly" configuration (with potentialy complex usecases)
  • avoid confusion between K8s native objects and Traefik one
  • avoid to break the current configuration

Context

The mirror and weighted services can use any combination of any kind of services as child (serverLB, wrr, mirror). We have to manage different types of objects that could be internal (traefik crd) or external (native k8s objects). The basic usage should stay easy to use.

Naming

All names could be change such as:

  • serviceName attribute that refers to a NodeService name
  • NodeService name of the CRD that defines a traefik service
  • nodeServices name of the list of traefik services

Usage

The samples have the following naming convention: <solution>_<usecase>.yaml

Solutions

serviceName Switch

Switch between two exclusives attributes:

  • name -> k8s services
  • serviceName -> traefik nodeService

It is the actual solution available in the PR

2 Distinct Lists

To avoid confusion between Traefik and K8s services, we can separe those 2 types of services in 2 distinct lists. The list could be under the actual service list but it would be breaking. Otherwise we can add a list at the same level of the existing one. We have to apply it both for mirroring and wrr. As we just use a name, we need to specify a specific object for the main service in the mirroring.

Provider Namespace

As Traefik use provider namespace to manage cross provider configuration, we may force the annotation to define if the service used is a Traefik (with namespace) or a K8s one (without namespace or with a specific one ?).

No explicit k8s service. (breaking).

This change would break the existing configuration schema. A service referenced by the "name" attribute is always a nodeService, so there's never any conflict with a reference to a k8s service. When we actually need to create a load-balancer of servers we wrap a k8s service within e.g. a traefik service wrr.

---
apiVersion: v1
kind: Service
metadata:
name: whoami5
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami5
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/foo`)
kind: Rule
priority: 12
# k8s services
services:
- name: whoami4
percent: 50
port: 8080
# Traefik services
nodeServices:
- name: wrr1
---
apiVersion: v1
kind: Service
metadata:
name: whoami5
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami5
---
apiVersion: v1
kind: Service
metadata:
name: whoami4
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami4
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr2
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: mirror1
namespace: default
spec:
mirroring:
# We need to define if the "main" service is a traefik or k8s one
# k8s main service
service:
name: whoami5
port: 8080
# Alternative with a Traefik service
# nodeService:
# name: wrr2
mirrors:
services:
- name: whoami4
percent: 50
port: 8080
nodeServices:
- name: wrr2
percent: 40
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
nodeServices:
- name: wrr2
weight: 1
- name: mirror1
weight: 1
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/foo`)
kind: Rule
priority: 12
# k8s services
services:
- name: whoami4
port: 8080
# Traefik services
nodeServices:
- name: wrr1
---
apiVersion: v1
kind: Service
metadata:
name: whoami5
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami5
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/foo`)
kind: Rule
priority: 12
services:
- name: wrr1@kubernetescrd
- name: whoami5
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoami5
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami5
---
apiVersion: v1
kind: Service
metadata:
name: whoami4
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami4
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr2
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
- name: wrr2@kubernetescrd
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: mirror1
namespace: default
spec:
mirroring:
name: whoami5
port: 8080
# Alternative with a Traefik service
# name: wrr2@kubernetescrd
mirrors:
- name: whoami4
percent: 50
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- name: wrr2@kubernetescrd
weight: 1
- name: whoami5
weight: 1
port: 8080
- name: mirror1@kubernetescrd
weight: 1
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/foo`)
kind: Rule
priority: 12
services:
- name: wrr1@kubernetescrd
- name: whoami4
percent: 50
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoami5
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami5
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/foo`)
kind: Rule
priority: 12
services:
- serviceName: wrr1
- name: whoami5
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoami5
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami5
---
apiVersion: v1
kind: Service
metadata:
name: whoami4
namespace: default
spec:
ports:
- name: web
port: 8080
selector:
app: containous
task: whoami4
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr2
namespace: default
spec:
weighted:
services:
- name: whoami5
weight: 1
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: mirror1
namespace: default
spec:
mirroring:
name: whoami5
port: 8080
# Alternative with a Traefik service
# serviceName: wrr2
mirrors:
- name: whoami4
percent: 50
port: 8080
- serviceName: wrr2
---
apiVersion: traefik.containo.us/v1alpha1
kind: NodeService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- serviceName: wrr2
weight: 1
- name: whoami5
weight: 1
port: 8080
- serviceName: mirror1
weight: 1
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/foo`)
kind: Rule
priority: 12
services:
- serviceName: wrr1
- name: whoami4
port: 8080
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment