{"id":13644460,"url":"https://github.com/knight42/krelay","last_synced_at":"2025-04-12T20:44:25.194Z","repository":{"id":37836090,"uuid":"268460503","full_name":"knight42/krelay","owner":"knight42","description":"A better alternative to `kubectl port-forward` that can forward TCP or UDP traffic to IP/Host which is accessible inside the cluster.","archived":false,"fork":false,"pushed_at":"2025-04-03T15:16:24.000Z","size":265,"stargazers_count":259,"open_issues_count":4,"forks_count":15,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-04T00:09:13.932Z","etag":null,"topics":["kubectl","kubectl-plugin","kubernetes","port-forward"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knight42.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":"2020-06-01T08:01:47.000Z","updated_at":"2025-04-03T15:16:27.000Z","dependencies_parsed_at":"2022-08-02T15:15:57.316Z","dependency_job_id":"8190421e-4fd4-414c-867c-5d3fdbd48427","html_url":"https://github.com/knight42/krelay","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knight42%2Fkrelay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knight42%2Fkrelay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knight42%2Fkrelay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knight42%2Fkrelay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knight42","download_url":"https://codeload.github.com/knight42/krelay/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631687,"owners_count":21136556,"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":["kubectl","kubectl-plugin","kubernetes","port-forward"],"created_at":"2024-08-02T01:02:05.385Z","updated_at":"2025-04-12T20:44:25.167Z","avatar_url":"https://github.com/knight42.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"![GitHub](https://img.shields.io/github/license/knight42/krelay)\n![](https://github.com/knight42/krelay/actions/workflows/test.yml/badge.svg)\n[![Go Report Card](https://goreportcard.com/badge/github.com/knight42/krelay)](https://goreportcard.com/report/github.com/knight42/krelay)\n![GitHub last commit](https://img.shields.io/github/last-commit/knight42/krelay)\n\n# krelay\n\n`krelay` is a drop-in replacement for `kubectl port-forward` with some enhanced features.\n\n## Table of Contents\n\n- [Highlights](#highlights)\n- [Demo](#demo)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Flags](#flags)\n- [How It Works](#how-it-works)\n\n## ✨Highlights\n\n* Supports UDP port forwarding\n* Supports simultaneous forwarding of data to multiple targets.\n* Forwarding data to the given IP or hostname that is accessible within the kubernetes cluster\n  * You could forward a local port to a port in the `Service` or a workload like `Deployment` or `StatefulSet`, and the forwarding session will not be interfered even if you perform rolling updates.\n  * The hostname is resolved inside the cluster, so you don't need to change your local nameserver or modify the `/etc/hosts`.\n\n## Demo\n\n### Forwarding UDP port\n\n[![asciicast](https://asciinema.org/a/452745.svg)](https://asciinema.org/a/452745)\n\n### Forwarding traffic to a Service\n\n[![asciicast](https://asciinema.org/a/452747.svg)](https://asciinema.org/a/452747)\n\n\u003e [!NOTE]\n\u003e The forwarding session is not affected after rolling update.\n\n### Forwarding traffic to a IP or hostname\n\n[![asciicast](https://asciinema.org/a/452749.svg)](https://asciinema.org/a/452749)\n\n### Forwarding traffic to multiple targets\n\n```bash\n$ cat \u003e targets.txt \u003c\u003cEOF\n# Each line in the file represents a target, the syntax is the same as the command line.\n# Empty line or line starts with '#' or '//' will be ignored.\n\n# namespace of the object can be specified by the -n flag\n-n kube-system svc/kube-dns 10053:53@udp\n\n# The default namespace is used if no namespace is specified\nsvc/nginx 8080:80\n\nhost/redis.cn-north-1.cache.amazonaws.com 6379\nEOF\n\n$ kubectl relay -f targets.txt\n```\n\n### Customize the forwarding server\n\nYou can provide a merge patch in JSON or YAML format to customize the forwarding server. For instance:\n```bash\n$ cat patch.yaml\nmetadata:\n  generateName: foo-\nspec:\n  nodeSelector:\n    your-key: your-value\n\n$ kubectl --patch-file patch.yaml svc/nginx 8080:80\n```\n\n## Installation\n\n| Distribution                          | Command / Link                                                 |\n|---------------------------------------|----------------------------------------------------------------|\n| [Krew](https://krew.sigs.k8s.io/)     | `kubectl krew install relay`                                   |\n| [Homebrew](https://brew.sh/)          | `brew install knight42/tap/krelay`                             |\n| Pre-built binaries for macOS, Linux   | [GitHub releases](https://github.com/knight42/krelay/releases) |\n\n\u003e [!NOTE]\n\u003e If you only have limited access to the cluster, please make sure the permissions specified in [rbac.yaml](./manifests/rbac.yaml)\nis granted:\n\n```bash\nwget https://raw.githubusercontent.com/knight42/krelay/main/manifests/rbac.yaml\n# Edit rbac.yaml to update the user name\nvim rbac.yaml\nkubectl create -f rbac.yaml\n```\n\n### Build from source\n\n```\ngit clone https://github.com/knight42/krelay\ncd krelay\nmake krelay\ncp krelay \"$GOPATH/bin/kubectl-relay\"\nkubectl relay -V\n```\n\n## Usage\n\n\u003e [!NOTE]\n\u003e Starting from version v0.1.2, `krelay` attempts to tunnel SPDY through websocket, in line with how `kubectl port-forward` works.\n\u003e\n\u003e This behavior can be disabled by setting the environment variable `KUBECTL_PORT_FORWARD_WEBSOCKETS` to `false`.\n\n```bash\n# Listen on port 8080 locally, forwarding data to the port named \"http\" in the service\nkubectl relay service/my-service 8080:http\n\n# Listen on a random port locally, forwarding udp packets to port 53 in a pod selected by the deployment\nkubectl relay -n kube-system deploy/kube-dns :53@udp\n\n# Listen on port 5353 on all addresses, forwarding data to port 53 in the pod\nkubectl relay --address 0.0.0.0 pod/my-pod 5353:53\n\n# Listen on port 6379 locally, forwarding data to \"redis.cn-north-1.cache.amazonaws.com:6379\" from the cluster\nkubectl relay host/redis.cn-north-1.cache.amazonaws.com 6379\n\n# Listen on port 5000 and 6000 locally, forwarding data to \"1.2.3.4:5000\" and \"1.2.3.4:6000\" from the cluster\nkubectl relay ip/1.2.3.4 5000@tcp 6000@udp\n\n# Customized the server, and forward local port 5000 to \"1.2.3.4:5000\"\nkubectl relay --patch '{\"metadata\":{\"namespace\":\"kube-public\"},\"spec\":{\"nodeSelector\":{\"k\": \"v\"}}}' ip/1.2.3.4 5000\n\n```\n\n## Flags\n\n| flag             | default                                 | description                                                             |\n|------------------|-----------------------------------------|-------------------------------------------------------------------------|\n| `--address`      | `127.0.0.1`                             | Address to listen on. Only accepts IP addresses as a value.             |\n| `-f`/`--file`    | N/A                                     | Forward traffic to the targets specified in the given file.             |\n| `--server.image` | `ghcr.io/knight42/krelay-server:v0.0.1` | The krelay-server image to use.                                         |\n| `-p`/`--patch`   | N/A                                     | The merge patch to be applied to the krelay-server pod.                 |\n| `--patch-file`   | N/A                                     | A file containing a merge patch to be applied to the krelay-server pod. |\n\n## How It Works\n\n`krelay` will install an agent(named `krelay-server`) to the kubernetes cluster, and the agent will forward the traffic to the target ip/hostname.\n\nIf the target is an object in the cluster, like `Deployment`, `StatefulSet`, `krelay` will automatically select a pod it managed like `kubectl port-forward` does.\nAfter that `krelay` will tell the destination IP(i.e. the pod's IP) and the destination port to the agent by sending a special `Header` first,\nand then the data will be forwarded to the agent and sent to the target address.\n\nSpecifically, if the target is a `Service`, `krelay` will try to determine the destination address automatically:\n* If the `Service` has a clusterIP, then the clusterIP is used as the destination IP.\n* If the type of `Service` is `ExternalName`, then the external name is used as the destination address.\n* If none of the above scenario is met, then `krelay` will choose a pod selected by this `Service`.\n\nThe `Header` looks like this:\n\n|            | Version | Header Length | Request ID | Protocol | Destination Port | Address Type | Address  |\n|------------|---------|---------------|------------|----------|------------------|--------------|----------|\n| Byte Count | 1       | 2             | 5          | 1        | 2                | 1            | Variable |\n\n* `Version`: This field is preserved for future extension, and it is not in-use now.\n* `Header Length`: The total length of the `Header` in bytes.\n* `Request ID`: The ID of the request.\n* `Protocol`: The protocol of the request, `0` stands for TCP and `1` stands for UDP.\n* `Destination Port`: The destination port of the request.\n* `Address Type`: The type of the destination address, `0` stands for IP and `1` stands for hostname.\n* `Address`: The destination address of the request:\n  * 4 bytes for IPv4 address\n  * 16 bytes for IPv6 address\n  * Variable bytes for hostname\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknight42%2Fkrelay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknight42%2Fkrelay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknight42%2Fkrelay/lists"}