Workaround missing docker.sock in plugin-v2
"docker.sock" is used to access Docker API which is required to: 1. subscribe to Docker events to configure-arp, 2. query Docker network info to detect whether multicast should be enabled. 3. get list of Swarm peers before starting the plugin. (1) is currently not implemented. (2) is replaced by WEAVE_MULTICAST env var which can enable multicast for all Weave networks created by the plugin (not ideal, but better than nothing). (3) is fixed by not removing "restart.sentinel".
This commit is contained in:
1 parent
bb66b6161a
commit
2ebd358aeb
5 files changed
+136
-84
No files matched your search
+47
-17
@@ -29,28 +29,39 @@ type network struct {
|
||||
|
||||
type driver struct {
|
||||
sync.RWMutex
|
||||
scope string
|
||||
docker *docker.Client
|
||||
dns bool
|
||||
isPluginV2 bool
|
||||
networks map[string]network
|
||||
isNetworkOur func(driverName string) bool
|
||||
name string
|
||||
scope string
|
||||
// Docker API is not available for plugin-v2
|
||||
docker *docker.Client
|
||||
dns bool
|
||||
isPluginV2 bool
|
||||
// Enable multicast regardless whether multicast opt is passed to Docker;
|
||||
// used only by plugin-v2
|
||||
forceMulticast bool
|
||||
networks map[string]network
|
||||
}
|
||||
|
||||
func New(client *docker.Client, weave *weaveapi.Client, scope string, dns, isPluginV2 bool, isNetworkOur func(string) bool) (skel.Driver, error) {
|
||||
func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns, isPluginV2, forceMulticast bool) (skel.Driver, error) {
|
||||
driver := &driver{
|
||||
scope: scope,
|
||||
docker: client,
|
||||
dns: dns,
|
||||
isPluginV2: isPluginV2,
|
||||
networks: make(map[string]network),
|
||||
isNetworkOur: isNetworkOur,
|
||||
name: name,
|
||||
scope: scope,
|
||||
docker: client,
|
||||
dns: dns,
|
||||
isPluginV2: isPluginV2,
|
||||
// make sure that it's used only by plugin-v2
|
||||
forceMulticast: isPluginV2 && forceMulticast,
|
||||
networks: make(map[string]network),
|
||||
}
|
||||
|
||||
_, err := NewWatcher(client, weave, driver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// Do not start watcher in the case of plugin v2, which prevents us from
|
||||
// configuring arp settings of containers.
|
||||
if client != nil {
|
||||
_, err := NewWatcher(client, weave, driver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
@@ -189,11 +200,30 @@ func (driver *driver) findNetworkInfo(id string) (network, error) {
|
||||
if found {
|
||||
return network, nil
|
||||
}
|
||||
|
||||
// plugin-v2 does not have access to docker.sock, so we cannot call Docker
|
||||
// API for the network info.
|
||||
if driver.isPluginV2 {
|
||||
// safe to set, as isOurs used only by the watcher which is disabled for plugin-v2
|
||||
network.isOurs = true
|
||||
network.hasMulticastRoute = driver.forceMulticast
|
||||
|
||||
driver.Lock()
|
||||
driver.networks[id] = network
|
||||
driver.Unlock()
|
||||
|
||||
return network, nil
|
||||
}
|
||||
|
||||
if driver.docker == nil {
|
||||
return network, fmt.Errorf("Docker client disabled; unable to get network info")
|
||||
}
|
||||
|
||||
info, err := driver.docker.NetworkInfo(id)
|
||||
if err != nil {
|
||||
return network, err
|
||||
}
|
||||
return driver.setupNetworkInfo(id, driver.isNetworkOur(info.Driver), info.Options)
|
||||
return driver.setupNetworkInfo(id, info.Driver == driver.name, info.Options)
|
||||
}
|
||||
|
||||
func (driver *driver) setupNetworkInfo(id string, isOurs bool, options map[string]string) (network, error) {
|
||||
|
||||
+10
-15
@@ -23,23 +23,23 @@ const (
|
||||
|
||||
var Log = common.Log
|
||||
|
||||
func Start(weaveAPIAddr string, dockerClient *docker.Client, address string, meshAddress string, dns bool, isPluginV2 bool) {
|
||||
func Start(weaveAPIAddr string, dockerClient *docker.Client, address string, meshAddress string, dns bool, isPluginV2, forceMulticast bool) {
|
||||
weave := weaveapi.NewClient(weaveAPIAddr, Log)
|
||||
|
||||
Log.Info("Waiting for Weave API Server...")
|
||||
weave.WaitAPIServer(30)
|
||||
Log.Info("Finished waiting for Weave API Server")
|
||||
|
||||
if err := run(dockerClient, weave, address, meshAddress, dns, isPluginV2); err != nil {
|
||||
if err := run(dockerClient, weave, address, meshAddress, dns, isPluginV2, forceMulticast); err != nil {
|
||||
Log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddress string, dns, isPluginV2 bool) error {
|
||||
func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddress string, dns, isPluginV2, forceMulticast bool) error {
|
||||
endChan := make(chan error, 1)
|
||||
|
||||
if address != "" {
|
||||
globalListener, err := listenAndServe(dockerClient, weave, address, endChan, "global", false, dns, isPluginV2)
|
||||
globalListener, err := listenAndServe(dockerClient, weave, address, endChan, "global", false, dns, isPluginV2, forceMulticast)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -47,7 +47,7 @@ func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddre
|
||||
defer globalListener.Close()
|
||||
}
|
||||
if meshAddress != "" {
|
||||
meshListener, err := listenAndServe(dockerClient, weave, meshAddress, endChan, "local", true, dns, isPluginV2)
|
||||
meshListener, err := listenAndServe(dockerClient, weave, meshAddress, endChan, "local", true, dns, isPluginV2, forceMulticast)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -58,20 +58,15 @@ func run(dockerClient *docker.Client, weave *weaveapi.Client, address, meshAddre
|
||||
return <-endChan
|
||||
}
|
||||
|
||||
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2 bool) (net.Listener, error) {
|
||||
var isNetworkOur func(string) bool
|
||||
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool) (net.Listener, error) {
|
||||
var name string
|
||||
if isPluginV2 {
|
||||
isNetworkOur = func(driverName string) bool {
|
||||
return strings.Contains(driverName, pluginV2Name)
|
||||
}
|
||||
name = pluginV2Name
|
||||
} else {
|
||||
name := strings.TrimSuffix(path.Base(address), ".sock")
|
||||
isNetworkOur = func(driverName string) bool {
|
||||
return driverName == name
|
||||
}
|
||||
name = strings.TrimSuffix(path.Base(address), ".sock")
|
||||
}
|
||||
|
||||
d, err := netplugin.New(dockerClient, weave, scope, dns, isPluginV2, isNetworkOur)
|
||||
d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -66,6 +66,14 @@
|
||||
"value"
|
||||
],
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"description": "Enable multicast for all Weave networks",
|
||||
"name": "WEAVE_MULTICAST",
|
||||
"settable": [
|
||||
"value"
|
||||
],
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"network": {
|
||||
|
||||
+36
-19
@@ -16,18 +16,36 @@ echo "Starting launch.sh"
|
||||
# Check if the IP range overlaps anything existing on the host
|
||||
/usr/bin/weaveutil netcheck $IPALLOC_RANGE weave
|
||||
|
||||
STATUS=0
|
||||
/usr/bin/weaveutil is-swarm-manager 2>/dev/null || STATUS=$?
|
||||
if [ $STATUS -eq 0 ]; then
|
||||
IS_SWARM_MANAGER=1
|
||||
elif [ $STATUS -eq 20 ]; then
|
||||
echo "Host swarm is not \"active\"; exiting." >&2
|
||||
exit 1
|
||||
fi
|
||||
# We need to get a list of Swarm nodes which might run the net-plugin:
|
||||
# - In the case of missing restart.sentinel, we assume that net-plugin has started
|
||||
# for the first time via the docker-plugin cmd. So it's safe to request docker.sock.
|
||||
# - If restart.sentinel present, let weaver restore from it as docker.sock is not
|
||||
# available to any plugin in general (https://github.com/moby/moby/issues/32815).
|
||||
|
||||
SWARM_MANAGER_PEERS=$(/usr/bin/weaveutil swarm-manager-peers)
|
||||
# Prevent from restoring from a persisted peers list
|
||||
rm -f "/restart.sentinel"
|
||||
PEERS=
|
||||
IPALLOC_INIT=
|
||||
if [ ! -f "/restart.sentinel" ]; then
|
||||
STATUS=0
|
||||
/usr/bin/weaveutil is-swarm-manager 2>/dev/null || STATUS=$?
|
||||
if [ $STATUS -eq 0 ]; then
|
||||
IS_SWARM_MANAGER=1
|
||||
elif [ $STATUS -eq 20 ]; then
|
||||
echo "Host swarm is not \"active\"; exiting." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SWARM_MANAGER_PEERS=$(/usr/bin/weaveutil swarm-manager-peers)
|
||||
|
||||
if [ -z "$IPALLOC_INIT" ]; then
|
||||
IPALLOC_INIT="observer"
|
||||
if [ "$IS_SWARM_MANAGER" == "1" ]; then
|
||||
IPALLOC_INIT="consensus=$(echo $SWARM_MANAGER_PEERS | wc -l)"
|
||||
fi
|
||||
fi
|
||||
|
||||
PEERS=$(echo $SWARM_MANAGER_PEERS | tr '\n' ' ')
|
||||
IPALLOC_INIT="--ipalloc-init $IPALLOC_INIT"
|
||||
fi
|
||||
|
||||
router_bridge_opts() {
|
||||
echo --datapath=datapath
|
||||
@@ -35,12 +53,9 @@ router_bridge_opts() {
|
||||
[ -z "$WEAVE_NO_FASTDP" ] || echo --no-fastdp
|
||||
}
|
||||
|
||||
if [ -z "$IPALLOC_INIT" ]; then
|
||||
IPALLOC_INIT="observer"
|
||||
if [ "$IS_SWARM_MANAGER" == "1" ]; then
|
||||
IPALLOC_INIT="consensus=$(echo $SWARM_MANAGER_PEERS | wc -l)"
|
||||
fi
|
||||
fi
|
||||
multicast_opt() {
|
||||
[ -z "$WEAVE_MULTICAST" ] || echo "--plugin-v2-multicast"
|
||||
}
|
||||
|
||||
exec /home/weave/weaver $EXTRA_ARGS --port=6783 $(router_bridge_opts) \
|
||||
--host-root=/host \
|
||||
@@ -48,10 +63,12 @@ exec /home/weave/weaver $EXTRA_ARGS --port=6783 $(router_bridge_opts) \
|
||||
--http-addr=$HTTP_ADDR --status-addr=$STATUS_ADDR \
|
||||
--no-dns \
|
||||
--ipalloc-range=$IPALLOC_RANGE \
|
||||
--ipalloc-init $IPALLOC_INIT \
|
||||
$IPALLOC_INIT \
|
||||
--nickname "$(hostname)" \
|
||||
--log-level=debug \
|
||||
--db-prefix="$WEAVE_DIR/weave" \
|
||||
--plugin-v2 \
|
||||
$(multicast_opt) \
|
||||
--plugin-mesh-socket='' \
|
||||
$(echo $SWARM_MANAGER_PEERS | tr '\n' ' ')
|
||||
--docker-api='' \
|
||||
$PEERS
|
||||
+35
-33
@@ -123,38 +123,39 @@ func main() {
|
||||
runtime.GOMAXPROCS(procs)
|
||||
|
||||
var (
|
||||
justVersion bool
|
||||
config mesh.Config
|
||||
bridgeConfig weavenet.BridgeConfig
|
||||
networkConfig weave.NetworkConfig
|
||||
protocolMinVersion int
|
||||
resume bool
|
||||
routerName string
|
||||
nickName string
|
||||
password string
|
||||
pktdebug bool
|
||||
logLevel string
|
||||
prof string
|
||||
bufSzMB int
|
||||
noDiscovery bool
|
||||
httpAddr string
|
||||
statusAddr string
|
||||
ipamConfig ipamConfig
|
||||
dockerAPI string
|
||||
peers []string
|
||||
noDNS bool
|
||||
dnsConfig dnsConfig
|
||||
trustedSubnetStr string
|
||||
dbPrefix string
|
||||
hostRoot string
|
||||
procPath string
|
||||
discoveryEndpoint string
|
||||
token string
|
||||
advertiseAddress string
|
||||
pluginSocket string
|
||||
pluginMeshSocket string
|
||||
enablePlugin bool
|
||||
enablePluginV2 bool
|
||||
justVersion bool
|
||||
config mesh.Config
|
||||
bridgeConfig weavenet.BridgeConfig
|
||||
networkConfig weave.NetworkConfig
|
||||
protocolMinVersion int
|
||||
resume bool
|
||||
routerName string
|
||||
nickName string
|
||||
password string
|
||||
pktdebug bool
|
||||
logLevel string
|
||||
prof string
|
||||
bufSzMB int
|
||||
noDiscovery bool
|
||||
httpAddr string
|
||||
statusAddr string
|
||||
ipamConfig ipamConfig
|
||||
dockerAPI string
|
||||
peers []string
|
||||
noDNS bool
|
||||
dnsConfig dnsConfig
|
||||
trustedSubnetStr string
|
||||
dbPrefix string
|
||||
hostRoot string
|
||||
procPath string
|
||||
discoveryEndpoint string
|
||||
token string
|
||||
advertiseAddress string
|
||||
pluginSocket string
|
||||
pluginMeshSocket string
|
||||
enablePlugin bool
|
||||
enablePluginV2 bool
|
||||
enablePluginV2Multicast bool
|
||||
|
||||
defaultDockerHost = "unix:///var/run/docker.sock"
|
||||
)
|
||||
@@ -208,6 +209,7 @@ func main() {
|
||||
|
||||
mflag.BoolVar(&enablePlugin, []string{"-plugin"}, false, "enable Docker plugin (v1)")
|
||||
mflag.BoolVar(&enablePluginV2, []string{"-plugin-v2"}, false, "enable Docker plugin (v2)")
|
||||
mflag.BoolVar(&enablePluginV2Multicast, []string{"-plugin-v2-multicast"}, false, "enable multicast for Docker plugin (v2)")
|
||||
mflag.StringVar(&pluginSocket, []string{"-plugin-socket"}, "/run/docker/plugins/weave.sock", "plugin socket on which to listen")
|
||||
mflag.StringVar(&pluginMeshSocket, []string{"-plugin-mesh-socket"}, "/run/docker/plugins/weavemesh.sock", "plugin socket on which to listen in mesh mode")
|
||||
|
||||
@@ -427,7 +429,7 @@ func main() {
|
||||
}
|
||||
|
||||
if enablePlugin || enablePluginV2 {
|
||||
go plugin.Start(httpAddr, dockerCli, pluginSocket, pluginMeshSocket, !noDNS, enablePluginV2)
|
||||
go plugin.Start(httpAddr, dockerCli, pluginSocket, pluginMeshSocket, !noDNS, enablePluginV2, enablePluginV2Multicast)
|
||||
}
|
||||
if enablePlugin {
|
||||
Log.Println("Creating default 'weave' network")
|
||||
|
||||
Reference in new issue
Block a user