kubelet_getters.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package kubelet
  14. import (
  15. "context"
  16. "fmt"
  17. "io/ioutil"
  18. "net"
  19. "path/filepath"
  20. cadvisorapiv1 "github.com/google/cadvisor/info/v1"
  21. "k8s.io/klog"
  22. "k8s.io/utils/mount"
  23. utilpath "k8s.io/utils/path"
  24. v1 "k8s.io/api/core/v1"
  25. "k8s.io/apimachinery/pkg/types"
  26. "k8s.io/kubernetes/pkg/kubelet/cm"
  27. "k8s.io/kubernetes/pkg/kubelet/config"
  28. kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
  29. kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
  30. utilnode "k8s.io/kubernetes/pkg/util/node"
  31. )
  32. // getRootDir returns the full path to the directory under which kubelet can
  33. // store data. These functions are useful to pass interfaces to other modules
  34. // that may need to know where to write data without getting a whole kubelet
  35. // instance.
  36. func (kl *Kubelet) getRootDir() string {
  37. return kl.rootDirectory
  38. }
  39. // getPodsDir returns the full path to the directory under which pod
  40. // directories are created.
  41. func (kl *Kubelet) getPodsDir() string {
  42. return filepath.Join(kl.getRootDir(), config.DefaultKubeletPodsDirName)
  43. }
  44. // getPluginsDir returns the full path to the directory under which plugin
  45. // directories are created. Plugins can use these directories for data that
  46. // they need to persist. Plugins should create subdirectories under this named
  47. // after their own names.
  48. func (kl *Kubelet) getPluginsDir() string {
  49. return filepath.Join(kl.getRootDir(), config.DefaultKubeletPluginsDirName)
  50. }
  51. // getPluginsRegistrationDir returns the full path to the directory under which
  52. // plugins socket should be placed to be registered.
  53. // More information is available about plugin registration in the pluginwatcher
  54. // module
  55. func (kl *Kubelet) getPluginsRegistrationDir() string {
  56. return filepath.Join(kl.getRootDir(), config.DefaultKubeletPluginsRegistrationDirName)
  57. }
  58. // getPluginDir returns a data directory name for a given plugin name.
  59. // Plugins can use these directories to store data that they need to persist.
  60. // For per-pod plugin data, see getPodPluginDir.
  61. func (kl *Kubelet) getPluginDir(pluginName string) string {
  62. return filepath.Join(kl.getPluginsDir(), pluginName)
  63. }
  64. // getVolumeDevicePluginsDir returns the full path to the directory under which plugin
  65. // directories are created. Plugins can use these directories for data that
  66. // they need to persist. Plugins should create subdirectories under this named
  67. // after their own names.
  68. func (kl *Kubelet) getVolumeDevicePluginsDir() string {
  69. return filepath.Join(kl.getRootDir(), config.DefaultKubeletPluginsDirName)
  70. }
  71. // getVolumeDevicePluginDir returns a data directory name for a given plugin name.
  72. // Plugins can use these directories to store data that they need to persist.
  73. // For per-pod plugin data, see getVolumeDevicePluginsDir.
  74. func (kl *Kubelet) getVolumeDevicePluginDir(pluginName string) string {
  75. return filepath.Join(kl.getVolumeDevicePluginsDir(), pluginName, config.DefaultKubeletVolumeDevicesDirName)
  76. }
  77. // GetPodDir returns the full path to the per-pod data directory for the
  78. // specified pod. This directory may not exist if the pod does not exist.
  79. func (kl *Kubelet) GetPodDir(podUID types.UID) string {
  80. return kl.getPodDir(podUID)
  81. }
  82. // getPodDir returns the full path to the per-pod directory for the pod with
  83. // the given UID.
  84. func (kl *Kubelet) getPodDir(podUID types.UID) string {
  85. return filepath.Join(kl.getPodsDir(), string(podUID))
  86. }
  87. // getPodVolumesSubpathsDir returns the full path to the per-pod subpaths directory under
  88. // which subpath volumes are created for the specified pod. This directory may not
  89. // exist if the pod does not exist or subpaths are not specified.
  90. func (kl *Kubelet) getPodVolumeSubpathsDir(podUID types.UID) string {
  91. return filepath.Join(kl.getPodDir(podUID), config.DefaultKubeletVolumeSubpathsDirName)
  92. }
  93. // getPodVolumesDir returns the full path to the per-pod data directory under
  94. // which volumes are created for the specified pod. This directory may not
  95. // exist if the pod does not exist.
  96. func (kl *Kubelet) getPodVolumesDir(podUID types.UID) string {
  97. return filepath.Join(kl.getPodDir(podUID), config.DefaultKubeletVolumesDirName)
  98. }
  99. // getPodVolumeDir returns the full path to the directory which represents the
  100. // named volume under the named plugin for specified pod. This directory may not
  101. // exist if the pod does not exist.
  102. func (kl *Kubelet) getPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
  103. return filepath.Join(kl.getPodVolumesDir(podUID), pluginName, volumeName)
  104. }
  105. // getPodVolumeDevicesDir returns the full path to the per-pod data directory under
  106. // which volumes are created for the specified pod. This directory may not
  107. // exist if the pod does not exist.
  108. func (kl *Kubelet) getPodVolumeDevicesDir(podUID types.UID) string {
  109. return filepath.Join(kl.getPodDir(podUID), config.DefaultKubeletVolumeDevicesDirName)
  110. }
  111. // getPodVolumeDeviceDir returns the full path to the directory which represents the
  112. // named plugin for specified pod. This directory may not exist if the pod does not exist.
  113. func (kl *Kubelet) getPodVolumeDeviceDir(podUID types.UID, pluginName string) string {
  114. return filepath.Join(kl.getPodVolumeDevicesDir(podUID), pluginName)
  115. }
  116. // getPodPluginsDir returns the full path to the per-pod data directory under
  117. // which plugins may store data for the specified pod. This directory may not
  118. // exist if the pod does not exist.
  119. func (kl *Kubelet) getPodPluginsDir(podUID types.UID) string {
  120. return filepath.Join(kl.getPodDir(podUID), config.DefaultKubeletPluginsDirName)
  121. }
  122. // getPodPluginDir returns a data directory name for a given plugin name for a
  123. // given pod UID. Plugins can use these directories to store data that they
  124. // need to persist. For non-per-pod plugin data, see getPluginDir.
  125. func (kl *Kubelet) getPodPluginDir(podUID types.UID, pluginName string) string {
  126. return filepath.Join(kl.getPodPluginsDir(podUID), pluginName)
  127. }
  128. // getPodContainerDir returns the full path to the per-pod data directory under
  129. // which container data is held for the specified pod. This directory may not
  130. // exist if the pod or container does not exist.
  131. func (kl *Kubelet) getPodContainerDir(podUID types.UID, ctrName string) string {
  132. return filepath.Join(kl.getPodDir(podUID), config.DefaultKubeletContainersDirName, ctrName)
  133. }
  134. // getPodResourcesSocket returns the full path to the directory containing the pod resources socket
  135. func (kl *Kubelet) getPodResourcesDir() string {
  136. return filepath.Join(kl.getRootDir(), config.DefaultKubeletPodResourcesDirName)
  137. }
  138. // GetPods returns all pods bound to the kubelet and their spec, and the mirror
  139. // pods.
  140. func (kl *Kubelet) GetPods() []*v1.Pod {
  141. pods := kl.podManager.GetPods()
  142. // a kubelet running without apiserver requires an additional
  143. // update of the static pod status. See #57106
  144. for _, p := range pods {
  145. if kubelettypes.IsStaticPod(p) {
  146. if status, ok := kl.statusManager.GetPodStatus(p.UID); ok {
  147. klog.V(2).Infof("status for pod %v updated to %v", p.Name, status)
  148. p.Status = status
  149. }
  150. }
  151. }
  152. return pods
  153. }
  154. // GetRunningPods returns all pods running on kubelet from looking at the
  155. // container runtime cache. This function converts kubecontainer.Pod to
  156. // v1.Pod, so only the fields that exist in both kubecontainer.Pod and
  157. // v1.Pod are considered meaningful.
  158. func (kl *Kubelet) GetRunningPods() ([]*v1.Pod, error) {
  159. pods, err := kl.runtimeCache.GetPods()
  160. if err != nil {
  161. return nil, err
  162. }
  163. apiPods := make([]*v1.Pod, 0, len(pods))
  164. for _, pod := range pods {
  165. apiPods = append(apiPods, pod.ToAPIPod())
  166. }
  167. return apiPods, nil
  168. }
  169. // GetPodByFullName gets the pod with the given 'full' name, which
  170. // incorporates the namespace as well as whether the pod was found.
  171. func (kl *Kubelet) GetPodByFullName(podFullName string) (*v1.Pod, bool) {
  172. return kl.podManager.GetPodByFullName(podFullName)
  173. }
  174. // GetPodByName provides the first pod that matches namespace and name, as well
  175. // as whether the pod was found.
  176. func (kl *Kubelet) GetPodByName(namespace, name string) (*v1.Pod, bool) {
  177. return kl.podManager.GetPodByName(namespace, name)
  178. }
  179. // GetPodByCgroupfs provides the pod that maps to the specified cgroup, as well
  180. // as whether the pod was found.
  181. func (kl *Kubelet) GetPodByCgroupfs(cgroupfs string) (*v1.Pod, bool) {
  182. pcm := kl.containerManager.NewPodContainerManager()
  183. if result, podUID := pcm.IsPodCgroup(cgroupfs); result {
  184. return kl.podManager.GetPodByUID(podUID)
  185. }
  186. return nil, false
  187. }
  188. // GetHostname Returns the hostname as the kubelet sees it.
  189. func (kl *Kubelet) GetHostname() string {
  190. return kl.hostname
  191. }
  192. // getRuntime returns the current Runtime implementation in use by the kubelet.
  193. func (kl *Kubelet) getRuntime() kubecontainer.Runtime {
  194. return kl.containerRuntime
  195. }
  196. // GetNode returns the node info for the configured node name of this Kubelet.
  197. func (kl *Kubelet) GetNode() (*v1.Node, error) {
  198. if kl.kubeClient == nil {
  199. return kl.initialNode(context.TODO())
  200. }
  201. return kl.nodeLister.Get(string(kl.nodeName))
  202. }
  203. // getNodeAnyWay() must return a *v1.Node which is required by RunGeneralPredicates().
  204. // The *v1.Node is obtained as follows:
  205. // Return kubelet's nodeInfo for this node, except on error or if in standalone mode,
  206. // in which case return a manufactured nodeInfo representing a node with no pods,
  207. // zero capacity, and the default labels.
  208. func (kl *Kubelet) getNodeAnyWay() (*v1.Node, error) {
  209. if kl.kubeClient != nil {
  210. if n, err := kl.nodeLister.Get(string(kl.nodeName)); err == nil {
  211. return n, nil
  212. }
  213. }
  214. return kl.initialNode(context.TODO())
  215. }
  216. // GetNodeConfig returns the container manager node config.
  217. func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
  218. return kl.containerManager.GetNodeConfig()
  219. }
  220. // GetPodCgroupRoot returns the listeral cgroupfs value for the cgroup containing all pods
  221. func (kl *Kubelet) GetPodCgroupRoot() string {
  222. return kl.containerManager.GetPodCgroupRoot()
  223. }
  224. // GetHostIP returns host IP or nil in case of error.
  225. func (kl *Kubelet) GetHostIP() (net.IP, error) {
  226. node, err := kl.GetNode()
  227. if err != nil {
  228. return nil, fmt.Errorf("cannot get node: %v", err)
  229. }
  230. return utilnode.GetNodeHostIP(node)
  231. }
  232. // getHostIPAnyway attempts to return the host IP from kubelet's nodeInfo, or
  233. // the initialNode.
  234. func (kl *Kubelet) getHostIPAnyWay() (net.IP, error) {
  235. node, err := kl.getNodeAnyWay()
  236. if err != nil {
  237. return nil, err
  238. }
  239. return utilnode.GetNodeHostIP(node)
  240. }
  241. // GetExtraSupplementalGroupsForPod returns a list of the extra
  242. // supplemental groups for the Pod. These extra supplemental groups come
  243. // from annotations on persistent volumes that the pod depends on.
  244. func (kl *Kubelet) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 {
  245. return kl.volumeManager.GetExtraSupplementalGroupsForPod(pod)
  246. }
  247. // getPodVolumePathListFromDisk returns a list of the volume paths by reading the
  248. // volume directories for the given pod from the disk.
  249. func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, error) {
  250. volumes := []string{}
  251. podVolDir := kl.getPodVolumesDir(podUID)
  252. if pathExists, pathErr := mount.PathExists(podVolDir); pathErr != nil {
  253. return volumes, fmt.Errorf("error checking if path %q exists: %v", podVolDir, pathErr)
  254. } else if !pathExists {
  255. klog.Warningf("Path %q does not exist", podVolDir)
  256. return volumes, nil
  257. }
  258. volumePluginDirs, err := ioutil.ReadDir(podVolDir)
  259. if err != nil {
  260. klog.Errorf("Could not read directory %s: %v", podVolDir, err)
  261. return volumes, err
  262. }
  263. for _, volumePluginDir := range volumePluginDirs {
  264. volumePluginName := volumePluginDir.Name()
  265. volumePluginPath := filepath.Join(podVolDir, volumePluginName)
  266. volumeDirs, err := utilpath.ReadDirNoStat(volumePluginPath)
  267. if err != nil {
  268. return volumes, fmt.Errorf("could not read directory %s: %v", volumePluginPath, err)
  269. }
  270. for _, volumeDir := range volumeDirs {
  271. volumes = append(volumes, filepath.Join(volumePluginPath, volumeDir))
  272. }
  273. }
  274. return volumes, nil
  275. }
  276. func (kl *Kubelet) getMountedVolumePathListFromDisk(podUID types.UID) ([]string, error) {
  277. mountedVolumes := []string{}
  278. volumePaths, err := kl.getPodVolumePathListFromDisk(podUID)
  279. if err != nil {
  280. return mountedVolumes, err
  281. }
  282. for _, volumePath := range volumePaths {
  283. isNotMount, err := kl.mounter.IsLikelyNotMountPoint(volumePath)
  284. if err != nil {
  285. return mountedVolumes, err
  286. }
  287. if !isNotMount {
  288. mountedVolumes = append(mountedVolumes, volumePath)
  289. }
  290. }
  291. return mountedVolumes, nil
  292. }
  293. // podVolumesSubpathsDirExists returns true if the pod volume-subpaths directory for
  294. // a given pod exists
  295. func (kl *Kubelet) podVolumeSubpathsDirExists(podUID types.UID) (bool, error) {
  296. podVolDir := kl.getPodVolumeSubpathsDir(podUID)
  297. if pathExists, pathErr := mount.PathExists(podVolDir); pathErr != nil {
  298. return true, fmt.Errorf("error checking if path %q exists: %v", podVolDir, pathErr)
  299. } else if !pathExists {
  300. return false, nil
  301. }
  302. return true, nil
  303. }
  304. // GetVersionInfo returns information about the version of cAdvisor in use.
  305. func (kl *Kubelet) GetVersionInfo() (*cadvisorapiv1.VersionInfo, error) {
  306. return kl.cadvisor.VersionInfo()
  307. }
  308. // GetCachedMachineInfo assumes that the machine info can't change without a reboot
  309. func (kl *Kubelet) GetCachedMachineInfo() (*cadvisorapiv1.MachineInfo, error) {
  310. return kl.machineInfo, nil
  311. }