feat: replace envoy config tunIP if header and uid is same

This commit is contained in:
fengcaiwen
2024-01-10 12:05:32 +08:00
parent b2a6e602e6
commit 156ee998cd
5 changed files with 77 additions and 39 deletions

View File

@@ -362,6 +362,15 @@ Now let's access local service with header `"a: 1"`
Hello world!
```
If you want cancel proxy, just run command:
```shell
➜ ~ kubevpn leave deployments/productpage
leave workload deployments/productpage
workload default/deployments/productpage is controlled by a controller
leave workload deployments/productpage successfully
```
### Dev mode in local Docker 🐳
Run the Kubernetes pod in the local Docker container, and cooperate with the service mesh to intercept the traffic with

View File

@@ -292,6 +292,15 @@ create remote inbound pod for deployment/productpage successfully
Hello world!%
```
如果你需要取消代理流量,可以执行如下命令:
```shell
➜ ~ kubevpn leave deployments/productpage
leave workload deployments/productpage
workload default/deployments/productpage is controlled by a controller
leave workload deployments/productpage successfully
```
### 本地进入开发模式 🐳
将 Kubernetes pod 运行在本地的 Docker 容器中,同时配合 service mesh, 拦截带有指定 header 的流量到本地,或者所有的流量到本地。这个开发模式依赖于本地 Docker。

View File

@@ -130,7 +130,7 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
return nil
},
}
cmd.Flags().StringToStringVarP(&options.Headers, "headers", "H", map[string]string{}, "Traffic with special headers with reverse it to clone workloads, you should startup your service after reverse workloads successfully, If not special, redirect all traffic to clone workloads, format is k=v, like: k1=v1,k2=v2")
cmd.Flags().StringToStringVarP(&options.Headers, "headers", "H", map[string]string{}, "Traffic with special headers (use `and` to match all headers) with reverse it to local PC, If not special, redirect all traffic to local PC. eg: --headers a=1 --headers b=2")
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug mode or not, true or false")
cmd.Flags().StringVar(&config.Image, "image", config.Image, "Use this image to startup container")
cmd.Flags().StringArrayVar(&options.ExtraCIDR, "extra-cidr", []string{}, "Extra cidr string, eg: --extra-cidr 192.168.0.159/24 --extra-cidr 192.168.1.160/32")

View File

@@ -45,6 +45,9 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
# Reverse proxy with mesh, traffic with header a=1, will hit local PC, otherwise no effect
kubevpn proxy service/productpage --headers a=1
# Reverse proxy with mesh, traffic with header a=1 and b=2, will hit local PC, otherwise no effect
kubevpn proxy service/productpage --headers a=1 --headers b=2
# Connect to api-server behind of bastion host or ssh jump host and proxy kubernetes resource traffic into local PC
kubevpn proxy deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile ~/.ssh/ssh.pem --headers a=1
@@ -146,7 +149,7 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
return nil
},
}
cmd.Flags().StringToStringVarP(&connect.Headers, "headers", "H", map[string]string{}, "Traffic with special headers with reverse it to local PC, you should startup your service after reverse workloads successfully, If not special, redirect all traffic to local PC, format is k=v, like: k1=v1,k2=v2")
cmd.Flags().StringToStringVarP(&connect.Headers, "headers", "H", map[string]string{}, "Traffic with special headers (use `and` to match all headers) with reverse it to local PC, If not special, redirect all traffic to local PC. eg: --headers a=1 --headers b=2")
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug mode or not, true or false")
cmd.Flags().StringVar(&config.Image, "image", config.Image, "Use this image to startup container")
cmd.Flags().StringArrayVar(&connect.ExtraCIDR, "extra-cidr", []string{}, "Extra cidr string, eg: --extra-cidr 192.168.0.159/24 --extra-cidr 192.168.1.160/32")

View File

@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"reflect"
"strings"
"time"
@@ -199,43 +200,8 @@ func addEnvoyConfig(mapInterface v12.ConfigMapInterface, nodeID string, tunIP ut
return err
}
}
var index = -1
for i, virtual := range v {
if nodeID == virtual.Uid {
index = i
break
}
}
if index < 0 {
v = append(v, &controlplane.Virtual{
Uid: nodeID,
Ports: port,
Rules: []*controlplane.Rule{{
Headers: headers,
LocalTunIPv4: tunIP.LocalTunIPv4,
LocalTunIPv6: tunIP.LocalTunIPv6,
}},
})
} else {
var found bool
for j, rule := range v[index].Rules {
if rule.LocalTunIPv4 == tunIP.LocalTunIPv4 &&
rule.LocalTunIPv6 == tunIP.LocalTunIPv6 {
found = true
v[index].Rules[j].Headers = util.Merge[string, string](v[index].Rules[j].Headers, headers)
}
}
if !found {
v[index].Rules = append(v[index].Rules, &controlplane.Rule{
Headers: headers,
LocalTunIPv4: tunIP.LocalTunIPv4,
LocalTunIPv6: tunIP.LocalTunIPv6,
})
if v[index].Ports == nil {
v[index].Ports = port
}
}
}
v = addVirtualRule(v, nodeID, port, headers, tunIP)
marshal, err := yaml.Marshal(v)
if err != nil {
@@ -246,6 +212,57 @@ func addEnvoyConfig(mapInterface v12.ConfigMapInterface, nodeID string, tunIP ut
return err
}
func addVirtualRule(v []*controlplane.Virtual, nodeID string, port []v1.ContainerPort, headers map[string]string, tunIP util.PodRouteConfig) []*controlplane.Virtual {
var index = -1
for i, virtual := range v {
if nodeID == virtual.Uid {
index = i
break
}
}
// 1) if not found uid, means nobody proxying it, just add it
if index < 0 {
return append(v, &controlplane.Virtual{
Uid: nodeID,
Ports: port,
Rules: []*controlplane.Rule{{
Headers: headers,
LocalTunIPv4: tunIP.LocalTunIPv4,
LocalTunIPv6: tunIP.LocalTunIPv6,
}},
})
}
// 2) if already proxy deployment/xxx with header a=1. also want to add b=2
for j, rule := range v[index].Rules {
if rule.LocalTunIPv4 == tunIP.LocalTunIPv4 &&
rule.LocalTunIPv6 == tunIP.LocalTunIPv6 {
v[index].Rules[j].Headers = util.Merge[string, string](v[index].Rules[j].Headers, headers)
return v
}
}
// 3) if already proxy deployment/xxx with header a=1, other user can replace it to self
for j, rule := range v[index].Rules {
if reflect.DeepEqual(rule.Headers, headers) {
v[index].Rules[j].LocalTunIPv6 = tunIP.LocalTunIPv6
v[index].Rules[j].LocalTunIPv4 = tunIP.LocalTunIPv4
return v
}
}
// 4) if header is not same and tunIP is not same, means another users, just add it
v[index].Rules = append(v[index].Rules, &controlplane.Rule{
Headers: headers,
LocalTunIPv4: tunIP.LocalTunIPv4,
LocalTunIPv6: tunIP.LocalTunIPv6,
})
if v[index].Ports == nil {
v[index].Ports = port
}
return v
}
func removeEnvoyConfig(mapInterface v12.ConfigMapInterface, nodeID string, localTunIPv4 string) (bool, error) {
configMap, err := mapInterface.Get(context.Background(), config.ConfigMapPodTrafficManager, metav1.GetOptions{})
if k8serrors.IsNotFound(err) {