agent/config/config_unix.go (139 lines of code) (raw):

//go:build !windows // +build !windows // 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. package config import ( "fmt" "os" "time" "github.com/aws/amazon-ecs-agent/agent/config/ipcompatibility" "github.com/aws/amazon-ecs-agent/agent/dockerclient" "github.com/aws/amazon-ecs-agent/agent/utils" netutils "github.com/aws/amazon-ecs-agent/agent/utils/net" "github.com/aws/amazon-ecs-agent/agent/utils/netlinkwrapper" "github.com/aws/amazon-ecs-agent/ecs-agent/ec2" "github.com/aws/amazon-ecs-agent/ecs-agent/logger" "github.com/aws/amazon-ecs-agent/ecs-agent/logger/field" "github.com/aws/amazon-ecs-agent/ecs-agent/tmds" ) const ( // AgentCredentialsAddress is used to serve the credentials for tasks. AgentCredentialsAddress = "" // this is left blank right now for net=bridge // defaultAuditLogFile specifies the default audit log filename defaultCredentialsAuditLogFile = "/log/audit.log" // defaultRuntimeStatsLogFile stores the path where the golang runtime stats are periodically logged defaultRuntimeStatsLogFile = `/log/agent-runtime-stats.log` // DefaultTaskCgroupV1Prefix is default cgroup v1 prefix for ECS tasks DefaultTaskCgroupV1Prefix = "/ecs" // DefaultTaskCgroupV2Prefix is default cgroup v2 prefix for ECS tasks // ecstasks is used because this creates a systemd "slice", and using just // ecs would create a confusing name conflict with the ecs systemd service. // (we would have both ecs.service and ecs.slice in /sys/fs/cgroup). DefaultTaskCgroupV2Prefix = "ecstasks" // Default cgroup memory system root path, this is the default used if the // path has not been configured through ECS_CGROUP_PATH defaultCgroupPath = "/sys/fs/cgroup" // minimumManifestPullTimeout is the minimum timeout allowed for manifest pulls minimumManifestPullTimeout = 30 * time.Second // defaultManifestPullTimeout is the default timeout for manifest pulls defaultManifestPullTimeout = 1 * time.Minute // defaultContainerStartTimeout specifies the value for container start timeout duration defaultContainerStartTimeout = 3 * time.Minute // minimumContainerStartTimeout specifies the minimum value for starting a container minimumContainerStartTimeout = 45 * time.Second // defaultContainerCreateTimeout specifies the value for container create timeout duration defaultContainerCreateTimeout = 4 * time.Minute // minimumContainerCreateTimeout specifies the minimum value for creating a container minimumContainerCreateTimeout = 1 * time.Minute // default docker inactivity time is extra time needed on container extraction defaultImagePullInactivityTimeout = 1 * time.Minute // default socket filepath is "/var/run/ecs/ebs-csi-driver/csi-driver.sock" defaultCSIDriverSocketPath = "/var/run/ecs/ebs-csi-driver/csi-driver.sock" // nodeStageTimeout is the deafult timeout for staging an EBS TA volume nodeStageTimeout = 2 * time.Second // nodeUnstageTimeout is the deafult timeout for unstaging an EBS TA volume nodeUnstageTimeout = 30 * time.Second ) var ( nlWrapper = netlinkwrapper.New() ) // DefaultConfig returns the default configuration for Linux func DefaultConfig() Config { return Config{ DockerEndpoint: "unix:///var/run/docker.sock", ReservedPorts: []uint16{SSHPort, DockerReservedPort, DockerReservedSSLPort, AgentIntrospectionPort, tmds.Port}, ReservedPortsUDP: []uint16{}, DataDir: "/data/", DataDirOnHost: "/var/lib/ecs", DisableMetrics: BooleanDefaultFalse{Value: ExplicitlyDisabled}, ReservedMemory: 0, AvailableLoggingDrivers: []dockerclient.LoggingDriver{dockerclient.JSONFileDriver, dockerclient.NoneDriver}, TaskCleanupWaitDuration: DefaultTaskCleanupWaitDuration, ManifestPullTimeout: defaultManifestPullTimeout, DockerStopTimeout: defaultDockerStopTimeout, ContainerStartTimeout: defaultContainerStartTimeout, ContainerCreateTimeout: defaultContainerCreateTimeout, DependentContainersPullUpfront: BooleanDefaultFalse{Value: ExplicitlyDisabled}, CredentialsAuditLogFile: defaultCredentialsAuditLogFile, CredentialsAuditLogDisabled: false, ImageCleanupDisabled: BooleanDefaultFalse{Value: ExplicitlyDisabled}, MinimumImageDeletionAge: DefaultImageDeletionAge, NonECSMinimumImageDeletionAge: DefaultNonECSImageDeletionAge, ImageCleanupInterval: DefaultImageCleanupTimeInterval, ImagePullInactivityTimeout: defaultImagePullInactivityTimeout, ImagePullTimeout: DefaultImagePullTimeout, NumImagesToDeletePerCycle: DefaultNumImagesToDeletePerCycle, NumNonECSContainersToDeletePerCycle: DefaultNumNonECSContainersToDeletePerCycle, CNIPluginsPath: defaultCNIPluginsPath, PauseContainerTarballPath: pauseContainerTarballPath, PauseContainerImageName: DefaultPauseContainerImageName, PauseContainerTag: DefaultPauseContainerTag, AWSVPCBlockInstanceMetdata: BooleanDefaultFalse{Value: ExplicitlyDisabled}, ContainerMetadataEnabled: BooleanDefaultFalse{Value: ExplicitlyDisabled}, TaskCPUMemLimit: BooleanDefaultTrue{Value: NotSet}, CgroupPath: defaultCgroupPath, TaskMetadataSteadyStateRate: DefaultTaskMetadataSteadyStateRate, TaskMetadataBurstRate: DefaultTaskMetadataBurstRate, SharedVolumeMatchFullConfig: BooleanDefaultFalse{Value: ExplicitlyDisabled}, // only requiring shared volumes to match on name, which is default docker behavior ContainerInstancePropagateTagsFrom: ContainerInstancePropagateTagsFromNoneType, PrometheusMetricsEnabled: false, PollMetrics: BooleanDefaultFalse{Value: NotSet}, PollingMetricsWaitDuration: DefaultPollingMetricsWaitDuration, NvidiaRuntime: DefaultNvidiaRuntime, CgroupCPUPeriod: defaultCgroupCPUPeriod, GMSACapable: parseGMSACapability(), GMSADomainlessCapable: parseGMSADomainlessCapability(), FSxWindowsFileServerCapable: BooleanDefaultTrue{Value: ExplicitlyDisabled}, RuntimeStatsLogFile: defaultRuntimeStatsLogFile, EnableRuntimeStats: BooleanDefaultFalse{Value: NotSet}, ShouldExcludeIPv6PortBinding: BooleanDefaultTrue{Value: ExplicitlyEnabled}, CSIDriverSocketPath: defaultCSIDriverSocketPath, NodeStageTimeout: nodeStageTimeout, NodeUnstageTimeout: nodeUnstageTimeout, FirelensAsyncEnabled: BooleanDefaultTrue{Value: ExplicitlyEnabled}, } } func (cfg *Config) platformOverrides() { cfg.PrometheusMetricsEnabled = utils.ParseBool(os.Getenv("ECS_ENABLE_PROMETHEUS_METRICS"), false) if cfg.PrometheusMetricsEnabled { cfg.ReservedPorts = append(cfg.ReservedPorts, AgentPrometheusExpositionPort) } if cfg.TaskENIEnabled.Enabled() { // when task networking is enabled, eni trunking is enabled by default cfg.ENITrunkingEnabled = parseBooleanDefaultTrueConfig("ECS_ENABLE_HIGH_DENSITY_ENI") } } // platformString returns platform-specific config data that can be serialized // to string for debugging func (cfg *Config) platformString() string { // Returns a string if the default image name/tag of the Pause container has // been overridden if cfg.PauseContainerImageName == DefaultPauseContainerImageName && cfg.PauseContainerTag == DefaultPauseContainerTag { return fmt.Sprintf(", PauseContainerImageName: %s, PauseContainerTag: %s", cfg.PauseContainerImageName, cfg.PauseContainerTag) } return "" } func getConfigFileName() (string, error) { return utils.DefaultIfBlank(os.Getenv("ECS_AGENT_CONFIG_FILE_PATH"), defaultConfigFileName), nil } // Determines and sets IP Compatibility of the container instance. // // Fails back to IPv4-only instance IP compatibility status in case there was an issue // determining the IP compatibility of the container instance. // This is a fallback to help with graceful adoption of Agent in IPv6-only environments // without disrupting existing environments. // // TODO feat:IPv6-only - Remove lint rule below // //lint:ignore U1000 Function will be used in the future func (c *Config) determineIPCompatibility(ec2client ec2.EC2MetadataClient) { // Load primary ENI's MAC address on EC2 Launch Type var primaryENIMAC string if !c.External.Enabled() { logger.Info("Calling IMDS to fetch mac address of the primary ENI") var eniMACFetchErr error primaryENIMAC, eniMACFetchErr = ec2client.PrimaryENIMAC() if eniMACFetchErr != nil { logger.Warn("Failed to fetch primary ENI's mac address from IMDS."+ " Failing back instance IP compatibility to IPv4-only.", logger.Fields{field.Error: eniMACFetchErr}) c.InstanceIPCompatibility = ipcompatibility.NewIPv4OnlyCompatibility() return } } var err error c.InstanceIPCompatibility, err = netutils.DetermineIPCompatibility(nlWrapper, primaryENIMAC) if err != nil { logger.Warn("Failed to determine instance IP compatibility."+ " Failing back instance IP compatibility to IPv4-only.", logger.Fields{field.Error: err}) c.InstanceIPCompatibility = ipcompatibility.NewIPv4OnlyCompatibility() return } logger.Info("Successfully determined IP compatibilty of the container instance", logger.Fields{ "IPv4": c.InstanceIPCompatibility.IsIPv4Compatible(), "IPv6": c.InstanceIPCompatibility.IsIPv6Compatible(), }) }