-
Notifications
You must be signed in to change notification settings - Fork 200
Specify network namespace for firecracker process #120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,26 +33,41 @@ import ( | |
) | ||
|
||
const ( | ||
kernelArgsFormat = "console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw ip=%s::%s:%s:::off::::" | ||
macAddress = "AA:FC:00:00:00:01" | ||
hostDevName = "tap0" | ||
kernelArgsFormat = "console=ttyS0 noapic reboot=k panic=1 pci=off nomodules rw ip=%s::%s:%s:::off::::" | ||
defaultMacAddress = "AA:FC:00:00:00:01" | ||
defaultHostDevName = "tap0" | ||
) | ||
|
||
func main() { | ||
var ip = flag.String("ip", "", "ip address assigned to the container. Example: -ip 172.16.0.1") | ||
var gateway = flag.String("gw", "", "gateway ip address. Example: -gw 172.16.0.1") | ||
var netMask = flag.String("mask", "", "subnet gatway mask. Example: -mask 255.255.255.0") | ||
var netNS = flag.String("netns", "", "firecracker VM network namespace. Example: -netNS testing") | ||
var hostDevName = flag.String("host_device", defaultHostDevName, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I'd prefer to use |
||
"the host device name for the network interface, required when specifying 'netns'. Example: -host_device tap0") | ||
var macAddress = flag.String("mac", defaultMacAddress, | ||
"the mac address for the network interface, required when specifying 'netns'. Example: -mac AA:FC:00:00:00:01") | ||
var kernelNetworkArgs = flag.Bool("kernel_nw_args", false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for hyphens rather than underscores. I also would prefer something other than "nw" for network. Maybe |
||
"specifies if network params for the VMs should be included with kernel args. Example: -kernel_nw_args true") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this always true when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It's true only when someone sets it. Depending on how your VM is configured you or may not need it. My rootfs has a dhcp client. Hence, I don't need to set this at all. The |
||
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) | ||
flag.Parse() | ||
if *ip != "" && (*gateway == "" || *netMask == "") { | ||
log.Fatal("Incorrect usage. 'gw' and 'mask' need to be specified when 'ip' is specified") | ||
if *kernelNetworkArgs && (*gateway == "" || *netMask == "" || *ip == "") { | ||
log.Fatal("Incorrect usage. 'ip', 'gw' and 'mask' need to be specified when 'kernel_nw_args' is set") | ||
} | ||
if err := taskWorkflow(*ip, *gateway, *netMask); err != nil { | ||
if err := taskWorkflow(*ip, *kernelNetworkArgs, *gateway, *netMask, *macAddress, *hostDevName, *netNS); err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
func taskWorkflow(containerIP string, gateway string, netMask string) error { | ||
func taskWorkflow( | ||
containerIP string, | ||
kernelNetworkArgs bool, | ||
gateway string, | ||
netMask string, | ||
macAddress string, | ||
hostDevName string, | ||
netNS string, | ||
) error { | ||
log.Println("Creating containerd client") | ||
client, err := containerd.New("/run/containerd/containerd.sock") | ||
if err != nil { | ||
|
@@ -93,21 +108,23 @@ func taskWorkflow(containerIP string, gateway string, netMask string) error { | |
task, err := container.NewTask(ctx, | ||
cio.NewCreator(cio.WithStdio), | ||
func(ctx context.Context, _ *containerd.Client, ti *containerd.TaskInfo) error { | ||
if containerIP == "" { | ||
if containerIP == "" && netNS == "" { | ||
// No params to configure, return. | ||
return nil | ||
} | ||
// An IP address for the container has been provided. Configure | ||
// the VM opts accordingly. | ||
firecrackerConfig := &proto.FirecrackerConfig{ | ||
NetworkInterfaces: []*proto.FirecrackerNetworkInterface{ | ||
{ | ||
MacAddress: macAddress, | ||
HostDevName: hostDevName, | ||
}, | ||
}, | ||
KernelArgs: fmt.Sprintf(kernelArgsFormat, containerIP, gateway, netMask), | ||
// An IP address or the network namespace for the container has | ||
// been provided. Configure VM opts accordingly. | ||
builder := newFirecrackerConfigBuilder() | ||
if containerIP != "" { | ||
builder.setNetworkConfig(macAddress, hostDevName) | ||
} | ||
ti.Options = firecrackerConfig | ||
if kernelNetworkArgs { | ||
builder.setKernelNetworkArgs(containerIP, gateway, netMask) | ||
} | ||
if netNS != "" { | ||
builder.setNetNS(netNS) | ||
} | ||
ti.Options = builder.build() | ||
return nil | ||
}) | ||
if err != nil { | ||
|
@@ -151,6 +168,47 @@ func taskWorkflow(containerIP string, gateway string, netMask string) error { | |
return nil | ||
} | ||
|
||
type firecrackerConfigBuilder struct { | ||
vmConfig *proto.FirecrackerConfig | ||
} | ||
|
||
func newFirecrackerConfigBuilder() *firecrackerConfigBuilder { | ||
return &firecrackerConfigBuilder{ | ||
vmConfig: &proto.FirecrackerConfig{}, | ||
} | ||
} | ||
|
||
func (builder *firecrackerConfigBuilder) build() *proto.FirecrackerConfig { | ||
return builder.vmConfig | ||
} | ||
|
||
// setNetworkConfig sets the fields in the protobuf message required to | ||
// configure the VM with the container IP, gateway and netmask sepcified. | ||
func (builder *firecrackerConfigBuilder) setNetworkConfig( | ||
macAddress string, | ||
hostDevName string, | ||
) { | ||
builder.vmConfig.NetworkInterfaces = []*proto.FirecrackerNetworkInterface{ | ||
{ | ||
MacAddress: macAddress, | ||
HostDevName: hostDevName, | ||
}, | ||
} | ||
} | ||
|
||
func (builder *firecrackerConfigBuilder) setKernelNetworkArgs( | ||
containerIP string, | ||
gateway string, | ||
netMask string, | ||
) { | ||
builder.vmConfig.KernelArgs = fmt.Sprintf(kernelArgsFormat, containerIP, gateway, netMask) | ||
} | ||
|
||
// setNetNS sets the network namespace field in the protobuf message. | ||
func (builder *firecrackerConfigBuilder) setNetNS(netNS string) { | ||
builder.vmConfig.FirecrackerNetworkNamespace = netNS | ||
} | ||
|
||
func getResponse(containerIP string) { | ||
response, err := http.Get("http://" + containerIP) | ||
if err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the example should read "-netns testing".