Configurer un drone sur le cluster Kubernets arm64


Poursuivant avec les récits multiarchitecture et Kubernetes sur lesquels j'écris depuis un certain temps maintenant, dans cet article, je présenterai certaines des capacités de l'outil d'intégration continue Drone.io exécuté sur mon cluster homelab arm64 Kubernetes.

Alors que arm64 continue de gagner en popularité, de plus en plus de projets ajoutent un support pour celui-ci, y compris Drone.io. Avec son annonce semi-récente, Drone peut désormais fonctionner sur une variété d'architectures différentes. De même, les mainteneurs de drones ont également travaillé à une version 1.0, qui apporte, entre autres, un support de première classe pour Kubernetes.

Je ne vais pas aborder trop de spécificités de Drone, mais si vous souhaitez en savoir plus, vous pouvez consulter le site Web. Je me concentrerai principalement sur la façon de faire fonctionner les choses dans Kubernetes, qui se révèle être exactement le même pour les architectures amd64 et arm64. Il y a eu quelques choses que j'ai découvertes en cours de route pour faire fonctionner les intégrations Kubernetes, mais pour la plupart, les choses «fonctionnent juste».

J'ai commencé en saisissant le graphique Helm et en le modifiant selon mes besoins. Je trouve plus facile de modéliser le graphique, puis de l'enregistrer localement afin de pouvoir jouer avec.

Remarque: l'exemple ci-dessous suppose que Helm est déjà installé localement.

git clone (email protected):helm/charts.git && cd charts
helm template --name drone --namespace cicd 
   --set 'sourceControl.provider=github' 
   --set 'sourceControl.github.clientID=XXXXXXXX' 
   --set 'sourceControl.secret=drone-server-secrets' 
   --set 'server.host=drone.example.com' 
   --set 'server.kubernetes.enabled=false' 
   stable/drone > /tmp/manifest.yaml

