{"id":22379145,"url":"https://github.com/sky-uk/feed","last_synced_at":"2026-03-15T06:52:54.331Z","repository":{"id":8453702,"uuid":"58119137","full_name":"sky-uk/feed","owner":"sky-uk","description":"Nginx based Kubernetes ingress controller for AWS","archived":false,"fork":false,"pushed_at":"2024-01-18T10:37:16.000Z","size":5587,"stargazers_count":58,"open_issues_count":4,"forks_count":10,"subscribers_count":51,"default_branch":"master","last_synced_at":"2024-06-20T13:40:07.612Z","etag":null,"topics":["ingress"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sky-uk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-05T09:14:33.000Z","updated_at":"2024-03-02T02:47:30.000Z","dependencies_parsed_at":"2024-06-20T13:08:17.466Z","dependency_job_id":"4ac881da-27ae-4a2e-810f-40802faf704b","html_url":"https://github.com/sky-uk/feed","commit_stats":null,"previous_names":[],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Ffeed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Ffeed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Ffeed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sky-uk%2Ffeed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sky-uk","download_url":"https://codeload.github.com/sky-uk/feed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228204606,"owners_count":17884711,"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":["ingress"],"created_at":"2024-12-04T23:09:06.649Z","updated_at":"2026-03-15T06:52:49.297Z","avatar_url":"https://github.com/sky-uk.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![travis](https://travis-ci.org/sky-uk/feed.svg?branch=master)\n\n# Feed\nThis project contains Kubernetes controllers for managing external ingress with\nAWS or [IPVS](https://github.com/sky-uk/merlin) load balancers.\n\nThere are two controllers provided, `feed-ingress` which runs an NGINX instance, and `feed-dns` which manages Amazon Route 53 entries.\nThey can be run independently as needed, or together to provide a full ingress solution. `feed-ingress` can be arbitrarily scaled up to support any traffic load.\n\nFeed is actively used in production and should be stable enough for general usage. We can scale to many thousands of\nrequests per second with only a handful of replicas.\n\n## Comparison to official NGINX ingress controller\nFeed was started before the [official NGINX ingress controller](https://github.com/kubernetes/ingress-nginx)\nbecame production ready.\nThe main differences that exist now are:\n* Feed has fewer features, as we only built it for our needs.\n* Feed pods attach directly to AWS load balancers or IPVS nodes. The official controller relies on the\n  `LoadBalancer` service type, which generally forwards traffic to every node in your cluster (`service.spec.externalTrafficPolicy` can be set in some providers to mitigate this). We found this problematic:\n  * It increases the amount of traffic flowing through your cluster, as traffic is routed through every node unnecessarily.\n  * ELB health checks don't work  - the ELBs will disable arbitrary nodes, rather than a broken ingress pod.\n* Feed uses services, while the official controller uses endpoints:\n  * Primarily to reduce the number of NGINX reloads that occur, which are problematic in busy environments.\n    It may be possible to mitigate this though with a dynamic update of NGINX (via plugin), and is something\n    we've discussed doing for service updates.\n  * It's debatable whether using endpoints directly is a good idea conceptually, as it bypasses kube-proxy\n    and any service mesh in place.\n\n# Using\nDocker images for `feed-ingress` and `feed-dns` are released using semantic versioning.\nSee the [examples](examples/) for deployment YAML files that can be applied to a cluster.\n\n# Requirements\n## RBAC permissions\nThe following RBAC permissions are required by the service account under which feed runs:\n\n```yaml\nrules:\n- apiGroups:\n  - \"\"\n  - extensions\n  resources:\n  - ingresses\n  - namespaces\n  - services\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - extensions\n  resources:\n  - ingresses/status\n  verbs:\n  - update\n```\n\n## AWS components\nWhen running `feed-dns` or `feed-ingress` with AWS load balancers, the following are required:\n* An internal and internet-facing load balancer which can reach your Kubernetes cluster.\nThe load balancers should be tagged with `sky.uk/KubernetesClusterFrontend=\u003cname\u003e` which is used by feed to discover them.\nIf you are using v2 of `feed-ingress` they should also be tagged with `sky.uk/KubernetesClusterIngressClass=\u003cname\u003e`.\nSee [upgrading from v1 to v2](#upgrade-from-v1-to-v2) for more information.\n* For `feed-dns`, a Route 53 hosted zone to match your ingress resources.\n\n# feed-ingress\n`feed-ingress` manages an NGINX instance, updating its configuration dynamically for ingress resources. It attaches to\nELBs which are intended to be the frontend for all traffic.\n\nSee the command line options with:\n\n    docker run --rm skycirrus/feed-ingress:v2.0.0 -h\n\n## Known limitations\n* NGINX reloads can be disruptive. On reload, NGINX will finish in-flight requests, then abruptly\n  close all server connections. This is a limitation of NGINX, and affects all NGINX solutions. We mitigate this by:\n    * Rate limiting reloads. This is user configurable.\n    * Using service IPs, which are stable. Reloads will only happen if an ingress or service changes, which is rare\n      compared to pod changes.\n\n## Upgrading from v1 to v2\nThis is a breaking change to support [multiple ingress controllers per cluster](#multiple-ingress-controllers-per-cluster).\nThe feed-ingress command-line structure has also changed. There are subcommands for the various load balancer types and\narguments use double dashes to be POSIX-compliant.\n\nTo upgrade, follow these steps:\n1. Tag the ELBs with `sky.uk/KubernetesClusterIngressClass=\u003cname\u003e` to indicate which feed-ingress controllers should attach to them\n1. Annotate all ingresses with `kubernetes.io/ingress.class=\u003cname\u003e`\n1. Replace deprecated ingress resource annotations with their replacements:\n   `sky.uk/frontend-elb-scheme` becomes `sky.uk/frontend-scheme`,\n   `sky.uk/backend-keepalive-seconds` becomes `sky.uk/backend-timeout-seconds`\n1. Use double dashes for all arguments\n1. Provide the mandatory argument `--ingress-class=\u003cname\u003e` to feed-ingress with a value matching the ELB tag.\n   For migrating existing deployments, you may provide the new (but deprecated) flag `--include-classless-ingresses`\n   which instructs feed-ingress to additionally consider ingress resources that have no `kubernetes.io/ingress.class` annotation\n1. Instead of using the argument `-registration-frontend-type`, use instead a subcommand of `feed-ingress`\n   (for example `feed-ingress -registration-frontend-type=elb \u003cargs...\u003e` becomes `feed-ingress elb \u003cargs\u003e`)\n1. Rename the argument `-elb-label-value` to `--elb-frontend-tag-value`\n1. Rename the argument `-nginx-default-backend-keepalive-seconds` to `--nginx-default-backend-timeout-seconds`\n\n## SSL termination\n### SSL termination on load balancer\nSSL termination could be done on ELBs, and we believe that this is the safest and best performing\napproach for production usage. Unfortunately, ELBs don't support SNI at this time, so this limits SSL usage to\na single domain. One workaround is to use a wildcard certificate for the entire zone that `feed-dns` manages.\nAnother is to place an SSL termination EC2 instance in front of the ELBs.\n\n### SSL termination on feed-ingress\nSSL termination can be done on feed-ingress. This approach still requires a layer 4 load balancer, eg. ELB or IPVS, in front.\n\nFor the moment you can setup a default wildcard SSL:\n\n```bash\n# Set default SSL path + name file without extension. Feed expects two files: one ending in .crt (the CA)\n# and the other in .key (the private key), for example: --ssl-path=/etc/ssl/default-ssl/default-ssl\n# will cause feed to look for /etc/ssl/default-ssl.crt and /etc/ssl/default.ssl.key\n```\n\nYou can mount the `.key` and `.crt` though a Kubernetes Secret see [feed-ingress-deployment-ssl](examples/feed-ingress-deployment-ssl.yml).\n\n## Merlin support\nMerlin is a distributed load balancer based on IPVS, with a gRPC based API. Feed supports attaching to merlin\nas a frontend for ingress.\n\nSee the [example](examples/feed-ingress-deployment-merlin.yml) for details.\n\n## GORB / IPVS Support\n_GORB support is deprecated, and will be removed at some point. Use merlin instead._\n\nFeed has support for configuring IPVS via [GORB](https://github.com/sky-uk/gorb).\nGORB exposes a REST api to interrogate and modify the IPVS configuration such as virtual services and backends.\nThe configuration can be stored in a distributed key/value store.\n\nAlthough IPVS supports multiple packet-forwarding methods, feed currently only supports 'DR' aka Direct Server Return.\nIt provides the ability to manage the loopback interface so the ingress instance can pretend to be IPVS at the IP level.\nfeed-ingress pod will need to define the `NET_ADMIN` Linux capability to be able to manage the loopback interface.\n\n```yaml\nsecurityContext:\n  capabilities:\n    add:\n    - NET_ADMIN\n```\n\nSee the [example deployment for GORB](examples/feed-ingress-deployment-gorb.yml)\n\n## AWS load balancer support\nFeed supports the three types of load balancer offered by AWS.\n\n### Classic Load Balancers (ELBs)\nSee the [example deployment for ELB](examples/feed-ingress-deployment-elb.yml)\n\n### Network Load Balancers (NLBs)\nSee the [example deployment for NLB](examples/feed-ingress-deployment-nlb.yml)\n\nPlease note that when a new Feed pod is added as a target to the target group of an NLB, it takes some time for the\nnew target to be registered and health-checked by the NLB before the NLB will send it any requests. Please see the\n\"Target Health Status\" section of the\n[AWS documentation on NLB target group health checks](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-health-checks.html) for more details.\n\n### Application Load Balancers (ALBs)\nFeed has support for ALBs. Unfortunately, ALBs have a bug that prevents non-disruptive deployments of feed (specifically,\nthey don't respect the deregistration delay). As a result, we don't recommend using ALBs at this time.\n\n## OpenTracing\nThe build now includes support for OpenTracing, and the default Docker image includes the Jaeger tracing vendor\nimplementation.\n\nTo enable OpenTracing, you will need to provide the following options:\n\n```bash\n# Define the path to the OpenTracing vendor plugin\n--nginx-opentracing-plugin-path=/usr/local/lib64/libjaegertracing.so\n# Define the path to the config for the vendor plugin\n--nginx-opentracing-config-path=/etc/jaeger-nginx-config.json\n```\n\nNote that the status and metrics endpoints will *not* have OpenTracing applied.\n\n## Handling large client requests\n`feed-ingress` now supports handling of large client requests (header and body). The following are the default values for the same.\n\n```\nclient_header_buffer_size 16k;\nclient_body_buffer_size 16k;\nlarge_client_header_buffers 4 16k\n```\n\nThey can be overridden by passing the following arguments during startup.\n\n```bash\n--nginx-client-header-buffer-size-in-kb=16\n--nginx-client-body-buffer-size-in-kb=16\n\n# Set the maximum number and size of buffers used for reading large client request header. If this value is set,\n# --nginx-client-header-buffer-size-in-kb should be passed in as well. Otherwise, this value will be ignored.\n--nginx-large-client-header-buffer-blocks=4\n```\n\n## Deriving client address from the request header\nA flag `set-real-ip-from-header` can be used to specify the name of the request header for the [real ip module](http://nginx.org/en/docs/http/ngx_http_realip_module.html) to use in the `set_real_ip_from` directive.\nThe default value of this flag would be `X-Forwarded-For`\n\n## Namespace selectors\nNamespace selectors can be used for the feed-ingress instance to only process ingress definitions from only those namespaces which have labels matching the ones passed in the input.\nThe following 2 flags help facilitate this\n\n1. `ingress-controller-namespace-selectors` - This flag will either be a repeated or comma separated value of namespace labels.\n\n```\nExamples:\n\n1. --ingress-controller-namespace-selectors=app=some-app,team=some-team\n2. --ingress-controller-namespace-selectors=app=some-app --ingress-controller-namespace-selectors=team=some-team\n```\n\n2. `match-all-namespace-selectors` - This flag is to determine how the above flags should be used for matching on the namespace labels. This would be false by default which would mean that a namespace matching any of the above labels will be picked.\nIf this flag is set, the namespace on which the ingress is defined should have all of the passed in labels.\n\n## Ingress status\nWhen using the [ELB](#elb), [NLB](#nlb), [Static](#static) or [Merlin](#merlin) updaters, the ingress status will be updated with relevant\nload balancer information. This can then be used with other controllers such as `external-dns` which can set DNS for any\ngiven ingress using the ingress status.\n\n### AWS load balancers\nFeed will automatically discover all of your load balancers and then use the `sky.uk/frontend-scheme` annotation to\nmatch a load balancer label to an ingress. The updater will then set the ingress status to the load balancer's DNS name.\n\n### Merlin\nThe Merlin updater is currently unable to auto-discover all hosted load balancers on a Merlin server; instead the status\nupdater supports two different types: `internal` and `internet-facing`. These two load balancers are set using the\n`merlin-internal-hostname` and `merlin-internet-facing-hostname` flags respectively.\n\nAn ingress can select which load balancer it wants to be associated with by setting the `sky.uk/frontend-scheme`\nannotation to either `internal` or `internet-facing`.\n\n### Static\nThe static updater sets an Ingress's status hostname to a static value.\nTwo values are supported: `external-hostname` and `internal-hostname`.\nAn ingress can select which hostname it wants to be associated with by setting the `sky.uk/frontend-scheme`\nannotation to either `internal` or `internet-facing`.\n\n## Running feed-ingress on privileged ports\nfeed-ingress can be run on privileged ports by defining  the `NET_BIND_SERVICE` Linux capability.\n\n```yaml\nsecurityContext:\n  capabilities:\n    add:\n    - NET_BIND_SERVICE\n```\n\n## Multiple ingress controllers per cluster\nMultiple feed-ingress controllers can be created per cluster. Load balancers should be tagged with\n`sky.uk/KubernetesClusterIngressClass=\u003cname\u003e` and feed instances started with `--ingress-class=\u003cname\u003e`.\nFeed instances will attach to load balancers with matching ingress class names.\n\nA feed ingress controller will adopt ingress resources with a matching `kubernetes.io/ingress.class=\u003cvalue\u003e` annotation.\nIngress resources with no annotation will normally not be adopted and will have no traffic sent to their associated services.\nHowever, see the deprecated flag `--include-classless-ingresses` which instructs feed-ingress to additionally consider\ningress resources with no `kubernetes.io/ingress.class` annotation.\n\nUse the script `classless-ingresses.sh` to find ingresses without this annotation.\n\nThis feature is supported by `feed-ingress` and the `elb` and `nlb` load balancer.  It is currently not supported by `feed-dns`\nor any other load balancer type. PRs are welcome.\n\n# feed-dns\n`feed-dns` manages a Route 53 hosted zone, updating entries to point to ELBs or arbitrary hostnames. It is designed to\nbe run as a single instance per zone in your cluster.\n\nSee the command line options with:\n\n    docker run skycirrus/feed-dns:v2.0.0 -h\n\n## DNS records\nThe feed-dns controller assumes that it can overwrite any entry in the supplied DNS zone and manages ALIAS and CNAME\nrecords per ingress.\n\nOn startup, all ingress entries are queried and compared to all the Record Sets in the configured hosted zone.\n\nAny records pointing to one of the endpoints associated with this controller that do not have an ingress\nentry are deleted. For any new ingress entry, a record is created to point to the correct endpoint. Existing\nrecords which do not meet these conditions remain untouched.\n\nEach ingress must have the following be annotated with `sky.uk/frontend-scheme` set to `internal` or `internet-facing`\nso the record can be set to the correct endpoint.\n\nIf you're using ELBs then ALIAS (A) records will be created. If you've explicitly provided CNAMEs of your\nload balancers then CNAMEs will be created.\n\n## Known limitations\n* `feed-dns` only supports a single hosted zone at this time, but this should be straightforward to add support for.\nPRs are welcome.\n\n# Development\nInstall the required tools and setup dependencies:\n\n    make setup\n\nBuild and test with:\n\n    make\n\n## Releasing\nTag the commit in master and push it to release it. Only maintainers can do this.\n\n## Dependencies\nDependencies are managed with [Go Modules](https://github.com/golang/go/wiki/Modules).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsky-uk%2Ffeed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsky-uk%2Ffeed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsky-uk%2Ffeed/lists"}