We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

  Назад к списку статей

Разработка и деплой микросервисов на Node.js/Go в Termux с использованием Kubernetes‑lite (k3s): контейнеризация, сервис‑дискавери и масштабирование

Termux давно перестал быть «только терминалом»: сегодня на Android реально организовать локальный контур для разработки, сборки образов, запуска Kubernetes‑lite (k3s) и последующего деплоя микросервисов. В этой статье покажу практический подход к построению небольшого кластера (k3s) в локальной среде, чтобы протестировать сервис‑дискавери, сетевую связность, горизонтальное масштабирование и наблюдаемость без сложной инфраструктуры.

Фокус: Node.js/Go микросервисы, контейнеризация, k3s, Ingress/LB‑подобные сценарии для локального доступа и шаблоны для расширения системы.

Архитектура решения: что именно мы собираем

В рамках локальной разработки обычно достаточно следующей структуры:

  • Termux — рабочая среда, где вы пишете код, собираете образы и управляете деплоем.
  • k3s (Kubernetes‑lite) — локальный кластер, в котором поды выполняют ваши микросервисы.
  • Контейнеризация — Docker/Buildah‑подобный процесс в Termux (или сборка на внешней машине с последующим переносом образов) в зависимости от доступности окружения.
  • Сервис‑дискавери — доступ между сервисами по DNS‑именам Kubernetes (например, service-name.namespace.svc.cluster.local).
  • Масштабирование — через Deployment и replicas + обновления.

Важно: мы делаем локальную сеть и тестируем функциональность. Ниже я не использую сценарии для обхода блокировок.

Требования и подготовка окружения в Termux

Подготовьте Android‑устройство и Termux. Базовые требования:

  • Termux установлен
  • Достаточно места под контейнеры/образы
  • Сетевая связность внутри вашей локальной среды (или через устройство‑хост, если кластер поднимается не строго «на телефоне»)

Начнем с обновления пакетов и установки минимального набора утилит. В зависимости от вашей сборки Termux‑репозитория названия пакетов могут отличаться, но логика остается той же.

pkg update && pkg upgrade -y
pkg install -y git curl ca-certificates tar gzip unzip
pkg install -y nodejs npm
pkg install -y golang

Если вам нужен CLI‑подход к Kubernetes и k3s, обычно требуется либо бинарник k3s, либо установка через удобный скрипт. В этой статье ориентируемся на «локальный кластер» через k3s и стандартные Kubernetes‑манифесты.

Контейнеризация микросервисов: Node.js и Go

Ниже — два примера микросервисов с минимальным API. Логику выбирайте под ваш домен, а шаблоны используйте как основу.

Пример: Node.js микросервис

Создайте проект:

mkdir -p ~/projects/k3s-demo/node-svc
cd ~/projects/k3s-demo/node-svc
npm init -y

Установите зависимости (минимально — express):

npm install express

Создайте server.js:

cat > server.js <<'EOF'
const express = require('express');

const app = express();
const port = process.env.PORT || 3000;

app.get('/healthz', (req, res) => res.status(200).json({ ok: true }));

app.get('/hello', (req, res) => {
  const from = process.env.HOSTNAME || 'unknown';
  res.json({ message: 'Hello from Node.js', from });
});

app.listen(port, () => {
  console.log(Node service listening on ${port});
});
EOF

Добавьте Dockerfile. Даже если вы собираете не внутри Termux, этот файл пригодится для переноса/сборки на любой среде:

cat > Dockerfile <<'EOF'
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm ci --only=production
COPY . .
ENV PORT=3000
EXPOSE 3000
CMD ["node", "server.js"]
EOF

Соберите образ. Команда зависит от того, есть ли у вас доступ к Docker/daemon на Android. Если вы собираете локально в Termux — используйте доступный движок. Если daemon недоступен, сборку логичнее делать на ПК/сервере и переносить образ в registry. Для примера показан стандартный вариант с Docker:

docker build -t local/node-svc:1.0.0 .

Если Docker внутри Termux недоступен, можно собрать образ на внешней машине, а затем загрузить в registry или перенести через docker save/docker load (в зависимости от вашей инфраструктуры разработки).

