Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2554b959
Commit
2554b959
authored
Feb 27, 2017
by
Vishnu kannan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Map nvidia devices one to one.
Signed-off-by:
Vishnu kannan
<
vishnuk@google.com
>
parent
318f4e10
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
59 additions
and
52 deletions
+59
-52
kube_features.go
pkg/features/kube_features.go
+2
-1
helpers.go
pkg/kubelet/gpu/nvidia/helpers.go
+1
-1
nvidia_gpu_manager.go
pkg/kubelet/gpu/nvidia/nvidia_gpu_manager.go
+46
-32
kubelet.go
pkg/kubelet/kubelet.go
+6
-1
kubelet_pods.go
pkg/kubelet/kubelet_pods.go
+4
-17
No files found.
pkg/features/kube_features.go
View file @
2554b959
...
...
@@ -78,7 +78,8 @@ const (
// alpha: v1.6
//
// Enables support for GPUs as a schedulable resource.
// Only Nvidia GPUs are supported as of v1.6
// Only Nvidia GPUs are supported as of v1.6.
// Works only with Docker Container Runtime.
Accelerators
utilfeature
.
Feature
=
"Accelerators"
)
...
...
pkg/kubelet/gpu/nvidia/helpers.go
View file @
2554b959
...
...
@@ -23,7 +23,7 @@ type podGPUs struct {
podGPUMapping
map
[
string
]
sets
.
String
}
func
newPodG
pu
s
()
*
podGPUs
{
func
newPodG
PU
s
()
*
podGPUs
{
return
&
podGPUs
{
podGPUMapping
:
map
[
string
]
sets
.
String
{},
}
...
...
pkg/kubelet/gpu/nvidia/nvidia_gpu_manager.go
View file @
2554b959
...
...
@@ -33,17 +33,17 @@ import (
"k8s.io/kubernetes/pkg/kubelet/gpu"
)
// TODO: If use NVML in the future, the implementation could be more complex,
// but also more powerful!
// TODO: rework to use Nvidia's NVML, which is more complex, but also provides more fine-grained information and stats.
const
(
// All NVIDIA GPUs cards should be mounted with nvidiactl and nvidia-uvm
// If the driver installed correctly, the 2 devices must be there.
NvidiaCtlDevice
string
=
"/dev/nvidiactl"
NvidiaUVMDevice
string
=
"/dev/nvidia-uvm"
devDirectory
=
"/dev"
nvidiaDeviceRE
=
`^nvidia[0-9]*$`
nvidiaFullpathRE
=
`^/dev/nvidia[0-9]*$`
// If the driver installed correctly, the 2 devices will be there.
nvidiaCtlDevice
string
=
"/dev/nvidiactl"
nvidiaUVMDevice
string
=
"/dev/nvidia-uvm"
// Optional device.
nvidiaUVMToolsDevice
string
=
"/dev/nvidia-uvm-tools"
devDirectory
=
"/dev"
nvidiaDeviceRE
=
`^nvidia[0-9]*$`
nvidiaFullpathRE
=
`^/dev/nvidia[0-9]*$`
)
type
activePodsLister
interface
{
...
...
@@ -55,8 +55,9 @@ type activePodsLister interface {
type
nvidiaGPUManager
struct
{
sync
.
Mutex
// All gpus available on the Node
allGPUs
sets
.
String
allocated
*
podGPUs
allGPUs
sets
.
String
allocated
*
podGPUs
defaultDevices
[]
string
// The interface which could get GPU mapping from all the containers.
// TODO: Should make this independent of Docker in the future.
dockerClient
dockertools
.
DockerInterface
...
...
@@ -65,35 +66,47 @@ type nvidiaGPUManager struct {
// NewNvidiaGPUManager returns a GPUManager that manages local Nvidia GPUs.
// TODO: Migrate to use pod level cgroups and make it generic to all runtimes.
func
NewNvidiaGPUManager
(
activePodsLister
activePodsLister
,
dockerClient
dockertools
.
DockerInterface
)
gpu
.
GPUManager
{
func
NewNvidiaGPUManager
(
activePodsLister
activePodsLister
,
dockerClient
dockertools
.
DockerInterface
)
(
gpu
.
GPUManager
,
error
)
{
if
dockerClient
==
nil
{
return
nil
,
fmt
.
Errorf
(
"invalid docker client specified"
)
}
return
&
nvidiaGPUManager
{
allGPUs
:
sets
.
NewString
(),
dockerClient
:
dockerClient
,
activePodsLister
:
activePodsLister
,
}
}
,
nil
}
// Initialize the GPU devices, so far only needed to discover the GPU paths.
func
(
ngm
*
nvidiaGPUManager
)
Start
()
error
{
if
_
,
err
:=
os
.
Stat
(
NvidiaCtlDevice
);
err
!=
nil
{
if
ngm
.
dockerClient
==
nil
{
return
fmt
.
Errorf
(
"invalid docker client specified"
)
}
ngm
.
Lock
()
defer
ngm
.
Unlock
()
if
_
,
err
:=
os
.
Stat
(
nvidiaCtlDevice
);
err
!=
nil
{
return
err
}
if
_
,
err
:=
os
.
Stat
(
N
vidiaUVMDevice
);
err
!=
nil
{
if
_
,
err
:=
os
.
Stat
(
n
vidiaUVMDevice
);
err
!=
nil
{
return
err
}
ngm
.
Lock
()
defer
ngm
.
Unlock
()
ngm
.
defaultDevices
=
[]
string
{
nvidiaCtlDevice
,
nvidiaUVMDevice
}
_
,
err
:=
os
.
Stat
(
nvidiaUVMToolsDevice
)
if
os
.
IsNotExist
(
err
)
{
ngm
.
defaultDevices
=
append
(
ngm
.
defaultDevices
,
nvidiaUVMToolsDevice
)
}
if
err
:=
ngm
.
discoverGPUs
();
err
!=
nil
{
return
err
}
// Its possible that the runtime isn't available now.
// It
'
s possible that the runtime isn't available now.
allocatedGPUs
,
err
:=
ngm
.
gpusInUse
()
if
err
==
nil
{
ngm
.
allocated
=
allocatedGPUs
}
// We ignore errors w
ith
identifying allocated GPUs because it is possible that the runtime interfaces may be not be logically up.
// We ignore errors w
hen
identifying allocated GPUs because it is possible that the runtime interfaces may be not be logically up.
return
nil
}
...
...
@@ -130,13 +143,13 @@ func (ngm *nvidiaGPUManager) AllocateGPU(pod *v1.Pod, container *v1.Container) (
// Initialization is not complete. Try now. Failures can no longer be tolerated.
allocated
,
err
:=
ngm
.
gpusInUse
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"
f
ailed to allocate GPUs because of issues identifying GPUs in use: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"
F
ailed to allocate GPUs because of issues identifying GPUs in use: %v"
,
err
)
}
ngm
.
allocated
=
allocated
}
else
{
// update internal list of GPUs in use prior to allocating new GPUs.
if
err
:=
ngm
.
updateAllocatedGPUs
();
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"
f
ailed to allocate GPUs because of issues with updating GPUs in use: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"
F
ailed to allocate GPUs because of issues with updating GPUs in use: %v"
,
err
)
}
}
// Get GPU devices in use.
...
...
@@ -146,23 +159,24 @@ func (ngm *nvidiaGPUManager) AllocateGPU(pod *v1.Pod, container *v1.Container) (
if
int64
(
available
.
Len
())
<
gpusNeeded
{
return
nil
,
fmt
.
Errorf
(
"requested number of GPUs unavailable. Requested: %d, Available: %d"
,
gpusNeeded
,
available
.
Len
())
}
var
ret
[]
string
for
_
,
device
:=
range
available
.
List
()
{
if
gpusNeeded
>
0
{
ret
=
append
(
ret
,
device
)
// Update internal allocated GPU cache.
ngm
.
allocated
.
insert
(
string
(
pod
.
UID
),
device
)
}
gpusNeeded
--
ret
:=
available
.
List
()[
:
gpusNeeded
]
for
_
,
device
:=
range
ret
{
// Update internal allocated GPU cache.
ngm
.
allocated
.
insert
(
string
(
pod
.
UID
),
device
)
}
// Add standard devices files that needs to be exposed.
ret
=
append
(
ret
,
ngm
.
defaultDevices
...
)
return
ret
,
nil
}
// updateAllocatedGPUs updates the list of GPUs in use.
// It gets a list of running pods and then frees any GPUs that are bound to terminated pods.
// Returns error on failure.
func
(
ngm
*
nvidiaGPUManager
)
updateAllocatedGPUs
()
error
{
activePods
,
err
:=
ngm
.
activePodsLister
.
GetRunningPods
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"
f
ailed to list active pods: %v"
,
err
)
return
fmt
.
Errorf
(
"
F
ailed to list active pods: %v"
,
err
)
}
activePodUids
:=
sets
.
NewString
()
for
_
,
pod
:=
range
activePods
{
...
...
@@ -232,12 +246,12 @@ func (ngm *nvidiaGPUManager) gpusInUse() (*podGPUs, error) {
// add the pod and its containers that need to be inspected.
podContainersToInspect
=
append
(
podContainersToInspect
,
podContainers
{
string
(
pod
.
UID
),
containerIDs
})
}
ret
:=
newPodG
pu
s
()
ret
:=
newPodG
PU
s
()
for
_
,
podContainer
:=
range
podContainersToInspect
{
for
_
,
containerId
:=
range
podContainer
.
containerIDs
.
List
()
{
containerJSON
,
err
:=
ngm
.
dockerClient
.
InspectContainer
(
containerId
)
if
err
!=
nil
{
glog
.
V
(
3
)
.
Infof
(
"
f
ailed to inspect container %q in pod %q while attempting to reconcile nvidia gpus in use"
,
containerId
,
podContainer
.
uid
)
glog
.
V
(
3
)
.
Infof
(
"
F
ailed to inspect container %q in pod %q while attempting to reconcile nvidia gpus in use"
,
containerId
,
podContainer
.
uid
)
continue
}
...
...
pkg/kubelet/kubelet.go
View file @
2554b959
...
...
@@ -788,7 +788,12 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
klet
.
appArmorValidator
=
apparmor
.
NewValidator
(
kubeCfg
.
ContainerRuntime
)
klet
.
softAdmitHandlers
.
AddPodAdmitHandler
(
lifecycle
.
NewAppArmorAdmitHandler
(
klet
.
appArmorValidator
))
if
utilfeature
.
DefaultFeatureGate
.
Enabled
(
features
.
Accelerators
)
{
klet
.
gpuManager
=
nvidia
.
NewNvidiaGPUManager
(
klet
,
klet
.
dockerClient
)
if
kubeCfg
.
ContainerRuntime
!=
"docker"
{
return
nil
,
fmt
.
Errorf
(
"Accelerators feature is supported with docker runtime only."
)
}
if
klet
.
gpuManager
,
err
=
nvidia
.
NewNvidiaGPUManager
(
klet
,
klet
.
dockerClient
);
err
!=
nil
{
return
nil
,
err
}
}
else
{
klet
.
gpuManager
=
gpu
.
NewGPUManagerStub
()
}
...
...
pkg/kubelet/kubelet_pods.go
View file @
2554b959
...
...
@@ -28,7 +28,6 @@ import (
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"sync"
"time"
...
...
@@ -49,7 +48,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm"
kubecontainer
"k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/envvars"
"k8s.io/kubernetes/pkg/kubelet/gpu/nvidia"
"k8s.io/kubernetes/pkg/kubelet/images"
"k8s.io/kubernetes/pkg/kubelet/qos"
"k8s.io/kubernetes/pkg/kubelet/server/portforward"
...
...
@@ -96,21 +94,10 @@ func (kl *Kubelet) makeDevices(pod *v1.Pod, container *v1.Container) ([]kubecont
if
err
!=
nil
{
return
nil
,
err
}
devices
:=
[]
kubecontainer
.
DeviceInfo
{
{
PathOnHost
:
nvidia
.
NvidiaCtlDevice
,
PathInContainer
:
nvidia
.
NvidiaCtlDevice
,
Permissions
:
"mrw"
,
},
{
PathOnHost
:
nvidia
.
NvidiaUVMDevice
,
PathInContainer
:
nvidia
.
NvidiaUVMDevice
,
Permissions
:
"mrw"
,
},
}
for
i
,
path
:=
range
nvidiaGPUPaths
{
devices
=
append
(
devices
,
kubecontainer
.
DeviceInfo
{
PathOnHost
:
path
,
PathInContainer
:
"/dev/nvidia"
+
strconv
.
Itoa
(
i
),
Permissions
:
"mrw"
})
var
devices
[]
kubecontainer
.
DeviceInfo
for
_
,
path
:=
range
nvidiaGPUPaths
{
// Devices have to be mapped one to one because of nvidia CUDA library requirements.
devices
=
append
(
devices
,
kubecontainer
.
DeviceInfo
{
PathOnHost
:
path
,
PathInContainer
:
path
,
Permissions
:
"mrw"
})
}
return
devices
,
nil
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment