@ -61,13 +61,13 @@ GRUB — это загрузчик, используемый в большинс
## Установка GRUB 2
## Установка GRUB 2
GRUB 2 можно установить с помощью утилиты grub-install. Если у вас незагружающаяся система, вам нужно будет загрузиться с Live CD или аварийного диска, узнать, какой раздел является загрузочным для вашей системы, смонтировать его и затем запустить утилиту.
GRUB 2 можно установить с помощью утилиты grub-install. Если у вас система не загружается, вам нужно будет загрузиться с Live CD или аварийного диска, узнать, какой раздел является загрузочным для вашей системы, смонтировать его и затем запустить утилиту.
## Примечание
## Примечание
Приведенные ниже команды предполагают, что вы вошли в систему как root. Если нет, сначала запустите `sudo su — `чтобы «стать» root. Когда закончите, введите exit, чтобы выйти из системы и вернуться к обычному пользователю.
Приведенные ниже команды предполагают, что вы вошли в систему как root. Если нет, сначала запустите `sudo su — `чтобы «стать» root. Когда закончите, введите exit, чтобы выйти из системы и вернуться к обычному пользователю.
Первый диск в системе обычно является загрузочным устройством, и вам может понадобиться узнать, есть ли на диске загрузочный раздел. Это можно сделать с помощью утилиты fdisk. Чтобы вывести список всех разделов на первом диске вашей машины, используйте:
Первый диск в системе обычно является загрузочным устройством, и вам может понадобиться узнать, есть ли на диске загрузочный раздел. Это можно сделать с помощью утилиты `fdisk`. Чтобы вывести список всех разделов на первом диске вашей машины, используйте:
```
```
# fdisk -l /dev/sda
# fdisk -l /dev/sda
@ -148,12 +148,12 @@ Device Boot Start End Sectors Size Id Type
```
```
пункт меню "ОС по умолчанию" {
пункт меню "ОС по умолчанию" {
установить корень = (hd0,1)
установить корень = (hd0,1)
linux /vmlinuz root=/dev/sda1 ro тихий всплеск
linux /vmlinuz root=/dev/sda1 ro quiet splash
initrd /initrd.img
initrd /initrd.img
}
}
```
```
Первая строка всегда начинается с menuentry и заканчивается {. Текст между кавычками будет отображаться как метка входа в меню загрузки GRUB 2.
Первая строка всегда начинается с`menuentry` и заканчивается `{`. Текст между кавычками будет отображаться как метка входа в меню загрузки GRUB 2.
Параметр set root определяет диск и раздел, где находится корневая файловая система операционной системы. Обратите внимание, что в GRUB 2 диски нумеруются с нуля, поэтому hd0 является первым диском.
Параметр set root определяет диск и раздел, где находится корневая файловая система операционной системы. Обратите внимание, что в GRUB 2 диски нумеруются с нуля, поэтому hd0 является первым диском.
В приведенном выше примере UUID для /dev/sda1 — это ae71b214-0aec-48e8-80b2-090b6986b625. Если вы хотите установить его в качестве корневого устройства для GRUB 2, введите команду search --set=root --fs-uuid ae71b214-0aec-48e8-80b2-090b6986b625.
В приведенном выше примере UUID для /`dev/sda1` — это `ae71b214-0aec-48e8-80b2-090b6986b625`. Если вы хотите установить его в качестве корневого устройства для GRUB 2, введите команду
При использовании команды поиска обычно добавляется параметр --no-floppy, чтобы GRUB не тратил время на поиск на гибких дисках.
При использовании команды поиска обычно добавляется параметр `--no-floppy`, чтобы GRUB не тратил время на поиск на гибких дисках.
Строка linux указывает, где находится ядро для операционной системы (в данном случае это файл vmlinuz в корне файловой системы). После этого вы можете передать параметры командной строки ядру.
Строка linux указывает, где находится ядро для операционной системы (в данном случае это файл vmlinuz в корне файловой системы). После этого вы можете передать параметры командной строки ядру.
В приведенном выше примере мы указали корневой раздел (root=/dev/sda1) и передали три параметра ядра: корневой раздел должен быть смонтирован только для чтения (ro), большинство сообщений журнала должны быть отключены (quiet) и заставка. экран должен быть показан (заставка).
В приведенном выше примере мы указали корневой раздел (`root=/dev/sda1`) и передали три параметра ядра: корневой раздел должен быть смонтирован только для чтения (`ro`), большинство сообщений журнала должны быть отключены (`quiet`) и экран заставки должен быть показан (`splash`).
Строка initrd указывает, где находится начальный RAM-диск. В приведенном выше примере это файл initrd.img, расположенный в корне файловой системы.
Строка `initrd` указывает, где находится начальный RAM-диск. В приведенном выше примере это файл `initrd.img`, расположенный в корне файловой системы.
Большинство дистрибутивов Linux на самом деле не помещают ядро и initrd в корневой каталог корневой файловой системы. Вместо этого это ссылки на реальные файлы внутри каталога или раздела /boot.
Большинство дистрибутивов Linux на самом деле не помещают ядро и `initrd` в корневой каталог корневой файловой системы. Вместо этого это ссылки на реальные файлы внутри каталога или раздела `/boot`.
Последняя строка пункта меню должна содержать только символ }.
Последняя строка пункта меню должна содержать только символ `}`.
После редактирования параметра нажмите Ctrl+X или F10 для загрузки или Esc, чтобы вернуться в меню.
После редактирования параметра нажмите Ctrl+X или F10 для загрузки или Esc, чтобы вернуться в меню.
Чтобы войти в оболочку GRUB 2, нажмите C на экране меню (или Ctrl+C) в окне редактирования). Вы увидите командную строку, подобную этой: grub >
Чтобы войти в оболочку GRUB 2, нажмите C на экране меню (или Ctrl+C) в окне редактирования). Вы увидите командную строку, подобную этой:
```
grub >
```
Введите help, чтобы увидеть список всех доступных команд, или нажмите Esc, чтобы выйти из оболочки и вернуться на экран меню.
Введите `help`, чтобы увидеть список всех доступных команд, или нажмите Esc, чтобы выйти из оболочки и вернуться на экран меню.
Помните, что это меню не появится, если для GRUB_TIMEOUT установлено значение 0 в /etc/default/grub.
Помните, что это меню не появится, если для `GRUB_TIMEOUT` установлено значение 0 в `/etc/default/grub`.
## Загрузка из оболочки GRUB 2
## Загрузка из оболочки GRUB 2
@ -211,36 +217,36 @@ grub> ls
(proc) (hd0) (hd0,msdos1)
(proc) (hd0) (hd0,msdos1)
```
```
В приведенном выше примере все просто. Есть только один диск (hd0) с одним разделом на нем: (hd0,msdos1).
В приведенном выше примере все просто. Есть только один диск (`hd0`) с одним разделом на нем: `(hd0,msdos1)`.
Перечисленные диски и разделы в вашей системе будут другими. В нашем примере первый раздел hd0 называется msdos1, потому что диск был разбит с использованием схемы разбиения MBR. Если бы он был разделен с использованием GPT, имя было бы gpt1.
Перечисленные диски и разделы в вашей системе будут другими. В нашем примере первый раздел `hd0` называется `msdos1`, потому что диск был разбит с использованием схемы разбиения MBR. Если бы он был разделен с использованием GPT, имя было бы gpt1.
Для загрузки Linux нам понадобится ядро и начальный RAM-диск (initrd). Проверим содержимое (hd0,msdos1):
Для загрузки Linux нам понадобится ядро и начальный RAM-диск (`initrd`). Проверим содержимое `(hd0,msdos1)`:
Вы можете добавить параметр -l к ls, чтобы получить длинный список, аналогичный тому, что вы получили бы на терминале Linux. Используйте Tab для автозаполнения имен дисков, разделов и файлов.
Вы можете добавить параметр `-l` к `ls`, чтобы получить длинный список, аналогичный тому, что вы получили бы на терминале Linux. Используйте Tab для автозаполнения имен дисков, разделов и файлов.
Обратите внимание, что у нас есть образы ядра (vmlinuz) и initrd (initrd.img) прямо в корневом каталоге. Если нет, мы можем проверить содержимое /boot с помощью list (hd0,msdos1)/boot/.
Обратите внимание, что у нас есть образы ядра (`vmlinuz`) и initrd (`initrd.img`) прямо в корневом каталоге. Если нет, мы можем проверить содержимое `/boot`с помощью list` (hd0,msdos1)/boot/`.
Теперь установите загрузочный раздел:
Теперь установите загрузочный раздел:
```
```
grub> set root=(hd0,msdos1)
grub> set root=(hd0,msdos1)
```
```
Загрузите ядро Linux с помощью команды linux, за которой следует путь к ядру и параметр root=, чтобы сообщить ядру, где находится корневая файловая система для операционной системы.
Загрузите ядро Linux с помощью команды linux, за которой следует путь к ядру и параметр `root=`, чтобы сообщить ядру, где находится корневая файловая система для операционной системы.
```
```
grub> linux /vmlinuz root=/dev/sda1
grub> linux /vmlinuz root=/dev/sda1
```
```
Загрузите исходный RAM-диск с помощью initrd, а затем укажите полный путь к файлу initrd.img:
Загрузите исходный RAM-диск с помощью `initrd`, а затем укажите полный путь к файлу `initrd.img`:
```
```
grub> initrd /initrd.img
grub> initrd /initrd.img
```
```
Теперь загрузите систему с помощью boot.
Теперь загрузите систему с помощью `boot`.
## Загрузка из Rescue Shell
## Загрузка из Rescue Shell
@ -250,7 +256,7 @@ grub> initrd /initrd.img
Процесс загрузки системы из этой оболочки почти такой же, как показано выше. Однако вам нужно будет загрузить несколько модулей GRUB 2, чтобы все заработало.
Процесс загрузки системы из этой оболочки почти такой же, как показано выше. Однако вам нужно будет загрузить несколько модулей GRUB 2, чтобы все заработало.
Узнав, какой раздел является загрузочным (с помощью ls, как показано ранее), используйте команду set prefix=, за которой следует полный путь к каталогу, содержащему файлы GRUB 2. Обычно /boot/grub. В нашем примере:
Узнав, какой раздел является загрузочным (с помощью ls, как показано ранее), используйте команду `set prefix=`, за которой следует полный путь к каталогу, содержащему файлы GRUB 2. Обычно `/boot/grub`. В нашем примере:
```
```
grub rescue> set prefix=(hd0,msdos1)/boot/grub
grub rescue> set prefix=(hd0,msdos1)/boot/grub
```
```
@ -261,4 +267,4 @@ grub rescue> insmod normal
grub rescue> insmod linux
grub rescue> insmod linux
```
```
Затем установите загрузочный раздел с помощью set root=, как было указано ранее, загрузите ядро Linux (с помощью linux), начальный RAM-диск (initrd) и попробуйте загрузиться с загрузкой.
Затем установите загрузочный раздел с помощью `set root=`, как было указано ранее, загрузите ядро Linux (с помощью linux), начальный RAM-диск (`initrd`) и попробуйте загрузиться с загрузкой.
Проделайте аналогичные инструкции для создания raid 1 (дублирование записи) на 2-х следующих дисках по 0.1ГБ.
Проделайте аналогичные инструкции для создания raid 1 (дублирование записи) на 2-х следующих дисках по 0.1ГБ.
Загрузите в gparted live диск. Запишите из меню `Device` таблицу разметки типа GPT на каждый диск. Создайте по одному неотформатированному разделу на дисках.
Загрузите в gparted live диск. Запишите из меню `Device` таблицу разметки типа GPT на каждый диск. Создайте по одному неотформатированному разделу на дисках.
Примечание. Если вы используете сырые диски без разметки, заменять диски можно только на идентичного размера диск. Предвариательная разметка диска позволяет заменить диск на диск большего размера, при сохранении размеров разделов.
Примечание. Если вы используете сырые диски без разметки, заменять диски можно только на идентичного размера диск. Предварительная разметка диска позволяет заменить диск на диск большего размера, при сохранении размеров разделов.
Примонтируйте сконфигурированный raid в `fstab`, используя метку файловой системы.
Примонтируйте сконфигурированный raid в `fstab`, используя метку файловой системы.
@ -64,7 +64,7 @@ mdadm /dev/md0 --re-add /dev/sdd
Вы можете управлять LVM либо с помощью большой группы простых команд (перечисленных в таблице 1), либо с помощью одной команды lvm и ее различных подкоманд. Отдельные команды — это просто ссылки на lvm.
Вы можете управлять LVM либо с помощью большой группы простых команд (перечисленных в таблице 1), либо с помощью одной команды lvm и ее различных подкоманд. Отдельные команды — это просто ссылки на lvm.
`man lvm` — хорошее введение в систему и ее инструменты.
`man lvm` — хорошее введение в систему и её инструменты.
Таблица1. Команды LVM
Таблица1. Команды LVM
| Сущность | Команды |
| Сущность | Команды |
@ -85,7 +85,7 @@ mdadm /dev/md0 --re-add /dev/sdd
### 2.2
### 2.2
Создайте логический диск с дублированием данных (аналог raid 1). Используйте параметры `--mirrors` и `--type`.
Создайте логический диск с дублированием данных (аналог raid 1). Используйте параметры `--mirrors` и `--type`.
Для созданных сущностей выведити свойства командами `pvdisplay`, `vgdisplay`, `lvdisplay`.
Для созданных сущностей выведите свойства командами `pvdisplay`, `vgdisplay`, `lvdisplay`.
## 3. Интегрированные подходы к управлению хранилищем btrfs и zfs
## 3. Интегрированные подходы к управлению хранилищем btrfs и zfs
Вы установили утилиты для работы с selinux, политики по-умолчанию, созданные для популярных пакетов и демон для логирования критичных с точки зрения безопасности системных событий. Активировали selinux, собрав модули политик по-умолчанию и добавив параметры запуска с selinux в grub.
Вы установили утилиты для работы с selinux, политики по-умолчанию, созданные для популярных пакетов и демон для логирования критичных с точки зрения безопасности системных событий. Активировали selinux, собрав модули политик по-умолчанию и добавив параметры запуска с selinux в grub.
После перезагрузки проверьте, что selinux активирован. Все процессы и файлы помечены контекстом SELinux. Контекст содержит информацию, необходимую SELinux для принятия решений по управлению доступом. Контекст это поля: пользователь, роль, домен(тип), чувствительность (степень секретности). Современная реализация SELinux хранит контекст безопасности в атрибутах `xattrs`. Для установки этих атрибутов в файловой системе может потребоваться какое-то время.
После перезагрузки проверьте, что selinux активирован. Все процессы и файлы помечены контекстом SELinux. Контекст содержит информацию, необходимую SELinux для принятия решений по управлению доступом. Контекст это поля: пользователь, роль, домен(тип), чувствительность (степень секретности). Современная реализация SELinux хранит контекст безопасности в атрибутах `xattrs`. Для установки этих атрибутов в файловой системе может потребоваться какое-то время.
Теперь сгенерируем автоматически структуру политики SELinux. Научимся обрабатывать сообщения AVC, которые генерируются SELinux, когда приложение нарушает политику.
Теперь сгенерируем автоматически структуру политики SELinux. Научимся обрабатывать сообщения AVC, которые генерируются SELinux, когда приложение нарушает политику.
### 4.1 Сгенерируйте шаблон политики SELinux
### 4.1 Сгенерируйте шаблон политики SELinux
Создайте каталог-проект политики и сгенерируйте в нём шаблонные файлы политики с помощью комадны `sepolicy generate`.
Создайте каталог-проект политики и сгенерируйте в нём шаблонные файлы политики с помощью команды `sepolicy generate`.
Настройте nginx в high available конфигурации с помощью модуля nginx - `ngx_http_upstream_module`. Сконфигурируйте nginx на трёх виртуальных машинах. Для тестировани используйте машину отличную от этих трёх.
Настройте nginx в high available конфигурации с помощью модуля nginx - `ngx_http_upstream_module`. Сконфигурируйте nginx на трёх виртуальных машинах. Для тестировании используйте машину отличную от этих трёх.
Пример конфигурации 1:
Пример конфигурации 1:
```
```
@ -155,7 +155,7 @@ fi
```
```
## 2.4
## 2.4
Проверьте работоспособность сайта по адресу `http://IP` (IP - virtual IP или соответствующему ему белому IP по адресу) для случаев когда `nginx 3` и `nginx 4` виртуальные машины включены, отключена основная, отключена резервная. Выведите информацию о назначенных IP для сетевых интерфесов для каждого случая.
Проверьте работоспособность сайта по адресу `http://IP` (IP - virtual IP или соответствующему ему белому IP по адресу) для случаев когда `nginx 3` и `nginx 4` виртуальные машины включены, отключена основная, отключена резервная. Выведите информацию о назначенных IP для сетевых интерфейсов для каждого случая.
@ -153,7 +153,7 @@ INNER JOIN departments d ON (e.department_id = d.department_id);
### 4.2 Левые внешние соединения (left outer join)
### 4.2 Левые внешние соединения (left outer join)
При использовании механизма `LEFT OUTER JOIN` из левой таблицы вернуться все строки, и если справа не найдётся соответсвия, то в столбцах правой таблицы вместо значений будет присутствовать `NULL`.
При использовании механизма `LEFT OUTER JOIN` из левой таблицы вернуться все строки, и если справа не найдётся соответствия, то в столбцах правой таблицы вместо значений будет присутствовать `NULL`.
В базе данных, с которой мы работаем младшие сотрудники зависят от старших. Ниже приведена схема третьей таблицы `dependents`, которая фиксирует эти отношения.
В базе данных, с которой мы работаем младшие сотрудники зависят от старших. Ниже приведена схема третьей таблицы `dependents`, которая фиксирует эти отношения.
@ -246,14 +246,14 @@ FROM employees e LEFT OUTER JOIN employees m ON (e.manager_id = m.employee_id);
## 5. Транзакции
## 5. Транзакции
Транзакия - это набор действий, которые выполняются атомарно для внешнего наблюдателя. Если часть действий выполнится не может, откатываются все изменения транзакции.
Транзакция - это набор действий, которые выполняются атомарно для внешнего наблюдателя. Если часть действий выполнится не может, откатываются все изменения транзакции.
Использование транзакций СУБД позволяет уменьшить количество кода необходимого для работы с данными. Если бы СУБД не управляли состоянием транзакций, тогда управляющий код пришлось бы реализовывать в каждом приложении, что усложняло бы код и приводило к ошибкам. Например, представьте типичную ситуацию регистрации пользователя в системе. На уровне приложения вам пришлось бы выполнить следующие действия:
Использование транзакций СУБД позволяет уменьшить количество кода необходимого для работы с данными. Если бы СУБД не управляли состоянием транзакций, тогда управляющий код пришлось бы реализовывать в каждом приложении, что усложняло бы код и приводило к ошибкам. Например, представьте типичную ситуацию регистрации пользователя в системе. На уровне приложения вам пришлось бы выполнить следующие действия:
1. Создать пользователя
1. Создать пользователя
2. Проверить, что он создан. Если не создан, завершить процесс с ошибкой.
2. Проверить, что он создан. Если не создан, завершить процесс с ошибкой.
3. Создать аккаунт.
3. Создать аккаунт.
4. Проверить, что он создан. Если не создан, удалить пользователя, завершить процесс с ошибкой.
4. Проверить, что он создан. Если не создан, удалить пользователя, завершить процесс с ошибкой.
5. Соединить аккаунт и ползьзователя.
5. Соединить аккаунт и пользователя.
6. Проверить, что соединение создано. Если не создано, удалить пользователя и аккаунт, завершить процесс с ошибкой.
6. Проверить, что соединение создано. Если не создано, удалить пользователя и аккаунт, завершить процесс с ошибкой.
С механизмом транзакций количество шагов уменьшается в 2 раза:
С механизмом транзакций количество шагов уменьшается в 2 раза:
@ -57,7 +57,7 @@ Docker это самый известный инструмент, который
### 3. Образы
### 3. Образы
Образ - это шаблон для будущих контейнеров. Образы контейнеров представляют из себя многоуровненвые файловые системы. Структура каталога и расположение бинарных файлов, библиотек, конфигурационных файлов соответствуют стандартным спецификациям иерархии файловой системы Linux. Для использования в качестве основы для образов контейнеров были разработаны специализированные дистрибутивы Linux.
Образ - это шаблон для будущих контейнеров. Образы контейнеров представляют из себя многоуровневые файловые системы. Структура каталога и расположение бинарных файлов, библиотек, конфигурационных файлов соответствуют стандартным спецификациям иерархии файловой системы Linux. Для использования в качестве основы для образов контейнеров были разработаны специализированные дистрибутивы Linux.
В Docker используется многоуровневая файловая система `UnionFS`. При старте контейнера слои образа объединяются и монтируются только на чтение, с добавлением слоя монтируемого для чтения и записи. Процессы контейнера в ходе своей работы изменяют имеет этот последний слой, оставляя содержимое слоёв образа нетронутым. Это свойство позволяет эффективно хранить контейнеры на основе одного и того же образа и сокращает их время запуска.
В Docker используется многоуровневая файловая система `UnionFS`. При старте контейнера слои образа объединяются и монтируются только на чтение, с добавлением слоя монтируемого для чтения и записи. Процессы контейнера в ходе своей работы изменяют имеет этот последний слой, оставляя содержимое слоёв образа нетронутым. Это свойство позволяет эффективно хранить контейнеры на основе одного и того же образа и сокращает их время запуска.
Теперь, когда мы лучше понимаем, что такое образы и какие они бывают, самое время создать собственный образ. Цель этого раздела — создать образ с простым приложением на Flask. Для этого заданияя подготовлено маленькое приложение `flask-app`, которое выводит случайную картинку с кошкой. Склонируйте этот репозиторий к себе на локальную машину `git clone <адрес-репозитория>` и перейдите в папку с приложением.
Теперь, когда мы лучше понимаем, что такое образы и какие они бывают, самое время создать собственный образ. Цель этого раздела — создать образ с простым приложением на Flask. Для этого задания подготовлено маленькое приложение `flask-app`, которое выводит случайную картинку с кошкой. Склонируйте этот репозиторий к себе на локальную машину `git clone <адрес-репозитория>` и перейдите в папку с приложением.
Следующим шагом является создание образа с данным веб-приложением. Как говорилось выше, все пользовательские образы базируются на базовых образах. Так как приложение написано на Python, базовый образ следует выбрать с предустановленным Python 3. Точнее мы собираемся использовать `python:3.8` версию python образа.
Следующим шагом является создание образа с данным веб-приложением. Как говорилось выше, все пользовательские образы базируются на базовых образах. Так как приложение написано на Python, базовый образ следует выбрать с предустановленным Python 3. Точнее мы собираемся использовать `python:3.8` версию python образа.
Видно, что контейнер e931ab24dedc находится в секции Containers. Также виден IP-адрес, выданный этому контейнеру — 172.17.0.2. Именно этот адрес мы и искали? Давайте проверим: запустим Flask-приложение и попробуем обратиться к нему по IP:
Видно, что контейнер `e931ab24dedc` находится в секции Containers. Также виден IP-адрес, выданный этому контейнеру —` 172.17.0.2`. Именно этот адрес мы и искали? Давайте проверим: запустим Flask-приложение и попробуем обратиться к нему по IP:
```
```
$ docker run -it --rm studX/<имя образа> --name flaskapp bash
$ docker run -it --rm studX/<имя образа> --name flaskapp bash