Files
obsidian-vault/family/how-to/kraken-portainer-access.md
T

169 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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