Skip to content

Octavia Ingress et LoadBalancer

Introduction

L'intégration OpenStack Cloud Provider permet à Kubernetes d'utiliser Octavia pour les Services LoadBalancer et l'Ingress Controller. Cela expose les applications vers l'extérieur via des floating IPs.

Prérequis

Points à apprendre

Architecture LoadBalancer Octavia

graph TB
    internet[Internet<br/>Users]

    subgraph openstack[OpenStack]
        fip[Floating IP<br/>203.0.113.10]
        octavia[Octavia LB<br/>Amphora<br/>VIP: 10.0.0.100]
    end

    subgraph k8s[Kubernetes Cluster]
        svc[Service<br/>type: LoadBalancer<br/>Expose port 80]
        pod1[Pod 1<br/>nginx]
        pod2[Pod 2<br/>nginx]
        pod3[Pod 3<br/>nginx]
        ccm[Cloud Controller<br/>openstack-cloud-controller-manager<br/>Gère les LB]
    end

    internet -->|HTTPS 443| fip
    fip --> octavia
    octavia -->|HTTP NodePort| pod1
    octavia --> pod2
    octavia --> pod3
    ccm -->|Create/Manage API| octavia
    svc -->|Watch| ccm

Installation Cloud Controller Manager

# Secret avec credentials OpenStack
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: cloud-config
  namespace: kube-system
stringData:
  cloud.conf: |
    [Global]
    auth-url=https://10.0.0.10:5000/v3
    username=admin
    password=<password>
    region=RegionOne
    tenant-name=admin
    domain-name=Default

    [LoadBalancer]
    lb-version=v2
    subnet-id=<subnet-id>
    floating-network-id=<external-network-id>
    lb-method=ROUND_ROBIN
    lb-provider=octavia
    create-monitor=true
    monitor-delay=5s
    monitor-timeout=3s
    monitor-max-retries=3

    [Networking]
    public-network-name=external
EOF

# Installer le Cloud Controller Manager
kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-openstack/master/manifests/controller-manager/openstack-cloud-controller-manager-ds.yaml

Via Helm

helm repo add cpo https://kubernetes.github.io/cloud-provider-openstack
helm repo update

cat > ccm-values.yaml <<EOF
cloudConfig:
  global:
    authUrl: https://10.0.0.10:5000/v3
    username: admin
    password: <password>
    region: RegionOne
    tenantName: admin
    domainName: Default
  loadBalancer:
    lbVersion: v2
    subnetId: <subnet-id>
    floatingNetworkId: <external-network-id>
    lbMethod: ROUND_ROBIN
    lbProvider: octavia
    createMonitor: true
    monitorDelay: 5s
    monitorTimeout: 3s
    monitorMaxRetries: 3
EOF

helm install openstack-ccm cpo/openstack-cloud-controller-manager \
  -n kube-system -f ccm-values.yaml

Service LoadBalancer

# service-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
  annotations:
    # Annotations Octavia optionnelles
    loadbalancer.openstack.org/floating-network-id: "<external-network-id>"
    loadbalancer.openstack.org/lb-method: "ROUND_ROBIN"
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
kubectl apply -f service-lb.yaml

# Attendre l'IP externe
kubectl get svc nginx-lb -w

# Vérifier dans Octavia
openstack loadbalancer list
openstack floating ip list

Annotations LoadBalancer

Annotation Description
loadbalancer.openstack.org/floating-network-id Réseau pour floating IP
loadbalancer.openstack.org/lb-method ROUND_ROBIN, LEAST_CONNECTIONS, SOURCE_IP
loadbalancer.openstack.org/timeout-client-data Timeout client
loadbalancer.openstack.org/timeout-member-data Timeout backend
loadbalancer.openstack.org/x-forwarded-for Activer header X-Forwarded-For
loadbalancer.openstack.org/keep-floatingip Conserver FIP après suppression

Ingress Controller avec Octavia

# Installer Nginx Ingress avec service LoadBalancer
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx --create-namespace \
  --set controller.service.type=LoadBalancer \
  --set controller.service.annotations."loadbalancer\.openstack\.org/floating-network-id"="<external-network-id>"

# Attendre l'IP
kubectl get svc -n ingress-nginx ingress-nginx-controller -w

Ingress Resource

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls

Diagramme Ingress

graph TB
    users[Users]

    subgraph openstack[OpenStack]
        fip[Floating IP<br/>203.0.113.20]
        octavia[Octavia LB<br/>Port 80, 443]
    end

    subgraph k8s[Kubernetes]
        svc_ingress[Service Ingress<br/>LoadBalancer]
        ingress_ctrl[Nginx Ingress Controller<br/>Deployment<br/>Route by host/path]

        ingress_app[Ingress app.example.com<br/>/]
        ingress_api[Ingress api.example.com<br/>/v1]

        svc_app[Service app<br/>ClusterIP]
        svc_api[Service api<br/>ClusterIP]

        pods_app[Pods app]
        pods_api[Pods api]
    end

    users -->|HTTPS 443| fip
    fip --> octavia
    octavia --> svc_ingress
    svc_ingress --> ingress_ctrl

    ingress_ctrl -->|Route app.example.com| ingress_app
    ingress_ctrl -->|Route api.example.com| ingress_api

    ingress_app --> svc_app
    ingress_api --> svc_api

    svc_app --> pods_app
    svc_api --> pods_api

TLS avec cert-manager

# Installer cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml

# ClusterIssuer pour Let's Encrypt
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx
EOF
# Ingress avec TLS automatique
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app
                port:
                  number: 80
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls  # Sera créé automatiquement

Exemples pratiques

Vérification LoadBalancer

# Status du service
kubectl describe svc nginx-lb

# LoadBalancer Octavia
openstack loadbalancer list
openstack loadbalancer show <lb-id>

# Pool et membres
openstack loadbalancer pool list --loadbalancer <lb-id>
openstack loadbalancer member list <pool-id>

# Health monitor
openstack loadbalancer healthmonitor list

# Test
curl http://<external-ip>

Monitoring LoadBalancer

# Métriques Octavia
openstack loadbalancer stats show <lb-id>

# Logs CCM
kubectl logs -n kube-system -l k8s-app=openstack-cloud-controller-manager

Troubleshooting

# Service sans IP externe
kubectl describe svc <service-name>
# Vérifier les events

# Logs CCM
kubectl logs -n kube-system deployment/openstack-cloud-controller-manager

# Vérifier Octavia
openstack loadbalancer list
openstack loadbalancer amphora list

# Provisioning bloqué
openstack loadbalancer show <lb-id> -c provisioning_status -c operating_status

Ressources

Checkpoint

  • Cloud Controller Manager installé
  • Service type LoadBalancer crée un LB Octavia
  • Floating IP assignée automatiquement
  • Application accessible via l'IP externe
  • Ingress Controller déployé
  • Ingress routes le trafic par host/path
  • TLS configuré (cert-manager optionnel)