Change 0 containers

This commit is contained in:
Magnus Root 2026-03-16 17:43:14 +03:00
parent 7cbc9b181c
commit 417f005e04
4 changed files with 62 additions and 21 deletions

View file

@ -212,22 +212,28 @@ func getContainerDrainInfo(containerName string) (timestamp int64, isMigration b
return ts, migration, true return ts, migration, true
} }
func markAngieConfigForDrain(clientTitle string) error { func markAngieConfigForDrain(clientTitle string, isMigration bool) error {
markerFile := fmt.Sprintf("/tmp/ptaf-angie-drain-%s", clientTitle) markerFile := fmt.Sprintf("/tmp/ptaf-angie-drain-%s", clientTitle)
return os.WriteFile(markerFile, []byte(fmt.Sprintf("%d", time.Now().Unix())), 0644) content := fmt.Sprintf("%d", time.Now().Unix())
if isMigration {
content += ":migration"
}
return os.WriteFile(markerFile, []byte(content), 0644)
} }
func getAngieConfigDrainTimestamp(clientTitle string) (int64, bool) { func getAngieConfigDrainInfo(clientTitle string) (timestamp int64, isMigration bool, found bool) {
markerFile := fmt.Sprintf("/tmp/ptaf-angie-drain-%s", clientTitle) markerFile := fmt.Sprintf("/tmp/ptaf-angie-drain-%s", clientTitle)
data, err := os.ReadFile(markerFile) data, err := os.ReadFile(markerFile)
if err != nil { if err != nil {
return 0, false return 0, false, false
} }
timestamp, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64) parts := strings.SplitN(strings.TrimSpace(string(data)), ":", 2)
ts, err := strconv.ParseInt(parts[0], 10, 64)
if err != nil { if err != nil {
return 0, false return 0, false, false
} }
return timestamp, true migration := len(parts) == 2 && parts[1] == "migration"
return ts, migration, true
} }
func stopAndRemoveContainer(containerName, composeFile, containerDir string) error { func stopAndRemoveContainer(containerName, composeFile, containerDir string) error {
@ -635,6 +641,10 @@ func generateDockerCompose(filePath string, config Config, clientTitle string, c
{{- end}} {{- end}}
sysctls: sysctls:
kernel.sem: "32000 1024000000 500 32000" kernel.sem: "32000 1024000000 500 32000"
ulimits:
nofile:
soft: 1048576
hard: 1048576
ports: ports:
{{- range .SortedHTTPPorts}} {{- range .SortedHTTPPorts}}
- 127.0.0.1:{{.DockerPort}}:{{.CustomPort}}/tcp - 127.0.0.1:{{.DockerPort}}:{{.CustomPort}}/tcp

View file

@ -43,7 +43,6 @@ func getActualContainerCount(clientTitle string) int {
func processDrainingAngieConfigs() { func processDrainingAngieConfigs() {
currentTime := time.Now().Unix() currentTime := time.Now().Unix()
timeout := int64(MigrationDrainTimeout)
hostname, err := os.Hostname() hostname, err := os.Hostname()
if err != nil { if err != nil {
log.Printf("⚠ Ошибка получения hostname: %v", err) log.Printf("⚠ Ошибка получения hostname: %v", err)
@ -65,16 +64,27 @@ func processDrainingAngieConfigs() {
continue continue
} }
clientTitle := strings.Join(parts[3:], "-") clientTitle := strings.Join(parts[3:], "-")
drainTimestamp, found := getAngieConfigDrainTimestamp(clientTitle) drainTimestamp, isMigration, found := getAngieConfigDrainInfo(clientTitle)
if !found { if !found {
continue continue
} }
var timeout int64
timeoutName := "масштабирование"
if isMigration {
timeout = int64(MigrationDrainTimeout)
timeoutName = "миграция"
} else {
timeout = int64(ContainerDrainTimeout)
}
elapsedTime := currentTime - drainTimestamp elapsedTime := currentTime - drainTimestamp
remainingTime := timeout - elapsedTime remainingTime := timeout - elapsedTime
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientTitle) angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientTitle)
if elapsedTime >= timeout { if elapsedTime >= timeout {
log.Printf(" Конфиг Angie для %s завершил drain (прошло %d сек), проверяю актуальность...", clientTitle, elapsedTime) log.Printf(" Конфиг Angie для %s завершил drain [%s] (прошло %d сек), проверяю актуальность...", clientTitle, timeoutName, elapsedTime)
if isMigration {
clientInfo, err := getClientInfoByClientTitle(db, clientTitle) clientInfo, err := getClientInfoByClientTitle(db, clientTitle)
if err == nil && clientInfo.WAFInstance != "" { if err == nil && clientInfo.WAFInstance != "" {
belongsNow, checkErr := checkHostBelongsToInstance(db, hostname, clientInfo.WAFInstance) belongsNow, checkErr := checkHostBelongsToInstance(db, hostname, clientInfo.WAFInstance)
@ -85,6 +95,9 @@ func processDrainingAngieConfigs() {
} }
} }
log.Printf(" → Клиент %s не принадлежит этому хосту, удаляю конфиг", clientTitle) log.Printf(" → Клиент %s не принадлежит этому хосту, удаляю конфиг", clientTitle)
} else {
log.Printf(" → Удаляю конфиг Angie для %s", clientTitle)
}
if _, err := os.Stat(angieConfigPath); err == nil { if _, err := os.Stat(angieConfigPath); err == nil {
if err := os.Remove(angieConfigPath); err != nil { if err := os.Remove(angieConfigPath); err != nil {
log.Printf(" ⚠ Ошибка удаления конфига Angie: %v", err) log.Printf(" ⚠ Ошибка удаления конфига Angie: %v", err)
@ -98,7 +111,7 @@ func processDrainingAngieConfigs() {
os.Remove(markerFile) os.Remove(markerFile)
} }
} else { } else {
log.Printf(" ○ Конфиг Angie для %s в процессе drain [миграция] (осталось %d сек)", clientTitle, remainingTime) log.Printf(" ○ Конфиг Angie для %s в процессе drain [%s] (осталось %d сек)", clientTitle, timeoutName, remainingTime)
} }
} }
} }
@ -169,7 +182,7 @@ func processAllDrainingContainersGlobally(db *sql.DB, hostname string) {
} }
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientTitle) angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientTitle)
if _, err := os.Stat(angieConfigPath); err == nil { if _, err := os.Stat(angieConfigPath); err == nil {
if err := markAngieConfigForDrain(clientTitle); err != nil { if err := markAngieConfigForDrain(clientTitle, true); err != nil {
log.Printf(" ⚠ Ошибка пометки Angie конфига: %v", err) log.Printf(" ⚠ Ошибка пометки Angie конфига: %v", err)
} else { } else {
log.Printf(" ✓ Angie конфиг помечен для удаления") log.Printf(" ✓ Angie конфиг помечен для удаления")

View file

@ -303,7 +303,7 @@ func handleClientMigration(clientInfo ClientInfo, hostname string) {
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientInfo.ClientTitle) angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientInfo.ClientTitle)
if _, err := os.Stat(angieConfigPath); err == nil { if _, err := os.Stat(angieConfigPath); err == nil {
log.Printf(" → Помечаю конфиг Angie для удаления (миграция, таймаут %d сек)", MigrationDrainTimeout) log.Printf(" → Помечаю конфиг Angie для удаления (миграция, таймаут %d сек)", MigrationDrainTimeout)
if err := markAngieConfigForDrain(clientInfo.ClientTitle); err != nil { if err := markAngieConfigForDrain(clientInfo.ClientTitle, true); err != nil {
log.Printf(" ⚠ Ошибка пометки конфига: %v", err) log.Printf(" ⚠ Ошибка пометки конфига: %v", err)
} else { } else {
log.Printf(" ✓ Конфиг Angie помечен для удаления") log.Printf(" ✓ Конфиг Angie помечен для удаления")

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"log" "log"
"net" "net"
"os"
"strings" "strings"
"time" "time"
) )
@ -53,6 +54,23 @@ func processPTAFClient(
log.Printf("✓ Клиент %s принадлежит instance '%s', обрабатываю", clientInfo.ClientTitle, clientInfo.WAFInstance) log.Printf("✓ Клиент %s принадлежит instance '%s', обрабатываю", clientInfo.ClientTitle, clientInfo.WAFInstance)
} }
// Если контейнеров 0 — помечаем все существующие для drain и выходим
if clientInfo.ContainersCount == 0 {
log.Printf("⚠ Количество контейнеров равно 0 для %s — помечаю существующие контейнеры для drain", clientInfo.ClientTitle)
processDrainingContainers(clientInfo.ClientTitle, 0)
angieConfigPath := fmt.Sprintf("/etc/angie/http.d/angie-ptaf-%s.conf", clientInfo.ClientTitle)
if _, err := os.Stat(angieConfigPath); err == nil {
log.Printf(" → Помечаю конфиг Angie для удаления (контейнеров 0)")
if err := markAngieConfigForDrain(clientInfo.ClientTitle, false); err != nil {
log.Printf(" ⚠ Ошибка пометки конфига Angie: %v", err)
} else {
log.Printf(" ✓ Конфиг Angie помечен для удаления")
}
}
return false
}
// Автоочистка устаревших маркеров drain // Автоочистка устаревших маркеров drain
cleanStaleDrainMarkers(clientInfo) cleanStaleDrainMarkers(clientInfo)