Définir une Ressource Personnalisée (CRD) pour Kubernetes

Pour créer une Ressource Personnalisée (CRD) dans Kubernetes, vous aurez besoin de quelques outils et d'une compréhansion claire de la structure de votre ressource. Ce guide vous présente comment installer les dépendances nécessaires, définir une fonction utilitaire pour le rendu de modèles Jinja2, créer une CRD d'exemple, puis générer et gérer des instences de cette ressource.

Installation des Outils

Assurez-vous d'avoir Python installé et utilisez pip pour installer les bibliothèques requises.

pip3 install Jinja2 PyYAML
pip3 install yq

Fonction de Rendu Jinja2

La fonction suivante simplifie le processus de rendu de fichiers modèles Jinja2 en fournissant le contenu des variables à la volée.

render_template() {
 local template_file="$1"
 local context_json="$2"

 local template_dir=$(dirname "$template_file")
 local template_name=$(basename "$template_file")

 if [[ -z "$template_dir" || "$template_dir" == "." ]]; then
   template_dir="./"
 fi

 python3 -c "
from jinja2 import Environment, FileSystemLoader
import json

context = json.loads('$context_json')
loader = FileSystemLoader('$template_dir')
env = Environment(loader=loader)
template = env.get_template('$template_name')
rendered_output = template.render(context)
print(rendered_output)
"
}

Exemple de Définition de CRD

Ci-dessous, un exemple de CRD pour définir une ressource nommée GnbMCS dans le groupe pwek.smart.edge.org. Cette CRD spécifie la structure attendue pour les objets de ce type, y compris des champs pour les configurations de liaison montante (UL), liaison descendante (DL), et d'autres paramètres.

cat <<eof antenna="" apiextensions.k8s.io="" apiversion:="" apply="" bcch.="" customresourcedefinition="" default:="" description:="" dl="" downlink="" downlinkantennaportsbcch:="" downlinkantennaportspcch:="" downlinkrankmax:="" eof="" for="" gnbmcs="" gnbmcses="" gnbmcses.pwek.smart.edge.org="" group:="" integer="" kind:="" kubectl="" maximum:="" mcs="" metadata:="" minimum:="" name:="" names:="" namespaced="" object="" of="" openapiv3schema:="" pcch.="" plural:="" ports="" ports.="" properties:="" pwek.smart.edge.org="" rank="" ranks.="" schema:="" scope:="" served:="" shortnames:="" singular:="" spec:="" storage:="" true="" type:="" ul="" uplink="" uplinkantennaports:="" uplinkrankmax:="" v1="" value.="" versions:=""></eof>

Exemple de Modèle Jinja2 pour une Instance de Ressource

Créez un fichier modèle (par exemple, gnb_mcs_template.yaml.j2) qui définit la structure d'une instance de GnbMCS. Les valeurs seront injectées via le moteur Jinja2.

cat << EOF > gnb_mcs_template.yaml.j2
---
apiVersion: "pwek.smart.edge.org/v1"
kind: GnbMCS
metadata:
 namespace: pwek-system
 name: primary-config
spec:
 uplinkRankMax: {{ ul_rank }}
 downlinkRankMax: {{ dl_rank }}
 uplinkAntennaPorts: {{ ul_ports }}
 downlinkAntennaPortsBCCH: {{ bcch_ports }}
 downlinkAntennaPortsPCCH: {{ pcch_ports }}
EOF

Création d'une Instance de Ressource

Préparez les données nécesssaires pour votre instance de ressource.

# Définir les variables de configuration
DL_RANK_VAL=12
UL_RANK_VAL=15
UL_PORTS_VAL=8
BCCH_PORTS_VAL=10
PCCH_PORTS_VAL=10

Utilisez la fonction render_template pour générer le fichier YAML de l'instance de ressource et appliquez-le à Kubernetes.

CONTEXT_DATA=$(jq -n \
 --argjson dl_rank "$DL_RANK_VAL" \
 --argjson ul_rank "$UL_RANK_VAL" \
 --argjson ul_ports "$UL_PORTS_VAL" \
 --argjson bcch_ports "$BCCH_PORTS_VAL" \
 --argjson pcch_ports "$PCCH_PORTS_VAL" \
 '{dl_rank: $dl_rank, ul_rank: $ul_rank, ul_ports: $ul_ports, bcch_ports: $bcch_ports, pcch_ports: $pcch_ports}')

render_template gnb_mcs_template.yaml.j2 "$CONTEXT_DATA" | kubectl apply -f -

Vérification de la CRD

Vous pouvez lister toutes les ressources personnalisées enregistrées dans votre cluster pour confirmer que votre CRD est bien reconnue.

kubectl api-resources --api-group=pwek.smart.edge.org

Vérification de l'Instance de Ressource

Pour vérifier l'instance de ressource que vous venez de créer, utilisez la commande kubectl get.

NAMESPACE="pwek-system"

kubectl get -n "$NAMESPACE" mcs

kubectl get -n "$NAMESPACE" mcs primary-config -o jsonpath="{.spec}" | jq

Mise à Jour d'une Instance de Ressource

Pour modifier une instance existante, vous pouvez utiliser kubectl patch. Voici un exemple pour mettre à jour la valeur de downlinkRankMax.

NAMESPACE="pwek-system"

PATCH_DATA=$(jq -n --argjson new_dl_rank 18 '{spec: {downlinkRankMax: $new_dl_rank}}')

kubectl patch -n "$NAMESPACE" mcs primary-config --type='merge' -p "$PATCH_DATA"

kubectl get -n "$NAMESPACE" mcs primary-config -o jsonpath="{.spec}" | jq

Exemple de Traitement de Fichiers XML Multiples

Dans certains cas, vous pourriez avoir besoin de traiter des données structurées au format XML. L'outil xq (une version de jq pour XML) peut être utile.

Créez un fichier exemple contenant plusieurs blocs XML.

cat << EOF > data.xml
<?xml version="1.0" encoding="UTF-8"??>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <capabilities>
     <capability>urn:ietf:params:netconf:base:1.0</capability>
  </capabilities>
</hello>
]]>]]>
<?xml version="1.0" encoding="UTF-8"??>
<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
     <config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <gnbconfig xmlns="urn:rdns:com:radisys:nr:gnb">
           <gnbducfg>
              <id>1</id>
              <heartbeatintervalinms>10000</heartbeatintervalinms>
           </gnbducfg>
       </gnbconfig>
     </config>
</rpc>
]]>]]>
<?xml version="1.0" encoding="UTF-8"??>
<rpc message-id="102" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <ok></ok>
</rpc>
]]>]]>
EOF

Pour extraire une valeur spécifique, vous pouvez utiliser une combinaison de sed et xq.

# Extraire la valeur de heartBeatIntervalInMs
sed -e '1,/]]>]]>/d' -e 's/^]]>]]>//' data.xml | \
 xq -R '.rpc.config.gnbConfig.gnbDuCfg.heartBeatIntervalInMs'

Étiquettes: kubernetes CRD jinja2 YAML kubectl

Publié le 18 juin à 00h57