diff --git a/controllers/nginx/Makefile b/controllers/nginx/Makefile index bebfb4cd3..ce0668a9d 100644 --- a/controllers/nginx/Makefile +++ b/controllers/nginx/Makefile @@ -4,8 +4,16 @@ all: push TAG = 0.5 PREFIX = gcr.io/google_containers/nginx-ingress-controller +REPO_INFO=$(shell git config --get remote.origin.url) + +ifndef VERSION + VERSION := git-$(shell git rev-parse --short HEAD) +endif + controller: controller.go clean - CGO_ENABLED=0 GOOS=linux godep go build -a -installsuffix cgo -ldflags '-w' -o nginx-ingress-controller + CGO_ENABLED=0 GOOS=linux godep go build -a -installsuffix cgo -ldflags \ + "-w -X main.version=${VERSION} -X main.gitRepo=${REPO_INFO}" \ + -o nginx-ingress-controller container: controller docker build -t $(PREFIX):$(TAG) . diff --git a/controllers/nginx/controller.go b/controllers/nginx/controller.go index 1e98e328c..85f478a9c 100644 --- a/controllers/nginx/controller.go +++ b/controllers/nginx/controller.go @@ -60,7 +60,7 @@ type loadBalancerController struct { svcLister cache.StoreToServiceLister endpLister cache.StoreToEndpointsLister nginx *nginx.Manager - lbInfo *lbInfo + podInfo *podInfo defaultSvc string nxgConfigMap string tcpConfigMap string @@ -84,7 +84,7 @@ type loadBalancerController struct { // newLoadBalancerController creates a controller for nginx loadbalancer func newLoadBalancerController(kubeClient *client.Client, resyncPeriod time.Duration, defaultSvc, - namespace, nxgConfigMapName, tcpConfigMapName, udpConfigMapName string, lbRuntimeInfo *lbInfo) (*loadBalancerController, error) { + namespace, nxgConfigMapName, tcpConfigMapName, udpConfigMapName string, runtimeInfo *podInfo) (*loadBalancerController, error) { eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) @@ -93,7 +93,7 @@ func newLoadBalancerController(kubeClient *client.Client, resyncPeriod time.Dura lbc := loadBalancerController{ client: kubeClient, stopCh: make(chan struct{}), - lbInfo: lbRuntimeInfo, + podInfo: runtimeInfo, nginx: nginx.NewManager(kubeClient), nxgConfigMap: nxgConfigMapName, tcpConfigMap: tcpConfigMapName, @@ -271,22 +271,22 @@ func (lbc *loadBalancerController) updateIngressStatus(key string) { lbIPs := ing.Status.LoadBalancer.Ingress if !lbc.isStatusIPDefined(lbIPs) { - glog.Infof("Updating loadbalancer %v/%v with IP %v", ing.Namespace, ing.Name, lbc.lbInfo.Address) + glog.Infof("Updating loadbalancer %v/%v with IP %v", ing.Namespace, ing.Name, lbc.podInfo.NodeIP) currIng.Status.LoadBalancer.Ingress = append(currIng.Status.LoadBalancer.Ingress, api.LoadBalancerIngress{ - IP: lbc.lbInfo.Address, + IP: lbc.podInfo.NodeIP, }) if _, err := ingClient.UpdateStatus(currIng); err != nil { lbc.recorder.Eventf(currIng, api.EventTypeWarning, "UPDATE", "error: %v", err) return } - lbc.recorder.Eventf(currIng, api.EventTypeNormal, "CREATE", "ip: %v", lbc.lbInfo.Address) + lbc.recorder.Eventf(currIng, api.EventTypeNormal, "CREATE", "ip: %v", lbc.podInfo.NodeIP) } } func (lbc *loadBalancerController) isStatusIPDefined(lbings []api.LoadBalancerIngress) bool { for _, lbing := range lbings { - if lbing.IP == lbc.lbInfo.Address { + if lbing.IP == lbc.podInfo.NodeIP { return true } } @@ -442,7 +442,7 @@ func (lbc *loadBalancerController) getUpstreamServers(data []interface{}) ([]*ng // default server - no servername. servers[defServerName] = &nginx.Server{ Name: defServerName, - Locations: []*nginx.Location{&nginx.Location{ + Locations: []*nginx.Location{{ Path: "/", Upstream: *lbc.getDefaultUpstream(), }, @@ -718,10 +718,10 @@ func (lbc *loadBalancerController) removeFromIngress() { lbIPs := ing.Status.LoadBalancer.Ingress if len(lbIPs) > 0 && lbc.isStatusIPDefined(lbIPs) { - glog.Infof("Updating loadbalancer %v/%v. Removing IP %v", ing.Namespace, ing.Name, lbc.lbInfo.Address) + glog.Infof("Updating loadbalancer %v/%v. Removing IP %v", ing.Namespace, ing.Name, lbc.podInfo.NodeIP) for idx, lbStatus := range currIng.Status.LoadBalancer.Ingress { - if lbStatus.IP == lbc.lbInfo.Address { + if lbStatus.IP == lbc.podInfo.NodeIP { currIng.Status.LoadBalancer.Ingress = append(currIng.Status.LoadBalancer.Ingress[:idx], currIng.Status.LoadBalancer.Ingress[idx+1:]...) break @@ -733,7 +733,7 @@ func (lbc *loadBalancerController) removeFromIngress() { continue } - lbc.recorder.Eventf(currIng, api.EventTypeNormal, "DELETE", "ip: %v", lbc.lbInfo.Address) + lbc.recorder.Eventf(currIng, api.EventTypeNormal, "DELETE", "ip: %v", lbc.podInfo.NodeIP) } } } diff --git a/controllers/nginx/examples/custom-configuration/rc-custom-configuration.yaml b/controllers/nginx/examples/custom-configuration/rc-custom-configuration.yaml index 2b9614f88..7e43da8b9 100644 --- a/controllers/nginx/examples/custom-configuration/rc-custom-configuration.yaml +++ b/controllers/nginx/examples/custom-configuration/rc-custom-configuration.yaml @@ -28,10 +28,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: diff --git a/controllers/nginx/examples/daemonset/as-daemonset.yaml b/controllers/nginx/examples/daemonset/as-daemonset.yaml index 28de460da..9cc493969 100644 --- a/controllers/nginx/examples/daemonset/as-daemonset.yaml +++ b/controllers/nginx/examples/daemonset/as-daemonset.yaml @@ -22,10 +22,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: @@ -40,5 +36,5 @@ spec: - containerPort: 443 hostPort: 4444 args: - - /nginx-ingress-controller-lb + - /nginx-ingress-controller - --default-backend-service=default/default-http-backend diff --git a/controllers/nginx/examples/default/rc-default.yaml b/controllers/nginx/examples/default/rc-default.yaml index ac7d25d86..842a372cc 100644 --- a/controllers/nginx/examples/default/rc-default.yaml +++ b/controllers/nginx/examples/default/rc-default.yaml @@ -28,10 +28,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: diff --git a/controllers/nginx/examples/full/rc-full.yaml b/controllers/nginx/examples/full/rc-full.yaml index 5ef8de056..d54fe4dbb 100644 --- a/controllers/nginx/examples/full/rc-full.yaml +++ b/controllers/nginx/examples/full/rc-full.yaml @@ -33,10 +33,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: diff --git a/controllers/nginx/examples/tcp/rc-tcp.yaml b/controllers/nginx/examples/tcp/rc-tcp.yaml index 2979be94d..ef64d30b7 100644 --- a/controllers/nginx/examples/tcp/rc-tcp.yaml +++ b/controllers/nginx/examples/tcp/rc-tcp.yaml @@ -28,10 +28,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: diff --git a/controllers/nginx/examples/tls/rc-ssl.yaml b/controllers/nginx/examples/tls/rc-ssl.yaml index 560477f7b..f98a71902 100644 --- a/controllers/nginx/examples/tls/rc-ssl.yaml +++ b/controllers/nginx/examples/tls/rc-ssl.yaml @@ -28,10 +28,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: diff --git a/controllers/nginx/examples/udp/rc-udp.yaml b/controllers/nginx/examples/udp/rc-udp.yaml index 1e1bcd933..283c2211b 100644 --- a/controllers/nginx/examples/udp/rc-udp.yaml +++ b/controllers/nginx/examples/udp/rc-udp.yaml @@ -28,10 +28,6 @@ spec: timeoutSeconds: 5 # use downward API env: - - name: POD_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: diff --git a/controllers/nginx/main.go b/controllers/nginx/main.go index 60d94dc65..ed6f7539a 100644 --- a/controllers/nginx/main.go +++ b/controllers/nginx/main.go @@ -41,6 +41,10 @@ const ( ) var ( + // value overwritten during build. This can be used to resolve issues. + version = "0.5" + gitRepo = "https://github.com/kubernetes/contrib" + flags = pflag.NewFlagSet("", pflag.ExitOnError) defaultSvc = flags.String("default-backend-service", "", @@ -82,6 +86,8 @@ func main() { flags.AddGoFlagSet(flag.CommandLine) flags.Parse(os.Args) + glog.Infof("Using build: %v - %v", gitRepo, version) + if *buildCfg { fmt.Printf("Example of ConfigMap to customize NGINX configuration:\n%v", nginx.ConfigMapAsString()) os.Exit(0) @@ -96,7 +102,7 @@ func main() { glog.Fatalf("failed to create client: %v", err) } - lbInfo, err := getLBDetails(kubeClient) + podInfo, err := getPodDetails(kubeClient) if err != nil { glog.Fatalf("unexpected error getting runtime information: %v", err) } @@ -106,7 +112,7 @@ func main() { glog.Fatalf("no service with name %v found: %v", *defaultSvc, err) } - lbc, err := newLoadBalancerController(kubeClient, *resyncPeriod, *defaultSvc, *watchNamespace, *nxgConfigMap, *tcpConfigMapName, *udpConfigMapName, lbInfo) + lbc, err := newLoadBalancerController(kubeClient, *resyncPeriod, *defaultSvc, *watchNamespace, *nxgConfigMap, *tcpConfigMapName, *udpConfigMapName, podInfo) if err != nil { glog.Fatalf("%v", err) } @@ -122,18 +128,22 @@ func main() { } } -// lbInfo contains runtime information about the pod -type lbInfo struct { - Podname string - PodIP string +// podInfo contains runtime information about the pod +type podInfo struct { + PodName string PodNamespace string - Address string + NodeIP string } func registerHandlers(lbc *loadBalancerController) { mux := http.NewServeMux() healthz.InstallHandler(mux, lbc.nginx) + http.HandleFunc("/build", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, "build: %v - %v", gitRepo, version) + }) + http.HandleFunc("/stop", func(w http.ResponseWriter, r *http.Request) { lbc.Stop() }) diff --git a/controllers/nginx/utils.go b/controllers/nginx/utils.go index fe4857684..196ba331d 100644 --- a/controllers/nginx/utils.go +++ b/controllers/nginx/utils.go @@ -97,27 +97,21 @@ func NewTaskQueue(syncFn func(string)) *taskQueue { } } -// getLBDetails returns runtime information about the pod (name, IP) and replication -// controller or daemonset (namespace and name). -// This is required to watch for changes in annotations or configuration (ConfigMap) -func getLBDetails(kubeClient *unversioned.Client) (*lbInfo, error) { +// getPodDetails returns runtime information about the pod: name, namespace and IP of the node +func getPodDetails(kubeClient *unversioned.Client) (*podInfo, error) { podName := os.Getenv("POD_NAME") podNs := os.Getenv("POD_NAMESPACE") + err := waitForPodRunning(kubeClient, podNs, podName, time.Millisecond*200, time.Second*30) + if err != nil { + return nil, err + } + pod, _ := kubeClient.Pods(podNs).Get(podName) if pod == nil { return nil, fmt.Errorf("Unable to get POD information") } - if pod.Status.Phase != api.PodRunning { - // we wait up to 30 seconds until the pod is running and - // it is possible to get the IP and name of the node - err := waitForPodRunning(kubeClient, podNs, podName, time.Millisecond*200, time.Second*30) - if err != nil { - return nil, err - } - } - node, err := kubeClient.Nodes().Get(pod.Spec.NodeName) if err != nil { return nil, err @@ -137,13 +131,10 @@ func getLBDetails(kubeClient *unversioned.Client) (*lbInfo, error) { } } - podIP := os.Getenv("POD_IP") - - return &lbInfo{ - PodIP: podIP, - Podname: podName, + return &podInfo{ + PodName: podName, PodNamespace: podNs, - Address: externalIP, + NodeIP: externalIP, }, nil }