Implement HealthzChecker interface. Add flag to allow profiling

This commit is contained in:
Manuel de Brito Fontes 2016-03-22 13:51:50 -03:00
parent d9934ec4db
commit f5892e06fe
10 changed files with 233 additions and 58 deletions

View file

@ -17,15 +17,19 @@ limitations under the License.
package nginx
import (
"fmt"
"net/http"
"os"
"os/exec"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/healthz"
)
// Start starts a nginx (master process) and waits. If the process ends
// we need to kill the controller process and return the reason.
func (ngx *NginxManager) Start() {
func (ngx *Manager) Start() {
glog.Info("Starting NGINX process...")
cmd := exec.Command("nginx")
cmd.Stdout = os.Stdout
@ -50,7 +54,7 @@ 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) CheckAndReload(cfg *nginxConfiguration, ingressCfg IngressConfig) {
func (ngx *Manager) CheckAndReload(cfg *nginxConfiguration, ingressCfg IngressConfig) {
ngx.reloadLock.Lock()
defer ngx.reloadLock.Unlock()
@ -70,7 +74,7 @@ func (ngx *NginxManager) CheckAndReload(cfg *nginxConfiguration, ingressCfg Ingr
// shellOut executes a command and returns its combined standard output and standard
// error in case of an error in the execution
func (ngx *NginxManager) shellOut(cmd string) error {
func (ngx *Manager) shellOut(cmd string) error {
out, err := exec.Command("sh", "-c", cmd).CombinedOutput()
if err != nil {
glog.Errorf("failed to execute %v: %v", cmd, string(out))
@ -79,3 +83,26 @@ func (ngx *NginxManager) shellOut(cmd string) error {
return nil
}
// check to verify Manager implements HealthzChecker interface
var _ healthz.HealthzChecker = Manager{}
// Name returns the healthcheck name
func (ngx Manager) Name() string {
return "NGINX"
}
// Check returns if the nginx healthz endpoint is returning ok (status code 200)
func (ngx Manager) Check(_ *http.Request) error {
res, err := http.Get("http://127.0.0.1:8080/healthz")
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != 200 {
return fmt.Errorf("NGINX is unhealthy")
}
return nil
}

View file

@ -203,8 +203,8 @@ type nginxConfiguration struct {
WorkerProcesses string `json:"workerProcesses,omitempty" structs:"workerProcesses,omitempty"`
}
// NginxManager ...
type NginxManager struct {
// Manager ...
type Manager struct {
ConfigFile string
defCfg *nginxConfiguration
@ -257,11 +257,11 @@ func newDefaultNginxCfg() *nginxConfiguration {
}
// NewManager ...
func NewManager(kubeClient *client.Client) *NginxManager {
ngx := &NginxManager{
func NewManager(kubeClient *client.Client) *Manager {
ngx := &Manager{
ConfigFile: "/etc/nginx/nginx.conf",
defCfg: newDefaultNginxCfg(),
defResolver: strings.Join(getDnsServers(), " "),
defResolver: strings.Join(getDNSServers(), " "),
reloadLock: &sync.Mutex{},
}
@ -274,7 +274,7 @@ func NewManager(kubeClient *client.Client) *NginxManager {
return ngx
}
func (nginx *NginxManager) createCertsDir(base string) {
func (nginx *Manager) createCertsDir(base string) {
if err := os.Mkdir(base, os.ModeDir); err != nil {
glog.Fatalf("Couldn't create directory %v: %v", base, err)
}

View file

@ -27,7 +27,7 @@ import (
)
// AddOrUpdateCertAndKey creates a .pem file wth the cert and the key with the specified name
func (nginx *NginxManager) AddOrUpdateCertAndKey(name string, cert string, key string) string {
func (nginx *Manager) AddOrUpdateCertAndKey(name string, cert string, key string) string {
pemFileName := sslDirectory + "/" + name + ".pem"
pem, err := os.Create(pemFileName)
@ -47,7 +47,7 @@ func (nginx *NginxManager) AddOrUpdateCertAndKey(name string, cert string, key s
// CheckSSLCertificate checks if the certificate and key file are valid
// returning the result of the validation and the list of hostnames
// contained in the common name/s
func (nginx *NginxManager) CheckSSLCertificate(secretName string) ([]string, error) {
func (nginx *Manager) CheckSSLCertificate(secretName string) ([]string, error) {
pemFileName := sslDirectory + "/" + secretName + ".pem"
pemCerts, err := ioutil.ReadFile(pemFileName)
if err != nil {
@ -55,7 +55,7 @@ func (nginx *NginxManager) CheckSSLCertificate(secretName string) ([]string, err
}
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
block, _ = pem.Decode(pemCerts)
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
@ -74,7 +74,7 @@ func (nginx *NginxManager) CheckSSLCertificate(secretName string) ([]string, err
// SearchDHParamFile iterates all the secrets mounted inside the /etc/nginx-ssl directory
// in order to find a file with the name dhparam.pem. If such file exists it will
// returns the path. If not it just returns an empty string
func (nginx *NginxManager) SearchDHParamFile(baseDir string) string {
func (nginx *Manager) SearchDHParamFile(baseDir string) string {
files, _ := ioutil.ReadDir(baseDir)
for _, file := range files {
if !file.IsDir() {

View file

@ -37,12 +37,12 @@ var funcMap = template.FuncMap{
},
}
func (ngx *NginxManager) loadTemplate() {
func (ngx *Manager) loadTemplate() {
tmpl, _ := template.New("nginx.tmpl").Funcs(funcMap).ParseFiles("./nginx.tmpl")
ngx.template = tmpl
}
func (ngx *NginxManager) writeCfg(cfg *nginxConfiguration, ingressCfg IngressConfig) (bool, error) {
func (ngx *Manager) writeCfg(cfg *nginxConfiguration, ingressCfg IngressConfig) (bool, error) {
fromMap := structs.Map(cfg)
toMap := structs.Map(ngx.defCfg)
curNginxCfg := merge(toMap, fromMap)

View file

@ -19,9 +19,7 @@ package nginx
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"reflect"
@ -33,23 +31,8 @@ import (
"k8s.io/kubernetes/pkg/api"
)
// IsHealthy checks if nginx is running
func (ngx *NginxManager) IsHealthy() error {
res, err := http.Get("http://127.0.0.1:8080/healthz")
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != 200 {
return fmt.Errorf("NGINX is unhealthy")
}
return nil
}
// getDnsServers returns the list of nameservers located in the file /etc/resolv.conf
func getDnsServers() []string {
// getDNSServers returns the list of nameservers located in the file /etc/resolv.conf
func getDNSServers() []string {
file, err := ioutil.ReadFile("/etc/resolv.conf")
if err != nil {
return []string{}
@ -78,7 +61,7 @@ func getDnsServers() []string {
}
// ReadConfig obtains the configuration defined by the user merged with the defaults.
func (ngx *NginxManager) ReadConfig(config *api.ConfigMap) (*nginxConfiguration, error) {
func (ngx *Manager) ReadConfig(config *api.ConfigMap) (*nginxConfiguration, error) {
if len(config.Data) == 0 {
return newDefaultNginxCfg(), nil
}
@ -96,7 +79,7 @@ func (ngx *NginxManager) ReadConfig(config *api.ConfigMap) (*nginxConfiguration,
return cfg, nil
}
func (ngx *NginxManager) needsReload(data *bytes.Buffer) (bool, error) {
func (ngx *Manager) needsReload(data *bytes.Buffer) (bool, error) {
filename := ngx.ConfigFile
in, err := os.Open(filename)
if err != nil {