mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor update for E2E framework
Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
20
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/doc.go
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2017 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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=kubelet.config.k8s.io
|
||||
|
||||
package config // import "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
30
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/helpers.go
generated
vendored
Normal file
30
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/helpers.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright 2017 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 config
|
||||
|
||||
// KubeletConfigurationPathRefs returns pointers to all of the KubeletConfiguration fields that contain filepaths.
|
||||
// You might use this, for example, to resolve all relative paths against some common root before
|
||||
// passing the configuration to the application. This method must be kept up to date as new fields are added.
|
||||
func KubeletConfigurationPathRefs(kc *KubeletConfiguration) []*string {
|
||||
paths := []*string{}
|
||||
paths = append(paths, &kc.StaticPodPath)
|
||||
paths = append(paths, &kc.Authentication.X509.ClientCAFile)
|
||||
paths = append(paths, &kc.TLSCertFile)
|
||||
paths = append(paths, &kc.TLSPrivateKeyFile)
|
||||
paths = append(paths, &kc.ResolverConfig)
|
||||
return paths
|
||||
}
|
44
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/register.go
generated
vendored
Normal file
44
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/register.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2017 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 config
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name used in this package
|
||||
const GroupName = "kubelet.config.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
var (
|
||||
// SchemeBuilder is the scheme builder with scheme init functions to run for this API package
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme is a global function that registers this API group & version to a scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// addKnownTypes registers known types to the given scheme
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&KubeletConfiguration{},
|
||||
&SerializedNodeConfigSource{},
|
||||
)
|
||||
return nil
|
||||
}
|
382
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go
generated
vendored
Normal file
382
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go
generated
vendored
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
Copyright 2015 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 config
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// HairpinMode denotes how the kubelet should configure networking to handle
|
||||
// hairpin packets.
|
||||
type HairpinMode string
|
||||
|
||||
// Enum settings for different ways to handle hairpin packets.
|
||||
const (
|
||||
// Set the hairpin flag on the veth of containers in the respective
|
||||
// container runtime.
|
||||
HairpinVeth = "hairpin-veth"
|
||||
// Make the container bridge promiscuous. This will force it to accept
|
||||
// hairpin packets, even if the flag isn't set on ports of the bridge.
|
||||
PromiscuousBridge = "promiscuous-bridge"
|
||||
// Neither of the above. If the kubelet is started in this hairpin mode
|
||||
// and kube-proxy is running in iptables mode, hairpin packets will be
|
||||
// dropped by the container bridge.
|
||||
HairpinNone = "none"
|
||||
)
|
||||
|
||||
// ResourceChangeDetectionStrategy denotes a mode in which internal
|
||||
// managers (secret, configmap) are discovering object changes.
|
||||
type ResourceChangeDetectionStrategy string
|
||||
|
||||
// Enum settings for different strategies of kubelet managers.
|
||||
const (
|
||||
// GetChangeDetectionStrategy is a mode in which kubelet fetches
|
||||
// necessary objects directly from apiserver.
|
||||
GetChangeDetectionStrategy ResourceChangeDetectionStrategy = "Get"
|
||||
// TTLCacheChangeDetectionStrategy is a mode in which kubelet uses
|
||||
// ttl cache for object directly fetched from apiserver.
|
||||
TTLCacheChangeDetectionStrategy ResourceChangeDetectionStrategy = "Cache"
|
||||
// WatchChangeDetectionStrategy is a mode in which kubelet uses
|
||||
// watches to observe changes to objects that are in its interest.
|
||||
WatchChangeDetectionStrategy ResourceChangeDetectionStrategy = "Watch"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// KubeletConfiguration contains the configuration for the Kubelet
|
||||
type KubeletConfiguration struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// staticPodPath is the path to the directory containing local (static) pods to
|
||||
// run, or the path to a single static pod file.
|
||||
StaticPodPath string
|
||||
// syncFrequency is the max period between synchronizing running
|
||||
// containers and config
|
||||
SyncFrequency metav1.Duration
|
||||
// fileCheckFrequency is the duration between checking config files for
|
||||
// new data
|
||||
FileCheckFrequency metav1.Duration
|
||||
// httpCheckFrequency is the duration between checking http for new data
|
||||
HTTPCheckFrequency metav1.Duration
|
||||
// staticPodURL is the URL for accessing static pods to run
|
||||
StaticPodURL string
|
||||
// staticPodURLHeader is a map of slices with HTTP headers to use when accessing the podURL
|
||||
StaticPodURLHeader map[string][]string
|
||||
// address is the IP address for the Kubelet to serve on (set to 0.0.0.0
|
||||
// for all interfaces)
|
||||
Address string
|
||||
// port is the port for the Kubelet to serve on.
|
||||
Port int32
|
||||
// readOnlyPort is the read-only port for the Kubelet to serve on with
|
||||
// no authentication/authorization (set to 0 to disable)
|
||||
ReadOnlyPort int32
|
||||
// tlsCertFile is the file containing x509 Certificate for HTTPS. (CA cert,
|
||||
// if any, concatenated after server cert). If tlsCertFile and
|
||||
// tlsPrivateKeyFile are not provided, a self-signed certificate
|
||||
// and key are generated for the public address and saved to the directory
|
||||
// passed to the Kubelet's --cert-dir flag.
|
||||
TLSCertFile string
|
||||
// tlsPrivateKeyFile is the file containing x509 private key matching tlsCertFile
|
||||
TLSPrivateKeyFile string
|
||||
// TLSCipherSuites is the list of allowed cipher suites for the server.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
TLSCipherSuites []string
|
||||
// TLSMinVersion is the minimum TLS version supported.
|
||||
// Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants).
|
||||
TLSMinVersion string
|
||||
// rotateCertificates enables client certificate rotation. The Kubelet will request a
|
||||
// new certificate from the certificates.k8s.io API. This requires an approver to approve the
|
||||
// certificate signing requests. The RotateKubeletClientCertificate feature
|
||||
// must be enabled.
|
||||
RotateCertificates bool
|
||||
// serverTLSBootstrap enables server certificate bootstrap. Instead of self
|
||||
// signing a serving certificate, the Kubelet will request a certificate from
|
||||
// the certificates.k8s.io API. This requires an approver to approve the
|
||||
// certificate signing requests. The RotateKubeletServerCertificate feature
|
||||
// must be enabled.
|
||||
ServerTLSBootstrap bool
|
||||
// authentication specifies how requests to the Kubelet's server are authenticated
|
||||
Authentication KubeletAuthentication
|
||||
// authorization specifies how requests to the Kubelet's server are authorized
|
||||
Authorization KubeletAuthorization
|
||||
// registryPullQPS is the limit of registry pulls per second.
|
||||
// Set to 0 for no limit.
|
||||
RegistryPullQPS int32
|
||||
// registryBurst is the maximum size of bursty pulls, temporarily allows
|
||||
// pulls to burst to this number, while still not exceeding registryPullQPS.
|
||||
// Only used if registryPullQPS > 0.
|
||||
RegistryBurst int32
|
||||
// eventRecordQPS is the maximum event creations per second. If 0, there
|
||||
// is no limit enforced.
|
||||
EventRecordQPS int32
|
||||
// eventBurst is the maximum size of a burst of event creations, temporarily
|
||||
// allows event creations to burst to this number, while still not exceeding
|
||||
// eventRecordQPS. Only used if eventRecordQPS > 0.
|
||||
EventBurst int32
|
||||
// enableDebuggingHandlers enables server endpoints for log collection
|
||||
// and local running of containers and commands
|
||||
EnableDebuggingHandlers bool
|
||||
// enableContentionProfiling enables lock contention profiling, if enableDebuggingHandlers is true.
|
||||
EnableContentionProfiling bool
|
||||
// healthzPort is the port of the localhost healthz endpoint (set to 0 to disable)
|
||||
HealthzPort int32
|
||||
// healthzBindAddress is the IP address for the healthz server to serve on
|
||||
HealthzBindAddress string
|
||||
// oomScoreAdj is The oom-score-adj value for kubelet process. Values
|
||||
// must be within the range [-1000, 1000].
|
||||
OOMScoreAdj int32
|
||||
// clusterDomain is the DNS domain for this cluster. If set, kubelet will
|
||||
// configure all containers to search this domain in addition to the
|
||||
// host's search domains.
|
||||
ClusterDomain string
|
||||
// clusterDNS is a list of IP addresses for a cluster DNS server. If set,
|
||||
// kubelet will configure all containers to use this for DNS resolution
|
||||
// instead of the host's DNS servers.
|
||||
ClusterDNS []string
|
||||
// streamingConnectionIdleTimeout is the maximum time a streaming connection
|
||||
// can be idle before the connection is automatically closed.
|
||||
StreamingConnectionIdleTimeout metav1.Duration
|
||||
// nodeStatusUpdateFrequency is the frequency that kubelet computes node
|
||||
// status. If node lease feature is not enabled, it is also the frequency that
|
||||
// kubelet posts node status to master. In that case, be cautious when
|
||||
// changing the constant, it must work with nodeMonitorGracePeriod in nodecontroller.
|
||||
NodeStatusUpdateFrequency metav1.Duration
|
||||
// nodeStatusReportFrequency is the frequency that kubelet posts node
|
||||
// status to master if node status does not change. Kubelet will ignore this
|
||||
// frequency and post node status immediately if any change is detected. It is
|
||||
// only used when node lease feature is enabled.
|
||||
NodeStatusReportFrequency metav1.Duration
|
||||
// nodeLeaseDurationSeconds is the duration the Kubelet will set on its corresponding Lease.
|
||||
NodeLeaseDurationSeconds int32
|
||||
// imageMinimumGCAge is the minimum age for an unused image before it is
|
||||
// garbage collected.
|
||||
ImageMinimumGCAge metav1.Duration
|
||||
// imageGCHighThresholdPercent is the percent of disk usage after which
|
||||
// image garbage collection is always run. The percent is calculated as
|
||||
// this field value out of 100.
|
||||
ImageGCHighThresholdPercent int32
|
||||
// imageGCLowThresholdPercent is the percent of disk usage before which
|
||||
// image garbage collection is never run. Lowest disk usage to garbage
|
||||
// collect to. The percent is calculated as this field value out of 100.
|
||||
ImageGCLowThresholdPercent int32
|
||||
// How frequently to calculate and cache volume disk usage for all pods
|
||||
VolumeStatsAggPeriod metav1.Duration
|
||||
// KubeletCgroups is the absolute name of cgroups to isolate the kubelet in
|
||||
KubeletCgroups string
|
||||
// SystemCgroups is absolute name of cgroups in which to place
|
||||
// all non-kernel processes that are not already in a container. Empty
|
||||
// for no container. Rolling back the flag requires a reboot.
|
||||
SystemCgroups string
|
||||
// CgroupRoot is the root cgroup to use for pods.
|
||||
// If CgroupsPerQOS is enabled, this is the root of the QoS cgroup hierarchy.
|
||||
CgroupRoot string
|
||||
// Enable QoS based Cgroup hierarchy: top level cgroups for QoS Classes
|
||||
// And all Burstable and BestEffort pods are brought up under their
|
||||
// specific top level QoS cgroup.
|
||||
CgroupsPerQOS bool
|
||||
// driver that the kubelet uses to manipulate cgroups on the host (cgroupfs or systemd)
|
||||
CgroupDriver string
|
||||
// CPUManagerPolicy is the name of the policy to use.
|
||||
// Requires the CPUManager feature gate to be enabled.
|
||||
CPUManagerPolicy string
|
||||
// CPU Manager reconciliation period.
|
||||
// Requires the CPUManager feature gate to be enabled.
|
||||
CPUManagerReconcilePeriod metav1.Duration
|
||||
// Map of QoS resource reservation percentages (memory only for now).
|
||||
// Requires the QOSReserved feature gate to be enabled.
|
||||
QOSReserved map[string]string
|
||||
// runtimeRequestTimeout is the timeout for all runtime requests except long running
|
||||
// requests - pull, logs, exec and attach.
|
||||
RuntimeRequestTimeout metav1.Duration
|
||||
// hairpinMode specifies how the Kubelet should configure the container
|
||||
// bridge for hairpin packets.
|
||||
// Setting this flag allows endpoints in a Service to loadbalance back to
|
||||
// themselves if they should try to access their own Service. Values:
|
||||
// "promiscuous-bridge": make the container bridge promiscuous.
|
||||
// "hairpin-veth": set the hairpin flag on container veth interfaces.
|
||||
// "none": do nothing.
|
||||
// Generally, one must set --hairpin-mode=hairpin-veth to achieve hairpin NAT,
|
||||
// because promiscuous-bridge assumes the existence of a container bridge named cbr0.
|
||||
HairpinMode string
|
||||
// maxPods is the number of pods that can run on this Kubelet.
|
||||
MaxPods int32
|
||||
// The CIDR to use for pod IP addresses, only used in standalone mode.
|
||||
// In cluster mode, this is obtained from the master.
|
||||
PodCIDR string
|
||||
// The maximum number of processes per pod. If -1, the kubelet defaults to the node allocatable pid capacity.
|
||||
PodPidsLimit int64
|
||||
// ResolverConfig is the resolver configuration file used as the basis
|
||||
// for the container DNS resolution configuration.
|
||||
ResolverConfig string
|
||||
// cpuCFSQuota enables CPU CFS quota enforcement for containers that
|
||||
// specify CPU limits
|
||||
CPUCFSQuota bool
|
||||
// CPUCFSQuotaPeriod sets the CPU CFS quota period value, cpu.cfs_period_us, defaults to 100ms
|
||||
CPUCFSQuotaPeriod metav1.Duration
|
||||
// maxOpenFiles is Number of files that can be opened by Kubelet process.
|
||||
MaxOpenFiles int64
|
||||
// contentType is contentType of requests sent to apiserver.
|
||||
ContentType string
|
||||
// kubeAPIQPS is the QPS to use while talking with kubernetes apiserver
|
||||
KubeAPIQPS int32
|
||||
// kubeAPIBurst is the burst to allow while talking with kubernetes
|
||||
// apiserver
|
||||
KubeAPIBurst int32
|
||||
// serializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
|
||||
SerializeImagePulls bool
|
||||
// Map of signal names to quantities that defines hard eviction thresholds. For example: {"memory.available": "300Mi"}.
|
||||
EvictionHard map[string]string
|
||||
// Map of signal names to quantities that defines soft eviction thresholds. For example: {"memory.available": "300Mi"}.
|
||||
EvictionSoft map[string]string
|
||||
// Map of signal names to quantities that defines grace periods for each soft eviction signal. For example: {"memory.available": "30s"}.
|
||||
EvictionSoftGracePeriod map[string]string
|
||||
// Duration for which the kubelet has to wait before transitioning out of an eviction pressure condition.
|
||||
EvictionPressureTransitionPeriod metav1.Duration
|
||||
// Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met.
|
||||
EvictionMaxPodGracePeriod int32
|
||||
// Map of signal names to quantities that defines minimum reclaims, which describe the minimum
|
||||
// amount of a given resource the kubelet will reclaim when performing a pod eviction while
|
||||
// that resource is under pressure. For example: {"imagefs.available": "2Gi"}
|
||||
EvictionMinimumReclaim map[string]string
|
||||
// podsPerCore is the maximum number of pods per core. Cannot exceed MaxPods.
|
||||
// If 0, this field is ignored.
|
||||
PodsPerCore int32
|
||||
// enableControllerAttachDetach enables the Attach/Detach controller to
|
||||
// manage attachment/detachment of volumes scheduled to this node, and
|
||||
// disables kubelet from executing any attach/detach operations
|
||||
EnableControllerAttachDetach bool
|
||||
// protectKernelDefaults, if true, causes the Kubelet to error if kernel
|
||||
// flags are not as it expects. Otherwise the Kubelet will attempt to modify
|
||||
// kernel flags to match its expectation.
|
||||
ProtectKernelDefaults bool
|
||||
// If true, Kubelet ensures a set of iptables rules are present on host.
|
||||
// These rules will serve as utility for various components, e.g. kube-proxy.
|
||||
// The rules will be created based on IPTablesMasqueradeBit and IPTablesDropBit.
|
||||
MakeIPTablesUtilChains bool
|
||||
// iptablesMasqueradeBit is the bit of the iptables fwmark space to mark for SNAT
|
||||
// Values must be within the range [0, 31]. Must be different from other mark bits.
|
||||
// Warning: Please match the value of the corresponding parameter in kube-proxy.
|
||||
// TODO: clean up IPTablesMasqueradeBit in kube-proxy
|
||||
IPTablesMasqueradeBit int32
|
||||
// iptablesDropBit is the bit of the iptables fwmark space to mark for dropping packets.
|
||||
// Values must be within the range [0, 31]. Must be different from other mark bits.
|
||||
IPTablesDropBit int32
|
||||
// featureGates is a map of feature names to bools that enable or disable alpha/experimental
|
||||
// features. This field modifies piecemeal the built-in default values from
|
||||
// "k8s.io/kubernetes/pkg/features/kube_features.go".
|
||||
FeatureGates map[string]bool
|
||||
// Tells the Kubelet to fail to start if swap is enabled on the node.
|
||||
FailSwapOn bool
|
||||
// A quantity defines the maximum size of the container log file before it is rotated. For example: "5Mi" or "256Ki".
|
||||
ContainerLogMaxSize string
|
||||
// Maximum number of container log files that can be present for a container.
|
||||
ContainerLogMaxFiles int32
|
||||
// ConfigMapAndSecretChangeDetectionStrategy is a mode in which config map and secret managers are running.
|
||||
ConfigMapAndSecretChangeDetectionStrategy ResourceChangeDetectionStrategy
|
||||
|
||||
/* the following fields are meant for Node Allocatable */
|
||||
|
||||
// A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=150G,pids=100) pairs
|
||||
// that describe resources reserved for non-kubernetes components.
|
||||
// Currently only cpu and memory are supported.
|
||||
// See http://kubernetes.io/docs/user-guide/compute-resources for more detail.
|
||||
SystemReserved map[string]string
|
||||
// A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=150G,pids=100) pairs
|
||||
// that describe resources reserved for kubernetes system components.
|
||||
// Currently cpu, memory and local ephemeral storage for root file system are supported.
|
||||
// See http://kubernetes.io/docs/user-guide/compute-resources for more detail.
|
||||
KubeReserved map[string]string
|
||||
// This flag helps kubelet identify absolute name of top level cgroup used to enforce `SystemReserved` compute resource reservation for OS system daemons.
|
||||
// Refer to [Node Allocatable](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md) doc for more information.
|
||||
SystemReservedCgroup string
|
||||
// This flag helps kubelet identify absolute name of top level cgroup used to enforce `KubeReserved` compute resource reservation for Kubernetes node system daemons.
|
||||
// Refer to [Node Allocatable](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md) doc for more information.
|
||||
KubeReservedCgroup string
|
||||
// This flag specifies the various Node Allocatable enforcements that Kubelet needs to perform.
|
||||
// This flag accepts a list of options. Acceptable options are `pods`, `system-reserved` & `kube-reserved`.
|
||||
// Refer to [Node Allocatable](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md) doc for more information.
|
||||
EnforceNodeAllocatable []string
|
||||
}
|
||||
|
||||
type KubeletAuthorizationMode string
|
||||
|
||||
const (
|
||||
// KubeletAuthorizationModeAlwaysAllow authorizes all authenticated requests
|
||||
KubeletAuthorizationModeAlwaysAllow KubeletAuthorizationMode = "AlwaysAllow"
|
||||
// KubeletAuthorizationModeWebhook uses the SubjectAccessReview API to determine authorization
|
||||
KubeletAuthorizationModeWebhook KubeletAuthorizationMode = "Webhook"
|
||||
)
|
||||
|
||||
type KubeletAuthorization struct {
|
||||
// mode is the authorization mode to apply to requests to the kubelet server.
|
||||
// Valid values are AlwaysAllow and Webhook.
|
||||
// Webhook mode uses the SubjectAccessReview API to determine authorization.
|
||||
Mode KubeletAuthorizationMode
|
||||
|
||||
// webhook contains settings related to Webhook authorization.
|
||||
Webhook KubeletWebhookAuthorization
|
||||
}
|
||||
|
||||
type KubeletWebhookAuthorization struct {
|
||||
// cacheAuthorizedTTL is the duration to cache 'authorized' responses from the webhook authorizer.
|
||||
CacheAuthorizedTTL metav1.Duration
|
||||
// cacheUnauthorizedTTL is the duration to cache 'unauthorized' responses from the webhook authorizer.
|
||||
CacheUnauthorizedTTL metav1.Duration
|
||||
}
|
||||
|
||||
type KubeletAuthentication struct {
|
||||
// x509 contains settings related to x509 client certificate authentication
|
||||
X509 KubeletX509Authentication
|
||||
// webhook contains settings related to webhook bearer token authentication
|
||||
Webhook KubeletWebhookAuthentication
|
||||
// anonymous contains settings related to anonymous authentication
|
||||
Anonymous KubeletAnonymousAuthentication
|
||||
}
|
||||
|
||||
type KubeletX509Authentication struct {
|
||||
// clientCAFile is the path to a PEM-encoded certificate bundle. If set, any request presenting a client certificate
|
||||
// signed by one of the authorities in the bundle is authenticated with a username corresponding to the CommonName,
|
||||
// and groups corresponding to the Organization in the client certificate.
|
||||
ClientCAFile string
|
||||
}
|
||||
|
||||
type KubeletWebhookAuthentication struct {
|
||||
// enabled allows bearer token authentication backed by the tokenreviews.authentication.k8s.io API
|
||||
Enabled bool
|
||||
// cacheTTL enables caching of authentication results
|
||||
CacheTTL metav1.Duration
|
||||
}
|
||||
|
||||
type KubeletAnonymousAuthentication struct {
|
||||
// enabled allows anonymous requests to the kubelet server.
|
||||
// Requests that are not rejected by another authentication method are treated as anonymous requests.
|
||||
// Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// SerializedNodeConfigSource allows us to serialize NodeConfigSource
|
||||
// This type is used internally by the Kubelet for tracking checkpointed dynamic configs.
|
||||
// It exists in the kubeletconfig API group because it is classified as a versioned input to the Kubelet.
|
||||
type SerializedNodeConfigSource struct {
|
||||
metav1.TypeMeta
|
||||
// Source is the source that we are serializing
|
||||
// +optional
|
||||
Source v1.NodeConfigSource
|
||||
}
|
279
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
vendored
Normal file
279
vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletAnonymousAuthentication) DeepCopyInto(out *KubeletAnonymousAuthentication) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletAnonymousAuthentication.
|
||||
func (in *KubeletAnonymousAuthentication) DeepCopy() *KubeletAnonymousAuthentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletAnonymousAuthentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletAuthentication) DeepCopyInto(out *KubeletAuthentication) {
|
||||
*out = *in
|
||||
out.X509 = in.X509
|
||||
out.Webhook = in.Webhook
|
||||
out.Anonymous = in.Anonymous
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletAuthentication.
|
||||
func (in *KubeletAuthentication) DeepCopy() *KubeletAuthentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletAuthentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletAuthorization) DeepCopyInto(out *KubeletAuthorization) {
|
||||
*out = *in
|
||||
out.Webhook = in.Webhook
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletAuthorization.
|
||||
func (in *KubeletAuthorization) DeepCopy() *KubeletAuthorization {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletAuthorization)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.SyncFrequency = in.SyncFrequency
|
||||
out.FileCheckFrequency = in.FileCheckFrequency
|
||||
out.HTTPCheckFrequency = in.HTTPCheckFrequency
|
||||
if in.StaticPodURLHeader != nil {
|
||||
in, out := &in.StaticPodURLHeader, &out.StaticPodURLHeader
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.TLSCipherSuites != nil {
|
||||
in, out := &in.TLSCipherSuites, &out.TLSCipherSuites
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.Authentication = in.Authentication
|
||||
out.Authorization = in.Authorization
|
||||
if in.ClusterDNS != nil {
|
||||
in, out := &in.ClusterDNS, &out.ClusterDNS
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.StreamingConnectionIdleTimeout = in.StreamingConnectionIdleTimeout
|
||||
out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency
|
||||
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
|
||||
out.ImageMinimumGCAge = in.ImageMinimumGCAge
|
||||
out.VolumeStatsAggPeriod = in.VolumeStatsAggPeriod
|
||||
out.CPUManagerReconcilePeriod = in.CPUManagerReconcilePeriod
|
||||
if in.QOSReserved != nil {
|
||||
in, out := &in.QOSReserved, &out.QOSReserved
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.RuntimeRequestTimeout = in.RuntimeRequestTimeout
|
||||
out.CPUCFSQuotaPeriod = in.CPUCFSQuotaPeriod
|
||||
if in.EvictionHard != nil {
|
||||
in, out := &in.EvictionHard, &out.EvictionHard
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.EvictionSoft != nil {
|
||||
in, out := &in.EvictionSoft, &out.EvictionSoft
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.EvictionSoftGracePeriod != nil {
|
||||
in, out := &in.EvictionSoftGracePeriod, &out.EvictionSoftGracePeriod
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
out.EvictionPressureTransitionPeriod = in.EvictionPressureTransitionPeriod
|
||||
if in.EvictionMinimumReclaim != nil {
|
||||
in, out := &in.EvictionMinimumReclaim, &out.EvictionMinimumReclaim
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.FeatureGates != nil {
|
||||
in, out := &in.FeatureGates, &out.FeatureGates
|
||||
*out = make(map[string]bool, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.SystemReserved != nil {
|
||||
in, out := &in.SystemReserved, &out.SystemReserved
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.KubeReserved != nil {
|
||||
in, out := &in.KubeReserved, &out.KubeReserved
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.EnforceNodeAllocatable != nil {
|
||||
in, out := &in.EnforceNodeAllocatable, &out.EnforceNodeAllocatable
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletConfiguration.
|
||||
func (in *KubeletConfiguration) DeepCopy() *KubeletConfiguration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletConfiguration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KubeletConfiguration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletWebhookAuthentication) DeepCopyInto(out *KubeletWebhookAuthentication) {
|
||||
*out = *in
|
||||
out.CacheTTL = in.CacheTTL
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletWebhookAuthentication.
|
||||
func (in *KubeletWebhookAuthentication) DeepCopy() *KubeletWebhookAuthentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletWebhookAuthentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletWebhookAuthorization) DeepCopyInto(out *KubeletWebhookAuthorization) {
|
||||
*out = *in
|
||||
out.CacheAuthorizedTTL = in.CacheAuthorizedTTL
|
||||
out.CacheUnauthorizedTTL = in.CacheUnauthorizedTTL
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletWebhookAuthorization.
|
||||
func (in *KubeletWebhookAuthorization) DeepCopy() *KubeletWebhookAuthorization {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletWebhookAuthorization)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeletX509Authentication) DeepCopyInto(out *KubeletX509Authentication) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeletX509Authentication.
|
||||
func (in *KubeletX509Authentication) DeepCopy() *KubeletX509Authentication {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeletX509Authentication)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SerializedNodeConfigSource) DeepCopyInto(out *SerializedNodeConfigSource) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.Source.DeepCopyInto(&out.Source)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SerializedNodeConfigSource.
|
||||
func (in *SerializedNodeConfigSource) DeepCopy() *SerializedNodeConfigSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SerializedNodeConfigSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *SerializedNodeConfigSource) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
27259
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2/api.pb.go
generated
vendored
Normal file
27259
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2/api.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
55
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2/constants.go
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2/constants.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2016 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 v1alpha2
|
||||
|
||||
// This file contains all constants defined in CRI.
|
||||
|
||||
// Required runtime condition type.
|
||||
const (
|
||||
// RuntimeReady means the runtime is up and ready to accept basic containers.
|
||||
RuntimeReady = "RuntimeReady"
|
||||
// NetworkReady means the runtime network is up and ready to accept containers which require network.
|
||||
NetworkReady = "NetworkReady"
|
||||
)
|
||||
|
||||
// LogStreamType is the type of the stream in CRI container log.
|
||||
type LogStreamType string
|
||||
|
||||
const (
|
||||
// Stdout is the stream type for stdout.
|
||||
Stdout LogStreamType = "stdout"
|
||||
// Stderr is the stream type for stderr.
|
||||
Stderr LogStreamType = "stderr"
|
||||
)
|
||||
|
||||
// LogTag is the tag of a log line in CRI container log.
|
||||
// Currently defined log tags:
|
||||
// * First tag: Partial/Full - P/F.
|
||||
// The field in the container log format can be extended to include multiple
|
||||
// tags by using a delimiter, but changes should be rare. If it becomes clear
|
||||
// that better extensibility is desired, a more extensible format (e.g., json)
|
||||
// should be adopted as a replacement and/or addition.
|
||||
type LogTag string
|
||||
|
||||
const (
|
||||
// LogTagPartial means the line is part of multiple lines.
|
||||
LogTagPartial LogTag = "P"
|
||||
// LogTagFull means the line is a single full line or the end of multiple lines.
|
||||
LogTagFull LogTag = "F"
|
||||
// LogTagDelimiter is the delimiter for different log tags.
|
||||
LogTagDelimiter = ":"
|
||||
)
|
335
vendor/k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1/types.go
generated
vendored
Normal file
335
vendor/k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1/types.go
generated
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
Copyright 2015 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 v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// Summary is a top-level container for holding NodeStats and PodStats.
|
||||
type Summary struct {
|
||||
// Overall node stats.
|
||||
Node NodeStats `json:"node"`
|
||||
// Per-pod stats.
|
||||
Pods []PodStats `json:"pods"`
|
||||
}
|
||||
|
||||
// NodeStats holds node-level unprocessed sample stats.
|
||||
type NodeStats struct {
|
||||
// Reference to the measured Node.
|
||||
NodeName string `json:"nodeName"`
|
||||
// Stats of system daemons tracked as raw containers.
|
||||
// The system containers are named according to the SystemContainer* constants.
|
||||
// +optional
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
SystemContainers []ContainerStats `json:"systemContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
// The time at which data collection for the node-scoped (i.e. aggregate) stats was (re)started.
|
||||
StartTime metav1.Time `json:"startTime"`
|
||||
// Stats pertaining to CPU resources.
|
||||
// +optional
|
||||
CPU *CPUStats `json:"cpu,omitempty"`
|
||||
// Stats pertaining to memory (RAM) resources.
|
||||
// +optional
|
||||
Memory *MemoryStats `json:"memory,omitempty"`
|
||||
// Stats pertaining to network resources.
|
||||
// +optional
|
||||
Network *NetworkStats `json:"network,omitempty"`
|
||||
// Stats pertaining to total usage of filesystem resources on the rootfs used by node k8s components.
|
||||
// NodeFs.Used is the total bytes used on the filesystem.
|
||||
// +optional
|
||||
Fs *FsStats `json:"fs,omitempty"`
|
||||
// Stats about the underlying container runtime.
|
||||
// +optional
|
||||
Runtime *RuntimeStats `json:"runtime,omitempty"`
|
||||
// Stats about the rlimit of system.
|
||||
// +optional
|
||||
Rlimit *RlimitStats `json:"rlimit,omitempty"`
|
||||
}
|
||||
|
||||
// RlimitStats are stats rlimit of OS.
|
||||
type RlimitStats struct {
|
||||
Time metav1.Time `json:"time"`
|
||||
|
||||
// The max PID of OS.
|
||||
MaxPID *int64 `json:"maxpid,omitempty"`
|
||||
// The number of running process in the OS.
|
||||
NumOfRunningProcesses *int64 `json:"curproc,omitempty"`
|
||||
}
|
||||
|
||||
// RuntimeStats are stats pertaining to the underlying container runtime.
|
||||
type RuntimeStats struct {
|
||||
// Stats about the underlying filesystem where container images are stored.
|
||||
// This filesystem could be the same as the primary (root) filesystem.
|
||||
// Usage here refers to the total number of bytes occupied by images on the filesystem.
|
||||
// +optional
|
||||
ImageFs *FsStats `json:"imageFs,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// SystemContainerKubelet is the container name for the system container tracking Kubelet usage.
|
||||
SystemContainerKubelet = "kubelet"
|
||||
// SystemContainerRuntime is the container name for the system container tracking the runtime (e.g. docker) usage.
|
||||
SystemContainerRuntime = "runtime"
|
||||
// SystemContainerMisc is the container name for the system container tracking non-kubernetes processes.
|
||||
SystemContainerMisc = "misc"
|
||||
// SystemContainerPods is the container name for the system container tracking user pods.
|
||||
SystemContainerPods = "pods"
|
||||
)
|
||||
|
||||
// PodStats holds pod-level unprocessed sample stats.
|
||||
type PodStats struct {
|
||||
// Reference to the measured Pod.
|
||||
PodRef PodReference `json:"podRef"`
|
||||
// The time at which data collection for the pod-scoped (e.g. network) stats was (re)started.
|
||||
StartTime metav1.Time `json:"startTime"`
|
||||
// Stats of containers in the measured pod.
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
Containers []ContainerStats `json:"containers" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
// Stats pertaining to CPU resources consumed by pod cgroup (which includes all containers' resource usage and pod overhead).
|
||||
// +optional
|
||||
CPU *CPUStats `json:"cpu,omitempty"`
|
||||
// Stats pertaining to memory (RAM) resources consumed by pod cgroup (which includes all containers' resource usage and pod overhead).
|
||||
// +optional
|
||||
Memory *MemoryStats `json:"memory,omitempty"`
|
||||
// Stats pertaining to network resources.
|
||||
// +optional
|
||||
Network *NetworkStats `json:"network,omitempty"`
|
||||
// Stats pertaining to volume usage of filesystem resources.
|
||||
// VolumeStats.UsedBytes is the number of bytes used by the Volume
|
||||
// +optional
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
VolumeStats []VolumeStats `json:"volume,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
// EphemeralStorage reports the total filesystem usage for the containers and emptyDir-backed volumes in the measured Pod.
|
||||
// +optional
|
||||
EphemeralStorage *FsStats `json:"ephemeral-storage,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerStats holds container-level unprocessed sample stats.
|
||||
type ContainerStats struct {
|
||||
// Reference to the measured container.
|
||||
Name string `json:"name"`
|
||||
// The time at which data collection for this container was (re)started.
|
||||
StartTime metav1.Time `json:"startTime"`
|
||||
// Stats pertaining to CPU resources.
|
||||
// +optional
|
||||
CPU *CPUStats `json:"cpu,omitempty"`
|
||||
// Stats pertaining to memory (RAM) resources.
|
||||
// +optional
|
||||
Memory *MemoryStats `json:"memory,omitempty"`
|
||||
// Metrics for Accelerators. Each Accelerator corresponds to one element in the array.
|
||||
Accelerators []AcceleratorStats `json:"accelerators,omitempty"`
|
||||
// Stats pertaining to container rootfs usage of filesystem resources.
|
||||
// Rootfs.UsedBytes is the number of bytes used for the container write layer.
|
||||
// +optional
|
||||
Rootfs *FsStats `json:"rootfs,omitempty"`
|
||||
// Stats pertaining to container logs usage of filesystem resources.
|
||||
// Logs.UsedBytes is the number of bytes used for the container logs.
|
||||
// +optional
|
||||
Logs *FsStats `json:"logs,omitempty"`
|
||||
// User defined metrics that are exposed by containers in the pod. Typically, we expect only one container in the pod to be exposing user defined metrics. In the event of multiple containers exposing metrics, they will be combined here.
|
||||
// +patchMergeKey=name
|
||||
// +patchStrategy=merge
|
||||
UserDefinedMetrics []UserDefinedMetric `json:"userDefinedMetrics,omitmepty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
}
|
||||
|
||||
// PodReference contains enough information to locate the referenced pod.
|
||||
type PodReference struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
UID string `json:"uid"`
|
||||
}
|
||||
|
||||
// InterfaceStats contains resource value data about interface.
|
||||
type InterfaceStats struct {
|
||||
// The name of the interface
|
||||
Name string `json:"name"`
|
||||
// Cumulative count of bytes received.
|
||||
// +optional
|
||||
RxBytes *uint64 `json:"rxBytes,omitempty"`
|
||||
// Cumulative count of receive errors encountered.
|
||||
// +optional
|
||||
RxErrors *uint64 `json:"rxErrors,omitempty"`
|
||||
// Cumulative count of bytes transmitted.
|
||||
// +optional
|
||||
TxBytes *uint64 `json:"txBytes,omitempty"`
|
||||
// Cumulative count of transmit errors encountered.
|
||||
// +optional
|
||||
TxErrors *uint64 `json:"txErrors,omitempty"`
|
||||
}
|
||||
|
||||
// NetworkStats contains data about network resources.
|
||||
type NetworkStats struct {
|
||||
// The time at which these stats were updated.
|
||||
Time metav1.Time `json:"time"`
|
||||
|
||||
// Stats for the default interface, if found
|
||||
InterfaceStats `json:",inline"`
|
||||
|
||||
Interfaces []InterfaceStats `json:"interfaces,omitempty"`
|
||||
}
|
||||
|
||||
// CPUStats contains data about CPU usage.
|
||||
type CPUStats struct {
|
||||
// The time at which these stats were updated.
|
||||
Time metav1.Time `json:"time"`
|
||||
// Total CPU usage (sum of all cores) averaged over the sample window.
|
||||
// The "core" unit can be interpreted as CPU core-nanoseconds per second.
|
||||
// +optional
|
||||
UsageNanoCores *uint64 `json:"usageNanoCores,omitempty"`
|
||||
// Cumulative CPU usage (sum of all cores) since object creation.
|
||||
// +optional
|
||||
UsageCoreNanoSeconds *uint64 `json:"usageCoreNanoSeconds,omitempty"`
|
||||
}
|
||||
|
||||
// MemoryStats contains data about memory usage.
|
||||
type MemoryStats struct {
|
||||
// The time at which these stats were updated.
|
||||
Time metav1.Time `json:"time"`
|
||||
// Available memory for use. This is defined as the memory limit - workingSetBytes.
|
||||
// If memory limit is undefined, the available bytes is omitted.
|
||||
// +optional
|
||||
AvailableBytes *uint64 `json:"availableBytes,omitempty"`
|
||||
// Total memory in use. This includes all memory regardless of when it was accessed.
|
||||
// +optional
|
||||
UsageBytes *uint64 `json:"usageBytes,omitempty"`
|
||||
// The amount of working set memory. This includes recently accessed memory,
|
||||
// dirty memory, and kernel memory. WorkingSetBytes is <= UsageBytes
|
||||
// +optional
|
||||
WorkingSetBytes *uint64 `json:"workingSetBytes,omitempty"`
|
||||
// The amount of anonymous and swap cache memory (includes transparent
|
||||
// hugepages).
|
||||
// +optional
|
||||
RSSBytes *uint64 `json:"rssBytes,omitempty"`
|
||||
// Cumulative number of minor page faults.
|
||||
// +optional
|
||||
PageFaults *uint64 `json:"pageFaults,omitempty"`
|
||||
// Cumulative number of major page faults.
|
||||
// +optional
|
||||
MajorPageFaults *uint64 `json:"majorPageFaults,omitempty"`
|
||||
}
|
||||
|
||||
// AcceleratorStats contains stats for accelerators attached to the container.
|
||||
type AcceleratorStats struct {
|
||||
// Make of the accelerator (nvidia, amd, google etc.)
|
||||
Make string `json:"make"`
|
||||
|
||||
// Model of the accelerator (tesla-p100, tesla-k80 etc.)
|
||||
Model string `json:"model"`
|
||||
|
||||
// ID of the accelerator.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Total accelerator memory.
|
||||
// unit: bytes
|
||||
MemoryTotal uint64 `json:"memoryTotal"`
|
||||
|
||||
// Total accelerator memory allocated.
|
||||
// unit: bytes
|
||||
MemoryUsed uint64 `json:"memoryUsed"`
|
||||
|
||||
// Percent of time over the past sample period (10s) during which
|
||||
// the accelerator was actively processing.
|
||||
DutyCycle uint64 `json:"dutyCycle"`
|
||||
}
|
||||
|
||||
// VolumeStats contains data about Volume filesystem usage.
|
||||
type VolumeStats struct {
|
||||
// Embedded FsStats
|
||||
FsStats
|
||||
// Name is the name given to the Volume
|
||||
// +optional
|
||||
Name string `json:"name,omitempty"`
|
||||
// Reference to the PVC, if one exists
|
||||
// +optional
|
||||
PVCRef *PVCReference `json:"pvcRef,omitempty"`
|
||||
}
|
||||
|
||||
// PVCReference contains enough information to describe the referenced PVC.
|
||||
type PVCReference struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
// FsStats contains data about filesystem usage.
|
||||
type FsStats struct {
|
||||
// The time at which these stats were updated.
|
||||
Time metav1.Time `json:"time"`
|
||||
// AvailableBytes represents the storage space available (bytes) for the filesystem.
|
||||
// +optional
|
||||
AvailableBytes *uint64 `json:"availableBytes,omitempty"`
|
||||
// CapacityBytes represents the total capacity (bytes) of the filesystems underlying storage.
|
||||
// +optional
|
||||
CapacityBytes *uint64 `json:"capacityBytes,omitempty"`
|
||||
// UsedBytes represents the bytes used for a specific task on the filesystem.
|
||||
// This may differ from the total bytes used on the filesystem and may not equal CapacityBytes - AvailableBytes.
|
||||
// e.g. For ContainerStats.Rootfs this is the bytes used by the container rootfs on the filesystem.
|
||||
// +optional
|
||||
UsedBytes *uint64 `json:"usedBytes,omitempty"`
|
||||
// InodesFree represents the free inodes in the filesystem.
|
||||
// +optional
|
||||
InodesFree *uint64 `json:"inodesFree,omitempty"`
|
||||
// Inodes represents the total inodes in the filesystem.
|
||||
// +optional
|
||||
Inodes *uint64 `json:"inodes,omitempty"`
|
||||
// InodesUsed represents the inodes used by the filesystem
|
||||
// This may not equal Inodes - InodesFree because this filesystem may share inodes with other "filesystems"
|
||||
// e.g. For ContainerStats.Rootfs, this is the inodes used only by that container, and does not count inodes used by other containers.
|
||||
InodesUsed *uint64 `json:"inodesUsed,omitempty"`
|
||||
}
|
||||
|
||||
// UserDefinedMetricType defines how the metric should be interpreted by the user.
|
||||
type UserDefinedMetricType string
|
||||
|
||||
const (
|
||||
// MetricGauge is an instantaneous value. May increase or decrease.
|
||||
MetricGauge UserDefinedMetricType = "gauge"
|
||||
|
||||
// MetricCumulative is a counter-like value that is only expected to increase.
|
||||
MetricCumulative UserDefinedMetricType = "cumulative"
|
||||
|
||||
// MetricDelta is a rate over a time period.
|
||||
MetricDelta UserDefinedMetricType = "delta"
|
||||
)
|
||||
|
||||
// UserDefinedMetricDescriptor contains metadata that describes a user defined metric.
|
||||
type UserDefinedMetricDescriptor struct {
|
||||
// The name of the metric.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Type of the metric.
|
||||
Type UserDefinedMetricType `json:"type"`
|
||||
|
||||
// Display Units for the stats.
|
||||
Units string `json:"units"`
|
||||
|
||||
// Metadata labels associated with this metric.
|
||||
// +optional
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
// UserDefinedMetric represents a metric defined and generated by users.
|
||||
type UserDefinedMetric struct {
|
||||
UserDefinedMetricDescriptor `json:",inline"`
|
||||
// The time at which these stats were updated.
|
||||
Time metav1.Time `json:"time"`
|
||||
// Value of the metric. Float64s have 53 bit precision.
|
||||
// We do not foresee any metrics exceeding that value.
|
||||
Value float64 `json:"value"`
|
||||
}
|
25
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_annotations.go
generated
vendored
Normal file
25
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_annotations.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2017 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 apis
|
||||
|
||||
const (
|
||||
// When kubelet is started with the "external" cloud provider, then
|
||||
// it sets this annotation on the node to denote an ip address set from the
|
||||
// cmd line flag (--node-ip). This ip is verified with the cloudprovider as valid by
|
||||
// the cloud-controller-manager
|
||||
AnnotationProvidedIPAddr = "alpha.kubernetes.io/provided-node-ip"
|
||||
)
|
41
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_annotations_windows.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_annotations_windows.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
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 apis
|
||||
|
||||
import (
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
const (
|
||||
// HypervIsolationAnnotationKey and HypervIsolationValue are used to run windows containers with hyperv isolation.
|
||||
// Refer https://aka.ms/hyperv-container.
|
||||
HypervIsolationAnnotationKey = "experimental.windows.kubernetes.io/isolation-type"
|
||||
HypervIsolationValue = "hyperv"
|
||||
)
|
||||
|
||||
// ShouldIsolatedByHyperV returns true if a windows container should be run with hyperv isolation.
|
||||
func ShouldIsolatedByHyperV(annotations map[string]string) bool {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.HyperVContainer) {
|
||||
return false
|
||||
}
|
||||
|
||||
v, ok := annotations[HypervIsolationAnnotationKey]
|
||||
return ok && v == HypervIsolationValue
|
||||
}
|
93
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_labels.go
generated
vendored
Normal file
93
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_labels.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright 2015 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 apis
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
const (
|
||||
// The OS/Arch labels are promoted to GA in 1.14. kubelet applies both beta
|
||||
// and GA labels to ensure backward compatibility.
|
||||
// TODO: stop applying the beta OS/Arch labels in Kubernetes 1.18.
|
||||
LabelOS = "beta.kubernetes.io/os"
|
||||
LabelArch = "beta.kubernetes.io/arch"
|
||||
|
||||
// GA versions of the legacy beta labels.
|
||||
// TODO: update kubelet and controllers to set both beta and GA labels, then export these constants
|
||||
labelZoneFailureDomainGA = "failure-domain.kubernetes.io/zone"
|
||||
labelZoneRegionGA = "failure-domain.kubernetes.io/region"
|
||||
labelInstanceTypeGA = "kubernetes.io/instance-type"
|
||||
)
|
||||
|
||||
var kubeletLabels = sets.NewString(
|
||||
v1.LabelHostname,
|
||||
v1.LabelZoneFailureDomain,
|
||||
v1.LabelZoneRegion,
|
||||
v1.LabelInstanceType,
|
||||
v1.LabelOSStable,
|
||||
v1.LabelArchStable,
|
||||
|
||||
LabelOS,
|
||||
LabelArch,
|
||||
|
||||
labelZoneFailureDomainGA,
|
||||
labelZoneRegionGA,
|
||||
labelInstanceTypeGA,
|
||||
)
|
||||
|
||||
var kubeletLabelNamespaces = sets.NewString(
|
||||
v1.LabelNamespaceSuffixKubelet,
|
||||
v1.LabelNamespaceSuffixNode,
|
||||
)
|
||||
|
||||
// KubeletLabels returns the list of label keys kubelets are allowed to set on their own Node objects
|
||||
func KubeletLabels() []string {
|
||||
return kubeletLabels.List()
|
||||
}
|
||||
|
||||
// KubeletLabelNamespaces returns the list of label key namespaces kubelets are allowed to set on their own Node objects
|
||||
func KubeletLabelNamespaces() []string {
|
||||
return kubeletLabelNamespaces.List()
|
||||
}
|
||||
|
||||
// IsKubeletLabel returns true if the label key is one that kubelets are allowed to set on their own Node object.
|
||||
// This checks if the key is in the KubeletLabels() list, or has a namespace in the KubeletLabelNamespaces() list.
|
||||
func IsKubeletLabel(key string) bool {
|
||||
if kubeletLabels.Has(key) {
|
||||
return true
|
||||
}
|
||||
|
||||
namespace := getLabelNamespace(key)
|
||||
for allowedNamespace := range kubeletLabelNamespaces {
|
||||
if namespace == allowedNamespace || strings.HasSuffix(namespace, "."+allowedNamespace) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func getLabelNamespace(key string) string {
|
||||
if parts := strings.SplitN(key, "/", 2); len(parts) == 2 {
|
||||
return parts[0]
|
||||
}
|
||||
return ""
|
||||
}
|
199
vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go
generated
vendored
Normal file
199
vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// Cache stores the PodStatus for the pods. It represents *all* the visible
|
||||
// pods/containers in the container runtime. All cache entries are at least as
|
||||
// new or newer than the global timestamp (set by UpdateTime()), while
|
||||
// individual entries may be slightly newer than the global timestamp. If a pod
|
||||
// has no states known by the runtime, Cache returns an empty PodStatus object
|
||||
// with ID populated.
|
||||
//
|
||||
// Cache provides two methods to retrive the PodStatus: the non-blocking Get()
|
||||
// and the blocking GetNewerThan() method. The component responsible for
|
||||
// populating the cache is expected to call Delete() to explicitly free the
|
||||
// cache entries.
|
||||
type Cache interface {
|
||||
Get(types.UID) (*PodStatus, error)
|
||||
Set(types.UID, *PodStatus, error, time.Time)
|
||||
// GetNewerThan is a blocking call that only returns the status
|
||||
// when it is newer than the given time.
|
||||
GetNewerThan(types.UID, time.Time) (*PodStatus, error)
|
||||
Delete(types.UID)
|
||||
UpdateTime(time.Time)
|
||||
}
|
||||
|
||||
type data struct {
|
||||
// Status of the pod.
|
||||
status *PodStatus
|
||||
// Error got when trying to inspect the pod.
|
||||
err error
|
||||
// Time when the data was last modified.
|
||||
modified time.Time
|
||||
}
|
||||
|
||||
type subRecord struct {
|
||||
time time.Time
|
||||
ch chan *data
|
||||
}
|
||||
|
||||
// cache implements Cache.
|
||||
type cache struct {
|
||||
// Lock which guards all internal data structures.
|
||||
lock sync.RWMutex
|
||||
// Map that stores the pod statuses.
|
||||
pods map[types.UID]*data
|
||||
// A global timestamp represents how fresh the cached data is. All
|
||||
// cache content is at the least newer than this timestamp. Note that the
|
||||
// timestamp is nil after initialization, and will only become non-nil when
|
||||
// it is ready to serve the cached statuses.
|
||||
timestamp *time.Time
|
||||
// Map that stores the subscriber records.
|
||||
subscribers map[types.UID][]*subRecord
|
||||
}
|
||||
|
||||
// NewCache creates a pod cache.
|
||||
func NewCache() Cache {
|
||||
return &cache{pods: map[types.UID]*data{}, subscribers: map[types.UID][]*subRecord{}}
|
||||
}
|
||||
|
||||
// Get returns the PodStatus for the pod; callers are expected not to
|
||||
// modify the objects returned.
|
||||
func (c *cache) Get(id types.UID) (*PodStatus, error) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
d := c.get(id)
|
||||
return d.status, d.err
|
||||
}
|
||||
|
||||
func (c *cache) GetNewerThan(id types.UID, minTime time.Time) (*PodStatus, error) {
|
||||
ch := c.subscribe(id, minTime)
|
||||
d := <-ch
|
||||
return d.status, d.err
|
||||
}
|
||||
|
||||
// Set sets the PodStatus for the pod.
|
||||
func (c *cache) Set(id types.UID, status *PodStatus, err error, timestamp time.Time) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
defer c.notify(id, timestamp)
|
||||
c.pods[id] = &data{status: status, err: err, modified: timestamp}
|
||||
}
|
||||
|
||||
// Delete removes the entry of the pod.
|
||||
func (c *cache) Delete(id types.UID) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
delete(c.pods, id)
|
||||
}
|
||||
|
||||
// UpdateTime modifies the global timestamp of the cache and notify
|
||||
// subscribers if needed.
|
||||
func (c *cache) UpdateTime(timestamp time.Time) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
c.timestamp = ×tamp
|
||||
// Notify all the subscribers if the condition is met.
|
||||
for id := range c.subscribers {
|
||||
c.notify(id, *c.timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
func makeDefaultData(id types.UID) *data {
|
||||
return &data{status: &PodStatus{ID: id}, err: nil}
|
||||
}
|
||||
|
||||
func (c *cache) get(id types.UID) *data {
|
||||
d, ok := c.pods[id]
|
||||
if !ok {
|
||||
// Cache should store *all* pod/container information known by the
|
||||
// container runtime. A cache miss indicates that there are no states
|
||||
// regarding the pod last time we queried the container runtime.
|
||||
// What this *really* means is that there are no visible pod/containers
|
||||
// associated with this pod. Simply return an default (mostly empty)
|
||||
// PodStatus to reflect this.
|
||||
return makeDefaultData(id)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// getIfNewerThan returns the data it is newer than the given time.
|
||||
// Otherwise, it returns nil. The caller should acquire the lock.
|
||||
func (c *cache) getIfNewerThan(id types.UID, minTime time.Time) *data {
|
||||
d, ok := c.pods[id]
|
||||
globalTimestampIsNewer := (c.timestamp != nil && c.timestamp.After(minTime))
|
||||
if !ok && globalTimestampIsNewer {
|
||||
// Status is not cached, but the global timestamp is newer than
|
||||
// minTime, return the default status.
|
||||
return makeDefaultData(id)
|
||||
}
|
||||
if ok && (d.modified.After(minTime) || globalTimestampIsNewer) {
|
||||
// Status is cached, return status if either of the following is true.
|
||||
// * status was modified after minTime
|
||||
// * the global timestamp of the cache is newer than minTime.
|
||||
return d
|
||||
}
|
||||
// The pod status is not ready.
|
||||
return nil
|
||||
}
|
||||
|
||||
// notify sends notifications for pod with the given id, if the requirements
|
||||
// are met. Note that the caller should acquire the lock.
|
||||
func (c *cache) notify(id types.UID, timestamp time.Time) {
|
||||
list, ok := c.subscribers[id]
|
||||
if !ok {
|
||||
// No one to notify.
|
||||
return
|
||||
}
|
||||
newList := []*subRecord{}
|
||||
for i, r := range list {
|
||||
if timestamp.Before(r.time) {
|
||||
// Doesn't meet the time requirement; keep the record.
|
||||
newList = append(newList, list[i])
|
||||
continue
|
||||
}
|
||||
r.ch <- c.get(id)
|
||||
close(r.ch)
|
||||
}
|
||||
if len(newList) == 0 {
|
||||
delete(c.subscribers, id)
|
||||
} else {
|
||||
c.subscribers[id] = newList
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cache) subscribe(id types.UID, timestamp time.Time) chan *data {
|
||||
ch := make(chan *data, 1)
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
d := c.getIfNewerThan(id, timestamp)
|
||||
if d != nil {
|
||||
// If the cache entry is ready, send the data and return immediately.
|
||||
ch <- d
|
||||
return ch
|
||||
}
|
||||
// Add the subscription record.
|
||||
c.subscribers[id] = append(c.subscribers[id], &subRecord{time: timestamp, ch: ch})
|
||||
return ch
|
||||
}
|
87
vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go
generated
vendored
Normal file
87
vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright 2014 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 container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// Specified a policy for garbage collecting containers.
|
||||
type ContainerGCPolicy struct {
|
||||
// Minimum age at which a container can be garbage collected, zero for no limit.
|
||||
MinAge time.Duration
|
||||
|
||||
// Max number of dead containers any single pod (UID, container name) pair is
|
||||
// allowed to have, less than zero for no limit.
|
||||
MaxPerPodContainer int
|
||||
|
||||
// Max number of total dead containers, less than zero for no limit.
|
||||
MaxContainers int
|
||||
}
|
||||
|
||||
// Manages garbage collection of dead containers.
|
||||
//
|
||||
// Implementation is thread-compatible.
|
||||
type ContainerGC interface {
|
||||
// Garbage collect containers.
|
||||
GarbageCollect() error
|
||||
// Deletes all unused containers, including containers belonging to pods that are terminated but not deleted
|
||||
DeleteAllUnusedContainers() error
|
||||
}
|
||||
|
||||
// SourcesReadyProvider knows how to determine if configuration sources are ready
|
||||
type SourcesReadyProvider interface {
|
||||
// AllReady returns true if the currently configured sources have all been seen.
|
||||
AllReady() bool
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Preferentially remove pod infra containers.
|
||||
type realContainerGC struct {
|
||||
// Container runtime
|
||||
runtime Runtime
|
||||
|
||||
// Policy for garbage collection.
|
||||
policy ContainerGCPolicy
|
||||
|
||||
// sourcesReadyProvider provides the readiness of kubelet configuration sources.
|
||||
sourcesReadyProvider SourcesReadyProvider
|
||||
}
|
||||
|
||||
// New ContainerGC instance with the specified policy.
|
||||
func NewContainerGC(runtime Runtime, policy ContainerGCPolicy, sourcesReadyProvider SourcesReadyProvider) (ContainerGC, error) {
|
||||
if policy.MinAge < 0 {
|
||||
return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge)
|
||||
}
|
||||
|
||||
return &realContainerGC{
|
||||
runtime: runtime,
|
||||
policy: policy,
|
||||
sourcesReadyProvider: sourcesReadyProvider,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cgc *realContainerGC) GarbageCollect() error {
|
||||
return cgc.runtime.GarbageCollect(cgc.policy, cgc.sourcesReadyProvider.AllReady(), false)
|
||||
}
|
||||
|
||||
func (cgc *realContainerGC) DeleteAllUnusedContainers() error {
|
||||
klog.Infof("attempting to delete unused containers")
|
||||
return cgc.runtime.GarbageCollect(cgc.policy, cgc.sourcesReadyProvider.AllReady(), true)
|
||||
}
|
60
vendor/k8s.io/kubernetes/pkg/kubelet/container/container_reference_manager.go
generated
vendored
Normal file
60
vendor/k8s.io/kubernetes/pkg/kubelet/container/container_reference_manager.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// RefManager manages the references for the containers.
|
||||
// The references are used for reporting events such as creation,
|
||||
// failure, etc. This manager is thread-safe, no locks are necessary
|
||||
// for the caller.
|
||||
type RefManager struct {
|
||||
sync.RWMutex
|
||||
containerIDToRef map[ContainerID]*v1.ObjectReference
|
||||
}
|
||||
|
||||
// NewRefManager creates and returns a container reference manager
|
||||
// with empty contents.
|
||||
func NewRefManager() *RefManager {
|
||||
return &RefManager{containerIDToRef: make(map[ContainerID]*v1.ObjectReference)}
|
||||
}
|
||||
|
||||
// SetRef stores a reference to a pod's container, associating it with the given container ID.
|
||||
func (c *RefManager) SetRef(id ContainerID, ref *v1.ObjectReference) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
c.containerIDToRef[id] = ref
|
||||
}
|
||||
|
||||
// ClearRef forgets the given container id and its associated container reference.
|
||||
func (c *RefManager) ClearRef(id ContainerID) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
delete(c.containerIDToRef, id)
|
||||
}
|
||||
|
||||
// GetRef returns the container reference of the given ID, or (nil, false) if none is stored.
|
||||
func (c *RefManager) GetRef(id ContainerID) (ref *v1.ObjectReference, ok bool) {
|
||||
c.RLock()
|
||||
defer c.RUnlock()
|
||||
ref, ok = c.containerIDToRef[id]
|
||||
return ref, ok
|
||||
}
|
335
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go
generated
vendored
Normal file
335
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go
generated
vendored
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/tools/record"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||
"k8s.io/kubernetes/third_party/forked/golang/expansion"
|
||||
)
|
||||
|
||||
// HandlerRunner runs a lifecycle handler for a container.
|
||||
type HandlerRunner interface {
|
||||
Run(containerID ContainerID, pod *v1.Pod, container *v1.Container, handler *v1.Handler) (string, error)
|
||||
}
|
||||
|
||||
// RuntimeHelper wraps kubelet to make container runtime
|
||||
// able to get necessary informations like the RunContainerOptions, DNS settings, Host IP.
|
||||
type RuntimeHelper interface {
|
||||
GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, cleanupAction func(), err error)
|
||||
GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error)
|
||||
// GetPodCgroupParent returns the CgroupName identifier, and its literal cgroupfs form on the host
|
||||
// of a pod.
|
||||
GetPodCgroupParent(pod *v1.Pod) string
|
||||
GetPodDir(podUID types.UID) string
|
||||
GeneratePodHostNameAndDomain(pod *v1.Pod) (hostname string, hostDomain string, err error)
|
||||
// GetExtraSupplementalGroupsForPod returns a list of the extra
|
||||
// supplemental groups for the Pod. These extra supplemental groups come
|
||||
// from annotations on persistent volumes that the pod depends on.
|
||||
GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64
|
||||
}
|
||||
|
||||
// ShouldContainerBeRestarted checks whether a container needs to be restarted.
|
||||
// TODO(yifan): Think about how to refactor this.
|
||||
func ShouldContainerBeRestarted(container *v1.Container, pod *v1.Pod, podStatus *PodStatus) bool {
|
||||
// Get latest container status.
|
||||
status := podStatus.FindContainerStatusByName(container.Name)
|
||||
// If the container was never started before, we should start it.
|
||||
// NOTE(random-liu): If all historical containers were GC'd, we'll also return true here.
|
||||
if status == nil {
|
||||
return true
|
||||
}
|
||||
// Check whether container is running
|
||||
if status.State == ContainerStateRunning {
|
||||
return false
|
||||
}
|
||||
// Always restart container in the unknown, or in the created state.
|
||||
if status.State == ContainerStateUnknown || status.State == ContainerStateCreated {
|
||||
return true
|
||||
}
|
||||
// Check RestartPolicy for dead container
|
||||
if pod.Spec.RestartPolicy == v1.RestartPolicyNever {
|
||||
klog.V(4).Infof("Already ran container %q of pod %q, do nothing", container.Name, format.Pod(pod))
|
||||
return false
|
||||
}
|
||||
if pod.Spec.RestartPolicy == v1.RestartPolicyOnFailure {
|
||||
// Check the exit code.
|
||||
if status.ExitCode == 0 {
|
||||
klog.V(4).Infof("Already successfully ran container %q of pod %q, do nothing", container.Name, format.Pod(pod))
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HashContainer returns the hash of the container. It is used to compare
|
||||
// the running container with its desired spec.
|
||||
func HashContainer(container *v1.Container) uint64 {
|
||||
hash := fnv.New32a()
|
||||
hashutil.DeepHashObject(hash, *container)
|
||||
return uint64(hash.Sum32())
|
||||
}
|
||||
|
||||
// EnvVarsToMap constructs a map of environment name to value from a slice
|
||||
// of env vars.
|
||||
func EnvVarsToMap(envs []EnvVar) map[string]string {
|
||||
result := map[string]string{}
|
||||
for _, env := range envs {
|
||||
result[env.Name] = env.Value
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// V1EnvVarsToMap constructs a map of environment name to value from a slice
|
||||
// of env vars.
|
||||
func V1EnvVarsToMap(envs []v1.EnvVar) map[string]string {
|
||||
result := map[string]string{}
|
||||
for _, env := range envs {
|
||||
result[env.Name] = env.Value
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ExpandContainerCommandOnlyStatic substitutes only static environment variable values from the
|
||||
// container environment definitions. This does *not* include valueFrom substitutions.
|
||||
// TODO: callers should use ExpandContainerCommandAndArgs with a fully resolved list of environment.
|
||||
func ExpandContainerCommandOnlyStatic(containerCommand []string, envs []v1.EnvVar) (command []string) {
|
||||
mapping := expansion.MappingFuncFor(V1EnvVarsToMap(envs))
|
||||
if len(containerCommand) != 0 {
|
||||
for _, cmd := range containerCommand {
|
||||
command = append(command, expansion.Expand(cmd, mapping))
|
||||
}
|
||||
}
|
||||
return command
|
||||
}
|
||||
|
||||
func ExpandContainerVolumeMounts(mount v1.VolumeMount, envs []EnvVar) (string, error) {
|
||||
|
||||
envmap := EnvVarsToMap(envs)
|
||||
missingKeys := sets.NewString()
|
||||
expanded := expansion.Expand(mount.SubPathExpr, func(key string) string {
|
||||
value, ok := envmap[key]
|
||||
if !ok || len(value) == 0 {
|
||||
missingKeys.Insert(key)
|
||||
}
|
||||
return value
|
||||
})
|
||||
|
||||
if len(missingKeys) > 0 {
|
||||
return "", fmt.Errorf("missing value for %s", strings.Join(missingKeys.List(), ", "))
|
||||
}
|
||||
return expanded, nil
|
||||
}
|
||||
|
||||
func ExpandContainerCommandAndArgs(container *v1.Container, envs []EnvVar) (command []string, args []string) {
|
||||
mapping := expansion.MappingFuncFor(EnvVarsToMap(envs))
|
||||
|
||||
if len(container.Command) != 0 {
|
||||
for _, cmd := range container.Command {
|
||||
command = append(command, expansion.Expand(cmd, mapping))
|
||||
}
|
||||
}
|
||||
|
||||
if len(container.Args) != 0 {
|
||||
for _, arg := range container.Args {
|
||||
args = append(args, expansion.Expand(arg, mapping))
|
||||
}
|
||||
}
|
||||
|
||||
return command, args
|
||||
}
|
||||
|
||||
// Create an event recorder to record object's event except implicitly required container's, like infra container.
|
||||
func FilterEventRecorder(recorder record.EventRecorder) record.EventRecorder {
|
||||
return &innerEventRecorder{
|
||||
recorder: recorder,
|
||||
}
|
||||
}
|
||||
|
||||
type innerEventRecorder struct {
|
||||
recorder record.EventRecorder
|
||||
}
|
||||
|
||||
func (irecorder *innerEventRecorder) shouldRecordEvent(object runtime.Object) (*v1.ObjectReference, bool) {
|
||||
if object == nil {
|
||||
return nil, false
|
||||
}
|
||||
if ref, ok := object.(*v1.ObjectReference); ok {
|
||||
if !strings.HasPrefix(ref.FieldPath, ImplicitContainerPrefix) {
|
||||
return ref, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (irecorder *innerEventRecorder) Event(object runtime.Object, eventtype, reason, message string) {
|
||||
if ref, ok := irecorder.shouldRecordEvent(object); ok {
|
||||
irecorder.recorder.Event(ref, eventtype, reason, message)
|
||||
}
|
||||
}
|
||||
|
||||
func (irecorder *innerEventRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
if ref, ok := irecorder.shouldRecordEvent(object); ok {
|
||||
irecorder.recorder.Eventf(ref, eventtype, reason, messageFmt, args...)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (irecorder *innerEventRecorder) PastEventf(object runtime.Object, timestamp metav1.Time, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
if ref, ok := irecorder.shouldRecordEvent(object); ok {
|
||||
irecorder.recorder.PastEventf(ref, timestamp, eventtype, reason, messageFmt, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (irecorder *innerEventRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) {
|
||||
if ref, ok := irecorder.shouldRecordEvent(object); ok {
|
||||
irecorder.recorder.AnnotatedEventf(ref, annotations, eventtype, reason, messageFmt, args...)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Pod must not be nil.
|
||||
func IsHostNetworkPod(pod *v1.Pod) bool {
|
||||
return pod.Spec.HostNetwork
|
||||
}
|
||||
|
||||
// TODO(random-liu): Convert PodStatus to running Pod, should be deprecated soon
|
||||
func ConvertPodStatusToRunningPod(runtimeName string, podStatus *PodStatus) Pod {
|
||||
runningPod := Pod{
|
||||
ID: podStatus.ID,
|
||||
Name: podStatus.Name,
|
||||
Namespace: podStatus.Namespace,
|
||||
}
|
||||
for _, containerStatus := range podStatus.ContainerStatuses {
|
||||
if containerStatus.State != ContainerStateRunning {
|
||||
continue
|
||||
}
|
||||
container := &Container{
|
||||
ID: containerStatus.ID,
|
||||
Name: containerStatus.Name,
|
||||
Image: containerStatus.Image,
|
||||
ImageID: containerStatus.ImageID,
|
||||
Hash: containerStatus.Hash,
|
||||
State: containerStatus.State,
|
||||
}
|
||||
runningPod.Containers = append(runningPod.Containers, container)
|
||||
}
|
||||
|
||||
// Populate sandboxes in kubecontainer.Pod
|
||||
for _, sandbox := range podStatus.SandboxStatuses {
|
||||
runningPod.Sandboxes = append(runningPod.Sandboxes, &Container{
|
||||
ID: ContainerID{Type: runtimeName, ID: sandbox.Id},
|
||||
State: SandboxToContainerState(sandbox.State),
|
||||
})
|
||||
}
|
||||
return runningPod
|
||||
}
|
||||
|
||||
// SandboxToContainerState converts runtimeapi.PodSandboxState to
|
||||
// kubecontainer.ContainerState.
|
||||
// This is only needed because we need to return sandboxes as if they were
|
||||
// kubecontainer.Containers to avoid substantial changes to PLEG.
|
||||
// TODO: Remove this once it becomes obsolete.
|
||||
func SandboxToContainerState(state runtimeapi.PodSandboxState) ContainerState {
|
||||
switch state {
|
||||
case runtimeapi.PodSandboxState_SANDBOX_READY:
|
||||
return ContainerStateRunning
|
||||
case runtimeapi.PodSandboxState_SANDBOX_NOTREADY:
|
||||
return ContainerStateExited
|
||||
}
|
||||
return ContainerStateUnknown
|
||||
}
|
||||
|
||||
// FormatPod returns a string representing a pod in a human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func FormatPod(pod *Pod) string {
|
||||
// Use underscore as the delimiter because it is not allowed in pod name
|
||||
// (DNS subdomain format), while allowed in the container name format.
|
||||
return fmt.Sprintf("%s_%s(%s)", pod.Name, pod.Namespace, pod.ID)
|
||||
}
|
||||
|
||||
// GetContainerSpec gets the container spec by containerName.
|
||||
func GetContainerSpec(pod *v1.Pod, containerName string) *v1.Container {
|
||||
for i, c := range pod.Spec.Containers {
|
||||
if containerName == c.Name {
|
||||
return &pod.Spec.Containers[i]
|
||||
}
|
||||
}
|
||||
for i, c := range pod.Spec.InitContainers {
|
||||
if containerName == c.Name {
|
||||
return &pod.Spec.InitContainers[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasPrivilegedContainer returns true if any of the containers in the pod are privileged.
|
||||
func HasPrivilegedContainer(pod *v1.Pod) bool {
|
||||
for _, c := range append(pod.Spec.Containers, pod.Spec.InitContainers...) {
|
||||
if c.SecurityContext != nil &&
|
||||
c.SecurityContext.Privileged != nil &&
|
||||
*c.SecurityContext.Privileged {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MakePortMappings creates internal port mapping from api port mapping.
|
||||
func MakePortMappings(container *v1.Container) (ports []PortMapping) {
|
||||
names := make(map[string]struct{})
|
||||
for _, p := range container.Ports {
|
||||
pm := PortMapping{
|
||||
HostPort: int(p.HostPort),
|
||||
ContainerPort: int(p.ContainerPort),
|
||||
Protocol: p.Protocol,
|
||||
HostIP: p.HostIP,
|
||||
}
|
||||
|
||||
// We need to create some default port name if it's not specified, since
|
||||
// this is necessary for rkt.
|
||||
// http://issue.k8s.io/7710
|
||||
if p.Name == "" {
|
||||
pm.Name = fmt.Sprintf("%s-%s:%d", container.Name, p.Protocol, p.ContainerPort)
|
||||
} else {
|
||||
pm.Name = fmt.Sprintf("%s-%s", container.Name, p.Name)
|
||||
}
|
||||
|
||||
// Protect against exposing the same protocol-port more than once in a container.
|
||||
if _, ok := names[pm.Name]; ok {
|
||||
klog.Warningf("Port name conflicted, %q is defined more than once", pm.Name)
|
||||
continue
|
||||
}
|
||||
ports = append(ports, pm)
|
||||
names[pm.Name] = struct{}{}
|
||||
}
|
||||
return
|
||||
}
|
107
vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go
generated
vendored
Normal file
107
vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// OSInterface collects system level operations that need to be mocked out
|
||||
// during tests.
|
||||
type OSInterface interface {
|
||||
MkdirAll(path string, perm os.FileMode) error
|
||||
Symlink(oldname string, newname string) error
|
||||
Stat(path string) (os.FileInfo, error)
|
||||
Remove(path string) error
|
||||
RemoveAll(path string) error
|
||||
Create(path string) (*os.File, error)
|
||||
Chmod(path string, perm os.FileMode) error
|
||||
Hostname() (name string, err error)
|
||||
Chtimes(path string, atime time.Time, mtime time.Time) error
|
||||
Pipe() (r *os.File, w *os.File, err error)
|
||||
ReadDir(dirname string) ([]os.FileInfo, error)
|
||||
Glob(pattern string) ([]string, error)
|
||||
}
|
||||
|
||||
// RealOS is used to dispatch the real system level operations.
|
||||
type RealOS struct{}
|
||||
|
||||
// MkdirAll will call os.MkdirAll to create a directory.
|
||||
func (RealOS) MkdirAll(path string, perm os.FileMode) error {
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
// Symlink will call os.Symlink to create a symbolic link.
|
||||
func (RealOS) Symlink(oldname string, newname string) error {
|
||||
return os.Symlink(oldname, newname)
|
||||
}
|
||||
|
||||
// Stat will call os.Stat to get the FileInfo for a given path
|
||||
func (RealOS) Stat(path string) (os.FileInfo, error) {
|
||||
return os.Stat(path)
|
||||
}
|
||||
|
||||
// Remove will call os.Remove to remove the path.
|
||||
func (RealOS) Remove(path string) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
// RemoveAll will call os.RemoveAll to remove the path and its children.
|
||||
func (RealOS) RemoveAll(path string) error {
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
|
||||
// Create will call os.Create to create and return a file
|
||||
// at path.
|
||||
func (RealOS) Create(path string) (*os.File, error) {
|
||||
return os.Create(path)
|
||||
}
|
||||
|
||||
// Chmod will change the permissions on the specified path or return
|
||||
// an error.
|
||||
func (RealOS) Chmod(path string, perm os.FileMode) error {
|
||||
return os.Chmod(path, perm)
|
||||
}
|
||||
|
||||
// Hostname will call os.Hostname to return the hostname.
|
||||
func (RealOS) Hostname() (name string, err error) {
|
||||
return os.Hostname()
|
||||
}
|
||||
|
||||
// Chtimes will call os.Chtimes to change the atime and mtime of the path
|
||||
func (RealOS) Chtimes(path string, atime time.Time, mtime time.Time) error {
|
||||
return os.Chtimes(path, atime, mtime)
|
||||
}
|
||||
|
||||
// Pipe will call os.Pipe to return a connected pair of pipe.
|
||||
func (RealOS) Pipe() (r *os.File, w *os.File, err error) {
|
||||
return os.Pipe()
|
||||
}
|
||||
|
||||
// ReadDir will call ioutil.ReadDir to return the files under the directory.
|
||||
func (RealOS) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(dirname)
|
||||
}
|
||||
|
||||
// Glob will call filepath.Glob to return the names of all files matching
|
||||
// pattern.
|
||||
func (RealOS) Glob(pattern string) ([]string, error) {
|
||||
return filepath.Glob(pattern)
|
||||
}
|
73
vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go
generated
vendored
Normal file
73
vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
ref "k8s.io/client-go/tools/reference"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
)
|
||||
|
||||
var ImplicitContainerPrefix string = "implicitly required container "
|
||||
|
||||
// GenerateContainerRef returns an *v1.ObjectReference which references the given container
|
||||
// within the given pod. Returns an error if the reference can't be constructed or the
|
||||
// container doesn't actually belong to the pod.
|
||||
//
|
||||
// This function will return an error if the provided Pod does not have a selfLink,
|
||||
// but we expect selfLink to be populated at all call sites for the function.
|
||||
func GenerateContainerRef(pod *v1.Pod, container *v1.Container) (*v1.ObjectReference, error) {
|
||||
fieldPath, err := fieldPath(pod, container)
|
||||
if err != nil {
|
||||
// TODO: figure out intelligent way to refer to containers that we implicitly
|
||||
// start (like the pod infra container). This is not a good way, ugh.
|
||||
fieldPath = ImplicitContainerPrefix + container.Name
|
||||
}
|
||||
ref, err := ref.GetPartialReference(legacyscheme.Scheme, pod, fieldPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
// fieldPath returns a fieldPath locating container within pod.
|
||||
// Returns an error if the container isn't part of the pod.
|
||||
func fieldPath(pod *v1.Pod, container *v1.Container) (string, error) {
|
||||
for i := range pod.Spec.Containers {
|
||||
here := &pod.Spec.Containers[i]
|
||||
if here.Name == container.Name {
|
||||
if here.Name == "" {
|
||||
return fmt.Sprintf("spec.containers[%d]", i), nil
|
||||
} else {
|
||||
return fmt.Sprintf("spec.containers{%s}", here.Name), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range pod.Spec.InitContainers {
|
||||
here := &pod.Spec.InitContainers[i]
|
||||
if here.Name == container.Name {
|
||||
if here.Name == "" {
|
||||
return fmt.Sprintf("spec.initContainers[%d]", i), nil
|
||||
} else {
|
||||
return fmt.Sprintf("spec.initContainers{%s}", here.Name), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("container %#v not found in pod %#v", container, pod)
|
||||
}
|
42
vendor/k8s.io/kubernetes/pkg/kubelet/container/resize.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/pkg/kubelet/container/resize.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
)
|
||||
|
||||
// handleResizing spawns a goroutine that processes the resize channel, calling resizeFunc for each
|
||||
// remotecommand.TerminalSize received from the channel. The resize channel must be closed elsewhere to stop the
|
||||
// goroutine.
|
||||
func HandleResizing(resize <-chan remotecommand.TerminalSize, resizeFunc func(size remotecommand.TerminalSize)) {
|
||||
if resize == nil {
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer runtime.HandleCrash()
|
||||
|
||||
for size := range resize {
|
||||
if size.Height < 1 || size.Width < 1 {
|
||||
continue
|
||||
}
|
||||
resizeFunc(size)
|
||||
}
|
||||
}()
|
||||
}
|
636
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go
generated
vendored
Normal file
636
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go
generated
vendored
Normal file
@ -0,0 +1,636 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
||||
type Version interface {
|
||||
// Compare compares two versions of the runtime. On success it returns -1
|
||||
// if the version is less than the other, 1 if it is greater than the other,
|
||||
// or 0 if they are equal.
|
||||
Compare(other string) (int, error)
|
||||
// String returns a string that represents the version.
|
||||
String() string
|
||||
}
|
||||
|
||||
// ImageSpec is an internal representation of an image. Currently, it wraps the
|
||||
// value of a Container's Image field, but in the future it will include more detailed
|
||||
// information about the different image types.
|
||||
type ImageSpec struct {
|
||||
Image string
|
||||
}
|
||||
|
||||
// ImageStats contains statistics about all the images currently available.
|
||||
type ImageStats struct {
|
||||
// Total amount of storage consumed by existing images.
|
||||
TotalStorageBytes uint64
|
||||
}
|
||||
|
||||
// Runtime interface defines the interfaces that should be implemented
|
||||
// by a container runtime.
|
||||
// Thread safety is required from implementations of this interface.
|
||||
type Runtime interface {
|
||||
// Type returns the type of the container runtime.
|
||||
Type() string
|
||||
|
||||
// Version returns the version information of the container runtime.
|
||||
Version() (Version, error)
|
||||
|
||||
// APIVersion returns the cached API version information of the container
|
||||
// runtime. Implementation is expected to update this cache periodically.
|
||||
// This may be different from the runtime engine's version.
|
||||
// TODO(random-liu): We should fold this into Version()
|
||||
APIVersion() (Version, error)
|
||||
// Status returns the status of the runtime. An error is returned if the Status
|
||||
// function itself fails, nil otherwise.
|
||||
Status() (*RuntimeStatus, error)
|
||||
// GetPods returns a list of containers grouped by pods. The boolean parameter
|
||||
// specifies whether the runtime returns all containers including those already
|
||||
// exited and dead containers (used for garbage collection).
|
||||
GetPods(all bool) ([]*Pod, error)
|
||||
// GarbageCollect removes dead containers using the specified container gc policy
|
||||
// If allSourcesReady is not true, it means that kubelet doesn't have the
|
||||
// complete list of pods from all avialble sources (e.g., apiserver, http,
|
||||
// file). In this case, garbage collector should refrain itself from aggressive
|
||||
// behavior such as removing all containers of unrecognized pods (yet).
|
||||
// If evictNonDeletedPods is set to true, containers and sandboxes belonging to pods
|
||||
// that are terminated, but not deleted will be evicted. Otherwise, only deleted pods will be GC'd.
|
||||
// TODO: Revisit this method and make it cleaner.
|
||||
GarbageCollect(gcPolicy ContainerGCPolicy, allSourcesReady bool, evictNonDeletedPods bool) error
|
||||
// Syncs the running pod into the desired pod.
|
||||
SyncPod(pod *v1.Pod, podStatus *PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) PodSyncResult
|
||||
// KillPod kills all the containers of a pod. Pod may be nil, running pod must not be.
|
||||
// TODO(random-liu): Return PodSyncResult in KillPod.
|
||||
// gracePeriodOverride if specified allows the caller to override the pod default grace period.
|
||||
// only hard kill paths are allowed to specify a gracePeriodOverride in the kubelet in order to not corrupt user data.
|
||||
// it is useful when doing SIGKILL for hard eviction scenarios, or max grace period during soft eviction scenarios.
|
||||
KillPod(pod *v1.Pod, runningPod Pod, gracePeriodOverride *int64) error
|
||||
// GetPodStatus retrieves the status of the pod, including the
|
||||
// information of all containers in the pod that are visible in Runtime.
|
||||
GetPodStatus(uid types.UID, name, namespace string) (*PodStatus, error)
|
||||
// TODO(vmarmol): Unify pod and containerID args.
|
||||
// GetContainerLogs returns logs of a specific container. By
|
||||
// default, it returns a snapshot of the container log. Set 'follow' to true to
|
||||
// stream the log. Set 'follow' to false and specify the number of lines (e.g.
|
||||
// "100" or "all") to tail the log.
|
||||
GetContainerLogs(ctx context.Context, pod *v1.Pod, containerID ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) (err error)
|
||||
// Delete a container. If the container is still running, an error is returned.
|
||||
DeleteContainer(containerID ContainerID) error
|
||||
// ImageService provides methods to image-related methods.
|
||||
ImageService
|
||||
// UpdatePodCIDR sends a new podCIDR to the runtime.
|
||||
// This method just proxies a new runtimeConfig with the updated
|
||||
// CIDR value down to the runtime shim.
|
||||
UpdatePodCIDR(podCIDR string) error
|
||||
}
|
||||
|
||||
// StreamingRuntime is the interface implemented by runtimes that handle the serving of the
|
||||
// streaming calls (exec/attach/port-forward) themselves. In this case, Kubelet should redirect to
|
||||
// the runtime server.
|
||||
type StreamingRuntime interface {
|
||||
GetExec(id ContainerID, cmd []string, stdin, stdout, stderr, tty bool) (*url.URL, error)
|
||||
GetAttach(id ContainerID, stdin, stdout, stderr, tty bool) (*url.URL, error)
|
||||
GetPortForward(podName, podNamespace string, podUID types.UID, ports []int32) (*url.URL, error)
|
||||
}
|
||||
|
||||
type ImageService interface {
|
||||
// PullImage pulls an image from the network to local storage using the supplied
|
||||
// secrets if necessary. It returns a reference (digest or ID) to the pulled image.
|
||||
PullImage(image ImageSpec, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error)
|
||||
// GetImageRef gets the reference (digest or ID) of the image which has already been in
|
||||
// the local storage. It returns ("", nil) if the image isn't in the local storage.
|
||||
GetImageRef(image ImageSpec) (string, error)
|
||||
// Gets all images currently on the machine.
|
||||
ListImages() ([]Image, error)
|
||||
// Removes the specified image.
|
||||
RemoveImage(image ImageSpec) error
|
||||
// Returns Image statistics.
|
||||
ImageStats() (*ImageStats, error)
|
||||
}
|
||||
|
||||
type ContainerAttacher interface {
|
||||
AttachContainer(id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) (err error)
|
||||
}
|
||||
|
||||
type ContainerCommandRunner interface {
|
||||
// RunInContainer synchronously executes the command in the container, and returns the output.
|
||||
// If the command completes with a non-0 exit code, a k8s.io/utils/exec.ExitError will be returned.
|
||||
RunInContainer(id ContainerID, cmd []string, timeout time.Duration) ([]byte, error)
|
||||
}
|
||||
|
||||
// Pod is a group of containers.
|
||||
type Pod struct {
|
||||
// The ID of the pod, which can be used to retrieve a particular pod
|
||||
// from the pod list returned by GetPods().
|
||||
ID types.UID
|
||||
// The name and namespace of the pod, which is readable by human.
|
||||
Name string
|
||||
Namespace string
|
||||
// List of containers that belongs to this pod. It may contain only
|
||||
// running containers, or mixed with dead ones (when GetPods(true)).
|
||||
Containers []*Container
|
||||
// List of sandboxes associated with this pod. The sandboxes are converted
|
||||
// to Container temporariliy to avoid substantial changes to other
|
||||
// components. This is only populated by kuberuntime.
|
||||
// TODO: use the runtimeApi.PodSandbox type directly.
|
||||
Sandboxes []*Container
|
||||
}
|
||||
|
||||
// PodPair contains both runtime#Pod and api#Pod
|
||||
type PodPair struct {
|
||||
// APIPod is the v1.Pod
|
||||
APIPod *v1.Pod
|
||||
// RunningPod is the pod defined in pkg/kubelet/container/runtime#Pod
|
||||
RunningPod *Pod
|
||||
}
|
||||
|
||||
// ContainerID is a type that identifies a container.
|
||||
type ContainerID struct {
|
||||
// The type of the container runtime. e.g. 'docker'.
|
||||
Type string
|
||||
// The identification of the container, this is comsumable by
|
||||
// the underlying container runtime. (Note that the container
|
||||
// runtime interface still takes the whole struct as input).
|
||||
ID string
|
||||
}
|
||||
|
||||
func BuildContainerID(typ, ID string) ContainerID {
|
||||
return ContainerID{Type: typ, ID: ID}
|
||||
}
|
||||
|
||||
// Convenience method for creating a ContainerID from an ID string.
|
||||
func ParseContainerID(containerID string) ContainerID {
|
||||
var id ContainerID
|
||||
if err := id.ParseString(containerID); err != nil {
|
||||
klog.Error(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (c *ContainerID) ParseString(data string) error {
|
||||
// Trim the quotes and split the type and ID.
|
||||
parts := strings.Split(strings.Trim(data, "\""), "://")
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("invalid container ID: %q", data)
|
||||
}
|
||||
c.Type, c.ID = parts[0], parts[1]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ContainerID) String() string {
|
||||
return fmt.Sprintf("%s://%s", c.Type, c.ID)
|
||||
}
|
||||
|
||||
func (c *ContainerID) IsEmpty() bool {
|
||||
return *c == ContainerID{}
|
||||
}
|
||||
|
||||
func (c *ContainerID) MarshalJSON() ([]byte, error) {
|
||||
return []byte(fmt.Sprintf("%q", c.String())), nil
|
||||
}
|
||||
|
||||
func (c *ContainerID) UnmarshalJSON(data []byte) error {
|
||||
return c.ParseString(string(data))
|
||||
}
|
||||
|
||||
// DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids
|
||||
type DockerID string
|
||||
|
||||
func (id DockerID) ContainerID() ContainerID {
|
||||
return ContainerID{
|
||||
Type: "docker",
|
||||
ID: string(id),
|
||||
}
|
||||
}
|
||||
|
||||
type ContainerState string
|
||||
|
||||
const (
|
||||
ContainerStateCreated ContainerState = "created"
|
||||
ContainerStateRunning ContainerState = "running"
|
||||
ContainerStateExited ContainerState = "exited"
|
||||
// This unknown encompasses all the states that we currently don't care.
|
||||
ContainerStateUnknown ContainerState = "unknown"
|
||||
)
|
||||
|
||||
// Container provides the runtime information for a container, such as ID, hash,
|
||||
// state of the container.
|
||||
type Container struct {
|
||||
// The ID of the container, used by the container runtime to identify
|
||||
// a container.
|
||||
ID ContainerID
|
||||
// The name of the container, which should be the same as specified by
|
||||
// v1.Container.
|
||||
Name string
|
||||
// The image name of the container, this also includes the tag of the image,
|
||||
// the expected form is "NAME:TAG".
|
||||
Image string
|
||||
// The id of the image used by the container.
|
||||
ImageID string
|
||||
// Hash of the container, used for comparison. Optional for containers
|
||||
// not managed by kubelet.
|
||||
Hash uint64
|
||||
// State is the state of the container.
|
||||
State ContainerState
|
||||
}
|
||||
|
||||
// PodStatus represents the status of the pod and its containers.
|
||||
// v1.PodStatus can be derived from examining PodStatus and v1.Pod.
|
||||
type PodStatus struct {
|
||||
// ID of the pod.
|
||||
ID types.UID
|
||||
// Name of the pod.
|
||||
Name string
|
||||
// Namespace of the pod.
|
||||
Namespace string
|
||||
// IP of the pod.
|
||||
IP string
|
||||
// Status of containers in the pod.
|
||||
ContainerStatuses []*ContainerStatus
|
||||
// Status of the pod sandbox.
|
||||
// Only for kuberuntime now, other runtime may keep it nil.
|
||||
SandboxStatuses []*runtimeapi.PodSandboxStatus
|
||||
}
|
||||
|
||||
// ContainerStatus represents the status of a container.
|
||||
type ContainerStatus struct {
|
||||
// ID of the container.
|
||||
ID ContainerID
|
||||
// Name of the container.
|
||||
Name string
|
||||
// Status of the container.
|
||||
State ContainerState
|
||||
// Creation time of the container.
|
||||
CreatedAt time.Time
|
||||
// Start time of the container.
|
||||
StartedAt time.Time
|
||||
// Finish time of the container.
|
||||
FinishedAt time.Time
|
||||
// Exit code of the container.
|
||||
ExitCode int
|
||||
// Name of the image, this also includes the tag of the image,
|
||||
// the expected form is "NAME:TAG".
|
||||
Image string
|
||||
// ID of the image.
|
||||
ImageID string
|
||||
// Hash of the container, used for comparison.
|
||||
Hash uint64
|
||||
// Number of times that the container has been restarted.
|
||||
RestartCount int
|
||||
// A string explains why container is in such a status.
|
||||
Reason string
|
||||
// Message written by the container before exiting (stored in
|
||||
// TerminationMessagePath).
|
||||
Message string
|
||||
}
|
||||
|
||||
// FindContainerStatusByName returns container status in the pod status with the given name.
|
||||
// When there are multiple containers' statuses with the same name, the first match will be returned.
|
||||
func (podStatus *PodStatus) FindContainerStatusByName(containerName string) *ContainerStatus {
|
||||
for _, containerStatus := range podStatus.ContainerStatuses {
|
||||
if containerStatus.Name == containerName {
|
||||
return containerStatus
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get container status of all the running containers in a pod
|
||||
func (podStatus *PodStatus) GetRunningContainerStatuses() []*ContainerStatus {
|
||||
runningContainerStatuses := []*ContainerStatus{}
|
||||
for _, containerStatus := range podStatus.ContainerStatuses {
|
||||
if containerStatus.State == ContainerStateRunning {
|
||||
runningContainerStatuses = append(runningContainerStatuses, containerStatus)
|
||||
}
|
||||
}
|
||||
return runningContainerStatuses
|
||||
}
|
||||
|
||||
// Basic information about a container image.
|
||||
type Image struct {
|
||||
// ID of the image.
|
||||
ID string
|
||||
// Other names by which this image is known.
|
||||
RepoTags []string
|
||||
// Digests by which this image is known.
|
||||
RepoDigests []string
|
||||
// The size of the image in bytes.
|
||||
Size int64
|
||||
}
|
||||
|
||||
type EnvVar struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
type Annotation struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
type Mount struct {
|
||||
// Name of the volume mount.
|
||||
// TODO(yifan): Remove this field, as this is not representing the unique name of the mount,
|
||||
// but the volume name only.
|
||||
Name string
|
||||
// Path of the mount within the container.
|
||||
ContainerPath string
|
||||
// Path of the mount on the host.
|
||||
HostPath string
|
||||
// Whether the mount is read-only.
|
||||
ReadOnly bool
|
||||
// Whether the mount needs SELinux relabeling
|
||||
SELinuxRelabel bool
|
||||
// Requested propagation mode
|
||||
Propagation runtimeapi.MountPropagation
|
||||
}
|
||||
|
||||
type PortMapping struct {
|
||||
// Name of the port mapping
|
||||
Name string
|
||||
// Protocol of the port mapping.
|
||||
Protocol v1.Protocol
|
||||
// The port number within the container.
|
||||
ContainerPort int
|
||||
// The port number on the host.
|
||||
HostPort int
|
||||
// The host IP.
|
||||
HostIP string
|
||||
}
|
||||
|
||||
type DeviceInfo struct {
|
||||
// Path on host for mapping
|
||||
PathOnHost string
|
||||
// Path in Container to map
|
||||
PathInContainer string
|
||||
// Cgroup permissions
|
||||
Permissions string
|
||||
}
|
||||
|
||||
// RunContainerOptions specify the options which are necessary for running containers
|
||||
type RunContainerOptions struct {
|
||||
// The environment variables list.
|
||||
Envs []EnvVar
|
||||
// The mounts for the containers.
|
||||
Mounts []Mount
|
||||
// The host devices mapped into the containers.
|
||||
Devices []DeviceInfo
|
||||
// The port mappings for the containers.
|
||||
PortMappings []PortMapping
|
||||
// The annotations for the container
|
||||
// These annotations are generated by other components (i.e.,
|
||||
// not users). Currently, only device plugins populate the annotations.
|
||||
Annotations []Annotation
|
||||
// If the container has specified the TerminationMessagePath, then
|
||||
// this directory will be used to create and mount the log file to
|
||||
// container.TerminationMessagePath
|
||||
PodContainerDir string
|
||||
// The type of container rootfs
|
||||
ReadOnly bool
|
||||
// hostname for pod containers
|
||||
Hostname string
|
||||
// EnableHostUserNamespace sets userns=host when users request host namespaces (pid, ipc, net),
|
||||
// are using non-namespaced capabilities (mknod, sys_time, sys_module), the pod contains a privileged container,
|
||||
// or using host path volumes.
|
||||
// This should only be enabled when the container runtime is performing user remapping AND if the
|
||||
// experimental behavior is desired.
|
||||
EnableHostUserNamespace bool
|
||||
}
|
||||
|
||||
// VolumeInfo contains information about the volume.
|
||||
type VolumeInfo struct {
|
||||
// Mounter is the volume's mounter
|
||||
Mounter volume.Mounter
|
||||
// BlockVolumeMapper is the Block volume's mapper
|
||||
BlockVolumeMapper volume.BlockVolumeMapper
|
||||
// SELinuxLabeled indicates whether this volume has had the
|
||||
// pod's SELinux label applied to it or not
|
||||
SELinuxLabeled bool
|
||||
// Whether the volume permission is set to read-only or not
|
||||
// This value is passed from volume.spec
|
||||
ReadOnly bool
|
||||
// Inner volume spec name, which is the PV name if used, otherwise
|
||||
// it is the same as the outer volume spec name.
|
||||
InnerVolumeSpecName string
|
||||
}
|
||||
|
||||
type VolumeMap map[string]VolumeInfo
|
||||
|
||||
// RuntimeConditionType is the types of required runtime conditions.
|
||||
type RuntimeConditionType string
|
||||
|
||||
const (
|
||||
// RuntimeReady means the runtime is up and ready to accept basic containers.
|
||||
RuntimeReady RuntimeConditionType = "RuntimeReady"
|
||||
// NetworkReady means the runtime network is up and ready to accept containers which require network.
|
||||
NetworkReady RuntimeConditionType = "NetworkReady"
|
||||
)
|
||||
|
||||
// RuntimeStatus contains the status of the runtime.
|
||||
type RuntimeStatus struct {
|
||||
// Conditions is an array of current observed runtime conditions.
|
||||
Conditions []RuntimeCondition
|
||||
}
|
||||
|
||||
// GetRuntimeCondition gets a specified runtime condition from the runtime status.
|
||||
func (r *RuntimeStatus) GetRuntimeCondition(t RuntimeConditionType) *RuntimeCondition {
|
||||
for i := range r.Conditions {
|
||||
c := &r.Conditions[i]
|
||||
if c.Type == t {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String formats the runtime status into human readable string.
|
||||
func (s *RuntimeStatus) String() string {
|
||||
var ss []string
|
||||
for _, c := range s.Conditions {
|
||||
ss = append(ss, c.String())
|
||||
}
|
||||
return fmt.Sprintf("Runtime Conditions: %s", strings.Join(ss, ", "))
|
||||
}
|
||||
|
||||
// RuntimeCondition contains condition information for the runtime.
|
||||
type RuntimeCondition struct {
|
||||
// Type of runtime condition.
|
||||
Type RuntimeConditionType
|
||||
// Status of the condition, one of true/false.
|
||||
Status bool
|
||||
// Reason is brief reason for the condition's last transition.
|
||||
Reason string
|
||||
// Message is human readable message indicating details about last transition.
|
||||
Message string
|
||||
}
|
||||
|
||||
// String formats the runtime condition into human readable string.
|
||||
func (c *RuntimeCondition) String() string {
|
||||
return fmt.Sprintf("%s=%t reason:%s message:%s", c.Type, c.Status, c.Reason, c.Message)
|
||||
}
|
||||
|
||||
type Pods []*Pod
|
||||
|
||||
// FindPodByID finds and returns a pod in the pod list by UID. It will return an empty pod
|
||||
// if not found.
|
||||
func (p Pods) FindPodByID(podUID types.UID) Pod {
|
||||
for i := range p {
|
||||
if p[i].ID == podUID {
|
||||
return *p[i]
|
||||
}
|
||||
}
|
||||
return Pod{}
|
||||
}
|
||||
|
||||
// FindPodByFullName finds and returns a pod in the pod list by the full name.
|
||||
// It will return an empty pod if not found.
|
||||
func (p Pods) FindPodByFullName(podFullName string) Pod {
|
||||
for i := range p {
|
||||
if BuildPodFullName(p[i].Name, p[i].Namespace) == podFullName {
|
||||
return *p[i]
|
||||
}
|
||||
}
|
||||
return Pod{}
|
||||
}
|
||||
|
||||
// FindPod combines FindPodByID and FindPodByFullName, it finds and returns a pod in the
|
||||
// pod list either by the full name or the pod ID. It will return an empty pod
|
||||
// if not found.
|
||||
func (p Pods) FindPod(podFullName string, podUID types.UID) Pod {
|
||||
if len(podFullName) > 0 {
|
||||
return p.FindPodByFullName(podFullName)
|
||||
}
|
||||
return p.FindPodByID(podUID)
|
||||
}
|
||||
|
||||
// FindContainerByName returns a container in the pod with the given name.
|
||||
// When there are multiple containers with the same name, the first match will
|
||||
// be returned.
|
||||
func (p *Pod) FindContainerByName(containerName string) *Container {
|
||||
for _, c := range p.Containers {
|
||||
if c.Name == containerName {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pod) FindContainerByID(id ContainerID) *Container {
|
||||
for _, c := range p.Containers {
|
||||
if c.ID == id {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Pod) FindSandboxByID(id ContainerID) *Container {
|
||||
for _, c := range p.Sandboxes {
|
||||
if c.ID == id {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToAPIPod converts Pod to v1.Pod. Note that if a field in v1.Pod has no
|
||||
// corresponding field in Pod, the field would not be populated.
|
||||
func (p *Pod) ToAPIPod() *v1.Pod {
|
||||
var pod v1.Pod
|
||||
pod.UID = p.ID
|
||||
pod.Name = p.Name
|
||||
pod.Namespace = p.Namespace
|
||||
|
||||
for _, c := range p.Containers {
|
||||
var container v1.Container
|
||||
container.Name = c.Name
|
||||
container.Image = c.Image
|
||||
pod.Spec.Containers = append(pod.Spec.Containers, container)
|
||||
}
|
||||
return &pod
|
||||
}
|
||||
|
||||
// IsEmpty returns true if the pod is empty.
|
||||
func (p *Pod) IsEmpty() bool {
|
||||
return reflect.DeepEqual(p, &Pod{})
|
||||
}
|
||||
|
||||
// GetPodFullName returns a name that uniquely identifies a pod.
|
||||
func GetPodFullName(pod *v1.Pod) string {
|
||||
// Use underscore as the delimiter because it is not allowed in pod name
|
||||
// (DNS subdomain format), while allowed in the container name format.
|
||||
return pod.Name + "_" + pod.Namespace
|
||||
}
|
||||
|
||||
// Build the pod full name from pod name and namespace.
|
||||
func BuildPodFullName(name, namespace string) string {
|
||||
return name + "_" + namespace
|
||||
}
|
||||
|
||||
// Parse the pod full name.
|
||||
func ParsePodFullName(podFullName string) (string, string, error) {
|
||||
parts := strings.Split(podFullName, "_")
|
||||
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||
return "", "", fmt.Errorf("failed to parse the pod full name %q", podFullName)
|
||||
}
|
||||
return parts[0], parts[1], nil
|
||||
}
|
||||
|
||||
// Option is a functional option type for Runtime, useful for
|
||||
// completely optional settings.
|
||||
type Option func(Runtime)
|
||||
|
||||
// Sort the container statuses by creation time.
|
||||
type SortContainerStatusesByCreationTime []*ContainerStatus
|
||||
|
||||
func (s SortContainerStatusesByCreationTime) Len() int { return len(s) }
|
||||
func (s SortContainerStatusesByCreationTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s SortContainerStatusesByCreationTime) Less(i, j int) bool {
|
||||
return s[i].CreatedAt.Before(s[j].CreatedAt)
|
||||
}
|
||||
|
||||
const (
|
||||
// MaxPodTerminationMessageLogLength is the maximum bytes any one pod may have written
|
||||
// as termination message output across all containers. Containers will be evenly truncated
|
||||
// until output is below this limit.
|
||||
MaxPodTerminationMessageLogLength = 1024 * 12
|
||||
// MaxContainerTerminationMessageLength is the upper bound any one container may write to
|
||||
// its termination message path. Contents above this length will be truncated.
|
||||
MaxContainerTerminationMessageLength = 1024 * 4
|
||||
// MaxContainerTerminationMessageLogLength is the maximum bytes any one container will
|
||||
// have written to its termination message when the message is read from the logs.
|
||||
MaxContainerTerminationMessageLogLength = 1024 * 2
|
||||
// MaxContainerTerminationMessageLogLines is the maximum number of previous lines of
|
||||
// log output that the termination message can contain.
|
||||
MaxContainerTerminationMessageLogLines = 80
|
||||
)
|
96
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go
generated
vendored
Normal file
96
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// TODO(yifan): Maybe set the them as parameters for NewCache().
|
||||
defaultCachePeriod = time.Second * 2
|
||||
)
|
||||
|
||||
type RuntimeCache interface {
|
||||
GetPods() ([]*Pod, error)
|
||||
ForceUpdateIfOlder(time.Time) error
|
||||
}
|
||||
|
||||
type podsGetter interface {
|
||||
GetPods(bool) ([]*Pod, error)
|
||||
}
|
||||
|
||||
// NewRuntimeCache creates a container runtime cache.
|
||||
func NewRuntimeCache(getter podsGetter) (RuntimeCache, error) {
|
||||
return &runtimeCache{
|
||||
getter: getter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// runtimeCache caches a list of pods. It records a timestamp (cacheTime) right
|
||||
// before updating the pods, so the timestamp is at most as new as the pods
|
||||
// (and can be slightly older). The timestamp always moves forward. Callers are
|
||||
// expected not to modify the pods returned from GetPods.
|
||||
type runtimeCache struct {
|
||||
sync.Mutex
|
||||
// The underlying container runtime used to update the cache.
|
||||
getter podsGetter
|
||||
// Last time when cache was updated.
|
||||
cacheTime time.Time
|
||||
// The content of the cache.
|
||||
pods []*Pod
|
||||
}
|
||||
|
||||
// GetPods returns the cached pods if they are not outdated; otherwise, it
|
||||
// retrieves the latest pods and return them.
|
||||
func (r *runtimeCache) GetPods() ([]*Pod, error) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
if time.Since(r.cacheTime) > defaultCachePeriod {
|
||||
if err := r.updateCache(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return r.pods, nil
|
||||
}
|
||||
|
||||
func (r *runtimeCache) ForceUpdateIfOlder(minExpectedCacheTime time.Time) error {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
if r.cacheTime.Before(minExpectedCacheTime) {
|
||||
return r.updateCache()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *runtimeCache) updateCache() error {
|
||||
pods, timestamp, err := r.getPodsWithTimestamp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.pods, r.cacheTime = pods, timestamp
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPodsWithTimestamp records a timestamp and retrieves pods from the getter.
|
||||
func (r *runtimeCache) getPodsWithTimestamp() ([]*Pod, time.Time, error) {
|
||||
// Always record the timestamp before getting the pods to avoid stale pods.
|
||||
timestamp := time.Now()
|
||||
pods, err := r.getter.GetPods(false)
|
||||
return pods, timestamp, err
|
||||
}
|
45
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache_fake.go
generated
vendored
Normal file
45
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache_fake.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
// TestRunTimeCache embeds runtimeCache with some additional methods for testing.
|
||||
// It must be declared in the container package to have visibility to runtimeCache.
|
||||
// It cannot be in a "..._test.go" file in order for runtime_cache_test.go to have cross-package visibility to it.
|
||||
// (cross-package declarations in test files cannot be used from dot imports if this package is vendored)
|
||||
type TestRuntimeCache struct {
|
||||
runtimeCache
|
||||
}
|
||||
|
||||
func (r *TestRuntimeCache) UpdateCacheWithLock() error {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
return r.updateCache()
|
||||
}
|
||||
|
||||
func (r *TestRuntimeCache) GetCachedPods() []*Pod {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
return r.pods
|
||||
}
|
||||
|
||||
func NewTestRuntimeCache(getter podsGetter) *TestRuntimeCache {
|
||||
return &TestRuntimeCache{
|
||||
runtimeCache: runtimeCache{
|
||||
getter: getter,
|
||||
},
|
||||
}
|
||||
}
|
128
vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go
generated
vendored
Normal file
128
vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright 2015 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 container
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
// TODO(random-liu): We need to better organize runtime errors for introspection.
|
||||
|
||||
// Container Terminated and Kubelet is backing off the restart
|
||||
var ErrCrashLoopBackOff = errors.New("CrashLoopBackOff")
|
||||
|
||||
var (
|
||||
// ErrContainerNotFound returned when a container in the given pod with the
|
||||
// given container name was not found, amongst those managed by the kubelet.
|
||||
ErrContainerNotFound = errors.New("no matching container")
|
||||
)
|
||||
|
||||
var (
|
||||
ErrRunContainer = errors.New("RunContainerError")
|
||||
ErrKillContainer = errors.New("KillContainerError")
|
||||
ErrVerifyNonRoot = errors.New("VerifyNonRootError")
|
||||
ErrRunInitContainer = errors.New("RunInitContainerError")
|
||||
ErrCreatePodSandbox = errors.New("CreatePodSandboxError")
|
||||
ErrConfigPodSandbox = errors.New("ConfigPodSandboxError")
|
||||
ErrKillPodSandbox = errors.New("KillPodSandboxError")
|
||||
)
|
||||
|
||||
var (
|
||||
ErrSetupNetwork = errors.New("SetupNetworkError")
|
||||
ErrTeardownNetwork = errors.New("TeardownNetworkError")
|
||||
)
|
||||
|
||||
// SyncAction indicates different kind of actions in SyncPod() and KillPod(). Now there are only actions
|
||||
// about start/kill container and setup/teardown network.
|
||||
type SyncAction string
|
||||
|
||||
const (
|
||||
StartContainer SyncAction = "StartContainer"
|
||||
KillContainer SyncAction = "KillContainer"
|
||||
SetupNetwork SyncAction = "SetupNetwork"
|
||||
TeardownNetwork SyncAction = "TeardownNetwork"
|
||||
InitContainer SyncAction = "InitContainer"
|
||||
CreatePodSandbox SyncAction = "CreatePodSandbox"
|
||||
ConfigPodSandbox SyncAction = "ConfigPodSandbox"
|
||||
KillPodSandbox SyncAction = "KillPodSandbox"
|
||||
)
|
||||
|
||||
// SyncResult is the result of sync action.
|
||||
type SyncResult struct {
|
||||
// The associated action of the result
|
||||
Action SyncAction
|
||||
// The target of the action, now the target can only be:
|
||||
// * Container: Target should be container name
|
||||
// * Network: Target is useless now, we just set it as pod full name now
|
||||
Target interface{}
|
||||
// Brief error reason
|
||||
Error error
|
||||
// Human readable error reason
|
||||
Message string
|
||||
}
|
||||
|
||||
// NewSyncResult generates new SyncResult with specific Action and Target
|
||||
func NewSyncResult(action SyncAction, target interface{}) *SyncResult {
|
||||
return &SyncResult{Action: action, Target: target}
|
||||
}
|
||||
|
||||
// Fail fails the SyncResult with specific error and message
|
||||
func (r *SyncResult) Fail(err error, msg string) {
|
||||
r.Error, r.Message = err, msg
|
||||
}
|
||||
|
||||
// PodSyncResult is the summary result of SyncPod() and KillPod()
|
||||
type PodSyncResult struct {
|
||||
// Result of different sync actions
|
||||
SyncResults []*SyncResult
|
||||
// Error encountered in SyncPod() and KillPod() that is not already included in SyncResults
|
||||
SyncError error
|
||||
}
|
||||
|
||||
// AddSyncResult adds multiple SyncResult to current PodSyncResult
|
||||
func (p *PodSyncResult) AddSyncResult(result ...*SyncResult) {
|
||||
p.SyncResults = append(p.SyncResults, result...)
|
||||
}
|
||||
|
||||
// AddPodSyncResult merges a PodSyncResult to current one
|
||||
func (p *PodSyncResult) AddPodSyncResult(result PodSyncResult) {
|
||||
p.AddSyncResult(result.SyncResults...)
|
||||
p.SyncError = result.SyncError
|
||||
}
|
||||
|
||||
// Fail fails the PodSyncResult with an error occurred in SyncPod() and KillPod() itself
|
||||
func (p *PodSyncResult) Fail(err error) {
|
||||
p.SyncError = err
|
||||
}
|
||||
|
||||
// Error returns an error summarizing all the errors in PodSyncResult
|
||||
func (p *PodSyncResult) Error() error {
|
||||
errlist := []error{}
|
||||
if p.SyncError != nil {
|
||||
errlist = append(errlist, fmt.Errorf("failed to SyncPod: %v\n", p.SyncError))
|
||||
}
|
||||
for _, result := range p.SyncResults {
|
||||
if result.Error != nil {
|
||||
errlist = append(errlist, fmt.Errorf("failed to %q for %q with %v: %q\n", result.Action, result.Target,
|
||||
result.Error, result.Message))
|
||||
}
|
||||
}
|
||||
return utilerrors.NewAggregate(errlist)
|
||||
}
|
154
vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/metrics/metrics.go
generated
vendored
Normal file
154
vendor/k8s.io/kubernetes/pkg/kubelet/dockershim/metrics/metrics.go
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright 2015 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 metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
// DockerOperationsKey is the key for docker operation metrics.
|
||||
DockerOperationsKey = "docker_operations_total"
|
||||
// DockerOperationsLatencyKey is the key for the operation latency metrics.
|
||||
DockerOperationsLatencyKey = "docker_operations_duration_seconds"
|
||||
// DockerOperationsErrorsKey is the key for the operation error metrics.
|
||||
DockerOperationsErrorsKey = "docker_operations_errors_total"
|
||||
// DockerOperationsTimeoutKey is the key for the operation timeout metrics.
|
||||
DockerOperationsTimeoutKey = "docker_operations_timeout_total"
|
||||
|
||||
// DeprecatedDockerOperationsKey is the deprecated key for docker operation metrics.
|
||||
DeprecatedDockerOperationsKey = "docker_operations"
|
||||
// DeprecatedDockerOperationsLatencyKey is the deprecated key for the operation latency metrics.
|
||||
DeprecatedDockerOperationsLatencyKey = "docker_operations_latency_microseconds"
|
||||
// DeprecatedDockerOperationsErrorsKey is the deprecated key for the operation error metrics.
|
||||
DeprecatedDockerOperationsErrorsKey = "docker_operations_errors"
|
||||
// DeprecatedDockerOperationsTimeoutKey is the deprecated key for the operation timeout metrics.
|
||||
DeprecatedDockerOperationsTimeoutKey = "docker_operations_timeout"
|
||||
|
||||
// Keep the "kubelet" subsystem for backward compatibility.
|
||||
kubeletSubsystem = "kubelet"
|
||||
)
|
||||
|
||||
var (
|
||||
// DockerOperationsLatency collects operation latency numbers by operation
|
||||
// type.
|
||||
DockerOperationsLatency = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DockerOperationsLatencyKey,
|
||||
Help: "Latency in seconds of Docker operations. Broken down by operation type.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
// DockerOperations collects operation counts by operation type.
|
||||
DockerOperations = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DockerOperationsKey,
|
||||
Help: "Cumulative number of Docker operations by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
// DockerOperationsErrors collects operation errors by operation
|
||||
// type.
|
||||
DockerOperationsErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DockerOperationsErrorsKey,
|
||||
Help: "Cumulative number of Docker operation errors by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
// DockerOperationsTimeout collects operation timeouts by operation type.
|
||||
DockerOperationsTimeout = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DockerOperationsTimeoutKey,
|
||||
Help: "Cumulative number of Docker operation timeout by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
|
||||
// DeprecatedDockerOperationsLatency collects operation latency numbers by operation
|
||||
// type.
|
||||
DeprecatedDockerOperationsLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DeprecatedDockerOperationsLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds of Docker operations. Broken down by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
// DeprecatedDockerOperations collects operation counts by operation type.
|
||||
DeprecatedDockerOperations = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DeprecatedDockerOperationsKey,
|
||||
Help: "(Deprecated) Cumulative number of Docker operations by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
// DeprecatedDockerOperationsErrors collects operation errors by operation
|
||||
// type.
|
||||
DeprecatedDockerOperationsErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DeprecatedDockerOperationsErrorsKey,
|
||||
Help: "(Deprecated) Cumulative number of Docker operation errors by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
// DeprecatedDockerOperationsTimeout collects operation timeouts by operation type.
|
||||
DeprecatedDockerOperationsTimeout = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: kubeletSubsystem,
|
||||
Name: DeprecatedDockerOperationsTimeoutKey,
|
||||
Help: "(Deprecated) Cumulative number of Docker operation timeout by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
)
|
||||
|
||||
var registerMetrics sync.Once
|
||||
|
||||
// Register all metrics.
|
||||
func Register() {
|
||||
registerMetrics.Do(func() {
|
||||
prometheus.MustRegister(DockerOperationsLatency)
|
||||
prometheus.MustRegister(DockerOperations)
|
||||
prometheus.MustRegister(DockerOperationsErrors)
|
||||
prometheus.MustRegister(DockerOperationsTimeout)
|
||||
prometheus.MustRegister(DeprecatedDockerOperationsLatency)
|
||||
prometheus.MustRegister(DeprecatedDockerOperations)
|
||||
prometheus.MustRegister(DeprecatedDockerOperationsErrors)
|
||||
prometheus.MustRegister(DeprecatedDockerOperationsTimeout)
|
||||
})
|
||||
}
|
||||
|
||||
// SinceInMicroseconds gets the time since the specified start in microseconds.
|
||||
func SinceInMicroseconds(start time.Time) float64 {
|
||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
||||
}
|
||||
|
||||
// SinceInSeconds gets the time since the specified start in seconds.
|
||||
func SinceInSeconds(start time.Time) float64 {
|
||||
return time.Since(start).Seconds()
|
||||
}
|
98
vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go
generated
vendored
Normal file
98
vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright 2014 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 events
|
||||
|
||||
const (
|
||||
// Container event reason list
|
||||
CreatedContainer = "Created"
|
||||
StartedContainer = "Started"
|
||||
FailedToCreateContainer = "Failed"
|
||||
FailedToStartContainer = "Failed"
|
||||
KillingContainer = "Killing"
|
||||
PreemptContainer = "Preempting"
|
||||
BackOffStartContainer = "BackOff"
|
||||
ExceededGracePeriod = "ExceededGracePeriod"
|
||||
|
||||
// Pod event reason list
|
||||
FailedToKillPod = "FailedKillPod"
|
||||
FailedToCreatePodContainer = "FailedCreatePodContainer"
|
||||
FailedToMakePodDataDirectories = "Failed"
|
||||
NetworkNotReady = "NetworkNotReady"
|
||||
|
||||
// Image event reason list
|
||||
PullingImage = "Pulling"
|
||||
PulledImage = "Pulled"
|
||||
FailedToPullImage = "Failed"
|
||||
FailedToInspectImage = "InspectFailed"
|
||||
ErrImageNeverPullPolicy = "ErrImageNeverPull"
|
||||
BackOffPullImage = "BackOff"
|
||||
|
||||
// kubelet event reason list
|
||||
NodeReady = "NodeReady"
|
||||
NodeNotReady = "NodeNotReady"
|
||||
NodeSchedulable = "NodeSchedulable"
|
||||
NodeNotSchedulable = "NodeNotSchedulable"
|
||||
StartingKubelet = "Starting"
|
||||
KubeletSetupFailed = "KubeletSetupFailed"
|
||||
FailedAttachVolume = "FailedAttachVolume"
|
||||
FailedDetachVolume = "FailedDetachVolume"
|
||||
FailedMountVolume = "FailedMount"
|
||||
VolumeResizeFailed = "VolumeResizeFailed"
|
||||
VolumeResizeSuccess = "VolumeResizeSuccessful"
|
||||
FileSystemResizeFailed = "FileSystemResizeFailed"
|
||||
FileSystemResizeSuccess = "FileSystemResizeSuccessful"
|
||||
FailedUnMountVolume = "FailedUnMount"
|
||||
FailedMapVolume = "FailedMapVolume"
|
||||
FailedUnmapDevice = "FailedUnmapDevice"
|
||||
WarnAlreadyMountedVolume = "AlreadyMountedVolume"
|
||||
SuccessfulDetachVolume = "SuccessfulDetachVolume"
|
||||
SuccessfulAttachVolume = "SuccessfulAttachVolume"
|
||||
SuccessfulMountVolume = "SuccessfulMountVolume"
|
||||
SuccessfulUnMountVolume = "SuccessfulUnMountVolume"
|
||||
HostPortConflict = "HostPortConflict"
|
||||
NodeSelectorMismatching = "NodeSelectorMismatching"
|
||||
InsufficientFreeCPU = "InsufficientFreeCPU"
|
||||
InsufficientFreeMemory = "InsufficientFreeMemory"
|
||||
NodeRebooted = "Rebooted"
|
||||
ContainerGCFailed = "ContainerGCFailed"
|
||||
ImageGCFailed = "ImageGCFailed"
|
||||
FailedNodeAllocatableEnforcement = "FailedNodeAllocatableEnforcement"
|
||||
SuccessfulNodeAllocatableEnforcement = "NodeAllocatableEnforced"
|
||||
UnsupportedMountOption = "UnsupportedMountOption"
|
||||
SandboxChanged = "SandboxChanged"
|
||||
FailedCreatePodSandBox = "FailedCreatePodSandBox"
|
||||
FailedStatusPodSandBox = "FailedPodSandBoxStatus"
|
||||
|
||||
// Image manager event reason list
|
||||
InvalidDiskCapacity = "InvalidDiskCapacity"
|
||||
FreeDiskSpaceFailed = "FreeDiskSpaceFailed"
|
||||
|
||||
// Probe event reason list
|
||||
ContainerUnhealthy = "Unhealthy"
|
||||
ContainerProbeWarning = "ProbeWarning"
|
||||
|
||||
// Pod worker event reason list
|
||||
FailedSync = "FailedSync"
|
||||
|
||||
// Config event reason list
|
||||
FailedValidation = "FailedValidation"
|
||||
|
||||
// Lifecycle hooks
|
||||
FailedPostStartHook = "FailedPostStartHook"
|
||||
FailedPreStopHook = "FailedPreStopHook"
|
||||
UnfinishedPreStopHook = "UnfinishedPreStopHook"
|
||||
)
|
36
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go
generated
vendored
Normal file
36
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2017 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 lifecycle
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
|
||||
)
|
||||
|
||||
// AdmissionFailureHandlerStub is an AdmissionFailureHandler that does not perform any handling of admission failure.
|
||||
// It simply passes the failure on.
|
||||
type AdmissionFailureHandlerStub struct{}
|
||||
|
||||
var _ AdmissionFailureHandler = &AdmissionFailureHandlerStub{}
|
||||
|
||||
func NewAdmissionFailureHandlerStub() *AdmissionFailureHandlerStub {
|
||||
return &AdmissionFailureHandlerStub{}
|
||||
}
|
||||
|
||||
func (n *AdmissionFailureHandlerStub) HandleAdmissionFailure(admitPod *v1.Pod, failureReasons []predicates.PredicateFailureReason) (bool, []predicates.PredicateFailureReason, error) {
|
||||
return false, failureReasons, nil
|
||||
}
|
19
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// Handlers for pod lifecycle events and interfaces to integrate
|
||||
// with kubelet admission, synchronization, and eviction of pods.
|
||||
package lifecycle // import "k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
302
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go
generated
vendored
Normal file
302
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go
generated
vendored
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
Copyright 2014 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 lifecycle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/pkg/security/apparmor"
|
||||
)
|
||||
|
||||
type HandlerRunner struct {
|
||||
httpGetter kubetypes.HttpGetter
|
||||
commandRunner kubecontainer.ContainerCommandRunner
|
||||
containerManager podStatusProvider
|
||||
}
|
||||
|
||||
type podStatusProvider interface {
|
||||
GetPodStatus(uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error)
|
||||
}
|
||||
|
||||
func NewHandlerRunner(httpGetter kubetypes.HttpGetter, commandRunner kubecontainer.ContainerCommandRunner, containerManager podStatusProvider) kubecontainer.HandlerRunner {
|
||||
return &HandlerRunner{
|
||||
httpGetter: httpGetter,
|
||||
commandRunner: commandRunner,
|
||||
containerManager: containerManager,
|
||||
}
|
||||
}
|
||||
|
||||
func (hr *HandlerRunner) Run(containerID kubecontainer.ContainerID, pod *v1.Pod, container *v1.Container, handler *v1.Handler) (string, error) {
|
||||
switch {
|
||||
case handler.Exec != nil:
|
||||
var msg string
|
||||
// TODO(tallclair): Pass a proper timeout value.
|
||||
output, err := hr.commandRunner.RunInContainer(containerID, handler.Exec.Command, 0)
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("Exec lifecycle hook (%v) for Container %q in Pod %q failed - error: %v, message: %q", handler.Exec.Command, container.Name, format.Pod(pod), err, string(output))
|
||||
klog.V(1).Infof(msg)
|
||||
}
|
||||
return msg, err
|
||||
case handler.HTTPGet != nil:
|
||||
msg, err := hr.runHTTPHandler(pod, container, handler)
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("Http lifecycle hook (%s) for Container %q in Pod %q failed - error: %v, message: %q", handler.HTTPGet.Path, container.Name, format.Pod(pod), err, msg)
|
||||
klog.V(1).Infof(msg)
|
||||
}
|
||||
return msg, err
|
||||
default:
|
||||
err := fmt.Errorf("Invalid handler: %v", handler)
|
||||
msg := fmt.Sprintf("Cannot run handler: %v", err)
|
||||
klog.Errorf(msg)
|
||||
return msg, err
|
||||
}
|
||||
}
|
||||
|
||||
// resolvePort attempts to turn an IntOrString port reference into a concrete port number.
|
||||
// If portReference has an int value, it is treated as a literal, and simply returns that value.
|
||||
// If portReference is a string, an attempt is first made to parse it as an integer. If that fails,
|
||||
// an attempt is made to find a port with the same name in the container spec.
|
||||
// If a port with the same name is found, it's ContainerPort value is returned. If no matching
|
||||
// port is found, an error is returned.
|
||||
func resolvePort(portReference intstr.IntOrString, container *v1.Container) (int, error) {
|
||||
if portReference.Type == intstr.Int {
|
||||
return portReference.IntValue(), nil
|
||||
}
|
||||
portName := portReference.StrVal
|
||||
port, err := strconv.Atoi(portName)
|
||||
if err == nil {
|
||||
return port, nil
|
||||
}
|
||||
for _, portSpec := range container.Ports {
|
||||
if portSpec.Name == portName {
|
||||
return int(portSpec.ContainerPort), nil
|
||||
}
|
||||
}
|
||||
return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container)
|
||||
}
|
||||
|
||||
func (hr *HandlerRunner) runHTTPHandler(pod *v1.Pod, container *v1.Container, handler *v1.Handler) (string, error) {
|
||||
host := handler.HTTPGet.Host
|
||||
if len(host) == 0 {
|
||||
status, err := hr.containerManager.GetPodStatus(pod.UID, pod.Name, pod.Namespace)
|
||||
if err != nil {
|
||||
klog.Errorf("Unable to get pod info, event handlers may be invalid.")
|
||||
return "", err
|
||||
}
|
||||
if status.IP == "" {
|
||||
return "", fmt.Errorf("failed to find networking container: %v", status)
|
||||
}
|
||||
host = status.IP
|
||||
}
|
||||
var port int
|
||||
if handler.HTTPGet.Port.Type == intstr.String && len(handler.HTTPGet.Port.StrVal) == 0 {
|
||||
port = 80
|
||||
} else {
|
||||
var err error
|
||||
port, err = resolvePort(handler.HTTPGet.Port, container)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
url := fmt.Sprintf("http://%s/%s", net.JoinHostPort(host, strconv.Itoa(port)), handler.HTTPGet.Path)
|
||||
resp, err := hr.httpGetter.Get(url)
|
||||
return getHttpRespBody(resp), err
|
||||
}
|
||||
|
||||
func getHttpRespBody(resp *http.Response) string {
|
||||
if resp == nil {
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if bytes, err := ioutil.ReadAll(resp.Body); err == nil {
|
||||
return string(bytes)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func NewAppArmorAdmitHandler(validator apparmor.Validator) PodAdmitHandler {
|
||||
return &appArmorAdmitHandler{
|
||||
Validator: validator,
|
||||
}
|
||||
}
|
||||
|
||||
type appArmorAdmitHandler struct {
|
||||
apparmor.Validator
|
||||
}
|
||||
|
||||
func (a *appArmorAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
// If the pod is already running or terminated, no need to recheck AppArmor.
|
||||
if attrs.Pod.Status.Phase != v1.PodPending {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
err := a.Validate(attrs.Pod)
|
||||
if err == nil {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "AppArmor",
|
||||
Message: fmt.Sprintf("Cannot enforce AppArmor: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
func NewNoNewPrivsAdmitHandler(runtime kubecontainer.Runtime) PodAdmitHandler {
|
||||
return &noNewPrivsAdmitHandler{
|
||||
Runtime: runtime,
|
||||
}
|
||||
}
|
||||
|
||||
type noNewPrivsAdmitHandler struct {
|
||||
kubecontainer.Runtime
|
||||
}
|
||||
|
||||
func (a *noNewPrivsAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
// If the pod is already running or terminated, no need to recheck NoNewPrivs.
|
||||
if attrs.Pod.Status.Phase != v1.PodPending {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// If the containers in a pod do not require no-new-privs, admit it.
|
||||
if !noNewPrivsRequired(attrs.Pod) {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Always admit runtimes except docker.
|
||||
if a.Runtime.Type() != kubetypes.DockerContainerRuntime {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Make sure docker api version is valid.
|
||||
rversion, err := a.Runtime.APIVersion()
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "NoNewPrivs",
|
||||
Message: fmt.Sprintf("Cannot enforce NoNewPrivs: %v", err),
|
||||
}
|
||||
}
|
||||
v, err := rversion.Compare("1.23.0")
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "NoNewPrivs",
|
||||
Message: fmt.Sprintf("Cannot enforce NoNewPrivs: %v", err),
|
||||
}
|
||||
}
|
||||
// If the version is less than 1.23 it will return -1 above.
|
||||
if v == -1 {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "NoNewPrivs",
|
||||
Message: fmt.Sprintf("Cannot enforce NoNewPrivs: docker runtime API version %q must be greater than or equal to 1.23", rversion.String()),
|
||||
}
|
||||
}
|
||||
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
func noNewPrivsRequired(pod *v1.Pod) bool {
|
||||
// Iterate over pod containers and check if we added no-new-privs.
|
||||
for _, c := range pod.Spec.Containers {
|
||||
if c.SecurityContext != nil && c.SecurityContext.AllowPrivilegeEscalation != nil && !*c.SecurityContext.AllowPrivilegeEscalation {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func NewProcMountAdmitHandler(runtime kubecontainer.Runtime) PodAdmitHandler {
|
||||
return &procMountAdmitHandler{
|
||||
Runtime: runtime,
|
||||
}
|
||||
}
|
||||
|
||||
type procMountAdmitHandler struct {
|
||||
kubecontainer.Runtime
|
||||
}
|
||||
|
||||
func (a *procMountAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
// If the pod is already running or terminated, no need to recheck NoNewPrivs.
|
||||
if attrs.Pod.Status.Phase != v1.PodPending {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// If the containers in a pod only need the default ProcMountType, admit it.
|
||||
if procMountIsDefault(attrs.Pod) {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Always admit runtimes except docker.
|
||||
if a.Runtime.Type() != kubetypes.DockerContainerRuntime {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Make sure docker api version is valid.
|
||||
// Merged in https://github.com/moby/moby/pull/36644
|
||||
rversion, err := a.Runtime.APIVersion()
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "ProcMount",
|
||||
Message: fmt.Sprintf("Cannot enforce ProcMount: %v", err),
|
||||
}
|
||||
}
|
||||
v, err := rversion.Compare("1.38.0")
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "ProcMount",
|
||||
Message: fmt.Sprintf("Cannot enforce ProcMount: %v", err),
|
||||
}
|
||||
}
|
||||
// If the version is less than 1.38 it will return -1 above.
|
||||
if v == -1 {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "ProcMount",
|
||||
Message: fmt.Sprintf("Cannot enforce ProcMount: docker runtime API version %q must be greater than or equal to 1.38", rversion.String()),
|
||||
}
|
||||
}
|
||||
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
func procMountIsDefault(pod *v1.Pod) bool {
|
||||
// Iterate over pod containers and check if we are using the DefaultProcMountType
|
||||
// for all containers.
|
||||
for _, c := range pod.Spec.Containers {
|
||||
if c.SecurityContext != nil {
|
||||
if c.SecurityContext.ProcMount != nil && *c.SecurityContext.ProcMount != v1.DefaultProcMount {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
122
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go
generated
vendored
Normal file
122
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright 2016 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 lifecycle
|
||||
|
||||
import "k8s.io/api/core/v1"
|
||||
|
||||
// PodAdmitAttributes is the context for a pod admission decision.
|
||||
// The member fields of this struct should never be mutated.
|
||||
type PodAdmitAttributes struct {
|
||||
// the pod to evaluate for admission
|
||||
Pod *v1.Pod
|
||||
// all pods bound to the kubelet excluding the pod being evaluated
|
||||
OtherPods []*v1.Pod
|
||||
}
|
||||
|
||||
// PodAdmitResult provides the result of a pod admission decision.
|
||||
type PodAdmitResult struct {
|
||||
// if true, the pod should be admitted.
|
||||
Admit bool
|
||||
// a brief single-word reason why the pod could not be admitted.
|
||||
Reason string
|
||||
// a brief message explaining why the pod could not be admitted.
|
||||
Message string
|
||||
}
|
||||
|
||||
// PodAdmitHandler is notified during pod admission.
|
||||
type PodAdmitHandler interface {
|
||||
// Admit evaluates if a pod can be admitted.
|
||||
Admit(attrs *PodAdmitAttributes) PodAdmitResult
|
||||
}
|
||||
|
||||
// PodAdmitTarget maintains a list of handlers to invoke.
|
||||
type PodAdmitTarget interface {
|
||||
// AddPodAdmitHandler adds the specified handler.
|
||||
AddPodAdmitHandler(a PodAdmitHandler)
|
||||
}
|
||||
|
||||
// PodSyncLoopHandler is invoked during each sync loop iteration.
|
||||
type PodSyncLoopHandler interface {
|
||||
// ShouldSync returns true if the pod needs to be synced.
|
||||
// This operation must return immediately as its called for each pod.
|
||||
// The provided pod should never be modified.
|
||||
ShouldSync(pod *v1.Pod) bool
|
||||
}
|
||||
|
||||
// PodSyncLoopTarget maintains a list of handlers to pod sync loop.
|
||||
type PodSyncLoopTarget interface {
|
||||
// AddPodSyncLoopHandler adds the specified handler.
|
||||
AddPodSyncLoopHandler(a PodSyncLoopHandler)
|
||||
}
|
||||
|
||||
// ShouldEvictResponse provides the result of a should evict request.
|
||||
type ShouldEvictResponse struct {
|
||||
// if true, the pod should be evicted.
|
||||
Evict bool
|
||||
// a brief CamelCase reason why the pod should be evicted.
|
||||
Reason string
|
||||
// a brief message why the pod should be evicted.
|
||||
Message string
|
||||
}
|
||||
|
||||
// PodSyncHandler is invoked during each sync pod operation.
|
||||
type PodSyncHandler interface {
|
||||
// ShouldEvict is invoked during each sync pod operation to determine
|
||||
// if the pod should be evicted from the kubelet. If so, the pod status
|
||||
// is updated to mark its phase as failed with the provided reason and message,
|
||||
// and the pod is immediately killed.
|
||||
// This operation must return immediately as its called for each sync pod.
|
||||
// The provided pod should never be modified.
|
||||
ShouldEvict(pod *v1.Pod) ShouldEvictResponse
|
||||
}
|
||||
|
||||
// PodSyncTarget maintains a list of handlers to pod sync.
|
||||
type PodSyncTarget interface {
|
||||
// AddPodSyncHandler adds the specified handler
|
||||
AddPodSyncHandler(a PodSyncHandler)
|
||||
}
|
||||
|
||||
// PodLifecycleTarget groups a set of lifecycle interfaces for convenience.
|
||||
type PodLifecycleTarget interface {
|
||||
PodAdmitTarget
|
||||
PodSyncLoopTarget
|
||||
PodSyncTarget
|
||||
}
|
||||
|
||||
// PodAdmitHandlers maintains a list of handlers to pod admission.
|
||||
type PodAdmitHandlers []PodAdmitHandler
|
||||
|
||||
// AddPodAdmitHandler adds the specified observer.
|
||||
func (handlers *PodAdmitHandlers) AddPodAdmitHandler(a PodAdmitHandler) {
|
||||
*handlers = append(*handlers, a)
|
||||
}
|
||||
|
||||
// PodSyncLoopHandlers maintains a list of handlers to pod sync loop.
|
||||
type PodSyncLoopHandlers []PodSyncLoopHandler
|
||||
|
||||
// AddPodSyncLoopHandler adds the specified observer.
|
||||
func (handlers *PodSyncLoopHandlers) AddPodSyncLoopHandler(a PodSyncLoopHandler) {
|
||||
*handlers = append(*handlers, a)
|
||||
}
|
||||
|
||||
// PodSyncHandlers maintains a list of handlers to pod sync.
|
||||
type PodSyncHandlers []PodSyncHandler
|
||||
|
||||
// AddPodSyncHandler adds the specified handler.
|
||||
func (handlers *PodSyncHandlers) AddPodSyncHandler(a PodSyncHandler) {
|
||||
*handlers = append(*handlers, a)
|
||||
}
|
174
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go
generated
vendored
Normal file
174
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go
generated
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
Copyright 2016 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 lifecycle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
|
||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||
)
|
||||
|
||||
type getNodeAnyWayFuncType func() (*v1.Node, error)
|
||||
|
||||
type pluginResourceUpdateFuncType func(*schedulernodeinfo.NodeInfo, *PodAdmitAttributes) error
|
||||
|
||||
// AdmissionFailureHandler is an interface which defines how to deal with a failure to admit a pod.
|
||||
// This allows for the graceful handling of pod admission failure.
|
||||
type AdmissionFailureHandler interface {
|
||||
HandleAdmissionFailure(admitPod *v1.Pod, failureReasons []predicates.PredicateFailureReason) (bool, []predicates.PredicateFailureReason, error)
|
||||
}
|
||||
|
||||
type predicateAdmitHandler struct {
|
||||
getNodeAnyWayFunc getNodeAnyWayFuncType
|
||||
pluginResourceUpdateFunc pluginResourceUpdateFuncType
|
||||
admissionFailureHandler AdmissionFailureHandler
|
||||
}
|
||||
|
||||
var _ PodAdmitHandler = &predicateAdmitHandler{}
|
||||
|
||||
func NewPredicateAdmitHandler(getNodeAnyWayFunc getNodeAnyWayFuncType, admissionFailureHandler AdmissionFailureHandler, pluginResourceUpdateFunc pluginResourceUpdateFuncType) *predicateAdmitHandler {
|
||||
return &predicateAdmitHandler{
|
||||
getNodeAnyWayFunc,
|
||||
pluginResourceUpdateFunc,
|
||||
admissionFailureHandler,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *predicateAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
node, err := w.getNodeAnyWayFunc()
|
||||
if err != nil {
|
||||
klog.Errorf("Cannot get Node info: %v", err)
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "InvalidNodeInfo",
|
||||
Message: "Kubelet cannot get node info.",
|
||||
}
|
||||
}
|
||||
admitPod := attrs.Pod
|
||||
pods := attrs.OtherPods
|
||||
nodeInfo := schedulernodeinfo.NewNodeInfo(pods...)
|
||||
nodeInfo.SetNode(node)
|
||||
// ensure the node has enough plugin resources for that required in pods
|
||||
if err = w.pluginResourceUpdateFunc(nodeInfo, attrs); err != nil {
|
||||
message := fmt.Sprintf("Update plugin resources failed due to %v, which is unexpected.", err)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "UnexpectedAdmissionError",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the requests of the extended resources that are missing in the
|
||||
// node info. This is required to support cluster-level resources, which
|
||||
// are extended resources unknown to nodes.
|
||||
//
|
||||
// Caveat: If a pod was manually bound to a node (e.g., static pod) where a
|
||||
// node-level extended resource it requires is not found, then kubelet will
|
||||
// not fail admission while it should. This issue will be addressed with
|
||||
// the Resource Class API in the future.
|
||||
podWithoutMissingExtendedResources := removeMissingExtendedResources(admitPod, nodeInfo)
|
||||
|
||||
fit, reasons, err := predicates.GeneralPredicates(podWithoutMissingExtendedResources, nil, nodeInfo)
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", err)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: "UnexpectedAdmissionError",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
if !fit {
|
||||
fit, reasons, err = w.admissionFailureHandler.HandleAdmissionFailure(admitPod, reasons)
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("Unexpected error while attempting to recover from admission failure: %v", err)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: "UnexpectedAdmissionError",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
}
|
||||
if !fit {
|
||||
var reason string
|
||||
var message string
|
||||
if len(reasons) == 0 {
|
||||
message = fmt.Sprint("GeneralPredicates failed due to unknown reason, which is unexpected.")
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: "UnknownReason",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
// If there are failed predicates, we only return the first one as a reason.
|
||||
r := reasons[0]
|
||||
switch re := r.(type) {
|
||||
case *predicates.PredicateFailureError:
|
||||
reason = re.PredicateName
|
||||
message = re.Error()
|
||||
klog.V(2).Infof("Predicate failed on Pod: %v, for reason: %v", format.Pod(admitPod), message)
|
||||
case *predicates.InsufficientResourceError:
|
||||
reason = fmt.Sprintf("OutOf%s", re.ResourceName)
|
||||
message = re.Error()
|
||||
klog.V(2).Infof("Predicate failed on Pod: %v, for reason: %v", format.Pod(admitPod), message)
|
||||
case *predicates.FailureReason:
|
||||
reason = re.GetReason()
|
||||
message = fmt.Sprintf("Failure: %s", re.GetReason())
|
||||
klog.V(2).Infof("Predicate failed on Pod: %v, for reason: %v", format.Pod(admitPod), message)
|
||||
default:
|
||||
reason = "UnexpectedPredicateFailureType"
|
||||
message = fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", r)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
}
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
return PodAdmitResult{
|
||||
Admit: true,
|
||||
}
|
||||
}
|
||||
|
||||
func removeMissingExtendedResources(pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *v1.Pod {
|
||||
podCopy := pod.DeepCopy()
|
||||
for i, c := range pod.Spec.Containers {
|
||||
// We only handle requests in Requests but not Limits because the
|
||||
// PodFitsResources predicate, to which the result pod will be passed,
|
||||
// does not use Limits.
|
||||
podCopy.Spec.Containers[i].Resources.Requests = make(v1.ResourceList)
|
||||
for rName, rQuant := range c.Resources.Requests {
|
||||
if v1helper.IsExtendedResourceName(rName) {
|
||||
if _, found := nodeInfo.AllocatableResource().ScalarResources[rName]; !found {
|
||||
continue
|
||||
}
|
||||
}
|
||||
podCopy.Spec.Containers[i].Resources.Requests[rName] = rQuant
|
||||
}
|
||||
}
|
||||
return podCopy
|
||||
}
|
554
vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go
generated
vendored
Normal file
554
vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go
generated
vendored
Normal file
@ -0,0 +1,554 @@
|
||||
/*
|
||||
Copyright 2015 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 metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
)
|
||||
|
||||
const (
|
||||
KubeletSubsystem = "kubelet"
|
||||
NodeNameKey = "node_name"
|
||||
NodeLabelKey = "node"
|
||||
PodWorkerDurationKey = "pod_worker_duration_seconds"
|
||||
PodStartDurationKey = "pod_start_duration_seconds"
|
||||
CgroupManagerOperationsKey = "cgroup_manager_duration_seconds"
|
||||
PodWorkerStartDurationKey = "pod_worker_start_duration_seconds"
|
||||
PLEGRelistDurationKey = "pleg_relist_duration_seconds"
|
||||
PLEGDiscardEventsKey = "pleg_discard_events"
|
||||
PLEGRelistIntervalKey = "pleg_relist_interval_seconds"
|
||||
EvictionStatsAgeKey = "eviction_stats_age_seconds"
|
||||
DeprecatedPodWorkerLatencyKey = "pod_worker_latency_microseconds"
|
||||
DeprecatedPodStartLatencyKey = "pod_start_latency_microseconds"
|
||||
DeprecatedCgroupManagerOperationsKey = "cgroup_manager_latency_microseconds"
|
||||
DeprecatedPodWorkerStartLatencyKey = "pod_worker_start_latency_microseconds"
|
||||
DeprecatedPLEGRelistLatencyKey = "pleg_relist_latency_microseconds"
|
||||
DeprecatedPLEGRelistIntervalKey = "pleg_relist_interval_microseconds"
|
||||
DeprecatedEvictionStatsAgeKey = "eviction_stats_age_microseconds"
|
||||
VolumeStatsCapacityBytesKey = "volume_stats_capacity_bytes"
|
||||
VolumeStatsAvailableBytesKey = "volume_stats_available_bytes"
|
||||
VolumeStatsUsedBytesKey = "volume_stats_used_bytes"
|
||||
VolumeStatsInodesKey = "volume_stats_inodes"
|
||||
VolumeStatsInodesFreeKey = "volume_stats_inodes_free"
|
||||
VolumeStatsInodesUsedKey = "volume_stats_inodes_used"
|
||||
// Metrics keys of remote runtime operations
|
||||
RuntimeOperationsKey = "runtime_operations_total"
|
||||
RuntimeOperationsDurationKey = "runtime_operations_duration_seconds"
|
||||
RuntimeOperationsErrorsKey = "runtime_operations_errors_total"
|
||||
DeprecatedRuntimeOperationsKey = "runtime_operations"
|
||||
DeprecatedRuntimeOperationsLatencyKey = "runtime_operations_latency_microseconds"
|
||||
DeprecatedRuntimeOperationsErrorsKey = "runtime_operations_errors"
|
||||
// Metrics keys of device plugin operations
|
||||
DevicePluginRegistrationCountKey = "device_plugin_registration_total"
|
||||
DevicePluginAllocationDurationKey = "device_plugin_alloc_duration_seconds"
|
||||
DeprecatedDevicePluginRegistrationCountKey = "device_plugin_registration_count"
|
||||
DeprecatedDevicePluginAllocationLatencyKey = "device_plugin_alloc_latency_microseconds"
|
||||
|
||||
// Metric keys for node config
|
||||
AssignedConfigKey = "node_config_assigned"
|
||||
ActiveConfigKey = "node_config_active"
|
||||
LastKnownGoodConfigKey = "node_config_last_known_good"
|
||||
ConfigErrorKey = "node_config_error"
|
||||
ConfigSourceLabelKey = "node_config_source"
|
||||
ConfigSourceLabelValueLocal = "local"
|
||||
ConfigUIDLabelKey = "node_config_uid"
|
||||
ConfigResourceVersionLabelKey = "node_config_resource_version"
|
||||
KubeletConfigKeyLabelKey = "node_config_kubelet_key"
|
||||
|
||||
// Metrics keys for RuntimeClass
|
||||
RunPodSandboxDurationKey = "run_podsandbox_duration_seconds"
|
||||
RunPodSandboxErrorsKey = "run_podsandbox_errors_total"
|
||||
)
|
||||
|
||||
var (
|
||||
NodeName = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: NodeNameKey,
|
||||
Help: "The node's name. The count is always 1.",
|
||||
},
|
||||
[]string{NodeLabelKey},
|
||||
)
|
||||
ContainersPerPodCount = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: "containers_per_pod_count",
|
||||
Help: "The number of containers per pod.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
)
|
||||
PodWorkerDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PodWorkerDurationKey,
|
||||
Help: "Duration in seconds to sync a single pod. Broken down by operation type: create, update, or sync",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
PodStartDuration = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PodStartDurationKey,
|
||||
Help: "Duration in seconds for a single pod to go from pending to running.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
)
|
||||
CgroupManagerDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: CgroupManagerOperationsKey,
|
||||
Help: "Duration in seconds for cgroup manager operations. Broken down by method.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
PodWorkerStartDuration = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PodWorkerStartDurationKey,
|
||||
Help: "Duration in seconds from seeing a pod to starting a worker.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
)
|
||||
PLEGRelistDuration = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PLEGRelistDurationKey,
|
||||
Help: "Duration in seconds for relisting pods in PLEG.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
)
|
||||
PLEGDiscardEvents = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PLEGDiscardEventsKey,
|
||||
Help: "The number of discard events in PLEG.",
|
||||
},
|
||||
[]string{},
|
||||
)
|
||||
PLEGRelistInterval = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PLEGRelistIntervalKey,
|
||||
Help: "Interval in seconds between relisting in PLEG.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
)
|
||||
// Metrics of remote runtime operations.
|
||||
RuntimeOperations = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: RuntimeOperationsKey,
|
||||
Help: "Cumulative number of runtime operations by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
RuntimeOperationsDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: RuntimeOperationsDurationKey,
|
||||
Help: "Duration in seconds of runtime operations. Broken down by operation type.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
RuntimeOperationsErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: RuntimeOperationsErrorsKey,
|
||||
Help: "Cumulative number of runtime operation errors by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
EvictionStatsAge = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: EvictionStatsAgeKey,
|
||||
Help: "Time between when stats are collected, and when pod is evicted based on those stats by eviction signal",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"eviction_signal"},
|
||||
)
|
||||
DevicePluginRegistrationCount = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DevicePluginRegistrationCountKey,
|
||||
Help: "Cumulative number of device plugin registrations. Broken down by resource name.",
|
||||
},
|
||||
[]string{"resource_name"},
|
||||
)
|
||||
DevicePluginAllocationDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DevicePluginAllocationDurationKey,
|
||||
Help: "Duration in seconds to serve a device plugin Allocation request. Broken down by resource name.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"resource_name"},
|
||||
)
|
||||
|
||||
DeprecatedPodWorkerLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedPodWorkerLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds to sync a single pod. Broken down by operation type: create, update, or sync",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
DeprecatedPodStartLatency = prometheus.NewSummary(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedPodStartLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds for a single pod to go from pending to running.",
|
||||
},
|
||||
)
|
||||
DeprecatedCgroupManagerLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedCgroupManagerOperationsKey,
|
||||
Help: "(Deprecated) Latency in microseconds for cgroup manager operations. Broken down by method.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
DeprecatedPodWorkerStartLatency = prometheus.NewSummary(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedPodWorkerStartLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds from seeing a pod to starting a worker.",
|
||||
},
|
||||
)
|
||||
DeprecatedPLEGRelistLatency = prometheus.NewSummary(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedPLEGRelistLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds for relisting pods in PLEG.",
|
||||
},
|
||||
)
|
||||
DeprecatedPLEGRelistInterval = prometheus.NewSummary(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedPLEGRelistIntervalKey,
|
||||
Help: "(Deprecated) Interval in microseconds between relisting in PLEG.",
|
||||
},
|
||||
)
|
||||
DeprecatedRuntimeOperations = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedRuntimeOperationsKey,
|
||||
Help: "(Deprecated) Cumulative number of runtime operations by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
DeprecatedRuntimeOperationsLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedRuntimeOperationsLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds of runtime operations. Broken down by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
DeprecatedRuntimeOperationsErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedRuntimeOperationsErrorsKey,
|
||||
Help: "(Deprecated) Cumulative number of runtime operation errors by operation type.",
|
||||
},
|
||||
[]string{"operation_type"},
|
||||
)
|
||||
DeprecatedEvictionStatsAge = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedEvictionStatsAgeKey,
|
||||
Help: "(Deprecated) Time between when stats are collected, and when pod is evicted based on those stats by eviction signal",
|
||||
},
|
||||
[]string{"eviction_signal"},
|
||||
)
|
||||
DeprecatedDevicePluginRegistrationCount = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedDevicePluginRegistrationCountKey,
|
||||
Help: "(Deprecated) Cumulative number of device plugin registrations. Broken down by resource name.",
|
||||
},
|
||||
[]string{"resource_name"},
|
||||
)
|
||||
DeprecatedDevicePluginAllocationLatency = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: DeprecatedDevicePluginAllocationLatencyKey,
|
||||
Help: "(Deprecated) Latency in microseconds to serve a device plugin Allocation request. Broken down by resource name.",
|
||||
},
|
||||
[]string{"resource_name"},
|
||||
)
|
||||
|
||||
// Metrics for node config
|
||||
|
||||
AssignedConfig = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: AssignedConfigKey,
|
||||
Help: "The node's understanding of intended config. The count is always 1.",
|
||||
},
|
||||
[]string{ConfigSourceLabelKey, ConfigUIDLabelKey, ConfigResourceVersionLabelKey, KubeletConfigKeyLabelKey},
|
||||
)
|
||||
ActiveConfig = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: ActiveConfigKey,
|
||||
Help: "The config source the node is actively using. The count is always 1.",
|
||||
},
|
||||
[]string{ConfigSourceLabelKey, ConfigUIDLabelKey, ConfigResourceVersionLabelKey, KubeletConfigKeyLabelKey},
|
||||
)
|
||||
LastKnownGoodConfig = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: LastKnownGoodConfigKey,
|
||||
Help: "The config source the node will fall back to when it encounters certain errors. The count is always 1.",
|
||||
},
|
||||
[]string{ConfigSourceLabelKey, ConfigUIDLabelKey, ConfigResourceVersionLabelKey, KubeletConfigKeyLabelKey},
|
||||
)
|
||||
ConfigError = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: ConfigErrorKey,
|
||||
Help: "This metric is true (1) if the node is experiencing a configuration-related error, false (0) otherwise.",
|
||||
},
|
||||
)
|
||||
RunPodSandboxDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: RunPodSandboxDurationKey,
|
||||
Help: "Duration in seconds of the run_podsandbox operations. Broken down by RuntimeClass.",
|
||||
// Use DefBuckets for now, will customize the buckets if necessary.
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"runtime_handler"},
|
||||
)
|
||||
RunPodSandboxErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: RunPodSandboxErrorsKey,
|
||||
Help: "Cumulative number of the run_podsandbox operation errors by RuntimeClass.",
|
||||
},
|
||||
[]string{"runtime_handler"},
|
||||
)
|
||||
)
|
||||
|
||||
var registerMetrics sync.Once
|
||||
|
||||
// Register all metrics.
|
||||
func Register(containerCache kubecontainer.RuntimeCache, collectors ...prometheus.Collector) {
|
||||
// Register the metrics.
|
||||
registerMetrics.Do(func() {
|
||||
prometheus.MustRegister(NodeName)
|
||||
prometheus.MustRegister(PodWorkerDuration)
|
||||
prometheus.MustRegister(PodStartDuration)
|
||||
prometheus.MustRegister(CgroupManagerDuration)
|
||||
prometheus.MustRegister(PodWorkerStartDuration)
|
||||
prometheus.MustRegister(ContainersPerPodCount)
|
||||
prometheus.MustRegister(newPodAndContainerCollector(containerCache))
|
||||
prometheus.MustRegister(PLEGRelistDuration)
|
||||
prometheus.MustRegister(PLEGDiscardEvents)
|
||||
prometheus.MustRegister(PLEGRelistInterval)
|
||||
prometheus.MustRegister(RuntimeOperations)
|
||||
prometheus.MustRegister(RuntimeOperationsDuration)
|
||||
prometheus.MustRegister(RuntimeOperationsErrors)
|
||||
prometheus.MustRegister(EvictionStatsAge)
|
||||
prometheus.MustRegister(DevicePluginRegistrationCount)
|
||||
prometheus.MustRegister(DevicePluginAllocationDuration)
|
||||
prometheus.MustRegister(DeprecatedPodWorkerLatency)
|
||||
prometheus.MustRegister(DeprecatedPodStartLatency)
|
||||
prometheus.MustRegister(DeprecatedCgroupManagerLatency)
|
||||
prometheus.MustRegister(DeprecatedPodWorkerStartLatency)
|
||||
prometheus.MustRegister(DeprecatedPLEGRelistLatency)
|
||||
prometheus.MustRegister(DeprecatedPLEGRelistInterval)
|
||||
prometheus.MustRegister(DeprecatedRuntimeOperations)
|
||||
prometheus.MustRegister(DeprecatedRuntimeOperationsLatency)
|
||||
prometheus.MustRegister(DeprecatedRuntimeOperationsErrors)
|
||||
prometheus.MustRegister(DeprecatedEvictionStatsAge)
|
||||
prometheus.MustRegister(DeprecatedDevicePluginRegistrationCount)
|
||||
prometheus.MustRegister(DeprecatedDevicePluginAllocationLatency)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) {
|
||||
prometheus.MustRegister(AssignedConfig)
|
||||
prometheus.MustRegister(ActiveConfig)
|
||||
prometheus.MustRegister(LastKnownGoodConfig)
|
||||
prometheus.MustRegister(ConfigError)
|
||||
}
|
||||
for _, collector := range collectors {
|
||||
prometheus.MustRegister(collector)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Gets the time since the specified start in microseconds.
|
||||
func SinceInMicroseconds(start time.Time) float64 {
|
||||
return float64(time.Since(start).Nanoseconds() / time.Microsecond.Nanoseconds())
|
||||
}
|
||||
|
||||
// SinceInSeconds gets the time since the specified start in seconds.
|
||||
func SinceInSeconds(start time.Time) float64 {
|
||||
return time.Since(start).Seconds()
|
||||
}
|
||||
|
||||
func newPodAndContainerCollector(containerCache kubecontainer.RuntimeCache) *podAndContainerCollector {
|
||||
return &podAndContainerCollector{
|
||||
containerCache: containerCache,
|
||||
}
|
||||
}
|
||||
|
||||
// Custom collector for current pod and container counts.
|
||||
type podAndContainerCollector struct {
|
||||
// Cache for accessing information about running containers.
|
||||
containerCache kubecontainer.RuntimeCache
|
||||
}
|
||||
|
||||
// TODO(vmarmol): Split by source?
|
||||
var (
|
||||
runningPodCountDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName("", KubeletSubsystem, "running_pod_count"),
|
||||
"Number of pods currently running",
|
||||
nil, nil)
|
||||
runningContainerCountDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName("", KubeletSubsystem, "running_container_count"),
|
||||
"Number of containers currently running",
|
||||
nil, nil)
|
||||
)
|
||||
|
||||
func (pc *podAndContainerCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- runningPodCountDesc
|
||||
ch <- runningContainerCountDesc
|
||||
}
|
||||
|
||||
func (pc *podAndContainerCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
runningPods, err := pc.containerCache.GetPods()
|
||||
if err != nil {
|
||||
klog.Warningf("Failed to get running container information while collecting metrics: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
runningContainers := 0
|
||||
for _, p := range runningPods {
|
||||
runningContainers += len(p.Containers)
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
runningPodCountDesc,
|
||||
prometheus.GaugeValue,
|
||||
float64(len(runningPods)))
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
runningContainerCountDesc,
|
||||
prometheus.GaugeValue,
|
||||
float64(runningContainers))
|
||||
}
|
||||
|
||||
const configMapAPIPathFmt = "/api/v1/namespaces/%s/configmaps/%s"
|
||||
|
||||
func configLabels(source *corev1.NodeConfigSource) (map[string]string, error) {
|
||||
if source == nil {
|
||||
return map[string]string{
|
||||
// prometheus requires all of the labels that can be set on the metric
|
||||
ConfigSourceLabelKey: "local",
|
||||
ConfigUIDLabelKey: "",
|
||||
ConfigResourceVersionLabelKey: "",
|
||||
KubeletConfigKeyLabelKey: "",
|
||||
}, nil
|
||||
}
|
||||
if source.ConfigMap != nil {
|
||||
return map[string]string{
|
||||
ConfigSourceLabelKey: fmt.Sprintf(configMapAPIPathFmt, source.ConfigMap.Namespace, source.ConfigMap.Name),
|
||||
ConfigUIDLabelKey: string(source.ConfigMap.UID),
|
||||
ConfigResourceVersionLabelKey: source.ConfigMap.ResourceVersion,
|
||||
KubeletConfigKeyLabelKey: source.ConfigMap.KubeletConfigKey,
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unrecognized config source type, all source subfields were nil")
|
||||
}
|
||||
|
||||
// track labels across metric updates, so we can delete old label sets and prevent leaks
|
||||
var assignedConfigLabels map[string]string = map[string]string{}
|
||||
|
||||
func SetAssignedConfig(source *corev1.NodeConfigSource) error {
|
||||
// compute the timeseries labels from the source
|
||||
labels, err := configLabels(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// clean up the old timeseries (WithLabelValues creates a new one for each distinct label set)
|
||||
AssignedConfig.Delete(assignedConfigLabels)
|
||||
// record the new timeseries
|
||||
assignedConfigLabels = labels
|
||||
// expose the new timeseries with a constant count of 1
|
||||
AssignedConfig.With(assignedConfigLabels).Set(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
// track labels across metric updates, so we can delete old label sets and prevent leaks
|
||||
var activeConfigLabels map[string]string = map[string]string{}
|
||||
|
||||
func SetActiveConfig(source *corev1.NodeConfigSource) error {
|
||||
// compute the timeseries labels from the source
|
||||
labels, err := configLabels(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// clean up the old timeseries (WithLabelValues creates a new one for each distinct label set)
|
||||
ActiveConfig.Delete(activeConfigLabels)
|
||||
// record the new timeseries
|
||||
activeConfigLabels = labels
|
||||
// expose the new timeseries with a constant count of 1
|
||||
ActiveConfig.With(activeConfigLabels).Set(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
// track labels across metric updates, so we can delete old label sets and prevent leaks
|
||||
var lastKnownGoodConfigLabels map[string]string = map[string]string{}
|
||||
|
||||
func SetLastKnownGoodConfig(source *corev1.NodeConfigSource) error {
|
||||
// compute the timeseries labels from the source
|
||||
labels, err := configLabels(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// clean up the old timeseries (WithLabelValues creates a new one for each distinct label set)
|
||||
LastKnownGoodConfig.Delete(lastKnownGoodConfigLabels)
|
||||
// record the new timeseries
|
||||
lastKnownGoodConfigLabels = labels
|
||||
// expose the new timeseries with a constant count of 1
|
||||
LastKnownGoodConfig.With(lastKnownGoodConfigLabels).Set(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetConfigError(err bool) {
|
||||
if err {
|
||||
ConfigError.Set(1)
|
||||
} else {
|
||||
ConfigError.Set(0)
|
||||
}
|
||||
}
|
||||
|
||||
func SetNodeName(name types.NodeName) {
|
||||
NodeName.WithLabelValues(string(name)).Set(1)
|
||||
}
|
60
vendor/k8s.io/kubernetes/pkg/kubelet/sysctl/namespace.go
generated
vendored
Normal file
60
vendor/k8s.io/kubernetes/pkg/kubelet/sysctl/namespace.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2016 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 sysctl
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Namespace represents a kernel namespace name.
|
||||
type Namespace string
|
||||
|
||||
const (
|
||||
// the Linux IPC namespace
|
||||
IpcNamespace = Namespace("ipc")
|
||||
|
||||
// the network namespace
|
||||
NetNamespace = Namespace("net")
|
||||
|
||||
// the zero value if no namespace is known
|
||||
UnknownNamespace = Namespace("")
|
||||
)
|
||||
|
||||
var namespaces = map[string]Namespace{
|
||||
"kernel.sem": IpcNamespace,
|
||||
}
|
||||
|
||||
var prefixNamespaces = map[string]Namespace{
|
||||
"kernel.shm": IpcNamespace,
|
||||
"kernel.msg": IpcNamespace,
|
||||
"fs.mqueue.": IpcNamespace,
|
||||
"net.": NetNamespace,
|
||||
}
|
||||
|
||||
// NamespacedBy returns the namespace of the Linux kernel for a sysctl, or
|
||||
// UnknownNamespace if the sysctl is not known to be namespaced.
|
||||
func NamespacedBy(val string) Namespace {
|
||||
if ns, found := namespaces[val]; found {
|
||||
return ns
|
||||
}
|
||||
for p, ns := range prefixNamespaces {
|
||||
if strings.HasPrefix(val, p) {
|
||||
return ns
|
||||
}
|
||||
}
|
||||
return UnknownNamespace
|
||||
}
|
95
vendor/k8s.io/kubernetes/pkg/kubelet/sysctl/runtime.go
generated
vendored
Normal file
95
vendor/k8s.io/kubernetes/pkg/kubelet/sysctl/runtime.go
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright 2016 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 sysctl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
||||
)
|
||||
|
||||
const (
|
||||
UnsupportedReason = "SysctlUnsupported"
|
||||
// CRI uses semver-compatible API version, while docker does not
|
||||
// (e.g., 1.24). Append the version with a ".0".
|
||||
dockerMinimumAPIVersion = "1.24.0"
|
||||
|
||||
dockerTypeName = "docker"
|
||||
)
|
||||
|
||||
// TODO: The admission logic in this file is runtime-dependent. It should be
|
||||
// changed to be generic and CRI-compatible.
|
||||
|
||||
type runtimeAdmitHandler struct {
|
||||
result lifecycle.PodAdmitResult
|
||||
}
|
||||
|
||||
var _ lifecycle.PodAdmitHandler = &runtimeAdmitHandler{}
|
||||
|
||||
// NewRuntimeAdmitHandler returns a sysctlRuntimeAdmitHandler which checks whether
|
||||
// the given runtime support sysctls.
|
||||
func NewRuntimeAdmitHandler(runtime container.Runtime) (*runtimeAdmitHandler, error) {
|
||||
switch runtime.Type() {
|
||||
case dockerTypeName:
|
||||
v, err := runtime.APIVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get runtime version: %v", err)
|
||||
}
|
||||
|
||||
// only Docker API version >= 1.24 supports sysctls
|
||||
c, err := v.Compare(dockerMinimumAPIVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compare Docker version for sysctl support: %v", err)
|
||||
}
|
||||
if c >= 0 {
|
||||
return &runtimeAdmitHandler{
|
||||
result: lifecycle.PodAdmitResult{
|
||||
Admit: true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
return &runtimeAdmitHandler{
|
||||
result: lifecycle.PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: UnsupportedReason,
|
||||
Message: "Docker API version before 1.24 does not support sysctls",
|
||||
},
|
||||
}, nil
|
||||
default:
|
||||
// Return admit for other runtimes.
|
||||
return &runtimeAdmitHandler{
|
||||
result: lifecycle.PodAdmitResult{
|
||||
Admit: true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Admit checks whether the runtime supports sysctls.
|
||||
func (w *runtimeAdmitHandler) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult {
|
||||
if attrs.Pod.Spec.SecurityContext != nil {
|
||||
|
||||
if len(attrs.Pod.Spec.SecurityContext.Sysctls) > 0 {
|
||||
return w.result
|
||||
}
|
||||
}
|
||||
|
||||
return lifecycle.PodAdmitResult{
|
||||
Admit: true,
|
||||
}
|
||||
}
|
136
vendor/k8s.io/kubernetes/pkg/kubelet/sysctl/whitelist.go
generated
vendored
Normal file
136
vendor/k8s.io/kubernetes/pkg/kubelet/sysctl/whitelist.go
generated
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright 2016 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 sysctl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
policyvalidation "k8s.io/kubernetes/pkg/apis/policy/validation"
|
||||
"k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
||||
)
|
||||
|
||||
const (
|
||||
AnnotationInvalidReason = "InvalidSysctlAnnotation"
|
||||
ForbiddenReason = "SysctlForbidden"
|
||||
)
|
||||
|
||||
// patternWhitelist takes a list of sysctls or sysctl patterns (ending in *) and
|
||||
// checks validity via a sysctl and prefix map, rejecting those which are not known
|
||||
// to be namespaced.
|
||||
type patternWhitelist struct {
|
||||
sysctls map[string]Namespace
|
||||
prefixes map[string]Namespace
|
||||
}
|
||||
|
||||
var _ lifecycle.PodAdmitHandler = &patternWhitelist{}
|
||||
|
||||
// NewWhitelist creates a new Whitelist from a list of sysctls and sysctl pattern (ending in *).
|
||||
func NewWhitelist(patterns []string) (*patternWhitelist, error) {
|
||||
w := &patternWhitelist{
|
||||
sysctls: map[string]Namespace{},
|
||||
prefixes: map[string]Namespace{},
|
||||
}
|
||||
|
||||
for _, s := range patterns {
|
||||
if !policyvalidation.IsValidSysctlPattern(s) {
|
||||
return nil, fmt.Errorf("sysctl %q must have at most %d characters and match regex %s",
|
||||
s,
|
||||
validation.SysctlMaxLength,
|
||||
policyvalidation.SysctlPatternFmt,
|
||||
)
|
||||
}
|
||||
if strings.HasSuffix(s, "*") {
|
||||
prefix := s[:len(s)-1]
|
||||
ns := NamespacedBy(prefix)
|
||||
if ns == UnknownNamespace {
|
||||
return nil, fmt.Errorf("the sysctls %q are not known to be namespaced", s)
|
||||
}
|
||||
w.prefixes[prefix] = ns
|
||||
} else {
|
||||
ns := NamespacedBy(s)
|
||||
if ns == UnknownNamespace {
|
||||
return nil, fmt.Errorf("the sysctl %q are not known to be namespaced", s)
|
||||
}
|
||||
w.sysctls[s] = ns
|
||||
}
|
||||
}
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// validateSysctl checks that a sysctl is whitelisted because it is known
|
||||
// to be namespaced by the Linux kernel. Note that being whitelisted is required, but not
|
||||
// sufficient: the container runtime might have a stricter check and refuse to launch a pod.
|
||||
//
|
||||
// The parameters hostNet and hostIPC are used to forbid sysctls for pod sharing the
|
||||
// respective namespaces with the host. This check is only possible for sysctls on
|
||||
// the static default whitelist, not those on the custom whitelist provided by the admin.
|
||||
func (w *patternWhitelist) validateSysctl(sysctl string, hostNet, hostIPC bool) error {
|
||||
nsErrorFmt := "%q not allowed with host %s enabled"
|
||||
if ns, found := w.sysctls[sysctl]; found {
|
||||
if ns == IpcNamespace && hostIPC {
|
||||
return fmt.Errorf(nsErrorFmt, sysctl, ns)
|
||||
}
|
||||
if ns == NetNamespace && hostNet {
|
||||
return fmt.Errorf(nsErrorFmt, sysctl, ns)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for p, ns := range w.prefixes {
|
||||
if strings.HasPrefix(sysctl, p) {
|
||||
if ns == IpcNamespace && hostIPC {
|
||||
return fmt.Errorf(nsErrorFmt, sysctl, ns)
|
||||
}
|
||||
if ns == NetNamespace && hostNet {
|
||||
return fmt.Errorf(nsErrorFmt, sysctl, ns)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("%q not whitelisted", sysctl)
|
||||
}
|
||||
|
||||
// Admit checks that all sysctls given in pod's security context
|
||||
// are valid according to the whitelist.
|
||||
func (w *patternWhitelist) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult {
|
||||
pod := attrs.Pod
|
||||
if pod.Spec.SecurityContext == nil || len(pod.Spec.SecurityContext.Sysctls) == 0 {
|
||||
return lifecycle.PodAdmitResult{
|
||||
Admit: true,
|
||||
}
|
||||
}
|
||||
|
||||
var hostNet, hostIPC bool
|
||||
if pod.Spec.SecurityContext != nil {
|
||||
hostNet = pod.Spec.HostNetwork
|
||||
hostIPC = pod.Spec.HostIPC
|
||||
}
|
||||
for _, s := range pod.Spec.SecurityContext.Sysctls {
|
||||
if err := w.validateSysctl(s.Name, hostNet, hostIPC); err != nil {
|
||||
return lifecycle.PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: ForbiddenReason,
|
||||
Message: fmt.Sprintf("forbidden sysctl: %v", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lifecycle.PodAdmitResult{
|
||||
Admit: true,
|
||||
}
|
||||
}
|
32
vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go
generated
vendored
Normal file
32
vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2015 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 types
|
||||
|
||||
const (
|
||||
// system default DNS resolver configuration
|
||||
ResolvConfDefault = "/etc/resolv.conf"
|
||||
|
||||
// different container runtimes
|
||||
DockerContainerRuntime = "docker"
|
||||
RemoteContainerRuntime = "remote"
|
||||
|
||||
// User visible keys for managing node allocatable enforcement on the node.
|
||||
NodeAllocatableEnforcementKey = "pods"
|
||||
SystemReservedEnforcementKey = "system-reserved"
|
||||
KubeReservedEnforcementKey = "kube-reserved"
|
||||
NodeAllocatableNoneKey = "none"
|
||||
)
|
18
vendor/k8s.io/kubernetes/pkg/kubelet/types/doc.go
generated
vendored
Normal file
18
vendor/k8s.io/kubernetes/pkg/kubelet/types/doc.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// Common types in the Kubelet.
|
||||
package types // import "k8s.io/kubernetes/pkg/kubelet/types"
|
40
vendor/k8s.io/kubernetes/pkg/kubelet/types/labels.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/pkg/kubelet/types/labels.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2016 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 types
|
||||
|
||||
const (
|
||||
KubernetesPodNameLabel = "io.kubernetes.pod.name"
|
||||
KubernetesPodNamespaceLabel = "io.kubernetes.pod.namespace"
|
||||
KubernetesPodUIDLabel = "io.kubernetes.pod.uid"
|
||||
KubernetesContainerNameLabel = "io.kubernetes.container.name"
|
||||
)
|
||||
|
||||
func GetContainerName(labels map[string]string) string {
|
||||
return labels[KubernetesContainerNameLabel]
|
||||
}
|
||||
|
||||
func GetPodName(labels map[string]string) string {
|
||||
return labels[KubernetesPodNameLabel]
|
||||
}
|
||||
|
||||
func GetPodUID(labels map[string]string) string {
|
||||
return labels[KubernetesPodUIDLabel]
|
||||
}
|
||||
|
||||
func GetPodNamespace(labels map[string]string) string {
|
||||
return labels[KubernetesPodNamespaceLabel]
|
||||
}
|
40
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_status.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_status.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
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 types
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// PodConditionsByKubelet is the list of pod conditions owned by kubelet
|
||||
var PodConditionsByKubelet = []v1.PodConditionType{
|
||||
v1.PodScheduled,
|
||||
v1.PodReady,
|
||||
v1.PodInitialized,
|
||||
v1.PodReasonUnschedulable,
|
||||
v1.ContainersReady,
|
||||
}
|
||||
|
||||
// PodConditionByKubelet returns if the pod condition type is owned by kubelet
|
||||
func PodConditionByKubelet(conditionType v1.PodConditionType) bool {
|
||||
for _, c := range PodConditionsByKubelet {
|
||||
if c == conditionType {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
199
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go
generated
vendored
Normal file
199
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2014 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 types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
kubeapi "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/scheduling"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
const (
|
||||
ConfigSourceAnnotationKey = "kubernetes.io/config.source"
|
||||
ConfigMirrorAnnotationKey = v1.MirrorPodAnnotationKey
|
||||
ConfigFirstSeenAnnotationKey = "kubernetes.io/config.seen"
|
||||
ConfigHashAnnotationKey = "kubernetes.io/config.hash"
|
||||
CriticalPodAnnotationKey = "scheduler.alpha.kubernetes.io/critical-pod"
|
||||
)
|
||||
|
||||
// PodOperation defines what changes will be made on a pod configuration.
|
||||
type PodOperation int
|
||||
|
||||
const (
|
||||
// This is the current pod configuration
|
||||
SET PodOperation = iota
|
||||
// Pods with the given ids are new to this source
|
||||
ADD
|
||||
// Pods with the given ids are gracefully deleted from this source
|
||||
DELETE
|
||||
// Pods with the given ids have been removed from this source
|
||||
REMOVE
|
||||
// Pods with the given ids have been updated in this source
|
||||
UPDATE
|
||||
// Pods with the given ids have unexpected status in this source,
|
||||
// kubelet should reconcile status with this source
|
||||
RECONCILE
|
||||
// Pods with the given ids have been restored from a checkpoint.
|
||||
RESTORE
|
||||
|
||||
// These constants identify the sources of pods
|
||||
// Updates from a file
|
||||
FileSource = "file"
|
||||
// Updates from querying a web page
|
||||
HTTPSource = "http"
|
||||
// Updates from Kubernetes API Server
|
||||
ApiserverSource = "api"
|
||||
// Updates from all sources
|
||||
AllSource = "*"
|
||||
|
||||
NamespaceDefault = metav1.NamespaceDefault
|
||||
)
|
||||
|
||||
// PodUpdate defines an operation sent on the channel. You can add or remove single services by
|
||||
// sending an array of size one and Op == ADD|REMOVE (with REMOVE, only the ID is required).
|
||||
// For setting the state of the system to a given state for this source configuration, set
|
||||
// Pods as desired and Op to SET, which will reset the system state to that specified in this
|
||||
// operation for this source channel. To remove all pods, set Pods to empty object and Op to SET.
|
||||
//
|
||||
// Additionally, Pods should never be nil - it should always point to an empty slice. While
|
||||
// functionally similar, this helps our unit tests properly check that the correct PodUpdates
|
||||
// are generated.
|
||||
type PodUpdate struct {
|
||||
Pods []*v1.Pod
|
||||
Op PodOperation
|
||||
Source string
|
||||
}
|
||||
|
||||
// Gets all validated sources from the specified sources.
|
||||
func GetValidatedSources(sources []string) ([]string, error) {
|
||||
validated := make([]string, 0, len(sources))
|
||||
for _, source := range sources {
|
||||
switch source {
|
||||
case AllSource:
|
||||
return []string{FileSource, HTTPSource, ApiserverSource}, nil
|
||||
case FileSource, HTTPSource, ApiserverSource:
|
||||
validated = append(validated, source)
|
||||
break
|
||||
case "":
|
||||
break
|
||||
default:
|
||||
return []string{}, fmt.Errorf("unknown pod source %q", source)
|
||||
}
|
||||
}
|
||||
return validated, nil
|
||||
}
|
||||
|
||||
// GetPodSource returns the source of the pod based on the annotation.
|
||||
func GetPodSource(pod *v1.Pod) (string, error) {
|
||||
if pod.Annotations != nil {
|
||||
if source, ok := pod.Annotations[ConfigSourceAnnotationKey]; ok {
|
||||
return source, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("cannot get source of pod %q", pod.UID)
|
||||
}
|
||||
|
||||
// SyncPodType classifies pod updates, eg: create, update.
|
||||
type SyncPodType int
|
||||
|
||||
const (
|
||||
// SyncPodSync is when the pod is synced to ensure desired state
|
||||
SyncPodSync SyncPodType = iota
|
||||
// SyncPodUpdate is when the pod is updated from source
|
||||
SyncPodUpdate
|
||||
// SyncPodCreate is when the pod is created from source
|
||||
SyncPodCreate
|
||||
// SyncPodKill is when the pod is killed based on a trigger internal to the kubelet for eviction.
|
||||
// If a SyncPodKill request is made to pod workers, the request is never dropped, and will always be processed.
|
||||
SyncPodKill
|
||||
)
|
||||
|
||||
func (sp SyncPodType) String() string {
|
||||
switch sp {
|
||||
case SyncPodCreate:
|
||||
return "create"
|
||||
case SyncPodUpdate:
|
||||
return "update"
|
||||
case SyncPodSync:
|
||||
return "sync"
|
||||
case SyncPodKill:
|
||||
return "kill"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// IsCriticalPod returns true if the pod bears the critical pod annotation key or if pod's priority is greater than
|
||||
// or equal to SystemCriticalPriority. Both the default scheduler and the kubelet use this function
|
||||
// to make admission and scheduling decisions.
|
||||
func IsCriticalPod(pod *v1.Pod) bool {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
if pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(*pod.Spec.Priority) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ExperimentalCriticalPodAnnotation) {
|
||||
if IsCritical(pod.Namespace, pod.Annotations) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Preemptable returns true if preemptor pod can preempt preemptee pod
|
||||
// if preemptee is not critical or if preemptor's priority is greater than preemptee's priority
|
||||
func Preemptable(preemptor, preemptee *v1.Pod) bool {
|
||||
if IsCriticalPod(preemptor) && !IsCriticalPod(preemptee) {
|
||||
return true
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
if (preemptor != nil && preemptor.Spec.Priority != nil) &&
|
||||
(preemptee != nil && preemptee.Spec.Priority != nil) {
|
||||
return *(preemptor.Spec.Priority) > *(preemptee.Spec.Priority)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCritical returns true if parameters bear the critical pod annotation
|
||||
// key. The DaemonSetController use this key directly to make scheduling decisions.
|
||||
// TODO: @ravig - Deprecated. Remove this when we move to resolving critical pods based on priorityClassName.
|
||||
func IsCritical(ns string, annotations map[string]string) bool {
|
||||
// Critical pods are restricted to "kube-system" namespace as of now.
|
||||
if ns != kubeapi.NamespaceSystem {
|
||||
return false
|
||||
}
|
||||
val, ok := annotations[CriticalPodAnnotationKey]
|
||||
if ok && val == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCriticalPodBasedOnPriority checks if the given pod is a critical pod based on priority resolved from pod Spec.
|
||||
func IsCriticalPodBasedOnPriority(priority int32) bool {
|
||||
if priority >= scheduling.SystemCriticalPriority {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
100
vendor/k8s.io/kubernetes/pkg/kubelet/types/types.go
generated
vendored
Normal file
100
vendor/k8s.io/kubernetes/pkg/kubelet/types/types.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright 2015 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 types
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// TODO: Reconcile custom types in kubelet/types and this subpackage
|
||||
|
||||
type HttpGetter interface {
|
||||
Get(url string) (*http.Response, error)
|
||||
}
|
||||
|
||||
// Timestamp wraps around time.Time and offers utilities to format and parse
|
||||
// the time using RFC3339Nano
|
||||
type Timestamp struct {
|
||||
time time.Time
|
||||
}
|
||||
|
||||
// NewTimestamp returns a Timestamp object using the current time.
|
||||
func NewTimestamp() *Timestamp {
|
||||
return &Timestamp{time.Now()}
|
||||
}
|
||||
|
||||
// ConvertToTimestamp takes a string, parses it using the RFC3339Nano layout,
|
||||
// and converts it to a Timestamp object.
|
||||
func ConvertToTimestamp(timeString string) *Timestamp {
|
||||
parsed, _ := time.Parse(time.RFC3339Nano, timeString)
|
||||
return &Timestamp{parsed}
|
||||
}
|
||||
|
||||
// Get returns the time as time.Time.
|
||||
func (t *Timestamp) Get() time.Time {
|
||||
return t.time
|
||||
}
|
||||
|
||||
// GetString returns the time in the string format using the RFC3339Nano
|
||||
// layout.
|
||||
func (t *Timestamp) GetString() string {
|
||||
return t.time.Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
// A type to help sort container statuses based on container names.
|
||||
type SortedContainerStatuses []v1.ContainerStatus
|
||||
|
||||
func (s SortedContainerStatuses) Len() int { return len(s) }
|
||||
func (s SortedContainerStatuses) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
func (s SortedContainerStatuses) Less(i, j int) bool {
|
||||
return s[i].Name < s[j].Name
|
||||
}
|
||||
|
||||
// SortInitContainerStatuses ensures that statuses are in the order that their
|
||||
// init container appears in the pod spec
|
||||
func SortInitContainerStatuses(p *v1.Pod, statuses []v1.ContainerStatus) {
|
||||
containers := p.Spec.InitContainers
|
||||
current := 0
|
||||
for _, container := range containers {
|
||||
for j := current; j < len(statuses); j++ {
|
||||
if container.Name == statuses[j].Name {
|
||||
statuses[current], statuses[j] = statuses[j], statuses[current]
|
||||
current++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reservation represents reserved resources for non-pod components.
|
||||
type Reservation struct {
|
||||
// System represents resources reserved for non-kubernetes components.
|
||||
System v1.ResourceList
|
||||
// Kubernetes represents resources reserved for kubernetes system components.
|
||||
Kubernetes v1.ResourceList
|
||||
}
|
||||
|
||||
// A pod UID which has been translated/resolved to the representation known to kubelets.
|
||||
type ResolvedPodUID types.UID
|
||||
|
||||
// A pod UID for a mirror pod.
|
||||
type MirrorPodUID types.UID
|
72
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
Normal file
72
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2015 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 format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type podHandler func(*v1.Pod) string
|
||||
|
||||
// Pod returns a string representing a pod in a consistent human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func Pod(pod *v1.Pod) string {
|
||||
return PodDesc(pod.Name, pod.Namespace, pod.UID)
|
||||
}
|
||||
|
||||
// PodDesc returns a string representing a pod in a consistent human readable format,
|
||||
// with pod UID as part of the string.
|
||||
func PodDesc(podName, podNamespace string, podUID types.UID) string {
|
||||
// Use underscore as the delimiter because it is not allowed in pod name
|
||||
// (DNS subdomain format), while allowed in the container name format.
|
||||
return fmt.Sprintf("%s_%s(%s)", podName, podNamespace, podUID)
|
||||
}
|
||||
|
||||
// PodWithDeletionTimestamp is the same as Pod. In addition, it prints the
|
||||
// deletion timestamp of the pod if it's not nil.
|
||||
func PodWithDeletionTimestamp(pod *v1.Pod) string {
|
||||
var deletionTimestamp string
|
||||
if pod.DeletionTimestamp != nil {
|
||||
deletionTimestamp = ":DeletionTimestamp=" + pod.DeletionTimestamp.UTC().Format(time.RFC3339)
|
||||
}
|
||||
return Pod(pod) + deletionTimestamp
|
||||
}
|
||||
|
||||
// Pods returns a string representation a list of pods in a human
|
||||
// readable format.
|
||||
func Pods(pods []*v1.Pod) string {
|
||||
return aggregatePods(pods, Pod)
|
||||
}
|
||||
|
||||
// PodsWithDeletionTimestamps is the same as Pods. In addition, it prints the
|
||||
// deletion timestamps of the pods if they are not nil.
|
||||
func PodsWithDeletionTimestamps(pods []*v1.Pod) string {
|
||||
return aggregatePods(pods, PodWithDeletionTimestamp)
|
||||
}
|
||||
|
||||
func aggregatePods(pods []*v1.Pod, handler podHandler) string {
|
||||
podStrings := make([]string, 0, len(pods))
|
||||
for _, pod := range pods {
|
||||
podStrings = append(podStrings, handler(pod))
|
||||
}
|
||||
return fmt.Sprintf(strings.Join(podStrings, ", "))
|
||||
}
|
36
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/resources.go
generated
vendored
Normal file
36
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/resources.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2016 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 format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// ResourceList returns a string representation of a resource list in a human readable format.
|
||||
func ResourceList(resources v1.ResourceList) string {
|
||||
resourceStrings := make([]string, 0, len(resources))
|
||||
for key, value := range resources {
|
||||
resourceStrings = append(resourceStrings, fmt.Sprintf("%v=%v", key, value.String()))
|
||||
}
|
||||
// sort the results for consistent log output
|
||||
sort.Strings(resourceStrings)
|
||||
return strings.Join(resourceStrings, ",")
|
||||
}
|
Reference in New Issue
Block a user