Я прочитал довольно много сообщений по этому поводу, но я все еще не уверен в правильном подходе, предполагая:
У меня есть виртуальная машина Ubuntu 14.04 LTS по умолчанию, созданная и работающая в Azure, которая не имеет подкачки
Я хотел бы создать подкачку, используя существующее хранилище виртуальных машин, вместо создания нового диска с использованием дополнительного хранилища
Сообщения, которые я прочитал:
Обсуждались многие решения, но я не могу найти одно, которое будет сохраняться при перезагрузке сервера (вероятно, из-за того, что cloud-init имеет собственное представление о разделении образов), может ли кто-нибудь посоветовать мне лучшую практику?
Предполагая, что у вас установлен агент Linux. Все, что вам нужно сделать, это включить подкачку в /etc/waagent.conf. Это соответствующие строки:
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.
Он автоматически использует ресурсный диск (который поставляется с каждой виртуальной машиной) для создания подкачки. Нет необходимости создавать для этого диск.
Обновить: Вам также необходимо выполнить следующие шаги, чтобы создать файл подкачки:
umount /mnt
service walinuxagent restart
Ответ Бруно - отличная отправная точка, но он сработал только после того, как я перезагрузился и дал ему еще минуту после загрузки.
а. Включить обмен в /etc/waagent.conf
, соответствующие строки:
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.
б. Выполните следующие действия от имени пользователя root, включая перезагрузку компьютера:
umount /mnt
service walinuxagent restart
reboot
c. После загрузки еще потребуется некоторое время, прежде чем своп будет фактически включен. Вы можете проверить это с помощью swapon -s
.
Я считаю, что это правильный способ сделать так, чтобы и cloud-init, и waagent играли "хорошо" вместе (от Документация Cloud-Init по Azure) состоит в том, чтобы оставить эти значения равными этому
# 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
Я попытался изменить точку монтирования, но, похоже, она не сработала должным образом, поэтому документы, вероятно, точны в отношении значений
А затем вы можете настроить параметры обмена по своему усмотрению.
# Create and use swapfile on resource disk.
ResourceDisk.EnableSwap=y
# Size of the swapfile.
ResourceDisk.SwapSizeMB=8192
При простом перезапуске штраф за новый своп
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
Я прочитал довольно много сообщений по этому поводу, но я все еще не уверен в правильном подходе, предполагая: 1. У меня есть виртуальная машина Ubuntu 14.04 LTS по умолчанию, созданная и работающая в Azure, которая не поставляется со свопом 2. Я хотел бы создать подкачку с использованием существующего хранилища виртуальных машин вместо создания нового диска с использованием дополнительного хранилища
Мне тоже это было нужно (на самом деле 16.04 вместо 14.04, но мой ответ, я думаю, применим к обоим).
Сообщения, которые я прочитал:
Но когда я увидел, что мне пришлось читать такие длинные эссе, на которые вы указываете, я собирался сдаться ... Но внезапно я вспомнил очень прямую статью в блоге DigitalOcean:
Как добавить своп в Ubuntu 14.04
Это настолько просто, что я даже написал для него сценарий (по крайней мере, в лучшем случае, пока еще не настройки подкачки и другие дополнительные вещи):
#!/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))
Чтобы вышеуказанное работало, вам необходимо sudo apt install fsharp
сначала (по крайней мере, Ubuntu 16.04 имеет fsharp в репозиториях, не уверен, что насчет 14.04).
Также вам нужно это 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())
Обсуждалось много решений, но я не могу найти одно, которое будет сохраняться при перезагрузке сервера
Часть, которая заставляет мой ответ работать через перезагрузку сервера, - это запись в файл / etc / fstab.
Преимущество этого решения в том, что оно должно работать в Azure, DigitalOcean, YouNameIt, ...
Наслаждайтесь!
Теперь в официальной документации Azure есть инструкции: https://support.microsoft.com/en-us/help/4010058/how-to-add-a-swap-file-in-linux-azure-virtual-machines