mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-14 06:15:45 +00:00
Initial ipv6 / iptables work
This commit is contained in:
parent
808be2d13b
commit
9a053a4b59
@ -100,8 +100,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocol := iptables.ProtocolIpv4
|
||||||
|
if net.IP(bindAddress).To4() == nil {
|
||||||
|
protocol = iptables.ProtocolIpv6
|
||||||
|
}
|
||||||
loadBalancer := proxy.NewLoadBalancerRR()
|
loadBalancer := proxy.NewLoadBalancerRR()
|
||||||
proxier := proxy.NewProxier(loadBalancer, net.IP(bindAddress), iptables.New(exec.New()))
|
proxier := proxy.NewProxier(loadBalancer, net.IP(bindAddress), iptables.New(exec.New(), protocol))
|
||||||
// Wire proxier to handle changes to services
|
// Wire proxier to handle changes to services
|
||||||
serviceConfig.RegisterHandler(proxier)
|
serviceConfig.RegisterHandler(proxier)
|
||||||
// And wire loadBalancer to handle changes to endpoints to services
|
// And wire loadBalancer to handle changes to endpoints to services
|
||||||
|
@ -529,8 +529,11 @@ func iptablesFlush(ipt iptables.Interface) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used below.
|
// Used below.
|
||||||
var zeroIP = net.ParseIP("0.0.0.0")
|
var zeroIPv4 = net.ParseIP("0.0.0.0")
|
||||||
var localhostIP = net.ParseIP("127.0.0.1")
|
var localhostIPv4 = net.ParseIP("127.0.0.1")
|
||||||
|
|
||||||
|
var zeroIPv6 = net.ParseIP("::0")
|
||||||
|
var localhostIPv6 = net.ParseIP("::1")
|
||||||
|
|
||||||
// Build a slice of iptables args for a portal rule.
|
// Build a slice of iptables args for a portal rule.
|
||||||
func iptablesPortalArgs(destIP net.IP, destPort int, proxyIP net.IP, proxyPort int, service string) []string {
|
func iptablesPortalArgs(destIP net.IP, destPort int, proxyIP net.IP, proxyPort int, service string) []string {
|
||||||
@ -558,10 +561,13 @@ func iptablesPortalArgs(destIP net.IP, destPort int, proxyIP net.IP, proxyPort i
|
|||||||
// Unfortunately, I don't know of any way to listen on some (N > 1)
|
// Unfortunately, I don't know of any way to listen on some (N > 1)
|
||||||
// interfaces but not ALL interfaces, short of doing it manually, and
|
// interfaces but not ALL interfaces, short of doing it manually, and
|
||||||
// this is simpler than that.
|
// this is simpler than that.
|
||||||
if proxyIP.Equal(zeroIP) || proxyIP.Equal(localhostIP) {
|
if proxyIP.Equal(zeroIPv4) || proxyIP.Equal(zeroIPv6) ||
|
||||||
|
proxyIP.Equal(localhostIPv4) || proxyIP.Equal(localhostIPv6) {
|
||||||
|
// TODO: Can we REDIRECT with IPv6?
|
||||||
args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort))
|
args = append(args, "-j", "REDIRECT", "--to-ports", fmt.Sprintf("%d", proxyPort))
|
||||||
} else {
|
} else {
|
||||||
args = append(args, "-j", "DNAT", "--to-destination", fmt.Sprintf("%s:%d", proxyIP.String(), proxyPort))
|
// TODO: Can we DNAT with IPv6?
|
||||||
|
args = append(args, "-j", "DNAT", "--to-destination", net.JoinHostPort(proxyIP.String(), strconv.Itoa(proxyPort)))
|
||||||
}
|
}
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,10 @@ func (fake *fakeIptables) DeleteRule(table iptables.Table, chain iptables.Chain,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fake *fakeIptables) IsIpv6() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var tcpServerPort string
|
var tcpServerPort string
|
||||||
var udpServerPort string
|
var udpServerPort string
|
||||||
|
|
||||||
|
@ -34,8 +34,17 @@ type Interface interface {
|
|||||||
EnsureRule(table Table, chain Chain, args ...string) (bool, error)
|
EnsureRule(table Table, chain Chain, args ...string) (bool, error)
|
||||||
// DeleteRule checks if the specified rule is present and, if so, deletes it.
|
// DeleteRule checks if the specified rule is present and, if so, deletes it.
|
||||||
DeleteRule(table Table, chain Chain, args ...string) error
|
DeleteRule(table Table, chain Chain, args ...string) error
|
||||||
|
// IsIpv6 returns true if this is managing ipv6 tables
|
||||||
|
IsIpv6() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Protocol bool
|
||||||
|
|
||||||
|
const (
|
||||||
|
ProtocolIpv4 Protocol = false
|
||||||
|
ProtocolIpv6 Protocol = true
|
||||||
|
)
|
||||||
|
|
||||||
type Table string
|
type Table string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -51,13 +60,14 @@ const (
|
|||||||
|
|
||||||
// runner implements Interface in terms of exec("iptables").
|
// runner implements Interface in terms of exec("iptables").
|
||||||
type runner struct {
|
type runner struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
exec utilexec.Interface
|
exec utilexec.Interface
|
||||||
|
protocol Protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Interface which will exec iptables.
|
// New returns a new Interface which will exec iptables.
|
||||||
func New(exec utilexec.Interface) Interface {
|
func New(exec utilexec.Interface, protocol Protocol) Interface {
|
||||||
return &runner{exec: exec}
|
return &runner{exec: exec, protocol: protocol}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureChain is part of Interface.
|
// EnsureChain is part of Interface.
|
||||||
@ -135,8 +145,20 @@ func (runner *runner) DeleteRule(table Table, chain Chain, args ...string) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (runner *runner) IsIpv6() bool {
|
||||||
|
return runner.protocol == ProtocolIpv6
|
||||||
|
}
|
||||||
|
|
||||||
|
func (runner *runner) iptablesCommand() string {
|
||||||
|
if runner.IsIpv6() {
|
||||||
|
return "ip6tables"
|
||||||
|
} else {
|
||||||
|
return "iptables"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (runner *runner) run(op operation, args []string) ([]byte, error) {
|
func (runner *runner) run(op operation, args []string) ([]byte, error) {
|
||||||
const iptablesCmd = "iptables"
|
iptablesCmd := runner.iptablesCommand()
|
||||||
|
|
||||||
fullArgs := append([]string{string(op)}, args...)
|
fullArgs := append([]string{string(op)}, args...)
|
||||||
glog.V(1).Infof("running iptables %s %v", string(op), args)
|
glog.V(1).Infof("running iptables %s %v", string(op), args)
|
||||||
|
@ -23,7 +23,17 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEnsureChain(t *testing.T) {
|
func getIptablesCommand(protocol Protocol) string {
|
||||||
|
if protocol == ProtocolIpv4 {
|
||||||
|
return "iptables"
|
||||||
|
}
|
||||||
|
if protocol == ProtocolIpv6 {
|
||||||
|
return "ip6tables"
|
||||||
|
}
|
||||||
|
panic("Unknown protocol")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEnsureChain(t *testing.T, protocol Protocol) {
|
||||||
fcmd := exec.FakeCmd{
|
fcmd := exec.FakeCmd{
|
||||||
CombinedOutputScript: []exec.FakeCombinedOutputAction{
|
CombinedOutputScript: []exec.FakeCombinedOutputAction{
|
||||||
// Success.
|
// Success.
|
||||||
@ -41,7 +51,7 @@ func TestEnsureChain(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, protocol)
|
||||||
// Success.
|
// Success.
|
||||||
exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR"))
|
exists, err := runner.EnsureChain(TableNAT, Chain("FOOBAR"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -53,7 +63,8 @@ func TestEnsureChain(t *testing.T) {
|
|||||||
if fcmd.CombinedOutputCalls != 1 {
|
if fcmd.CombinedOutputCalls != 1 {
|
||||||
t.Errorf("expected 1 CombinedOutput() call, got %d", fcmd.CombinedOutputCalls)
|
t.Errorf("expected 1 CombinedOutput() call, got %d", fcmd.CombinedOutputCalls)
|
||||||
}
|
}
|
||||||
if !util.NewStringSet(fcmd.CombinedOutputLog[0]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
|
cmd := getIptablesCommand(protocol)
|
||||||
|
if !util.NewStringSet(fcmd.CombinedOutputLog[0]...).HasAll(cmd, "-t", "nat", "-N", "FOOBAR") {
|
||||||
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0])
|
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[0])
|
||||||
}
|
}
|
||||||
// Exists.
|
// Exists.
|
||||||
@ -71,6 +82,14 @@ func TestEnsureChain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnsureChainIpv4(t *testing.T) {
|
||||||
|
testEnsureChain(t, ProtocolIpv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnsureChainIpv6(t *testing.T) {
|
||||||
|
testEnsureChain(t, ProtocolIpv6)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFlushChain(t *testing.T) {
|
func TestFlushChain(t *testing.T) {
|
||||||
fcmd := exec.FakeCmd{
|
fcmd := exec.FakeCmd{
|
||||||
CombinedOutputScript: []exec.FakeCombinedOutputAction{
|
CombinedOutputScript: []exec.FakeCombinedOutputAction{
|
||||||
@ -86,7 +105,7 @@ func TestFlushChain(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
// Success.
|
// Success.
|
||||||
err := runner.FlushChain(TableNAT, Chain("FOOBAR"))
|
err := runner.FlushChain(TableNAT, Chain("FOOBAR"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,7 +137,7 @@ func TestEnsureRuleAlreadyExists(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected success, got %+v", err)
|
t.Errorf("expected success, got %+v", err)
|
||||||
@ -150,7 +169,7 @@ func TestEnsureRuleNew(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
exists, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected success, got %+v", err)
|
t.Errorf("expected success, got %+v", err)
|
||||||
@ -179,7 +198,7 @@ func TestEnsureRuleErrorChecking(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
_, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
_, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected failure")
|
t.Errorf("expected failure")
|
||||||
@ -205,7 +224,7 @@ func TestEnsureRuleErrorCreating(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
_, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
_, err := runner.EnsureRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected failure")
|
t.Errorf("expected failure")
|
||||||
@ -228,7 +247,7 @@ func TestDeleteRuleAlreadyExists(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected success, got %+v", err)
|
t.Errorf("expected success, got %+v", err)
|
||||||
@ -257,7 +276,7 @@ func TestDeleteRuleNew(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("expected success, got %+v", err)
|
t.Errorf("expected success, got %+v", err)
|
||||||
@ -283,7 +302,7 @@ func TestDeleteRuleErrorChecking(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected failure")
|
t.Errorf("expected failure")
|
||||||
@ -309,7 +328,7 @@ func TestDeleteRuleErrorCreating(t *testing.T) {
|
|||||||
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
runner := New(&fexec)
|
runner := New(&fexec, ProtocolIpv4)
|
||||||
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
err := runner.DeleteRule(TableNAT, ChainOutput, "abc", "123")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("expected failure")
|
t.Errorf("expected failure")
|
||||||
|
Loading…
Reference in New Issue
Block a user