Évidemment, vous voudrez définir les configurations pour correspondre à vos propres paramètres, comme le nom de domaine et les paramètres oauth (j'ai utilisé Github).

Après avoir enregistré le manifeste, le premier problème que j'ai rencontré est que le port 9000 est toujours référencé dans le graphique Helm, qui était utilisé pour la communication entre le client et le serveur dans les anciennes versions, mais n'est plus utilisé. J'ai donc complètement supprimé les références au port dans ma configuration Frankenstein. Si vous utilisez simplement la configuration Kubernetes mentionnée ci-dessous, vous ne rencontrerez pas ces problèmes de connexion au serveur et à l'agent, mais si vous utilisez l'agent, vous le ferez.

Il y a une configuration de serveur qui devra également être ajustée pour que les choses fonctionnent. Par exemple, les paramètres oauth devront d'abord être créés côté Github pour que tout cela fonctionne. En outre, l'hôte du serveur de drone devra être accessible depuis Internet, de sorte que toutes les règles de pare-feu devront être ajoutées ou ajustées pour autoriser le trafic.

 env:
  # Webhook setings
  - name: DRONE_ALWAYS_AUTH
    value: "false"
  - name: DRONE_SERVER_HOST
    value: "drone.example.com"
  - name: DRONE_SERVER_PROTO
    #value: http
    value: https
  # Agent config
  - name: DRONE_RPC_SECRET
    valueFrom:
      secretKeyRef:
        name: drone
        key: secret
  # Server config
  - name: DRONE_DATABASE_DATASOURCE
    value: "/var/lib/drone/drone.sqlite"
  - name: DRONE_DATABASE_DRIVER
    value: "sqlite3"
  - name: DRONE_LOGS_DEBUG
    value: "true"
  - name: DRONE_LOGS_PRETTY
    value: "true"
  - name: DRONE_USER_CREATE
    value: "username:,machine:false,admin:true,token:abc123"
  # Github config
  - name: DRONE_GITHUB_CLIENT_ID
    value: abcd
  - name: DRONE_GITHUB_SERVER
    value: https://github.com
  - name: DRONE_GITHUB_CLIENT_SECRET
    valueFrom:
      secretKeyRef:
        name: client-secret-drone
        key: secret

Ajoutez la var env DRONE_USER_CREATE pour démarrer un compte administrateur lors du démarrage du serveur Drone. Cela permettra à votre utilisateur d'effectuer toutes les tâches d'administration à l'aide de l'outil CLI.

Les secrets doivent donc être générés lorsque vous videz le graphique Helm, alors n'hésitez pas à mettre à jour ceux avec les valeurs dont vous pourriez avoir besoin.

Remarque: si vous avez revérifié tous vos paramètres mais que les builds ne sont pas déclenchés, il y a de fortes chances que le webhook soit le problème. Il y a un très bon article sur la façon de dépanner ces paramètres ici.

Exécuter Drone avec l'intégration de Kubernetes

Cette option s'est avérée être l'approche la plus facile. Ajoutez simplement la configuration suivante aux variables d'environnement de déploiement du serveur de drone, en les mettant à jour en fonction de votre environnement. Par exemple, l'espace de noms vers lequel je déploie s'appelle «cicd», qui devra être mis à jour si vous choisissez un autre espace de noms.

- name: DRONE_KUBERNETES_ENABLED
  value: "true"
- name: DRONE_KUBERNETES_NAMESPACE
  value: cicd
- name: DRONE_KUBERNETES_SERVICE_ACCOUNT
  value: drone-pipeline

Le principal inconvénient de cette méthode est qu'elle crée des travaux Kubernetes pour chaque build. Par défaut, une fois ces builds terminés, le se fermera et ne se nettoiera pas, donc si vous faites beaucoup de builds alors votre espace de noms sera bouché. Il existe un moyen de définir les TTL sur fini pour se nettoyer dans les nouvelles versions de Kubernetes via le drapeau TTLAfterFinished mais cette fonctionnalité n'est pas encore par défaut dans Kubernetes et est un peu hors de portée de cet article.

Exécuter Drone avec la configuration de l'agent

L'agent utilise le modèle sidecar pour exécuter un conteneur Docker dans Docker (dind) pour se connecter au socket Docker afin de permettre à l'agent Drone de faire ses builds.

Le principal inconvénient de l'utilisation de cette approche est qu'il semble y avoir (parfois) un problème où les composants du drone ne peuvent pas communiquer avec la socket Docker, vous pouvez trouver une meilleure description de ce problème et plus de détails ici. Le problème semble être une condition de concurrence où le socket docker ne peut pas être monté avant que l'agent ne se lève, mais je n'ai pas encore totalement résolu le problème. Le conseil pour contourner ce problème consiste à exécuter l'agent sur un hôte autonome dédié pour éviter les conditions de course et autres pièges.

Cela dit, si vous souhaitez toujours utiliser cette méthode, vous devrez ajouter un déploiement supplémentaire à la configuration de l'agent de drone. Si vous utilisez l'agent, vous pouvez ignorer les configurations de variables d'environnement Kubernetes ci-dessus et définir à la place les variables d'environnement appropriées dans l'agent. Vous trouverez ci-dessous l'extrait de travail que j'ai utilisé pour déployer l'agent sur mon cluster de test.


---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: drone-agent
  labels:
    app: drone
    component: agent
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: drone
        component: agent
    spec:
      serviceAccountName: drone
      containers:
      - name: agent
        image: "docker.io/drone/agent:1.0.0-rc.6"
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 3000
          protocol: TCP
        env:
          # This value should point to the Drone server service
          - name: DRONE_RPC_SERVER
            value: http://drone.cicd
          - name: DRONE_RPC_SECRET
            valueFrom:
              secretKeyRef:
                name: drone
                key: secret
          - name: DOCKER_HOST
            value: tcp://localhost:2375
          - name: DRONE_LOGS_DEBUG
            value: "true"
          # Uncomment this for additional trace logs
          #- name: DRONE_LOGS_TRACE
          #  value: "true"
          - name: DRONE_LOGS_PRETTY
            value: "true"

      - name: dind
        image: "docker.io/library/docker:18.06-dind"
        imagePullPolicy: IfNotPresent
        env:
        - name: DOCKER_DRIVER
          value: overlay2

        securityContext:
          privileged: true

        volumeMounts:
          - name: docker-graph-storage
            mountPath: /var/lib/docker
      volumes:
      - name: docker-graph-storage
        emptyDir: {}

J'ai réussi à faire travailler l'agent, je n'ai pas eu beaucoup de succès à le faire fonctionner de manière cohérente. J'éviterais d'utiliser cette méthode à moins que vous ne deviez ou comme mentionné ci-dessus, obtenir un hôte dédié pour l'exécution des builds.

Tester

Après avoir tout câblé, le reste est facile. Ajoutez un fichier appelé .drone.yml à un référentiel pour lequel vous souhaitez automatiser les builds. Vous pouvez en savoir plus sur les différentes fonctionnalités ici.

Pour mon cas d'utilisation, je voulais dire au drone de créer et de publier une image Docker basée sur arm64 chaque fois qu'un changement de maître se produit. Vous pouvez consulter ma configuration de drone ici pour avoir une meilleure idée des options multiarchitecture ainsi que l'authentification dans un registre Docker.

Après avoir ajouté le .drone.yml à votre dépôt et déclenché une construction, vous devriez voir quelque chose de similaire dans votre instance Drone locale.

Exemple de construction de drone

Si tout fonctionnait correctement et était vert, alors vous devriez être prêt à partir. Évidemment, il y a beaucoup de frais généraux que Kubernetes apporte, mais la configuration réelle du drone est vraiment simple. Il vous suffit de configurer le côté Github, de le traduire en configurations Kubernetes et d'ajouter d'autres options de configuration spécifiques au drone et vous devriez avoir un bel environnement CI / CD prêt à l'emploi.

Conclusion

Je suis très heureux de voir Drone grandir et mûrir et l'utiliser davantage à l'avenir. Il est simple mais flexible et il s'intègre parfaitement dans le nouveau paradigme de l'utilisation de conteneurs pour tout.

La nouvelle syntaxe 1.0 YAML est également très agréable, car elle correspond essentiellement aux conventions choisies par Kubernetes, donc si vous connaissez cette syntaxe, vous devriez vous sentir chez vous. Vous pouvez consulter les plugins disponibles ici, qui couvrent environ 90% des cas d'utilisation que vous verriez dans la nature.

Un inconvénient est que les erreurs de syntaxe YAML sont vraiment difficiles à déboguer, et il n'y a pas grand-chose en sortie pour déterminer où sont vos problèmes. La meilleure approche que j'ai trouvée consiste à exécuter le fichier .drone.yml via l'outil Drone CLI lint / fmt avant de valider et de générer.

L'outil Drone CLI est vraiment puissant et pourrait probablement être son propre article. Il y a quelques liens dans les références qui montrent certaines de ses autres fonctionnalités.

Les références

Il y a quelques ressources Drone sympas que je recommanderais certainement de vérifier si vous êtes intéressé à exécuter Drone dans votre propre environnement. La référence aux documents est un excellent point de départ et est idéale pour trouver des informations sur la façon de configurer et de modifier divers paramètres du drone.

https://docs.drone.io/reference/

Voici un lien vers la référence CLI.

https://github.com/drone/awesome-drone

Je recommande également de vérifier les documents d'extension jsonnet, qui peuvent être utilisés pour améliorer les flux de travail d'automatisation. Le deuxième lien montre un bon exemple de son fonctionnement.

https://docs.drone.io/extend/config/jsonnet/
https://github.com/drone/drone/blob/master/.drone.jsonnet

Voici un lien pour divers trucs sympas de drones, y compris des articles de blog et des outils.

https://docs.drone.io/cli/

Nous serions ravis de connaître votre avis

      Laisser un commentaire