{"id":18384880,"url":"https://github.com/allegro/consul-registration-hook","last_synced_at":"2025-04-06T23:32:54.459Z","repository":{"id":29336410,"uuid":"121387001","full_name":"allegro/consul-registration-hook","owner":"allegro","description":"Hook that can be used for synchronous registration and deregistration in Consul discovery service on Kubernetes or Mesos cluster with Allegro executor","archived":false,"fork":false,"pushed_at":"2024-12-11T22:41:26.000Z","size":2376,"stargazers_count":17,"open_issues_count":5,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-22T09:25:07.055Z","etag":null,"topics":["consul","kubernetes","marathon","mesos","work-in-progress"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allegro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-13T13:42:05.000Z","updated_at":"2024-09-26T10:56:22.000Z","dependencies_parsed_at":"2024-06-19T01:42:27.059Z","dependency_job_id":null,"html_url":"https://github.com/allegro/consul-registration-hook","commit_stats":{"total_commits":63,"total_committers":9,"mean_commits":7.0,"dds":0.5873015873015873,"last_synced_commit":"4f8aabc5966038c532cd6dacd447bbc75576f9b2"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allegro%2Fconsul-registration-hook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allegro%2Fconsul-registration-hook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allegro%2Fconsul-registration-hook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allegro%2Fconsul-registration-hook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allegro","download_url":"https://codeload.github.com/allegro/consul-registration-hook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247569139,"owners_count":20959758,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consul","kubernetes","marathon","mesos","work-in-progress"],"created_at":"2024-11-06T01:15:47.357Z","updated_at":"2025-04-06T23:32:53.448Z","avatar_url":"https://github.com/allegro.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Consul Registration Hook\n\n[![Build Status](https://github.com/allegro/consul-registration-hook/actions/workflows/golangci.yaml/badge.svg)](https://github.com/allegro/consul-registration-hook/actions/workflows/golangci.yaml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/allegro/consul-registration-hook)](https://goreportcard.com/report/github.com/allegro/consul-registration-hook)\n[![Codecov](https://codecov.io/gh/allegro/consul-registration-hook/branch/master/graph/badge.svg)](https://codecov.io/gh/allegro/consul-registration-hook)\n[![GoDoc](https://godoc.org/github.com/allegro/consul-registration-hook?status.svg)](https://godoc.org/github.com/allegro/consul-registration-hook)\n\nHook that can be used for synchronous registration and deregistration in\n[Consul][1] discovery service on [Kubernetes][2] or [Mesos][3] cluster with\nAllegro [executor][4].\n\n## Why hook uses synchronous communication\n\nSynchronous communication with Consul allows to achieve a gracefull shutdown of\nold application version during the deployment. New instances are considered\nrunning and healthy when they are registered succesfully in discovery service.\nOld instances are first deregistered and then killed with configurable delay,\nwhich allows to propagate deregistration across whole Consul cluster and its\nclients.\n\nSynchronous communication has one drawback - deregistration from Consul may never\ntake place. This situation is mitigated by forcing to use `DeregisterCriticalServiceAfter`\nfield in Consul checks, which deregisters automatically instances that are\nunhealthy for too long. The time after which unhealthy instances are removed can\nbe long enough that some other application will start up on the same address and\nstart responding to Consul checks - this is mitigated by using service ID\ncomposed from IP and port of the instance that should be registered. This results\nin overwriting the old obsolete instance with a new one, accelerating the\ncleaning of the Consul service catalog.\n\n## Usage\n\n### Kubernetes\n\nOn Kubernetes the hook is fired by using [Container Lifecycle Hooks][7]:\n\n```yaml\n# container\nlifecycle:\n  postStart:\n    exec:\n      command: [\"/bin/sh\", \"-c\", \"/hooks/consul-registration-hook register k8s\"]\n  preStop:\n    exec:\n      command: [\"/bin/sh\", \"-c\", \"/hooks/consul-registration-hook deregister k8s\"]\n```\n\nHook requires additional configuration passed by environmental variables. Because\nthe pod name and namespace is not passed by default to the container they have\nto be passed manually:\n\n```yaml\n# container\nenv:\n  - name: KUBERNETES_POD_NAME\n    valueFrom:\n      fieldRef:\n        fieldPath: metadata.name\n  - name: KUBERNETES_POD_NAMESPACE\n    valueFrom:\n      fieldRef:\n        fieldPath: metadata.namespace\n```\n\nOptionally, if Consul agent requires token for authentication it can be passed\nby using [Secrets][8]:\n\n```yaml\ncontainers:\n# ... other configuration ...\n    volumeMounts:\n      - name: consul-acl\n        mountPath: /consul-acl\n    lifecycle:\n    postStart:\n      exec:\n        command: [\"/bin/sh\", \"-c\", \"/hooks/consul-registration-hook --consul-acl-file /consul-acl/token register k8s\"]\n    preStop:\n      exec:\n        command: [\"/bin/sh\", \"-c\", \"/hooks/consul-registration-hook --consul-acl-file /consul-acl/token deregister k8s\"]\n# ... other configuration ...\nvolumes:\n  - name: consul-acl\n    secret:\n      secretName: consul-acl\n      items:\n      - key: agent-token\n        path: token\n        mode: 511\n```\n\n#### Production\n\nIt is recommended to have a local copy of the hook on the production environment.\nFor example on Google Cloud Platform you can have a copy of the hook in dedicated\nCloud Storage bucket. Then you can authorize Compute Engine service account to\nhave read only access to the bucket. After everything is prepared you can use\n[Init Container][9] to download hook and expose it on shared volume to the main\ncontainer:\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: pod-with-consul-hook\n  labels:\n    consul: service-name\nspec:\n  initContainers:\n  - name: hook-init-container\n    image: google/cloud-sdk:alpine\n    imagePullPolicy: Always\n    command: [\"/bin/sh\"]\n    args: [\"-c\", \"gsutil cat ${GS_URL} | tar -C /hooks -zxvf -\"]\n    env:\n    - name: GS_URL\n        valueFrom:\n          configMapKeyRef:\n            name: consul-registration-hook\n            key: GS_URL\n    volumeMounts:\n    - name: hooks\n      mountPath: /hooks\n  containers:\n  - name: service-with-consul-hook-container\n    image: python:2\n    command: [\"python\", \"-m\", \"SimpleHTTPServer\", \"8080\"]\n    env:\n    - name: KUBERNETES_POD_NAME\n      valueFrom:\n        fieldRef:\n          fieldPath: metadata.name\n    - name: KUBERNETES_POD_NAMESPACE\n      valueFrom:\n        fieldRef:\n          fieldPath: metadata.namespace\n    - name: HOST_IP\n      valueFrom:\n        fieldRef:\n          fieldPath: status.hostIP\n    - name: CONSUL_HTTP_ADDR\n      value: \"$(HOST_IP):8500\"\n    ports:\n    - containerPort: 8080\n    volumeMounts:\n    - name: hooks\n      mountPath: /hooks\n    lifecycle:\n      postStart:\n        exec:\n          command: [\"/bin/sh\", \"-c\", \"/hooks/consul-registration-hook register k8s\"]\n      preStop:\n        exec:\n          command: [\"/bin/sh\", \"-c\", \"/hooks/consul-registration-hook deregister k8s\"]\n  volumes:\n  - name: hooks\n    emptyDir: {}\n```\n\n### Mesos\n\nRegistration based on data provided from Mesos API is supported only partially.\nBecause Mesos API do not provide health check definions we are unable to sync\nthem with Consul agent.\n\n## Development\n\n### Kubernetes integration\n\nTo develop the hook locally you need the following things to be installed on\nyour machine:\n\n* [Minikube][5]\n* [Go][6]\n\nWhen everything is installed and setup properly, you can build hook for the Linux\noperating system (as Minikube starts Kubernetes cluster on Linux virtual machine):\n\n```bash\nmake build-linux\n```\n\nAfter successful build, you can start your local mini Kubernetes cluster with\nproject root mounted to the Kubernetes virtual machine:\n\n```bash\nminikube start --mount --mount-string .:/hooks\n```\n\n#### Simple usecase, consul agent in separate container in the pod\n\nCreate a pod with Consul agent in development mode and hooks mounted:\n\n```bash\nkubectl create -f ./examples/service-for-dev.yaml\n```\n\nYou can login to the container with hooks using the following command:\n\n```bash\nkubectl exec -it myservice-pod -- /bin/bash\n```\n\n#### Consul ACL \u0026 DaemonSet usecase\n\nCreate consul secret:\n\n```bash\nkubectl create -f ./examples/secret-for-consul-agent.yaml\n```\n\nCreate consul agent DaemonSet:\n\n```bash\nkubectl create -f ./examples/daemonset-with-acl-bootstrapping.yaml\n```\n\nCreate service pod:\n\n```bash\nkubectl create -f ./examples/service-with-consul-lifecycle-hooks-and-acl-support.yaml\n```\n\nYou can find the hook binary in `/hooks` folder on the container. All required\nenvironment variables are set up so you can run a command without any additional\nconfiguration.\n\n### Mesos integration\n\nTo develop the hook locally you need the following things to be installed on\nyour machine:\n\n* [Docker CE][10]\n* [Go][6]\n\nWhen everything is installed and setup properly, you can build hook for the Linux\noperating system (we will use dockerized Mesos cluster for development):\n\n```bash\nmake build-linux\n```\n\nAfter successful build, you can start your local Mesos + Marathon cluster:\n\n```bash\ndocker-compose up\n```\n\nHook binary is available on Mesos slave container in `/opt/consul-registration-hook/`\nfolder, and can be used directly when deploying apps using Marathon (localhost:8080).\n\n[1]: https://www.consul.io/\n[2]: https://kubernetes.io/\n[3]: http://mesos.apache.org/\n[4]: https://github.com/allegro/mesos-executor/\n[5]: https://kubernetes.io/docs/getting-started-guides/minikube/\n[6]: https://golang.org/doc/install\n[7]: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/\n[8]: https://kubernetes.io/docs/concepts/configuration/secret/\n[9]: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/\n[10]: https://www.docker.com/get-docker\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallegro%2Fconsul-registration-hook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallegro%2Fconsul-registration-hook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallegro%2Fconsul-registration-hook/lists"}