Wie erstelle ich einen Swap für Azure Ubuntu VM?

9

Ich habe einige Beiträge dazu gelesen, bin mir aber immer noch nicht sicher, wie ich vorgehen soll, vorausgesetzt:

  1. Ich habe eine Standard-Ubuntu 14.04 LTS-VM, die von Azure erstellt wurde und auf Azure ausgeführt wird und ohne Swap geliefert wird

  2. Ich möchte einen Swap mit vorhandenem VM-Speicher erstellen, anstatt eine neue Festplatte mit zusätzlichem Speicher zu erstellen

Beiträge, die ich gelesen habe:

Viele Lösungen wurden diskutiert, aber ich kann anscheinend keine finden, die auch nach einem Neustart des Servers bestehen bleibt (wahrscheinlich hat Cloud-Init eine eigene Vorstellung von der Image-Partitionierung). Kann mich jemand zu den Best Practices beraten?

Bitinn
quelle

Antworten:

8

Angenommen, Sie haben Linux Agent installiert. Sie müssen lediglich den Austausch unter /etc/waagent.conf aktivieren. Dies sind die relevanten Zeilen:

ResourceDisk.Format=y                   # Format if unformatted. If 'n', resour$
ResourceDisk.Filesystem=ext4            # Typically ext3 or ext4. FreeBSD image$
ResourceDisk.MountPoint=/mnt/resource   #
ResourceDisk.EnableSwap=y               # Create and use swapfile on resource d$
ResourceDisk.SwapSizeMB=2048            # Size of the swapfile.

Es wird automatisch die Ressourcenfestplatte (die mit jeder VM geliefert wird) verwendet, um den Swap zu erstellen. Es ist nicht erforderlich, eine Festplatte dafür zu erstellen.

Update : Sie müssen auch die folgenden Schritte ausführen, um die Auslagerungsdatei zu erstellen:

umount /mnt
service walinuxagent restart
Bruno Faria
quelle
Die Festplattenbereitstellung wird im Gegensatz zu anderen Distributionen von Cloud Init unter Ubuntu gesteuert. Also nein, das sollte nicht funktionieren und sowohl doc als auch mein Test bestätigen es.
Bitinn
2
Ich kontaktierte MS Unterstützung und fand die Lösung zu setzen , ist ResourceDisk.Format, ResourceDisk.EnableSwapund ResourceDisk.SwapSizeMB. ABER der wichtige Schritt ist, ein Handbuch sudo service walinuxagent restartzum Erstellen der Auslagerungsdatei zu erstellen, da nur ein Neustart des Servers für mich nicht funktioniert.
Bitinn
Ich frage immer noch, wie Cloud Init in all das einfließt, weil ihre Kommentare zu doc ​​und waagent.conf irreführend sind.
Bitinn
Jep. Es tut mir Leid. Ich habe vergessen, den Neustart des Agenten einzuschließen. Ich habe auf meinem Ubuntu VM getestet und ohne Probleme gearbeitet. Ich habe die Antwort aktualisiert. In Bezug auf Cloud-Init glaube ich, dass es überhaupt nichts mit der Erstellung der Swap-Datei zu tun hat, da der Agent die Datei in einer ext4-Partition (/ mnt) erstellt. Es wird keine Swap-Partition erstellt.
Bruno Faria
2
Funktionierte nicht mit Ubuntu 14.04 LTS VM, die aus dem Azure Gallery-Image erstellt wurde. Nach dem Ausführen aller Schritte wird swapon -sweiterhin eine leere Liste der Auslagerungsdateien angezeigt.
JustAMartin
2

Brunos Antwort ist ein guter Ausgangspunkt, aber sie hat erst nach dem Neustart funktioniert und nach dem Booten eine weitere Minute gegeben.

ein. Aktivieren Sie das Eintauschen /etc/waagent.confrelevanter Zeilen:

ResourceDisk.Format=y                   # Format if unformatted. If 'n', resour$
ResourceDisk.Filesystem=ext4            # Typically ext3 or ext4. FreeBSD image$
ResourceDisk.MountPoint=/mnt/resource   #
ResourceDisk.EnableSwap=y               # Create and use swapfile on resource d$
ResourceDisk.SwapSizeMB=2048            # Size of the swapfile.

b. Führen Sie als Root Folgendes aus, einschließlich eines Neustarts Ihres Computers:

umount /mnt
service walinuxagent restart
reboot

c. Nach dem Booten dauert es noch einige Zeit, bis der Swap tatsächlich aktiviert ist. Sie können es mit überprüfen swapon -s.

kqw
quelle
1

Ich glaube, der richtige Weg, dies zu tun, damit sowohl Cloud-Init als auch der Waagent 'nett' zusammen spielen (aus Cloud-Init Azure-Dokumenten ), besteht darin, diese Werte auf diesen Wert zu setzen

