Skip to content

Commit

Permalink
VPC-CNI minimal image builds
Browse files Browse the repository at this point in the history
  • Loading branch information
jdn5126 committed Nov 21, 2022
1 parent 9dc83c6 commit a3ccb92
Show file tree
Hide file tree
Showing 14 changed files with 771 additions and 304 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
aws-k8s-agent
aws-cni
aws-vpc-cni
aws-vpc-cni-init
bandwidth
host-local
loopback
verify-aws
verify-network
*~
Expand Down
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ LDFLAGS = -X pkg/version/info.Version=$(VERSION) -X pkg/awsutils/awssession.vers
# ALLPKGS is the set of packages provided in source.
ALLPKGS = $(shell go list $(VENDOR_OVERRIDE_FLAG) ./... | grep -v cmd/packet-verifier)
# BINS is the set of built command executables.
BINS = aws-k8s-agent aws-cni grpc-health-probe cni-metrics-helper
BINS = aws-k8s-agent aws-cni grpc-health-probe cni-metrics-helper aws-vpc-cni aws-vpc-cni-init
# Plugin binaries
# Not copied: bridge dhcp firewall flannel host-device host-local ipvlan macvlan ptp sbr static tuning vlan
# For gnu tar, the full path in the tar file is required
Expand Down Expand Up @@ -119,6 +119,16 @@ build-linux: ## Build the VPC CNI plugin agent using the host's Go toolchain.
go build $(VENDOR_OVERRIDE_FLAG) $(BUILD_FLAGS) -o grpc-health-probe ./cmd/grpc-health-probe
go build $(VENDOR_OVERRIDE_FLAG) $(BUILD_FLAGS) -o egress-v4-cni ./cmd/egress-v4-cni-plugin

# Build VPC CNI init container entrypoint
build-aws-vpc-cni-init: BUILD_FLAGS = $(BUILD_MODE) -ldflags '-s -w $(LDFLAGS)'
build-aws-vpc-cni-init: ## Build the VPC CNI init container using the host's Go toolchain.
go build $(VENDOR_OVERRIDE_FLAG) $(BUILD_FLAGS) -o aws-vpc-cni-init ./cmd/aws-vpc-cni-init

# Build VPC CNI container entrypoint
build-aws-vpc-cni: BUILD_FLAGS = $(BUILD_MODE) -ldflags '-s -w $(LDFLAGS)'
build-aws-vpc-cni: ## Build the VPC CNI container using the host's Go toolchain.
go build $(VENDOR_OVERRIDE_FLAG) $(BUILD_FLAGS) -o aws-vpc-cni ./cmd/aws-vpc-cni

# Build VPC CNI plugin & agent container image.
docker: setup-ec2-sdk-override ## Build VPC CNI plugin & agent container image.
docker build $(DOCKER_BUILD_FLAGS) \
Expand Down
177 changes: 177 additions & 0 deletions cmd/aws-vpc-cni-init/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.

// The aws-node initialization
package main

import (
"os"

"github.com/aws/amazon-vpc-cni-k8s/utils/cp"
"github.com/aws/amazon-vpc-cni-k8s/utils/imds"
"github.com/aws/amazon-vpc-cni-k8s/utils/sysctl"
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
)

const (
defaultHostCNIBinPath = "/host/opt/cni/bin"
vpcCniInitDonePath = "/vpc-cni-init/done"
metadataLocalIP = "local-ipv4"
metadataMAC = "mac"

envDisableIPv4TcpEarlyDemux = "DISABLE_TCP_EARLY_DEMUX"
envEnableIPv6 = "ENABLE_IPv6"
envHostCniBinPath = "HOST_CNI_BIN_PATH"
)

func getEnv(env, def string) string {
if val, ok := os.LookupEnv(env); ok {
return val
}
return def
}

func main() {
os.Exit(_main())
}

