-
Notifications
You must be signed in to change notification settings - Fork 39.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CRI: add methods for container stats #45614
CRI: add methods for container stats #45614
Conversation
Feel free to review and leave comments: @dashpole @vishh @timstclair @Random-Liu @feiskyer @mrunalp /cc @michmike based on #27097 (comment). Note that CRI didn't start with the windows use case, so the API will need quite a lot of changes to support windows. This PR alone should not affect the current status of support of windows containers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just one nit. Otherwise looks good
UInt64Value UsageCoreNanoSeocnds = 2; | ||
} | ||
|
||
// CpuUsage provides the memory usage information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/CpuUsage/MemoryUsage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like the async + timestamp model of these stats (I know it's what we use now with cAdvisor), and I'm wondering whether we can get away from it.
What if:
- (List)ContainerStats is expected to be slow, and on-demand.
- Requests are for specific stats (maybe they should even be separate requests?)
- Kubelet handles caching
I guess I'm mostly wondering how much flexibility the current model adds over the above. Can you think of an example of where the async scan method we currently use would be preferred?
I'm just brainstorming here - Interested in hearing everyone's thoughts.
Also, are we going to need any "core" monitoring of non-standard resources (e.g. GPU), or will the Kubelet not need usage information for those?
message CpuUsage { | ||
// Timestamp in nanoseconds at which the information were collected. Must be > 0. | ||
int64 timestamp = 1; | ||
// Cumulative CPU usage (sum of all cores) since object creation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/object/container/ ? Do you expect these messages to be reused with other object types?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the message
doesn't have "Container" in the name, I thought we could keep the term neutral.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: sum across all cores
@@ -71,6 +71,12 @@ service RuntimeService { | |||
// PortForward prepares a streaming endpoint to forward ports from a PodSandbox. | |||
rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {} | |||
|
|||
// ContainerStats returns stats of the container. If the container does not | |||
// exist, the call returns an error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add any expectations about how long this call is allowed to take? E.g. if it can take a few seconds to get disk stats, can this do so on demand, or is it expected to return the last known value?
Good question. I agree that the on-demand model is simpler and gives kubelet more control (if it caches), but I have a few reservations. Runtimes could gather the stats in different ways, and some of them may already rely on cached data from cadvisor or Prometheus (e.g., containerd). I am not certain whether we can enforce all containers runtimes to move to the on-demand model right now. Another concern is the scalability and performance since kubelet would be making N calls for each container, where N number of categories of stats. Also, runtimes should have better ideas about how long it takes to gather specific stats, so (I assume) they can adjust the frequency better than kubelet if needed.
Me too.
We haven't got there yet, but it's definitely something to think about. For now, GPU is just a device we pass to the runtime. Maybe monitoring doesn't have to go through CRI? |
BTW, it's still uncertain whether containerd can support stats with timestamps. See discussions in containerd/containerd#678 |
@yujuhong: GitHub didn't allow me to request PR reviews from the following users: stevvooe. Note that only people with write access to kubernetes/kubernetes can review this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
There are two possibilities for supporting this:
I do share @timstclair's concern that the sample rate should be set by the client, rather than an internal cache, so we'd have to figure out 1. Last time I spoke with @thockin and @juliusv, we thought it best to get the metrics out the door on the containerd and address the sampling problems as they come. In that vein, I think both 1 and 2 are option which could be implemented in the current approach. To clarify on containerd/containerd#678, the concern was over the solution of solving the split sample rate problem for unrelated metrics on a single endpoint. Our approach right now ends up having containerd export something very close to cadvisor in breadth and cardinality. This approach means the sample rate of metrics will defer to the lowest common denominator, which is probably disk usage. Option 1 would allow one to query certain metrics, like CPU, at a much higher sample rate. |
// ContainerStats provides the resource usage statistics for a container. | ||
message ContainerStats { | ||
// Information of the container. | ||
Container container = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the Container
object embedded here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe container id and metadata is enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would not be enough. Kubelet relies on labels and annotations heavily and it'd need those to reconstruct the pod. If we group all of those (id, metdata, labels, annotations, ...) into a separate metadada object like the k8s API, it would help, but that's a bigger change.
// Memory usage gathered from the container. | ||
MemoryUsage memory_usage = 3; | ||
// Root filesystem usage gathered from the container. | ||
FilesystemUsage root_filesystem_usage = 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest using writable_layer_usage
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And do we need the _usage
suffix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and done.
message CpuUsage { | ||
// Timestamp in nanoseconds at which the information were collected. Must be > 0. | ||
int64 timestamp = 1; | ||
// Cumulative CPU usage (sum of all cores) since object creation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: sum across all cores
// Timestamp in nanoseconds at which the information were collected. Must be > 0. | ||
int64 timestamp = 1; | ||
// The amount of working set memory in bytes. | ||
UInt64Value WorkingSetBytes = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WorkingSet isn't well defined outside of cAdvisor currently. At the CRI level can we instead get more detailed metrics - essentially the output of memory.stat
from cgroups?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that working set may not be the best field, but I'm hesitant to include the output of the cgroups memory.stat as they are very detailed. Can we include only a subgroup of those and expand later if needed? Do you have any suggestion on what to included? @vishh @dchen1107
294de25
to
8a0db2e
Compare
8a0db2e
to
2145088
Compare
Here is a simple (and incomplete) comparison:
2. Cached w/ timestamps
If we rule out a hybrid model (where some stats are on-demand and some cached), I think the "cached model" is more reasonable given that the on-demand model is not suitable for slow stats. Thoughts and/or objections? |
This commit also changes the image-filesystem-related types.
3bc86c4
to
946af0e
Compare
59f9407
to
d41f10c
Compare
d41f10c
to
417e9c8
Compare
@dchen1107 PTAL! |
@yujuhong: The following test(s) failed:
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
@k8s-bot verify test this |
@k8s-bot pull-kubernetes-federation-e2e-gce test this |
@k8s-bot pull-kubernetes-e2e-gce-etcd3 test this |
/lgtm We can introduce on-demand API in the future. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: dchen1107, yujuhong
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
Automatic merge from submit-queue (batch tested with PRs 45809, 46515, 46484, 46516, 45614) |
Automatic merge from submit-queue (batch tested with PRs 50555, 51152). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Implement CRI stats in Docker Shim **What this PR does / why we need it**: This PR implements CRI Stats in the Docker Shim. It is needed to enable CRI stats for Docker and ongoing /stats/summary API changes in moving to use CRI. Related issues: kubernetes#46984 (CRI: instruct kubelet to (optionally) consume container stats from CRI) kubernetes#45614 (CRI: add methods for container stats) This PR is also a followup to my original PR (kubernetes#50396) to implement Windows Container Stats. The plan is that Windows Stats will use a hybrid model: pod and container level stats will come from CRI (via dockershim) and that node level stats will come from a "winstats" package that exports cadvisor like datastructures using windows specific perf counters from the node. I will update that PR to only export node level stats. @yujuhong @yguo0905 @dchen1107 @jdumars @anhowe @michmike **Special notes for your reviewer**: **Release note**: ```release-note ```
What this PR does / why we need it:
Define methods in CRI to get container stats.
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close that issue when PR gets merged):Part of kubernetes/enhancements#290; addresses #27097
Special notes for your reviewer:
This PR defines the minimum required container metrics for the existing components to function, loosely based on the previous discussion on core metrics as well as the existing cadvisor/summary APIs.
Two new RPC calls are added to the RuntimeService:
ContainerStats
andListContainerStats
. The former retrieves stats for a given container, while the latter gets stats for all containers in one call.The stats gathering time of each subsystem can vary substantially (e.g., cpu vs. disk), so even though the on-demand model preferred due to its simplicity, we’d rather give the container runtime more flexibility to determine the collection frequency for each subsystem*. As a trade-off, each piece of stats for the subsystem must contain a timestamp to let kubelet know how fresh/recent the stats are. In the future, we should also recommend a guideline for how recent the stats should be in order to ensure the reliability (e.g., eviction) and the responsiveness (e.g., autoscaling) of the kubernetes cluster.
The next step is to plumb this through kubelet so that kubelet can choose consume container stats from CRI or cadvisor.
*Alternatively, we can add calls to get stats of individual subsystems. However, kubelet does not have the complete knowledge of the runtime environment, so this would only lead to unnecessary complexity in kubelet.
Release note: