Skip to content

Commit c2d1541

Browse files
authored
Merge pull request kubernetes#91277 from borgerli/master
log tls handshake error at trace level to avoid error flooding
2 parents d20c5ed + eabb362 commit c2d1541

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

staging/src/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ var (
123123
},
124124
[]string{"requestKind"},
125125
)
126+
// TLSHandshakeErrors is a number of requests dropped with 'TLS handshake error from' error
127+
TLSHandshakeErrors = compbasemetrics.NewCounter(
128+
&compbasemetrics.CounterOpts{
129+
Name: "apiserver_tls_handshake_errors_total",
130+
Help: "Number of requests dropped with 'TLS handshake error from' error",
131+
StabilityLevel: compbasemetrics.ALPHA,
132+
},
133+
)
126134
// RegisteredWatchers is a number of currently registered watchers splitted by resource.
127135
RegisteredWatchers = compbasemetrics.NewGaugeVec(
128136
&compbasemetrics.GaugeOpts{
@@ -177,6 +185,7 @@ var (
177185
requestLatencies,
178186
responseSizes,
179187
DroppedRequests,
188+
TLSHandshakeErrors,
180189
RegisteredWatchers,
181190
WatchEvents,
182191
WatchEventsSizes,

staging/src/k8s.io/apiserver/pkg/server/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ go_library(
102102
"//staging/src/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library",
103103
"//staging/src/k8s.io/apiserver/pkg/endpoints/filters:go_default_library",
104104
"//staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters:go_default_library",
105+
"//staging/src/k8s.io/apiserver/pkg/endpoints/metrics:go_default_library",
105106
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
106107
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
107108
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",

staging/src/k8s.io/apiserver/pkg/server/secure_serving.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,20 @@ import (
2020
"context"
2121
"crypto/tls"
2222
"fmt"
23+
"io"
24+
"log"
2325
"net"
2426
"net/http"
27+
"os"
28+
"strings"
2529
"time"
2630

2731
"golang.org/x/net/http2"
2832
"k8s.io/component-base/cli/flag"
2933
"k8s.io/klog/v2"
3034

3135
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
36+
"k8s.io/apiserver/pkg/endpoints/metrics"
3237
"k8s.io/apiserver/pkg/server/dynamiccertificates"
3338
)
3439

@@ -184,6 +189,11 @@ func (s *SecureServingInfo) Serve(handler http.Handler, shutdownTimeout time.Dur
184189
}
185190
}
186191

192+
// use tlsHandshakeErrorWriter to handle messages of tls handshake error
193+
tlsErrorWriter := &tlsHandshakeErrorWriter{os.Stderr}
194+
tlsErrorLogger := log.New(tlsErrorWriter, "", 0)
195+
secureServer.ErrorLog = tlsErrorLogger
196+
187197
klog.Infof("Serving securely on %s", secureServer.Addr)
188198
return RunServer(secureServer, s.Listener, shutdownTimeout, stopCh)
189199
}
@@ -258,3 +268,22 @@ func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
258268
}
259269
return c, nil
260270
}
271+
272+
// tlsHandshakeErrorWriter writes TLS handshake errors to klog with
273+
// trace level - V(5), to avoid flooding of tls handshake errors.
274+
type tlsHandshakeErrorWriter struct {
275+
out io.Writer
276+
}
277+
278+
const tlsHandshakeErrorPrefix = "http: TLS handshake error"
279+
280+
func (w *tlsHandshakeErrorWriter) Write(p []byte) (int, error) {
281+
if strings.Contains(string(p), tlsHandshakeErrorPrefix) {
282+
klog.V(5).Info(string(p))
283+
metrics.TLSHandshakeErrors.Inc()
284+
return len(p), nil
285+
}
286+
287+
// for non tls handshake error, log it as usual
288+
return w.out.Write(p)
289+
}

staging/src/k8s.io/component-base/metrics/counter.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ func NewCounter(opts *CounterOpts) *Counter {
4545
return kc
4646
}
4747

48+
// Reset resets the underlying prometheus Counter to start counting from 0 again
49+
func (c *Counter) Reset() {
50+
if !c.IsCreated() {
51+
return
52+
}
53+
c.setPrometheusCounter(prometheus.NewCounter(c.CounterOpts.toPromCounterOpts()))
54+
}
55+
4856
// setPrometheusCounter sets the underlying CounterMetric object, i.e. the thing that does the measurement.
4957
func (c *Counter) setPrometheusCounter(counter prometheus.Counter) {
5058
c.CounterMetric = counter

0 commit comments

Comments
 (0)