{"id":28234926,"url":"https://github.com/cozystack/cozy-proxy","last_synced_at":"2025-06-12T22:30:36.740Z","repository":{"id":275926666,"uuid":"927641631","full_name":"cozystack/cozy-proxy","owner":"cozystack","description":"A simple kube-proxy addon for 1:1 NAT services in Kubernetes with NFT backend.","archived":false,"fork":false,"pushed_at":"2025-03-27T09:12:06.000Z","size":48,"stargazers_count":10,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-18T22:14:36.160Z","etag":null,"topics":[],"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/cozystack.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-05T09:50:21.000Z","updated_at":"2025-04-14T06:02:36.000Z","dependencies_parsed_at":"2025-02-05T10:36:49.513Z","dependency_job_id":"bf8f0137-6ceb-4608-83f3-797c3980bf30","html_url":"https://github.com/cozystack/cozy-proxy","commit_stats":null,"previous_names":["aenix-io/cozy-proxy","cozystack/cozy-proxy"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/cozystack/cozy-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozystack%2Fcozy-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozystack%2Fcozy-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozystack%2Fcozy-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozystack%2Fcozy-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cozystack","download_url":"https://codeload.github.com/cozystack/cozy-proxy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cozystack%2Fcozy-proxy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259541496,"owners_count":22873708,"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":[],"created_at":"2025-05-18T22:14:38.876Z","updated_at":"2025-06-12T22:30:36.707Z","avatar_url":"https://github.com/cozystack.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cozy-proxy\n\nA simple kube-proxy addon for 1:1 NAT services in Kubernetes using an NFT backend.\n\nThis project ensures a one-to-one mapping between a service and a pod in Kubernetes.\n\n## Why\n\nAt [Cozystack](https://cozystack.io), we strive to follow the standard Kubernetes network architecture by separating the pod network, service networks, and external load balancers. However, our platform also runs virtual machines that sometimes require an external IP address.\n\nThere are several ways to achieve this:\n- Using a separate Kube-OVN subnet and exposing it via BGP with kube-ovn-speaker.\n- Adding a secondary interface with Multus.\n- Using native Kubernetes services with externalIPs and exposing them via MetalLB.\n\nThe last option is the simplest and most flexible, but it has a limitation: Kubernetes services do not forward all traffic,\nbut only traffic on specific ports (see: [Kubernetes Issue #23864](https://github.com/kubernetes/kubernetes/issues/23864)).\nAdditionally, kube-proxy does not perform SNAT, which causes outgoing traffic from the pod to use the default gateway of the host where it is running.\n\nTo address these issues, we have added an additional controller that performs 1:1 NAT for services annotated with `networking.cozystack.io/wholeIP=true`.\n\n## How It Works\n\ncozy-proxy is a simple Kubernetes controller that watches for services with the `networking.cozystack.io/wholeIP=true` annotation. When it finds such a service, it creates an NFT rule that forwards all traffic from the service's external IP to the pod's IP and vice versa. It also disables connection tracking (conntrack) for traffic between the service and the pod, offloading that work to NFTables.\n\nThis controller can be used together with kube-proxy and Cilium in kube-proxy replacement mode.\n\n## Installation\n\nInstall controller using Helm-chart:\n\n```bash\nhelm install cozy-proxy charts/cozy-proxy -n kube-system\n```\n\n## Usage\n\nCreate a LoadBalancer service with `networking.cozystack.io/wholeIP=true` annotation:\n\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  annotations:\n    networking.cozystack.io/wholeIP: \"true\"\n  name: example-service\nspec:\n  allocateLoadBalancerNodePorts: false\n  externalTrafficPolicy: Local\n  ports:\n  - port: 65535 # any\n  selector:\n    app: nginx\n  type: LoadBalancer\n---\napiVersion: v1\nkind: Pod\nmetadata:\n  name: nginx\n  labels:\n    app: nginx\nspec:\n  containers:\n  - name: nginx\n    image: docker.io/library/nginx:alpine\n```\n\nCheck that the service has an external IP:\n\n```bash\nkubectl get svc\n```\n\nExample output:\n\n```console\nNAME              TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)     AGE\nexample-service   LoadBalancer   10.96.195.46   1.2.3.4         65535/TCP   84s\n```\n\nNow try to access the service using `icmp` and `tcp`; both should work:\n\n```bash\nping 1.2.3.4\ncurl 1.2.3.4\n```\n\nCheck external IP from inside the pod:\n\n```bash\nkubectl exec -ti nginx -- curl icanhazip.com\n```\n\nExample output would be the same as the service external IP:\n```console\n1.2.3.4\n```\n\n## Environment\n\nThis controller was developed primarily for the [Cozystack](https://cozystack.io) platform and has been tested in the following environment:\n- **OS**: Talos Linux\n- **CNI**: Kube-OVN with Cilium in chaining mode.\n- **Kube-proxy**: Cilium in kube-proxy replacement mode.\n- **LoadBalancer**: MetalLB in L2 mode with `externalTrafficPolicy: Local`.\n\n*If you have tested it in other environments, please let us know.*\n\n## Credits\n- [@kvaps](https://github.com/kvaps) – for the implementation.\n- [@hexchain](https://github.com/hexchain) – for the [Stateless NAT with NFTables](https://wiki.hexchain.org/linux/networking/nft-stateless-nat/) snippet.\n- [@danwinship](https://github.com/danwinship) – for the [idea regarding the annotation](https://github.com/kubernetes/kubernetes/issues/23864#issuecomment-2607297206).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcozystack%2Fcozy-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcozystack%2Fcozy-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcozystack%2Fcozy-proxy/lists"}