Report Additional POD IPs
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
9d60f9c56e
commit
fcd6bf318b
@ -87,8 +87,9 @@ type CniConfig struct {
|
|||||||
NetworkPluginMaxConfNum int `toml:"max_conf_num" json:"maxConfNum"`
|
NetworkPluginMaxConfNum int `toml:"max_conf_num" json:"maxConfNum"`
|
||||||
// NetworkPluginConfTemplate is the file path of golang template used to generate
|
// NetworkPluginConfTemplate is the file path of golang template used to generate
|
||||||
// cni config.
|
// cni config.
|
||||||
// When it is set, containerd will get cidr from kubelet to replace {{.PodCIDR}} in
|
// When it is set, containerd will get cidr(s) from kubelet to replace {{.PodCIDR}},
|
||||||
// the template, and write the config into NetworkPluginConfDir.
|
// {{.PodCIDRRanges}} or {{.Routes}} in the template, and write the config into
|
||||||
|
// NetworkPluginConfDir.
|
||||||
// Ideally the cni config should be placed by system admin or cni daemon like calico,
|
// Ideally the cni config should be placed by system admin or cni daemon like calico,
|
||||||
// weaveworks etc. However, there are still users using kubenet
|
// weaveworks etc. However, there are still users using kubenet
|
||||||
// (https://kubernetes.io/docs/concepts/cluster-administration/network-plugins/#kubenet)
|
// (https://kubernetes.io/docs/concepts/cluster-administration/network-plugins/#kubenet)
|
||||||
|
@ -137,14 +137,14 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
|||||||
// In this case however caching the IP will add a subtle performance enhancement by avoiding
|
// In this case however caching the IP will add a subtle performance enhancement by avoiding
|
||||||
// calls to network namespace of the pod to query the IP of the veth interface on every
|
// calls to network namespace of the pod to query the IP of the veth interface on every
|
||||||
// SandboxStatus request.
|
// SandboxStatus request.
|
||||||
sandbox.IP, sandbox.CNIResult, err = c.setupPod(ctx, id, sandbox.NetNSPath, config)
|
sandbox.IP, sandbox.AdditionalIPs, sandbox.CNIResult, err = c.setupPodNetwork(ctx, id, sandbox.NetNSPath, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to setup network for sandbox %q", id)
|
return nil, errors.Wrapf(err, "failed to setup network for sandbox %q", id)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if retErr != nil {
|
if retErr != nil {
|
||||||
// Teardown network if an error is returned.
|
// Teardown network if an error is returned.
|
||||||
if err := c.teardownPod(ctx, id, sandbox.NetNSPath, config); err != nil {
|
if err := c.teardownPodNetwork(ctx, id, sandbox.NetNSPath, config); err != nil {
|
||||||
log.G(ctx).WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
log.G(ctx).WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,31 +302,32 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
|
|||||||
return &runtime.RunPodSandboxResponse{PodSandboxId: id}, nil
|
return &runtime.RunPodSandboxResponse{PodSandboxId: id}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupPod setups up the network for a pod
|
// setupPodNetwork setups up the network for a pod
|
||||||
func (c *criService) setupPod(ctx context.Context, id string, path string, config *runtime.PodSandboxConfig) (string, *cni.CNIResult, error) {
|
func (c *criService) setupPodNetwork(ctx context.Context, id string, path string, config *runtime.PodSandboxConfig) (string, []string, *cni.CNIResult, error) {
|
||||||
if c.netPlugin == nil {
|
if c.netPlugin == nil {
|
||||||
return "", nil, errors.New("cni config not initialized")
|
return "", nil, nil, errors.New("cni config not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
opts, err := cniNamespaceOpts(id, config)
|
opts, err := cniNamespaceOpts(id, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, errors.Wrap(err, "get cni namespace options")
|
return "", nil, nil, errors.Wrap(err, "get cni namespace options")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := c.netPlugin.Setup(ctx, id, path, opts...)
|
result, err := c.netPlugin.Setup(ctx, id, path, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, nil, err
|
||||||
}
|
}
|
||||||
logDebugCNIResult(ctx, id, result)
|
logDebugCNIResult(ctx, id, result)
|
||||||
// Check if the default interface has IP config
|
// Check if the default interface has IP config
|
||||||
if configs, ok := result.Interfaces[defaultIfName]; ok && len(configs.IPConfigs) > 0 {
|
if configs, ok := result.Interfaces[defaultIfName]; ok && len(configs.IPConfigs) > 0 {
|
||||||
return selectPodIP(configs.IPConfigs), result, nil
|
ip, additionalIPs := selectPodIPs(configs.IPConfigs)
|
||||||
|
return ip, additionalIPs, result, nil
|
||||||
}
|
}
|
||||||
// If it comes here then the result was invalid so destroy the pod network and return error
|
// If it comes here then the result was invalid so destroy the pod network and return error
|
||||||
if err := c.teardownPod(ctx, id, path, config); err != nil {
|
if err := c.teardownPodNetwork(ctx, id, path, config); err != nil {
|
||||||
log.G(ctx).WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
log.G(ctx).WithError(err).Errorf("Failed to destroy network for sandbox %q", id)
|
||||||
}
|
}
|
||||||
return "", result, errors.Errorf("failed to find network info for sandbox %q", id)
|
return "", nil, result, errors.Errorf("failed to find network info for sandbox %q", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cniNamespaceOpts get CNI namespace options from sandbox config.
|
// cniNamespaceOpts get CNI namespace options from sandbox config.
|
||||||
@ -426,14 +427,28 @@ func toCNIDNS(dns *runtime.DNSConfig) *cni.DNS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// selectPodIP select an ip from the ip list. It prefers ipv4 more than ipv6.
|
// selectPodIPs select an ip from the ip list. It prefers ipv4 more than ipv6
|
||||||
func selectPodIP(ipConfigs []*cni.IPConfig) string {
|
// and returns the additional ips
|
||||||
|
// TODO(random-liu): Revisit the ip order in the ipv6 beta stage. (cri#1278)
|
||||||
|
func selectPodIPs(ipConfigs []*cni.IPConfig) (string, []string) {
|
||||||
|
var (
|
||||||
|
additionalIPs []string
|
||||||
|
ip string
|
||||||
|
)
|
||||||
for _, c := range ipConfigs {
|
for _, c := range ipConfigs {
|
||||||
if c.IP.To4() != nil {
|
if c.IP.To4() != nil && ip == "" {
|
||||||
return c.IP.String()
|
ip = c.IP.String()
|
||||||
|
} else {
|
||||||
|
additionalIPs = append(additionalIPs, c.IP.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ipConfigs[0].IP.String()
|
if ip != "" {
|
||||||
|
return ip, additionalIPs
|
||||||
|
}
|
||||||
|
if len(ipConfigs) == 1 {
|
||||||
|
return additionalIPs[0], nil
|
||||||
|
}
|
||||||
|
return additionalIPs[0], additionalIPs[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// untrustedWorkload returns true if the sandbox contains untrusted workload.
|
// untrustedWorkload returns true if the sandbox contains untrusted workload.
|
||||||
|
@ -246,16 +246,29 @@ func TestToCNIPortMappings(t *testing.T) {
|
|||||||
|
|
||||||
func TestSelectPodIP(t *testing.T) {
|
func TestSelectPodIP(t *testing.T) {
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
ips []string
|
ips []string
|
||||||
expected string
|
expectedIP string
|
||||||
|
expectedAdditionalIPs []string
|
||||||
}{
|
}{
|
||||||
"ipv4 should be picked even if ipv6 comes first": {
|
"ipv4 should be picked even if ipv6 comes first": {
|
||||||
ips: []string{"2001:db8:85a3::8a2e:370:7334", "192.168.17.43"},
|
ips: []string{"2001:db8:85a3::8a2e:370:7334", "192.168.17.43"},
|
||||||
expected: "192.168.17.43",
|
expectedIP: "192.168.17.43",
|
||||||
|
expectedAdditionalIPs: []string{"2001:db8:85a3::8a2e:370:7334"},
|
||||||
|
},
|
||||||
|
"ipv4 should be picked when there is only ipv4": {
|
||||||
|
ips: []string{"192.168.17.43"},
|
||||||
|
expectedIP: "192.168.17.43",
|
||||||
|
expectedAdditionalIPs: nil,
|
||||||
},
|
},
|
||||||
"ipv6 should be picked when there is no ipv4": {
|
"ipv6 should be picked when there is no ipv4": {
|
||||||
ips: []string{"2001:db8:85a3::8a2e:370:7334"},
|
ips: []string{"2001:db8:85a3::8a2e:370:7334"},
|
||||||
expected: "2001:db8:85a3::8a2e:370:7334",
|
expectedIP: "2001:db8:85a3::8a2e:370:7334",
|
||||||
|
expectedAdditionalIPs: nil,
|
||||||
|
},
|
||||||
|
"the first ipv4 should be picked when there are multiple ipv4": { // unlikely to happen
|
||||||
|
ips: []string{"2001:db8:85a3::8a2e:370:7334", "192.168.17.43", "2001:db8:85a3::8a2e:370:7335", "192.168.17.45"},
|
||||||
|
expectedIP: "192.168.17.43",
|
||||||
|
expectedAdditionalIPs: []string{"2001:db8:85a3::8a2e:370:7334", "2001:db8:85a3::8a2e:370:7335", "192.168.17.45"},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Logf("TestCase %q", desc)
|
t.Logf("TestCase %q", desc)
|
||||||
@ -265,7 +278,9 @@ func TestSelectPodIP(t *testing.T) {
|
|||||||
IP: net.ParseIP(ip),
|
IP: net.ParseIP(ip),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
assert.Equal(t, test.expected, selectPodIP(ipConfigs))
|
ip, additionalIPs := selectPodIPs(ipConfigs)
|
||||||
|
assert.Equal(t, test.expectedIP, ip)
|
||||||
|
assert.Equal(t, test.expectedAdditionalIPs, additionalIPs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
|
|||||||
return nil, errors.Wrap(err, "an error occurred when try to find sandbox")
|
return nil, errors.Wrap(err, "an error occurred when try to find sandbox")
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := c.getIP(sandbox)
|
ip, additionalIPs, err := c.getIPs(sandbox)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to get sandbox ip")
|
return nil, errors.Wrap(err, "failed to get sandbox ip")
|
||||||
}
|
}
|
||||||
status := toCRISandboxStatus(sandbox.Metadata, sandbox.Status.Get(), ip)
|
status := toCRISandboxStatus(sandbox.Metadata, sandbox.Status.Get(), ip, additionalIPs)
|
||||||
if status.GetCreatedAt() == 0 {
|
if status.GetCreatedAt() == 0 {
|
||||||
// CRI doesn't allow CreatedAt == 0.
|
// CRI doesn't allow CreatedAt == 0.
|
||||||
info, err := sandbox.Container.Info(ctx)
|
info, err := sandbox.Container.Info(ctx)
|
||||||
@ -67,39 +67,46 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *criService) getIP(sandbox sandboxstore.Sandbox) (string, error) {
|
func (c *criService) getIPs(sandbox sandboxstore.Sandbox) (string, []string, error) {
|
||||||
config := sandbox.Config
|
config := sandbox.Config
|
||||||
|
|
||||||
if goruntime.GOOS != "windows" &&
|
if goruntime.GOOS != "windows" &&
|
||||||
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
config.GetLinux().GetSecurityContext().GetNamespaceOptions().GetNetwork() == runtime.NamespaceMode_NODE {
|
||||||
// For sandboxes using the node network we are not
|
// For sandboxes using the node network we are not
|
||||||
// responsible for reporting the IP.
|
// responsible for reporting the IP.
|
||||||
return "", nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if closed, err := sandbox.NetNS.Closed(); err != nil {
|
if closed, err := sandbox.NetNS.Closed(); err != nil {
|
||||||
return "", errors.Wrap(err, "check network namespace closed")
|
return "", nil, errors.Wrap(err, "check network namespace closed")
|
||||||
} else if closed {
|
} else if closed {
|
||||||
return "", nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return sandbox.IP, nil
|
return sandbox.IP, sandbox.AdditionalIPs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// toCRISandboxStatus converts sandbox metadata into CRI pod sandbox status.
|
// toCRISandboxStatus converts sandbox metadata into CRI pod sandbox status.
|
||||||
func toCRISandboxStatus(meta sandboxstore.Metadata, status sandboxstore.Status, ip string) *runtime.PodSandboxStatus {
|
func toCRISandboxStatus(meta sandboxstore.Metadata, status sandboxstore.Status, ip string, additionalIPs []string) *runtime.PodSandboxStatus {
|
||||||
// Set sandbox state to NOTREADY by default.
|
// Set sandbox state to NOTREADY by default.
|
||||||
state := runtime.PodSandboxState_SANDBOX_NOTREADY
|
state := runtime.PodSandboxState_SANDBOX_NOTREADY
|
||||||
if status.State == sandboxstore.StateReady {
|
if status.State == sandboxstore.StateReady {
|
||||||
state = runtime.PodSandboxState_SANDBOX_READY
|
state = runtime.PodSandboxState_SANDBOX_READY
|
||||||
}
|
}
|
||||||
nsOpts := meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions()
|
nsOpts := meta.Config.GetLinux().GetSecurityContext().GetNamespaceOptions()
|
||||||
|
var ips []*runtime.PodIP
|
||||||
|
for _, additionalIP := range additionalIPs {
|
||||||
|
ips = append(ips, &runtime.PodIP{Ip: additionalIP})
|
||||||
|
}
|
||||||
return &runtime.PodSandboxStatus{
|
return &runtime.PodSandboxStatus{
|
||||||
Id: meta.ID,
|
Id: meta.ID,
|
||||||
Metadata: meta.Config.GetMetadata(),
|
Metadata: meta.Config.GetMetadata(),
|
||||||
State: state,
|
State: state,
|
||||||
CreatedAt: status.CreatedAt.UnixNano(),
|
CreatedAt: status.CreatedAt.UnixNano(),
|
||||||
Network: &runtime.PodSandboxNetworkStatus{Ip: ip},
|
Network: &runtime.PodSandboxNetworkStatus{
|
||||||
|
Ip: ip,
|
||||||
|
AdditionalIps: ips,
|
||||||
|
},
|
||||||
Linux: &runtime.LinuxPodSandboxStatus{
|
Linux: &runtime.LinuxPodSandboxStatus{
|
||||||
Namespaces: &runtime.Namespace{
|
Namespaces: &runtime.Namespace{
|
||||||
Options: &runtime.NamespaceOption{
|
Options: &runtime.NamespaceOption{
|
||||||
|
@ -31,6 +31,7 @@ func TestPodSandboxStatus(t *testing.T) {
|
|||||||
id = "test-id"
|
id = "test-id"
|
||||||
ip = "10.10.10.10"
|
ip = "10.10.10.10"
|
||||||
)
|
)
|
||||||
|
additionalIPs := []string{"8.8.8.8", "2001:db8:85a3::8a2e:370:7334"}
|
||||||
createdAt := time.Now()
|
createdAt := time.Now()
|
||||||
config := &runtime.PodSandboxConfig{
|
config := &runtime.PodSandboxConfig{
|
||||||
Metadata: &runtime.PodSandboxMetadata{
|
Metadata: &runtime.PodSandboxMetadata{
|
||||||
@ -62,7 +63,17 @@ func TestPodSandboxStatus(t *testing.T) {
|
|||||||
Id: id,
|
Id: id,
|
||||||
Metadata: config.GetMetadata(),
|
Metadata: config.GetMetadata(),
|
||||||
CreatedAt: createdAt.UnixNano(),
|
CreatedAt: createdAt.UnixNano(),
|
||||||
Network: &runtime.PodSandboxNetworkStatus{Ip: ip},
|
Network: &runtime.PodSandboxNetworkStatus{
|
||||||
|
Ip: ip,
|
||||||
|
AdditionalIps: []*runtime.PodIP{
|
||||||
|
{
|
||||||
|
Ip: additionalIPs[0],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Ip: additionalIPs[1],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
Linux: &runtime.LinuxPodSandboxStatus{
|
Linux: &runtime.LinuxPodSandboxStatus{
|
||||||
Namespaces: &runtime.Namespace{
|
Namespaces: &runtime.Namespace{
|
||||||
Options: &runtime.NamespaceOption{
|
Options: &runtime.NamespaceOption{
|
||||||
@ -99,7 +110,7 @@ func TestPodSandboxStatus(t *testing.T) {
|
|||||||
State: test.state,
|
State: test.state,
|
||||||
}
|
}
|
||||||
expected.State = test.expectedState
|
expected.State = test.expectedState
|
||||||
got := toCRISandboxStatus(metadata, status, ip)
|
got := toCRISandboxStatus(metadata, status, ip, additionalIPs)
|
||||||
assert.Equal(t, expected, got)
|
assert.Equal(t, expected, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
|
|||||||
} else if closed {
|
} else if closed {
|
||||||
netNSPath = ""
|
netNSPath = ""
|
||||||
}
|
}
|
||||||
if err := c.teardownPod(ctx, id, netNSPath, sandbox.Config); err != nil {
|
if err := c.teardownPodNetwork(ctx, id, netNSPath, sandbox.Config); err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
|
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
|
||||||
}
|
}
|
||||||
if err = sandbox.NetNS.Remove(); err != nil {
|
if err = sandbox.NetNS.Remove(); err != nil {
|
||||||
@ -155,8 +155,8 @@ func (c *criService) waitSandboxStop(ctx context.Context, sandbox sandboxstore.S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// teardownPod removes the network from the pod
|
// teardownPodNetwork removes the network from the pod
|
||||||
func (c *criService) teardownPod(ctx context.Context, id string, path string, config *runtime.PodSandboxConfig) error {
|
func (c *criService) teardownPodNetwork(ctx context.Context, id string, path string, config *runtime.PodSandboxConfig) error {
|
||||||
if c.netPlugin == nil {
|
if c.netPlugin == nil {
|
||||||
return errors.New("cni config not initialized")
|
return errors.New("cni config not initialized")
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,10 @@ limitations under the License.
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -32,17 +34,36 @@ import (
|
|||||||
type cniConfigTemplate struct {
|
type cniConfigTemplate struct {
|
||||||
// PodCIDR is the cidr for pods on the node.
|
// PodCIDR is the cidr for pods on the node.
|
||||||
PodCIDR string
|
PodCIDR string
|
||||||
|
// PodCIDRRanges is the cidr ranges for pods on the node.
|
||||||
|
PodCIDRRanges []string
|
||||||
|
// Routes is a list of routes configured.
|
||||||
|
Routes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// cniConfigFileName is the name of cni config file generated by containerd.
|
const (
|
||||||
const cniConfigFileName = "10-containerd-net.conflist"
|
// cniConfigFileName is the name of cni config file generated by containerd.
|
||||||
|
cniConfigFileName = "10-containerd-net.conflist"
|
||||||
|
// zeroCIDRv6 is the null route for IPv6.
|
||||||
|
zeroCIDRv6 = "::/0"
|
||||||
|
// zeroCIDRv4 is the null route for IPv4.
|
||||||
|
zeroCIDRv4 = "0.0.0.0/0"
|
||||||
|
)
|
||||||
|
|
||||||
// UpdateRuntimeConfig updates the runtime config. Currently only handles podCIDR updates.
|
// UpdateRuntimeConfig updates the runtime config. Currently only handles podCIDR updates.
|
||||||
func (c *criService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateRuntimeConfigRequest) (*runtime.UpdateRuntimeConfigResponse, error) {
|
func (c *criService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateRuntimeConfigRequest) (*runtime.UpdateRuntimeConfigResponse, error) {
|
||||||
podCIDR := r.GetRuntimeConfig().GetNetworkConfig().GetPodCidr()
|
podCIDRs := r.GetRuntimeConfig().GetNetworkConfig().GetPodCidr()
|
||||||
if podCIDR == "" {
|
if podCIDRs == "" {
|
||||||
return &runtime.UpdateRuntimeConfigResponse{}, nil
|
return &runtime.UpdateRuntimeConfigResponse{}, nil
|
||||||
}
|
}
|
||||||
|
cidrs := strings.Split(podCIDRs, ",")
|
||||||
|
for i := range cidrs {
|
||||||
|
cidrs[i] = strings.TrimSpace(cidrs[i])
|
||||||
|
}
|
||||||
|
routes, err := getRoutes(cidrs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "get routes")
|
||||||
|
}
|
||||||
|
|
||||||
confTemplate := c.config.NetworkPluginConfTemplate
|
confTemplate := c.config.NetworkPluginConfTemplate
|
||||||
if confTemplate == "" {
|
if confTemplate == "" {
|
||||||
log.G(ctx).Info("No cni config template is specified, wait for other system components to drop the config.")
|
log.G(ctx).Info("No cni config template is specified, wait for other system components to drop the config.")
|
||||||
@ -70,8 +91,38 @@ func (c *criService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateR
|
|||||||
return nil, errors.Wrapf(err, "failed to open cni config file %q", confFile)
|
return nil, errors.Wrapf(err, "failed to open cni config file %q", confFile)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if err := t.Execute(f, cniConfigTemplate{PodCIDR: podCIDR}); err != nil {
|
if err := t.Execute(f, cniConfigTemplate{
|
||||||
|
PodCIDR: cidrs[0],
|
||||||
|
PodCIDRRanges: cidrs,
|
||||||
|
Routes: routes,
|
||||||
|
}); err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to generate cni config file %q", confFile)
|
return nil, errors.Wrapf(err, "failed to generate cni config file %q", confFile)
|
||||||
}
|
}
|
||||||
return &runtime.UpdateRuntimeConfigResponse{}, nil
|
return &runtime.UpdateRuntimeConfigResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getRoutes generates required routes for the passed in cidrs.
|
||||||
|
func getRoutes(cidrs []string) ([]string, error) {
|
||||||
|
var (
|
||||||
|
routes []string
|
||||||
|
hasV4, hasV6 bool
|
||||||
|
)
|
||||||
|
for _, c := range cidrs {
|
||||||
|
_, cidr, err := net.ParseCIDR(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cidr.IP.To4() != nil {
|
||||||
|
hasV4 = true
|
||||||
|
} else {
|
||||||
|
hasV6 = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hasV4 {
|
||||||
|
routes = append(routes, zeroCIDRv4)
|
||||||
|
}
|
||||||
|
if hasV6 {
|
||||||
|
routes = append(routes, zeroCIDRv6)
|
||||||
|
}
|
||||||
|
return routes, nil
|
||||||
|
}
|
||||||
|
@ -45,14 +45,13 @@ func TestUpdateRuntimeConfig(t *testing.T) {
|
|||||||
"ipam": {
|
"ipam": {
|
||||||
"type": "host-local",
|
"type": "host-local",
|
||||||
"subnet": "{{.PodCIDR}}",
|
"subnet": "{{.PodCIDR}}",
|
||||||
"routes": [
|
"ranges": [{{range $i, $range := .PodCIDRRanges}}{{if $i}}, {{end}}[{"subnet": "{{$range}}"}]{{end}}],
|
||||||
{"dst": "0.0.0.0/0"}
|
"routes": [{{range $i, $route := .Routes}}{{if $i}}, {{end}}{"dst": "{{$route}}"}{{end}}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}`
|
}`
|
||||||
testCIDR = "10.0.0.0/24"
|
testCIDR = "10.0.0.0/24, 2001:4860:4860::8888/32"
|
||||||
expected = `
|
expected = `
|
||||||
{
|
{
|
||||||
"name": "test-pod-network",
|
"name": "test-pod-network",
|
||||||
@ -64,9 +63,8 @@ func TestUpdateRuntimeConfig(t *testing.T) {
|
|||||||
"ipam": {
|
"ipam": {
|
||||||
"type": "host-local",
|
"type": "host-local",
|
||||||
"subnet": "10.0.0.0/24",
|
"subnet": "10.0.0.0/24",
|
||||||
"routes": [
|
"ranges": [[{"subnet": "10.0.0.0/24"}], [{"subnet": "2001:4860:4860::8888/32"}]],
|
||||||
{"dst": "0.0.0.0/0"}
|
"routes": [{"dst": "0.0.0.0/0"}, {"dst": "::/0"}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -55,6 +55,8 @@ type Metadata struct {
|
|||||||
NetNSPath string
|
NetNSPath string
|
||||||
// IP of Pod if it is attached to non host network
|
// IP of Pod if it is attached to non host network
|
||||||
IP string
|
IP string
|
||||||
|
// AdditionalIPs of the Pod if it is attached to non host network
|
||||||
|
AdditionalIPs []string
|
||||||
// RuntimeHandler is the runtime handler name of the pod.
|
// RuntimeHandler is the runtime handler name of the pod.
|
||||||
RuntimeHandler string
|
RuntimeHandler string
|
||||||
// CNIresult resulting configuration for attached network namespace interfaces
|
// CNIresult resulting configuration for attached network namespace interfaces
|
||||||
|
Loading…
Reference in New Issue
Block a user