Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for disabling /logs endpoint in kubelet #87273

Merged
merged 1 commit into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/kubelet/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,8 @@ func startKubelet(k kubelet.Bootstrap, podCfg *config.PodConfig, kubeCfg *kubele

// start the kubelet server
if enableServer {
go k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth, enableCAdvisorJSONEndpoints, kubeCfg.EnableDebuggingHandlers, kubeCfg.EnableContentionProfiling)
go k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth,
enableCAdvisorJSONEndpoints, kubeCfg.EnableDebuggingHandlers, kubeCfg.EnableContentionProfiling, kubeCfg.EnableSystemLogHandler)

}
if kubeCfg.ReadOnlyPort > 0 {
Expand Down
1 change: 1 addition & 0 deletions pkg/kubelet/apis/config/fuzzer/fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
if obj.Logging.Format == "" {
obj.Logging.Format = "text"
}
obj.EnableSystemLogHandler = true
},
}
}
1 change: 1 addition & 0 deletions pkg/kubelet/apis/config/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ var (
"EnableControllerAttachDetach",
"EnableDebuggingHandlers",
"EnableServer",
"EnableSystemLogHandler",
"EnforceNodeAllocatable[*]",
"EventBurst",
"EventRecordQPS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enableServer: true
enableSystemLogHandler: true
enforceNodeAllocatable:
- pods
eventBurst: 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enableServer: true
enableSystemLogHandler: true
enforceNodeAllocatable:
- pods
eventBurst: 10
Expand Down
2 changes: 2 additions & 0 deletions pkg/kubelet/apis/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ type KubeletConfiguration struct {
// Logging specifies the options of logging.
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information.
Logging componentbaseconfig.LoggingConfiguration
// EnableSystemLogHandler enables /logs handler.
EnableSystemLogHandler bool
}

// KubeletAuthorizationMode denotes the authorization mode for the kubelet
Expand Down
3 changes: 3 additions & 0 deletions pkg/kubelet/apis/config/v1beta1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,7 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura
}
// Use the Default LoggingConfiguration option
componentbaseconfigv1alpha1.RecommendedLoggingConfiguration(&obj.Logging)
if obj.EnableSystemLogHandler == nil {
obj.EnableSystemLogHandler = utilpointer.BoolPtr(true)
}
}
6 changes: 6 additions & 0 deletions pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions pkg/kubelet/kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ type Bootstrap interface {
GetConfiguration() kubeletconfiginternal.KubeletConfiguration
BirthCry()
StartGarbageCollection()
ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling bool)
ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling, enableSystemLogHandler bool)
ListenAndServeReadOnly(address net.IP, port uint, enableCAdvisorJSONEndpoints bool)
ListenAndServePodResources()
Run(<-chan kubetypes.PodUpdate)
Expand Down Expand Up @@ -2153,8 +2153,8 @@ func (kl *Kubelet) ResyncInterval() time.Duration {
}

// ListenAndServe runs the kubelet HTTP server.
func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling bool) {
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling, kl.redirectContainerStreaming, kl.criHandler)
func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling, enableSystemLogHandler bool) {
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling, kl.redirectContainerStreaming, enableSystemLogHandler, kl.criHandler)
}

// ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode.
Expand Down
48 changes: 31 additions & 17 deletions pkg/kubelet/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,11 @@ func ListenAndServeKubeletServer(
enableCAdvisorJSONEndpoints,
enableDebuggingHandlers,
enableContentionProfiling,
redirectContainerStreaming bool,
redirectContainerStreaming,
enableSystemLogHandler bool,
criHandler http.Handler) {
klog.Infof("Starting to listen on %s:%d", address, port)
handler := NewServer(host, resourceAnalyzer, auth, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling, redirectContainerStreaming, criHandler)
handler := NewServer(host, resourceAnalyzer, auth, enableCAdvisorJSONEndpoints, enableDebuggingHandlers, enableContentionProfiling, redirectContainerStreaming, enableSystemLogHandler, criHandler)
s := &http.Server{
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
Handler: &handler,
Expand All @@ -168,7 +169,7 @@ func ListenAndServeKubeletServer(
// ListenAndServeKubeletReadOnlyServer initializes a server to respond to HTTP network requests on the Kubelet.
func ListenAndServeKubeletReadOnlyServer(host HostInterface, resourceAnalyzer stats.ResourceAnalyzer, address net.IP, port uint, enableCAdvisorJSONEndpoints bool) {
klog.V(1).Infof("Starting to listen read-only on %s:%d", address, port)
s := NewServer(host, resourceAnalyzer, nil, enableCAdvisorJSONEndpoints, false, false, false, nil)
s := NewServer(host, resourceAnalyzer, nil, enableCAdvisorJSONEndpoints, false, false, false, false, nil)

server := &http.Server{
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
Expand Down Expand Up @@ -222,7 +223,8 @@ func NewServer(
enableCAdvisorJSONEndpoints,
enableDebuggingHandlers,
enableContentionProfiling,
redirectContainerStreaming bool,
redirectContainerStreaming,
enableSystemLogHandler bool,
criHandler http.Handler) Server {
server := Server{
host: host,
Expand All @@ -239,6 +241,9 @@ func NewServer(
server.InstallDefaultHandlers(enableCAdvisorJSONEndpoints)
if enableDebuggingHandlers {
server.InstallDebuggingHandlers(criHandler)
// To maintain backward compatibility serve logs only when enableDebuggingHandlers is also enabled
// see https://github.com/kubernetes/kubernetes/pull/87273
server.InstallSystemLogHandler(enableSystemLogHandler)
if enableContentionProfiling {
goruntime.SetBlockProfileRate(1)
}
Expand Down Expand Up @@ -470,19 +475,6 @@ func (s *Server) InstallDebuggingHandlers(criHandler http.Handler) {
Operation("getPortForward"))
s.restfulCont.Add(ws)

s.addMetricsBucketMatcher("logs")
ws = new(restful.WebService)
ws.
Path(logsPath)
ws.Route(ws.GET("").
To(s.getLogs).
Operation("getLogs"))
ws.Route(ws.GET("/{logpath:*}").
To(s.getLogs).
Operation("getLogs").
Param(ws.PathParameter("logpath", "path to the log").DataType("string")))
s.restfulCont.Add(ws)

s.addMetricsBucketMatcher("containerLogs")
ws = new(restful.WebService)
ws.
Expand Down Expand Up @@ -561,6 +553,28 @@ func (s *Server) InstallDebuggingDisabledHandlers() {
}
}

// InstallSystemLogHandler registers the HTTP request patterns for logs endpoint.
func (s *Server) InstallSystemLogHandler(enableSystemLogHandler bool) {
s.addMetricsBucketMatcher("logs")
if enableSystemLogHandler {
ws := new(restful.WebService)
ws.Path(logsPath)
ws.Route(ws.GET("").
To(s.getLogs).
Operation("getLogs"))
ws.Route(ws.GET("/{logpath:*}").
To(s.getLogs).
Operation("getLogs").
Param(ws.PathParameter("logpath", "path to the log").DataType("string")))
s.restfulCont.Add(ws)
} else {
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "logs endpoint is disabled.", http.StatusMethodNotAllowed)
})
s.restfulCont.Handle(logsPath, h)
}
}

// Checks if kubelet's sync loop that updates containers is working.
func (s *Server) syncLoopHealthCheck(req *http.Request) error {
duration := s.host.ResyncInterval() * 2
Expand Down
47 changes: 33 additions & 14 deletions pkg/kubelet/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ func newServerTest() *serverTestFramework {
}

func newServerTestWithDebug(enableDebugging, redirectContainerStreaming bool, streamingServer streaming.Server) *serverTestFramework {
return newServerTestWithDebuggingHandlers(enableDebugging, enableDebugging, redirectContainerStreaming, streamingServer)
}

func newServerTestWithDebuggingHandlers(enableDebugging, enableSystemLogHandler, redirectContainerStreaming bool,
streamingServer streaming.Server) *serverTestFramework {
fw := &serverTestFramework{}
fw.fakeKubelet = &fakeKubelet{
hostnameFunc: func() string {
Expand Down Expand Up @@ -340,6 +345,7 @@ func newServerTestWithDebug(enableDebugging, redirectContainerStreaming bool, st
enableDebugging,
false,
redirectContainerStreaming,
enableSystemLogHandler,
fw.criHandler)
fw.serverUnderTest = &server
fw.testHTTPServer = httptest.NewServer(fw.serverUnderTest)
Expand Down Expand Up @@ -1544,7 +1550,9 @@ func TestMetricMethodBuckets(t *testing.T) {
}

func TestDebuggingDisabledHandlers(t *testing.T) {
fw := newServerTestWithDebug(false, false, nil)
// for backward compatibility even if enablesystemLogHandler is set but not enableDebuggingHandler then /logs
//shouldn't be served.
fw := newServerTestWithDebuggingHandlers(false, true, false, nil)
defer fw.testHTTPServer.Close()

paths := []string{
Expand All @@ -1554,19 +1562,7 @@ func TestDebuggingDisabledHandlers(t *testing.T) {
}

for _, p := range paths {
resp, err := http.Get(fw.testHTTPServer.URL + p)
require.NoError(t, err)
assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode)
body, err := ioutil.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, "Debug endpoints are disabled.\n", string(body))

resp, err = http.Post(fw.testHTTPServer.URL+p, "", nil)
require.NoError(t, err)
assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode)
body, err = ioutil.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, "Debug endpoints are disabled.\n", string(body))
verifyEndpointResponse(t, fw, p, "Debug endpoints are disabled.\n")
}

// test some other paths, make sure they're working
Expand Down Expand Up @@ -1599,6 +1595,14 @@ func TestDebuggingDisabledHandlers(t *testing.T) {

}

func TestDisablingSystemLogHandler(t *testing.T) {
fw := newServerTestWithDebuggingHandlers(true, false, false, nil)
defer fw.testHTTPServer.Close()

// verify logs endpoint is disabled
verifyEndpointResponse(t, fw, "/logs/kubelet.log", "logs endpoint is disabled.\n")
}

func TestFailedParseParamsSummaryHandler(t *testing.T) {
fw := newServerTest()
defer fw.testHTTPServer.Close()
Expand All @@ -1610,7 +1614,22 @@ func TestFailedParseParamsSummaryHandler(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
assert.Contains(t, string(v), "parse form failed")
}

func verifyEndpointResponse(t *testing.T, fw *serverTestFramework, path string, expectedResponse string) {
resp, err := http.Get(fw.testHTTPServer.URL + path)
require.NoError(t, err)
assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode)
body, err := ioutil.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, expectedResponse, string(body))

resp, err = http.Post(fw.testHTTPServer.URL+path, "", nil)
require.NoError(t, err)
assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode)
body, err = ioutil.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, expectedResponse, string(body))
}

func TestTrimURLPath(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions staging/src/k8s.io/kubelet/config/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,10 @@ type KubeletConfiguration struct {
// Format: text
// + optional
Logging componentbaseconfigv1alpha1.LoggingConfiguration `json:"logging,omitempty"`
// enableSystemLogHandler enables system logs via web interface host:port/logs/
// Default: true
// +optional
EnableSystemLogHandler *bool `json:"enableSystemLogHandler,omitempty"`
}

type KubeletAuthorizationMode string
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.