# disabling provisioning turns off all 'Provisioning.*' function
Provisioning.Enabled=n
# this is currently not handled by cloud-init, so let walinuxagent do it.
ResourceDisk.Format=y
ResourceDisk.MountPoint=/mnt

Ich habe versucht, den Mountpoint zu ändern, aber es schien nicht richtig zu funktionieren, sodass die Dokumente wahrscheinlich genau über die Werte sind

Anschließend können Sie die Swap-Optionen nach Ihren Wünschen anpassen

# Create and use swapfile on resource disk.
ResourceDisk.EnableSwap=y

# Size of the swapfile.
ResourceDisk.SwapSizeMB=8192

Ein grundlegender Neustart nimmt die neue Swap-Geldstrafe auf

sudo service walinuxagent restart

free -m
             total       used       free     shared    buffers     cached
Mem:          3944        882       3061         44         29        163
-/+ buffers/cache:        689       3255
Swap:         8192          0       8192
FearlessHyena
quelle
0

Ich habe einige Beiträge dazu gelesen, bin mir aber immer noch nicht sicher, wie ich vorgehen soll, vorausgesetzt: 1. Ich habe eine Standard-Ubuntu 14.04 LTS-VM, die von Azure erstellt wurde und auf Azure ausgeführt wird und nicht mit einem Swap geliefert wird. 2. I. Sie möchten einen Swap mit vorhandenem VM-Speicher erstellen, anstatt eine neue Festplatte mit zusätzlichem Speicher zu erstellen

Ich brauchte das auch (eigentlich 16.04 statt 14.04, aber meine Antwort gilt meiner Meinung nach für beide).

Beiträge, die ich gelesen habe:

Aber als ich sah, dass ich so lange Essays lesen musste, dass Sie darauf hinweisen, wollte ich aufgeben ... Aber plötzlich erinnerte ich mich an einen sehr einfachen Artikel in DigitalOceans Blog:

So fügen Sie Swap unter Ubuntu 14.04 hinzu

Es ist so einfach, dass ich sogar ein Skript dafür geschrieben habe (zumindest zum größten Teil, noch nicht die Swappiness-Einstellungen und andere fortgeschrittene Dinge):

#!/usr/bin/env fsharpi

open System
open System.IO
open System.Net
open System.Diagnostics

#load "InfraTools.fs"
open Gatecoin.Infrastructure

// automation of https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04

let NUMBER_OF_GB_FOR_SWAP = 1

let isThereSwapMemoryInTheSystem (): bool =
    let _,output,_ = Tools.SafeHiddenExec("swapon", "-s")
    (output.Trim().Length > 0)

if (isThereSwapMemoryInTheSystem()) then
    Console.WriteLine("Swap already setup")
    Environment.Exit(0)

let swapFile = new FileInfo(Path.Combine("/", "swapfile"))
if not (swapFile.Exists) then
    Tools.BailIfNotSudoer("Need to use 'fallocate' to create swap file")
    Console.WriteLine("Creating swap file...")
    Tools.SafeExec("fallocate", String.Format("-l {0}G {1}", NUMBER_OF_GB_FOR_SWAP, swapFile.FullName), true)

let permissionsForSwapFile = 600
if not (Tools.OctalPermissions(swapFile) = permissionsForSwapFile) then
    Tools.BailIfNotSudoer("Need to adjust permissions of the swap file")
    Tools.SafeExec("chmod", String.Format("{0} {1}", permissionsForSwapFile, swapFile.FullName), true)

Tools.BailIfNotSudoer("Enable swap memory")
Tools.SafeExec("mkswap", swapFile.FullName, true)
Tools.SafeExec("swapon", swapFile.FullName, true)
if not (isThereSwapMemoryInTheSystem()) then
    Console.WriteLine("Something went wrong while enabling the swap file")
    Environment.Exit(1)

Tools.BailIfNotSudoer("Writing into /etc/fstab")
Tools.SafeHiddenExecBashCommand(String.Format("echo \"{0}   none    swap    sw    0   0\" >> /etc/fstab", swapFile.FullName))

Damit das oben genannte funktioniert, müssen Sie sudo apt install fsharpzuerst (mindestens Ubuntu 16.04 hat fsharp in den Repositories, nicht sicher über 14.04).

Außerdem benötigen Sie diese InfraTools.fsDatei:

open System
open System.IO
open System.Net

namespace Gatecoin.Infrastructure

