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

8.4 KiB
Raw Blame History

Kraken — Portainer Access & Cloudflared SSH Tunnel

Статус: cloudflared pending — ждём CF Tunnel token от Alex

Portainer

Параметр Значение
URL http://localhost:9000
Auth header X-API-Key: ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g=
Endpoint ID уточнить через GET /api/endpoints (обычно 1 для local Docker)

Portainer API — Quick Reference

BASE=http://localhost:9000
KEY="ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g="
EP=1  # endpoint ID

# Список endpoints (узнать EP)
curl -s -H "X-API-Key: $KEY" $BASE/api/endpoints | jq '[.[].Id]'

# Список контейнеров
curl -s -H "X-API-Key: $KEY" "$BASE/api/endpoints/$EP/docker/containers/json?all=true" | jq '[.[] | {name: .Names[0], status: .Status, image: .Image}]'

# Создать контейнер
curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  "$BASE/api/endpoints/$EP/docker/containers/create?name=<NAME>" \
  -d '<JSON>'

# Запустить контейнер
curl -s -X POST -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/<ID>/start"

# Логи
curl -s -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/<ID>/logs?stdout=1&stderr=1&tail=50"

# Удалить контейнер
curl -s -X DELETE -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/<ID>"

Временный Alpine-контейнер (запустить команду на хосте)

Для разовых задач (записать файл, проверить путь и т.д.) — alpine с bind /:/host:

BASE=http://localhost:9000
KEY="ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g="
EP=1

# 1. Создать
ID=$(curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  "$BASE/api/endpoints/$EP/docker/containers/create?name=alpine-tmp-$$" \
  -d '{
    "Image": "alpine",
    "Cmd": ["sh", "-c", "echo hello from host > /host/tmp/test.txt && echo DONE"],
    "HostConfig": {
      "Binds": ["/:/host"],
      "AutoRemove": false
    }
  }' | jq -r '.Id')

# 2. Запустить
curl -s -X POST -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$ID/start"

# 3. Подождать завершения (1-2 сек) и забрать логи
sleep 2
curl -s -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$ID/logs?stdout=1&stderr=1"

# 4. Удалить
curl -s -X DELETE -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$ID"

⚠️ AutoRemove: false — обязательно, иначе контейнер удалится до того как получишь логи ⚠️ Используй alpine, не alpine/git и подобные — у них есть ENTRYPOINT, sh -c не сработает


Cloudflared — деплой

Шаг 1 — Получить CF Tunnel token (делает Alex вручную)

  1. Открыть Cloudflare Zero Trust → Networks → Tunnels
  2. Create a tunnel → Cloudflared → назвать kraken
  3. На шаге "Install connector": скопировать команду вида:
    cloudflared service install eyJ...
    
    Нас интересует только токен — длинная строка после service install
  4. Сохранить токен — вписать в эту заметку ниже

CF Tunnel Token:

<ВСТАВИТЬ СЮДА ТОКЕН ПОСЛЕ СОЗДАНИЯ ТОННЕЛЯ>

Шаг 2 — Создать docker-compose.yml через alpine

Используем alpine-контейнер с bind /:/host для записи файла:

BASE=http://localhost:9000
KEY="ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g="
EP=1
TOKEN="<CF_TUNNEL_TOKEN>"

COMPOSE_B64=$(echo "services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: [\"tunnel\", \"--no-autoupdate\", \"run\"]
    environment:
      - TUNNEL_TOKEN=${TOKEN}
    network_mode: host" | base64 | tr -d '\n')

ID=$(curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  "$BASE/api/endpoints/$EP/docker/containers/create?name=alpine-setup-$$" \
  -d "{
    \"Image\": \"alpine\",
    \"Cmd\": [\"sh\", \"-c\", \"mkdir -p /host/home/kraken/cloudflared && echo ${COMPOSE_B64} | base64 -d > /host/home/kraken/cloudflared/docker-compose.yml && echo DONE\"],
    \"HostConfig\": {
      \"Binds\": [\"/:/host\"],
      \"AutoRemove\": false
    }
  }" | jq -r '.Id')

curl -s -X POST -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$ID/start"
sleep 2
curl -s -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$ID/logs?stdout=1&stderr=1"
curl -s -X DELETE -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$ID"

Шаг 3 — Поднять cloudflared контейнер через Portainer API

BASE=http://localhost:9000
KEY="ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g="
EP=1
TOKEN="<CF_TUNNEL_TOKEN>"

# Создать контейнер
CID=$(curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  "$BASE/api/endpoints/$EP/docker/containers/create?name=cloudflared" \
  -d "{
    \"Image\": \"cloudflare/cloudflared:latest\",
    \"Cmd\": [\"tunnel\", \"--no-autoupdate\", \"run\"],
    \"Env\": [\"TUNNEL_TOKEN=${TOKEN}\"],
    \"HostConfig\": {
      \"RestartPolicy\": {\"Name\": \"unless-stopped\"},
      \"NetworkMode\": \"host\"
    }
  }" | jq -r '.Id')

# Запустить
curl -s -X POST -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$CID/start"

echo "Container ID: $CID"

Шаг 4 — Проверить логи

BASE=http://localhost:9000
KEY="ptr_AJY+Ba9A7f6pcAHZfDD5koU4stkKgJCdbTEXLDLxn0g="
EP=1
CID=$(curl -s -H "X-API-Key: $KEY" "$BASE/api/endpoints/$EP/docker/containers/json?all=true" | jq -r '.[] | select(.Names[] | contains("cloudflared")) | .Id')

curl -s -H "X-API-Key: $KEY" \
  "$BASE/api/endpoints/$EP/docker/containers/$CID/logs?stdout=1&stderr=1&tail=30"

Ожидаем в логах:

INF Registered tunnel connection connIndex=0 ... protocol=http2
INF Connection ... registered connIndex=0
INF Connection ... registered connIndex=1
...

Если видишь все 4 соединения — туннель активен.

Шаг 5 — Обновить статус в этой заметке

Заменить ⏳ cloudflared pending в заголовке на ✅ cloudflared запущен.


Что делает Alex после запуска (вручную в CF Zero Trust)

После того как cloudflared запущен и туннель появился как Active в Zero Trust:

  1. Открыть туннель krakenEdit → вкладка Public HostnameAdd a public hostname
  2. Добавить поддомен SSH:
    • Subdomain: ssh
    • Domain: kraken.qentra.top (создать заранее в DNS)
    • Service type: SSH
    • URL: localhost:22
  3. Сохранить — DNS запись создаётся автоматически

Повторить для других сервисов если нужно:

  • omv.kraken.qentra.top → HTTP → localhost:80 (OMV Web UI)
  • portainer.kraken.qentra.top → HTTP → localhost:9000

⚠️ Аналогично тому как настраивался zulip.qentra.top на Eagle: токен получается при создании тоннеля в Zero Trust → вставляется в TUNNEL_TOKEN


SSH-доступ через Cloudflare Tunnel (с Eagle)

После настройки поддомена добавить в ~/.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 уже есть (используется для zulip.qentra.top)


Связанные заметки