add: minor.
This commit is contained in:
parent
0a90d4a444
commit
c7a5241d33
28
kubernetes/k3s-3xui-pod.md
Normal file
28
kubernetes/k3s-3xui-pod.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Установка 3X-UI как под в K3s (Kubernetes)
|
||||||
|
|
||||||
|
3X-UI — это симпатичный веб-интерфейс для управления VPN-серверами, такими как WireGuard, Shadowsocks, Xray, V2Ray
|
||||||
|
и тому подобное. Он позволяет настраивать и мониторить VPN-соединения и клиентов через браузер. Мы будем запускать
|
||||||
|
его как контейнер (под) внутри K3s кластера на Orange Pi 5.
|
||||||
|
|
||||||
|
### Создание namespace (не обязательно)
|
||||||
|
|
||||||
|
Для удобства организации рекомендую создать отдельное пространство имён (`namespace`) для 3X-UI. Это как папка для
|
||||||
|
ресурсов, чтобы они не смешивались с другими приложениями.
|
||||||
|
|
||||||
|
Выполним в терминале:
|
||||||
|
```bash
|
||||||
|
sudo kubectl create namespace x-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверим, что пространство имён создано:
|
||||||
|
```bash
|
||||||
|
kubectl get namespaces
|
||||||
|
```
|
||||||
|
|
||||||
|
Увидим x-ui в списке:
|
||||||
|
```text
|
||||||
|
NAME STATUS AGE
|
||||||
|
... ... ...
|
||||||
|
... ... ...
|
||||||
|
x-ui Active 6s
|
||||||
|
```
|
@ -23,8 +23,8 @@
|
|||||||
│ └── cclient-shadowsocks--izmir/ # Локация Измир
|
│ └── cclient-shadowsocks--izmir/ # Локация Измир
|
||||||
│ ├── config.yaml
|
│ ├── config.yaml
|
||||||
│ └── deployment.yaml
|
│ └── deployment.yaml
|
||||||
├── ...
|
├── …
|
||||||
└── ...
|
└── …
|
||||||
```
|
```
|
||||||
|
|
||||||
Создаем файл `config.yaml` для первого Shadowsocks-клиента (Москва):
|
Создаем файл `config.yaml` для первого Shadowsocks-клиента (Москва):
|
||||||
@ -61,7 +61,7 @@ data:
|
|||||||
- `data:` — данные конфигурации.
|
- `data:` — данные конфигурации.
|
||||||
- `config.json:` — имя файла, в который будет записан конфиг.
|
- `config.json:` — имя файла, в который будет записан конфиг.
|
||||||
- `|` — говорит, что дальше будет многострочный текст.
|
- `|` — говорит, что дальше будет многострочный текст.
|
||||||
- `{...}` — Собственно JSON-конфигурация нашего Shadowsocks-клиента.
|
- `{…}` — Собственно JSON-конфигурация нашего Shadowsocks-клиента.
|
||||||
- `server` и `server_port` — адрес и порт нашего VPS.
|
- `server` и `server_port` — адрес и порт нашего VPS.
|
||||||
- `local_address` и `local_port` — где будет SOCKS5 внутри кластера.
|
- `local_address` и `local_port` — где будет SOCKS5 внутри кластера.
|
||||||
- `password` и `method` — пароль и метод шифрования. Метод шифрования `chacha20-ietf-poly1305` -- используется,
|
- `password` и `method` — пароль и метод шифрования. Метод шифрования `chacha20-ietf-poly1305` -- используется,
|
||||||
@ -150,10 +150,10 @@ sudo k3s kubectl get pods -n kube-system
|
|||||||
Увидим что-то типа:
|
Увидим что-то типа:
|
||||||
```text
|
```text
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
...
|
…
|
||||||
...
|
…
|
||||||
shadowsocks-client-moscow-54d64bf5f4-trb6p 1/1 Running 0 24m
|
shadowsocks-client-moscow-54d64bf5f4-trb6p 1/1 Running 0 24m
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
Можно проверь логи:
|
Можно проверь логи:
|
||||||
@ -232,10 +232,10 @@ sudo k3s ctr images ls | grep shadowsocks
|
|||||||
|
|
||||||
Увидим что-то типа:
|
Увидим что-то типа:
|
||||||
```text
|
```text
|
||||||
...
|
…
|
||||||
docker.io/library/shadowsocks-with-tools:latest application/vnd.oci.image.manifest.v1+json sha256:... 22.5 MiB linux/arm64 io.cri-containerd.image=managed
|
docker.io/library/shadowsocks-with-tools:latest application/vnd.oci.image.manifest.v1+json sha256:… 22.5 MiB linux/arm64 io.cri-containerd.image=managed
|
||||||
...
|
…
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
Теперь нам нужно передать образ контейнера на другие ноды кластера. Как это сделать есть заметка "[Развертывание
|
Теперь нам нужно передать образ контейнера на другие ноды кластера. Как это сделать есть заметка "[Развертывание
|
||||||
@ -246,15 +246,15 @@ docker.io/library/shadowsocks-with-tools:latest application/vnd.oci.image.ma
|
|||||||
новый образ. Закомментируем строку `image: shadowsocks/shadowsocks-libev:latest` и вставим две строки после неё
|
новый образ. Закомментируем строку `image: shadowsocks/shadowsocks-libev:latest` и вставим две строки после неё
|
||||||
(обратите внимание на заметки):
|
(обратите внимание на заметки):
|
||||||
```yaml
|
```yaml
|
||||||
...
|
…
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: shadowsocks-client
|
- name: shadowsocks-client
|
||||||
# image: shadowsocks/shadowsocks-libev:latest
|
# image: shadowsocks/shadowsocks-libev:latest
|
||||||
image: shadowsocks-with-tools # Без :latest, чтобы k3s не "ходил" за контейнером в реестр (например, DockerHub)
|
image: shadowsocks-with-tools # Без :latest, чтобы k3s не "ходил" за контейнером в реестр (например, DockerHub)
|
||||||
imagePullPolicy: Never # Только локальный образ, не тянуть из реестра
|
imagePullPolicy: Never # Только локальный образ, не тянуть из реестра
|
||||||
...
|
…
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
Уберём старый под из deployment и удалим сам под из k3s:
|
Уберём старый под из deployment и удалим сам под из k3s:
|
||||||
@ -276,9 +276,9 @@ sudo k3s kubectl get pods -n kube-system
|
|||||||
Увидим что-то типа:
|
Увидим что-то типа:
|
||||||
```text
|
```text
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
...
|
…
|
||||||
shadowsocks-client-moscow-6cf7b956b8-mtsg4 1/1 Running 0 9s
|
shadowsocks-client-moscow-6cf7b956b8-mtsg4 1/1 Running 0 9s
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Проверка работы Shadowsocks
|
#### Проверка работы Shadowsocks
|
||||||
@ -344,12 +344,12 @@ sudo k3s kubectl logs -n kube-system shadowsocks-client-moscow-<hash>
|
|||||||
Для этого нужно изменить _local_address_ в конфиге shadowsocks-клиента `config.yaml`:
|
Для этого нужно изменить _local_address_ в конфиге shadowsocks-клиента `config.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
...
|
…
|
||||||
"server_port": <ПОРТ>,
|
"server_port": <ПОРТ>,
|
||||||
# "local_address": "127.0.0.1",
|
# "local_address": "127.0.0.1",
|
||||||
"local_address": "0.0.0.0",
|
"local_address": "0.0.0.0",
|
||||||
"local_port": 1081,
|
"local_port": 1081,
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
Применим конфиг:
|
Применим конфиг:
|
||||||
@ -437,9 +437,9 @@ sudo k3s kubectl get service -n kube-system
|
|||||||
Увидим что-то типа:
|
Увидим что-то типа:
|
||||||
```text
|
```text
|
||||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
...
|
…
|
||||||
ss-moscow-service ClusterIP 10.43.236.81 <none> 1081/TCP,1081/UDP 5m5s
|
ss-moscow-service ClusterIP 10.43.236.81 <none> 1081/TCP,1081/UDP 5m5s
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
Теперь другие поды могут обращаться к `ss-moscow-service.kube-system.svc.cluster.local:1081` как к SOCKS5-прокси.
|
Теперь другие поды могут обращаться к `ss-moscow-service.kube-system.svc.cluster.local:1081` как к SOCKS5-прокси.
|
||||||
|
@ -20,7 +20,7 @@ IoT-устройства, edge-серверы и т.п.). Для кластер
|
|||||||
контейнеры всё равно запускаются runtime’ом (это containerd в k3s). И Docker все равно еще нужен для создания
|
контейнеры всё равно запускаются runtime’ом (это containerd в k3s). И Docker все равно еще нужен для создания
|
||||||
образов, и если при установке k3s не указать `--docker` то k3s будет использовать его как runtime._
|
образов, и если при установке k3s не указать `--docker` то k3s будет использовать его как runtime._
|
||||||
|
|
||||||
Но, есть у k3s и минус для конкретно моего случая -- распределенная база **etcd**, в которой хранится состояния
|
Но, есть у k3s и минус для конкретно моего случая — распределенная база **etcd**, в которой хранится состояния
|
||||||
кластера, нод и подов, в нем заменена SQLite. Это круто для маленьких компьютеров: экономно по памяти и другим ресурсам,
|
кластера, нод и подов, в нем заменена SQLite. Это круто для маленьких компьютеров: экономно по памяти и другим ресурсам,
|
||||||
и, что главное, никак не сказывается на производительности (пока узлов меньше 50-80), но означает, что в кластере k3s
|
и, что главное, никак не сказывается на производительности (пока узлов меньше 50-80), но означает, что в кластере k3s
|
||||||
может быть только одна мастер-нода. Если мастер-нода упадет, её некому будет заменить и весь кластер умрет.
|
может быть только одна мастер-нода. Если мастер-нода упадет, её некому будет заменить и весь кластер умрет.
|
||||||
@ -29,7 +29,7 @@ IoT-устройства, edge-серверы и т.п.). Для кластер
|
|||||||
|
|
||||||
### Важное предупреждение
|
### Важное предупреждение
|
||||||
|
|
||||||
k3s -- это не упрощенная мини-версия Kubernetes, здесь все компоненты упакованы в один бинарник, а значит намного
|
k3s — это не упрощенная мини-версия Kubernetes, здесь все компоненты упакованы в один бинарник, а значит намного
|
||||||
проще не только добавлять узлы, но и удалять их. Так что если что-то пойдет не так с настройкой узла, просто удалите
|
проще не только добавлять узлы, но и удалять их. Так что если что-то пойдет не так с настройкой узла, просто удалите
|
||||||
и начните заново. Удаление k3s с узла:
|
и начните заново. Удаление k3s с узла:
|
||||||
```bash
|
```bash
|
||||||
@ -51,14 +51,14 @@ curl -sfL https://get.k3s.io | sh -s - server --cluster-init --tls-san=192.168.1
|
|||||||
```
|
```
|
||||||
|
|
||||||
Здесь:
|
Здесь:
|
||||||
* `server` -- значение по умолчанию, устанавливает узел k3s в режиме *мастер* (control-plane). В этом режиме узел
|
* `server` — значение по умолчанию, устанавливает узел k3s в режиме *мастер* (control-plane). В этом режиме узел
|
||||||
будет запускать все компоненты управления Kubernetes: API-сервер, контроллер-менеджер, планировщик (scheduler).
|
будет запускать все компоненты управления Kubernetes: API-сервер, контроллер-менеджер, планировщик (scheduler).
|
||||||
Такой узел отвечает за управление кластером и может также выполнять рабочие нагрузки (workloads), если
|
Такой узел отвечает за управление кластером и может также выполнять рабочие нагрузки (workloads), если
|
||||||
не настроены ограничения (taints). Если бы мы указали `agent` -- был бы установлен узел k3s в режиме *воркер*-узла.
|
не настроены ограничения (taints). Если бы мы указали `agent` — был бы установлен узел k3s в режиме *воркер*-узла.
|
||||||
* `--cluster-init` -- добавляет поддержку высокой доступности (HA -- High Availability) через встроенный `etcd`. Это
|
* `--cluster-init` — добавляет поддержку высокой доступности (HA — High Availability) через встроенный `etcd`. Это
|
||||||
значит, что узел инициализирует новый кластер и готов к тому, чтобы другие мастер-узлы могли к нему подключиться
|
значит, что узел инициализирует новый кластер и готов к тому, чтобы другие мастер-узлы могли к нему подключиться
|
||||||
(для создания HA-конфигурации).
|
(для создания HA-конфигурации).
|
||||||
* `--tls-san=192.168.1.27` -- добавляет IP 192.168.1.27 в сертификаты API-сервера, чтобы другие узлы и клиенты
|
* `--tls-san=192.168.1.27` — добавляет IP 192.168.1.27 в сертификаты API-сервера, чтобы другие узлы и клиенты
|
||||||
могли обращаться к нему по этому адресу.
|
могли обращаться к нему по этому адресу.
|
||||||
|
|
||||||
Проверим, что все k3s запущен:
|
Проверим, что все k3s запущен:
|
||||||
@ -70,9 +70,9 @@ sudo service k3s status
|
|||||||
```text
|
```text
|
||||||
● k3s.service - Lightweight Kubernetes
|
● k3s.service - Lightweight Kubernetes
|
||||||
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enabled)
|
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enabled)
|
||||||
Active: active (running) since ...
|
Active: active (running) since …
|
||||||
...
|
…
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
Посмотрим сколько нод в кластере:
|
Посмотрим сколько нод в кластере:
|
||||||
@ -113,16 +113,16 @@ kube-system traefik-5d45fc8cc9-t5d58 1/1 Running 0
|
|||||||
Представлены следующие поды:
|
Представлены следующие поды:
|
||||||
1. `coredns` — это DNS-сервер для кластера. Он отвечает за разрешение имен внутри Kubernetes (например, чтобы поды
|
1. `coredns` — это DNS-сервер для кластера. Он отвечает за разрешение имен внутри Kubernetes (например, чтобы поды
|
||||||
могли обращаться друг к другу по именам сервисов вроде my-service.default.svc.cluster.local).
|
могли обращаться друг к другу по именам сервисов вроде my-service.default.svc.cluster.local).
|
||||||
2. `helm-install-traefik-crd` -- это временный под (Job), который устанавливает Custom Resource Definitions (CRD)
|
2. `helm-install-traefik-crd` — это временный под (Job), который устанавливает Custom Resource Definitions (CRD)
|
||||||
для *Traefik* — ingress-контроллера, встроенного в k3s. CRD нужны для управления ingress-ресурсами
|
для *Traefik* — ingress-контроллера, встроенного в k3s. CRD нужны для управления ingress-ресурсами
|
||||||
(маршрутизацией HTTP/HTTPS). Этот под — одноразовая задача (Job), а не постоянный сервис. Он запустился, выполнил
|
(маршрутизацией HTTP/HTTPS). Этот под — одноразовая задача (Job), а не постоянный сервис. Он запустился, выполнил
|
||||||
работу (установил CRD) и завершился. Статус "*Completed*" значит, что он больше не работает.
|
работу (установил CRD) и завершился. Статус "*Completed*" значит, что он больше не работает.
|
||||||
3. `helm-install-traefik` -- ещё один Job, который устанавливает сам Traefik через Helm-чарт. Этот под развернул
|
3. `helm-install-traefik` — ещё один Job, который устанавливает сам Traefik через Helm-чарт. Этот под развернул
|
||||||
основной Traefik-под и завершился.
|
основной Traefik-под и завершился.
|
||||||
4. `local-path-provisioner` -- компонент для автоматического создания локальных Persistent Volumes (PV) на узлах. Он
|
4. `local-path-provisioner` — компонент для автоматического создания локальных Persistent Volumes (PV) на узлах. Он
|
||||||
позволяет подам запрашивать хранилище (например, через PersistentVolumeClaim) без сложной настройки NFS или внешних
|
позволяет подам запрашивать хранилище (например, через PersistentVolumeClaim) без сложной настройки NFS или внешних
|
||||||
хранилищ. В k3s это встроено для простоты.
|
хранилищ. В k3s это встроено для простоты.
|
||||||
5. `metrics-server` -- собирает данные об использовании ресурсов (CPU, память) подов и узлов. Это нужно для команд
|
5. `metrics-server` — собирает данные об использовании ресурсов (CPU, память) подов и узлов. Это нужно для команд
|
||||||
вроде `kubectl top` или для Horizontal Pod Autoscaler (HPA). Установку метрик можно отключить при запуске k3s
|
вроде `kubectl top` или для Horizontal Pod Autoscaler (HPA). Установку метрик можно отключить при запуске k3s
|
||||||
флагом `--disable=metrics-server`.
|
флагом `--disable=metrics-server`.
|
||||||
6. `svclb-traefik` - это под для балансировки нагрузки (Service Load Balancer) для Traefik. В k3s нет встроенного
|
6. `svclb-traefik` - это под для балансировки нагрузки (Service Load Balancer) для Traefik. В k3s нет встроенного
|
||||||
@ -131,14 +131,14 @@ kube-system traefik-5d45fc8cc9-t5d58 1/1 Running 0
|
|||||||
* один для самой логики балансировки;
|
* один для самой логики балансировки;
|
||||||
* другой для мониторинга или дополнительной функциональности (например, *keepalived* или аналога) и это зависит
|
* другой для мониторинга или дополнительной функциональности (например, *keepalived* или аналога) и это зависит
|
||||||
от реализации в k3s.
|
от реализации в k3s.
|
||||||
7. `traefik` -- сам Traefik, ingress-контроллер, который обрабатывает HTTP/HTTPS трафик кластера и маршрутизирует
|
7. `traefik` — сам Traefik, ingress-контроллер, который обрабатывает HTTP/HTTPS трафик кластера и маршрутизирует
|
||||||
его к соответствующим подам (с динамической конфигурацией нашим) и сервисам по правилам Ingress. Traefik в k3s
|
его к соответствующим подам (с динамической конфигурацией нашим) и сервисам по правилам Ingress. Traefik в k3s
|
||||||
установлен по умолчанию, но его можно отключить при запуске k3s флагом `--disable=traefik` (не будет ни *traefik*,
|
установлен по умолчанию, но его можно отключить при запуске k3s флагом `--disable=traefik` (не будет ни *traefik*,
|
||||||
ни *svclb*, ни связанных *Helm Jobs*).
|
ни *svclb*, ни связанных *Helm Jobs*).
|
||||||
|
|
||||||
Обратите внимание, что, например, под `coredns` получил имя `coredns-ccb96694c-tfjwj`. Имена подов (Pod Names)
|
Обратите внимание, что, например, под `coredns` получил имя `coredns-ccb96694c-tfjwj`. Имена подов (Pod Names)
|
||||||
в Kubernetes генерируются автоматически на основе правил, чтобы каждый под в кластере имел уникальное имя.
|
в Kubernetes генерируются автоматически на основе правил, чтобы каждый под в кластере имел уникальное имя.
|
||||||
Структура имени -- `<имя-приложения>-<хеш-ревизии>-<случайный-суффикс>`. Впрочем, `<хеш-ревизии>` может отсутствовать,
|
Структура имени — `<имя-приложения>-<хеш-ревизии>-<случайный-суффикс>`. Впрочем, `<хеш-ревизии>` может отсутствовать,
|
||||||
если под не имеет контроллера репликации (например, Job или CronJob).
|
если под не имеет контроллера репликации (например, Job или CronJob).
|
||||||
|
|
||||||
Можно проверить, что API нашего узла (кластера) отвечает:
|
Можно проверить, что API нашего узла (кластера) отвечает:
|
||||||
@ -168,7 +168,7 @@ Unauthorized JSON-ответ от API. Что-то вроде:
|
|||||||
sudo cat /var/lib/rancher/k3s/server/node-token
|
sudo cat /var/lib/rancher/k3s/server/node-token
|
||||||
```
|
```
|
||||||
|
|
||||||
Вывод будет что-то вроде `K10...::server:longrandomstring`. Это и есть токен, который нужно будет использовать.
|
Вывод будет что-то вроде `K10…::server:longrandomstring`. Это и есть токен, который нужно будет использовать.
|
||||||
|
|
||||||
Теперь на втором Orange Pi (например, с IP 192.168.1.28) можно запустить второй мастер-узел (вставим токен
|
Теперь на втором Orange Pi (например, с IP 192.168.1.28) можно запустить второй мастер-узел (вставим токен
|
||||||
из предыдущего шага):
|
из предыдущего шага):
|
||||||
@ -176,9 +176,9 @@ sudo cat /var/lib/rancher/k3s/server/node-token
|
|||||||
curl -sfL https://get.k3s.io | sh -s - server --server https://192.168.1.27:6443 --token <ТОКЕН> --tls-san=192.168.1.28
|
curl -sfL https://get.k3s.io | sh -s - server --server https://192.168.1.27:6443 --token <ТОКЕН> --tls-san=192.168.1.28
|
||||||
```
|
```
|
||||||
Здесь ключи:
|
Здесь ключи:
|
||||||
* `--server https://192.168.1.27:6443` -- указывает на API мастер-узла, чтобы наш новый узел мог подключиться к кластеру.
|
* `--server https://192.168.1.27:6443` — указывает на API мастер-узла, чтобы наш новый узел мог подключиться к кластеру.
|
||||||
* `--token` — токен аутентификации из предыдущего шага.
|
* `--token` — токен аутентификации из предыдущего шага.
|
||||||
* `--tls-san=192.168.1.28` -- добавляет IP нашего второго мастера в сертификаты (для будущих подключений).
|
* `--tls-san=192.168.1.28` — добавляет IP нашего второго мастера в сертификаты (для будущих подключений).
|
||||||
|
|
||||||
Проверим какие теперь ноды в кластере:
|
Проверим какие теперь ноды в кластере:
|
||||||
```bash
|
```bash
|
||||||
@ -210,7 +210,7 @@ kube-system svclb-traefik-4f8c2580-xzt5d 2/2 Running 0
|
|||||||
kube-system traefik-5d45fc8cc9-t5d58 1/1 Running 0 2h 10.42.0.8 opi5plus-2 <none> <none>
|
kube-system traefik-5d45fc8cc9-t5d58 1/1 Running 0 2h 10.42.0.8 opi5plus-2 <none> <none>
|
||||||
```
|
```
|
||||||
|
|
||||||
Как видим, у нас появился еще один `svclb-traefik` на второй ноде. Это под -- Service Load Balancer (SLB) для Traefik.
|
Как видим, у нас появился еще один `svclb-traefik` на второй ноде. Это под — Service Load Balancer (SLB) для Traefik.
|
||||||
Он эмулирует облачный балансировщик нагрузки (типа AWS ELB), которого нет в локальном окружении вроде Orange Pi.
|
Он эмулирует облачный балансировщик нагрузки (типа AWS ELB), которого нет в локальном окружении вроде Orange Pi.
|
||||||
SLB перенаправляет внешний трафик (например, на порты 80/443) к сервисам типа LoadBalancer внутри кластера.
|
SLB перенаправляет внешний трафик (например, на порты 80/443) к сервисам типа LoadBalancer внутри кластера.
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ curl -sfL https://get.k3s.io | sh -s - agent --server https://192.168.1.10:6443
|
|||||||
```
|
```
|
||||||
|
|
||||||
Здесь ключ:
|
Здесь ключ:
|
||||||
* `agent` -- устанавливает узел в режиме воркера (worker). Это значит, что узел будет выполнять рабочие нагрузки
|
* `agent` — устанавливает узел в режиме воркера (worker). Это значит, что узел будет выполнять рабочие нагрузки
|
||||||
(поды), но не будет управлять кластером (без *control-plane*, *master* и на нем нет реплики *etcd*).
|
(поды), но не будет управлять кластером (без *control-plane*, *master* и на нем нет реплики *etcd*).
|
||||||
|
|
||||||
Посмотрим на ноды (команда выполняется на одном из мастер-узлов):
|
Посмотрим на ноды (команда выполняется на одном из мастер-узлов):
|
||||||
@ -301,7 +301,7 @@ traefik LoadBalancer 10.43.164.48 192.168.1.26,192.168.1.27,192.16
|
|||||||
им не нужен доступ к etcd в реальном времени.
|
им не нужен доступ к etcd в реальном времени.
|
||||||
|
|
||||||
В чем может быть смысл иметь два мастера? Это обеспечивает репликацию данных (второй хранит копию etcd), но не
|
В чем может быть смысл иметь два мастера? Это обеспечивает репликацию данных (второй хранит копию etcd), но не
|
||||||
даёт отказоустойчивости -- когда один мастер упал, кластер становится неуправляемым (нет управления через kubectl),
|
даёт отказоустойчивости — когда один мастер упал, кластер становится неуправляемым (нет управления через kubectl),
|
||||||
рабочие нагрузки (поды) могут продолжать работать, пока жив хотя бы один узел, но новые изменения (развертывание
|
рабочие нагрузки (поды) могут продолжать работать, пока жив хотя бы один узел, но новые изменения (развертывание
|
||||||
подов и обновления) невозможны.
|
подов и обновления) невозможны.
|
||||||
|
|
||||||
@ -399,7 +399,7 @@ traefik-6c979cd89d-z6wwm 1/1 Running 0 2
|
|||||||
```
|
```
|
||||||
|
|
||||||
Хотя, в целом, кластер остается рабочим, и сам чинится при отключении и восстановлении узлов, но если отключается нода
|
Хотя, в целом, кластер остается рабочим, и сам чинится при отключении и восстановлении узлов, но если отключается нода
|
||||||
на которой исполняется под с `coredns` -- то временно будет затруднен перезапуска и создание новых подов, а значит
|
на которой исполняется под с `coredns` — то временно будет затруднен перезапуска и создание новых подов, а значит
|
||||||
и "переезд" подов с погашенного узла, до восстановления `coredns` тоже будет замедлен. Кроме того, если сценарий
|
и "переезд" подов с погашенного узла, до восстановления `coredns` тоже будет замедлен. Кроме того, если сценарий
|
||||||
приложения(ий) развернутых внутри k3s предполагает переподключение с использованием имен подов или обнаружение подов,
|
приложения(ий) развернутых внутри k3s предполагает переподключение с использованием имен подов или обнаружение подов,
|
||||||
то это тоже перестанет работать.
|
то это тоже перестанет работать.
|
||||||
@ -410,12 +410,12 @@ sudo k3s kubectl edit deployment coredns -n kube-system
|
|||||||
```
|
```
|
||||||
|
|
||||||
Здесь:
|
Здесь:
|
||||||
* `kubectl edit` -- Открывает редактор (по умолчанию *vim*) для изменения ресурса Kubernetes напрямую в кластере.
|
* `kubectl edit` — Открывает редактор (по умолчанию *vim*) для изменения ресурса Kubernetes напрямую в кластере.
|
||||||
Вместо создания локального YAML-файла и применения его через `kubectl apply`, мы сразу редактируем "живой" конфиг.
|
Вместо создания локального YAML-файла и применения его через `kubectl apply`, мы сразу редактируем "живой" конфиг.
|
||||||
* `deployment coredns` -- Указывает, что редактируем объект типа *deployment* с именем `coredns`. Deployment — это
|
* `deployment coredns` — Указывает, что редактируем объект типа *deployment* с именем `coredns`. Deployment — это
|
||||||
контроллер, который управляет набором подов (в данном случае coredns), обеспечивая их количество (реплики),
|
контроллер, который управляет набором подов (в данном случае coredns), обеспечивая их количество (реплики),
|
||||||
перезапуск и обновления.
|
перезапуск и обновления.
|
||||||
* `-n kube-system` -- Указывает пространство имён (namespace), где находится *coredns8. В k3s системные компоненты,
|
* `-n kube-system` — Указывает пространство имён (namespace), где находится *coredns8. В k3s системные компоненты,
|
||||||
к которым относится *coredns(, обычно живут в kube-system.
|
к которым относится *coredns(, обычно живут в kube-system.
|
||||||
|
|
||||||
В открывшемся окне найдем строку `replicas: 1` и заменим её на `replicas: 2`.
|
В открывшемся окне найдем строку `replicas: 1` и заменим её на `replicas: 2`.
|
||||||
@ -431,7 +431,7 @@ spec:
|
|||||||
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
|
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
|
||||||
coredns-ccb96694c-n4qsp 0/1 ContainerCreating 0 5s <none> opi5plus-1 <none> <none>
|
coredns-ccb96694c-n4qsp 0/1 ContainerCreating 0 5s <none> opi5plus-1 <none> <none>
|
||||||
coredns-ccb96694c-wzh96 1/1 Running 0 3h10m 10.42.1.8 opi5plus-3 <none> <none>
|
coredns-ccb96694c-wzh96 1/1 Running 0 3h10m 10.42.1.8 opi5plus-3 <none> <none>
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
А затем:
|
А затем:
|
||||||
@ -439,7 +439,7 @@ coredns-ccb96694c-wzh96 1/1 Running 0
|
|||||||
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
|
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
|
||||||
coredns-ccb96694c-n4qsp 1/1 Running 0 15s 10.42.2.6 opi5plus-1 <none> <none>
|
coredns-ccb96694c-n4qsp 1/1 Running 0 15s 10.42.2.6 opi5plus-1 <none> <none>
|
||||||
coredns-ccb96694c-wzh96 1/1 Running 0 3h10m 10.42.1.8 opi5plus-3 <none> <none>
|
coredns-ccb96694c-wzh96 1/1 Running 0 3h10m 10.42.1.8 opi5plus-3 <none> <none>
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
|
|
||||||
**Как это будет работать?** Обе реплики `coredns` привязаны к сервису `kube-dns` в пространстве имён `kube-system`.
|
**Как это будет работать?** Обе реплики `coredns` привязаны к сервису `kube-dns` в пространстве имён `kube-system`.
|
||||||
@ -455,10 +455,10 @@ sudo k3s kubectl get endpoints kube-dns -n kube-system
|
|||||||
гасили при экспериментах с устойчивостью кластера:
|
гасили при экспериментах с устойчивостью кластера:
|
||||||
```text
|
```text
|
||||||
NAME ENDPOINTS AGE
|
NAME ENDPOINTS AGE
|
||||||
kube-dns 10.42.1.8:53,10.42.2.6:53,10.42.1.8:53 + 3 more... 5d23h
|
kube-dns 10.42.1.8:53,10.42.2.6:53,10.42.1.8:53 + 3 more… 5d23h
|
||||||
```
|
```
|
||||||
|
|
||||||
Каждый под `coredns` -- самостоятельный DNS-сервер. Они не взаимодействуют друг с другом и не обмениваются данными. Это
|
Каждый под `coredns` — самостоятельный DNS-сервер. Они не взаимодействуют друг с другом и не обмениваются данными. Это
|
||||||
просто экземпляры одного и того же сервиса, работающие параллельно. Они независимы, получают данные из API Kubernetes
|
просто экземпляры одного и того же сервиса, работающие параллельно. Они независимы, получают данные из API Kubernetes
|
||||||
и отвечают на запросы параллельно. В каждом поде кластера в качестве DNS настроен `kube-dns` (задаётся в файле
|
и отвечают на запросы параллельно. В каждом поде кластера в качестве DNS настроен `kube-dns` (задаётся в файле
|
||||||
`/etc/resolv.conf` внутри пода). Когда под отправляет DNS-запрос, его получит `kube-dns` и перенаправит запрос
|
`/etc/resolv.conf` внутри пода). Когда под отправляет DNS-запрос, его получит `kube-dns` и перенаправит запрос
|
||||||
@ -518,7 +518,7 @@ sudo apt install keepalived
|
|||||||
sudo nano /etc/keepalived/keepalived.conf
|
sudo nano /etc/keepalived/keepalived.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
На первом мастер-узле (хост -- `opi5plus-1`, IP -- `192.168.1.26`):
|
На первом мастер-узле (хост — `opi5plus-1`, IP — `192.168.1.26`):
|
||||||
```text
|
```text
|
||||||
vrrp_instance VI_1 {
|
vrrp_instance VI_1 {
|
||||||
state MASTER # ЭТО ГЛАВНЫЙ ХОСТ. ПО УМОЛЧАНИЮ ТРАФИК С VIP БУДЕТ ПЕРЕНАПРАВЛЯТЬСЯ НА ЭТОТ ХОСТ
|
state MASTER # ЭТО ГЛАВНЫЙ ХОСТ. ПО УМОЛЧАНИЮ ТРАФИК С VIP БУДЕТ ПЕРЕНАПРАВЛЯТЬСЯ НА ЭТОТ ХОСТ
|
||||||
@ -537,7 +537,7 @@ vrrp_instance VI_1 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
На втором мастер-узле (хост -- `opi5plus-2`, IP -- `192.168.1.27`):
|
На втором мастер-узле (хост — `opi5plus-2`, IP — `192.168.1.27`):
|
||||||
```text
|
```text
|
||||||
vrrp_instance VI_1 {
|
vrrp_instance VI_1 {
|
||||||
state BACKUP # ЭТО ВТОРОЙ ХОСТ. ОН БУДЕТ ПОЛУЧАТЬ ТРАФИК С VIP, ЕСЛИ ГЛАВНЫЙ ХОСТ УПАДЕТ
|
state BACKUP # ЭТО ВТОРОЙ ХОСТ. ОН БУДЕТ ПОЛУЧАТЬ ТРАФИК С VIP, ЕСЛИ ГЛАВНЫЙ ХОСТ УПАДЕТ
|
||||||
@ -556,7 +556,7 @@ vrrp_instance VI_1 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
И, наконец, на третьем мастер-узле (хост -- `opi5plus-3`, IP -- `192.168.1.28`):
|
И, наконец, на третьем мастер-узле (хост — `opi5plus-3`, IP — `192.168.1.28`):
|
||||||
```text
|
```text
|
||||||
vrrp_instance VI_1 {
|
vrrp_instance VI_1 {
|
||||||
state BACKUP # ЭТО ТРЕТИЙ ХОСТ. ОН БУДЕТ ПОЛУЧАТЬ ТРАФИК С VIP, ЕСЛИ ГЛАВНЫЙ- И БЭКАП-ХОСТ УПАДЕТ
|
state BACKUP # ЭТО ТРЕТИЙ ХОСТ. ОН БУДЕТ ПОЛУЧАТЬ ТРАФИК С VIP, ЕСЛИ ГЛАВНЫЙ- И БЭКАП-ХОСТ УПАДЕТ
|
||||||
@ -588,15 +588,15 @@ ip addr show
|
|||||||
|
|
||||||
то увидим:
|
то увидим:
|
||||||
```text
|
```text
|
||||||
...
|
…
|
||||||
...
|
…
|
||||||
2: enP4p65s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
2: enP4p65s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
|
||||||
link/ether c0:74:2b:fd:42:3c brd ff:ff:ff:ff:ff:ff
|
link/ether c0:74:2b:fd:42:3c brd ff:ff:ff:ff:ff:ff
|
||||||
inet 192.168.1.26/24 brd 192.168.1.255 scope global dynamic noprefixroute enP4p65s0
|
inet 192.168.1.26/24 brd 192.168.1.255 scope global dynamic noprefixroute enP4p65s0
|
||||||
valid_lft 68779sec preferred_lft 68779sec
|
valid_lft 68779sec preferred_lft 68779sec
|
||||||
inet 192.168.1.200/32 scope global enP4p65s0
|
inet 192.168.1.200/32 scope global enP4p65s0
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
...
|
…
|
||||||
```
|
```
|
||||||
Обратите внимание на виртуальный IP-адрес `192.168.1.200` находится в другой подсети (CIDR) и имеет маску `/32` (то
|
Обратите внимание на виртуальный IP-адрес `192.168.1.200` находится в другой подсети (CIDR) и имеет маску `/32` (то
|
||||||
есть с маской подсети `255.255.255.255`). Это "точечная" подсеть, содержащая только один адрес, не привязан к основной
|
есть с маской подсети `255.255.255.255`). Это "точечная" подсеть, содержащая только один адрес, не привязан к основной
|
||||||
@ -652,9 +652,9 @@ vps-sw-eye Ready <none> 35m v1.31.6+k3s1
|
|||||||
|
|
||||||
Таким образом, для управления удаленным узлом нужно чтобы он имел локальный IP-адрес в домашней сети, а не внешний.
|
Таким образом, для управления удаленным узлом нужно чтобы он имел локальный IP-адрес в домашней сети, а не внешний.
|
||||||
SSH-тоннель с помощью `autossh` и упаковкой UDP-трафика в TCP через `socat` не сработает (а я надеялся). Таким образом
|
SSH-тоннель с помощью `autossh` и упаковкой UDP-трафика в TCP через `socat` не сработает (а я надеялся). Таким образом
|
||||||
"пробросить" Flannel для полноценного подключения удаленного k3s-узла -- VPN-туннель между каждой мастер-нодой на
|
"пробросить" Flannel для полноценного подключения удаленного k3s-узла — VPN-туннель между каждой мастер-нодой на
|
||||||
удаленный узел. Это вполне рабочия вариант, если удаленные узлы -- полноценные и произвольные хосты. Но в моём
|
удаленный узел. Это вполне рабочия вариант, если удаленные узлы — полноценные и произвольные хосты. Но в моём
|
||||||
случае удаленный узел -- хост на 1 ядро и 1 ГБ ОЗУ. К тому же он на платформе x86_64, а не ARM, а значит ради одного
|
случае удаленный узел — хост на 1 ядро и 1 ГБ ОЗУ. К тому же он на платформе x86_64, а не ARM, а значит ради одного
|
||||||
узла не стоит заморачиваться с VPN.
|
узла не стоит заморачиваться с VPN.
|
||||||
|
|
||||||
Другим вариантом является подключение внутри самих подов на удаленном узле к необходимым сервисам напрямую. Но таким
|
Другим вариантом является подключение внутри самих подов на удаленном узле к необходимым сервисам напрямую. Но таким
|
||||||
|
@ -9,14 +9,14 @@ SSD NVMe, и для eMMC. Но, как и всякая магия, она мож
|
|||||||
|
|
||||||
## Установка накопителей
|
## Установка накопителей
|
||||||
|
|
||||||
Выключим Orange Pi 5 Plus и установим в него eMMC-носитель...
|
Выключим Orange Pi 5 Plus и установим в него eMMC-носитель…
|
||||||
|
|
||||||
| Фото до и после установки eMMC. Внимание, устанавливайте до щелчка с обоих сторон! |
|
| Фото до и после установки eMMC. Внимание, устанавливайте до щелчка с обоих сторон! |
|
||||||
|:-------------------------------------------------------------------------------------|
|
|:-------------------------------------------------------------------------------------|
|
||||||
|  |
|
|  |
|
||||||
|  |
|
|  |
|
||||||
|
|
||||||
...и/или SSD-накопитель NVMe
|
…и/или SSD-накопитель NVMe
|
||||||
|
|
||||||
| Фото до и после установки NVMe. Более просто в установке. Для надёжности закрепить винтиком. |
|
| Фото до и после установки NVMe. Более просто в установке. Для надёжности закрепить винтиком. |
|
||||||
|:---------------------------------------------------------------------------------------------------|
|
|:---------------------------------------------------------------------------------------------------|
|
||||||
|
@ -61,8 +61,8 @@ ls -al /tmp/boot-backup.tar.gz
|
|||||||
|
|
||||||
Теперь нам нужно скопировать его на какой-нибудь внешний хост (или носитель, но я буду копировать на хост другого
|
Теперь нам нужно скопировать его на какой-нибудь внешний хост (или носитель, но я буду копировать на хост другого
|
||||||
компьютера). Если что-то пойдёт не так (например, после обновления ядра система не загрузится) можно будет восстановить
|
компьютера). Если что-то пойдёт не так (например, после обновления ядра система не загрузится) можно будет восстановить
|
||||||
файлы из этого архива. Мой Orange Pi 5 Plus, на котором я буду компилировать ядро имеет хост -- `opi5plus-3` (замени
|
файлы из этого архива. Мой Orange Pi 5 Plus, на котором я буду компилировать ядро имеет хост — `opi5plus-3` (замени
|
||||||
на свой хост), а имя пользователя от которого я работаю -- `opi` (замени на свой). На рабочем компьютере, с которого
|
на свой хост), а имя пользователя от которого я работаю — `opi` (замени на свой). На рабочем компьютере, с которого
|
||||||
я захожу по SSH на Orange, у меня есть папка `~/backup/` (`mkdir -p ~/backup`). Скачиваю в неё архив:
|
я захожу по SSH на Orange, у меня есть папка `~/backup/` (`mkdir -p ~/backup`). Скачиваю в неё архив:
|
||||||
```bash
|
```bash
|
||||||
scp opi@opi5plus-3.local:/tmp/boot-backup.tar.gz ~/backup/opi5plus-3-boot-backup.tar.gz
|
scp opi@opi5plus-3.local:/tmp/boot-backup.tar.gz ~/backup/opi5plus-3-boot-backup.tar.gz
|
||||||
@ -93,38 +93,38 @@ drwxr-xr-x 3 root root 4096 ноя 21 09:55 dtb-6.1.43-rockchip-rk3588/
|
|||||||
```
|
```
|
||||||
|
|
||||||
Ключевые файлы:
|
Ключевые файлы:
|
||||||
* `Image` -- собственно ядро Linux (в данном случае версия 6.1.43 для Rockchip RK3588). При старте компьютера загрузчик
|
* `Image` — собственно ядро Linux (в данном случае версия 6.1.43 для Rockchip RK3588). При старте компьютера загрузчик
|
||||||
U-Boot загрузит его в память и передаст ему управление. Без этого файла система не запустится.
|
U-Boot загрузит его в память и передаст ему управление. Без этого файла система не запустится.
|
||||||
* `vmlinuz-6.1.43-rockchip-rk3588` -- копия ядра (в системе уже есть резервная копия).
|
* `vmlinuz-6.1.43-rockchip-rk3588` — копия ядра (в системе уже есть резервная копия).
|
||||||
* `dtb/` -- Каталог файлами **Device Tree Blob** (`DTB`). Это бинарные файлы, описывающие аппаратное обеспечение устройства.
|
* `dtb/` — Каталог файлами **Device Tree Blob** (`DTB`). Это бинарные файлы, описывающие аппаратное обеспечение устройства.
|
||||||
Для Orange Pi 5 Plus используется файл вроде `rk3588-orangepi-5-plus.dtb` (находится в подкаталоге `dtb/rockchip/`).
|
Для Orange Pi 5 Plus используется файл вроде `rk3588-orangepi-5-plus.dtb` (находится в подкаталоге `dtb/rockchip/`).
|
||||||
DTB передаётся ядру, чтобы оно знало, как работать с процессором (количество ядер, частоты), памятью (RAM, её объём
|
DTB передаётся ядру, чтобы оно знало, как работать с процессором (количество ядер, частоты), памятью (RAM, её объём
|
||||||
и адреса), периферией (UART, I2C, SPI, Ethernet, USB, GPIO, прерывания и тому подобное). На ARM-устройствах
|
и адреса), периферией (UART, I2C, SPI, Ethernet, USB, GPIO, прерывания и тому подобное). На ARM-устройствах
|
||||||
(в отличие от x86, где есть ACPI) нет стандартного способа обнаружения оборудования. DTB решает эту проблему,
|
(в отличие от x86, где есть ACPI) нет стандартного способа обнаружения оборудования. DTB решает эту проблему,
|
||||||
предоставляя ядру "карту" железа. U-Boot загружает DTB из `/boot/dtb/ `и передаёт его ядру при старте. Кстати,
|
предоставляя ядру "карту" железа. U-Boot загружает DTB из `/boot/dtb/ `и передаёт его ядру при старте. Кстати,
|
||||||
в подкаталоге dtb/rockchip/ есть `overlay/` -- это дополнительные файлы, которые могут использоваться для добавления
|
в подкаталоге dtb/rockchip/ есть `overlay/` — это дополнительные файлы, которые могут использоваться для добавления
|
||||||
и/или изменения функциональности устройства. Например, можно добавить поддержку новых периферийных устройств (камеру,
|
и/или изменения функциональности устройства. Например, можно добавить поддержку новых периферийных устройств (камеру,
|
||||||
дисплей и т.п.).
|
дисплей и т.п.).
|
||||||
* `uInitrd` -- Начальный RAM-диск (initrd), адаптированный для U-Boot. Содержит модули и скрипты, необходимые для
|
* `uInitrd` — Начальный RAM-диск (initrd), адаптированный для U-Boot. Содержит модули и скрипты, необходимые для
|
||||||
пред-загрузки (выбор накопителя, монтирование корневой файловой системы и т.п.). Если он повреждён или несовместим
|
пред-загрузки (выбор накопителя, монтирование корневой файловой системы и т.п.). Если он повреждён или несовместим
|
||||||
с ядром, загрузка может упасть на этапе инициализации.
|
с ядром, загрузка может упасть на этапе инициализации.
|
||||||
* `orangepiEnv.txt` -- Конфигурационный файл для U-Boot. Здесь задаются параметры загрузки, такие как путь расположение
|
* `orangepiEnv.txt` — Конфигурационный файл для U-Boot. Здесь задаются параметры загрузки, такие как путь расположение
|
||||||
дерева DTB, UUID корневой файловой системы, тип файловой системы... Без правильных настроек в этом файле U-Boot не
|
дерева DTB, UUID корневой файловой системы, тип файловой системы… Без правильных настроек в этом файле U-Boot не
|
||||||
найдёт нужные для загрузки файлы.
|
найдёт нужные для загрузки файлы.
|
||||||
* `boot.scr` -- Скрипт загрузки для U-Boot. Содержит команды для загрузки ядра, initrd и DTB. U-Boot выполняет его
|
* `boot.scr` — Скрипт загрузки для U-Boot. Содержит команды для загрузки ядра, initrd и DTB. U-Boot выполняет его
|
||||||
при старте системы. Этот файл создаётся из `boot.cmd` с помощью утилиты `mkimage`. Если он повреждён или отсутствует,
|
при старте системы. Этот файл создаётся из `boot.cmd` с помощью утилиты `mkimage`. Если он повреждён или отсутствует,
|
||||||
U-Boot не сможет загрузить систему.
|
U-Boot не сможет загрузить систему.
|
||||||
* `dtb-6.1.43-rockchip-rk3588/` -- Копия каталога `dtb/`, обычно появляется, когда ядро устанавливается или обновляется
|
* `dtb-6.1.43-rockchip-rk3588/` — Копия каталога `dtb/`, обычно появляется, когда ядро устанавливается или обновляется
|
||||||
через пакетный менеджер (например, `apt`). Она привязана к конкретной версии ядра — в данном случае
|
через пакетный менеджер (например, `apt`). Она привязана к конкретной версии ядра — в данном случае
|
||||||
`6.1.43-rockchip-rk3588`, для того, чтобы: Хранить DTB-файлы, соответствующие этой версии ядра и избегать конфликты
|
`6.1.43-rockchip-rk3588`, для того, чтобы: Хранить DTB-файлы, соответствующие этой версии ядра и избегать конфликты
|
||||||
между DTB от разных версий ядра (если используется несколько ядер на одной системе).
|
между DTB от разных версий ядра (если используется несколько ядер на одной системе).
|
||||||
|
|
||||||
Менее критичные, но полезные файлы:
|
Менее критичные, но полезные файлы:
|
||||||
* `config-6.1.43-rockchip-rk3588` -- Конфигурация ядра, использованная при его сборке (он нам понадобится, чтобы
|
* `config-6.1.43-rockchip-rk3588` — Конфигурация ядра, использованная при его сборке (он нам понадобится, чтобы
|
||||||
пересобрать ядро с iSCSI).
|
пересобрать ядро с iSCSI).
|
||||||
* `System.map-6.1.43-rockchip-rk3588` -- Карта меток (символов) ядра, полезна для отладки.
|
* `System.map-6.1.43-rockchip-rk3588` — Карта меток (символов) ядра, полезна для отладки.
|
||||||
* `initrd.img-6.1.43-rockchip-rk3588` -- Обычный initrd, из которого генерируется uInitrd.
|
* `initrd.img-6.1.43-rockchip-rk3588` — Обычный initrd, из которого генерируется uInitrd.
|
||||||
* `boot.bmp` и `logo.bmp` -- Изображения для экрана загрузки (не влияют на работу системы).
|
* `boot.bmp` и `logo.bmp` — Изображения для экрана загрузки (не влияют на работу системы).
|
||||||
|
|
||||||
## Устанавливать инструменты для сборки ядра
|
## Устанавливать инструменты для сборки ядра
|
||||||
|
|
||||||
@ -136,13 +136,13 @@ sudo apt install -y build-essential bc flex bison libssl-dev libncurses-dev git
|
|||||||
|
|
||||||
Нам понадобятся следующие пакеты:
|
Нам понадобятся следующие пакеты:
|
||||||
|
|
||||||
* `build-essential` -- Включает `gcc` (для ARM64, make и другие базовые инструменты компиляции.
|
* `build-essential` — Включает `gcc` (для ARM64, make и другие базовые инструменты компиляции.
|
||||||
* `bc` -- Утилита для точных математических вычислений в командной строке. Используется для вычислений в скриптах сборки ядра.
|
* `bc` — Утилита для точных математических вычислений в командной строке. Используется для вычислений в скриптах сборки ядра.
|
||||||
* `flex` и `bison` -- генератор лексических анализаторов и парсер. Нужны для обработки конфигурационных файлов ядра.
|
* `flex` и `bison` — генератор лексических анализаторов и парсер. Нужны для обработки конфигурационных файлов ядра.
|
||||||
* `libssl-dev` -- Для поддержки криптографии в ядре и `OpenSSL`.
|
* `libssl-dev` — Для поддержки криптографии в ядре и `OpenSSL`.
|
||||||
* `libncurses-dev` -- Библиотека для создания текстовых интерфейсов в терминале. Необходимо для работы интерфейса
|
* `libncurses-dev` — Библиотека для создания текстовых интерфейсов в терминале. Необходимо для работы интерфейса
|
||||||
`menuconfig` при настройке параметров ядра.
|
`menuconfig` при настройке параметров ядра.
|
||||||
* `git` -- Для клонирования исходного кода ядра из репозитория Xunlong.
|
* `git` — Для клонирования исходного кода ядра из репозитория Xunlong.
|
||||||
|
|
||||||
> **Примечание:** Если вы хотите собрать ядро на x86-системе, установите кросс-компилятор `gcc-aarch64-linux-gnu` (`sudo apt install gcc-aarch64-linux-gnu`) и используйте его вместо обычного gcc в командах сборки. Он позволит собрать ядро для ARM64-архитектуры на x86-системе.
|
> **Примечание:** Если вы хотите собрать ядро на x86-системе, установите кросс-компилятор `gcc-aarch64-linux-gnu` (`sudo apt install gcc-aarch64-linux-gnu`) и используйте его вместо обычного gcc в командах сборки. Он позволит собрать ядро для ARM64-архитектуры на x86-системе.
|
||||||
|
|
||||||
@ -314,10 +314,10 @@ sudo reboot
|
|||||||
|
|
||||||
Если вы все делали правильно, то такого быть не должно. Но, тем не менее, если загрузка не произошла, то это может
|
Если вы все делали правильно, то такого быть не должно. Но, тем не менее, если загрузка не произошла, то это может
|
||||||
выглядеть двумя способами:
|
выглядеть двумя способами:
|
||||||
* Система зависает на этапе загрузки: синенький огонек на Orange Pi не загорается и Ethernet тоже не мигает --
|
* Система зависает на этапе загрузки: синенький огонек на Orange Pi не загорается и Ethernet тоже не мигает —
|
||||||
_вы неправильно собрали ядро или испортили загрузчик_.
|
_вы неправильно собрали ядро или испортили загрузчик.
|
||||||
* Система, вроде как, грузится, но все никак... огоньки весело мигают, но не получается подключиться ни по SSH, ни
|
* Система, вроде как, грузится, но все никак… огоньки весело мигают, но не получается подключиться ни по SSH, ни
|
||||||
другим способом, пинги на IP-адрес не проходят -- _вы забыли подключить модули, накосячили с конфигом или с `.dtb`_.
|
другим способом, пинги на IP-адрес не проходят — вы забыли подключить модули, накосячили с конфигом или с `.dtb`_.
|
||||||
|
|
||||||
Чтобы починить, загружайтесь с MicroSD-карты (не забудьте отключить питание перед тем как вставить MicroSD-карту).
|
Чтобы починить, загружайтесь с MicroSD-карты (не забудьте отключить питание перед тем как вставить MicroSD-карту).
|
||||||
Затем смонтируйте, в зависимости где у вас система, eMMC:
|
Затем смонтируйте, в зависимости где у вас система, eMMC:
|
||||||
@ -327,7 +327,7 @@ mount /dev/mmcblk2p1 /mnt/emmc
|
|||||||
cd /mnt/emmc
|
cd /mnt/emmc
|
||||||
```
|
```
|
||||||
|
|
||||||
...или NVMe:
|
…или NVMe:
|
||||||
```bash
|
```bash
|
||||||
mkdir -p /mnt/nvme
|
mkdir -p /mnt/nvme
|
||||||
mount /dev/nvme0n1p1 /mnt/nvme
|
mount /dev/nvme0n1p1 /mnt/nvme
|
||||||
|
Loading…
x
Reference in New Issue
Block a user