module Tools =

    let HiddenExec (command: string, arguments: string) =
        let startInfo = new System.Diagnostics.ProcessStartInfo(command)
        startInfo.Arguments <- arguments
        startInfo.UseShellExecute <- false

        // equivalent to `>/dev/null 2>&1` in unix
        startInfo.RedirectStandardError <- true
        startInfo.RedirectStandardOutput <- true

        use proc = System.Diagnostics.Process.Start(startInfo)
        proc.WaitForExit()
        (proc.ExitCode,proc.StandardOutput.ReadToEnd(),proc.StandardError.ReadToEnd())

    let HiddenExecBashCommand (commandWithArguments: string) =
        let args = String.Format("-c \"{0}\"", commandWithArguments.Replace("\"", "\\\""))
        HiddenExec("bash", args)

    let SafeHiddenExecBashCommand (commandWithArguments: string) =
        let exitCode,stdOut,stdErr = HiddenExecBashCommand commandWithArguments
        if not (exitCode = 0) then
            Console.Error.WriteLine(stdErr)
            Console.Error.WriteLine()
            Console.Error.WriteLine("Bash command '{0}' failed with exit code {1}.", commandWithArguments, exitCode.ToString())
            Environment.Exit(1)
        exitCode,stdOut,stdErr

    let Exec (command: string, arguments: string, echo: bool) =
        let psi = new System.Diagnostics.ProcessStartInfo(command)
        psi.Arguments <- arguments
        psi.UseShellExecute <- false
        if (echo) then
            Console.WriteLine("{0} {1}", command, arguments)
        let p = System.Diagnostics.Process.Start(psi)
        p.WaitForExit()
        p.ExitCode

    let ExecBashCommand (commandWithArguments: string, echo: bool) =
        let args = String.Format("-c \"{0}\"", commandWithArguments.Replace("\"", "\\\""))
        if (echo) then
            Console.WriteLine(commandWithArguments)
        Exec("bash", args, false)

    let SafeHiddenExec (command: string, arguments: string) =
        let exitCode,stdOut,stdErr = HiddenExec(command, arguments)
        if not (exitCode = 0) then
            Console.Error.WriteLine(stdErr)
            Console.Error.WriteLine()
            Console.Error.WriteLine("Command '{0}' failed with exit code {1}. Arguments supplied: '{2}'", command, exitCode.ToString(), arguments)
            Environment.Exit(1)
        exitCode,stdOut,stdErr

    let SafeExec (command: string, arguments: string, echo: bool) =
        let exitCode = Exec(command, arguments, echo)
        if not (exitCode = 0) then
            Console.Error.WriteLine("Command '{0}' failed with exit code {1}. Arguments supplied: '{2}'", command, exitCode.ToString(), arguments)
            Environment.Exit(1)
            failwith "unreached"
        ()

    let SafeExecBashCommand (commandWithArguments: string, echo: bool) =
        let args = String.Format("-c \"{0}\"", commandWithArguments.Replace("\"", "\\\""))
        if (echo) then
            Console.WriteLine(commandWithArguments)
        SafeExec("bash", args, false)

    let FirstElementOf3Tuple (a, _, _) = a
    let SecondElementOf3Tuple (_, b, _) = b

    let SimpleStringSplit (str: string, separator: string): string list =
        List.ofSeq(str.Split([|separator|], StringSplitOptions.RemoveEmptyEntries))

    let SplitStringInLines (str: string): string list =
        SimpleStringSplit(str,Environment.NewLine)

    let CommandWorksInShell (command: string): bool =
        let exitCode =
            try
                Some(FirstElementOf3Tuple(HiddenExec(command,String.Empty))
            with
                | :? System.ComponentModel.Win32Exception -> (); None
        if exitCode.IsNone then
            false
        else
            true

    let BailIfNotSudoer(reason: string): unit =   
        if not (CommandWorksInShell "id") then
            Console.WriteLine ("'id' unix command is needed for this script to work")
            Environment.Exit(2)
            ()

        let _,idOutput,_ = HiddenExec("id","-u")
        if not (idOutput.Trim() = "0") then
            Console.Error.WriteLine ("Error: needs sudo privilege. Reason: {0}", reason)
            Environment.Exit(3)
            ()
        ()

    let OctalPermissions (file: FileInfo): int =
        let output = SecondElementOf3Tuple(SafeHiddenExec("stat", String.Format("-c \"%a\" {0}", file.FullName)))
        Int32.Parse(output.Trim())

Viele Lösungen wurden diskutiert, aber ich kann anscheinend keine finden, die auch nach einem Neustart des Servers bestehen bleibt

Der Teil, der meine Antwort durch Serverneustarts funktioniert, ist das Schreiben in die Datei / etc / fstab.

Das Gute an dieser Lösung ist, dass sie in Azure, DigitalOcean, YouNameIt, ... funktionieren sollte.

Genießen!

knocte
quelle
2
"Es ist so einfach", gefolgt von 50 Codezeilen, scheint ein Oxymoron zu sein!
kqw