{"id":22757919,"url":"https://github.com/d2iq-archive/marathon-lb","last_synced_at":"2025-08-09T00:31:16.603Z","repository":{"id":51062574,"uuid":"43829723","full_name":"d2iq-archive/marathon-lb","owner":"d2iq-archive","description":"Marathon-lb is a service discovery \u0026 load balancing tool for DC/OS","archived":true,"fork":false,"pushed_at":"2021-05-25T09:49:37.000Z","size":1292,"stargazers_count":450,"open_issues_count":85,"forks_count":300,"subscribers_count":142,"default_branch":"master","last_synced_at":"2024-12-11T08:06:54.195Z","etag":null,"topics":["dcos","dcos-networking-guild","haproxy","haproxy-templates","letsencrypt","load-balancer","marathon","marathon-api","marathon-lb","mesos","mesosphere","service-discovery"],"latest_commit_sha":null,"homepage":"","language":"Python","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/d2iq-archive.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":null,"security":null,"support":null}},"created_at":"2015-10-07T16:36:32.000Z","updated_at":"2024-12-04T10:51:21.000Z","dependencies_parsed_at":"2022-09-04T04:22:04.672Z","dependency_job_id":null,"html_url":"https://github.com/d2iq-archive/marathon-lb","commit_stats":null,"previous_names":["d2iq-archive/marathon-lb"],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d2iq-archive%2Fmarathon-lb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d2iq-archive%2Fmarathon-lb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d2iq-archive%2Fmarathon-lb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d2iq-archive%2Fmarathon-lb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d2iq-archive","download_url":"https://codeload.github.com/d2iq-archive/marathon-lb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229193853,"owners_count":18034497,"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":["dcos","dcos-networking-guild","haproxy","haproxy-templates","letsencrypt","load-balancer","marathon","marathon-api","marathon-lb","mesos","mesosphere","service-discovery"],"created_at":"2024-12-11T08:07:25.101Z","updated_at":"2024-12-11T08:07:26.165Z","avatar_url":"https://github.com/d2iq-archive.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# marathon-lb [![Build Status](https://jenkins.mesosphere.com/service/jenkins/buildStatus/icon?job=marathon-lb/public-marathon-lb-master)](https://jenkins.mesosphere.com/service/jenkins/job/marathon-lb/job/public-marathon-lb-master/)\n\nMarathon-lb is a tool for managing HAProxy, by consuming\n[Marathon's](https://github.com/mesosphere/marathon) app state. HAProxy is a\nfast, efficient, battle-tested, highly available load balancer with many advanced features which power a number of high-profile websites.\n\n### Features\n\n * **Stateless design**: no direct dependency on any third-party state store like ZooKeeper or etcd (_except through Marathon_)\n * **Idempotent and deterministic**: scales horizontally\n * **Highly scalable**: [can achieve line-rate](http://www.haproxy.org/10g.html) per instance, with multiple instances providing fault-tolerance and greater throughput\n * **Real-time LB updates**, via [Marathon's event bus](https://mesosphere.github.io/marathon/docs/event-bus.html)\n * Support for Marathon's **health checks**\n * **Multi-cert TLS/SSL** support\n * [Zero-downtime deployments](#zero-downtime-deployments)\n * Per-service **HAProxy templates**\n * DC/OS integration\n * Automated Docker image builds ([mesosphere/marathon-lb](https://hub.docker.com/r/mesosphere/marathon-lb))\n * Global HAProxy templates which can be supplied at launch\n * Supports IP-per-task integration, such as [Project Calico](https://github.com/projectcalico/calico-containers)\n * Includes [tini](https://github.com/krallin/tini) zombies reaper\n\n### Getting Started\n\n * [Using marathon-lb](https://github.com/mesosphere/marathon-lb/wiki/Using-Marathon-LB)\n * [Securing your service with TLS/SSL (blog post)](https://mesosphere.com/blog/2016/04/06/lets-encrypt-dcos/)\n\nTake a look at [the marathon-lb wiki](https://github.com/mesosphere/marathon-lb/wiki) for example usage, templates, and more.\n\n## Architecture\nThe marathon-lb script `marathon_lb.py` connects to the marathon API\nto retrieve all running apps, generates a HAProxy config and reloads HAProxy.\nBy default, marathon-lb binds to the service port of every application and\nsends incoming requests to the application instances.\n\nServices are exposed on their service port (see\n[Service Discovery \u0026 Load Balancing](https://mesosphere.github.io/marathon/docs/service-discovery-load-balancing)\nfor reference) as defined in their Marathon definition. Furthermore, apps are\nonly exposed on LBs which have the same LB tag (or group) as defined in the Marathon\napp's labels (using `HAPROXY_GROUP`). HAProxy parameters can be tuned by specify labels in your app.\n\nTo create a virtual host or hosts the `HAPROXY_{n}_VHOST` label needs to be set on the\ngiven application. Applications with a vhost set will be exposed on ports 80\nand 443, in addition to their service port. Multiple virtual hosts may be specified\nin `HAPROXY_{n}_VHOST` using a comma as a delimiter between hostnames.\n\nAll applications are also exposed on port 9091, using the `X-Marathon-App-Id`\nHTTP header. See the documentation for `HAPROXY_HTTP_FRONTEND_APPID_HEAD` in\nthe [templates section](Longhelp.md#templates)\n\nYou can access the HAProxy statistics via `:9090/haproxy?stats`, and you can\nretrieve the current HAProxy config from the `:9090/_haproxy_getconfig` endpoint.\n\n## Deployment\nThe package is currently available [from the universe](https://github.com/mesosphere/universe).\nTo deploy marathon-lb on the public slaves in your DC/OS cluster,\nsimply run:\n\n```\ndcos package install marathon-lb\n```\n\nTo configure a custom ssl-certificate, set the dcos cli option `ssl-cert`\nto your concatenated cert and private key in .pem format. For more details\nsee the [HAProxy documentation](https://cbonte.github.io/haproxy-dconv/configuration-1.7.html#crt (Bind options)).\n\nFor further customization, templates can be added by pointing the dcos cli\noption `template-url` to a tarball containing a directory `templates/`.\nSee [comments in script](marathon_lb.py) on how to name those.\n\n### Docker\nSynopsis: `docker run -e PORTS=$portnumber --net=host mesosphere/marathon-lb sse|poll ...`\n\nYou must set `PORTS` environment variable to allow haproxy bind to this port.\nSyntax: `docker run -e PORTS=9090 mesosphere/marathon-lb sse [other args]`\n\nYou can pass in your own certificates for the SSL frontend by setting\nthe `HAPROXY_SSL_CERT` environment variable. If you need more than one\ncertificate you can specify additional ones by setting `HAPROXY_SSL_CERT0` - `HAPROXY_SSL_CERT100`.\n\n#### `sse` mode\nIn SSE mode, the script connects to the marathon events endpoint to get\nnotified about state changes. This only works with Marathon 0.11.0 or\nnewer versions.\n\nSyntax: `docker run mesosphere/marathon-lb sse [other args]`\n\n#### `poll` mode\nIf you can't use the HTTP callbacks, the script can poll the APIs to get\nthe schedulers state periodically.\n\nSyntax: `docker run mesosphere/marathon-lb poll [other args]`\n\nTo change the poll interval (defaults to 60s), you can set the `POLL_INTERVAL`\nenvironment variable.\n\n### Direct Invocation\nYou can also run the update script directly.\nTo generate an HAProxy configuration from Marathon running at `localhost:8080` with the `marathon_lb.py` script, run:\n\n```console\n$ ./marathon_lb.py --marathon http://localhost:8080 --group external --strict-mode --health-check\n```\n\nIt is possible to pass `--auth-credentials=` option if your Marathon requires authentication:\n```console\n$ ./marathon_lb.py --marathon http://localhost:8080 --auth-credentials=admin:password\n```\n\nIt is possible to get the auth credentials (user \u0026 password) from VAULT if you define the following\nenvironment variables before running marathon-lb: VAULT_TOKEN, VAULT_HOST, VAULT_PORT, VAULT_PATH\nwhere VAULT_PATH is the root path where your user and password are located.\n\nThis will refresh `haproxy.cfg`, and if there were any changes, then it will\nautomatically reload HAProxy. Only apps with the label `HAPROXY_GROUP=external`\nwill be exposed on this LB.\n\n`marathon_lb.py` has a lot of additional functionality like sticky sessions, HTTP to HTTPS redirection, SSL offloading, virtual host support and templating capabilities.\n\nTo get the full documentation run:\n``` console\n$ ./marathon_lb.py --help\n```\n\n### Providing SSL Certificates\nYou can provide your SSL certificate paths to be placed in frontend marathon_https_in section with `--ssl-certs`.\n\n``` console\n$ ./marathon_lb.py --marathon http://localhost:8080 --group external --ssl-certs /etc/ssl/site1.co,/etc/ssl/site2.co --health-check --strict-mode\n```\n\nIf you are using the script directly, you have two options:\n\n * Provide nothing and config will use `/etc/ssl/cert.pem` as the certificate path. Put the certificate in this path or edit the file for the correct path.\n * Provide `--ssl-certs` command line argument and config will use these paths.\n\nIf you are using the provided `run` script or Docker image, you have three options:\n\n * Provide your certificate text in `HAPROXY_SSL_CERT` environment variable. Contents will be written to `/etc/ssl/cert.pem`. Config will use this path unless you specified extra certificate paths as in the next option.\n * Provide SSL certificate paths with `--ssl-certs` command line argument. Your config will use these certificate paths.\n * Provide nothing and it will create self-signed certificate on `/etc/ssl/cert.pem` and config will use it.\n\n\n### Skipping Configuration Validation\nYou can skip the configuration file validation (via calling HAProxy service) process if you don't have HAProxy installed. This is especially useful if you are running HAProxy on Docker containers.\n\n``` console\n$ ./marathon_lb.py --marathon http://localhost:8080 --group external --skip-validation\n```\n\n### Using HAProxy Maps for Backend Lookup\nYou can use HAProxy maps to speed up web application (vhosts) to backend lookup. This is very useful for large installations where the traditional vhost to backend rules comparison takes considerable time since it sequentially compares each rule. HAProxy map creates a hash based lookup table so its fast compared to the other approach, this is supported in marathon-lb using `--haproxy-map` flag.\n\n```console\n$ ./marathon_lb.py --marathon http://localhost:8080 --group external --haproxy-map\n```\nCurrently it creates a lookup dictionary only for host header (both HTTP and HTTPS) and X-Marathon-App-Id header. But for path based routing and auth, it uses the usual backend rules comparison.\n\n### API Endpoints\n\nMarathon-lb exposes a few endpoints on port 9090 (by default). They are:\n\n| Endpoint                      | Description                                                                                                                                                                                                                                                                                                               |\n|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `:9090/haproxy?stats`         | HAProxy stats endpoint. This produces an HTML page which can be viewed in your browser, providing various statistics about the current HAProxy instance.                                                                                                                                                                  |\n| `:9090/haproxy?stats;csv`     | This is a CSV version of the stats above, which can be consumed by other tools. For example, it's used in the [`zdd.py`](zdd.py) script.                                                                                                                                                        |\n| `:9090/_haproxy_health_check` | HAProxy health check endpoint. Returns `200 OK` if HAProxy is healthy.                                                                                                                                                                                                                                                    |\n| `:9090/_haproxy_getconfig`    | Returns the HAProxy config file as it was when HAProxy was started. Implemented in [`getconfig.lua`](getconfig.lua).                                                                                                                                                                                                      |\n| `:9090/_haproxy_getvhostmap`  | Returns the HAProxy vhost to backend map. This endpoint returns HAProxy map file only when the `--haproxy-map` flag is enabled, it returns an empty string otherwise. Implemented in [`getmaps.lua`](getmaps.lua).                                                                              |\n| `:9090/_haproxy_getappmap`    | Returns the HAProxy app ID to backend map. Like `_haproxy_getvhostmap`, this requires the `--haproxy-map` flag to be enabled and returns an empty string otherwise. Also implemented in `getmaps.lua`.                                                                                          |\n| `:9090/_haproxy_getpids`      | Returns the PIDs for all HAProxy instances within the current process namespace. This literally returns `$(pidof haproxy)`. Implemented in [`getpids.lua`](getpids.lua). This is also used by the [`zdd.py`](zdd.py) script to determine if connections have finished draining during a deploy. |\n| `:9090/_mlb_signal/hup`*      | Sends a `SIGHUP` signal to the marathon-lb process, causing it to fetch the running apps from Marathon and reload the HAProxy config as though an event was received from Marathon.                                                                                                             |\n| `:9090/_mlb_signal/usr1`*     | Sends a `SIGUSR1` signal to the marathon-lb process, causing it to restart HAProxy with the existing config, without checking Marathon for changes.                                                                                                                                             |\n| `:9090/metrics`               | Exposes HAProxy metrics in prometheus format.                                                                                                                                                                                                                                                   |\n\n\\* These endpoints won't function when marathon-lb is in `poll` mode as there is no marathon-lb process to be signaled in this mode (marathon-lb exits after each poll).\n\n## HAProxy Configuration\n\n### App Labels\nApp labels are specified in the Marathon app definition. These can be used to override HAProxy behaviour. For example, to specify the `external` group for an app with a virtual host named `service.mesosphere.com`:\n\n```json\n{\n  \"id\": \"http-service\",\n  \"labels\": {\n    \"HAPROXY_GROUP\":\"external\",\n    \"HAPROXY_0_VHOST\":\"service.mesosphere.com\"\n  }\n}\n```\n\nSome labels are specified _per service port_. These are denoted with the `{n}` parameter in the label key, where `{n}` corresponds to the service port index, beginning at `0`.\n\nSee [the configuration doc for the full list](Longhelp.md#other-labels)\nof labels.\n\n### Templates\n\nMarathon-lb global templates (as listed in the [Longhelp](Longhelp.md#templates)) can be overwritten in two ways:\n-By creating an environment variable in the marathon-lb container\n-By placing configuration files in the `templates/` directory (relative to where the script is run from)\n\nFor example, to replace `HAPROXY_HTTPS_FRONTEND_HEAD` with this content:\n\n```\nfrontend new_frontend_label\n  bind *:443 ssl crt /etc/ssl/cert.pem\n  mode http\n```\n\nThen this environment variable could be added to the Marathon-LB configuration:\n```\n\"HAPROXY_HTTPS_FRONTEND_HEAD\": \"\\\\nfrontend new_frontend_label\\\\n  bind *:443 ssl {sslCerts}\\\\n  mode http\"\n```\n\nAlternately, a file called`HAPROXY_HTTPS_FRONTEND_HEAD` could be placed in `templates/` directory through the use of an artifact URI.\n\nAdditionally, some templates can also be [overridden _per app service port_](#overridable-templates). You may add your own templates to the Docker image, or provide them at startup.\n\nSee [the configuration doc for the full list](Longhelp.md#templates) of templates.\n\n#### Overridable Templates\n\nSome templates may be overridden using app labels,\nas per the [labels section](#app-labels). Strings are interpreted as literal\nHAProxy configuration parameters, with substitutions respected (as per the\n[templates section](#templates)). The HAProxy configuration will be validated\nfor correctness before reloading HAProxy after changes. **Note:** Since the\nHAProxy config is checked before reloading, if an app's HAProxy\nlabels aren't syntactically correct, HAProxy will not be reloaded and may\nresult in stale config.\n\nHere is an example for a service called `http-service` which requires that\n`http-keep-alive` be disabled:\n\n```json\n{\n  \"id\": \"http-service\",\n  \"labels\":{\n    \"HAPROXY_GROUP\":\"external\",\n    \"HAPROXY_0_BACKEND_HTTP_OPTIONS\":\"  option forwardfor\\n  no option http-keep-alive\\n  http-request set-header X-Forwarded-Port %[dst_port]\\n  http-request add-header X-Forwarded-Proto https if { ssl_fc }\\n\"\n  }\n}\n```\n\nThe full list of per service port templates which can be specified\nare [documented here](Longhelp.md#templates).\n\n#### HAProxy Global Default Options\n\nAs a shortcut to add haproxy global default options (without overriding the global template) a comma-separated\nlist of options may be specified via the `HAPROXY_GLOBAL_DEFAULT_OPTIONS` environment variable.\nThe default value when not specified is `redispatch,http-server-close,dontlognull`; as an example, to add the\n`httplog` option (and keep the existing defaults), one should specify `HAPROXY_GLOBAL_DEFAULT_OPTIONS=redispatch,http-server-close,dontlognull,httplog`.\n - _Note that this setting has no effect when the `HAPROXY_HEAD` template has been overridden._\n\n## Operational Best Practices\n\n * Use service ports within the reserved range (which is 10000 to 10100 by default). This will prevent port conflicts, and ensure reloads don't result in connection errors.\n * Avoid using the `HAPROXY_{n}_PORT` label; prefer defining service ports.\n * Consider running multiple marathon-lb instances. In practice, 3 or more should be used to provide high availability for production workloads. Running 1 instance is never recommended, and unless you have significant load running more than 5 instances may not add value. The number of MLB instances you run will vary depending on workload and the amount of failure tolerance required. Note: **do not** run marathon-lb on every node in your cluster. This is considered an anti-pattern due to the implications of hammering the Marathon API and excess health checking.\n * Consider using a dedicated load balancer in front of marathon-lb to permit upgrades/changes. Common choices include an ELB (on AWS) or a hardware load balancer for on-premise installations.\n * Use separate marathon-lb groups (specified with `--group`) for internal and external load balancing. On DC/OS, the default group is `external`. A simple `options.json` for an internal load balancer would be:\n\n ```json\n   {\n     \"marathon-lb\": {\n       \"name\": \"marathon-lb-internal\",\n       \"haproxy-group\": \"internal\",\n       \"bind-http-https\": false,\n       \"role\": \"\"\n     }\n   }\n ```\n * For HTTP services, consider setting VHost (and optionally a path) to access the service on ports 80 and 443. Alternatively, the service can be accessed on port 9091 using the `X-Marathon-App-Id` header. For example, to access an app with the ID `tweeter`:\n\n  ```\n  $ curl -vH \"X-Marathon-App-Id: /tweeter\" marathon-lb.marathon.mesos:9091/\n  *   Trying 10.0.4.74...\n  * Connected to marathon-lb.marathon.mesos (10.0.4.74) port 9091 (#0)\n  \u003e GET / HTTP/1.1\n  \u003e Host: marathon-lb.marathon.mesos:9091\n  \u003e User-Agent: curl/7.48.0\n  \u003e Accept: */*\n  \u003e X-Marathon-App-Id: /tweeter\n  \u003e\n  \u003c HTTP/1.1 200 OK\n  ```\n * Some of the features of marathon-lb assume that it is the only instance of itself running in a PID namespace. i.e. marathon-lb assumes that it is running in a container. Certain features like the `/_mlb_signal` endpoints and the `/_haproxy_getpids` endpoint (and by extension, zero-downtime deployments) may behave unexpectedly if more than one instance of marathon-lb is running in the same PID namespace or if there are other HAProxy processes in the same PID namespace.\n * Sometimes it is desirable to get detailed container and HAProxy logging for easier debugging as well as viewing connection logging to frontends and backends. This can be achieved by setting the `HAPROXY_SYSLOGD` environment variable or `container-syslogd` value in `options.json` like so:\n\n ```json\n   {\n     \"marathon-lb\": {\n       \"container-syslogd\": true\n     }\n   }\n ```\n\n\n## Zero-downtime Deployments\n\n* Please note that `zdd.py` is not to be used in a production environment and is purely developed for demonstration purposes.\n\nMarathon-lb is able to perform canary style blue/green deployment with zero downtime. To execute such deployments, you must follow certain patterns when using Marathon.\n\nThe deployment method is described [in this Marathon document](https://mesosphere.github.io/marathon/docs/blue-green-deploy.html). Marathon-lb provides an implementation of the aforementioned deployment method with the script [`zdd.py`](zdd.py). To perform a zero downtime deploy using `zdd.py`, you must:\n\n\n- Specify the `HAPROXY_DEPLOYMENT_GROUP` and `HAPROXY_DEPLOYMENT_ALT_PORT` labels in your app template\n  - `HAPROXY_DEPLOYMENT_GROUP`: This label uniquely identifies a pair of apps belonging to a blue/green deployment, and will be used as the app name in the HAProxy configuration\n  - `HAPROXY_DEPLOYMENT_ALT_PORT`: An alternate service port is required because Marathon requires service ports to be unique across all apps\n- Only use 1 service port: multiple ports are not yet implemented\n- Use the provided `zdd.py` script to orchestrate the deploy: the script will make API calls to Marathon, and use the HAProxy stats endpoint to gracefully terminate instances\n- The marathon-lb container must be run in privileged mode (to execute `iptables` commands) due to the issues outlined in the excellent blog post by the [Yelp engineering team found here](http://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.html)\n- If you have long-lived TCP connections using the same HAProxy instances, it may cause the deploy to take longer than necessary. The script will wait up to 5 minutes (by default) for connections to drain from HAProxy between steps, but any long-lived TCP connections will cause old instances of HAProxy to stick around.\n\nAn example minimal configuration for a [test instance of nginx is included here](tests/1-nginx.json). You might execute a deployment from a CI tool like Jenkins with:\n\n```\n./zdd.py -j 1-nginx.json -m http://master.mesos:8080 -f -l http://marathon-lb.marathon.mesos:9090 --syslog-socket /dev/null\n```\n\nZero downtime deployments are accomplished through the use of a Lua module, which reports the number of HAProxy processes which are currently running by hitting the stats endpoint at the `/_haproxy_getpids`. After a restart, there will be multiple HAProxy PIDs until all remaining connections have gracefully terminated. By waiting for all connections to complete, you may safely and deterministically drain tasks. A caveat of this, however, is that if you have any long-lived connections on the same LB, HAProxy will continue to run and serve those connections until they complete, thereby breaking this technique.\n\nThe ZDD script includes the ability to specify a pre-kill hook, which is executed before draining tasks are terminated. This allows you to run your own automated checks against the old and new app before the deploy continues.\n\n\n### Traffic Splitting Between Blue/Green Apps\n\nZdd has support to split the traffic between two versions of same app (version 'blue' and version 'green') by having instances of both versions live at the same time. This is supported with the help of the `HAPROXY_DEPLOYMENT_NEW_INSTANCES` label.\n\nWhen you run zdd with the `--new-instances` flag, it creates only the specified number of instances of the new app, and deletes the same number of instances from the old app (instead of the normal, create all instances in new and delete all from old approach), to ensure that the number of instances in new app and old app together is equal to `HAPROXY_DEPLOYMENT_TARGET_INSTANCES`.\n\nExample: Consider the same nginx app example where there are 10 instances of nginx running image version v1, now we can use zdd to create 2 instances of version v2, and retain 8 instances of V1 so that traffic is split in ratio 80:20 (old:new).\n\nCreating 2 instances with new version automatically deletes 2 instances in existing version. You could do this using the following command:\n\n```console\n$ ./zdd.py -j 1-nginx.json -m http://master.mesos:8080 -f -l http://marathon-lb.marathon.mesos:9090 --syslog-socket /dev/null --new-instances 2\n```\n\nThis state where you have instances of both old and new versions of same app live at the same time is called hybrid state.\n\nWhen a deployment group is in hybrid state, it needs to be converted into completely current version or completely previous version before deploying any further versions, this could be done with the help of the `--complete-cur` and `--complete-prev` flags in zdd.\n\nWhen you run the below command, it converts all instances to new version so that traffic split ratio becomes 0:100 (old:new) and it deletes the old app. This is graceful as it follows usual zdd procedure of waiting for tasks/instances to drain before deleting them.\n\n```console\n$ ./zdd.py -j 1-nginx.json -m http://master.mesos:8080 -f -l http://marathon-lb.marathon.mesos:9090 --syslog-socket /dev/null --complete-cur\n```\n\nSimilarly you can use `--complete-prev` flag to convert all instances to old version (and this is essentially a rollback) so that traffic split ratio becomes 100:0 (old:new) and it deletes the new app.\n\nCurrently only one hop of traffic split is supported, so you can specify the number of new instances (directly proportional to traffic split ratio) only when app is having all instances of same version (completely blue or completely green). This implies `--new-instances` flag cannot be specified in hybrid mode to change traffic split ratio (instance ratio) as updating Marathon label (`HAPROXY_DEPLOYMENT_NEW_INSTANCES`) currently triggers new deployment in marathon which will not be graceful. Currently for the example mentioned, the traffic split ratio is 100:0 -\u003e 80:20 -\u003e 0:100, where there is only one hop when both versions get traffic simultaneously.\n\n## Mesos with IP-per-task Support\n\nMarathon-lb supports load balancing for applications that use the Mesos IP-per-task\nfeature, whereby each task is assigned unique, accessible, IP addresses.  For these\ntasks services are directly accessible via the configured discovery ports and there\nis no host port mapping.  Note, that due to limitations with Marathon (see\n[mesosphere/marathon#3636](https://github.com/mesosphere/marathon/issues/3636))\nconfigured service ports are not exposed to marathon-lb for IP-per-task apps.\n\nFor these apps, if the service ports are missing from the Marathon app data,\nmarathon-lb will automatically assign port values from a configurable range if you\nspecify it.  The range is configured using the `--min-serv-port-ip-per-task` and\n`--max-serv-port-ip-per-task` options. While port assignment is deterministic, the\nassignment is not guaranteed if you change the current set of deployed apps. In\nother words, when you deploy a new app, the port assignments may change.\n\n\n## Zombie reaping\n\nWhen running with isolated containers, you may need to take care of reaping orphaned child processes. HAProxy typically produces orphan processes because of its two-step reload mechanism. Marathon-LB uses [tini](https://github.com/krallin/tini) for this purpose. When running in a container without PID namespace isolation, setting the `TINI_SUBREAPER` environment variable is recommended.\n\n\n## Contributing\n\nPRs are welcome, but here are a few general guidelines:\n\n - Avoid making changes which may break existing behaviour\n - Document new features\n - Update/include tests for new functionality. To install dependencies and run tests:\n\n   ```\n   pip install -r requirements-dev.txt\n   nosetests\n   ```\n - Use the pre-commit hook to automatically generate docs:\n\n   ```\n   bash /path/to/marathon-lb/scripts/install-git-hooks.sh\n   ```\n\n### Using the Makefile and docker for developement and testing\n\nRunning unit and integration tests is automated as `make` targets. Docker\nis required to use the targets as it will run all tests in containers.\n\nSeveral environment variables can be set to control the image tags,\nDCOS version/variant, etc. Check the top of the `Makefile` for more info.\n\nTo run the unit tests:\n\n```bash\nmake test-unit\n```\n\nTo run the integration tests a DCOS installation will be started via\n[dcos-e2e](https://github.com/dcos/dcos-e2e). The installation of\n`dcos-e2e` and management of the cluster will all be done in docker\ncontainers. Since the installers are rather large downloads, it is\nbenificial to specify a value for `DCOS_E2E_INSTALLERS_DIR`. By default\n`DCOS_E2E_INSTALLERS_DIR` is inside the `.cache` directory that will be\nremoved upon `make clean`. You must provide a repository for the\nresultant docker image to be pushed to via the `CONTAINTER_REPO`\nenvironemnt variable. It is assumed that the local docker is already\nlogged in and the image will be pushed prior to launching the cluster.\n\nTo run the integration tests on the OSS variant of DCOS:\n\n```bash\nDCOS_E2E_INSTALLERS_DIR=\"${HOME}/dcos/installers\" \\\nCONTAINTER_REPO=\"my_docker_user/my-marathon-lb-repo\" make test-integration\n```\n\nTo run the integration tests on the ENTERPRISE variant of DCOS:\n\n\n```bash\nDCOS_LICENSE_KEY_PATH=${HOME}/license.txt \\\nDCOS_E2E_VARIANT=enterprise \\\nDCOS_E2E_INSTALLERS_DIR=\"${HOME}/dcos/installers\"\\\nCONTAINTER_REPO=\"my_docker_user/my-marathon-lb-repo\" make test-integration\n```\n\nTo run both unit and integration tests (add appropriate variables):\n\n```bash\nCONTAINTER_REPO=\"my_docker_user/my-marathon-lb-repo\" make test\n```\n\n### Troubleshooting your development environment setup\n\n#### FileNotFoundError: [Errno 2] No such file or directory: 'curl-config'\n\nYou need to install the curl development package.\n\n```sh\n# Fedora\ndnf install libcurl-devel\n\n# Ubuntu\napt-get install libcurl-dev\n```\n\n#### ImportError: pycurl: libcurl link-time ssl backend (nss) is different from compile-time ssl backend (openssl)\n\nThe `pycurl` package linked against the wrong SSL backend when you installed it.\n\n```sh\npip uninstall pycurl\nexport PYCURL_SSL_LIBRARY=nss\npip install -r requirements-dev.txt\n```\n\nSwap `nss` for whatever backend it mentions.\n\n## Release Process\n\n1. Create a Github release. Follow the convention of past releases. You can find\nsomething to copy/paste if you hit the \"edit\" button of a previous release.\n\n1. The Github release creates a tag, and Dockerhub will build off of that tag.\n\n1. Make a PR to Universe. The suggested way is to create one commit that **only** copies\nthe previous dir to a new one, and then a second commit that makes the actual changes.\nIf unsure, check out the previous commits to the marathon-lb directory in Universe.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd2iq-archive%2Fmarathon-lb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd2iq-archive%2Fmarathon-lb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd2iq-archive%2Fmarathon-lb/lists"}