Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

feat: configurable unattended-upgrades #4614

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/topics/clusterdefinitions.md
Expand Up @@ -863,6 +863,7 @@ A cluster can have 0 to 12 agent pool profiles. Agent Pool Profiles are used for
| adminUsername | yes | Describes the username to be used on all linux clusters |
| ssh.publicKeys[].keyData | yes | The public SSH key used for authenticating access to all Linux nodes in the cluster |
| secrets | no | Specifies an array of key vaults to pull secrets from and what secrets to pull from each |
| enableUnattendedUpgrades | no (will be required in a future release) | Configure each Linux node VM (including control plane node VMs) to run `/usr/bin/unattended-upgrade` in the background according to a daily schedule. If enabled, the default `unattended-upgrades` package configuration will be used as provided by the Ubuntu distro version running on the VM. More information [here](https://help.ubuntu.com/community/AutomaticSecurityUpdates). By default, `enableUnattendedUpgrades` is set to `true`. We encourage you to declare an explicit configuration for `enableUnattendedUpgrades` and a warning will be logged if you do not. In a future release of `aks-engine`, we may default this to `false`, requiring the user to self-maintain OS package and security updates. |
| runUnattendedUpgradesOnBootstrap | no | Invoke an unattended-upgrade when each Linux node VM comes online for the first time. In practice this is accomplished by performing an `apt-get update`, followed by a manual invocation of `/usr/bin/unattended-upgrade`, to fetch updated apt configuration, and install all package updates provided by the unattended-upgrade facility, respectively. Defaults to true for public Azure clouds, and to false for Azure Stack Hub and other non-public, custom cloud environments. |
| customSearchDomain.name | no | describes the search domain to be used on all linux clusters |
| customSearchDomain.realmUser | no | describes the realm user with permissions to update dns registries on Windows Server DNS |
Expand Down
Expand Up @@ -98,6 +98,7 @@
}
],
"linuxProfile": {
"enableUnattendedUpgrades": false,
"adminUsername": "azureuser",
"ssh": {
"publicKeys": [
Expand Down
4 changes: 2 additions & 2 deletions parts/k8s/cloud-init/artifacts/cse_config.sh
Expand Up @@ -394,7 +394,7 @@ ensureKubelet() {
if [[ -n ${MASTER_NODE} ]]; then
systemctlEnableAndStart kubelet || exit {{GetCSEErrorCode "ERR_KUBELET_START_FAIL"}}
else
{{- if not RunUnattendedUpgrades}}
{{- if not RunUnattendedUpgradesOnBootstrap}}
systemctlEnableAndStart kubelet || exit {{GetCSEErrorCode "ERR_KUBELET_START_FAIL"}}
{{else}}
systemctl_enable 100 5 30 kubelet || exit {{GetCSEErrorCode "ERR_KUBELET_START_FAIL"}}
Expand All @@ -405,7 +405,7 @@ ensureKubelet() {
if [[ -n ${MASTER_NODE} ]]; then
systemctlEnableAndStart kubelet-monitor || exit {{GetCSEErrorCode "ERR_KUBELET_START_FAIL"}}
else
{{- if not RunUnattendedUpgrades}}
{{- if not RunUnattendedUpgradesOnBootstrap}}
systemctlEnableAndStart kubelet-monitor || exit {{GetCSEErrorCode "ERR_KUBELET_START_FAIL"}}
{{else}}
systemctl_enable 100 5 30 kubelet-monitor || exit {{GetCSEErrorCode "ERR_KUBELET_START_FAIL"}}
Expand Down
6 changes: 4 additions & 2 deletions parts/k8s/cloud-init/artifacts/cse_main.sh
Expand Up @@ -273,7 +273,9 @@ fi
{{end}}

{{- /* re-enable unattended upgrades */}}
{{- if EnableUnattendedUpgrades}}
rm -f /etc/apt/apt.conf.d/99periodic
{{- end}}

{{- if not IsAzureStackCloud}}
if [[ $OS == $UBUNTU_OS_NAME ]]; then
Expand All @@ -282,7 +284,7 @@ fi
{{end}}

{{- if not HasBlockOutboundInternet}}
{{- if RunUnattendedUpgrades}}
{{- if RunUnattendedUpgradesOnBootstrap}}
apt_get_update && unattended_upgrade
{{- end}}
{{- end}}
Expand All @@ -294,7 +296,7 @@ if [ -f /var/run/reboot-required ]; then
aptmarkWALinuxAgent unhold &
fi
else
{{- if RunUnattendedUpgrades}}
{{- if RunUnattendedUpgradesOnBootstrap}}
if [[ -z ${MASTER_NODE} ]]; then
systemctl_restart 100 5 30 kubelet
systemctl_restart 100 5 30 kubelet-monitor
Expand Down
4 changes: 4 additions & 0 deletions pkg/api/const.go
Expand Up @@ -223,6 +223,10 @@ const (
StandardVMType = "standard"
// DefaultRunUnattendedUpgradesOnBootstrap sets the default configuration for running a blocking unattended-upgrade on Linux VMs as part of CSE
DefaultRunUnattendedUpgradesOnBootstrap = true
// DefaultEnableUnattendedUpgrades sets the default configuration for running unattended-upgrade on a regular schedule in the background
DefaultEnableUnattendedUpgrades = true
// DefaultEnableUnattendedUpgradesAzureStack sets the default configuration for running unattended-upgrade on a regular schedule in the background for Azure Stack Hub
DefaultEnableUnattendedUpgradesAzureStack = true
jackfrancis marked this conversation as resolved.
Show resolved Hide resolved
// DefaultEth0MTU is the default MTU configuration for eth0 Linux interfaces
DefaultEth0MTU = 1500
)
Expand Down
7 changes: 7 additions & 0 deletions pkg/api/defaults.go
Expand Up @@ -703,6 +703,13 @@ func (p *Properties) setLinuxProfileDefaults() {
if !p.IsAzureStackCloud() && p.LinuxProfile.RunUnattendedUpgradesOnBootstrap == nil {
p.LinuxProfile.RunUnattendedUpgradesOnBootstrap = to.BoolPtr(DefaultRunUnattendedUpgradesOnBootstrap)
}
if p.LinuxProfile.EnableUnattendedUpgrades == nil {
if p.IsAzureStackCloud() {
p.LinuxProfile.EnableUnattendedUpgrades = to.BoolPtr(DefaultEnableUnattendedUpgradesAzureStack)
} else {
p.LinuxProfile.EnableUnattendedUpgrades = to.BoolPtr(DefaultEnableUnattendedUpgrades)
}
}
if p.OrchestratorProfile.IsAzureCNI() && p.LinuxProfile.Eth0MTU == 0 {
p.LinuxProfile.Eth0MTU = DefaultEth0MTU
}
Expand Down
1 change: 1 addition & 0 deletions pkg/api/types.go
Expand Up @@ -140,6 +140,7 @@ type LinuxProfile struct {
CustomNodesDNS *CustomNodesDNS `json:"CustomNodesDNS,omitempty"`
IsSSHKeyAutoGenerated *bool `json:"isSSHKeyAutoGenerated,omitempty"`
RunUnattendedUpgradesOnBootstrap *bool `json:"runUnattendedUpgradesOnBootstrap,omitempty"`
EnableUnattendedUpgrades *bool `json:"enableUnattendedUpgrades,omitempty"`
Eth0MTU int `json:"eth0MTU,omitempty"`
}

Expand Down
1 change: 1 addition & 0 deletions pkg/api/vlabs/types.go
Expand Up @@ -140,6 +140,7 @@ type LinuxProfile struct {
CustomSearchDomain *CustomSearchDomain `json:"customSearchDomain,omitempty"`
CustomNodesDNS *CustomNodesDNS `json:"customNodesDNS,omitempty"`
RunUnattendedUpgradesOnBootstrap *bool `json:"runUnattendedUpgradesOnBootstrap,omitempty"`
EnableUnattendedUpgrades *bool `json:"enableUnattendedUpgrades,omitempty"`
Eth0MTU int `json:"eth0MTU,omitempty"`
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/api/vlabs/validate.go
Expand Up @@ -650,6 +650,9 @@ func (a *Properties) validateLinuxProfile() error {
return errors.New("KeyData in LinuxProfile.SSH.PublicKeys cannot be empty string")
}
}
if a.LinuxProfile.EnableUnattendedUpgrades == nil {
log.Warnf("linuxProfile.enableUnattendedUpgrades configuration was not declared, your cluster nodes will be configured to run unattended-upgrade by default")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make the warning message scarier and add something about the impact, ie. this can lead to downtime if a bad patch is applied to all your nodes at once.

}
return validateKeyVaultSecrets(a.LinuxProfile.Secrets, false)
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/api/vlabs/validate_test.go
Expand Up @@ -998,6 +998,24 @@ func ExampleProperties_validateAddons() {
// level=warning msg="The Azure CNI networkmonitor addon has been deprecated, it will be marked as disabled"
}

func ExampleProperties_validateLinuxProfile() {
log.SetOutput(os.Stdout)
log.SetFormatter(&log.TextFormatter{
DisableColors: true,
DisableTimestamp: true,
})
p := Properties{
LinuxProfile: &LinuxProfile{},
}

if err := p.validateLinuxProfile(); err != nil {
fmt.Printf("error in validateLinuxProfile: %s", err)
}

// Output:
// level=warning msg="linuxProfile.enableUnattendedUpgrades configuration was not declared, your cluster nodes will be configured to run unattended-upgrade by default"
}

func Test_Properties_ValidateNetworkPlugin(t *testing.T) {
p := &Properties{}
p.OrchestratorProfile = &OrchestratorProfile{}
Expand Down
8 changes: 7 additions & 1 deletion pkg/engine/template_generator.go
Expand Up @@ -802,12 +802,18 @@ version = 2
"GetLinuxCSELogPath": func() string {
return linuxCSELogPath
},
"RunUnattendedUpgrades": func() bool {
"RunUnattendedUpgradesOnBootstrap": func() bool {
if cs.Properties.LinuxProfile != nil {
return to.Bool(cs.Properties.LinuxProfile.RunUnattendedUpgradesOnBootstrap)
}
return false
},
"EnableUnattendedUpgrades": func() bool {
if cs.Properties.LinuxProfile != nil {
return to.Bool(cs.Properties.LinuxProfile.EnableUnattendedUpgrades)
}
return false
},
"GetEth0MTU": func() int {
if cs.Properties.LinuxProfile != nil {
return cs.Properties.LinuxProfile.Eth0MTU
Expand Down
10 changes: 6 additions & 4 deletions pkg/engine/templates_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.