[2026-05-13] Add kraken-portainer-access.md: cloudflared docker deploy instructions
This commit is contained in:
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"workspace:new-window": [
|
||||||
|
{
|
||||||
|
"modifiers": [
|
||||||
|
"Mod",
|
||||||
|
"Shift"
|
||||||
|
],
|
||||||
|
"key": "N"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"file-explorer:new-file-in-new-pane": []
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
# Kraken — Portainer Access & Cloudflared SSH Tunnel
|
||||||
|
|
||||||
|
> Статус: ⏳ cloudflared pending deploy (см. инструкции ниже)
|
||||||
|
|
||||||
|
## Portainer
|
||||||
|
|
||||||
|
| Параметр | Значение |
|
||||||
|
|---|---|
|
||||||
|
| URL (локальный) | http://localhost:9000 |
|
||||||
|
| Auth header | `X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=` |
|
||||||
|
| Endpoint ID | 1 (local Docker) |
|
||||||
|
|
||||||
|
## Cloudflare Tunnel Token
|
||||||
|
|
||||||
|
```
|
||||||
|
eyJhIjoiODFlOGYwYThmMzg5ZTllNzg3NGFmMTE3NGQxYzIxOTIiLCJ0IjoiNjQxMGI0YTYtZWUyMS00MTczLWJhMzItMTcwOGY1MjNlNDMyIiwicyI6Ik9XWmpNVEkxWVRFdE9EWXpZaTAwWlRjNExXSTBaVFl0TkdNeU16Z3daV0pqTW1RMyJ9
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Задача для Кракен Hermes
|
||||||
|
|
||||||
|
Поднять `cloudflare/cloudflared` в Docker через Portainer API. После запуска Alex добавит SSH-поддомен в Cloudflare Zero Trust (вручную, как делал для `zulip.qentra.top`).
|
||||||
|
|
||||||
|
### Шаг 1 — Проверить Portainer и Docker endpoint
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Получить список endpoints (endpoint ID нужен для всех последующих запросов)
|
||||||
|
curl -s -H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
|
||||||
|
http://localhost:9000/api/endpoints | jq '.[].Id'
|
||||||
|
# Ожидаем: 1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 2 — Создать контейнер cloudflared через Portainer API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать контейнер (не запускать)
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
"http://localhost:9000/api/endpoints/1/docker/containers/create?name=cloudflared" \
|
||||||
|
-d '{
|
||||||
|
"Image": "cloudflare/cloudflared:latest",
|
||||||
|
"Cmd": ["tunnel", "--no-autoupdate", "run"],
|
||||||
|
"Env": [
|
||||||
|
"TUNNEL_TOKEN=eyJhIjoiODFlOGYwYThmMzg5ZTllNzg3NGFmMTE3NGQxYzIxOTIiLCJ0IjoiNjQxMGI0YTYtZWUyMS00MTczLWJhMzItMTcwOGY1MjNlNDMyIiwicyI6Ik9XWmpNVEkxWVRFdE9EWXpZaTAwWlRjNExXSTBaVFl0TkdNeU16Z3daV0pqTW1RMyJ9"
|
||||||
|
],
|
||||||
|
"HostConfig": {
|
||||||
|
"RestartPolicy": {"Name": "unless-stopped"},
|
||||||
|
"NetworkMode": "host"
|
||||||
|
}
|
||||||
|
}' | jq -r '.Id'
|
||||||
|
# Сохранить полученный container ID
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 3 — Запустить контейнер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CONTAINER_ID="<id из шага 2>"
|
||||||
|
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
|
||||||
|
"http://localhost:9000/api/endpoints/1/docker/containers/${CONTAINER_ID}/start"
|
||||||
|
# Ожидаем: пустой ответ или 204 No Content = OK
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 4 — Проверить логи
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s \
|
||||||
|
-H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
|
||||||
|
"http://localhost:9000/api/endpoints/1/docker/containers/${CONTAINER_ID}/logs?stdout=true&stderr=true&tail=30" \
|
||||||
|
| strings
|
||||||
|
# Ожидаем в логах:
|
||||||
|
# INF Registered tunnel connection connIndex=0 ... protocol=http2
|
||||||
|
# INF Connection ... registered connIndex=0..3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 5 — Создать docker-compose.yml для постоянного управления
|
||||||
|
|
||||||
|
Через Alpine-контейнер с доступом к хосту:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать alpine контейнер, который запишет compose-файл на хост
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
"http://localhost:9000/api/endpoints/1/docker/containers/create?name=alpine-setup" \
|
||||||
|
-d '{
|
||||||
|
"Image": "alpine:latest",
|
||||||
|
"Cmd": ["sh", "-c", "mkdir -p /host/home/kraken/cloudflared && cat > /host/home/kraken/cloudflared/docker-compose.yml << '"'"'EOF'"'"'\nservices:\n cloudflared:\n image: cloudflare/cloudflared:latest\n container_name: cloudflared\n restart: unless-stopped\n command: [\"tunnel\", \"--no-autoupdate\", \"run\"]\n environment:\n - TUNNEL_TOKEN=eyJhIjoiODFlOGYwYThmMzg5ZTllNzg3NGFmMTE3NGQxYzIxOTIiLCJ0IjoiNjQxMGI0YTYtZWUyMS00MTczLWJhMzItMTcwOGY1MjNlNDMyIiwicyI6Ik9XWmpNVEkxWVRFdE9EWXpZaTAwWlRjNExXSTBaVFl0TkdNeU16Z3daV0pqTW1RMyJ9\n network_mode: host\nEOF\necho DONE"],
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": ["/:/host"],
|
||||||
|
"AutoRemove": true
|
||||||
|
}
|
||||||
|
}' | jq -r '.Id'
|
||||||
|
|
||||||
|
# Запустить alpine контейнер
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=" \
|
||||||
|
"http://localhost:9000/api/endpoints/1/docker/containers/<alpine-id>/start"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Шаг 6 — Обновить Obsidian
|
||||||
|
|
||||||
|
После успешного запуска cloudflared — обновить статус в этой заметке: `Статус: ⏳` → `Статус: ✅ cloudflared запущен`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что делает Alex вручную (после запуска)
|
||||||
|
|
||||||
|
1. Открыть [Cloudflare Zero Trust → Networks → Tunnels](https://one.dash.cloudflare.com/)
|
||||||
|
2. Найти туннель (должен появиться как активный после запуска контейнера)
|
||||||
|
3. Нажать **Edit** → вкладка **Public Hostname** → **Add a public hostname**:
|
||||||
|
- Subdomain: `ssh`
|
||||||
|
- Domain: `kraken.qentra.top` (или другой по вкусу)
|
||||||
|
- Service type: **SSH**
|
||||||
|
- URL: `localhost:22`
|
||||||
|
4. Сохранить → DNS запись создаётся автоматически
|
||||||
|
|
||||||
|
> Повторить для других сервисов если нужно:
|
||||||
|
> - `omv.kraken.qentra.top` → HTTP → `localhost:80`
|
||||||
|
> - `portainer.kraken.qentra.top` → HTTP → `localhost:9000`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SSH-доступ через Cloudflare Tunnel (с любой машины)
|
||||||
|
|
||||||
|
После настройки поддомена Alex создаёт скилл на Eagle для доступа к Кракену через тоннель (аналог Таига через alpine+portainer):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Один раз настроить ~/.ssh/config на Eagle:
|
||||||
|
Host ssh.kraken.qentra.top
|
||||||
|
ProxyCommand cloudflared access ssh --hostname %h
|
||||||
|
User kraken
|
||||||
|
IdentityFile ~/.ssh/id_rsa
|
||||||
|
StrictHostKeyChecking no
|
||||||
|
|
||||||
|
# Подключиться:
|
||||||
|
ssh ssh.kraken.qentra.top
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ `cloudflared` должен быть установлен на клиентской машине (Eagle).
|
||||||
|
> На Eagle уже есть — он используется для `zulip.qentra.top`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Проверка что туннель работает
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# На Кракене: посмотреть статус контейнера
|
||||||
|
docker ps | grep cloudflared
|
||||||
|
|
||||||
|
# Логи cloudflared
|
||||||
|
docker logs cloudflared --tail 20
|
||||||
|
|
||||||
|
# С Eagle (после настройки DNS): тест SSH
|
||||||
|
ssh -o ProxyCommand="cloudflared access ssh --hostname ssh.kraken.qentra.top" \
|
||||||
|
-i ~/.ssh/id_rsa kraken@ssh.kraken.qentra.top whoami
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Связанные заметки
|
||||||
|
|
||||||
|
- [[openmediavault-rpi5]] — настройка Kraken (Docker, Hermes, структура папок)
|
||||||
|
- [[truenas-infrastructure]] — Taiga (аналогичный подход через Portainer)
|
||||||
|
- [[obsidian-sync]] — синхронизация vault
|
||||||
Reference in New Issue
Block a user