Пример: Go микросервис

Создайте проект:

mkdir -p ~/projects/k3s-demo/go-svc
cd ~/projects/k3s-demo/go-svc
go mod init go-svc

Создайте main.go:

cat > main.go <<'EOF'
package main

import (
  "encoding/json"
  "net/http"
  "os"
)

func main() {
  port := os.Getenv("PORT")
  if port == "" {
    port = "8080"
  }

  http.HandleFunc("/healthz", func(w http.ResponseWriter, r http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    _ = json.NewEncoder(w).Encode(map[string]any{"ok": true})
  })

  http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    from := os.Getenv("HOSTNAME")
    if from == "" {
      from = "unknown"
    }
    _ = json.NewEncoder(w).Encode(map[string]any{
      "message": "Hello from Go",
      "from":    from,
    })
  })

  addr := ":" + port
  http.ListenAndServe(addr, nil)
}
EOF

Добавьте Dockerfile:

cat > Dockerfile <<'EOF'
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN go build -o /app/server main.go

FROM alpine:3.20
WORKDIR /app
COPY --from=builder /app/server /app/server
ENV PORT=8080
EXPOSE 8080
CMD ["/app/server"]
EOF

Соберите образ:

docker build -t local/go-svc:1.0.0 .

Подготовка Kubernetes‑lite (k3s)

k3s предоставляет минимально необходимый набор компонентов Kubernetes для разработки. В зависимости от того, поднимаете ли вы кластер прямо на телефоне или на отдельном хосте, схема шагов может отличаться. Логику манифестов ниже можно применять в любом варианте.

Сценарий для локального кластера (типовой): вы запускаете k3s, получаете доступ к Kubernetes API, а затем применяете манифесты через kubectl.

Базовая проверка после поднятия k3s:

kubectl get nodes
kubectl get pods -A

Namespace и образы

Создадим рабочее пространство имен:

kubectl create namespace demo

Далее определим, как будут доставляться образы. На практике:

  • Если у вас локальный registry — используйте его URL в тегах образов.
  • Если у вас нет registry — иногда настраивают локальное подключение образов к runtime (зависит от окружения).

Для примера я покажу манифесты, где образы находятся по local/.... В реальном проекте подставьте ваш registry/способ доставки образов.

Деплой микросервисов: Deployment + Service

Node.js Deployment и Service

Создайте манифест node-deployment.yaml:

cat > node-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-svc
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-svc
  template:
    metadata:
      labels:
        app: node-svc
    spec:
      containers:
        - name: node-svc
          image: local/node-svc:1.0.0
          ports:
            - containerPort: 3000
          readinessProbe:
            httpGet:
              path: /healthz
              port: 3000
            initialDelaySeconds: 3
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /healthz
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 20
EOF

Создайте Service node-service.yaml:

cat > node-service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
  name: node-svc
  namespace: demo
spec:
  selector:
    app: node-svc
  ports:
    - name: http
      port: 80
      targetPort: 3000
  type: ClusterIP
EOF

Примените манифесты:

kubectl apply -f node-deployment.yaml
kubectl apply -f node-service.yaml

Go Deployment и Service

Создайте go-deployment.yaml:

cat > go-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-svc
  namespace: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: go-svc
  template:
    metadata:
      labels:
        app: go-svc
    spec:
      containers:
        - name: go-svc
          image: local/go-svc:1.0.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 3
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 20
EOF

Создайте go-service.yaml:

cat > go-service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
  name: go-svc
  namespace: demo
spec:
  selector:
    app: go-svc
  ports:
    - name: http
      port: 80
      targetPort: 8080
  type: ClusterIP
EOF

Примените:

kubectl apply -f go-deployment.yaml
kubectl apply -f go-service.yaml

Сервис‑дискавери: проверяем DNS внутри кластера

Kubernetes автоматически создает DNS‑записи для сервисов. Для сервисов в namespace demo доступ обычно выглядит так:

  • node-svc (внутри того же namespace)
  • node-svc.demo.svc.cluster.local (полный FQDN)
  • Аналогично для go-svc

Проверим связность через временный Pod с curl. Для удобства создадим Job или однократный Pod. Например, используйте BusyBox:

