Send signal SIGQUIT instead of SIGTERM to nginx

This commit is contained in:
Manuel de Brito Fontes 2017-08-28 18:42:00 -03:00
parent a8bfdc2427
commit 9b2013ac56
2 changed files with 56 additions and 30 deletions

View file

@ -23,6 +23,7 @@ import (
"time"
"github.com/golang/glog"
"k8s.io/ingress/core/pkg/ingress/controller"
)
@ -31,29 +32,32 @@ func main() {
ngx := newNGINXController()
// create a custom Ingress controller using NGINX as backend
ic := controller.NewIngressController(ngx)
go handleSigterm(ic)
// start the controller
ic.Start()
// wait
glog.Infof("shutting down Ingress controller...")
for {
glog.Infof("Handled quit, awaiting pod deletion")
time.Sleep(30 * time.Second)
}
}
func handleSigterm(ic *controller.GenericController) {
// start the controller
go ic.Start()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGTERM)
<-signalChan
glog.Infof("Received SIGTERM, shutting down")
exitCode := 0
if err := ic.Stop(); err != nil {
glog.Infof("Error during shutdown %v", err)
exitCode = 1
glog.Errorf("unexpected error shutting down the ingress controller: %v", err)
}
glog.Infof("Exiting with %v", exitCode)
os.Exit(exitCode)
glog.Infof("stopping nginx gracefully...")
ngx.Stop()
timer := time.NewTicker(time.Second * 1)
for {
select {
case <-timer.C:
if !isNginxRunning(ngx.ports.Status) {
glog.Infof("nginx stopped...")
glog.Infof("Exiting with code 0")
os.Exit(0)
}
}
}
}

View file

@ -71,7 +71,7 @@ var (
// newNGINXController creates a new NGINX Ingress controller.
// If the environment variable NGINX_BINARY exists it will be used
// as source for nginx commands
func newNGINXController() ingress.Controller {
func newNGINXController() *NGINXController {
ngx := os.Getenv("NGINX_BINARY")
if ngx == "" {
ngx = binary
@ -88,6 +88,7 @@ func newNGINXController() ingress.Controller {
isIPV6Enabled: isIPv6Enabled(),
resolver: h,
ports: &config.ListenPorts{},
done: make(chan error),
}
fcgiListener, err := net.Listen("unix", fastCGISocket)
@ -134,11 +135,13 @@ Error loading new template : %v
go n.Start()
return ingress.Controller(n)
return n
}
// NGINXController ...
type NGINXController struct {
done chan error
t *ngx_template.Template
configmap *api_v1.ConfigMap
@ -166,15 +169,16 @@ type NGINXController struct {
ports *config.ListenPorts
backendDefaults defaults.Backend
isShuttingDown bool
}
// Start start a new NGINX master process running in foreground.
func (n *NGINXController) Start() {
glog.Info("starting NGINX process...")
done := make(chan error, 1)
cmd := exec.Command(n.binary, "-c", cfgPath)
n.start(cmd, done)
start(cmd, n.done)
// if the nginx master process dies the workers continue to process requests,
// passing checks but in case of updates in ingress no updates will be
@ -182,7 +186,12 @@ func (n *NGINXController) Start() {
// issues because of this behavior.
// To avoid this issue we restart nginx in case of errors.
for {
err := <-done
err := <-n.done
if n.isShuttingDown {
break
}
if exitError, ok := err.(*exec.ExitError); ok {
waitStatus := exitError.Sys().(syscall.WaitStatus)
glog.Warningf(`
@ -195,19 +204,25 @@ NGINX master process died (%v): %v
cmd = exec.Command(n.binary, "-c", cfgPath)
// we wait until the workers are killed
for {
conn, err := net.DialTimeout("tcp", "127.0.0.1:80", 1*time.Second)
if err != nil {
if !isNginxRunning(n.ports.Status) {
break
}
conn.Close()
time.Sleep(1 * time.Second)
}
// start a new nginx master process
n.start(cmd, done)
start(cmd, n.done)
}
}
func (n *NGINXController) start(cmd *exec.Cmd, done chan error) {
func (n *NGINXController) Stop() error {
n.isShuttingDown = true
cmd := exec.Command(n.binary, "-c", cfgPath, "-s", "quit")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
func start(cmd *exec.Cmd, done chan error) {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
@ -216,8 +231,6 @@ func (n *NGINXController) start(cmd *exec.Cmd, done chan error) {
return
}
n.cmdArgs = cmd.Args
go func() {
done <- cmd.Wait()
}()
@ -230,7 +243,7 @@ func (n NGINXController) BackendDefaults() defaults.Backend {
// printDiff returns the difference between the running configuration
// and the new one
func (n NGINXController) printDiff(data []byte) {
func printDiff(data []byte) {
if !glog.V(2) {
return
}
@ -655,7 +668,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
return err
}
n.printDiff(content)
printDiff(content)
err = ioutil.WriteFile(cfgPath, content, 0644)
if err != nil {
@ -716,3 +729,12 @@ func isIPv6Enabled() bool {
cmd := exec.Command("test", "-f", "/proc/net/if_inet6")
return cmd.Run() == nil
}
func isNginxRunning(port int) bool {
conn, err := net.DialTimeout("tcp", fmt.Sprintf("127.0.0.1:%v", port), 1*time.Second)
if err != nil {
return false
}
conn.Close()
return true
}