Skip to content

Commit 05bdeeb

Browse files
committed
feat(components/router): add kubernetes native common ingress component
1 parent 0bdf8b4 commit 05bdeeb

File tree

21 files changed

+438
-1
lines changed

21 files changed

+438
-1
lines changed

.github/workflows/router-test.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Router Tests
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
paths:
7+
- 'components/router/**'
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
test:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Go
21+
uses: actions/setup-go@v5
22+
with:
23+
go-version: '1.24.0'
24+
25+
- name: Run golint
26+
run: |
27+
cd components/router
28+
make golint
29+
30+
- name: Run Build
31+
run: |
32+
cd components/router
33+
make build
34+
35+
- name: Run tests
36+
run: |
37+
cd components/router
38+
make test

components/router/DEVELOPMENT.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Development Guide (Quick)
2+
3+
## Prerequisites
4+
- Go 1.24+
5+
- Docker (optional, for image build)
6+
- Access to a Kubernetes cluster if you want to exercise proxy behavior.
7+
8+
## Install deps
9+
```bash
10+
cd components/router
11+
go mod tidy && go mod vendor
12+
```
13+
14+
## Build & Run
15+
```bash
16+
make build # binary at bin/router with ldflags version info
17+
./bin/router \
18+
--namespace <ns> \
19+
--ingress-label-key <label-key> \
20+
--port 28888 \
21+
--log-level info
22+
```
23+
24+
## Tests & Lint
25+
```bash
26+
make test # go test ./pkg/...
27+
go vet ./... # included in make build
28+
```
29+
30+
## Docker (with build args)
31+
```bash
32+
docker build \
33+
--build-arg VERSION=$(git describe --tags --always --dirty) \
34+
--build-arg GIT_COMMIT=$(git rev-parse HEAD) \
35+
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
36+
-t opensandbox/router:dev .
37+
```
38+
39+
## Key Paths
40+
- `main.go` — entrypoint, HTTP routes.
41+
- `pkg/proxy/` — HTTP/WebSocket proxy logic and pod watching.
42+
- `version/` — build metadata (ldflags).
43+
44+
## Tips
45+
- Health check: `/status.ok`
46+
- Env overrides: `VERSION/GIT_COMMIT/BUILD_TIME` usable via Makefile and build.sh.
47+

components/router/Dockerfile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@ FROM golang:1.24.0 AS builder
1616

1717
WORKDIR /build
1818

19+
ARG VERSION=dev
20+
ARG GIT_COMMIT=unknown
21+
ARG BUILD_TIME=unknown
22+
1923
COPY go.mod go.sum ./
2024

2125
RUN go mod download
2226

2327
COPY . .
2428

25-
RUN CGO_ENABLED=0 go build -o /build/router ./main.go
29+
RUN CGO_ENABLED=0 go build \
30+
-ldflags "-X 'github.com/alibaba/opensandbox/router/version.Version=${VERSION}' \
31+
-X 'github.com/alibaba/opensandbox/router/version.BuildTime=${BUILD_TIME}' \
32+
-X 'github.com/alibaba/opensandbox/router/version.GitCommit=${GIT_COMMIT}'" \
33+
-o /build/router ./main.go
2634

2735
FROM alpine:latest
2836

components/router/README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# OpenSandbox Router
2+
3+
## Overview
4+
- HTTP/WebSocket reverse proxy that routes to sandbox Pods by `OPEN-SANDBOX-INGRESS` header or Host.
5+
- Watches Pods in a target Namespace filtered by an ingress label, and routes only when exactly one ready Pod matches.
6+
- Exposes `/status.ok` health check; prints build metadata (version, commit, time, Go/platform) at startup.
7+
8+
## Quick Start
9+
```bash
10+
go run main.go \
11+
--namespace <target-namespace> \
12+
--ingress-label-key <label-key> \
13+
--port 28888 \
14+
--log-level info
15+
```
16+
Endpoints: `/` (proxy), `/status.ok` (health).
17+
18+
## Build
19+
```bash
20+
cd components/router
21+
make build
22+
# override build metadata if needed
23+
VERSION=1.2.3 GIT_COMMIT=$(git rev-parse HEAD) BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") make build
24+
```
25+
26+
## Docker Build
27+
Dockerfile already wires ldflags via build args:
28+
```bash
29+
docker build \
30+
--build-arg VERSION=$(git describe --tags --always --dirty) \
31+
--build-arg GIT_COMMIT=$(git rev-parse HEAD) \
32+
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
33+
-t opensandbox/router:local .
34+
```
35+
36+
## Multi-arch Publish Script
37+
`build.sh` uses buildx to build/push linux/amd64 and linux/arm64:
38+
```bash
39+
cd components/router
40+
TAG=local VERSION=1.2.3 GIT_COMMIT=abc BUILD_TIME=2025-01-01T00:00:00Z bash build.sh
41+
```
42+
43+
## Runtime Requirements
44+
- Access to Kubernetes API (in-cluster or via KUBECONFIG).
45+
- Pods in the specified Namespace labeled with the configured ingress label; Pod IPs must be reachable.
46+
47+
## Behavior Notes
48+
- Routing key priority: `OPEN-SANDBOX-INGRESS` header first, otherwise Host parsing `<ingress>-<port>.*`.
49+
- Multiple matching Pods → HTTP 409; no matching Pod → HTTP 404.
50+
- WebSocket path forwards essential headers and X-Forwarded-*; HTTP path strips `OPEN-SANDBOX-INGRESS` before proxying.
51+
52+
## Development & Tests
53+
```bash
54+
cd components/router
55+
go test ./...
56+
```
57+
Key code:
58+
- `main.go`: entrypoint and handlers.
59+
- `pkg/proxy/`: HTTP/WebSocket proxy logic, pod watching, health check.
60+
- `version/`: build metadata output (populated via ldflags).
61+

components/router/README_zh.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# OpenSandbox Router
2+
3+
## 功能概览
4+
- 基于 Kubernetes Pod 标签的 HTTP / WebSocket 反向代理,按 `OPEN-SANDBOX-INGRESS` 或 Host 解析目标沙箱。
5+
- 自动监听目标 Namespace 内带有 `ingress-label-key` 标签的 Pod 列表,动态路由到单个可用实例,避免多实例冲突。
6+
- 提供 `/status.ok` 健康探针,启动时打印编译版本、时间、提交、Go/平台信息。
7+
8+
## 启动与参数
9+
```bash
10+
go run main.go \
11+
--namespace <目标命名空间> \
12+
--ingress-label-key <标签键> \
13+
--port 28888 \
14+
--log-level info
15+
```
16+
- `--namespace`:监听的 Kubernetes 命名空间。
17+
- `--ingress-label-key`:用于匹配沙箱 Pod 的标签键。
18+
- `--port`:监听端口(默认 28888)。
19+
- `--log-level`:日志级别,遵循 zap 定义。
20+
21+
入口:`/` 走代理,`/status.ok` 健康检查。
22+
23+
## 构建与发布
24+
### 本地二进制
25+
```bash
26+
cd components/router
27+
make build
28+
# 可覆盖版本信息
29+
VERSION=1.2.3 GIT_COMMIT=$(git rev-parse HEAD) BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") make build
30+
```
31+
32+
### Docker 镜像
33+
Dockerfile 支持编译期注入:
34+
```bash
35+
docker build \
36+
--build-arg VERSION=$(git describe --tags --always --dirty) \
37+
--build-arg GIT_COMMIT=$(git rev-parse HEAD) \
38+
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
39+
-t opensandbox/router:local .
40+
```
41+
42+
### 多架构推送脚本
43+
`build.sh` 使用 buildx 构建并推送 amd64/arm64,多标签支持,传入同名环境变量即可覆盖:
44+
```bash
45+
cd components/router
46+
TAG=local VERSION=1.2.3 GIT_COMMIT=abc BUILD_TIME=2025-01-01T00:00:00Z bash build.sh
47+
```
48+
49+
## 运行时依赖
50+
- 可访问的 Kubernetes API(集群内或 KUBECONFIG)。
51+
- 目标命名空间中按 `ingress-label-key` 标记的运行中 Pod,并确保 Pod IP 可直连。
52+
53+
## 开发与测试
54+
```bash
55+
cd components/router
56+
go test ./...
57+
```
58+
主要代码位置:
59+
- `main.go`:入口与 HTTP 路由注册。
60+
- `pkg/proxy/`:HTTP/WebSocket 代理逻辑、Pod 监听、健康检查。
61+
- `version/`:版本信息输出(ldflags 注入)。
62+
63+
## 常见行为说明
64+
- Header 优先:`OPEN-SANDBOX-INGRESS`,否则回退 Host 解析 `<ingress>-<port>.*`
65+
- 多实例同 ingress 时返回 409;无可用 Pod 返回 404。
66+
- WebSocket 保留关键头并透传 X-Forwarded-*,HTTP 会移除 `OPEN-SANDBOX-INGRESS` 后再转发。
67+

components/router/build.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
set -ex
1717

1818
TAG=${TAG:-latest}
19+
VERSION=${VERSION:-$(git describe --tags --always --dirty 2>/dev/null || echo "dev")}
20+
GIT_COMMIT=${GIT_COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo "unknown")}
21+
BUILD_TIME=${BUILD_TIME:-$(date -u +"%Y-%m-%dT%H:%M:%SZ")}
1922

2023
docker buildx rm router-builder || true
2124

@@ -28,6 +31,9 @@ docker buildx ls
2831
docker buildx build \
2932
-t opensandbox/router:${TAG} \
3033
-t sandbox-registry.cn-zhangjiakou.cr.aliyuncs.com/opensandbox/router:${TAG} \
34+
--build-arg VERSION="${VERSION}" \
35+
--build-arg GIT_COMMIT="${GIT_COMMIT}" \
36+
--build-arg BUILD_TIME="${BUILD_TIME}" \
3137
--platform linux/amd64,linux/arm64 \
3238
--push \
3339
.

components/router/main.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Copyright 2025 Alibaba Group Holding Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package main
216

317
import (

components/router/pkg/flag/flags.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Copyright 2025 Alibaba Group Holding Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package flag
216

317
var (

components/router/pkg/flag/parser.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Copyright 2025 Alibaba Group Holding Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package flag
216

317
import (

components/router/pkg/proxy/header.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Copyright 2025 Alibaba Group Holding Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package proxy
216

317
import "net/http"

0 commit comments

Comments
 (0)