Question:
We should introduce a buffer (similar to what we have in the webhook output backend) to the log file output backend. Audit events should be queued on a relatively large buffer chanel, and an output go routine should grab events off the queue and write them to disk. If an audit event is output when the channel is full, it should be dropped (this should be counted by a prometheus metric, and an e2e test should ensure that the count is below some threshold). This behavior should be optional (configurable) /cc is tracking the regression
Naturally os will cache , these cached data will be written to disk either by fsync or pdflush periodically. What do you think is the most time-costing procedure in audit?
The problem is not with the time consumed. The problem is that currently write is performed synchronously with processing the request, which slows the request down, no matter how well caching works
The problem is that currently write is performed synchronously with processing the request Sure synchronously write does cost time serializing. Introduce buffer mechanism can really reduce api request latency time.
It doesn't matter that much if it happens asynchronously Indeed
Yes, this is a good point to improve performance.
Now I totally comprehend this. I am pleased to implement this buffer.
I'll be happy to review that
audit log is important sensitive information which we should try to make sure it reaches disk at all cost. Does this effort compromises that in favor of optimizing for latency ?
I'll make sure it's configurable and if the security is critical, you can setup synchronous write in your deployment. Having said that, it's critical to be able to accommodate the case where having 100% calls written does not compensate for increased latencies. Does it make sense?
thanks my preference would be to keep the default as no buffering when making it configurable. I didnt understand how does one setup "synchronous write in your deployment" and how that will affect audit logs reaching disk. My worry is mainly around a crash where the buffered audit logs dont reach the disk and are lost
if use buffer, audit events lost is inevitable when crash. As like webhook backend, still exist this risk. But to improve apiserver qps, something should comprise. By the way, we still reserve the synchronous write mode, which is configurable.
To make it simple, when offered trade-off, people are more likely to give up audit logs reliability than performance. Makes sense?
i am not against this change. i think what would be best is to make the default as no buffering and enable buffering through a parameter. Also for Enterprises, the trade off is not correct, they would prefer to NOT give up audit logs
I understand what you're suggesting and I don't agree :) Switching to buffering will for sure increase the latency, but will only increase the probability of losing logs, which will never be zero. I'm pretty sure we need to have buffered mode by default. However, since this argument is about making a trade-off and since neither of us represents quorum, let's ask more people for their opinion What do you think?
The default is slightly less important here since audit logging as a whole is not enabled by default. If we do turn it on by default, it becomes more important. That said, my hunch is that we should default to the mode with lower performance impact, but I don't have strong feelings either way.
As long as there are options to turn it on of off (the synchronous write) I'm fine with either default. Still, I'd like to see due diligence towards ensuring low lost rate when using buffered write, and sufficient documentation around caveats of using one or the other. Audit, from my personal experience, is crucial for majority of enterprises and they won't tolerate not even single lost event.
That is not possible, there will always be a situation when an audit event can be lost: sudden power loss, disk/network failure, random bit flip, etc. The questions is whether 10^(-6) is low enough loss probability, or we need to get 10^(-14) by sacrificing performance (arbitrary numbers, just to illustrate my point). Note, that reduced performance can increase the number of timeouts and retries, increasing load and leading to failures and even more lost events.
I think this is an important bug that we're not testing audit logging at scale
Marking it as urgent, since it's blocking
If split into 3 prs, I must do it one by one . Now first one is up .
SGTM Status of this issue: ETA: 1/12/2017 Risks: Complicated fix required
has been reviewed for almost 2 months and has not done. If I raise 3 prs to replace it, I am still worried whether all of them can be merged. They act as a whole.
Now I'm going to devote my time to it, we'll do it
OK.
In progress, reviewed first PR, waiting for applying changes ETA: Dec 01
Per Exception discussion, this portion of the feature is being removed from the milestone. As such, changing the priority. /priority important-soon /remove-priority critical-urgent
[MILESTONENOTIFIER] Milestone Removed From Issue Important: Code freeze is in effect and only issues with may remain in the v1.9 milestone. <details<summaryHelp</summary<ul<li<a href=""Additional instructions</a</li<li<a href=""Commands for setting labels</a</li</ul</details

name = "all-srcs", srcs = [ ":package-srcs", <ins> "//staging/src/k8s.io/apiserver/plugin/pkg/audit/buffered:all-srcs", </ins> "//staging/src/k8s.io/apiserver/plugin/pkg/audit/log:all-srcs", "//staging/src/k8s.io/apiserver/plugin/pkg/audit/webhook:all-srcs", ],


Question:
We should introduce a buffer (similar to what we have in the webhook output backend) to the log file output backend. Audit events should be queued on a relatively large buffer chanel, and an output go routine should grab events off the queue and write them to disk. If an audit event is output when the channel is full, it should be dropped (this should be counted by a prometheus metric, and an e2e test should ensure that the count is below some threshold). This behavior should be optional (configurable) /cc is tracking the regression
Naturally os will cache , these cached data will be written to disk either by fsync or pdflush periodically. What do you think is the most time-costing procedure in audit?
The problem is not with the time consumed. The problem is that currently write is performed synchronously with processing the request, which slows the request down, no matter how well caching works
The problem is that currently write is performed synchronously with processing the request Sure synchronously write does cost time serializing. Introduce buffer mechanism can really reduce api request latency time.
It doesn't matter that much if it happens asynchronously Indeed
Yes, this is a good point to improve performance.
Now I totally comprehend this. I am pleased to implement this buffer.
I'll be happy to review that
audit log is important sensitive information which we should try to make sure it reaches disk at all cost. Does this effort compromises that in favor of optimizing for latency ?
I'll make sure it's configurable and if the security is critical, you can setup synchronous write in your deployment. Having said that, it's critical to be able to accommodate the case where having 100% calls written does not compensate for increased latencies. Does it make sense?
thanks my preference would be to keep the default as no buffering when making it configurable. I didnt understand how does one setup "synchronous write in your deployment" and how that will affect audit logs reaching disk. My worry is mainly around a crash where the buffered audit logs dont reach the disk and are lost
if use buffer, audit events lost is inevitable when crash. As like webhook backend, still exist this risk. But to improve apiserver qps, something should comprise. By the way, we still reserve the synchronous write mode, which is configurable.
To make it simple, when offered trade-off, people are more likely to give up audit logs reliability than performance. Makes sense?
i am not against this change. i think what would be best is to make the default as no buffering and enable buffering through a parameter. Also for Enterprises, the trade off is not correct, they would prefer to NOT give up audit logs
I understand what you're suggesting and I don't agree :) Switching to buffering will for sure increase the latency, but will only increase the probability of losing logs, which will never be zero. I'm pretty sure we need to have buffered mode by default. However, since this argument is about making a trade-off and since neither of us represents quorum, let's ask more people for their opinion What do you think?
The default is slightly less important here since audit logging as a whole is not enabled by default. If we do turn it on by default, it becomes more important. That said, my hunch is that we should default to the mode with lower performance impact, but I don't have strong feelings either way.
As long as there are options to turn it on of off (the synchronous write) I'm fine with either default. Still, I'd like to see due diligence towards ensuring low lost rate when using buffered write, and sufficient documentation around caveats of using one or the other. Audit, from my personal experience, is crucial for majority of enterprises and they won't tolerate not even single lost event.
That is not possible, there will always be a situation when an audit event can be lost: sudden power loss, disk/network failure, random bit flip, etc. The questions is whether 10^(-6) is low enough loss probability, or we need to get 10^(-14) by sacrificing performance (arbitrary numbers, just to illustrate my point). Note, that reduced performance can increase the number of timeouts and retries, increasing load and leading to failures and even more lost events.
I think this is an important bug that we're not testing audit logging at scale
Marking it as urgent, since it's blocking
If split into 3 prs, I must do it one by one . Now first one is up .
SGTM Status of this issue: ETA: 1/12/2017 Risks: Complicated fix required
has been reviewed for almost 2 months and has not done. If I raise 3 prs to replace it, I am still worried whether all of them can be merged. They act as a whole.
Now I'm going to devote my time to it, we'll do it
OK.
In progress, reviewed first PR, waiting for applying changes ETA: Dec 01
Per Exception discussion, this portion of the feature is being removed from the milestone. As such, changing the priority. /priority important-soon /remove-priority critical-urgent
[MILESTONENOTIFIER] Milestone Removed From Issue Important: Code freeze is in effect and only issues with may remain in the v1.9 milestone. <details<summaryHelp</summary<ul<li<a href=""Additional instructions</a</li<li<a href=""Commands for setting labels</a</li</ul</details

<ins> load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ "buffered.go", "doc.go", ], importpath = "k8s.io/apiserver/plugin/pkg/audit/buffered", visibility = ["//visibility:public"], deps = [ "//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library", "//vendor/k8s.io/apiserver/pkg/audit:go_default_library", "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library", ], ) go_test( name = "go_default_test", srcs = ["buffered_test.go"], embed = [":go_default_library"], deps = [ "//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apiserver/pkg/apis/audit:go_default_library", "//vendor/k8s.io/apiserver/pkg/audit:go_default_library", ], ) filegroup( name = "package-srcs", srcs = glob(["**"]), tags = ["automanaged"], visibility = ["//visibility:private"], ) filegroup( name = "all-srcs", srcs = [":package-srcs"], tags = ["automanaged"], visibility = ["//visibility:public"], ) </ins>


Question:
We should introduce a buffer (similar to what we have in the webhook output backend) to the log file output backend. Audit events should be queued on a relatively large buffer chanel, and an output go routine should grab events off the queue and write them to disk. If an audit event is output when the channel is full, it should be dropped (this should be counted by a prometheus metric, and an e2e test should ensure that the count is below some threshold). This behavior should be optional (configurable) /cc is tracking the regression
Naturally os will cache , these cached data will be written to disk either by fsync or pdflush periodically. What do you think is the most time-costing procedure in audit?
The problem is not with the time consumed. The problem is that currently write is performed synchronously with processing the request, which slows the request down, no matter how well caching works
The problem is that currently write is performed synchronously with processing the request Sure synchronously write does cost time serializing. Introduce buffer mechanism can really reduce api request latency time.
It doesn't matter that much if it happens asynchronously Indeed
Yes, this is a good point to improve performance.
Now I totally comprehend this. I am pleased to implement this buffer.
I'll be happy to review that
audit log is important sensitive information which we should try to make sure it reaches disk at all cost. Does this effort compromises that in favor of optimizing for latency ?
I'll make sure it's configurable and if the security is critical, you can setup synchronous write in your deployment. Having said that, it's critical to be able to accommodate the case where having 100% calls written does not compensate for increased latencies. Does it make sense?
thanks my preference would be to keep the default as no buffering when making it configurable. I didnt understand how does one setup "synchronous write in your deployment" and how that will affect audit logs reaching disk. My worry is mainly around a crash where the buffered audit logs dont reach the disk and are lost
if use buffer, audit events lost is inevitable when crash. As like webhook backend, still exist this risk. But to improve apiserver qps, something should comprise. By the way, we still reserve the synchronous write mode, which is configurable.
To make it simple, when offered trade-off, people are more likely to give up audit logs reliability than performance. Makes sense?
i am not against this change. i think what would be best is to make the default as no buffering and enable buffering through a parameter. Also for Enterprises, the trade off is not correct, they would prefer to NOT give up audit logs
I understand what you're suggesting and I don't agree :) Switching to buffering will for sure increase the latency, but will only increase the probability of losing logs, which will never be zero. I'm pretty sure we need to have buffered mode by default. However, since this argument is about making a trade-off and since neither of us represents quorum, let's ask more people for their opinion What do you think?
The default is slightly less important here since audit logging as a whole is not enabled by default. If we do turn it on by default, it becomes more important. That said, my hunch is that we should default to the mode with lower performance impact, but I don't have strong feelings either way.
As long as there are options to turn it on of off (the synchronous write) I'm fine with either default. Still, I'd like to see due diligence towards ensuring low lost rate when using buffered write, and sufficient documentation around caveats of using one or the other. Audit, from my personal experience, is crucial for majority of enterprises and they won't tolerate not even single lost event.
That is not possible, there will always be a situation when an audit event can be lost: sudden power loss, disk/network failure, random bit flip, etc. The questions is whether 10^(-6) is low enough loss probability, or we need to get 10^(-14) by sacrificing performance (arbitrary numbers, just to illustrate my point). Note, that reduced performance can increase the number of timeouts and retries, increasing load and leading to failures and even more lost events.
I think this is an important bug that we're not testing audit logging at scale
Marking it as urgent, since it's blocking
If split into 3 prs, I must do it one by one . Now first one is up .
SGTM Status of this issue: ETA: 1/12/2017 Risks: Complicated fix required
has been reviewed for almost 2 months and has not done. If I raise 3 prs to replace it, I am still worried whether all of them can be merged. They act as a whole.
Now I'm going to devote my time to it, we'll do it
OK.
In progress, reviewed first PR, waiting for applying changes ETA: Dec 01
Per Exception discussion, this portion of the feature is being removed from the milestone. As such, changing the priority. /priority important-soon /remove-priority critical-urgent
[MILESTONENOTIFIER] Milestone Removed From Issue Important: Code freeze is in effect and only issues with may remain in the v1.9 milestone. <details<summaryHelp</summary<ul<li<a href=""Additional instructions</a</li<li<a href=""Commands for setting labels</a</li</ul</details

