Kubernetes Nginx 配置热加载

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Kubernetes Nginx 配置热加载


网络异常,图片无法展示
|

Nginx 本身是支持热更新的,通过 nginx -s reload 指令,实际通过向进程发送 HUB 信号实现不停服重新加载配置,然而在 Docker 或者 Kubernetes 中,每次都需要进容器执行 nginx -s reload 指令,单 docker 容器还好说,可以在外面通过 exec 指定容器执行该指令进行热加载,Kubernetes 的话,就比较难受了


今天介绍一下 Kubernetes 中 Nginx 热加载配置的处理方法——reloader


reloader 地址:https://github.com/stakater/Reloader


reloader 主要就是用来监测 ConfigMap 或 Secret 的变化,然后对相关 DeploymentConfig 的 Deployment、DaemonSet 执行滚动升级


reloader 需要 kubernetes1.9 以上的版本才支持

使用方法

首先是安装部署 reloader

# 直接通过官方yaml文件部署kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml


默认情况下 reloader 是部署在 default 命名空间,但是它是监控所有命名空间的 configmaps 和 secrets


当然,如果不想监控某个 configmap 或 secret,可以通过--resources-to-ignore=configMaps/secrets 来忽略某个资源


网络异常,图片无法展示
|


部署成功后,就可以直接使用了,我提前部署了 nginx 和 configmap


网络异常,图片无法展示
|


这是目前的配置,看一下 Nginx 目前的配置

网络异常,图片无法展示
|


接着,我修改 Nginx 的 Deployment,添加 reloader,监听 nginx-config 这个 ConfigMap,执行

reload

