mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-07 08:11:01 +08:00
feat: use created network to startup container
This commit is contained in:
@@ -32,7 +32,7 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
|
||||
Env: opts.NewListOpts(nil),
|
||||
Volumes: opts.NewListOpts(nil),
|
||||
ExtraHosts: opts.NewListOpts(nil),
|
||||
//Aliases: opts.NewListOpts(nil),
|
||||
Aliases: opts.NewListOpts(nil),
|
||||
NoProxy: false,
|
||||
ExtraCIDR: []string{},
|
||||
}
|
||||
@@ -164,9 +164,9 @@ Startup your kubernetes workloads in local Docker container with same volume、e
|
||||
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().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")
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
@@ -16,7 +17,9 @@ import (
|
||||
"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/api/types/network"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
log "github.com/sirupsen/logrus"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@@ -27,8 +30,10 @@ import (
|
||||
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||
"k8s.io/kubectl/pkg/util/podutils"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/handler"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/mesh"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/tun"
|
||||
"github.com/wencaiwulue/kubevpn/pkg/util"
|
||||
)
|
||||
|
||||
@@ -52,7 +57,7 @@ type Options struct {
|
||||
Expose opts.ListOpts
|
||||
ExtraHosts opts.ListOpts
|
||||
NetMode opts.NetworkOpt
|
||||
//Aliases opts.ListOpts
|
||||
Aliases opts.ListOpts
|
||||
Env opts.ListOpts
|
||||
Mounts opts.MountOpt
|
||||
Volumes opts.ListOpts
|
||||
@@ -146,6 +151,43 @@ func (d Options) Main(ctx context.Context) error {
|
||||
config.config.Hostname = ""
|
||||
}
|
||||
} else {
|
||||
getInterface, err := tun.GetInterface()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrs, err := getInterface.Addrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cidr, _, err := net.ParseCIDR(addrs[0].String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
create, err := cli.NetworkCreate(ctx, list[0].containerName, types.NetworkCreate{
|
||||
Driver: "bridge",
|
||||
Scope: "local",
|
||||
IPAM: &network.IPAM{
|
||||
Driver: "",
|
||||
Options: nil,
|
||||
Config: []network.IPAMConfig{
|
||||
{
|
||||
Subnet: config.CIDR.String(),
|
||||
Gateway: cidr.String(),
|
||||
},
|
||||
},
|
||||
},
|
||||
Internal: true,
|
||||
})
|
||||
if err != nil {
|
||||
if errdefs.IsForbidden(err) {
|
||||
_, _ = cli.NetworkList(ctx, types.NetworkListOptions{})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
list[0].networkingConfig.EndpointsConfig[list[0].containerName] = &network.EndpointSettings{
|
||||
NetworkID: create.ID,
|
||||
}
|
||||
// skip first
|
||||
for _, config := range list[1:] {
|
||||
// remove expose port
|
||||
@@ -182,24 +224,24 @@ func (r Run) Remove(ctx context.Context) error {
|
||||
}
|
||||
|
||||
for _, config := range r {
|
||||
//err = cli.NetworkDisconnect(ctx, config.networkName, config.containerName, true)
|
||||
//if err != nil {
|
||||
// log.Errorln(err)
|
||||
//}
|
||||
err = cli.NetworkDisconnect(ctx, config.containerName, config.containerName, true)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
err = cli.ContainerRemove(ctx, config.containerName, types.ContainerRemoveOptions{Force: true})
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
//for _, config := range r {
|
||||
// _, err = cli.NetworkInspect(ctx, config.networkName, types.NetworkInspectOptions{})
|
||||
// if err == nil {
|
||||
// err = cli.NetworkRemove(ctx, config.networkName)
|
||||
// if err != nil {
|
||||
// log.Errorln(err)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
for _, config := range r {
|
||||
_, err = cli.NetworkInspect(ctx, config.containerName, types.NetworkInspectOptions{})
|
||||
if err == nil {
|
||||
err = cli.NetworkRemove(ctx, config.containerName)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -3,13 +3,17 @@ package dev
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/cli/compose/loader"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/go-connections/nat"
|
||||
v12 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
@@ -147,6 +151,11 @@ func fillOptions(r Run, copts Options) error {
|
||||
}
|
||||
|
||||
config.hostConfig.Binds = binds
|
||||
networkOpts, err := parseNetworkOpts(copts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.networkingConfig = &network.NetworkingConfig{EndpointsConfig: networkOpts}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -171,3 +180,87 @@ func convertToStandardNotation(ports []string) ([]string, error) {
|
||||
}
|
||||
return optsList, nil
|
||||
}
|
||||
|
||||
// parseNetworkOpts converts --network advanced options to endpoint-specs, and combines
|
||||
// them with the old --network-alias and --links. If returns an error if conflicting options
|
||||
// are found.
|
||||
//
|
||||
// this function may return _multiple_ endpoints, which is not currently supported
|
||||
// by the daemon, but may be in future; it's up to the daemon to produce an error
|
||||
// in case that is not supported.
|
||||
func parseNetworkOpts(copts Options) (map[string]*network.EndpointSettings, error) {
|
||||
var (
|
||||
endpoints = make(map[string]*network.EndpointSettings, len(copts.NetMode.Value()))
|
||||
hasUserDefined, hasNonUserDefined bool
|
||||
)
|
||||
|
||||
for i, n := range copts.NetMode.Value() {
|
||||
n := n
|
||||
if container.NetworkMode(n.Target).IsUserDefined() {
|
||||
hasUserDefined = true
|
||||
} else {
|
||||
hasNonUserDefined = true
|
||||
}
|
||||
if i == 0 {
|
||||
// The first network corresponds with what was previously the "only"
|
||||
// network, and what would be used when using the non-advanced syntax
|
||||
// `--network-alias`, `--link`, `--ip`, `--ip6`, and `--link-local-ip`
|
||||
// are set on this network, to preserve backward compatibility with
|
||||
// the non-advanced notation
|
||||
n.Aliases = copts.Aliases.GetAll()
|
||||
}
|
||||
ep, err := parseNetworkAttachmentOpt(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := endpoints[n.Target]; ok {
|
||||
return nil, errdefs.InvalidParameter(errors.Errorf("network %q is specified multiple times", n.Target))
|
||||
}
|
||||
|
||||
// For backward compatibility: if no custom options are provided for the network,
|
||||
// and only a single network is specified, omit the endpoint-configuration
|
||||
// on the client (the daemon will still create it when creating the container)
|
||||
if i == 0 && len(copts.NetMode.Value()) == 1 {
|
||||
if ep == nil || reflect.DeepEqual(*ep, network.EndpointSettings{}) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
endpoints[n.Target] = ep
|
||||
}
|
||||
if hasUserDefined && hasNonUserDefined {
|
||||
return nil, errdefs.InvalidParameter(errors.New("conflicting options: cannot attach both user-defined and non-user-defined network-modes"))
|
||||
}
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func parseNetworkAttachmentOpt(ep opts.NetworkAttachmentOpts) (*network.EndpointSettings, error) {
|
||||
if strings.TrimSpace(ep.Target) == "" {
|
||||
return nil, errors.New("no name set for network")
|
||||
}
|
||||
if !container.NetworkMode(ep.Target).IsUserDefined() {
|
||||
if len(ep.Aliases) > 0 {
|
||||
return nil, errors.New("network-scoped aliases are only supported for user-defined networks")
|
||||
}
|
||||
if len(ep.Links) > 0 {
|
||||
return nil, errors.New("links are only supported for user-defined networks")
|
||||
}
|
||||
}
|
||||
|
||||
epConfig := &network.EndpointSettings{}
|
||||
epConfig.Aliases = append(epConfig.Aliases, ep.Aliases...)
|
||||
if len(ep.DriverOpts) > 0 {
|
||||
epConfig.DriverOpts = make(map[string]string)
|
||||
epConfig.DriverOpts = ep.DriverOpts
|
||||
}
|
||||
if len(ep.Links) > 0 {
|
||||
epConfig.Links = ep.Links
|
||||
}
|
||||
if ep.IPv4Address != "" || ep.IPv6Address != "" || len(ep.LinkLocalIPs) > 0 {
|
||||
epConfig.IPAMConfig = &network.EndpointIPAMConfig{
|
||||
IPv4Address: ep.IPv4Address,
|
||||
IPv6Address: ep.IPv6Address,
|
||||
LinkLocalIPs: ep.LinkLocalIPs,
|
||||
}
|
||||
}
|
||||
return epConfig, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user