kubelet_getters.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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. "fmt"
  16. "io/ioutil"
  17. "net"
  18. "path"
  19. "github.com/golang/glog"
  20. "k8s.io/kubernetes/cmd/kubelet/app/options"
  21. "k8s.io/kubernetes/pkg/api"
  22. "k8s.io/kubernetes/pkg/kubelet/cm"
  23. kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
  24. "k8s.io/kubernetes/pkg/types"
  25. "k8s.io/kubernetes/pkg/util"
  26. nodeutil "k8s.io/kubernetes/pkg/util/node"
  27. )
  28. // getRootDir returns the full path to the directory under which kubelet can
  29. // store data. These functions are useful to pass interfaces to other modules
  30. // that may need to know where to write data without getting a whole kubelet
  31. // instance.
  32. func (kl *Kubelet) getRootDir() string {
  33. return kl.rootDirectory
  34. }
  35. // getPodsDir returns the full path to the directory under which pod
  36. // directories are created.
  37. func (kl *Kubelet) getPodsDir() string {
  38. return path.Join(kl.getRootDir(), options.DefaultKubeletPodsDirName)
  39. }
  40. // getPluginsDir returns the full path to the directory under which plugin
  41. // directories are created. Plugins can use these directories for data that
  42. // they need to persist. Plugins should create subdirectories under this named
  43. // after their own names.
  44. func (kl *Kubelet) getPluginsDir() string {
  45. return path.Join(kl.getRootDir(), options.DefaultKubeletPluginsDirName)
  46. }
  47. // getPluginDir returns a data directory name for a given plugin name.
  48. // Plugins can use these directories to store data that they need to persist.
  49. // For per-pod plugin data, see getPodPluginDir.
  50. func (kl *Kubelet) getPluginDir(pluginName string) string {
  51. return path.Join(kl.getPluginsDir(), pluginName)
  52. }
  53. // GetPodDir returns the full path to the per-pod data directory for the
  54. // specified pod. This directory may not exist if the pod does not exist.
  55. func (kl *Kubelet) GetPodDir(podUID types.UID) string {
  56. return kl.getPodDir(podUID)
  57. }
  58. // getPodDir returns the full path to the per-pod directory for the pod with
  59. // the given UID.
  60. func (kl *Kubelet) getPodDir(podUID types.UID) string {
  61. // Backwards compat. The "old" stuff should be removed before 1.0
  62. // release. The thinking here is this:
  63. // !old && !new = use new
  64. // !old && new = use new
  65. // old && !new = use old
  66. // old && new = use new (but warn)
  67. oldPath := path.Join(kl.getRootDir(), string(podUID))
  68. oldExists := dirExists(oldPath)
  69. newPath := path.Join(kl.getPodsDir(), string(podUID))
  70. newExists := dirExists(newPath)
  71. if oldExists && !newExists {
  72. return oldPath
  73. }
  74. if oldExists {
  75. glog.Warningf("Data dir for pod %q exists in both old and new form, using new", podUID)
  76. }
  77. return newPath
  78. }
  79. // getPodVolumesDir returns the full path to the per-pod data directory under
  80. // which volumes are created for the specified pod. This directory may not
  81. // exist if the pod does not exist.
  82. func (kl *Kubelet) getPodVolumesDir(podUID types.UID) string {
  83. return path.Join(kl.getPodDir(podUID), options.DefaultKubeletVolumesDirName)
  84. }
  85. // getPodVolumeDir returns the full path to the directory which represents the
  86. // named volume under the named plugin for specified pod. This directory may not
  87. // exist if the pod does not exist.
  88. func (kl *Kubelet) getPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
  89. return path.Join(kl.getPodVolumesDir(podUID), pluginName, volumeName)
  90. }
  91. // getPodPluginsDir returns the full path to the per-pod data directory under
  92. // which plugins may store data for the specified pod. This directory may not
  93. // exist if the pod does not exist.
  94. func (kl *Kubelet) getPodPluginsDir(podUID types.UID) string {
  95. return path.Join(kl.getPodDir(podUID), options.DefaultKubeletPluginsDirName)
  96. }
  97. // getPodPluginDir returns a data directory name for a given plugin name for a
  98. // given pod UID. Plugins can use these directories to store data that they
  99. // need to persist. For non-per-pod plugin data, see getPluginDir.
  100. func (kl *Kubelet) getPodPluginDir(podUID types.UID, pluginName string) string {
  101. return path.Join(kl.getPodPluginsDir(podUID), pluginName)
  102. }
  103. // getPodContainerDir returns the full path to the per-pod data directory under
  104. // which container data is held for the specified pod. This directory may not
  105. // exist if the pod or container does not exist.
  106. func (kl *Kubelet) getPodContainerDir(podUID types.UID, ctrName string) string {
  107. // Backwards compat. The "old" stuff should be removed before 1.0
  108. // release. The thinking here is this:
  109. // !old && !new = use new
  110. // !old && new = use new
  111. // old && !new = use old
  112. // old && new = use new (but warn)
  113. oldPath := path.Join(kl.getPodDir(podUID), ctrName)
  114. oldExists := dirExists(oldPath)
  115. newPath := path.Join(kl.getPodDir(podUID), options.DefaultKubeletContainersDirName, ctrName)
  116. newExists := dirExists(newPath)
  117. if oldExists && !newExists {
  118. return oldPath
  119. }
  120. if oldExists {
  121. glog.Warningf("Data dir for pod %q, container %q exists in both old and new form, using new", podUID, ctrName)
  122. }
  123. return newPath
  124. }
  125. // GetPods returns all pods bound to the kubelet and their spec, and the mirror
  126. // pods.
  127. func (kl *Kubelet) GetPods() []*api.Pod {
  128. return kl.podManager.GetPods()
  129. }
  130. // GetRunningPods returns all pods running on kubelet from looking at the
  131. // container runtime cache. This function converts kubecontainer.Pod to
  132. // api.Pod, so only the fields that exist in both kubecontainer.Pod and
  133. // api.Pod are considered meaningful.
  134. func (kl *Kubelet) GetRunningPods() ([]*api.Pod, error) {
  135. pods, err := kl.runtimeCache.GetPods()
  136. if err != nil {
  137. return nil, err
  138. }
  139. apiPods := make([]*api.Pod, 0, len(pods))
  140. for _, pod := range pods {
  141. apiPods = append(apiPods, pod.ToAPIPod())
  142. }
  143. return apiPods, nil
  144. }
  145. // GetPodByFullName gets the pod with the given 'full' name, which
  146. // incorporates the namespace as well as whether the pod was found.
  147. func (kl *Kubelet) GetPodByFullName(podFullName string) (*api.Pod, bool) {
  148. return kl.podManager.GetPodByFullName(podFullName)
  149. }
  150. // GetPodByName provides the first pod that matches namespace and name, as well
  151. // as whether the pod was found.
  152. func (kl *Kubelet) GetPodByName(namespace, name string) (*api.Pod, bool) {
  153. return kl.podManager.GetPodByName(namespace, name)
  154. }
  155. // GetHostname Returns the hostname as the kubelet sees it.
  156. func (kl *Kubelet) GetHostname() string {
  157. return kl.hostname
  158. }
  159. // GetRuntime returns the current Runtime implementation in use by the kubelet. This func
  160. // is exported to simplify integration with third party kubelet extensions (e.g. kubernetes-mesos).
  161. func (kl *Kubelet) GetRuntime() kubecontainer.Runtime {
  162. return kl.containerRuntime
  163. }
  164. // GetNode returns the node info for the configured node name of this Kubelet.
  165. func (kl *Kubelet) GetNode() (*api.Node, error) {
  166. if kl.standaloneMode {
  167. return kl.initialNode()
  168. }
  169. return kl.nodeInfo.GetNodeInfo(kl.nodeName)
  170. }
  171. // getNodeAnyWay() must return a *api.Node which is required by RunGeneralPredicates().
  172. // The *api.Node is obtained as follows:
  173. // Return kubelet's nodeInfo for this node, except on error or if in standalone mode,
  174. // in which case return a manufactured nodeInfo representing a node with no pods,
  175. // zero capacity, and the default labels.
  176. func (kl *Kubelet) getNodeAnyWay() (*api.Node, error) {
  177. if !kl.standaloneMode {
  178. if n, err := kl.nodeInfo.GetNodeInfo(kl.nodeName); err == nil {
  179. return n, nil
  180. }
  181. }
  182. return kl.initialNode()
  183. }
  184. // GetNodeConfig returns the container manager node config.
  185. func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
  186. return kl.containerManager.GetNodeConfig()
  187. }
  188. // Returns host IP or nil in case of error.
  189. func (kl *Kubelet) GetHostIP() (net.IP, error) {
  190. node, err := kl.GetNode()
  191. if err != nil {
  192. return nil, fmt.Errorf("cannot get node: %v", err)
  193. }
  194. return nodeutil.GetNodeHostIP(node)
  195. }
  196. // getHostIPAnyway attempts to return the host IP from kubelet's nodeInfo, or
  197. // the initialNode.
  198. func (kl *Kubelet) getHostIPAnyWay() (net.IP, error) {
  199. node, err := kl.getNodeAnyWay()
  200. if err != nil {
  201. return nil, err
  202. }
  203. return nodeutil.GetNodeHostIP(node)
  204. }
  205. // GetExtraSupplementalGroupsForPod returns a list of the extra
  206. // supplemental groups for the Pod. These extra supplemental groups come
  207. // from annotations on persistent volumes that the pod depends on.
  208. func (kl *Kubelet) GetExtraSupplementalGroupsForPod(pod *api.Pod) []int64 {
  209. return kl.volumeManager.GetExtraSupplementalGroupsForPod(pod)
  210. }
  211. // getPodVolumeNameListFromDisk returns a list of the volume names by reading the
  212. // volume directories for the given pod from the disk.
  213. func (kl *Kubelet) getPodVolumeNameListFromDisk(podUID types.UID) ([]string, error) {
  214. volumes := []string{}
  215. podVolDir := kl.getPodVolumesDir(podUID)
  216. volumePluginDirs, err := ioutil.ReadDir(podVolDir)
  217. if err != nil {
  218. glog.Errorf("Could not read directory %s: %v", podVolDir, err)
  219. return volumes, err
  220. }
  221. for _, volumePluginDir := range volumePluginDirs {
  222. volumePluginName := volumePluginDir.Name()
  223. volumePluginPath := path.Join(podVolDir, volumePluginName)
  224. volumeDirs, volumeDirsStatErrs, err := util.ReadDirNoExit(volumePluginPath)
  225. if err != nil {
  226. return volumes, fmt.Errorf("Could not read directory %s: %v", volumePluginPath, err)
  227. }
  228. for i, volumeDir := range volumeDirs {
  229. if volumeDir != nil {
  230. volumes = append(volumes, volumeDir.Name())
  231. continue
  232. }
  233. glog.Errorf("Could not read directory %s: %v", podVolDir, volumeDirsStatErrs[i])
  234. }
  235. }
  236. return volumes, nil
  237. }