kubectl run -n demo tmp-curl --image=busybox:1.36 --restart=Never -- /bin/sh -c "sleep 2 && wget -qO- http://node-svc/hello && echo && wget -qO- http://go-svc/hello"

Если все настроено, вы увидите JSON‑ответы от обоих сервисов. Это и есть базовая «магия» сервис‑дискавери.

Маршрутизация для локального доступа: Ingress (опционально)

В локальном k3s часто удобно использовать Ingress для доступа снаружи к ClusterIP сервисам. Конкретный контроллер зависит от вашей конфигурации k3s.

Если у вас есть ingress‑контроллер, создайте, например, простой Ingress для Node.js сервиса. Подставьте доступный host (в локальной сети) или используйте wildcard/локальный домен в зависимости от ваших настроек.

cat > node-ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: node-ingress
  namespace: demo
spec:
  rules:
    - host: node.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: node-svc
                port:
                  number: 80
EOF

Примените:

kubectl apply -f node-ingress.yaml

Доступ извне будет зависеть от того, как вы резолвите node.local в вашей локальной сети. Часто используют записи в /etc/hosts на тестовом устройстве или локальный DNS.

Масштабирование: горизонтальное увеличение replicas

Для базового горизонтального масштабирования достаточно увеличить spec.replicas в Deployment.

Например, увеличим Node.js до 4 реплик:

kubectl scale deployment/node-svc -n demo --replicas=4

Проверим:

kubectl get pods -n demo -l app=node-svc -o wide

Для проверки, что масштабирование работает как ожидается, вызывайте /hello и смотрите на поле from (hostname контейнеров), чтобы убедиться, что запросы обслуживаются разными Pod‑ами.

Обновления версий: rolling update

Чтобы обновить сервис, поменяйте образ и повторно примените манифест или используйте:

kubectl set image deployment/node-svc -n demo node-svc=local/node-svc:1.1.0

Следите за статусом развертывания:

kubectl rollout status deployment/node-svc -n demo
kubectl get pods -n demo -l app=node-svc -w

Наблюдаемость в локальной среде: что контролировать

Минимальный набор, который стоит держать в привычке:

  • Статусы Pod: kubectl get pods -n demo
  • Логи контейнеров: kubectl logs -n demo <pod>
  • События (events): kubectl get events -n demo --sort-by=.metadata.creationTimestamp

Пример просмотра логов:

kubectl logs -n demo -l app=go-svc --tail=100

Практические советы для Termux + k3s

  • Разделяйте сборку и деплой: если сборка образов в Termux неудобна из‑за ограничений Android‑окружения, логичнее собирать на ПК, а деплой делать в k3s.
  • Тестируйте DNS и сервисы отдельно: сначала убедитесь, что ClusterIP сервисы доступны изнутри (tmp‑curl), и только потом подключайте Ingress.
  • Используйте healthz: readiness/liveness сильно упрощают работу в маленьком кластере.
  • Думайте про версионирование: фиксируйте теги образов (semver), чтобы rolling update был предсказуемым.

Выводы

Мы рассмотрели практический путь разработки и деплоя микросервисов Node.js и Go в локальной Kubernetes‑lite среде k3s: контейнеризация через Dockerfile, развертывание Deployment+Service, проверка сервис‑дискавери через Kubernetes DNS и базовое масштабирование replicas. Такой подход отлично подходит для обучения, прототипирования и отладки микросервисной архитектуры в «домашних» условиях.

Если хотите быстрее пройти путь от идеи до работающего контура (k3s, контейнеризация, манифесты, сетевые настройки, локальный доступ и best practices), обратитесь в РыбинскЛАБ — мы поможем с внедрением и настройкой под ваш сценарий разработки.

* Текст статьи подготовлен и структурирован с использованием технологий искусственного интеллекта. Проверен и доработан перед публикацией.

Нужна помощь с настройкой Termux, Linux и серверов?

Я оказываю ИТ-услуги: настройка серверов, автоматизация, безопасность, помощь с Linux и инфраструктурой. Материалы сайта — только в ознакомительных и образовательных целях.

Связаться со мной
Поддержать проект