<ins> /* Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package buffered import ( "fmt" "sync" "time" "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/audit" "k8s.io/client-go/util/flowcontrol" ) // The plugin name reported in error metrics. const pluginName = "buffered" const ( // Default configuration values for ModeBatch. defaultBatchBufferSize = 10000            // Buffer up to 10000 events before starting discarding. defaultBatchMaxSize    = 400              // Only send up to 400 events at a time. defaultBatchMaxWait    = 30 * time.Second // Send events at least twice a minute. defaultBatchThrottleQPS   = 10 // Limit the send rate by 10 QPS. defaultBatchThrottleBurst = 15 // Allow up to 15 QPS burst. ) // BatchConfig represents batching delegate audit backend configuration. type BatchConfig struct { // BufferSize defines a size of the buffering queue. BufferSize int // MaxBatchSize defines maximum size of a batch. MaxBatchSize int // MaxBatchWait indicates the maximum interval between two batches. MaxBatchWait time.Duration // ThrottleEnable defines whether throttling will be applied to the batching process. ThrottleEnable bool // ThrottleQPS defines the allowed rate of batches per second sent to the delegate backend. ThrottleQPS float32 // ThrottleBurst defines the maximum rate of batches per second sent to the delegate backend in case // the capacity defined by ThrottleQPS was not utilized. ThrottleBurst int } // NewDefaultBatchConfig returns new Config objects populated by default values. func NewDefaultBatchConfig() BatchConfig { return BatchConfig{ BufferSize:   defaultBatchBufferSize, MaxBatchSize: defaultBatchMaxSize, MaxBatchWait: defaultBatchMaxWait, ThrottleEnable: true, ThrottleQPS:    defaultBatchThrottleQPS, ThrottleBurst:  defaultBatchThrottleBurst, } } type bufferedBackend struct { // The delegate backend that actually exports events. delegateBackend audit.Backend // Channel to buffer events before sending to the delegate backend. buffer chan *auditinternal.Event // Maximum number of events in a batch sent to the delegate backend. maxBatchSize int // Amount of time to wait after sending a batch to the delegate backend before sending another one. // // Receiving maxBatchSize events will always trigger sending a batch, regardless of the amount of time passed. maxBatchWait time.Duration // Channel to signal that the batching routine has processed all remaining events and exited. // Once `shutdownCh` is closed no new events will be sent to the delegate backend. shutdownCh chan struct{} // WaitGroup to control the concurrency of sending batches to the delegate backend. // Worker routine calls Add before sending a batch and // then spawns a routine that calls Done after batch was processed by the delegate backend. // This WaitGroup is used to wait for all sending routines to finish before shutting down audit backend. wg sync.WaitGroup // Limits the number of batches sent to the delegate backend per second. throttle flowcontrol.RateLimiter } var _ audit.Backend = &bufferedBackend{} // NewBackend returns a buffered audit backend that wraps delegate backend. func NewBackend(delegate audit.Backend, config BatchConfig) audit.Backend { var throttle flowcontrol.RateLimiter if config.ThrottleEnable { throttle = flowcontrol.NewTokenBucketRateLimiter(config.ThrottleQPS, config.ThrottleBurst) } return &bufferedBackend{ delegateBackend: delegate, buffer:          make(chan *auditinternal.Event, config.BufferSize), maxBatchSize:    config.MaxBatchSize, maxBatchWait:    config.MaxBatchWait, shutdownCh:      make(chan struct{}), wg:              sync.WaitGroup{}, throttle:        throttle, } } func (b *bufferedBackend) Run(stopCh <-chan struct{}) error { go func() { // Signal that the working routine has exited. defer close(b.shutdownCh) b.processIncomingEvents(stopCh) // Handle the events that were received after the last buffer // scraping and before this line. Since the buffer is closed, no new // events will come through. allEventsProcessed := false timer := make(chan time.Time) for !allEventsProcessed { allEventsProcessed = func() bool { // Recover from any panic in order to try to process all remaining events. // Note, that in case of a panic, the return value will be false and // the loop execution will continue. defer runtime.HandleCrash() events := b.collectEvents(timer, wait.NeverStop) b.processEvents(events) return len(events) == 0 }() } }() return b.delegateBackend.Run(stopCh) } // Shutdown blocks until stopCh passed to the Run method is closed and all // events added prior to that moment are batched and sent to the delegate backend. func (b *bufferedBackend) Shutdown() { // Wait until the routine spawned in Run method exits. <-b.shutdownCh // Wait until all sending routines exit. b.wg.Wait() b.delegateBackend.Shutdown() } // processIncomingEvents runs a loop that collects events from the buffer. When // b.stopCh is closed, processIncomingEvents stops and closes the buffer. func (b *bufferedBackend) processIncomingEvents(stopCh <-chan struct{}) { defer close(b.buffer) t := time.NewTimer(b.maxBatchWait) defer t.Stop() for { func() { // Recover from any panics caused by this function so a panic in the // goroutine can't bring down the main routine. defer runtime.HandleCrash() t.Reset(b.maxBatchWait) b.processEvents(b.collectEvents(t.C, stopCh)) }() select { case <-stopCh: return default: } } } // collectEvents attempts to collect some number of events in a batch. // // The following things can cause collectEvents to stop and return the list // of events: // //   * Maximum number of events for a batch. //   * Timer has passed. //   * Buffer channel is closed and empty. //   * stopCh is closed. func (b *bufferedBackend) collectEvents(timer <-chan time.Time, stopCh <-chan struct{}) []*auditinternal.Event { var events []*auditinternal.Event L: for i := 0; i < b.maxBatchSize; i++ { select { case ev, ok := <-b.buffer: // Buffer channel was closed and no new events will follow. if !ok { break L } events = append(events, ev) case <-timer: // Timer has expired. Send currently accumulated batch. break L case <-stopCh: // Backend has been stopped. Send currently accumulated batch. break L } } return events } // processEvents process the batch events in a goroutine using delegateBackend's ProcessEvents. func (b *bufferedBackend) processEvents(events []*auditinternal.Event) { if len(events) == 0 { return } // TODO(audit): Should control the number of active goroutines // if one goroutine takes 5 seconds to finish, the number of goroutines can be 5 * defaultBatchThrottleQPS if b.throttle != nil { b.throttle.Accept() } b.wg.Add(1) go func() { defer b.wg.Done() defer runtime.HandleCrash() // Execute the real processing in a goroutine to keep it from blocking. // This lets the batching routine continue draining the queue immediately. b.delegateBackend.ProcessEvents(events...) }() } func (b *bufferedBackend) ProcessEvents(ev ...*auditinternal.Event) { // The following mechanism is in place to support the situation when audit // events are still coming after the backend was stopped. var sendErr error var evIndex int // If the delegateBackend was shutdown and the buffer channel was closed, an // attempt to add an event to it will result in panic that we should // recover from. defer func() { if err := recover(); err != nil { sendErr = fmt.Errorf("panic when processing events: %v", err) } if sendErr != nil { audit.HandlePluginError(pluginName, sendErr, ev[evIndex:]...) } }() for i, e := range ev { evIndex = i // Per the audit.Backend interface these events are reused after being // sent to the Sink. Deep copy and send the copy to the queue. event := e.DeepCopy() select { case b.buffer <- event: default: sendErr = fmt.Errorf("audit buffer queue blocked") return } } } </ins>


Question:
We should introduce a buffer (similar to what we have in the webhook output backend) to the log file output backend. Audit events should be queued on a relatively large buffer chanel, and an output go routine should grab events off the queue and write them to disk. If an audit event is output when the channel is full, it should be dropped (this should be counted by a prometheus metric, and an e2e test should ensure that the count is below some threshold). This behavior should be optional (configurable) /cc is tracking the regression
Naturally os will cache , these cached data will be written to disk either by fsync or pdflush periodically. What do you think is the most time-costing procedure in audit?
The problem is not with the time consumed. The problem is that currently write is performed synchronously with processing the request, which slows the request down, no matter how well caching works
The problem is that currently write is performed synchronously with processing the request Sure synchronously write does cost time serializing. Introduce buffer mechanism can really reduce api request latency time.
It doesn't matter that much if it happens asynchronously Indeed
Yes, this is a good point to improve performance.
Now I totally comprehend this. I am pleased to implement this buffer.
I'll be happy to review that
audit log is important sensitive information which we should try to make sure it reaches disk at all cost. Does this effort compromises that in favor of optimizing for latency ?
I'll make sure it's configurable and if the security is critical, you can setup synchronous write in your deployment. Having said that, it's critical to be able to accommodate the case where having 100% calls written does not compensate for increased latencies. Does it make sense?
thanks my preference would be to keep the default as no buffering when making it configurable. I didnt understand how does one setup "synchronous write in your deployment" and how that will affect audit logs reaching disk. My worry is mainly around a crash where the buffered audit logs dont reach the disk and are lost
if use buffer, audit events lost is inevitable when crash. As like webhook backend, still exist this risk. But to improve apiserver qps, something should comprise. By the way, we still reserve the synchronous write mode, which is configurable.
To make it simple, when offered trade-off, people are more likely to give up audit logs reliability than performance. Makes sense?
i am not against this change. i think what would be best is to make the default as no buffering and enable buffering through a parameter. Also for Enterprises, the trade off is not correct, they would prefer to NOT give up audit logs
I understand what you're suggesting and I don't agree :) Switching to buffering will for sure increase the latency, but will only increase the probability of losing logs, which will never be zero. I'm pretty sure we need to have buffered mode by default. However, since this argument is about making a trade-off and since neither of us represents quorum, let's ask more people for their opinion What do you think?
The default is slightly less important here since audit logging as a whole is not enabled by default. If we do turn it on by default, it becomes more important. That said, my hunch is that we should default to the mode with lower performance impact, but I don't have strong feelings either way.
As long as there are options to turn it on of off (the synchronous write) I'm fine with either default. Still, I'd like to see due diligence towards ensuring low lost rate when using buffered write, and sufficient documentation around caveats of using one or the other. Audit, from my personal experience, is crucial for majority of enterprises and they won't tolerate not even single lost event.
That is not possible, there will always be a situation when an audit event can be lost: sudden power loss, disk/network failure, random bit flip, etc. The questions is whether 10^(-6) is low enough loss probability, or we need to get 10^(-14) by sacrificing performance (arbitrary numbers, just to illustrate my point). Note, that reduced performance can increase the number of timeouts and retries, increasing load and leading to failures and even more lost events.
I think this is an important bug that we're not testing audit logging at scale
Marking it as urgent, since it's blocking
If split into 3 prs, I must do it one by one . Now first one is up .
SGTM Status of this issue: ETA: 1/12/2017 Risks: Complicated fix required
has been reviewed for almost 2 months and has not done. If I raise 3 prs to replace it, I am still worried whether all of them can be merged. They act as a whole.
Now I'm going to devote my time to it, we'll do it
OK.
In progress, reviewed first PR, waiting for applying changes ETA: Dec 01
Per Exception discussion, this portion of the feature is being removed from the milestone. As such, changing the priority. /priority important-soon /remove-priority critical-urgent
[MILESTONENOTIFIER] Milestone Removed From Issue Important: Code freeze is in effect and only issues with may remain in the v1.9 milestone. <details<summaryHelp</summary<ul<li<a href=""Additional instructions</a</li<li<a href=""Commands for setting labels</a</li</ul</details

<ins> /* Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package buffered import ( "testing" "time" "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/util/wait" auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/audit" ) var ( closedStopCh = func() <-chan struct{} { ch := make(chan struct{}) close(ch) return ch }() infiniteTimeCh <-chan time.Time = make(chan time.Time) closedTimeCh                    = func() <-chan time.Time { ch := make(chan time.Time) close(ch) return ch }() ) func newEvents(number int) []*auditinternal.Event { events := make([]*auditinternal.Event, number) for i := range events { events[i] = &auditinternal.Event{} } return events } func TestBufferedBackendCollectEvents(t *testing.T) { config := NewDefaultBatchConfig() testCases := []struct { desc          string timer         <-chan time.Time stopCh        <-chan struct{} numEvents     int wantBatchSize int }{ { desc:          "max batch size encountered", timer:         infiniteTimeCh, stopCh:        wait.NeverStop, numEvents:     config.MaxBatchSize + 1, wantBatchSize: config.MaxBatchSize, }, { desc:   "timer expired", timer:  closedTimeCh, stopCh: wait.NeverStop, }, { desc:   "chanel closed", timer:  infiniteTimeCh, stopCh: closedStopCh, }, } for _, tc := range testCases { tc := tc t.Run(tc.desc, func(t *testing.T) { t.Parallel() backend := NewBackend(&fakeBackend{}, config).(*bufferedBackend) backend.ProcessEvents(newEvents(tc.numEvents)...) batch := backend.collectEvents(tc.timer, tc.stopCh) require.Equal(t, tc.wantBatchSize, len(batch), "unexpected batch size") }) } } func TestBufferedBackendProcessEventsAfterStop(t *testing.T) { t.Parallel() backend := NewBackend(&fakeBackend{}, NewDefaultBatchConfig()).(*bufferedBackend) backend.Run(closedStopCh) backend.Shutdown() backend.ProcessEvents(newEvents(1)...) batch := backend.collectEvents(infiniteTimeCh, wait.NeverStop) require.Equal(t, 0, len(batch), "processed events after the backed has been stopped") } func TestBufferedBackendProcessEventsBufferFull(t *testing.T) { t.Parallel() config := NewDefaultBatchConfig() config.BufferSize = 1 backend := NewBackend(&fakeBackend{}, config).(*bufferedBackend) backend.ProcessEvents(newEvents(2)...) require.Equal(t, 1, len(backend.buffer), "buffed contains more elements than it should") } func TestBufferedBackendShutdownWaitsForDelegatedCalls(t *testing.T) { t.Parallel() delegatedCallStartCh := make(chan struct{}) delegatedCallEndCh := make(chan struct{}) delegateBackend := &fakeBackend{ onRequest: func(_ []*auditinternal.Event) { close(delegatedCallStartCh) <-delegatedCallEndCh }, } config := NewDefaultBatchConfig() backend := NewBackend(delegateBackend, config) // Run backend, process events, wait for them to be batched and for delegated call to start. stopCh := make(chan struct{}) backend.Run(stopCh) backend.ProcessEvents(newEvents(config.MaxBatchSize)...) <-delegatedCallStartCh // Start shutdown procedure. shutdownEndCh := make(chan struct{}) go func() { close(stopCh) backend.Shutdown() close(shutdownEndCh) }() // Wait for some time and then check whether Shutdown has exited. Can give false positive, // but never false negative. time.Sleep(100 * time.Millisecond) select { case <-shutdownEndCh: t.Fatalf("Shutdown exited before delegated call ended") default: } // Wait for Shutdown to exit after delegated call has exited. close(delegatedCallEndCh) <-shutdownEndCh } type fakeBackend struct { onRequest func(events []*auditinternal.Event) } var _ audit.Backend = &fakeBackend{} func (b *fakeBackend) Run(stopCh <-chan struct{}) error { return nil } func (b *fakeBackend) Shutdown() { return } func (b *fakeBackend) ProcessEvents(ev ...*auditinternal.Event) { if b.onRequest != nil { b.onRequest(ev) } } </ins>


Question:
We should introduce a buffer (similar to what we have in the webhook output backend) to the log file output backend. Audit events should be queued on a relatively large buffer chanel, and an output go routine should grab events off the queue and write them to disk. If an audit event is output when the channel is full, it should be dropped (this should be counted by a prometheus metric, and an e2e test should ensure that the count is below some threshold). This behavior should be optional (configurable) /cc is tracking the regression
Naturally os will cache , these cached data will be written to disk either by fsync or pdflush periodically. What do you think is the most time-costing procedure in audit?
The problem is not with the time consumed. The problem is that currently write is performed synchronously with processing the request, which slows the request down, no matter how well caching works
The problem is that currently write is performed synchronously with processing the request Sure synchronously write does cost time serializing. Introduce buffer mechanism can really reduce api request latency time.
It doesn't matter that much if it happens asynchronously Indeed
Yes, this is a good point to improve performance.
Now I totally comprehend this. I am pleased to implement this buffer.
I'll be happy to review that
audit log is important sensitive information which we should try to make sure it reaches disk at all cost. Does this effort compromises that in favor of optimizing for latency ?
I'll make sure it's configurable and if the security is critical, you can setup synchronous write in your deployment. Having said that, it's critical to be able to accommodate the case where having 100% calls written does not compensate for increased latencies. Does it make sense?
thanks my preference would be to keep the default as no buffering when making it configurable. I didnt understand how does one setup "synchronous write in your deployment" and how that will affect audit logs reaching disk. My worry is mainly around a crash where the buffered audit logs dont reach the disk and are lost
if use buffer, audit events lost is inevitable when crash. As like webhook backend, still exist this risk. But to improve apiserver qps, something should comprise. By the way, we still reserve the synchronous write mode, which is configurable.
To make it simple, when offered trade-off, people are more likely to give up audit logs reliability than performance. Makes sense?
i am not against this change. i think what would be best is to make the default as no buffering and enable buffering through a parameter. Also for Enterprises, the trade off is not correct, they would prefer to NOT give up audit logs
I understand what you're suggesting and I don't agree :) Switching to buffering will for sure increase the latency, but will only increase the probability of losing logs, which will never be zero. I'm pretty sure we need to have buffered mode by default. However, since this argument is about making a trade-off and since neither of us represents quorum, let's ask more people for their opinion What do you think?
The default is slightly less important here since audit logging as a whole is not enabled by default. If we do turn it on by default, it becomes more important. That said, my hunch is that we should default to the mode with lower performance impact, but I don't have strong feelings either way.
As long as there are options to turn it on of off (the synchronous write) I'm fine with either default. Still, I'd like to see due diligence towards ensuring low lost rate when using buffered write, and sufficient documentation around caveats of using one or the other. Audit, from my personal experience, is crucial for majority of enterprises and they won't tolerate not even single lost event.
That is not possible, there will always be a situation when an audit event can be lost: sudden power loss, disk/network failure, random bit flip, etc. The questions is whether 10^(-6) is low enough loss probability, or we need to get 10^(-14) by sacrificing performance (arbitrary numbers, just to illustrate my point). Note, that reduced performance can increase the number of timeouts and retries, increasing load and leading to failures and even more lost events.
I think this is an important bug that we're not testing audit logging at scale
Marking it as urgent, since it's blocking
If split into 3 prs, I must do it one by one . Now first one is up .
SGTM Status of this issue: ETA: 1/12/2017 Risks: Complicated fix required
has been reviewed for almost 2 months and has not done. If I raise 3 prs to replace it, I am still worried whether all of them can be merged. They act as a whole.
Now I'm going to devote my time to it, we'll do it
OK.
In progress, reviewed first PR, waiting for applying changes ETA: Dec 01
Per Exception discussion, this portion of the feature is being removed from the milestone. As such, changing the priority. /priority important-soon /remove-priority critical-urgent
[MILESTONENOTIFIER] Milestone Removed From Issue Important: Code freeze is in effect and only issues with may remain in the v1.9 milestone. <details<summaryHelp</summary<ul<li<a href=""Additional instructions</a</li<li<a href=""Commands for setting labels</a</li</ul</details

<ins> /* Copyright 2018 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // Package buffered provides an implementation for the audit.Backend interface // that batches incoming audit events and sends batches to the delegate audit.Backend. package buffered // import "k8s.io/apiserver/plugin/pkg/audit/buffered" </ins>


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: Creating a service with created a load balancer without a floating IP. What you expected to happen: Load balancer should have a floating IP assigned by default. How to reproduce it (as minimally and precisely as possible): Deploy this manifest on a cluster and check the resulting load balancer. No floating IP will be assigned. Anything else we need to know?: The default behavior changed from k8s 1.7.x. It appears that an annotation that will add a floating IP, but the default should not have changed without warning. This also breaks the workflow. For example: Environment: Kubernetes version (use ): v1.8.0-rc.1+coreos.0 Cloud provider or hardware configuration**: openstack OS (e.g. from /etc/os-release): Container Linux by CoreOS 1520.4.0 (Ladybug) Kernel (e.g. ): 4.13.3-coreos Install tools: Others:
There are no sig labels on this issue. Please by: a sig: e.g., to notify the contributor experience sig, OR the label manually: e.g., to apply the label Note: Method 1 will trigger an email to the group. You can find the group list and label list . The in the method 1 has to be replaced with one of these: bugs, feature-requests, pr-reviews, test-failures, proposals
/sig openstack
Reiterating the mentions to trigger a notification: <detailsIn response to : Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
Oops, default should be external. /assign

// ServiceAnnotationLoadBalancerInternal is the annotation used on the service // to indicate that we want an internal loadbalancer service. <del> // If the value of ServiceAnnotationLoadBalancerInternal is false, it indicates that we want an external loadbalancer service. Default to true. </del> <ins> // If the value of ServiceAnnotationLoadBalancerInternal is false, it indicates that we want an external loadbalancer service. Default to false. </ins> ServiceAnnotationLoadBalancerInternal = "service.beta.kubernetes.io/openstack-internal-load-balancer" )


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: Creating a service with created a load balancer without a floating IP. What you expected to happen: Load balancer should have a floating IP assigned by default. How to reproduce it (as minimally and precisely as possible): Deploy this manifest on a cluster and check the resulting load balancer. No floating IP will be assigned. Anything else we need to know?: The default behavior changed from k8s 1.7.x. It appears that an annotation that will add a floating IP, but the default should not have changed without warning. This also breaks the workflow. For example: Environment: Kubernetes version (use ): v1.8.0-rc.1+coreos.0 Cloud provider or hardware configuration**: openstack OS (e.g. from /etc/os-release): Container Linux by CoreOS 1520.4.0 (Ladybug) Kernel (e.g. ): 4.13.3-coreos Install tools: Others:
There are no sig labels on this issue. Please by: a sig: e.g., to notify the contributor experience sig, OR the label manually: e.g., to apply the label Note: Method 1 will trigger an email to the group. You can find the group list and label list . The in the method 1 has to be replaced with one of these: bugs, feature-requests, pr-reviews, test-failures, proposals
/sig openstack
Reiterating the mentions to trigger a notification: <detailsIn response to : Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
Oops, default should be external. /assign

glog.V(4).Infof("EnsureLoadBalancer using floatingPool: %v", floatingPool) var internalAnnotation bool <del> internal := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerInternal, "true") </del> <ins> internal := getStringFromServiceAnnotation(apiService, ServiceAnnotationLoadBalancerInternal, "false") </ins> switch internal { case "true": glog.V(4).Infof("Ensure an internal loadbalancer service.")


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: Creating a service with created a load balancer without a floating IP. What you expected to happen: Load balancer should have a floating IP assigned by default. How to reproduce it (as minimally and precisely as possible): Deploy this manifest on a cluster and check the resulting load balancer. No floating IP will be assigned. Anything else we need to know?: The default behavior changed from k8s 1.7.x. It appears that an annotation that will add a floating IP, but the default should not have changed without warning. This also breaks the workflow. For example: Environment: Kubernetes version (use ): v1.8.0-rc.1+coreos.0 Cloud provider or hardware configuration**: openstack OS (e.g. from /etc/os-release): Container Linux by CoreOS 1520.4.0 (Ladybug) Kernel (e.g. ): 4.13.3-coreos Install tools: Others:
There are no sig labels on this issue. Please by: a sig: e.g., to notify the contributor experience sig, OR the label manually: e.g., to apply the label Note: Method 1 will trigger an email to the group. You can find the group list and label list . The in the method 1 has to be replaced with one of these: bugs, feature-requests, pr-reviews, test-failures, proposals
/sig openstack
Reiterating the mentions to trigger a notification: <detailsIn response to : Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
Oops, default should be external. /assign

glog.V(4).Infof("Ensure an external loadbalancer service.") internalAnnotation = false } else { <del> return nil, fmt.Errorf("floating-network-id or loadbalancer.openstack.org/floating-network-id should be specified when service.beta.kubernetes.io/openstack-internal-load-balancer is false") </del> <ins> return nil, fmt.Errorf("floating-network-id or loadbalancer.openstack.org/floating-network-id should be specified when ensuring an external loadbalancer service.") </ins> } default: return nil, fmt.Errorf("unknow service.beta.kubernetes.io/openstack-internal-load-balancer annotation: %v, specify "true" or "false".",


Question:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: What you expected to happen: Test should not flake /sig storage /cc
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
- You won't be able to assign this to me (not a kubernetes member). Am taking a look.
volumemetrics.go_ could/should have more logging, either calling or more calls to .
The test appears to fail on this metric: "kubeletvolumestatsused_bytes". So samplePVC != pvcName and/or sampleNS != namespace. It would be nice if the sample name and ns were also logged. Also something is weird here: the framework's is called before the local . Note in the log:
- will add a couple of Logf() statements to log the samples - you're right that will help. Once the volume is attached, volume stats are grabbed every interval. The thing I noticed in the logs is that we issue a delete for the pod at but the volume only got attached/bound successfully at The test assumes blocks till the pod is running and PVC is attached but maybe that's not a valid assumption?
Nevermind - That log message has 2 timestamps in it - the volume was provisioned at .
Pushed The working theory being that volume stats were not collected within the wait earlier being used.
did you figure out if I was correct in thinking that the framework was invoked before the local ? That seems very, very unlikely but that is how it looked in the log.
- I believe you're right that the framework is being invoked before the local one. I observe the same in a test as well, so I don't think it's specific to this call. Based on the , nested blocks should be invoked inner-outer. It's not clear, however - whether the local is nested - or at the same level as the framework block when I look at

pod, err = c.CoreV1().Pods(ns).Get(pod.Name, metav1.GetOptions{}) Expect(err).NotTo(HaveOccurred()) <del> // Wait for `VolumeStatsAggPeriod' to grab metrics time.Sleep(1 * time.Minute) // Grab kubelet metrics from the node the pod was scheduled on kubeMetrics, err := metricsGrabber.GrabFromKubelet(pod.Spec.NodeName) Expect(err).NotTo(HaveOccurred(), "Error getting kubelet metrics : %v", err) framework.Logf("Deleting pod %q/%q", pod.Namespace, pod.Name) framework.ExpectNoError(framework.DeletePodWithWait(f, c, pod)) </del> // Verify volume stat metrics were collected for the referenced PVC volumeStatKeys := []string{ kubeletmetrics.VolumeStatsUsedBytesKey,


Question:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: What you expected to happen: Test should not flake /sig storage /cc
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
- You won't be able to assign this to me (not a kubernetes member). Am taking a look.
volumemetrics.go_ could/should have more logging, either calling or more calls to .
The test appears to fail on this metric: "kubeletvolumestatsused_bytes". So samplePVC != pvcName and/or sampleNS != namespace. It would be nice if the sample name and ns were also logged. Also something is weird here: the framework's is called before the local . Note in the log:
- will add a couple of Logf() statements to log the samples - you're right that will help. Once the volume is attached, volume stats are grabbed every interval. The thing I noticed in the logs is that we issue a delete for the pod at but the volume only got attached/bound successfully at The test assumes blocks till the pod is running and PVC is attached but maybe that's not a valid assumption?
Nevermind - That log message has 2 timestamps in it - the volume was provisioned at .
Pushed The working theory being that volume stats were not collected within the wait earlier being used.
did you figure out if I was correct in thinking that the framework was invoked before the local ? That seems very, very unlikely but that is how it looked in the log.
- I believe you're right that the framework is being invoked before the local one. I observe the same in a test as well, so I don't think it's specific to this call. Based on the , nested blocks should be invoked inner-outer. It's not clear, however - whether the local is nested - or at the same level as the framework block when I look at

kubeletmetrics.VolumeStatsInodesFreeKey, kubeletmetrics.VolumeStatsInodesUsedKey, } <ins> // Poll kubelet metrics waiting for the volume to be picked up // by the volume stats collector var kubeMetrics metrics.KubeletMetrics waitErr := wait.Poll(30*time.Second, 5*time.Minute, func() (bool, error) { framework.Logf("Grabbing Kubelet metrics") // Grab kubelet metrics from the node the pod was scheduled on var err error kubeMetrics, err = metricsGrabber.GrabFromKubelet(pod.Spec.NodeName) if err != nil { framework.Logf("Error fetching kubelet metrics") return false, err } key := volumeStatKeys[0] kubeletKeyName := fmt.Sprintf("%s_%s", kubeletmetrics.KubeletSubsystem, key) if !findVolumeStatMetric(kubeletKeyName, pvc.Namespace, pvc.Name, kubeMetrics) { return false, nil } return true, nil }) Expect(waitErr).NotTo(HaveOccurred(), "Error finding volume metrics : %v", waitErr) </ins> for _, key := range volumeStatKeys { kubeletKeyName := fmt.Sprintf("%s_%s", kubeletmetrics.KubeletSubsystem, key) <del> verifyVolumeStatMetric(kubeletKeyName, pvc.Namespace, pvc.Name, kubeMetrics) </del> <ins> found := findVolumeStatMetric(kubeletKeyName, pvc.Namespace, pvc.Name, kubeMetrics) Expect(found).To(BeTrue(), "PVC %s, Namespace %s not found for %s", pvc.Name, pvc.Namespace, kubeletKeyName) </ins> } <ins> framework.Logf("Deleting pod %q/%q", pod.Namespace, pod.Name) framework.ExpectNoError(framework.DeletePodWithWait(f, c, pod)) </ins> }) })


Question:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: What you expected to happen: Test should not flake /sig storage /cc
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
- You won't be able to assign this to me (not a kubernetes member). Am taking a look.
volumemetrics.go_ could/should have more logging, either calling or more calls to .
The test appears to fail on this metric: "kubeletvolumestatsused_bytes". So samplePVC != pvcName and/or sampleNS != namespace. It would be nice if the sample name and ns were also logged. Also something is weird here: the framework's is called before the local . Note in the log:
- will add a couple of Logf() statements to log the samples - you're right that will help. Once the volume is attached, volume stats are grabbed every interval. The thing I noticed in the logs is that we issue a delete for the pod at but the volume only got attached/bound successfully at The test assumes blocks till the pod is running and PVC is attached but maybe that's not a valid assumption?
Nevermind - That log message has 2 timestamps in it - the volume was provisioned at .
Pushed The working theory being that volume stats were not collected within the wait earlier being used.
did you figure out if I was correct in thinking that the framework was invoked before the local ? That seems very, very unlikely but that is how it looked in the log.
- I believe you're right that the framework is being invoked before the local one. I observe the same in a test as well, so I don't think it's specific to this call. Based on the , nested blocks should be invoked inner-outer. It's not clear, however - whether the local is nested - or at the same level as the framework block when I look at

return result } <del> // Verifies the specified metrics are in `kubeletMetrics` func verifyVolumeStatMetric(metricKeyName string, namespace string, pvcName string, kubeletMetrics metrics.KubeletMetrics) { </del> <ins> // Finds the sample in the specified metric from `KubeletMetrics` tagged with // the specified namespace and pvc name func findVolumeStatMetric(metricKeyName string, namespace string, pvcName string, kubeletMetrics metrics.KubeletMetrics) bool { </ins> found := false errCount := 0 <ins> framework.Logf("Looking for sample in metric `%s` tagged with namespace `%s`, PVC `%s`", metricKeyName, namespace, pvcName) </ins> if samples, ok := kubeletMetrics[metricKeyName]; ok { for _, sample := range samples { <ins> framework.Logf("Found sample %s", sample.String()) </ins> samplePVC, ok := sample.Metric["persistentvolumeclaim"] if !ok { framework.Logf("Error getting pvc for metric %s, sample %s", metricKeyName, sample.String())


Question:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: What you expected to happen: Test should not flake /sig storage /cc
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign
GitHub didn't allow me to assign the following users: vkamra. Note that only can be assigned. <detailsIn response to : /assign Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
- You won't be able to assign this to me (not a kubernetes member). Am taking a look.
volumemetrics.go_ could/should have more logging, either calling or more calls to .
The test appears to fail on this metric: "kubeletvolumestatsused_bytes". So samplePVC != pvcName and/or sampleNS != namespace. It would be nice if the sample name and ns were also logged. Also something is weird here: the framework's is called before the local . Note in the log:
- will add a couple of Logf() statements to log the samples - you're right that will help. Once the volume is attached, volume stats are grabbed every interval. The thing I noticed in the logs is that we issue a delete for the pod at but the volume only got attached/bound successfully at The test assumes blocks till the pod is running and PVC is attached but maybe that's not a valid assumption?
Nevermind - That log message has 2 timestamps in it - the volume was provisioned at .
Pushed The working theory being that volume stats were not collected within the wait earlier being used.
did you figure out if I was correct in thinking that the framework was invoked before the local ? That seems very, very unlikely but that is how it looked in the log.
- I believe you're right that the framework is being invoked before the local one. I observe the same in a test as well, so I don't think it's specific to this call. Based on the , nested blocks should be invoked inner-outer. It's not clear, however - whether the local is nested - or at the same level as the framework block when I look at

} } Expect(errCount).To(Equal(0), "Found invalid samples") <del> Expect(found).To(BeTrue(), "PVC %s, Namespace %s not found for %s", pvcName, namespace, metricKeyName) </del> <ins> return found </ins> }


PortOpenCheck{port: 10252}, HTTPProxyCheck{Proto: "https", Host: cfg.API.AdvertiseAddress, Port: int(cfg.API.BindPort)}, DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)}, <del> DirAvailableCheck{Path: "/var/lib/kubelet"}, </del> FileContentCheck{Path: bridgenf, Content: []byte{'1'}}, SwapCheck{}, InPathCheck{executable: "ip", mandatory: true},


ServiceCheck{Service: "docker", CheckIfActive: true}, PortOpenCheck{port: 10250}, DirAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.ManifestsSubDirName)}, <del> DirAvailableCheck{Path: "/var/lib/kubelet"}, </del> FileAvailableCheck{Path: cfg.CACertPath}, FileAvailableCheck{Path: filepath.Join(kubeadmconstants.KubernetesDir, kubeadmconstants.KubeletKubeConfigFileName)}, FileContentCheck{Path: bridgenf, Content: []byte{'1'}},


RequireKubeConfig:       false, KubeConfig:              flag.NewStringFlag("/var/lib/kubelet/kubeconfig"), ContainerRuntimeOptions: *NewContainerRuntimeOptions(), <del> CertDirectory:           "/var/run/kubernetes", </del> <ins> CertDirectory:           "/var/lib/kubelet/pki", </ins> RootDirectory:           v1alpha1.DefaultRootDir, // DEPRECATED: auto detecting cloud providers goes against the initiative // for out-of-tree cloud providers as we'll now depend on cAdvisor integrations


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: CRD: Existing object: New object: says: If this is a problem with the new object definition rather than a bug with , I'd expect a better error message. (The new object looks fine to me, though; it should be identical to the old object.) What you expected to happen: I expected the object to be updated without an error. How to reproduce it (as minimally and precisely as possible): See description. Anything else we need to know?: Environment: Kubernetes version (use ):Cloud provider or hardware configuration**: GCE OS (e.g. from /etc/os-release): CentOS Linux 7.4 (1708) Kernel (e.g. ): Linux master-head-1 4.13.4- SMP Wed Sep 27 13:32:23 EDT 2017 x8664 x8664 x8664 GNU/Linux Install tools: Custom scripts Others:
/sig api-machinery
Are you able to reproduce this everytime? I am able to use apply normally with your example.
I can reliably reproduce it if the annotation exists: If I use to remove the annotation, then it works the first time but fails thereafter:
This is happening for other CRDs as well (Prometheus Operator ServiceMonitors). If I apply a ServiceMonitor CRD 3 times: If I remove the annotation or replace the object () then I can work around the issue.
Seems any CRD is affected; the CRD used by our are also not working: This has completely broken our CI/CD workflow... unfortunately we'd already completed the TPR-CRD migration for the 1.8 upgrade before noticing this problem, so we can't really downgrade. How safe is as an alternative to ? It still generates an update event for watchers, not a delete/recreate, right?
It looks like something going wrong during the patching. After using changes from , I get this: /cc /area third-party-resource
But uses json merge patch and not strategic merge patch for custom resources:
I was able to reproduce this in v1.8.0 with the original manifests at the top. As found, it only happens on the 3rd execution: It also seems to only happen when the ought to be a no-op. If I change something in the IPPool spec, works once more, then starts failing again. When the is a no-op, the PATCH request body generated by looks like this: When the is NOT a no-op, the PATCH request body looks like this:
There's a typo in the code generating the error messages for both and : They should be calling instead of . When I fix that, the error message becomes:
I can reproduce this without , just by doing a no-op twice:
The same issue affects v1.7.8 (tested on GKE)
Same issue with v1.8.1
This just fix the error message: But it doesn't fix the issue
Still investigating the issue but I noticed that when we do a no-op patch for native resources, we get a "not patched" response. However, for non-native resources, it still tries to patch it (and bumps the resourceVersion too).
I don't konwn whether this is a issue, I can't do strategic merge patch to CRD. When I run , --type=merge must be passed.
We should be able to apply strategic merge patch to CRDs. However, we can't apply strategic merge to CRs because we're missing the metadata about how to handle each field for the strategic merge patch. Unfortunately, this error is occuring even with . :(
/assign
do you know if the fix fir this will make it to 1.8.3
hopefully yes, this should be merged soon.
thanks! this has been a blocker for us to upgrade to 1.8
can you confirm this is completely fixed? The PR writes "partial fix".
Now we can't reproduce this issue with the method descripted above. I still need some I extra time to research it. Maybe we can close this one. If I can reproduce the issue in another way, I can open another issue with new situation.
If it's not fixed, let's keep it open.
Fun, a fork closing issues.
From Then I think we can officially close this.
(the fix is merged into release-1.8, but after v1.8.4-beta.0)
what stable release of k8s will this be in? 1.8.4 or 1.8.5?
Is there an update for this?
looks like it was merged here: but did not make it into 1.8.4, might make it into 1.8.5

"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", <ins> "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", </ins> "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: CRD: Existing object: New object: says: If this is a problem with the new object definition rather than a bug with , I'd expect a better error message. (The new object looks fine to me, though; it should be identical to the old object.) What you expected to happen: I expected the object to be updated without an error. How to reproduce it (as minimally and precisely as possible): See description. Anything else we need to know?: Environment: Kubernetes version (use ):Cloud provider or hardware configuration**: GCE OS (e.g. from /etc/os-release): CentOS Linux 7.4 (1708) Kernel (e.g. ): Linux master-head-1 4.13.4- SMP Wed Sep 27 13:32:23 EDT 2017 x8664 x8664 x8664 GNU/Linux Install tools: Custom scripts Others:
/sig api-machinery
Are you able to reproduce this everytime? I am able to use apply normally with your example.
I can reliably reproduce it if the annotation exists: If I use to remove the annotation, then it works the first time but fails thereafter:
This is happening for other CRDs as well (Prometheus Operator ServiceMonitors). If I apply a ServiceMonitor CRD 3 times: If I remove the annotation or replace the object () then I can work around the issue.
Seems any CRD is affected; the CRD used by our are also not working: This has completely broken our CI/CD workflow... unfortunately we'd already completed the TPR-CRD migration for the 1.8 upgrade before noticing this problem, so we can't really downgrade. How safe is as an alternative to ? It still generates an update event for watchers, not a delete/recreate, right?
It looks like something going wrong during the patching. After using changes from , I get this: /cc /area third-party-resource
But uses json merge patch and not strategic merge patch for custom resources:
I was able to reproduce this in v1.8.0 with the original manifests at the top. As found, it only happens on the 3rd execution: It also seems to only happen when the ought to be a no-op. If I change something in the IPPool spec, works once more, then starts failing again. When the is a no-op, the PATCH request body generated by looks like this: When the is NOT a no-op, the PATCH request body looks like this:
There's a typo in the code generating the error messages for both and : They should be calling instead of . When I fix that, the error message becomes:
I can reproduce this without , just by doing a no-op twice:
The same issue affects v1.7.8 (tested on GKE)
Same issue with v1.8.1
This just fix the error message: But it doesn't fix the issue
Still investigating the issue but I noticed that when we do a no-op patch for native resources, we get a "not patched" response. However, for non-native resources, it still tries to patch it (and bumps the resourceVersion too).
I don't konwn whether this is a issue, I can't do strategic merge patch to CRD. When I run , --type=merge must be passed.
We should be able to apply strategic merge patch to CRDs. However, we can't apply strategic merge to CRs because we're missing the metadata about how to handle each field for the strategic merge patch. Unfortunately, this error is occuring even with . :(
/assign
do you know if the fix fir this will make it to 1.8.3
hopefully yes, this should be merged soon.
thanks! this has been a blocker for us to upgrade to 1.8
can you confirm this is completely fixed? The PR writes "partial fix".
Now we can't reproduce this issue with the method descripted above. I still need some I extra time to research it. Maybe we can close this one. If I can reproduce the issue in another way, I can open another issue with new situation.
If it's not fixed, let's keep it open.
Fun, a fork closing issues.
From Then I think we can officially close this.
(the fix is merged into release-1.8, but after v1.8.4-beta.0)
what stable release of k8s will this be in? 1.8.4 or 1.8.5?
Is there an update for this?
looks like it was merged here: but did not make it into 1.8.4, might make it into 1.8.5

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" <ins> "k8s.io/apimachinery/pkg/types" </ins> "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic"


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: CRD: Existing object: New object: says: If this is a problem with the new object definition rather than a bug with , I'd expect a better error message. (The new object looks fine to me, though; it should be identical to the old object.) What you expected to happen: I expected the object to be updated without an error. How to reproduce it (as minimally and precisely as possible): See description. Anything else we need to know?: Environment: Kubernetes version (use ):Cloud provider or hardware configuration**: GCE OS (e.g. from /etc/os-release): CentOS Linux 7.4 (1708) Kernel (e.g. ): Linux master-head-1 4.13.4- SMP Wed Sep 27 13:32:23 EDT 2017 x8664 x8664 x8664 GNU/Linux Install tools: Custom scripts Others:
/sig api-machinery
Are you able to reproduce this everytime? I am able to use apply normally with your example.
I can reliably reproduce it if the annotation exists: If I use to remove the annotation, then it works the first time but fails thereafter:
This is happening for other CRDs as well (Prometheus Operator ServiceMonitors). If I apply a ServiceMonitor CRD 3 times: If I remove the annotation or replace the object () then I can work around the issue.
Seems any CRD is affected; the CRD used by our are also not working: This has completely broken our CI/CD workflow... unfortunately we'd already completed the TPR-CRD migration for the 1.8 upgrade before noticing this problem, so we can't really downgrade. How safe is as an alternative to ? It still generates an update event for watchers, not a delete/recreate, right?
It looks like something going wrong during the patching. After using changes from , I get this: /cc /area third-party-resource
But uses json merge patch and not strategic merge patch for custom resources:
I was able to reproduce this in v1.8.0 with the original manifests at the top. As found, it only happens on the 3rd execution: It also seems to only happen when the ought to be a no-op. If I change something in the IPPool spec, works once more, then starts failing again. When the is a no-op, the PATCH request body generated by looks like this: When the is NOT a no-op, the PATCH request body looks like this:
There's a typo in the code generating the error messages for both and : They should be calling instead of . When I fix that, the error message becomes:
I can reproduce this without , just by doing a no-op twice:
The same issue affects v1.7.8 (tested on GKE)
Same issue with v1.8.1
This just fix the error message: But it doesn't fix the issue
Still investigating the issue but I noticed that when we do a no-op patch for native resources, we get a "not patched" response. However, for non-native resources, it still tries to patch it (and bumps the resourceVersion too).
I don't konwn whether this is a issue, I can't do strategic merge patch to CRD. When I run , --type=merge must be passed.
We should be able to apply strategic merge patch to CRDs. However, we can't apply strategic merge to CRs because we're missing the metadata about how to handle each field for the strategic merge patch. Unfortunately, this error is occuring even with . :(
/assign
do you know if the fix fir this will make it to 1.8.3
hopefully yes, this should be merged soon.
thanks! this has been a blocker for us to upgrade to 1.8
can you confirm this is completely fixed? The PR writes "partial fix".
Now we can't reproduce this issue with the method descripted above. I still need some I extra time to research it. Maybe we can close this one. If I can reproduce the issue in another way, I can open another issue with new situation.
If it's not fixed, let's keep it open.
Fun, a fork closing issues.
From Then I think we can officially close this.
(the fix is merged into release-1.8, but after v1.8.4-beta.0)
what stable release of k8s will this be in? 1.8.4 or 1.8.5?
Is there an update for this?
looks like it was merged here: but did not make it into 1.8.4, might make it into 1.8.5

} } <ins> func TestPatch(t *testing.T) { stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil { t.Fatal(err) } defer close(stopCh) noxuDefinition := testserver.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped) noxuVersionClient, err := testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, clientPool) if err != nil { t.Fatal(err) } ns := "not-the-default" noxuNamespacedResourceClient := noxuVersionClient.Resource(&metav1.APIResource{ Name:       noxuDefinition.Spec.Names.Plural, Namespaced: true, }, ns) noxuInstanceToCreate := testserver.NewNoxuInstance(ns, "foo") createdNoxuInstance, err := noxuNamespacedResourceClient.Create(noxuInstanceToCreate) if err != nil { t.Fatal(err) } patch := []byte(`{"num": {"num2":999}}`) createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch) if err != nil { t.Fatalf("unexpected error: %v", err) } // a patch with no change createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch) if err != nil { t.Fatalf("unexpected error: %v", err) } // an empty patch createdNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`)) if err != nil { t.Fatalf("unexpected error: %v", err) } originalJSON, err := runtime.Encode(unstructured.UnstructuredJSONScheme, createdNoxuInstance) if err != nil { t.Fatalf("unexpected error: %v", err) } gottenNoxuInstance, err := runtime.Decode(unstructured.UnstructuredJSONScheme, originalJSON) if err != nil { t.Fatalf("unexpected error: %v", err) } // Check if int is preserved. unstructuredObj := gottenNoxuInstance.(*unstructured.Unstructured).Object num := unstructuredObj["num"].(map[string]interface{}) num1 := num["num1"].(int64) num2 := num["num2"].(int64) if num1 != 9223372036854775807 || num2 != 999 { t.Errorf("Expected %v, got %v, %v", `9223372036854775807, 999`, num1, num2) } } </ins> func TestCrossNamespaceListWatch(t *testing.T) { stopCh, apiExtensionClient, clientPool, err := testserver.StartDefaultServer() if err != nil {


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: CRD: Existing object: New object: says: If this is a problem with the new object definition rather than a bug with , I'd expect a better error message. (The new object looks fine to me, though; it should be identical to the old object.) What you expected to happen: I expected the object to be updated without an error. How to reproduce it (as minimally and precisely as possible): See description. Anything else we need to know?: Environment: Kubernetes version (use ):Cloud provider or hardware configuration**: GCE OS (e.g. from /etc/os-release): CentOS Linux 7.4 (1708) Kernel (e.g. ): Linux master-head-1 4.13.4- SMP Wed Sep 27 13:32:23 EDT 2017 x8664 x8664 x8664 GNU/Linux Install tools: Custom scripts Others:
/sig api-machinery
Are you able to reproduce this everytime? I am able to use apply normally with your example.
I can reliably reproduce it if the annotation exists: If I use to remove the annotation, then it works the first time but fails thereafter:
This is happening for other CRDs as well (Prometheus Operator ServiceMonitors). If I apply a ServiceMonitor CRD 3 times: If I remove the annotation or replace the object () then I can work around the issue.
Seems any CRD is affected; the CRD used by our are also not working: This has completely broken our CI/CD workflow... unfortunately we'd already completed the TPR-CRD migration for the 1.8 upgrade before noticing this problem, so we can't really downgrade. How safe is as an alternative to ? It still generates an update event for watchers, not a delete/recreate, right?
It looks like something going wrong during the patching. After using changes from , I get this: /cc /area third-party-resource
But uses json merge patch and not strategic merge patch for custom resources:
I was able to reproduce this in v1.8.0 with the original manifests at the top. As found, it only happens on the 3rd execution: It also seems to only happen when the ought to be a no-op. If I change something in the IPPool spec, works once more, then starts failing again. When the is a no-op, the PATCH request body generated by looks like this: When the is NOT a no-op, the PATCH request body looks like this:
There's a typo in the code generating the error messages for both and : They should be calling instead of . When I fix that, the error message becomes:
I can reproduce this without , just by doing a no-op twice:
The same issue affects v1.7.8 (tested on GKE)
Same issue with v1.8.1
This just fix the error message: But it doesn't fix the issue
Still investigating the issue but I noticed that when we do a no-op patch for native resources, we get a "not patched" response. However, for non-native resources, it still tries to patch it (and bumps the resourceVersion too).
I don't konwn whether this is a issue, I can't do strategic merge patch to CRD. When I run , --type=merge must be passed.
We should be able to apply strategic merge patch to CRDs. However, we can't apply strategic merge to CRs because we're missing the metadata about how to handle each field for the strategic merge patch. Unfortunately, this error is occuring even with . :(
/assign
do you know if the fix fir this will make it to 1.8.3
hopefully yes, this should be merged soon.
thanks! this has been a blocker for us to upgrade to 1.8
can you confirm this is completely fixed? The PR writes "partial fix".
Now we can't reproduce this issue with the method descripted above. I still need some I extra time to research it. Maybe we can close this one. If I can reproduce the issue in another way, I can open another issue with new situation.
If it's not fixed, let's keep it open.
Fun, a fork closing issues.
From Then I think we can officially close this.
(the fix is merged into release-1.8, but after v1.8.4-beta.0)
what stable release of k8s will this be in? 1.8.4 or 1.8.5?
Is there an update for this?
looks like it was merged here: but did not make it into 1.8.4, might make it into 1.8.5

if err != nil { return err } <del> mustCheckData = false continue </del> <ins> if !bytes.Equal(data, origState.data) { // original data changed, restart loop mustCheckData = false continue } </ins> } return decode(s.codec, s.versioner, origState.data, out, origState.rev) }


Question:
This issue is meant to track planned work items for pre-allocated hugepages across releases. This issue captures the plan of record discussed in the wg-resource-mgmt meetings. [x] HugePages should be restricted via ResourceQuota [Owner: , fixed ] Assess ability to graduate feature to beta. [x] HugePages should require the user to request cpu or memory [Owner: fixed ] [x] HugePages should not be tied to QoS [Owner: fixed ] [ ] HugePages promoted to beta [Owner: ][ ] HugePages isolated at container and not just pod boundary [Owner: TBD] [ ] HugePages should be restricted via LimitRange [Owner: TBD] cc
/cc
If no one is doing it, I'd like to work on the ResourceQuota part.
would this be discussed in the meeting recently? i would like to try on the "via LimitRange" but seems more details need to be settled.
/cc
Regarding to the ResourceQuota issue, all I could think is to add support for resource HugePages in podEvaluator of quota, so that it could be aware of the hugepage declared in resourceQuota, and that requested in podSpec. It is thought to be a small change, The only thing that needs attention is the way to address resource HugePages, as it's name is not fixed, like CPU or memory, but in a specific format. Correct me if I miss something :)
-- the quota change is relatively small, if you want to pick up the work, i would be happy to shephard it.
-- you as owner, thanks for volunteering! let me know when you have the pr up
are you ready for the LimitRange part? :)
yes, I've worked on this for some time and will commit the pr ASAP.
/cc
hi, I am confused by the tests I've made, which seems the "HugePages should be restricted via LimitRange" has already been done. I created the LimitRange as below: apiVersion: v1 kind: LimitRange metadata: name: mytest spec: limits: default: hugepages-2Mi: 40Mi defaultRequest: hugepages-2Mi: 40Mi type: Container and the pods created by the following yaml: apiVersion: v1 kind: Pod metadata: generateName: hugepages-volume- spec: containers: image: tomcatjava:v6.0 command: name: example and the output of the pod in yaml is like: spec: containers: command: image: tomcatjava:v6.0 imagePullPolicy: IfNotPresent name: example resources: limits: hugepages-2Mi: 40Mi memory: 250Mi requests: hugepages-2Mi: 40Mi memory: 125Mi Is this the LimitRange part already been done? Otherwise anything wrong with my understanding? Also, I found an subtle error in the error info when creating pods restricted by the hugepage , would you please take a look?
-- thanks for the feedback, i have been distracted looking at other topics, but hope to return to this later this week.
I have filed an issue related to hugepages, would you please check when you are free? link:
you can't re-open an issue/PR unless you authored it or you are assigned to it. <detailsIn response to : /reopen </details
hi, I've worked on the HugePages isolated at container and not just pod boundary issue and would like to confirm some details. My first though was to implement this issue via docker, just like what cpu and memory did. But docker seems not support hugepage limit in present. Which means we have to get it done by coding in kubernetes or libcontainer, is that right? Please let me know if there are any other instructions that may help :)
-- to support isolation at container boundary, we would need support from the container runtime. that would require support in the CRI to expose the resource, and support in individual container runtimes (contianerd, cri-o, docker, rkt, etc.) to actually make use of it. in practice though, i have not seen a major requirement to support container boundary isolation. do you have use cases in mind that would require it?
I have no any other use cases as well, for now all the achievements fit well for our requirements. BTW, does the still need to move on? I found it seems already being supported by default.
I don't think the intent was for to close this /reopen
you can't re-open an issue/PR unless you authored it or you are assigned to it. <detailsIn response to : I don't think the intent was for to close this /reopen Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

CPUManager utilfeature.Feature = "CPUManager" // owner: @derekwaynecarr <del> // alpha: v1.8 </del> <ins> // beta: v1.10 </ins> // // Enable pods to consume pre-allocated huge pages of varying page sizes HugePages utilfeature.Feature = "HugePages"


Question:
This issue is meant to track planned work items for pre-allocated hugepages across releases. This issue captures the plan of record discussed in the wg-resource-mgmt meetings. [x] HugePages should be restricted via ResourceQuota [Owner: , fixed ] Assess ability to graduate feature to beta. [x] HugePages should require the user to request cpu or memory [Owner: fixed ] [x] HugePages should not be tied to QoS [Owner: fixed ] [ ] HugePages promoted to beta [Owner: ][ ] HugePages isolated at container and not just pod boundary [Owner: TBD] [ ] HugePages should be restricted via LimitRange [Owner: TBD] cc
/cc
If no one is doing it, I'd like to work on the ResourceQuota part.
would this be discussed in the meeting recently? i would like to try on the "via LimitRange" but seems more details need to be settled.
/cc
Regarding to the ResourceQuota issue, all I could think is to add support for resource HugePages in podEvaluator of quota, so that it could be aware of the hugepage declared in resourceQuota, and that requested in podSpec. It is thought to be a small change, The only thing that needs attention is the way to address resource HugePages, as it's name is not fixed, like CPU or memory, but in a specific format. Correct me if I miss something :)
-- the quota change is relatively small, if you want to pick up the work, i would be happy to shephard it.
-- you as owner, thanks for volunteering! let me know when you have the pr up
are you ready for the LimitRange part? :)
yes, I've worked on this for some time and will commit the pr ASAP.
/cc
hi, I am confused by the tests I've made, which seems the "HugePages should be restricted via LimitRange" has already been done. I created the LimitRange as below: apiVersion: v1 kind: LimitRange metadata: name: mytest spec: limits: default: hugepages-2Mi: 40Mi defaultRequest: hugepages-2Mi: 40Mi type: Container and the pods created by the following yaml: apiVersion: v1 kind: Pod metadata: generateName: hugepages-volume- spec: containers: image: tomcatjava:v6.0 command: name: example and the output of the pod in yaml is like: spec: containers: command: image: tomcatjava:v6.0 imagePullPolicy: IfNotPresent name: example resources: limits: hugepages-2Mi: 40Mi memory: 250Mi requests: hugepages-2Mi: 40Mi memory: 125Mi Is this the LimitRange part already been done? Otherwise anything wrong with my understanding? Also, I found an subtle error in the error info when creating pods restricted by the hugepage , would you please take a look?
-- thanks for the feedback, i have been distracted looking at other topics, but hope to return to this later this week.
I have filed an issue related to hugepages, would you please check when you are free? link:
you can't re-open an issue/PR unless you authored it or you are assigned to it. <detailsIn response to : /reopen </details
hi, I've worked on the HugePages isolated at container and not just pod boundary issue and would like to confirm some details. My first though was to implement this issue via docker, just like what cpu and memory did. But docker seems not support hugepage limit in present. Which means we have to get it done by coding in kubernetes or libcontainer, is that right? Please let me know if there are any other instructions that may help :)
-- to support isolation at container boundary, we would need support from the container runtime. that would require support in the CRI to expose the resource, and support in individual container runtimes (contianerd, cri-o, docker, rkt, etc.) to actually make use of it. in practice though, i have not seen a major requirement to support container boundary isolation. do you have use cases in mind that would require it?
I have no any other use cases as well, for now all the achievements fit well for our requirements. BTW, does the still need to move on? I found it seems already being supported by default.
I don't think the intent was for to close this /reopen
you can't re-open an issue/PR unless you authored it or you are assigned to it. <detailsIn response to : I don't think the intent was for to close this /reopen Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

RotateKubeletClientCertificate:              {Default: true, PreRelease: utilfeature.Beta}, PersistentLocalVolumes:                      {Default: false, PreRelease: utilfeature.Alpha}, LocalStorageCapacityIsolation:               {Default: false, PreRelease: utilfeature.Alpha}, <del> HugePages:                                   {Default: false, PreRelease: utilfeature.Alpha}, </del> <ins> HugePages:                                   {Default: true, PreRelease: utilfeature.Beta}, </ins> DebugContainers:                             {Default: false, PreRelease: utilfeature.Alpha}, PodPriority:                                 {Default: false, PreRelease: utilfeature.Alpha}, EnableEquivalenceClassCache:                 {Default: false, PreRelease: utilfeature.Alpha},


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: Pods with volumeMount gitRepo volumes in 1.8.0 see the following error in kubelet logs (also in ) It is important to not that the git repo clone is done via ssh. I think what is happening is that hyperkube image now used to have command in it and now it does not have it. So the git clone command that kubelet runs fails with the above stacktrace since it cannot find . What you expected to happen: gitRepo is volume mounted. How to reproduce it (as minimally and precisely as possible): Reproducible in kubernetes 1.8.0+ hyperkube images. Anything else we need to know?: This probably is due to missing ssh binary in the new 1.8.0 hyperkube images. The commit might be an issue. Will comment further if I find otherwise. Environment: Kubernetes version (use ): =1.8.0 Cloud provider or hardware configuration**: Not Application. OS (e.g. from /etc/os-release): hyperkube base image Kernel (e.g. ): Install tools: Others:
How did you installed Kubernetes may I ask?
how does this help?
Normally, it is suggest to install kubelet as a daemon on host instead of using hyperkube container. cc you may be interested in this issue.
Need your help in identifying the fix here. I can send something for review. Suggestions are welcome.
The problem is that ssh isn't installed inside of the container. I don't know if it should be either, as the hyperkube image grows so large. If you install the openssh-client, it should work
Yes I did identify that as the problem if you see the description I mentioned. I pointed to a git commit that might have caused this. I am not sure what package installation has changed in the hyperkube container. "ssh" used to be available and now it is not. For the gitrepo feature to work it should be available.
Ah okay. If it was there before, we might want to add it back. SGTM.
Yeah, I switched the hyperkube image base from to our with some additional dependencies back. Apparently due to lack of volume + hyperkube test coverage, I've missed a number of dependencies needed. cc
we could use dropbear as a replacement for just the ssh client?
I would prefer to use the openssh client over the dropbear client. It has wider usage and a stronger security track record IMO. The dropbear client also has somewhat different usage and configuration, so arguably using it is still a regression over the previous state. Saving a couple MB isn't worth using worse utilities, however much fun "dockerfile-golfing" is.
to fix
cherrypick to release-1.8:
This should be fixed in v1.8.3.

RUN ln -s /bin/sh /bin/bash RUN echo CACHEBUST>/dev/null && clean-install  <del> iptables  </del> <ins> ca-certificates  ceph-common  cifs-utils  conntrack  </ins> e2fsprogs  ebtables  ethtool  <del> kmod  ca-certificates  conntrack  util-linux  socat  </del> git  <ins> glusterfs-client  iptables  </ins> jq  <ins> kmod  openssh-client  </ins> nfs-common  <del> glusterfs-client  cifs-utils  ceph-common </del> <ins> socat  util-linux </ins> COPY cni-bin/bin /opt/cni/bin


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: Pods with volumeMount gitRepo volumes in 1.8.0 see the following error in kubelet logs (also in ) It is important to not that the git repo clone is done via ssh. I think what is happening is that hyperkube image now used to have command in it and now it does not have it. So the git clone command that kubelet runs fails with the above stacktrace since it cannot find . What you expected to happen: gitRepo is volume mounted. How to reproduce it (as minimally and precisely as possible): Reproducible in kubernetes 1.8.0+ hyperkube images. Anything else we need to know?: This probably is due to missing ssh binary in the new 1.8.0 hyperkube images. The commit might be an issue. Will comment further if I find otherwise. Environment: Kubernetes version (use ): =1.8.0 Cloud provider or hardware configuration**: Not Application. OS (e.g. from /etc/os-release): hyperkube base image Kernel (e.g. ): Install tools: Others:
How did you installed Kubernetes may I ask?
how does this help?
Normally, it is suggest to install kubelet as a daemon on host instead of using hyperkube container. cc you may be interested in this issue.
Need your help in identifying the fix here. I can send something for review. Suggestions are welcome.
The problem is that ssh isn't installed inside of the container. I don't know if it should be either, as the hyperkube image grows so large. If you install the openssh-client, it should work
Yes I did identify that as the problem if you see the description I mentioned. I pointed to a git commit that might have caused this. I am not sure what package installation has changed in the hyperkube container. "ssh" used to be available and now it is not. For the gitrepo feature to work it should be available.
Ah okay. If it was there before, we might want to add it back. SGTM.
Yeah, I switched the hyperkube image base from to our with some additional dependencies back. Apparently due to lack of volume + hyperkube test coverage, I've missed a number of dependencies needed. cc
we could use dropbear as a replacement for just the ssh client?
I would prefer to use the openssh client over the dropbear client. It has wider usage and a stronger security track record IMO. The dropbear client also has somewhat different usage and configuration, so arguably using it is still a regression over the previous state. Saving a couple MB isn't worth using worse utilities, however much fun "dockerfile-golfing" is.
to fix
cherrypick to release-1.8:
This should be fixed in v1.8.3.

REGISTRY?=gcr.io/google-containers IMAGE?=debian-hyperkube-base <del> TAG=0.5 </del> <ins> TAG=0.6 </ins> ARCH?=amd64 CACHEBUST?=1


Question:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: Pods with volumeMount gitRepo volumes in 1.8.0 see the following error in kubelet logs (also in ) It is important to not that the git repo clone is done via ssh. I think what is happening is that hyperkube image now used to have command in it and now it does not have it. So the git clone command that kubelet runs fails with the above stacktrace since it cannot find . What you expected to happen: gitRepo is volume mounted. How to reproduce it (as minimally and precisely as possible): Reproducible in kubernetes 1.8.0+ hyperkube images. Anything else we need to know?: This probably is due to missing ssh binary in the new 1.8.0 hyperkube images. The commit might be an issue. Will comment further if I find otherwise. Environment: Kubernetes version (use ): =1.8.0 Cloud provider or hardware configuration**: Not Application. OS (e.g. from /etc/os-release): hyperkube base image Kernel (e.g. ): Install tools: Others:
How did you installed Kubernetes may I ask?
how does this help?
Normally, it is suggest to install kubelet as a daemon on host instead of using hyperkube container. cc you may be interested in this issue.
Need your help in identifying the fix here. I can send something for review. Suggestions are welcome.
The problem is that ssh isn't installed inside of the container. I don't know if it should be either, as the hyperkube image grows so large. If you install the openssh-client, it should work
Yes I did identify that as the problem if you see the description I mentioned. I pointed to a git commit that might have caused this. I am not sure what package installation has changed in the hyperkube container. "ssh" used to be available and now it is not. For the gitrepo feature to work it should be available.
Ah okay. If it was there before, we might want to add it back. SGTM.
Yeah, I switched the hyperkube image base from to our with some additional dependencies back. Apparently due to lack of volume + hyperkube test coverage, I've missed a number of dependencies needed. cc
we could use dropbear as a replacement for just the ssh client?
I would prefer to use the openssh client over the dropbear client. It has wider usage and a stronger security track record IMO. The dropbear client also has somewhat different usage and configuration, so arguably using it is still a regression over the previous state. Saving a couple MB isn't worth using worse utilities, however much fun "dockerfile-golfing" is.
to fix
cherrypick to release-1.8:
This should be fixed in v1.8.3.

docker_pull( name = "debian-hyperkube-base-amd64", <del> digest = "sha256:d216b425004fcb6d8047f74e81b30e7ead55f73e73511ca53a329c358786b6c9", </del> <ins> digest = "sha256:10546d592e58d5fdb2e25d79f291b8ac62c8d3a3d83337ad7309cca766dbebce", </ins> registry = "gcr.io", repository = "google-containers/debian-hyperkube-base-amd64", <del> tag = "0.5",  # ignored, but kept here for documentation </del> <ins> tag = "0.6",  # ignored, but kept here for documentation </ins> ) docker_pull(