Como criar uma troca para o Azure Ubuntu VM?

8

Eu li alguns posts sobre isso, mas ainda não tenho certeza sobre a abordagem correta, assumindo:

  1. Eu tenho uma VM LTS Ubuntu 14.04 padrão criada e em execução no Azure, que não vem com uma troca

  2. Eu gostaria de criar uma troca usando o armazenamento de VM existente, em vez de criar um novo disco usando armazenamento adicional

Postagens que li:

Muitas soluções foram discutidas, mas parece que não consigo encontrar uma que persista nas reinicializações do servidor (provavelmente devido ao cloud-init ter sua própria idéia sobre o particionamento de imagens), alguém pode me aconselhar sobre as melhores práticas?

    
por bitinn 31.05.2015 / 11:10

4 respostas

8

Supondo que você tenha o Linux Agent instalado. Tudo o que você precisa fazer é ativar o swap em /etc/waagent.conf. Estas são as linhas relevantes:

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.

Ele usará automaticamente o disco de recursos (fornecido com todas as VMs) para criar a troca. Não há necessidade de criar um disco para isso.

Atualizar : você também precisa executar as etapas abaixo para criar o arquivo de troca:

umount /mnt
service walinuxagent restart
    
por 31.05.2015 / 17:25
2

A resposta de Bruno é um ótimo ponto de partida, mas só funcionou depois que eu reiniciei e dei mais um minuto após a inicialização.

a. Ativar troca em /etc/waagent.conf , linhas relevantes:

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. Faça o seguinte como root, que inclui a reinicialização da sua máquina:

umount /mnt
service walinuxagent restart
reboot

c. Após a inicialização, ainda levará algum tempo até que a troca seja ativada. Você pode verificar com swapon -s .

    
por 23.07.2016 / 00:28
1

Eu acredito que o jeito certo de fazer isso é que tanto o cloud-init quanto o waagent tocam 'legal' juntos (de Documentação do Azure do Cloud-Init ) é manter esses valores configurados como

# 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

Eu tentei alterar o ponto de montagem, mas parece que ele não funcionou corretamente, portanto, os documentos provavelmente são precisos sobre os valores

E então você pode personalizar as opções de troca como quiser

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

# Size of the swapfile.
ResourceDisk.SwapSizeMB=8192

Um reinício básico pega a nova multa de troca

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
    
por 01.06.2017 / 06:42
0

I have read quite a few posts on this, but I am still unsure about the correct approach, assuming: 1. I have a default Ubuntu 14.04 LTS VM created by and running on Azure, which doesn't come with a swap 2. I would like to create a swap using existing VM storage, instead of create a new disk using additional storage

Eu também estava precisando disso (na verdade 16.04 ao invés de 14.04, mas minha resposta será aplicada a ambos, eu acho).

Posts I have read:

Mas quando eu vi que tinha que ler longos ensaios que você apontou, eu ia desistir ... Mas de repente me lembrei de um artigo muito direto no blog da DigitalOcean:

Como adicionar swap no Ubuntu 14.04

É tão simples que eu até escrevi um script para ele (pelo menos para a melhor parte, ainda não as configurações de swappiness e outras coisas avançadas):

#!/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))

Para o acima funcionar, você precisa sudo apt install fsharp primeiro (pelo menos o Ubuntu 16.04 tem fsharp nos repositórios, não tenho certeza sobre 14.04).

Você também precisa deste arquivo InfraTools.fs :

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())

Many solutions were discussed but I can't seem to find one that will persists across server reboots

A parte que faz minha resposta funcionar através de reinicializações do servidor é a gravação no arquivo / etc / fstab.

O bom desta solução é que ela deve funcionar no Azure, DigitalOcean, YouNameIt, ...

Aproveite!

    
por 07.07.2016 / 06:32