mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-06 07:47:08 +08:00
feat: use network instead of parent-container
This commit is contained in:
2
Makefile
2
Makefile
@@ -89,7 +89,7 @@ container:
|
||||
############################ build local
|
||||
.PHONY: container-local
|
||||
container-local: kubevpn-linux-amd64
|
||||
docker buildx build --platform linux/amd64 -t docker.io/naison/kubevpn:latest -f $(BUILD_DIR)/local.Dockerfile .
|
||||
docker buildx build --platform linux/amd64 -t docker.io/naison/kubevpn:latest -f $(BUILD_DIR)/local.Dockerfile --push .
|
||||
|
||||
.PHONY: container-test
|
||||
container-test: kubevpn-linux-amd64
|
||||
|
18
README.md
18
README.md
@@ -333,7 +333,7 @@ as `--entrypoint "tail -f /dev/null"`, for more parameters, see `kubevpn dev --h
|
||||
|
||||
If you want to start the development mode locally using Docker in Docker (DinD), because the program will read and
|
||||
write the `/tmp` directory, you need to manually add the parameter `-v /tmp:/tmp` (outer docker) and other thing is you
|
||||
need to special parameter `--parent-container` (inner docker) for sharing network and pid
|
||||
need to special parameter `--network` (inner docker) for sharing network and pid
|
||||
|
||||
Example:
|
||||
|
||||
@@ -345,7 +345,7 @@ docker run -it --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /tmp
|
||||
➜ ~ docker run -it --privileged -c authors -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp -v /Users/naison/.kube/vke:/root/.kube/config -v /Users/naison/Desktop/kubevpn/bin:/app naison/kubevpn:v1.1.21
|
||||
root@4d0c3c4eae2b:/# hostname
|
||||
4d0c3c4eae2b
|
||||
root@4d0c3c4eae2b:/# kubevpn dev deployment/authors -n kube-system --image naison/kubevpn:v1.1.21 --headers user=naison --parent-container 4d0c3c4eae2b --entrypoint "tail -f /dev/null"
|
||||
root@4d0c3c4eae2b:/# kubevpn dev deployment/authors -n kube-system --image naison/kubevpn:v1.1.21 --headers user=naison --network container:4d0c3c4eae2b --entrypoint "tail -f /dev/null"
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
Warn: Use sudo to execute command kubevpn can not use user env KUBECONFIG.
|
||||
@@ -507,7 +507,7 @@ pod [kubevpn-traffic-manager] status is Running
|
||||
...
|
||||
```
|
||||
|
||||
- When use kubevpn dev, but got error code 137, how to resolve ?
|
||||
- When use `kubevpn dev`, but got error code 137, how to resolve ?
|
||||
|
||||
```text
|
||||
dns service ok
|
||||
@@ -527,3 +527,15 @@ clean up successful
|
||||
|
||||
This is because of your docker-desktop required resource is less than pod running request resource, it OOM killed, so
|
||||
you can add more resource in your docker-desktop setting `Preferences --> Resources --> Memory`
|
||||
|
||||
- I am using WSL( Windows Sub Linux ) Docker, when use mode `kubevpn dev`, can not connect to cluster network, how to
|
||||
solve this problem?
|
||||
|
||||
Answer: this is because WSL'Docker using Windows's Network, so if even start a container in WSL, this container will
|
||||
not use WSL network, but use Windows network
|
||||
Solution:
|
||||
|
||||
- 1): install docker in WSL, not use Windows Docker-desktop
|
||||
- 2): use command `kubevpn connect` on Windows, and then startup `kubevpn dev` in WSL
|
||||
- 3): startup a container using command `kubevpn connect` on Windows, and then
|
||||
startup `kubevpn dev --network container:$CONTAINER_ID` in WSL
|
14
README_ZH.md
14
README_ZH.md
@@ -325,7 +325,7 @@ de9e2f8ab57d nginx:latest "/docker-entrypoint.…" 5 seconds
|
||||
### DinD ( Docker in Docker ) 在 Docker 中使用 kubevpn
|
||||
|
||||
如果你想在本地使用 Docker in Docker (DinD) 的方式启动开发模式, 由于程序会读写 `/tmp` 目录,您需要手动添加参数 `-v /tmp:/tmp`, 还有一点需要注意, 如果使用 DinD
|
||||
模式,为了共享容器网络和 pid, 还需要指定参数 `--parent-container`
|
||||
模式,为了共享容器网络和 pid, 还需要指定参数 `--network`
|
||||
|
||||
例如:
|
||||
|
||||
@@ -337,7 +337,7 @@ docker run -it --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /tmp
|
||||
➜ ~ docker run -it --privileged -c authors -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp -v /Users/naison/.kube/config:/root/.kube/config naison/kubevpn:v1.1.21
|
||||
root@4d0c3c4eae2b:/# hostname
|
||||
4d0c3c4eae2b
|
||||
root@4d0c3c4eae2b:/# kubevpn dev deployment/authors -n kube-system --image naison/kubevpn:v1.1.21 --headers user=naison --parent-container 4d0c3c4eae2b --entrypoint "tail -f /dev/null"
|
||||
root@4d0c3c4eae2b:/# kubevpn dev deployment/authors -n kube-system --image naison/kubevpn:v1.1.21 --headers user=naison --network container:4d0c3c4eae2b --entrypoint "tail -f /dev/null"
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
Warn: Use sudo to execute command kubevpn can not use user env KUBECONFIG.
|
||||
@@ -517,3 +517,13 @@ clean up successful
|
||||
|
||||
这是因为你的 `Docker-desktop` 声明的资源, 小于 container 容器启动时所需要的资源, 因此被 OOM 杀掉了, 你可以增加 `Docker-desktop` 对于 resources
|
||||
的设置, 目录是:`Preferences --> Resources --> Memory`
|
||||
|
||||
- 我在使用 WSL( Windows Sub Linux ) Docker, 当我在使用命令 `kubevpn dev` 进入开发模式的时候, 在 terminal 中无法提示链接集群网络, 这是为什么, 如何解决?
|
||||
|
||||
答案: 这是因为 WSL 的 Docker 使用的是 主机 Windows 的网络, 所以即便在 WSL 中启动 container, 这个 container 不会使用 WSL 的网络,而是使用 Windows 的网络。
|
||||
解决方案:
|
||||
|
||||
- 1): 在 WSL 中安装 Docker, 不要使用 Windows 版本的 Docker-desktop
|
||||
- 2): 在主机 Windows 使用命令 `kubevpn connect`, 然后在 WSL 中使用 `kubevpn dev` 进入开发模式
|
||||
- 3): 在主机 Windows 上启动一个 container,在 container 中使用命令 `kubevpn connect`, 然后在 WSL
|
||||
中使用 `kubevpn dev --network container:$CONTAINER_ID`
|
@@ -16,7 +16,7 @@ ARG BASE=github.com/wencaiwulue/kubevpn
|
||||
RUN sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list \
|
||||
&& sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
|
||||
RUN apt-get clean && apt-get update && apt-get install -y wget dnsutils vim curl \
|
||||
net-tools iptables iputils-ping lsof iproute2 tcpdump binutils
|
||||
net-tools iptables iputils-ping lsof iproute2 tcpdump binutils traceroute
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
@@ -4,7 +4,7 @@ FROM ubuntu:latest
|
||||
RUN sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list \
|
||||
&& sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
|
||||
RUN apt-get clean && apt-get update && apt-get install -y wget dnsutils vim curl \
|
||||
net-tools iptables iputils-ping lsof iproute2 tcpdump binutils
|
||||
net-tools iptables iputils-ping lsof iproute2 tcpdump binutils traceroute
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
cmdutil "k8s.io/kubectl/pkg/cmd/util"
|
||||
@@ -32,26 +33,30 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
Env: opts.NewListOpts(nil),
|
||||
Volumes: opts.NewListOpts(nil),
|
||||
ExtraHosts: opts.NewListOpts(nil),
|
||||
Aliases: opts.NewListOpts(nil),
|
||||
NoProxy: false,
|
||||
ExtraCIDR: []string{},
|
||||
}
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "dev",
|
||||
Short: i18n.T("Proxy kubernetes workloads inbound traffic into local PC and dev in docker container"),
|
||||
Long: templates.LongDesc(i18n.T(`Proxy kubernetes workloads inbound traffic into local PC`)),
|
||||
Short: i18n.T("Startup your workloads in local Docker container use same volume、env、and network with cluster"),
|
||||
Long: templates.LongDesc(i18n.T(`Startup your workloads in local Docker container use same volume、env、and network with cluster`)),
|
||||
Example: templates.Examples(i18n.T(`
|
||||
# Dev reverse proxy
|
||||
- reverse deployment
|
||||
# Develop workloads
|
||||
- develop deployment
|
||||
kubevpn dev deployment/productpage
|
||||
|
||||
- reverse service
|
||||
- develop service
|
||||
kubevpn dev service/productpage
|
||||
|
||||
# Reverse proxy with mesh, traffic with header a=1, will hit local PC, otherwise no effect
|
||||
# Develop workloads with mesh, traffic with header a=1, will hit local PC, otherwise no effect
|
||||
kubevpn dev service/productpage --headers a=1
|
||||
|
||||
# Dev reverse proxy api-server behind of bastion host or ssh jump host
|
||||
# Develop workloads without proxy traffic
|
||||
kubevpn dev service/productpage --no-proxy
|
||||
|
||||
# Develop workloads which api-server behind of bastion host or ssh jump host
|
||||
kubevpn dev deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem
|
||||
|
||||
# it also support ProxyJump, like
|
||||
@@ -78,13 +83,14 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
ExtraCIDR: devOptions.ExtraCIDR,
|
||||
}
|
||||
|
||||
if devOptions.ParentContainer != "" {
|
||||
mode := container.NetworkMode(devOptions.NetMode.NetworkMode())
|
||||
if mode.IsContainer() {
|
||||
client, _, err := dev.GetClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var inspect types.ContainerJSON
|
||||
inspect, err = client.ContainerInspect(context.Background(), devOptions.ParentContainer)
|
||||
inspect, err = client.ContainerInspect(context.Background(), mode.ConnectedContainer())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,7 +98,7 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
return fmt.Errorf("can not get container status, please make contianer name is valid")
|
||||
}
|
||||
if !inspect.State.Running {
|
||||
return fmt.Errorf("container %s status is %s, expect is running, please make sure your outer docker name is correct", devOptions.ParentContainer, inspect.State.Status)
|
||||
return fmt.Errorf("container %s status is %s, expect is running, please make sure your outer docker name is correct", mode.ConnectedContainer(), inspect.State.Status)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +151,15 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
|
||||
// docker options
|
||||
cmd.Flags().Var(&devOptions.ExtraHosts, "add-host", "Add a custom host-to-IP mapping (host:ip)")
|
||||
cmd.Flags().StringVar(&devOptions.ParentContainer, "parent-container", "", "Parent container name if running in Docker (Docker in Docker)")
|
||||
//cmd.Flags().StringVar(&devOptions.ParentContainer, "parent-container", "", "Parent container name if running in Docker (Docker in Docker)")
|
||||
// We allow for both "--net" and "--network", although the latter is the recommended way.
|
||||
cmd.Flags().Var(&devOptions.NetMode, "net", "Connect a container to a network")
|
||||
cmd.Flags().Var(&devOptions.NetMode, "network", "Connect a container to a network")
|
||||
cmd.Flags().MarkHidden("net")
|
||||
// We allow for both "--net-alias" and "--network-alias", although the latter is the recommended way.
|
||||
cmd.Flags().Var(&devOptions.Aliases, "net-alias", "Add network-scoped alias for the container")
|
||||
cmd.Flags().Var(&devOptions.Aliases, "network-alias", "Add network-scoped alias for the container")
|
||||
cmd.Flags().MarkHidden("net-alias")
|
||||
cmd.Flags().VarP(&devOptions.Volumes, "volume", "v", "Bind mount a volume")
|
||||
cmd.Flags().Var(&devOptions.Mounts, "mount", "Attach a filesystem mount to the container")
|
||||
cmd.Flags().Var(&devOptions.Expose, "expose", "Expose a port or a range of ports")
|
||||
|
@@ -28,26 +28,29 @@ func CmdDuplicate(f cmdutil.Factory) *cobra.Command {
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "duplicate",
|
||||
Short: i18n.T("Connect to kubernetes cluster network, and duplicate workloads to target-kubeconfig cluster with same volume、env、and network"),
|
||||
Long: templates.LongDesc(i18n.T(`Connect to kubernetes cluster network, and duplicate workloads to target-kubeconfig cluster with same volume、env、and network`)),
|
||||
Short: i18n.T("Duplicate workloads to target-kubeconfig cluster with same volume、env、and network"),
|
||||
Long: templates.LongDesc(i18n.T(`Duplicate workloads to target-kubeconfig cluster with same volume、env、and network`)),
|
||||
Example: templates.Examples(i18n.T(`
|
||||
# duplicate
|
||||
- duplicate deployment
|
||||
- duplicate deployment in current cluster and current namespace
|
||||
kubevpn duplicate deployment/productpage
|
||||
|
||||
- duplicate service
|
||||
kubevpn proxy service/productpage
|
||||
- duplicate deployment in current cluster with different namespace
|
||||
kubevpn duplicate deployment/productpage -n test
|
||||
|
||||
- duplicate deployment to another cluster
|
||||
kubevpn duplicate deployment/productpage --target-kubeconfig ~/.kube/other-kubeconfig
|
||||
|
||||
- duplicate multiple workloads
|
||||
kubevpn duplicate deployment/authors deployment/productpage
|
||||
or
|
||||
kubevpn duplicate deployment authors productpage
|
||||
|
||||
# Reverse duplicate with mesh, traffic with header a=1, will hit local PC, otherwise no effect
|
||||
kubevpn duplicate service/productpage --headers a=1
|
||||
# duplicate with mesh, traffic with header a=1, will hit duplicate workloads, otherwise hit origin workloads
|
||||
kubevpn duplicate deployment/productpage --headers a=1
|
||||
|
||||
# Connect to api-server behind of bastion host or ssh jump host and proxy kubernetes resource traffic into local PC
|
||||
kubevpn duplicate --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem service/productpage --headers a=1
|
||||
# duplicate workloads which api-server behind of bastion host or ssh jump host
|
||||
kubevpn duplicate deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem --headers a=1
|
||||
|
||||
# it also support ProxyJump, like
|
||||
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐
|
||||
|
@@ -25,8 +25,8 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
|
||||
var sshConf = &util.SshConfig{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "proxy",
|
||||
Short: i18n.T("Connect to kubernetes cluster network and proxy kubernetes workloads inbound traffic into local PC"),
|
||||
Long: templates.LongDesc(i18n.T(`Connect to kubernetes cluster network, or proxy kubernetes workloads inbound traffic into local PC`)),
|
||||
Short: i18n.T("Proxy kubernetes workloads inbound traffic into local PC"),
|
||||
Long: templates.LongDesc(i18n.T(`Proxy kubernetes workloads inbound traffic into local PC`)),
|
||||
Example: templates.Examples(i18n.T(`
|
||||
# Reverse proxy
|
||||
- proxy deployment
|
||||
@@ -44,7 +44,7 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
|
||||
kubevpn proxy service/productpage --headers a=1
|
||||
|
||||
# Connect to api-server behind of bastion host or ssh jump host and proxy kubernetes resource traffic into local PC
|
||||
kubevpn proxy --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem service/productpage --headers a=1
|
||||
kubevpn proxy deployment/productpage --ssh-addr 192.168.1.100:22 --ssh-username root --ssh-keyfile /Users/naison/.ssh/ssh.pem --headers a=1
|
||||
|
||||
# it also support ProxyJump, like
|
||||
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────────┐
|
||||
|
16
pkg/cp/cp.go
16
pkg/cp/cp.go
@@ -7,10 +7,11 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
@@ -52,7 +53,10 @@ func extractFileSpec(arg string) (fileSpec, error) {
|
||||
if i == 0 {
|
||||
return fileSpec{}, errFileSpecDoesntMatchFormat
|
||||
}
|
||||
if i == -1 {
|
||||
|
||||
// C:\Users\ADMINI~1\AppData\Local\Temp\849198392506502457
|
||||
// disk name C is not a pod name
|
||||
if i == -1 || (runtime.GOOS == "windows" && strings.Contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ", arg[:i])) {
|
||||
return fileSpec{
|
||||
File: newLocalPath(arg),
|
||||
}, nil
|
||||
@@ -178,7 +182,9 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec, options *exec.ExecOptions) e
|
||||
|
||||
go func(src localPath, dest remotePath, writer io.WriteCloser) {
|
||||
defer writer.Close()
|
||||
cmdutil.CheckErr(makeTar(src, dest, writer))
|
||||
if err := makeTar(src, dest, writer); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}(srcFile, destFile, writer)
|
||||
var cmdArr []string
|
||||
|
||||
@@ -259,7 +265,9 @@ func (t *TarPipe) initReadFrom(n uint64) {
|
||||
|
||||
go func() {
|
||||
defer t.outStream.Close()
|
||||
cmdutil.CheckErr(t.o.execute(options))
|
||||
if err := t.o.execute(options); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/client"
|
||||
@@ -49,7 +50,8 @@ type Options struct {
|
||||
Publish opts.ListOpts
|
||||
Expose opts.ListOpts
|
||||
ExtraHosts opts.ListOpts
|
||||
ParentContainer string
|
||||
NetMode opts.NetworkOpt
|
||||
Aliases opts.ListOpts
|
||||
Env opts.ListOpts
|
||||
Mounts opts.MountOpt
|
||||
Volumes opts.ListOpts
|
||||
@@ -124,12 +126,15 @@ func (d Options) Main(ctx context.Context) error {
|
||||
if outOfMemory {
|
||||
return fmt.Errorf("your pod resource request is bigger than docker-desktop resource, please adjust your docker-desktop resource")
|
||||
}
|
||||
if d.ParentContainer != "" {
|
||||
mode := container.NetworkMode(d.NetMode.NetworkMode())
|
||||
if mode.IsUserDefined() {
|
||||
for _, config := range list[:] {
|
||||
// remove expose port
|
||||
config.config.ExposedPorts = nil
|
||||
config.hostConfig.NetworkMode = containertypes.NetworkMode("container:" + d.ParentContainer)
|
||||
config.hostConfig.PidMode = containertypes.PidMode("container:" + d.ParentContainer)
|
||||
config.hostConfig.NetworkMode = mode
|
||||
if mode.IsContainer() {
|
||||
config.hostConfig.PidMode = containertypes.PidMode(d.NetMode.NetworkMode())
|
||||
}
|
||||
config.hostConfig.PortBindings = nil
|
||||
|
||||
// remove dns
|
||||
|
@@ -148,6 +148,11 @@ func fillOptions(r Run, copts Options) error {
|
||||
|
||||
config.hostConfig.Binds = binds
|
||||
|
||||
// todo
|
||||
if copts.Aliases.Len() != 0 {
|
||||
//config.networkingConfig.EndpointsConfig
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -146,7 +146,7 @@ func GetVolume(ctx context.Context, f util.Factory, ns, pod string) (map[string]
|
||||
}
|
||||
err = copyOptions.Run()
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "Can not download volume %s path %s, err: %v, ignore...\n", volumeMount.Name, volumeMount.MountPath, err)
|
||||
_, _ = fmt.Fprintf(os.Stderr, "failed to download volume %s path %s to %s, err: %v, ignore...\n", volumeMount.Name, remotePath, join, err)
|
||||
continue
|
||||
}
|
||||
m = append(m, mount.Mount{
|
||||
|
Reference in New Issue
Block a user