OpenShift est une solution polyvalente s’appuyant sur Kubernetes, orchestrant l’exécution d’images Docker. Orientée Micro-services, pour connecter les différents conteneurs composant une application, Kubernetes proposera le type d’objet “Service“. Il existe plusieurs types de Services : le plus couramment utilise, le ClusterIP, exposera notre conteneur dans le SDN du cluster, limitant son accès aux autres acteurs du cluster :

$ cat << EOF >clusterip.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    description: Exposes CodiMD
  name: codimd-wsweet
spec:
  ports:
  - name: codimd
    port: 3000
    protocol: TCP
    targetPort: 3000
  selector:
    name: codimd-wsweet
  type: ClusterIP
EOF
$ oc create -f clusterip.yaml
$ oc get svc codimd-wsweet
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
codimd-wsweet   ClusterIP   172.30.147.249           3000/TCP   42s

Lorsque l’on voudra exposer un Service a l’extérieur du cluster, par exemple pour permettre la sauvegarde d’une base de données hébergée dans le cluster, par une solution externe, nous pourrions utiliser le type NodePort : un port non-privilegié statique est aléatoirement alloué a ces Services. Nous pourrons alors joindre ce service en interrogeant n’importe quel noeud du cluster, sur le port en question :

$ cat << EOF >nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    description: Exposes Postgres
  name: postgres-wsweet
spec:
  ports:
  - name: postgres
    port: 5432
    protocol: TCP
  selector:
    name: postgres-wsweet
  type: NodePort
EOF
$ oc create -f nodeport.yaml
$ oc get svc postgres-wsweet
NAME             TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
postgres-wsweet  NodePort   172.30.176.227           5432:32455/TCP  42s
$ psql  -p32455
[...]

Dans certains cas, de telles translations de ports ne pourront pas répondre au besoin. Nous pourrions alors utiliser les IPs d’ingress. Dans un premier temps, nous éditerons le fichier /etc/origin/master/master-config.yaml, sur tous les noeuds Master du cluster, pour y rajouter un paramètre networkConfig.ingressIPNetworkCIDR :

networkConfig:
  clusterNetworks:
  - cidr: 10.128.0.0/14
    hostSubnetLength: 9
  ingressIPNetworkCIDR: 172.19.0.0/24
  networkPluginName: redhat/openshift-ovs-networkpolicy
  serviceNetworkCIDR: 172.30.0.0/16

Nous choisirons d’utiliser 172.19.0.0/24, réseau qui est ici dédie a OpenShift, distinct des réseaux de services (172.30.0.0/16) et conteneurs (10.128.0.0/14) originalement choisis au déploiement du cluster. Après l’ajout de ce paramètre dans notre configuration, nous devrons redémarrer les services master-api et master-controllers des noeuds Master du cluster :

# master-restart api
# master-restart controllers

Nous pourrons alors créer nos Services avec le type LoadBalancer, leur attribuant une IP choisie dans le réseau précédemment désigné.

$ cat << EOF >loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: openldap-bluemind
spec:
  loadBalancerIP: 172.19.0.1
  ports:
  - port: 389
    protocol: TCP
    name: ldap
    targetPort: 389
  - port: 636
    protocol: TCP
    name: ldaps
    targetPort: 636
  selector:
    name: openldap-wsweet
  type: LoadBalancer
EOF
$ oc create -f loadbalancer.yaml
$ oc get svc openldap-bluemind
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP            PORT(S)                      AGE
openldap-bluemind LoadBalancer   172.30.212.10   172.19.0.1,172.19.0.1  389:31101/TCP,636:31102/TCP  42s

Restera a s’assurer que notre réseau d’ingress soit joignable depuis le reste de notre LAN, en rajoutant la route nécessaire :

router# route add -net 172.19.0.0/24 gw node1

Et confirmer que notre service soit joignable depuis un poste, hors du cluster OpenShift :

$ ldapsearch -H ldaps://172.19.0.1/ -D xxx -w xx
[...]

Notons que cet exemple reste perfectible, centralisant tous les échanges a destination du réseau d’ingress vers un unique noeud du cluster. L’utilisation d’une VIP partagée par certains noeuds du cluster, ou celle d’OSPF, permettront d’assurer la bonne disponibilité du réseau d’ingress, sans risquer qu’un incident affectant un noeud ne coupe tout le trafic. Rappelons qu’OpenShift propose par ailleurs le type d’objet “Route” pouvant exposer des services de type HTTP a l’extérieur du cluster, s’appuyant sur un cluster HAProxy redirigeant les requettes entrantes fonctions du nom de domaine interroge. Les IPs d’Ingress seront particulièrement utiles pour exposer des services non TCP, ou non HTTP.