Потому что:
- Массив в Java не переопределяет equals() и hashCode(), сравнение идёт по ссылке.
- Это приведёт к тому, что два массива с одинаковыми значениями будут считаться разными ключами.
- Лучше использовать ByteBuffer.wrap(byte[]) или вручную реализовать equals/hashCode.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это контроллеры, используемые для управления подами, но они предназначены для различных типов приложений и имеют разные функции. Разница между ними связана с тем, как они управляют жизненным циклом подов, сетевой идентичностью, постоянством данных и порядком развертывания.
Используется для управления статическими или бесстаточными приложениями, где порядок запуска подов, их идентичность и состояние не имеют значения.
Примеры: веб-серверы, микросервисы, обработка очередей. Каждый под одинаков, и потеря одного из них не нарушает работу приложения.
Поды запускаются и удаляются в любом порядке. Если под удаляется, создается новый с другой идентичностью.
Поды доступны через Service, но они не сохраняют фиксированные сетевые имена.
Поддерживает обновления без простоя (rolling updates). Умеет откатываться на предыдущую версию.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21.6
Используется для управления состоянием и обеспечивает упорядоченность и идентичность подов. Это важно для приложений, где требуется сохранение данных, стабильные идентификаторы или порядок операций.
Примеры: базы данных (MySQL, PostgreSQL), системы очередей (Kafka), распределенные системы (Cassandra, Elasticsearch). Каждый под имеет уникальный идентификатор и связан с определенным хранилищем данных.
Поды запускаются, обновляются и удаляются строго в определенном порядке (0, 1, 2...). Это важно для приложений, где один узел должен быть доступен перед запуском другого.
Каждый под имеет фиксированное имя (например,
pod-0
, pod-1
), что упрощает взаимодействие между подами.Выполняются поэтапно, с учетом порядка.
Поды используют PersistentVolumeClaim (PVC) для сохранения данных. Даже если под удален, данные остаются на диске и доступны после повторного запуска.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql-service"
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
Бесстаточное. Требует быстрой масштабируемости. Не зависит от порядка запуска подов.
Требует сохранения данных между перезапусками. Зависит от фиксированной идентичности подов. Требует упорядоченного запуска или удаления.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
NAT (Network Address Translation):
- Преобразует внутренние IP-адреса в один внешний IP.
- Позволяет многим устройствам пользоваться Интернетом через один адрес.
- Типы:
- SNAT — исходящий трафик (от локального к Интернету).
- DNAT / Port forwarding — входящий трафик (от Интернета к устройству).
- Обеспечивает безопасность и экономию IP-адресов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Запуск контейнеров от имени пользователя root (рута) в Docker является обычной практикой, но это может привести к серьезным проблемам безопасности. Вот основные причины, почему это считается плохой практикой:
Эксплуатация уязвимостей: Если злоумышленник получает доступ к контейнеру, запущенному от имени root, он может легко использовать уязвимости контейнера для атаки на хост-систему.
Злоумышленники: Контейнеры могут содержать уязвимые или злонамеренные коды, которые при запуске с привилегиями root могут получить доступ к чувствительной информации или вызвать сбои.
Гостевая изоляция: Контейнеры должны быть изолированы от хост-системы. Запуск контейнера от имени root нарушает эту изоляцию, так как root внутри контейнера — это также root на хосте.
Повышенные привилегии: Контейнеры, запущенные от имени root, могут иметь доступ к системным ресурсам, что увеличивает риск нарушения безопасности.
Принцип наименьших привилегий: Этот принцип гласит, что процесс должен иметь только те привилегии, которые необходимы для выполнения его задач. Запуск контейнера от имени root нарушает этот принцип, предоставляя ему избыточные права.
Если в контейнере, запущенном от имени root, найдена уязвимость, злоумышленник может использовать ее для выполнения команд с привилегиями root на хосте, что может привести к серьезным нарушениям безопасности.
Контейнер, запущенный от имени root, может получить доступ к критически важным файлам хостовой системы, изменять их или удалять, что может привести к нарушению работы всей системы.
Использование непривилегированных пользователей:
В Dockerfile можно создать пользователя с ограниченными привилегиями и переключиться на него.
FROM ubuntu:20.04
RUN useradd -m myuser
USER myuser
CMD ["myapp"]
Использование флага --user:
При запуске контейнера можно использовать флаг
--user
, чтобы указать непривилегированного пользователя.docker run --user 1000:1000 myapp
Использование механизмов безопасности Docker:
Использование профилей seccomp для ограничения системных вызовов.
Использование AppArmor или SELinux для ограничения доступа контейнеров к системным ресурсам.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Изменение в ReplicaSet не сохранится надолго: Deployment всё равно будет следить за своим состоянием и при следующем изменении пересоздаст ReplicaSet с заданной в манифесте конфигурацией. Поэтому любые ручные изменения потеряются — надо менять именно Deployment.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
В Bash функция возвращает код завершения (exit status), который представляет собой числовое значение от 0 до 255. Это значение используется для указания успешного или неуспешного выполнения функции. По умолчанию, если явно не указано возвращаемое значение, функция возвращает код завершения последней выполненной команды внутри нее.
Чтобы явно задать код завершения функции, используется команда
return
. my_function() {
if [[ $1 -gt 0 ]]; then
return 0 # Успех
else
return 1 # Ошибка
fi
}
my_function 5
echo $? # Выведет 0 (успех)
Для передачи данных из функции (например, строки или числа) можно использовать
echo
. Вывод можно перехватить через подстановку команд $()
my_function() {
echo "Hello, $1!"
}
result=$(my_function "world")
echo "$result" # Выведет "Hello, world!"
Функция может менять значения глобальных переменных, которые затем используются за ее пределами
my_function() {
result=$(( $1 + $2 ))
}
my_function 3 7
echo $result # Выведет 10
Используется в сценариях для проверки, выполнилась ли функция успешно. Значение
0
обычно означает успех, а любое другое число — ошибку.Удобен для передачи данных из функции.
Полезно, если функция должна сохранять данные для дальнейшей обработки.
# Функция проверки файла
check_file() {
if [[ -f $1 ]]; then
echo "Файл $1 существует."
return 0
else
echo "Файл $1 не найден."
return 1
fi
}
# Вызов функции
check_file "/etc/passwd"
status=$? # Сохраняем код завершения
if [[ $status -eq 0 ]]; then
echo "Продолжаем работу..."
else
echo "Останавливаемся из-за ошибки."
fi
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
- Least privilege (минимальный RBAC).
- Ограничение доступа к hostPath, privileged, capabilities.
- Использование NetworkPolicies.
- Использование PodSecurityPolicy / PodSecurityAdmission.
- Контейнеры без root.
- Сканирование образов (Trivy, Clair).
- ReadOnlyRootFilesystem, Seccomp, AppArmor.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Императивный подход — это стиль программирования, где мы пошагово указываем компьютеру, что делать и как это делать.
Программист описывает процесс решения задачи.
Код выполняется шаг за шагом, изменяя состояние программы.
Пример на Python (императивный подход)
numbers = [1, 2, 3, 4, 5]
squared = []
for num in numbers:
squared.append(num ** 2) # Явно указываем, что делать на каждом шаге
print(squared) # [1, 4, 9, 16, 25]
C, Java, Python (может быть и императивным, и декларативным).
где важно управлять состоянием
(например, скрипты Bash
Пример в DevOps (Bash-скрипт, императивный стиль)
#!/bin/bash
mkdir /backup
cp /var/log/syslog /backup/
echo "Backup создан"
Императивный (Ansible, Bash)
apt update
apt install nginx
Шаги установки Nginx описаны вручную.
Декларативный (Terraform, Kubernetes)
resource "aws_instance" "web" {
ami = "ami-123456"
instance_type = "t2.micro"
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
proc — это виртуальная файловая система, которая содержит:
- информацию о процессах (/proc/<pid>/);
- информацию о системе (cpuinfo, meminfo, uptime);
- псевдофайлы, которые отражают текущее состояние ядра и процессов;
- не занимает физическое место, создаётся динамически.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
В
iptables
есть 5 таблиц, но чаще всего работают с тремя: основная таблица для контроля трафика (используется по умолчанию)
для трансляции адресов (SNAT, DNAT, редиректы)
для изменения пакетов (маркировка, TTL, QoS)
для исключения пакетов из обработки
conntrack
используется в SELinux для меток безопасности
Используется для разрешения или блокировки трафика.
iptables -P INPUT DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Используется для NAT, порт-форвардинга, маскарадинга.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Пример: Проброс порта (DNAT) – входящие пакеты на 80 порт перенаправляем на 8080
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
Используется для маркировки пакетов, изменения TTL, QoS.
iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64
Пример: Маркировка пакетов для использования в
tc
(QoS) iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 1
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это значит, что устройство не смогло получить IP от DHCP-сервера, и сработала автоконфигурация (APIPA).
Используется Windows и другими ОС для временной работы в локальной сети, без подключения к Интернету.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Если вам нужно собирать метрики (нагрузка, ошибки, задержки, бизнес-показатели) с вашего продукта, то вот лучшие инструменты
Prometheus – база данных временных рядов (time-series DB) для хранения метрик.
Grafana – мощная визуализация метрик.
Метрики собираются экспортерами (
node_exporter
, blackbox_exporter
и т. д.). Данные хранятся в Prometheus.
Grafana показывает красивые графики.
rate(http_requests_total[5m]) # Запросы в секунду за 5 минут
Устанавливается агент на сервер (
zabbix-agent
). Сервер собирает метрики и генерирует алерты.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Multi-stage используется в Dockerfile для оптимизации размеров образа, когда:
- в первом этапе происходит сборка приложения с инструментами, зависимостями;
- в последующих — копируются только необходимые артефакты, без сборочных инструментов.
Это позволяет разделить окружение сборки и запуска, повышая безопасность и уменьшая размер итогового контейнера.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
В Prometheus данные собираются по pull-модели – сервер сам запрашивает метрики у клиентов. Чтобы клиенты отдавали метрики, нужно:
1. Настроить приложение на экспонирование метрик в формате Prometheus.
2. Добавить Prometheus job для сбора этих метрик.
3. Опционально – использовать Pushgateway, если pull-модель не подходит.
Если приложение написано на Go, Python, Java или Node.js. Prometheus предлагает официальные клиентские библиотеки:
Go: [
prometheus/client_golang
](https://github.com/prometheus/client_golang) Python: [
prometheus_client
](https://github.com/prometheus/client_python) Java: [
simpleclient
](https://github.com/prometheus/client_java) Node.js: [
prom-client
](https://github.com/siimon/prom-client) Пример для Python
pip install prometheus_client
from prometheus_client import start_http_server, Counter
import time
# Создаем счетчик запросов
REQUEST_COUNT = Counter('app_requests_total', 'Total requests')
def process_request():
REQUEST_COUNT.inc() # Увеличиваем счетчик
time.sleep(1) # Имитация обработки запроса
if __name__ == '__main__':
start_http_server(8000) # Открываем метрики на 8000 порту
while True:
process_request()
npm install prom-client express
const express = require('express');
const client = require('prom-client');
const app = express();
const collectDefaultMetrics = client.collectDefaultMetrics;
collectDefaultMetrics();
const requestCounter = new client.Counter({
name: 'http_requests_total',
help: 'Total HTTP requests',
});
app.get('/', (req, res) => {
requestCounter.inc();
res.send('Hello, World!');
});
app.get('/metrics', (req, res) => {
res.set('Content-Type', client.register.contentType);
res.end(client.register.metrics());
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Добавляем job в
prometheus.yml
scrape_configs:
- job_name: 'my_app'
static_configs:
- targets: ['app_host:8000']
Если клиент не может сам отдавать метрики (например, это краткоживущий job), можно использовать Pushgateway.
Запускаем Pushgateway:
docker run -d -p 9091:9091 prom/pushgateway
Отправляем метрики через
curl
echo "job_execution_time 5.3" | curl --data-binary @- http://localhost:9091/metrics/job/my_batch_job
Настраиваем Prometheus на сбор данных из Pushgateway
scrape_configs:
- job_name: 'pushgateway'
static_configs:
- targets: ['localhost:9091']
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
- В контейнере сохранить дамп в файл (например, SQL-дамп).
- Использовать команду docker cp:
Она копирует файл из контейнера на хост.
Можно также использовать docker exec и перенаправление вывода.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Когда GitLab CI/CD скачивает код (
git clone
), он начинает выполнять pipeline, состоящий из job'ов и stage'ов. Определяется
gitlab-ci.yml
Запускается раннер (GitLab Runner)
Определяются переменные окружения
Запускаются
before_script
, script
, after_script
Артефакты сохраняются и передаются между stage'ами
После скачивания кода GitLab ищет
.gitlab-ci.yml
в репозитории. stages:
- build
- test
- deploy
build:
stage: build
script:
- echo "Building project..."
GitLab CI/CD отправляет задачу в GitLab Runner, который выполняет команды. Runner может работать в Docker, Kubernetes, Shell, VM.
Running with gitlab-runner 15.0.0 (abcdef12)
Using Docker executor with image python:3.9 ...
Перед выполнением
script
, GitLab загружает переменные окружения. CI_COMMIT_REF_NAME=main
CI_PROJECT_NAME=my-repo
CI_PIPELINE_ID=12345
Можно использовать их в
script
script:
- echo "Branch: $CI_COMMIT_REF_NAME"
GitLab выполняет основные команды pipeline
before_script:
- echo "Preparing environment..."
script:
- echo "Running main job..."
- python build.py
after_script:
- echo "Cleaning up..."
Если один stage создает файлы, их можно передать в следующий stage через
artifacts
. build:
stage: build
script:
- echo "Compiling..." > build.log
artifacts:
paths:
- build.log
test:
stage: test
script:
- cat build.log
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Для этого применяются команды с опциями контекста, которые показывают несколько строк до и после совпадения. Это полезно для понимания причины и последствий ошибки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
SaaS (Software as a Service, "Программное обеспечение как услуга") – это модель, при которой пользователи получают доступ к программному обеспечению через интернет без необходимости установки на локальный компьютер.
нужно было скачивать и устанавливать программы на свой компьютер.
просто открываешь браузер и работаешь онлайн.
Пользователь заходит на сайт или приложение.
Вся логика и данные хранятся на серверах провайдера.
Обновления и обслуживание происходят автоматически.
Оплата обычно по подписке (ежемесячно/ежегодно).
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это подход в Docker:
- Используются несколько FROM в одном Dockerfile.
- Сборка проходит в первом (build stage), финальный образ собирается из второго (final stage) — без лишнего мусора.
Плюсы:
- меньше размер образа;
- разделение логики сборки и выполнения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ansible – мощный инструмент для автоматизации, но у него есть серьезные недостатки, особенно при масштабировании.
каждый раз Ansible подключается по SSH и выполняет задачи без предварительного кеширования
что замедляет процесс.
если целевой сервер слабый или без Python, выполнение плейбуков будет медленным.
по умолчанию Ansible выполняет задачи последовательно, что дольше, чем параллельные методы (например, в SaltStack).
yaml
- name: Установка Nginx
hosts: all
tasks:
- name: Установить Nginx
apt:
name: nginx
state: present
Запуск задач параллельно (
-f 50
) sh
ansible-playbook playbook.yml -f 50
Если 1000+ серверов, главный Ansible-узел может быстро перегрузиться.
Роли могут конфликтовать, если версии не совпадают. Ansible Galaxy не такой удобный, как Terraform Registry
Некоторые модули (особенно shell и command) не всегда понимают, применялась ли конфигурация раньше.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
GitOps — это подход, при котором инфраструктура и конфигурация приложений описываются декларативно в Git, а изменения автоматически применяются через CD-процессы. Все действия по управлению кластерами и сервисами происходят через Git, а не вручную. Это улучшает контроль версий, даёт аудит и упрощает откаты.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM