first commit

This commit is contained in:
2026-09-09 23:15:49 +02:00
commit 71cd045e96
15 changed files with 570 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
# tcp-echo
Minimal .NET 8 TCP echo server. Every reply is prefixed with the instance identifier
(`INSTANCE_ID` env var, falling back to the hostname), and a `[<id>] connected` line is sent on connect.
Two instances are deployed behind Traefik:
| Instance | INSTANCE_ID | External port |
|----------|-------------|---------------|
| a | echo-a | 9098 |
| b | echo-b | 9099 |
## Build and push
Requires a prior `docker login gitea.eitczech.com`.
```powershell
./build-push.ps1 -Tag 1.0.0 # pushes gitea.eitczech.com/public/tcp-echo-server:1.0.0
./build-push.ps1 -Tag 1.0.0 -AlsoLatest # additionally pushes :latest
```
The manifests reference `gitea.eitczech.com/public/tcp-echo-server:latest`. To pin a specific tag either edit
`k8s/instance-a.yaml` / `k8s/instance-b.yaml`, or after `kubectl apply -k` run:
```sh
kubectl -n tcp-echo set image deploy/tcp-echo-a deploy/tcp-echo-b tcp-echo=gitea.eitczech.com/public/tcp-echo-server:1.0.0
```
If the Gitea registry is private, create a pull secret in the namespace and reference it via `imagePullSecrets`.
### Package description on Gitea
The `Dockerfile` sets the standard OCI labels (`org.opencontainers.image.*`). Gitea reads them from the pushed
image and shows them on the package page:
| Label | Shown as / effect |
|------------------|--------------------------------------------------------------------------------|
| `description` | Package description text |
| `source` | Links the package to the repository with the same URL (repo must exist first) |
| `url`, `documentation`, `licenses`, `authors`, `vendor` | Metadata section on the package page |
| `version`, `revision`, `created` | Filled in by `build-push.ps1` from the tag, git commit and current time |
To change the description, edit the `LABEL` in `Dockerfile` and rebuild. If the package was pushed before the
repository existed, link it manually: package page -> **Settings** -> **Link to repository**.
## Deploy
```sh
kubectl apply -k k8s/
kubectl -n tcp-echo rollout status deploy/tcp-echo-a deploy/tcp-echo-b
```
`30-traefik-entrypoint.yaml` adds `tcpechoa` (9098) and `tcpechob` (9099) entrypoints to the k3s-managed
Traefik (Traefik restarts once). For a Helm-managed Traefik, drop that file from `kustomization.yaml` and run:
```sh
helm upgrade traefik traefik/traefik -n kube-system --reuse-values -f k8s/traefik-values.yaml
```
If Traefik's Service is a LoadBalancer, make sure the cloud/VPS firewall allows TCP 9098 and 9099.
## Test
### Linux / macOS
```sh
$ nc <server-ip> 9098
[echo-a] connected
hello
[echo-a] hello
$ nc <server-ip> 9099
[echo-b] connected
hello
[echo-b] hello
```
### Windows (PowerShell)
Windows has no `nc`. Use the included script, which opens a TCP connection, prints the greeting,
sends a message and prints the echoed reply:
```powershell
. est-echo.ps1 -Server <server-ip> -Port 9098
. est-echo.ps1 -Server <server-ip> -Port 9099 -Message "ping"
```
Expected output:
```
Connecting to <server-ip>:9098 ...
<- [echo-a] connected
-> hello
<- [echo-a] hello
```
Just to check the port is reachable (no echo):
```powershell
Test-NetConnection -ComputerName <server-ip> -Port 9098
```
For an interactive session, `telnet <server-ip> 9098` works if the Telnet Client feature is enabled
(`Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient`), or install `ncat` via `winget install Insecure.Nmap`.
### Local test with Docker
```powershell
docker build -t tcp-echo:local .
docker run --rm -d --name tcp-echo-test -e INSTANCE_ID=echo-local -p 9099:9099 tcp-echo:local
. est-echo.ps1 -Server localhost -Port 9099
docker rm -f tcp-echo-test
```