diff --git a/cluster/gce/config-default.sh b/cluster/gce/config-default.sh index 1edb52879b..04e618fc7f 100755 --- a/cluster/gce/config-default.sh +++ b/cluster/gce/config-default.sh @@ -46,6 +46,7 @@ CLUSTER_IP_RANGE="${CLUSTER_IP_RANGE:-10.244.0.0/16}" MINION_SCOPES="${MINION_SCOPES:-compute-rw,monitoring,logging-write,storage-ro}" RUNTIME_CONFIG="${KUBE_RUNTIME_CONFIG:-}" ENABLE_EXPERIMENTAL_API="${KUBE_ENABLE_EXPERIMENTAL_API:-false}" +KUBELET_PORT="${KUBELET_PORT:-10250}" # Increase the sleep interval value if concerned about API rate limits. 3, in seconds, is the default. POLL_SLEEP_INTERVAL="${POLL_SLEEP_INTERVAL:-3}" diff --git a/cluster/gce/config-test.sh b/cluster/gce/config-test.sh index 2faa613763..8b4c7bdae8 100755 --- a/cluster/gce/config-test.sh +++ b/cluster/gce/config-test.sh @@ -48,6 +48,7 @@ MINION_SCOPES="${MINION_SCOPES:-compute-rw,monitoring,logging-write,storage-ro}" RUNTIME_CONFIG="${KUBE_RUNTIME_CONFIG:-}" ENABLE_EXPERIMENTAL_API="${KUBE_ENABLE_EXPERIMENTAL_API:-false}" TERMINATED_POD_GC_THRESHOLD=${TERMINATED_POD_GC_THRESHOLD:-100} +KUBELET_PORT="${KUBELET_PORT:-10250}" # Increase the sleep interval value if concerned about API rate limits. 3, in seconds, is the default. POLL_SLEEP_INTERVAL=3 diff --git a/cluster/gce/configure-vm.sh b/cluster/gce/configure-vm.sh index 37488654da..c33cc5293b 100755 --- a/cluster/gce/configure-vm.sh +++ b/cluster/gce/configure-vm.sh @@ -284,6 +284,7 @@ opencontrail_public_subnet: '$(echo "$OPENCONTRAIL_PUBLIC_SUBNET")' enable_manifest_url: '$(echo "$ENABLE_MANIFEST_URL" | sed -e "s/'/''/g")' manifest_url: '$(echo "$MANIFEST_URL" | sed -e "s/'/''/g")' manifest_url_header: '$(echo "$MANIFEST_URL_HEADER" | sed -e "s/'/''/g")' +kubelet_port: '$(echo "$KUBELET_PORT")' EOF if [ -n "${APISERVER_TEST_ARGS:-}" ]; then diff --git a/cluster/gce/debian/helper.sh b/cluster/gce/debian/helper.sh index c01848ddab..e212412b7c 100755 --- a/cluster/gce/debian/helper.sh +++ b/cluster/gce/debian/helper.sh @@ -60,6 +60,7 @@ NETWORK_PROVIDER: $(yaml-quote ${NETWORK_PROVIDER:-}) OPENCONTRAIL_TAG: $(yaml-quote ${OPENCONTRAIL_TAG:-}) OPENCONTRAIL_KUBERNETES_TAG: $(yaml-quote ${OPENCONTRAIL_KUBERNETES_TAG:-}) OPENCONTRAIL_PUBLIC_SUBNET: $(yaml-quote ${OPENCONTRAIL_PUBLIC_SUBNET:-}) +KUBELET_PORT: $(yaml-quote ${KUBELET_PORT}) EOF if [ -n "${KUBE_APISERVER_REQUEST_TIMEOUT:-}" ]; then cat >>$file < 0 { return nil, errors.NewInvalid("podlogs", name, errs) } - location, transport, err := pod.LogLocation(r.Store, r.KubeletConn, ctx, name, logOpts) + location, transport, err := pod.LogLocation(r.Store, r.KubeletConn, ctx, name, logOpts, r.HostLocator) if err != nil { return nil, err } + if location.Host == "" { + return nil, fmt.Errorf("Empty location.Host in %#v", location) + } return &genericrest.LocationStreamer{ Location: location, Transport: transport, diff --git a/pkg/registry/pod/strategy.go b/pkg/registry/pod/strategy.go index 82ac5c49b0..961e27a86b 100644 --- a/pkg/registry/pod/strategy.go +++ b/pkg/registry/pod/strategy.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/registry/generic" + nodeetcd "k8s.io/kubernetes/pkg/registry/node/etcd" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/fielderrors" @@ -224,7 +225,14 @@ func ResourceLocation(getter ResourceGetter, rt http.RoundTripper, ctx api.Conte // LogLocation returns the log URL for a pod container. If opts.Container is blank // and only one container is present in the pod, that container is used. -func LogLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodLogOptions) (*url.URL, http.RoundTripper, error) { +func LogLocation( + getter ResourceGetter, + connInfo client.ConnectionInfoGetter, + ctx api.Context, + name string, + opts *api.PodLogOptions, + hostLocator nodeetcd.HostLocator, +) (*url.URL, http.RoundTripper, error) { pod, err := getPod(getter, ctx, name) if err != nil { return nil, nil, err @@ -248,6 +256,13 @@ func LogLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ct if err != nil { return nil, nil, err } + daemonPort, err := hostLocator.HostKubeletPort(pod, ctx) + if err != nil { + return nil, nil, err + } + if daemonPort > 0 { + nodePort = uint(daemonPort) + } params := url.Values{} if opts.Follow { params.Add("follow", "true") @@ -318,17 +333,40 @@ func streamParams(params url.Values, opts runtime.Object) error { // AttachLocation returns the attach URL for a pod container. If opts.Container is blank // and only one container is present in the pod, that container is used. -func AttachLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodAttachOptions) (*url.URL, http.RoundTripper, error) { - return streamLocation(getter, connInfo, ctx, name, opts, opts.Container, "attach") +func AttachLocation( + getter ResourceGetter, + connInfo client.ConnectionInfoGetter, + ctx api.Context, + name string, + opts *api.PodAttachOptions, + hostLocator nodeetcd.HostLocator, +) (*url.URL, http.RoundTripper, error) { + return streamLocation(getter, connInfo, ctx, name, opts, opts.Container, "attach", hostLocator) } // ExecLocation returns the exec URL for a pod container. If opts.Container is blank // and only one container is present in the pod, that container is used. -func ExecLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts *api.PodExecOptions) (*url.URL, http.RoundTripper, error) { - return streamLocation(getter, connInfo, ctx, name, opts, opts.Container, "exec") +func ExecLocation( + getter ResourceGetter, + connInfo client.ConnectionInfoGetter, + ctx api.Context, + name string, + opts *api.PodExecOptions, + hostLocator nodeetcd.HostLocator, +) (*url.URL, http.RoundTripper, error) { + return streamLocation(getter, connInfo, ctx, name, opts, opts.Container, "exec", hostLocator) } -func streamLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string, opts runtime.Object, container, path string) (*url.URL, http.RoundTripper, error) { +func streamLocation( + getter ResourceGetter, + connInfo client.ConnectionInfoGetter, + ctx api.Context, + name string, + opts runtime.Object, + container, + path string, + hostLocator nodeetcd.HostLocator, +) (*url.URL, http.RoundTripper, error) { pod, err := getPod(getter, ctx, name) if err != nil { return nil, nil, err @@ -351,6 +389,13 @@ func streamLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, if err != nil { return nil, nil, err } + daemonPort, err := hostLocator.HostKubeletPort(pod, ctx) + if err != nil { + return nil, nil, err + } + if daemonPort > 0 { + nodePort = uint(daemonPort) + } params := url.Values{} if err := streamParams(params, opts); err != nil { return nil, nil, err @@ -365,7 +410,13 @@ func streamLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, } // PortForwardLocation returns the port-forward URL for a pod. -func PortForwardLocation(getter ResourceGetter, connInfo client.ConnectionInfoGetter, ctx api.Context, name string) (*url.URL, http.RoundTripper, error) { +func PortForwardLocation( + getter ResourceGetter, + connInfo client.ConnectionInfoGetter, + ctx api.Context, + name string, + hostLocator nodeetcd.HostLocator, +) (*url.URL, http.RoundTripper, error) { pod, err := getPod(getter, ctx, name) if err != nil { return nil, nil, err @@ -380,6 +431,13 @@ func PortForwardLocation(getter ResourceGetter, connInfo client.ConnectionInfoGe if err != nil { return nil, nil, err } + daemonPort, err := hostLocator.HostKubeletPort(pod, ctx) + if err != nil { + return nil, nil, err + } + if daemonPort > 0 { + nodePort = uint(daemonPort) + } loc := &url.URL{ Scheme: nodeScheme, Host: fmt.Sprintf("%s:%d", nodeHost, nodePort),