Что такое «шаблон Sidecar»?

Sidecar  —  это шаблон проектирования в программной архитектуре, применяемый, в частности, для создания и развертывания микросервисов. Рядом с основным контейнером приложения шаблоном развертывается дополнительная служба. Похоже на люльку, прицепляемую к мотоциклу. Этим вспомогательным контейнером-«люлькой» базовая функциональность приложения расширяется, но не изменяется.

Шаблон Sidecar обычно используется в контейнерных приложениях.

Службы

  • Служба аутентификации Sidecar-контейнера на Go.
  • Служба основного контейнера на Go.

Служба основного контейнера

Здесь все просто, в качестве HTTP-ответа единственной конечной точкой API возвращается сообщение в формате JSON:

package main

import (
"fmt"
"github.com/gin-gonic/gin"
)

func main() {
fmt.Println("Api Go!")

r := gin.Default()
r.GET("/ping", ping)
r.Run(":8080")

}

func ping(c *gin.Context) {

c.JSON(200, gin.H{
"message": "pong",
})
}

Dockefile

FROM golang:1.22-alpine as builder
WORKDIR /go/app
COPY . .
RUN go build -v -o app cmd/api/main.go
FROM alpine
COPY --from=builder /go/app/ .
EXPOSE 8080
CMD ["/app"]

Запускаем сборку Docker:

docker build -t mertcakmak2/go-container.

Служба Sidecar-контейнера

Службой Sidecar-контейнера этот входящий HTTP-запрос перенаправляется в службу основного контейнера:

package main

import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"net/http/httputil"
"net/url"
)

func main() {
fmt.Println("Sidecar Go!")

r := gin.Default()
// Выполняем обратное проксирование
r.Any("/*proxyPath", authProxy)
r.Run(":8081")
}

// Имитируем аутентификацию
func authProxy(c *gin.Context) {

// Проверяем токен носителя...

// Url-адрес основного контейнера
remote, err := url.Parse("http://localhost:8080")
if err != nil {
panic(err)
}

proxy := httputil.NewSingleHostReverseProxy(remote)
proxy.Director = func(req *http.Request) {
req.Header = c.Request.Header
req.Host = remote.Host
req.URL.Scheme = remote.Scheme
req.URL.Host = remote.Host
req.URL.Path = c.Param("proxyPath")
}

proxy.ServeHTTP(c.Writer, c.Request)
}

Dockerfile

FROM golang:1.22-alpine as builder
WORKDIR /go/app
COPY . .
RUN go build -v -o app cmd/sidecar/main.go
FROM alpine
COPY --from=builder /go/app/ .
EXPOSE 8081
CMD ["/app"]

Запускаем сборку Docker:

docker build -f Dockerfile.sidecar -t mertcakmak2/go-sidecar.

Развертывание Kubernetes

  • Файл развертывания Kubernetes:
apiVersion: v1
kind: Service
metadata:
name: go-container-sidecar
spec:
selector:
app: go-container-sidecar
ports:
- protocol: "TCP"
name: main-container-port
port: 8080
targetPort: 8080
- protocol: "TCP"
name: sidecar-container-port
port: 8081
targetPort: 8081
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-container-sidecar
spec:
selector:
matchLabels:
app: go-container-sidecar
replicas: 1
template:
metadata:
labels:
app: go-container-sidecar
spec:
containers:
- name: go-container
image: mertcakmak2/go-container:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
- name: go-sidecar
image: mertcakmak2/go-sidecar:latest
imagePullPolicy: Always
ports:
- containerPort: 8081

Создав файл развертывания, располагаем две службы на разных портах:

Служба основного контейнера => 8080.
Служба Sidecar-контейнера => 8081.

Запускаем развертывание:

kubectl apply -f k8s-deployment.yaml

Дашборд Kubernetes

  • Создан под с двумя контейнерами:

Отправка HTTP-запроса

  • Получается доступ к службе Minikube:
minikube service go-container-sidecar --url

Сгенерировано два URL-адреса, первый  —  служба основного контейнера, второй  —  служба Sidecar-контейнера:

Служба основного контейнера => http://127.0.0.1:57496.
Служба Sidecar-контейнера => http://127.0.0.1:57497.

  • Отправляем запрос командой Curl:
  • Из API возвращается JSON-сообщение, вот логи контейнеров:

Службой Sidecar-контейнера эти входящие HTTP-запросы перенаправлены в службу основного контейнера.

Вот репозиторий на GitHub.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Mert ÇAKMAK: Sidecar Pattern with Kubernetes and Go

Предыдущая статьяПолное руководство по кэшированию Laravel