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.