{  "kind": "Deployment",  "apiVersion": "extensions/v1beta1",  "metadata": {    "name": "nginx",    "namespace": "default",    "selfLink": "/apis/extensions/v1beta1/namespaces/default/deployments/nginx",    "uid": "7eee5fa8-7514-11ec-a916-0210d5e9ca3b",    "resourceVersion": "286141",    "generation": 10,    "creationTimestamp": "2022-01-14T08:32:23Z",    "labels": {      "k8s-app": "nginx"    },    "annotations": {      "deployment.kubernetes.io/revision": "9",      "description": "nginx应用"      # 主要是这行      "reloader.stakater.com/reload": "nginx-config"    }  },  "spec": {    "replicas": 1,    "selector": {      "matchLabels": {        "k8s-app": "nginx"      }    }    ……


然后 apply 该 Deployment,之后我们去更新 ConfigMap,更新 nginx 配置文件


网络异常,图片无法展示
|

更新完成,去掉 proxy_redirect,然后去看 nginx 容器是否执行滚动更新


网络异常,图片无法展示
|


可以看到,nginx 执行了滚动更新,接着看下 nginx 配置文件是否更新


网络异常,图片无法展示
|

这样很简单的通过 reloader 就可以实现 Nginx 的配置热加载


除了这种方法,常见的方法还有使用 sidecar,通过 sidecar 去做的话,需要自己写监听脚本,比较麻烦,但是有时候也相对灵活,这里也附一个 sidecar 的 python 脚本


#!/usr/bin/env python# -*- encoding: utf8 -*-"""需求:nginx配置文件变化,自动更新配置文件,类似nginx -s reload实现:    1、用pyinotify实时监控nginx配置文件变化    2、如果配置文件变化,给系统发送HUP来reload nginx"""import osimport reimport pyinotifyimport loggingfrom threading import Timer
# ParamLOG_PATH = "/root/python/log"CONF_PATHS = [  "/etc/nginx",]DELAY = 5SUDO = FalseRELOAD_COMMAND = "nginx -s reload"if SUDO:  RELOAD_COMMAND = "sudo " + RELOAD_COMMAND
# Loglogger = logging.getLogger(__name__)logger.setLevel(level = logging.INFO)log_handler = logging.FileHandler(LOG_PATH)log_handler.setLevel(logging.INFO)log_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')log_handler.setFormatter(log_formatter)logger.addHandler(log_handler)
# Reloaderdef reload_nginx():  os.system(RELOAD_COMMAND)  logger.info("nginx is reloaded")
t = Timer(DELAY, reload_nginx)
def trigger_reload_nginx(pathname, action):  logger.info("nginx monitor is triggered because %s is %s" % (pathname, action))  global t  if t.is_alive():    t.cancel()    t = Timer(DELAY, reload_nginx)    t.start()  else:    t = Timer(DELAY, reload_nginx)    t.start()
events = pyinotify.IN_MODIFY | pyinotify.IN_CREATE | pyinotify.IN_DELETE
watcher = pyinotify.WatchManager()watcher.add_watch(CONF_PATHS, events, rec=True, auto_add=True)
class EventHandler(pyinotify.ProcessEvent):  def process_default(self, event):    if event.name.endswith(".conf"):      if event.mask == pyinotify.IN_CREATE:        action = "created"      if event.mask == pyinotify.IN_MODIFY:        action = "modified"      if event.mask == pyinotify.IN_DELETE:        action = "deleted"      trigger_reload_nginx(event.pathname, action)
handler = EventHandler()notifier = pyinotify.Notifier(watcher, handler)
# Startlogger.info("Start Monitoring")notifier.loop()

如果喜欢用 go 的,这里也提供 go 脚本


package main
import (    "log"    "os"    "path/filepath"    "syscall"
    "github.com/fsnotify/fsnotify"    proc "github.com/shirou/gopsutil/process")
const (    nginxProcessName = "nginx"    defaultNginxConfPath = "/etc/nginx"    watchPathEnvVarName = "WATCH_NGINX_CONF_PATH")
var stderrLogger = log.New(os.Stderr, "error: ", log.Lshortfile)var stdoutLogger = log.New(os.Stdout, "", log.Lshortfile)
func getMasterNginxPid() (int, error) {    processes, processesErr := proc.Processes()    if processesErr != nil {        return 0, processesErr    }
    nginxProcesses := map[int32]int32{}
    for _, process := range processes {        processName, processNameErr := process.Name()        if processNameErr != nil {            return 0, processNameErr        }
        if processName == nginxProcessName {            ppid, ppidErr := process.Ppid()
            if ppidErr != nil {                return 0, ppidErr            }
            nginxProcesses[process.Pid] = ppid        }    }
    var masterNginxPid int32
    for pid, ppid := range nginxProcesses {        if ppid == 0 {            masterNginxPid = pid
            break        }    }
    stdoutLogger.Println("found master nginx pid:", masterNginxPid)
    return int(masterNginxPid), nil}
func signalNginxReload(pid int) error {    stdoutLogger.Printf("signaling master nginx process (pid: %d) -> SIGHUP\n", pid)    nginxProcess, nginxProcessErr := os.FindProcess(pid)
    if nginxProcessErr != nil {        return nginxProcessErr    }
    return nginxProcess.Signal(syscall.SIGHUP)}
func main() {    watcher, watcherErr := fsnotify.NewWatcher()    if watcherErr != nil {        stderrLogger.Fatal(watcherErr)    }    defer watcher.Close()
    done := make(chan bool)    go func() {        for {            select {            case event, ok := <-watcher.Events:                if !ok {                    return                }
                if event.Op&fsnotify.Create == fsnotify.Create {                    if filepath.Base(event.Name) == "..data" {                        stdoutLogger.Println("config map updated")
                        nginxPid, nginxPidErr := getMasterNginxPid()                        if nginxPidErr != nil {                            stderrLogger.Printf("getting master nginx pid failed: %s", nginxPidErr.Error())
                            continue                        }
                        if err := signalNginxReload(nginxPid); err != nil {                            stderrLogger.Printf("signaling master nginx process failed: %s", err)                        }                    }                }            case err, ok := <-watcher.Errors:                if !ok {                    return                }                stderrLogger.Printf("received watcher.Error: %s", err)            }        }    }()
    pathToWatch, ok := os.LookupEnv(watchPathEnvVarName)    if !ok {        pathToWatch = defaultNginxConfPath    }
    stdoutLogger.Printf("adding path: `%s` to watch\n", pathToWatch)
    if err := watcher.Add(pathToWatch); err != nil {        stderrLogger.Fatal(err)    }    <-done}



相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
15天前
|
应用服务中间件 BI nginx
Nginx的location配置详解
【10月更文挑战第16天】Nginx的location配置详解
|
22天前
|
缓存 负载均衡 安全
Nginx常用基本配置总结:从入门到实战的全方位指南
Nginx常用基本配置总结:从入门到实战的全方位指南
207 0
|
8天前
|
应用服务中间件 API nginx
nginx配置反向代理404问题
【10月更文挑战第18天】本文介绍了使用Nginx进行反向代理的配置方法,解决了404错误、跨域问题和302重定向问题。关键配置包括代理路径、请求头设置、跨域头添加以及端口转发设置。通过调整`proxy_set_header`和添加必要的HTTP头,实现了稳定的服务代理和跨域访问。
nginx配置反向代理404问题
|
2天前
|
应用服务中间件 网络安全 PHP
八个免费开源 Nginx 管理系统,轻松管理 Nginx 站点配置
Nginx 是一个高效的 HTTP 服务器和反向代理,擅长处理静态资源、负载均衡和网关代理等任务。其配置主要通过 `nginx.conf` 文件完成,但复杂设置可能导致错误。本文介绍了几个开源的 Nginx 可视化配置系统,如 Nginx UI、VeryNginx、OpenPanel、Ajenti、Schenkd nginx-ui、EasyEngine、CapRover 和 NGINX Agent,帮助简化和安全地管理 Nginx 实例。
|
12天前
|
缓存 负载均衡 应用服务中间件
Nginx配置
【10月更文挑战第22天】在实际配置 Nginx 时,需要根据具体的需求和环境进行调整和优化。同时,还需要注意配置文件的语法正确性和安全性。
31 7
|
21天前
|
前端开发 JavaScript 应用服务中间件
终极 Nginx 配置指南
本文介绍了Nginx的基本配置及其优化方法。首先,通过删除注释简化了Nginx的默认配置文件,使其更易于理解。接着,文章将Nginx配置文件分为全局块、events块和http块三部分进行详细解释。此外,还提供了如何快速上线网站、解决前端history模式404问题、配置反向代理、开启gzip压缩、设置维护页面、在同一IP上部署多个网站以及实现动静分离的具体配置示例。最后,附上了Nginx的基础命令,包括安装、启动、重启和关闭等操作。
|
25天前
|
负载均衡 应用服务中间件 nginx
Nginx的6大负载均衡策略及权重轮询手写配置
【10月更文挑战第9天】 Nginx是一款高性能的HTTP服务器和反向代理服务器,它在处理大量并发请求时表现出色。Nginx的负载均衡功能可以将请求分发到多个服务器,提高网站的吞吐量和可靠性。以下是Nginx支持的6大负载均衡策略:
112 7
|
23天前
|
缓存 前端开发 JavaScript
一、nginx配置
一、nginx配置
125 1
|
22天前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
111 0
|
25天前
|
缓存 监控 负载均衡
nginx相关配置及高并发优化
Nginx的高并发优化是一个综合性的过程,需要根据具体的业务场景和硬件资源量身定制。以上配置只是基础,实际应用中还需根据服务器监控数据进行持续调整和优化。例如,利用工具如ab(Apache Benchmarks)进行压力测试,监控CPU、内存、网络和磁盘I/O等资源使用情况,确保配置的有效性和服务的稳定性。
87 0