func _main() int {
log.Debug("Started Initialization")
pluginBins := []string{"loopback", "portmap", "bandwidth", "aws-cni-support.sh"}
var err error
for _, plugin := range pluginBins {
if _, err = os.Stat(plugin); err != nil {
log.WithError(err).Fatalf("Required executable: %s not found\n", plugin)
return 1
}
}

hostCNIBinPath := getEnv(envHostCniBinPath, defaultHostCNIBinPath)

log.Infof("Copying CNI plugin binaries ...")
err = cp.InstallBinaries(pluginBins, hostCNIBinPath)
if err != nil {
log.WithError(err).Errorf("Failed to install binaries")
return 1
}

log.Infof("Copied all CNI plugin binaries to %s\n", hostCNIBinPath)

var primaryMAC string
primaryMAC, err = imds.GetMetaData("mac")
if err != nil {
log.WithError(err).Fatalf("aws-vpc-cni init failed\n")
return 1
}

log.Infof("Found primaryMAC %s", primaryMAC)

links, err := netlink.LinkList()
if err != nil {
log.WithError(err).Fatalf("Failed to list links\n")
return 1
}

var primaryIF string
for _, link := range links {
if link.Attrs().HardwareAddr.String() == primaryMAC {
primaryIF = link.Attrs().Name
break
}
}

if primaryIF == "" {
log.Errorf("Failed to retrieve primary IF")
return 1
}
log.Infof("Found primaryIF %s", primaryIF)

sys := sysctl.New()
// Configure rp_filter in loose mode
entry := "net/ipv4/conf/" + primaryIF + "/rp_filter"
err = sys.SetSysctl(entry, 2)
if err != nil {
log.WithError(err).Fatalf("Failed to set rp_filter for %s\n", primaryIF)
return 1
}

val, _ := sys.GetSysctl(entry)
log.Infof("Updated entry for %d", val)

// Enable or disable TCP early demux based on environment variable
disableIPv4EarlyDemux := getEnv(envDisableIPv4TcpEarlyDemux, "false")
entry = "net/ipv4/tcp_early_demux"
if disableIPv4EarlyDemux == "true" {
err = sys.SetSysctl(entry, 0)
if err != nil {
log.WithError(err).Fatalf("Failed to disable tcp_early_demux\n")
return 1
}
} else {
err = sys.SetSysctl(entry, 1)
if err != nil {
log.WithError(err).Fatalf("Failed to enable tcp_early_demux\n")
return 1
}
}

val, _ = sys.GetSysctl(entry)
log.Infof("Updated entry for %d", val)

// Enable IPv6 when environment variable is set
// Note that IPv6 is not disabled when environment variable is unset. This is omitted to preserve default host semantics.
enableIPv6 := getEnv(envEnableIPv6, "false")
if enableIPv6 == "true" {
entry = "net/ipv6/conf/all/disable_ipv6"
err = sys.SetSysctl(entry, 0)
if err != nil {
log.WithError(err).Fatalf("Failed to set disable_ipv6 to 0\n")
return 1
}
val, _ = sys.GetSysctl(entry)
log.Infof("Updated entry for %d", val)

entry = "net/ipv6/conf/all/forwarding"
err = sys.SetSysctl(entry, 1)
if err != nil {
log.WithError(err).Fatalf("Failed to enable ipv6 forwarding\n")
return 1
}
val, _ = sys.GetSysctl(entry)
log.Infof("Updated entry for %d", val)

entry = "net/ipv6/conf/" + primaryIF + "/accept_ra"
err = sys.SetSysctl(entry, 2)
if err != nil {
log.WithError(err).Fatalf("Failed to enable ipv6 accept_ra\n")
return 1
}
val, _ = sys.GetSysctl(entry)
log.Infof("Updated entry for %d", val)
}

// TODO: In order to speed up pod launch time, VPC CNI init container is not a Kubernetes init container.
// The VPC CNI container blocks on the existence of vpcCniInitDonePath
//err = cp.TouchFile(vpcCniInitDonePath)
//if err != nil {
// log.WithError(err).Errorf("Failed to set VPC CNI init done")
// return 1
//}

log.Infof("CNI init container done")

// TODO: Since VPC CNI init container is a real container, it never exits
// time.Sleep(time.Duration(1<<63 - 1))
return 0
}
Loading

0 comments on commit a3ccb92

Please sign in to comment.