Use nginx upstreams and reload only if configuration changes
This commit is contained in:
parent
d0a15b1267
commit
cad814cbb3
50 changed files with 370 additions and 10432 deletions
11
controllers/nginx-third-party/nginx/command.go
vendored
11
controllers/nginx-third-party/nginx/command.go
vendored
|
|
@ -52,17 +52,20 @@ func (ngx *NginxManager) Start() {
|
|||
// shut down, stop accepting new connections and continue to service current requests
|
||||
// until all such requests are serviced. After that, the old worker processes exit.
|
||||
// http://nginx.org/en/docs/beginners_guide.html#control
|
||||
func (ngx *NginxManager) Reload(cfg *nginxConfiguration, servicesL4 []Service) {
|
||||
func (ngx *NginxManager) CheckAndReload(cfg *nginxConfiguration, upstreams []Upstream, servers []Server, servicesL4 []Service) {
|
||||
ngx.reloadLock.Lock()
|
||||
defer ngx.reloadLock.Unlock()
|
||||
|
||||
if err := ngx.writeCfg(cfg, servicesL4); err != nil {
|
||||
newCfg, err := ngx.writeCfg(cfg, upstreams, servers, servicesL4)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to write new nginx configuration. Avoiding reload: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := ngx.shellOut("nginx -s reload"); err == nil {
|
||||
glog.Info("Change in configuration detected. Reloading...")
|
||||
if newCfg {
|
||||
if err := ngx.shellOut("nginx -s reload"); err == nil {
|
||||
glog.Info("Change in configuration detected. Reloading...")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
92
controllers/nginx-third-party/nginx/nginx.go
vendored
Normal file
92
controllers/nginx-third-party/nginx/nginx.go
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package nginx
|
||||
|
||||
// NGINXController Updates NGINX configuration, starts and reloads NGINX
|
||||
type NGINXController struct {
|
||||
resolver string
|
||||
nginxConfdPath string
|
||||
nginxCertsPath string
|
||||
local bool
|
||||
}
|
||||
|
||||
// IngressNGINXConfig describes an NGINX configuration
|
||||
type IngressNGINXConfig struct {
|
||||
Upstreams []Upstream
|
||||
Servers []Server
|
||||
}
|
||||
|
||||
// Upstream describes an NGINX upstream
|
||||
type Upstream struct {
|
||||
Name string
|
||||
Backends []UpstreamServer
|
||||
}
|
||||
|
||||
type UpstreamByNameServers []Upstream
|
||||
|
||||
func (c UpstreamByNameServers) Len() int { return len(c) }
|
||||
func (c UpstreamByNameServers) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c UpstreamByNameServers) Less(i, j int) bool {
|
||||
return c[i].Name < c[j].Name
|
||||
}
|
||||
|
||||
// UpstreamServer describes a server in an NGINX upstream
|
||||
type UpstreamServer struct {
|
||||
Address string
|
||||
Port string
|
||||
}
|
||||
|
||||
type UpstreamServerByAddrPort []UpstreamServer
|
||||
|
||||
func (c UpstreamServerByAddrPort) Len() int { return len(c) }
|
||||
func (c UpstreamServerByAddrPort) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c UpstreamServerByAddrPort) Less(i, j int) bool {
|
||||
iName := c[i].Address
|
||||
jName := c[j].Address
|
||||
if iName != jName {
|
||||
return iName < jName
|
||||
}
|
||||
|
||||
iU := c[i].Port
|
||||
jU := c[j].Port
|
||||
return iU < jU
|
||||
}
|
||||
|
||||
// Server describes an NGINX server
|
||||
type Server struct {
|
||||
Name string
|
||||
Locations []Location
|
||||
SSL bool
|
||||
SSLCertificate string
|
||||
SSLCertificateKey string
|
||||
}
|
||||
|
||||
type ServerByNamePort []Server
|
||||
|
||||
func (c ServerByNamePort) Len() int { return len(c) }
|
||||
func (c ServerByNamePort) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c ServerByNamePort) Less(i, j int) bool {
|
||||
return c[i].Name < c[j].Name
|
||||
}
|
||||
|
||||
// Location describes an NGINX location
|
||||
type Location struct {
|
||||
Path string
|
||||
Upstream Upstream
|
||||
}
|
||||
|
||||
type locByPathUpstream []Location
|
||||
|
||||
func (c locByPathUpstream) Len() int { return len(c) }
|
||||
func (c locByPathUpstream) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
func (c locByPathUpstream) Less(i, j int) bool {
|
||||
return c[i].Path < c[j].Path
|
||||
}
|
||||
|
||||
// NewUpstreamWithDefaultServer creates an upstream with the default server.
|
||||
// proxy_pass to an upstream with the default server returns 502.
|
||||
// We use it for services that have no endpoints
|
||||
func NewUpstreamWithDefaultServer(name string) Upstream {
|
||||
return Upstream{
|
||||
Name: name,
|
||||
Backends: []UpstreamServer{UpstreamServer{Address: "127.0.0.1", Port: "8181"}},
|
||||
}
|
||||
}
|
||||
10
controllers/nginx-third-party/nginx/template.go
vendored
10
controllers/nginx-third-party/nginx/template.go
vendored
|
|
@ -60,10 +60,10 @@ func (ngx *NginxManager) loadTemplate() {
|
|||
ngx.template = tmpl
|
||||
}
|
||||
|
||||
func (ngx *NginxManager) writeCfg(cfg *nginxConfiguration, servicesL4 []Service) error {
|
||||
func (ngx *NginxManager) writeCfg(cfg *nginxConfiguration, upstreams []Upstream, servers []Server, servicesL4 []Service) (bool, error) {
|
||||
file, err := os.Create(ngx.ConfigFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
fromMap := structs.Map(cfg)
|
||||
|
|
@ -72,6 +72,8 @@ func (ngx *NginxManager) writeCfg(cfg *nginxConfiguration, servicesL4 []Service)
|
|||
|
||||
conf := make(map[string]interface{})
|
||||
conf["sslCertificates"] = ngx.sslCertificates
|
||||
conf["upstreams"] = upstreams
|
||||
conf["servers"] = servers
|
||||
conf["tcpServices"] = servicesL4
|
||||
conf["defBackend"] = ngx.defBackend
|
||||
conf["defResolver"] = ngx.defResolver
|
||||
|
|
@ -94,8 +96,8 @@ func (ngx *NginxManager) writeCfg(cfg *nginxConfiguration, servicesL4 []Service)
|
|||
|
||||
err = ngx.template.Execute(file, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
return nil
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
|||
22
controllers/nginx-third-party/nginx/utils.go
vendored
22
controllers/nginx-third-party/nginx/utils.go
vendored
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package nginx
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
|
@ -28,27 +27,6 @@ import (
|
|||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// SyncIngress creates a GET request to nginx to indicate that is required to refresh the Ingress rules.
|
||||
func (ngx *NginxManager) SyncIngress(ingList []interface{}) error {
|
||||
encData, _ := json.Marshal(ingList)
|
||||
req, err := http.NewRequest("POST", "http://127.0.0.1:8080/update-ingress", bytes.NewBuffer(encData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
body, _ := ioutil.ReadAll(res.Body)
|
||||
glog.Errorf("Error: %v", string(body))
|
||||
return fmt.Errorf("nginx status is unhealthy")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// IsHealthy checks if nginx is running
|
||||
func (ngx *NginxManager) IsHealthy() error {
|
||||
res, err := http.Get("http://127.0.0.1:8080/healthz")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue