본문 바로가기

아이티 :D/Docker

nvidia-docker 컨테이너에서 사용중인 Gpu 제거하기

 

안녕하세요 :D

오늘은 지구에서 가장 핫한 IT키워드중 하나인 Docker를 주제삼아 포스팅 하려고 

합니다. 요즘 Docker로 개발환경을 구성하는 개발회사들이 굉장히 많아졌고 

저희팀 또한 모든 개발환경이 Docker로 구성되어 있습니다. 

즉 각각의 Docker Container에 서비스에 맞는 개발환경이 구성되어 있는거죠.

때문에 본의 아니게 Docker 삽질을 굉장히 많이 했습니다...

IT의 매력중 하나는 삽질이니까 괜찮아요...하하


Container는 Host와 매핑된 정보를 가지고 있습니다. 때문에 기동시에는 

이 정보를 가지고 있는 파일을 참조하게 됩니다.  그렇다면 

질문: GPU 4개를 사용중인 Docker Container는 GPU를 1개 제거한다면 

기동이 될까요 안될까요?

정답은 "설정파일을 수정하지 않는 이상 기동이 안된다"입니다.


테스트를 하기위해 4개중 1개의 GPU를 제거하고 Container를 기동했을때 

"linux runtime spec devices: error gathering device information while adding 

 custom device /dev/nvidia3"

이라는 에러메시지를 확인할 수 있었고 GPU를 제거하면서 /dev/nvidia3 

디바이스에 대한 정보를 수집할 수 없기때문에 에러가 나는것으로 보여집니다.


그렇다면 정상적으로 Container를 기동하기 위해서는 어떻게 해야 할까요?

저는 우선 Container의 정보를 확인하기 위해 docker inspect "컨테이너명" 

이라는 명령어를 실행했습니다. 실행결과 JSON형식으로 Container의 정보가 

쭉 나오는데 첫째로는 Container의 id를 확인했고 그 다음으로는 아래와 같이 

호스트에 매핑된 디바이스의 정보를 확인하였습니다.


{
"PathOnHost": "/dev/nvidia0",
"PathInContainer": "/dev/nvidia0",
"CgroupPermissions": "rwm"
},
{
"PathOnHost": "/dev/nvidia1",
"PathInContainer": "/dev/nvidia1",
"CgroupPermissions": "rwm"
},
{
"PathOnHost": "/dev/nvidia2",
"PathInContainer": "/dev/nvidia2",
"CgroupPermissions": "rwm"
},
{
"PathOnHost": "/dev/nvidia3",
"PathInContainer": "/dev/nvidia3",
"CgroupPermissions": "rwm"
}
 




보이시나요? 에러메시지에서 나온 "/dev/nvidia3" 디바이스가 보입니다.

GPU 4개가 nvidia0 ~ 3 번으로 네이밍되서 존재하는거 같네요.

GPU는 4개에서 3개가 되었기때문에 더이상 "/dev/nvidia3" 이라는 

디바이스는 존재하지 않습니다. 따라서 Container에서 저 "/dev/nvidia3" 이라는 

디바이스에 대한 모든걸 지우면 Container를 기동할 수 있지 않을까 라는 생각을 

했고, 시도해보기 위해 Container id에 해당하는 폴더로 이동하였습니다.

아래의 그림에서 생성된 Container들에 대한 폴더가 Container id 형식으로 

되어 있는걸 확인할 수 있습니다.


root@tensorflow01:/var/lib/docker/containers# ls
1c7389693206f3593f77faebb8d1215ad9e06ee75b6a6517f84117c95c971e7c
92ec8766bc24a033e36a119c03357b48dbba4ca83b9eea29772b84463d81822e
d6a993a2acefd47c90c6ccdf0f8b312f1bf4d47fcfb95c524d554f0edd00bd27
2f69ad48485ffc78778dda9eb148c82b765bf3b4f2b7dd7f901c446030a2b267
95ca02b1ebb1d268f0e46a0edad37573a3c46761a4437c5cb925c5f639b99108
fd2523d96b4b7e05ddd5e6aef8dc3631a3e57f2a92b65754483f562e8e28a00e
36a6486dca688e4318aa4024a4b69c65a3fbfb2e474603480cd9fb04225d9360
aeee6be051b9d03b02a75f26e26b9f7857addbdb86450d72f6af29c5db077471
43435870ccd8c5013de396997d811d2e1ed6c0c6b270b87102389658e5040412
c684858e1fff035ea27632065aa15c4ccd159a08a8120c41f0e508395e87385c


실행불가였던 Container에 해당하는 폴더로 이동 후 내부에 존재하는 파일의 

리스트를 확인해봅니다.


bfb2e474603480cd9fb04225d9360# ls

36a6486dca688e4318aa4024a4b69c65a3fbfb2e474603480cd9fb04225d9360-json.log
checkpoints
config.v2.json
hostconfig.json
hostname
hosts
resolv.conf
resolv.conf.hash
shm

 

여기서 hostconfing.json이라는 파일이 보이실텐데요. 바로 이 파일이 호스트와 

컨테이너간의 매핑정보를 가지고 있습니다. 

따라서 이 파일내에 "/dev/nvidia3" 디바이스의 정보만 삭제한다면 Container는 

기동이 가능할꺼 같네요.


"Devices" :[{"PathOnHost":"/dev/nvidiactl","PathInContainer":"/dev/nvidiactl","CgroupPermissions":"rwm"},
{"PathOnHost":"/dev/nvidia-uvm","PathInContainer":"/dev/nvidia-uvm","CgroupPermissions":"rwm"},
{"PathOnHost":"/dev/nvidia-uvm-tools","Path InContainer":"/dev/nvidia-uvm-tools","CgroupPermissions":"rwm"},
{"PathOnHost":"/dev/nvidia0","PathInContainer":"/dev/nvidia0","CgroupPermissions":"rwm"},
{"PathOnHost":"/dev/nvidia1","PathInContainer":"/dev/nvidia1","CgroupPermissions ":"rwm"},
{"PathOnHost":"/dev/nvidia2","PathInContainer":"/dev/nvidia2","CgroupPermissions":"rwm"}
{"PathOnHost":"/dev/nvidia3","PathInContainer":"/dev/nvidia3","CgroupPermissions":"rwm"}],


"Devices" 라는 key의 Value들이 매핑된 디바이스의 정보인데요. "/dev/nvidia3"

에 해당하는 Value만 삭제한 후 hostconfig.json 파일을 저장하신 뒤 Container를

 기동하시면 Container가 잘 실행이 되는걸 확인하실 수 있습니다.


리소스 재분배 혹은 기타 다른 이유로 인해 GPU를 제거하는 경우가 그렇게 많지는 

않으실테지만 만약 그런 설계가 필요하신 경우 이렇게 매핑된 디바이스의 정보를 

삭제함으로써 기존의 Container를 사용하실 수 있습니다.

GPU를 새로 추가할때는 자동으로 config에 추가되는거 같은데, 제거할때는 

그렇게 안되는거 같아요. 이런식으로 Docker에 대한 삽질을 또 하나 끝냈습니다.

부디 이 정보로 도움을 받으시는분들이 계셨으면 좋겠어요. :)