Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93c1e755e6 | ||
|
|
5f4756aa80 | ||
|
|
106f1c4434 | ||
|
|
4f86a20824 | ||
|
|
49ad336a35 | ||
|
|
6feaa72abd | ||
|
|
71d6f9cdfb | ||
|
|
341d5ecbb6 | ||
|
|
2e208b4921 | ||
|
|
c983d9f39f | ||
|
|
adc5784fc9 | ||
|
|
a8c3551040 | ||
|
|
3332f94a00 | ||
|
|
cd1cca3df2 | ||
|
|
158fb36c8c | ||
|
|
5f385a297c | ||
|
|
1d6f1f7561 | ||
|
|
1769cdad7c | ||
|
|
4f73ef73bb | ||
|
|
0cb2e80e09 | ||
|
|
10a9f58d13 | ||
|
|
f919ef12d0 | ||
|
|
20c9bc04a7 | ||
|
|
10c3f47bd1 | ||
|
|
915bf392e9 | ||
|
|
af5531cbf6 | ||
|
|
32c35da402 | ||
|
|
147c7f503c | ||
|
|
c8b95a2527 | ||
|
|
169eb19523 | ||
|
|
b26e2128e4 | ||
|
|
cb73b73862 | ||
|
|
84aa629010 | ||
|
|
536d55a226 |
No files matched your search
@@ -1,3 +1,59 @@
|
||||
## Release 0.11.2
|
||||
|
||||
This is a bug fix release, addressing the following issues:
|
||||
|
||||
- `weave run` did not respect DOCKER_CLIENT_ARGS. #855
|
||||
- Negative result cache did not expire if requeried within TTL. #845
|
||||
|
||||
More details in the [change
|
||||
log](https://github.com/weaveworks/weave/issues?q=milestone%3A0.11.2).
|
||||
|
||||
*NB: This release does not change the weave protocol version.
|
||||
Therefore, when upgrading an existing 0.11 installation incrementally,
|
||||
connectivity between peers will be retained.*
|
||||
|
||||
## Release 0.11.1
|
||||
|
||||
This is a bug fix release, addressing the following issues:
|
||||
|
||||
- The IP Allocator could crash in some relatively rare
|
||||
circumstances. #782/#783.
|
||||
- When the proxy failed to attach a container to the weave network,
|
||||
there was no failure indication and descriptive error anywhere, and
|
||||
the application process would still start. Now an error is reported
|
||||
to the client (i.e. typically the Docker CLI), recorded in the proxy
|
||||
logs, and the container is terminated. #788/#799.
|
||||
- `weave launch-proxy --with-ipam` failed to configure the entrypoint
|
||||
and DNS unless a (possibly blank) `WEAVE_CIDR` was
|
||||
specified. Affected containers could start the application process
|
||||
w/o the weave network interface being available, and without
|
||||
functioning name resolution for the weaveDNS domain.
|
||||
#744/#747/#751/#752
|
||||
- The `weave status` output for the IP Allocator was misleadingly
|
||||
conveying a sense of brokenness when no IP allocation requests had
|
||||
been made yet. #787/#801
|
||||
- When invoking `weave launch-proxy` twice, the second invocation
|
||||
would output a blank line and terminate with a success exit
|
||||
status. Now it reports that the proxy is already running and exits
|
||||
with a non-zero status. #767/#780
|
||||
- `weave launch-proxy` was not respecting WEAVEPROXY_DOCKER_ARGS, so
|
||||
any user-supplied custom configuration for the weaveproxy container
|
||||
was ignored. #755/#780
|
||||
- The proxy was not intercepting API calls to the unversioned (1.0)
|
||||
Docker Remote API. Hence none of the weave functionality was
|
||||
available when Docker clients were using that version of the
|
||||
API. #770/#774/#777,#809
|
||||
- The proxy would crash when certain elements of the
|
||||
`/containers/create` JSON were missing. We are not aware of any
|
||||
Docker clients doing this, but it's been fixed regardless. #778/#777
|
||||
|
||||
More details in the [change
|
||||
log](https://github.com/weaveworks/weave/issues?q=milestone%3A0.11.1).
|
||||
|
||||
*NB: This release does not change the weave protocol version.
|
||||
Therefore, when upgrading an existing 0.11 installation incrementally,
|
||||
connectivity between peers will be retained.*
|
||||
|
||||
## Release 0.11.0
|
||||
|
||||
**Highlights**:
|
||||
|
||||
@@ -160,7 +160,7 @@ if a node receives a packet that is bigger than the next MTU, it is
|
||||
required to drop the packet and send back an ICMP 3,4 packet which
|
||||
informs the sending node of the next hop MTU (RFC 1191). In theory,
|
||||
these ICMP packets should have all the reverse NAT and so forth
|
||||
applied, to make it all the way back to the sender. In practise this
|
||||
applied, to make it all the way back to the sender. In practice, this
|
||||
does often work, but in some cases all ICMP are sometimes blocked,
|
||||
often by idiots who don't understand that ICMP is really the error
|
||||
channel of all network traffic.
|
||||
@@ -187,16 +187,16 @@ If weave determines that fragmentation is reliable then when weave
|
||||
sniffs large packets (i.e. packets larger than the MTU and thus don't
|
||||
have DF set) then weave will encapsulate these packets as necessary
|
||||
and similarly send them out as-is, without DF set, trusting to the
|
||||
network to do all necessary fragementation and reassembly.
|
||||
network to do all necessary fragmentation and reassembly.
|
||||
|
||||
However, if weave determines that fragementation is not reliable
|
||||
However, if weave determines that fragmentation is not reliable
|
||||
between any two peers then it will manually fragment larger packets
|
||||
correctly according to the IP spec, and will then send them between
|
||||
weave peers with the DF flag set (i.e. the fragmentation will ensure
|
||||
that the encapsulatated traffic will not be greater than the PMTU
|
||||
that the encapsulated traffic will not be greater than the PMTU
|
||||
between weave peers). Because the fragmentation is done according to
|
||||
the IP spec, we don't need to do reassembly ourselves - on the
|
||||
receiving weave, we jus inject all the fragments and rely on the
|
||||
receiving weave, we just inject all the fragments and rely on the
|
||||
stack to do reassembly.
|
||||
|
||||
Sometimes PMTU discovery doesn't work as ICMP packets sometimes get
|
||||
|
||||
@@ -52,3 +52,10 @@ func Subtract(a, b Address) Offset {
|
||||
common.Assert(a >= b)
|
||||
return Offset(a - b)
|
||||
}
|
||||
|
||||
func Min(a, b Offset) Offset {
|
||||
if a > b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
+12
-10
@@ -456,10 +456,12 @@ func (alloc *Allocator) actorLoop(actionChan <-chan func()) {
|
||||
|
||||
func (alloc *Allocator) string() string {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "Allocator subnet %s/%d\n", alloc.subnetStart.String(), alloc.prefixLen)
|
||||
fmt.Fprintf(&buf, "Allocator subnet %s/%d", alloc.subnetStart.String(), alloc.prefixLen)
|
||||
|
||||
if alloc.ring.Empty() {
|
||||
fmt.Fprintf(&buf, "Awaiting consensus: %s", alloc.paxos.String())
|
||||
if alloc.paxosTicker != nil {
|
||||
fmt.Fprintf(&buf, " awaiting consensus: %s", alloc.paxos.String())
|
||||
}
|
||||
} else {
|
||||
localFreeSpace := alloc.space.NumFreeAddresses()
|
||||
remoteFreeSpace := alloc.ring.TotalRemoteFree()
|
||||
@@ -469,14 +471,14 @@ func (alloc *Allocator) string() string {
|
||||
|
||||
fmt.Fprint(&buf, "Owned Ranges:")
|
||||
alloc.ring.FprintWithNicknames(&buf, alloc.nicknames)
|
||||
if len(alloc.pendingAllocates)+len(alloc.pendingClaims) > 0 {
|
||||
fmt.Fprintf(&buf, "\nPending requests for ")
|
||||
for _, op := range alloc.pendingAllocates {
|
||||
fmt.Fprintf(&buf, "%s, ", op.String())
|
||||
}
|
||||
for _, op := range alloc.pendingClaims {
|
||||
fmt.Fprintf(&buf, "%s, ", op.String())
|
||||
}
|
||||
}
|
||||
if len(alloc.pendingAllocates)+len(alloc.pendingClaims) > 0 {
|
||||
fmt.Fprintf(&buf, "\nPending requests:")
|
||||
for _, op := range alloc.pendingAllocates {
|
||||
fmt.Fprintf(&buf, "\n %s", op.String())
|
||||
}
|
||||
for _, op := range alloc.pendingClaims {
|
||||
fmt.Fprintf(&buf, "\n %s", op.String())
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
|
||||
+2
-3
@@ -40,7 +40,6 @@ var (
|
||||
ErrInvalidEntry = errors.New("Received invalid state update!")
|
||||
ErrEntryInMyRange = errors.New("Received new entry in my range!")
|
||||
ErrNoFreeSpace = errors.New("No free space found!")
|
||||
ErrTooMuchFreeSpace = errors.New("Entry reporting too much free space!")
|
||||
ErrInvalidTimeout = errors.New("dt must be greater than 0")
|
||||
ErrNotFound = errors.New("No entries for peer found")
|
||||
)
|
||||
@@ -76,7 +75,7 @@ func (r *Ring) checkInvariants() error {
|
||||
distance := r.distance(entry.Token, next.Token)
|
||||
|
||||
if entry.Free > distance {
|
||||
return ErrTooMuchFreeSpace
|
||||
return fmt.Errorf("Entry %s-%s reporting too much free space: %d > %d", entry.Token, next.Token, entry.Free, distance)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +166,7 @@ func (r *Ring) GrantRangeToHost(start, end address.Address, peer router.PeerName
|
||||
pos := preceedingPos + 1
|
||||
for ; pos < len(r.Entries) && r.Entries.entry(pos).Token < end; pos++ {
|
||||
entry := r.Entries.entry(pos)
|
||||
entry.update(peer, entry.Free)
|
||||
entry.update(peer, address.Min(entry.Free, r.distance(entry.Token, end)))
|
||||
}
|
||||
|
||||
// There is never an entry with a token of r.End, as the end of
|
||||
|
||||
@@ -158,6 +158,17 @@ func TestGrantSplit(t *testing.T) {
|
||||
wt.AssertEquals(t, ring1.Entries, entries{{Token: start, Peer: peer1name, Free: 10, Version: 1},
|
||||
{Token: dot10, Peer: peer2name, Free: 235},
|
||||
{Token: dot245, Peer: peer1name, Free: 10}})
|
||||
ring1.assertInvariants()
|
||||
|
||||
// Grant range spanning a live token, and inserting a new token
|
||||
ring1.Entries = []*entry{{Token: start, Peer: peer1name, Free: 10, Version: 2},
|
||||
{Token: dot10, Peer: peer1name, Free: 118}, {Token: middle, Peer: peer1name, Free: 127}}
|
||||
ring1.GrantRangeToHost(dot10, dot245, peer2name)
|
||||
wt.AssertEquals(t, ring1.Entries, entries{{Token: start, Peer: peer1name, Free: 10, Version: 2},
|
||||
{Token: dot10, Peer: peer2name, Free: 118, Version: 1},
|
||||
{Token: middle, Peer: peer2name, Free: 117, Version: 1},
|
||||
{Token: dot245, Peer: peer1name, Free: 10, Version: 0}})
|
||||
ring1.assertInvariants()
|
||||
}
|
||||
|
||||
func TestMergeSimple(t *testing.T) {
|
||||
|
||||
+16
-6
@@ -5,13 +5,14 @@ import (
|
||||
"container/heap"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/benbjohnson/clock"
|
||||
"github.com/miekg/dns"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/benbjohnson/clock"
|
||||
"github.com/miekg/dns"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -145,9 +146,12 @@ func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Tim
|
||||
prevValidUntil = e.validUntil
|
||||
}
|
||||
|
||||
e.Status = stResolved
|
||||
e.Flags = flags
|
||||
e.putTime = now
|
||||
// make sure we do not overwrite noLocalReplies entries
|
||||
if flags&CacheNoLocalReplies != 0 {
|
||||
if e.Flags&CacheNoLocalReplies != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if ttl != nullTTL {
|
||||
e.validUntil = now.Add(time.Second * time.Duration(ttl))
|
||||
@@ -161,8 +165,14 @@ func (e *cacheEntry) setReply(reply *dns.Msg, ttl int, flags uint8, now time.Tim
|
||||
}
|
||||
}
|
||||
e.validUntil = now.Add(time.Second * time.Duration(minTTL))
|
||||
} else {
|
||||
Warning.Printf("[cache] no valid TTL could be calculated")
|
||||
}
|
||||
|
||||
e.Status = stResolved
|
||||
e.Flags = flags
|
||||
e.putTime = now
|
||||
|
||||
if reply != nil {
|
||||
e.reply = *reply
|
||||
e.ReplyLen = reply.Len()
|
||||
|
||||
@@ -2,13 +2,14 @@ package nameserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/benbjohnson/clock"
|
||||
"github.com/miekg/dns"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
wt "github.com/weaveworks/weave/testing"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Check that the cache keeps its intended capacity constant
|
||||
@@ -195,12 +196,23 @@ func TestCacheEntries(t *testing.T) {
|
||||
question3 := &questionMsg3.Question[0]
|
||||
|
||||
t.Logf("Checking that a entry with CacheNoLocalReplies return an error")
|
||||
l.Put(questionMsg3, nil, nullTTL, CacheNoLocalReplies)
|
||||
l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies)
|
||||
resp, err = l.Get(questionMsg3, minUDPSize)
|
||||
wt.AssertNil(t, resp, "Get() response with CacheNoLocalReplies")
|
||||
wt.AssertNotNil(t, err, "Get() error with CacheNoLocalReplies")
|
||||
wt.AssertTrue(t, err == errNoLocalReplies, "Get() error with CacheNoLocalReplies")
|
||||
|
||||
clk.Add(time.Second * time.Duration(negLocalTTL+1))
|
||||
t.Logf("Checking that more Put's do not make the negative TTL longer")
|
||||
clk.Add(time.Duration(negLocalTTL/2) * time.Second)
|
||||
l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies)
|
||||
clk.Add(time.Duration(1) * time.Second)
|
||||
l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies)
|
||||
clk.Add(time.Duration(1) * time.Second)
|
||||
l.Put(questionMsg3, nil, negLocalTTL, CacheNoLocalReplies)
|
||||
resp, err = l.Get(questionMsg3, minUDPSize)
|
||||
wt.AssertNil(t, resp, "Get() response with CacheNoLocalReplies")
|
||||
wt.AssertTrue(t, err == errNoLocalReplies, "Get() error with CacheNoLocalReplies")
|
||||
|
||||
clk.Add(time.Duration(negLocalTTL/2) * time.Second)
|
||||
t.Logf("Checking that we get an expired response after %f seconds", negLocalTTL)
|
||||
resp, err = l.Get(questionMsg3, minUDPSize)
|
||||
wt.AssertNil(t, resp, "expired Get() response with CacheNoLocalReplies")
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ func (c *client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case err == docker.ErrNoSuchImage:
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
default:
|
||||
http.Error(w, "Unable to intercept request", http.StatusInternalServerError)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
Warning.Print("Error intercepting request: ", err)
|
||||
}
|
||||
return
|
||||
@@ -58,7 +58,7 @@ func (c *client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
err = c.InterceptResponse(resp)
|
||||
if err != nil {
|
||||
http.Error(w, "Unable to intercept response", http.StatusInternalServerError)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
Warning.Print("Error intercepting response: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
containerIDRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/([^/]*)/.*")
|
||||
containerIDRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/([^/]*)/.*")
|
||||
weaveWaitEntrypoint = []string{"/home/weavewait/weavewait"}
|
||||
)
|
||||
|
||||
@@ -54,7 +54,7 @@ func inspectContainerInPath(client *docker.Client, path string) (*docker.Contain
|
||||
Warning.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
containerID := subs[1]
|
||||
containerID := subs[2]
|
||||
|
||||
container, err := client.InspectContainer(containerID)
|
||||
if err != nil {
|
||||
|
||||
@@ -15,6 +15,7 @@ type createContainerInterceptor struct {
|
||||
client *docker.Client
|
||||
withDNS bool
|
||||
dockerBridgeIP string
|
||||
withIPAM bool
|
||||
}
|
||||
|
||||
type createContainerRequestBody struct {
|
||||
@@ -35,9 +36,15 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok {
|
||||
if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok || i.withIPAM {
|
||||
Info.Printf("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " "))
|
||||
if container.HostConfig == nil {
|
||||
container.HostConfig = &docker.HostConfig{}
|
||||
}
|
||||
container.HostConfig.VolumesFrom = append(container.HostConfig.VolumesFrom, "weaveproxy")
|
||||
if container.Config == nil {
|
||||
container.Config = &docker.Config{}
|
||||
}
|
||||
if err := i.setWeaveWaitEntrypoint(container.Config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ import (
|
||||
)
|
||||
|
||||
type createExecInterceptor struct {
|
||||
client *docker.Client
|
||||
client *docker.Client
|
||||
withIPAM bool
|
||||
}
|
||||
|
||||
type createExecRequestBody struct {
|
||||
@@ -37,7 +38,7 @@ func (i *createExecInterceptor) InterceptRequest(r *http.Request) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok {
|
||||
if cidrs, ok := weaveCIDRsFromConfig(container.Config); ok || i.withIPAM {
|
||||
Info.Printf("Exec in container %s with WEAVE_CIDR \"%s\"", container.ID, strings.Join(cidrs, " "))
|
||||
options.Cmd = append(weaveWaitEntrypoint, options.Cmd...)
|
||||
}
|
||||
|
||||
+5
-5
@@ -12,9 +12,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
containerCreateRegexp = regexp.MustCompile("/v[0-9\\.]*/containers/create")
|
||||
containerStartRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/(re)?start$")
|
||||
execCreateRegexp = regexp.MustCompile("^/v[0-9\\.]*/containers/[^/]*/exec$")
|
||||
containerCreateRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/create$")
|
||||
containerStartRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/[^/]*/(re)?start$")
|
||||
execCreateRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/[^/]*/exec$")
|
||||
)
|
||||
|
||||
type Proxy struct {
|
||||
@@ -68,11 +68,11 @@ func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
switch {
|
||||
case containerCreateRegexp.MatchString(path):
|
||||
proxy.serveWithInterceptor(&createContainerInterceptor{proxy.client, proxy.withDNS, proxy.dockerBridgeIP}, w, r)
|
||||
proxy.serveWithInterceptor(&createContainerInterceptor{proxy.client, proxy.withDNS, proxy.dockerBridgeIP, proxy.withIPAM}, w, r)
|
||||
case containerStartRegexp.MatchString(path):
|
||||
proxy.serveWithInterceptor(&startContainerInterceptor{proxy.client, proxy.withDNS, proxy.withIPAM}, w, r)
|
||||
case execCreateRegexp.MatchString(path):
|
||||
proxy.serveWithInterceptor(&createExecInterceptor{proxy.client}, w, r)
|
||||
proxy.serveWithInterceptor(&createExecInterceptor{proxy.client, proxy.withIPAM}, w, r)
|
||||
case strings.HasPrefix(path, "/weave"):
|
||||
w.WriteHeader(http.StatusOK)
|
||||
default:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -33,8 +34,10 @@ func (i *startContainerInterceptor) InterceptResponse(r *http.Response) error {
|
||||
args := []string{"attach"}
|
||||
args = append(args, cidrs...)
|
||||
args = append(args, container.ID)
|
||||
if _, err := callWeave(args...); err != nil {
|
||||
Warning.Printf("Attaching container %s to weave network failed: %v", container.ID, err)
|
||||
if output, err := callWeave(args...); err != nil {
|
||||
i.client.KillContainer(docker.KillContainerOptions{ID: container.ID})
|
||||
Warning.Printf("Attaching container %s to weave network failed: %s", container.ID, string(output))
|
||||
return errors.New(string(output))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+1
-1
@@ -170,7 +170,7 @@ $ vagrant ssh -c 'make -C src/github.com/weaveworks/weave'
|
||||
```
|
||||
|
||||
you should then find container snapshot tarballs in the top-level
|
||||
directory. You can use these snapshots with `docker load` agains a
|
||||
directory. You can use these snapshots with `docker load` against a
|
||||
different host, e.g.
|
||||
|
||||
```bash
|
||||
|
||||
+2
-12
@@ -103,18 +103,8 @@ host3 has caught fire, we can go to one of the other hosts and run:
|
||||
Weave will take all the IP address ranges owned by host3 and transfer
|
||||
them to be owned by host1. The name "host3" is resolved via the
|
||||
'nickname' feature of weave, which defaults to the local host
|
||||
name. You can see the full set of range assignments in the output from
|
||||
`weave status`, which will show the internal hex ID and nickname in
|
||||
brackets, like this:
|
||||
|
||||
Ring [10.2.1.1, 10.2.1.255)
|
||||
10.2.1.1 -> 96:e9:e2:2e:2d:bc (host1) (version: 3, free: 126)
|
||||
10.2.1.128 -> ea:84:25:9b:31:2e (host2) (version: 2, free: 64)
|
||||
10.2.1.192 -> ea:6c:21:09:cf:f0 (host3) (version: 1, free: 62)
|
||||
|
||||
So, in our example, we could equivalently do:
|
||||
|
||||
host1$ weave rmpeer ea:6c:21:09:cf:f0
|
||||
name. Alternatively, one can supply a peer name as shown in `weave
|
||||
status`.
|
||||
|
||||
## <a name="troubleshooting"></a>Troubleshooting
|
||||
|
||||
|
||||
+26
-18
@@ -52,24 +52,9 @@ or, equivalently with
|
||||
5ef831df61d50a1a49272357155a976595e7268e590f0a2c75693337b14e1382
|
||||
host1$ docker start 5ef831df61d50a1a49272357155a976595e7268e590f0a2c75693337b14e1382
|
||||
|
||||
Multiple IP addresses and networks can be supplied in the WEAVE_CIDR
|
||||
Multiple IP addresses and networks can be supplied in the `WEAVE_CIDR`
|
||||
variable by space-separating them, as in
|
||||
`WEAVE_CIDR=10.2.1.1/24 10.2.2.1/24`.
|
||||
|
||||
## Usage with WeaveDNS
|
||||
|
||||
Containers started via the proxy can be automatically configured to
|
||||
use WeaveDNS for name resolution. To accomplish this we need to launch
|
||||
the proxy with the `--with-dns` option
|
||||
|
||||
host1$ weave launch
|
||||
host1$ weave launch-dns 10.2.254.1/24
|
||||
host1$ weave launch-proxy --with-dns
|
||||
|
||||
With this done, any containers launched through the proxy will use
|
||||
weaveDNS for name resolution. WeaveDNS is used in addition to any dns
|
||||
servers specified via the `--dns` option. More details on weaveDNS can
|
||||
be found in the [weaveDNS documentation](weavedns.html).
|
||||
`WEAVE_CIDR="10.2.1.1/24 10.2.2.1/24"`.
|
||||
|
||||
## Usage with IPAM
|
||||
|
||||
@@ -91,8 +76,31 @@ without a `WEAVE_CIDR`, we can launch the proxy with the `--with-ipam`
|
||||
option. For example:
|
||||
|
||||
host1$ weave launch-proxy --with-ipam
|
||||
host1$ export DOCKER_HOST=tcp://host1:12375
|
||||
|
||||
More details on IPAM can be found in the [IPAM documentation](ipam.html).
|
||||
Now, containers will always be automatically assigned an IP address
|
||||
and attached to the weave network when we start them. For example:
|
||||
|
||||
host1$ docker run -ti ubuntu /bin/sh
|
||||
|
||||
More details on IPAM can be found in the [IPAM
|
||||
documentation](ipam.html).
|
||||
|
||||
## Usage with WeaveDNS
|
||||
|
||||
Containers started via the proxy can be automatically configured to
|
||||
use WeaveDNS for name resolution. To accomplish this we need to launch
|
||||
the proxy with the `--with-dns` option
|
||||
|
||||
host1$ weave launch
|
||||
host1$ weave launch-dns 10.2.254.1/24
|
||||
host1$ weave launch-proxy --with-dns
|
||||
|
||||
With this done, any containers connected via IPAM or `WEAVE_CIDR=...`,
|
||||
which are launched through the proxy will use weaveDNS for name
|
||||
resolution. WeaveDNS is used in addition to any dns servers specified
|
||||
via the `--dns` option. More details on weaveDNS can be found in the
|
||||
[weaveDNS documentation](weavedns.html).
|
||||
|
||||
## Limitations
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ not currently connected to. Each line contains some information about
|
||||
what went wrong the last time; whether it is attempting to connect or
|
||||
is waiting for a while before connecting again.
|
||||
|
||||
There may also be further sections for
|
||||
There may also be further sections for
|
||||
[IP allocator](ipam.html#troubleshooting) and
|
||||
[weaveDNS](weavedns.html#troubleshooting).
|
||||
|
||||
|
||||
+20
-5
@@ -39,7 +39,7 @@ $ weave run 10.2.1.25/24 -ti -h pingme.weave.local ubuntu
|
||||
$ shell1=$(weave run --with-dns 10.2.1.26/24 -ti -h ubuntu.weave.local ubuntu)
|
||||
$ docker attach $shell1
|
||||
|
||||
# ping pingme
|
||||
root@ubuntu:/# ping pingme
|
||||
...
|
||||
```
|
||||
|
||||
@@ -52,9 +52,24 @@ not attempt to do load-balancing.
|
||||
Each weaveDNS container started with `launch-dns` needs to be given
|
||||
its own, unique, IP address, in a subnet that is a) common to all
|
||||
weaveDNS containers, b) disjoint from the application subnets, and c)
|
||||
not in use on any of the hosts. In our example the weaveDNS address is
|
||||
in subnet 10.2.254.0/24 and the application containers are in
|
||||
subnet 10.2.1.0/24.
|
||||
not in use on any of the hosts.
|
||||
|
||||
In our example the weaveDNS address is in subnet 10.2.254.0/24 and the
|
||||
application containers are in subnet 10.2.1.0/24. So, to launch and
|
||||
use weaveDNS on a second host we would run:
|
||||
|
||||
```bash
|
||||
host2$ weave launch $HOST1
|
||||
host2$ weave launch-dns 10.2.254.2/24
|
||||
host2$ shell2=$(weave run --with-dns 10.2.1.36/24 -ti -h ubuntu2.weave.local ubuntu)
|
||||
host2$ docker attach $shell2
|
||||
|
||||
root@ubuntu2:/# ping pingme
|
||||
...
|
||||
```
|
||||
|
||||
Notice the different IP address in the 10.2.254.0/24 subnet we gave to
|
||||
`weave launch-dns`, compared to what we supplied on the first host.
|
||||
|
||||
WeaveDNS containers can be stopped with `stop-dns`.
|
||||
|
||||
@@ -163,7 +178,7 @@ $ weave launch-dns 10.2.254.1/24 --domain="mycompany.local."
|
||||
|
||||
The local domain should end with `local.`, since these names are
|
||||
link-local as per [RFC6762](https://tools.ietf.org/html/rfc6762),
|
||||
(though this is not strictly neccessary).
|
||||
(though this is not strictly necessary).
|
||||
|
||||
## <a name="without-run"></a>Using weaveDNS without `weave run`
|
||||
|
||||
|
||||
@@ -26,4 +26,28 @@ run_container "grep ^1$ /sys/class/net/ethwe/carrier"
|
||||
build_image false '["/bin/false"]' ''
|
||||
run_container "--entrypoint='grep' false ^1$ /sys/class/net/ethwe/carrier"
|
||||
|
||||
weave_on $HOST1 launch -iprange 10.2.2.0/24
|
||||
docker_on $HOST1 kill weaveproxy
|
||||
weave_on $HOST1 launch-proxy --with-ipam
|
||||
|
||||
assert_raises "proxy docker_on $HOST1 run check-ethwe-up"
|
||||
|
||||
create_container_json=$(cat <<-EOF
|
||||
{
|
||||
"Hostname":"c1",
|
||||
"AttachStdin":false,
|
||||
"AttachStdout":true,
|
||||
"AttachStderr":true,
|
||||
"Tty":false,
|
||||
"OpenStdin":false,
|
||||
"StdinOnce":false,
|
||||
"Image":"check-ethwe-up"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Test a minimal request to the unversioned (v1.0) docker api
|
||||
CONTAINER_ID=$(curl -s -X POST --header "Content-Type: application/json" http://$HOST1:12375/containers/create -d "$create_container_json" | sed -e 's/.*"Id":"\([^"]*\)".*/\1/')
|
||||
assert_raises "proxy docker_on $HOST1 start -ai $CONTAINER_ID"
|
||||
|
||||
end_suite
|
||||
@@ -61,6 +61,7 @@ exec_remote() {
|
||||
-e WEAVE_DEBUG \
|
||||
-e WEAVE_DOCKER_ARGS \
|
||||
-e WEAVEDNS_DOCKER_ARGS \
|
||||
-e WEAVEPROXY_DOCKER_ARGS \
|
||||
-e WEAVE_PASSWORD \
|
||||
-e WEAVE_PORT \
|
||||
-e WEAVE_CONTAINER_NAME \
|
||||
@@ -141,7 +142,7 @@ if [ "$1" = "run" ]; then
|
||||
fi
|
||||
collect_cidr_args "$@"
|
||||
shift $CIDR_COUNT
|
||||
CONTAINER=$(docker run $DNS_ARGS -d "$@")
|
||||
CONTAINER=$(docker $DOCKER_CLIENT_ARGS run $DNS_ARGS -d "$@")
|
||||
exec_remote attach $CIDR_ARGS $CONTAINER
|
||||
echo $CONTAINER
|
||||
exit 0
|
||||
@@ -167,6 +168,13 @@ MTU=65535
|
||||
PORT=${WEAVE_PORT:-6783}
|
||||
HTTP_PORT=6784
|
||||
DNS_HTTP_PORT=6785
|
||||
PROXY_PORT=12375
|
||||
PROXY_CONTAINER_NAME=weaveproxy
|
||||
PROXY_HOST="localhost"
|
||||
if [ "$DOCKER_HOST" != "${DOCKER_HOST#tcp://}" ] ; then
|
||||
PROXY_HOST=$(echo "$DOCKER_HOST" | sed -e "s|tcp://\([^:]*\):[0-9]*|\1|")
|
||||
fi
|
||||
|
||||
|
||||
######################################################################
|
||||
# general helpers; independent of docker and weave
|
||||
@@ -540,6 +548,18 @@ wait_for_status() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Just like wait_for_status, but takes the IP instead of a container ID
|
||||
wait_for_status_ip() {
|
||||
WAIT_TIME=0
|
||||
while [ $WAIT_TIME -lt 3 ]; do
|
||||
sleep $WAIT_TIME
|
||||
http_call_ip $1 $2 GET ${3:-/status} >/dev/null && return 0
|
||||
WAIT_TIME=$((WAIT_TIME+1))
|
||||
done
|
||||
echo "Timed out waiting for container to start." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# Call $1 for all containers, passing container ID, all MACs and all IPs
|
||||
with_container_addresses() {
|
||||
COMMAND=$1
|
||||
@@ -688,63 +708,6 @@ get_ipam_cidr() {
|
||||
fi
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# weave proxy helpers
|
||||
######################################################################
|
||||
|
||||
PROXY_PORT=12375
|
||||
PROXY_CONTAINER_NAME=weaveproxy
|
||||
|
||||
proxy_host() {
|
||||
case $DOCKER_HOST in
|
||||
tcp://*)
|
||||
PROXY_HOST=$(echo $DOCKER_HOST | sed -e "s|tcp://\([^:]*\):[0-9]*|\1|")
|
||||
;;
|
||||
*)
|
||||
PROXY_HOST="localhost"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
wait_for_proxy_to_boot() {
|
||||
proxy_host
|
||||
for n in $(seq 1 10); do
|
||||
if curl --max-time 1 --connect-timeout 1 -s -X GET http://$PROXY_HOST:$PROXY_PORT/weave ; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "Proxy did not start within 10 seconds" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
ensure_proxy_running() {
|
||||
case $(docker inspect --format '{{.State.Running}} {{.Config.Image}}' $PROXY_CONTAINER_NAME 2>/dev/null) in
|
||||
"true $EXEC_IMAGE")
|
||||
return 0
|
||||
;;
|
||||
true*)
|
||||
echo "Proxy already running with unknown image" >&2
|
||||
exit 1
|
||||
;;
|
||||
false*)
|
||||
docker rm -f $PROXY_CONTAINER_NAME >/dev/null
|
||||
;;
|
||||
esac
|
||||
# Set WEAVEPROXY_DOCKER_ARGS in the environment in order to supply
|
||||
# additional parameters, such as resource limits, to docker
|
||||
# when launching the weave proxy container.
|
||||
PROXY_CONTAINER=$(docker run --privileged --net=host -d \
|
||||
--name=$PROXY_CONTAINER_NAME \
|
||||
-p $PROXY_PORT:$PROXY_PORT/tcp -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /proc:/hostproc -e PROCFS=/hostproc \
|
||||
--entrypoint=/home/weave/weaveproxy \
|
||||
$WEAVE_DOCKER_ARGS $WEAVEPROXY_DOCKER_ARGS \
|
||||
$EXEC_IMAGE "$@")
|
||||
|
||||
wait_for_proxy_to_boot
|
||||
}
|
||||
|
||||
##########################################################################################
|
||||
|
||||
[ $(id -u) = 0 ] || {
|
||||
@@ -874,7 +837,20 @@ case "$COMMAND" in
|
||||
echo $DNS_CONTAINER
|
||||
;;
|
||||
launch-proxy)
|
||||
ensure_proxy_running "$@"
|
||||
check_not_running $PROXY_CONTAINER_NAME $EXEC_IMAGE
|
||||
# Set WEAVEPROXY_DOCKER_ARGS in the environment in order to supply
|
||||
# additional parameters, such as resource limits, to docker
|
||||
# when launching the weaveproxy container.
|
||||
PROXY_CONTAINER=$(docker run --privileged --net=host -d \
|
||||
--name=$PROXY_CONTAINER_NAME \
|
||||
-p $PROXY_PORT:$PROXY_PORT/tcp \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /proc:/hostproc -e PROCFS=/hostproc \
|
||||
--entrypoint=/home/weave/weaveproxy \
|
||||
$WEAVEPROXY_DOCKER_ARGS \
|
||||
$EXEC_IMAGE "$@")
|
||||
|
||||
wait_for_status_ip $PROXY_HOST $PROXY_PORT /weave
|
||||
echo $PROXY_CONTAINER
|
||||
;;
|
||||
connect)
|
||||
|
||||
+8
-8
@@ -10,22 +10,22 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
if _, err := net.EnsureInterface("ethwe", 20); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
_, err := net.EnsureInterface("ethwe", 20)
|
||||
checkErr(err)
|
||||
|
||||
if len(os.Args) <= 1 {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
binary, err := exec.LookPath(os.Args[1])
|
||||
checkErr(err)
|
||||
|
||||
checkErr(syscall.Exec(binary, os.Args[1:], os.Environ()))
|
||||
}
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := syscall.Exec(binary, os.Args[1:], os.Environ()); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user