特別說明:要在個人隨筆後寫評論的小夥伴們請注意了,個人博客開啓了 MathJax 數學公式支持,MathJax 使用
$
標記數學公式的開始和結束。若是某條評論中出現了兩個$
,MathJax 會將兩個$
之間的內容按照數學公式進行排版,從而致使評論區格式混亂。若是你們的評論中用到了$
,可是又不是爲了使用數學公式,就請使用\$
轉義一下,謝謝。html
想從頭閱讀該系列嗎?下面是傳送門:git
關於 Docker 的介紹,我這裏就不廢話了。Docker 是什麼?Docker 和虛擬機有什麼區別?Docker 適用的場景是什麼?這些介紹早就爛大街了。你們能夠去 Docker 的官網首頁看介紹,也能夠在博客園的首頁隨便搜一下,入門級的文章處處都是。若是想了解更深一點的技術細節,能夠看 sparkdev 的博客,我這裏先對 sparkdev 表示感謝,我這篇隨筆中,引用了他的部份內容。並且,我這篇的標題是「我對 Docker 的使用的學習心得」,重點是學習它的使用,而不是它的原理。程序員
在 Ubuntu 中安裝 Docker 真的是太方便了。徹底不用訪問 Docker 的官網,不須要本身去下載,apt
超級牛力瞬間搞定。稍微須要注意的是,不是安裝docker
軟件包,而是安裝docker.io
軟件包。首先,我先用sudo aptitude search docker
命令查看 Ubuntu 的軟件源中有哪些和 Docker 有關的包,以下圖:
github
其中docker
被明確標記爲 transitional package,因此咱們安裝下面的docker.io
包,使用sudo aptitude install docker.io
命令。安裝完成後,使用sudo docker --version
查看一下,發現是最新的版本,並且是社區版,不是企業版,因此其版本號爲 18.06.1-ce。以下圖:
docker
只要稍微瞭解一點 Docker 的人都知道有一個 dockerhub,和咱們經常使用的 github 同樣,能夠得到別人精心製做並分享的資源。在 github 中,咱們能夠找到咱們感興趣的項目,並把它 clone 到本地。而在 dockerhub 中,這些資源叫 Image,咱們能夠把咱們感興趣的 Image 拉到本地,並以該 Image 爲基礎,運行一些 Container。編程
關於 Image 和 Container 的概念,我這裏再也不廢話。我選擇了一個 ubuntu,還有一個 spacevim。使用的命令分別爲sudo docker pull ubuntu
和sudo docker pull spacevim
。以下圖:
json
上面拉取 Image 的操做看似簡單,其實經歷過失敗,主要緣由就是國外的倉庫被牆擋住了。解決這個問題的方法,就是設置 Docker 使用中國的 Image 倉庫。其設置方法爲修改/etc/docker/daemon.json
配置文件,若是沒有該文件,就新建一個。將其內容修改成:ubuntu
{ "registry-mirrors":["https://registry.docker-cn.com"] }
而後,使用以下命令重啓 Docker 服務:vim
systemctl daemon-reload systemctl restart docker
使用sudo docker image ls
命令能夠查看咱們的機器上有哪些 Image,使用sudo docker container ps -a
命令,能夠查看咱們的機器上有哪些 Container。在上圖中,在咱們拉取鏡像以前,它們的顯示結果都是空的。sudo docker container ps -a
命令之因此要加上-a
參數,就是爲了顯示全部的 Container,包括運行的和中止的。bash
拉取完了之後,再使用sudo docker image ls
命令,顯示的就再也不是空的了。以下圖:
而後,使用sudo docker run -it spacevim/spacevim nvim
命令運行一個容器,啓動 SpaceVim,以下圖:
在上圖中,我分別寫了一個 C 語言的文件和一個 Python 語言的文件,同時修改了一下 SpaceVim 本身的配置文件。
SpaceVim 是一個很是優秀的 Vim 整合項目,簡單點說,就是經過各類插件把 Vim 打形成一個萬能的 IDE,並且它對 NeoVim 支持很是好。確實很漂亮,功能也確實很強大。可是,我係統上用的 Vim 是我本身配的一個很是簡潔的 Vim(請看我前面的隨筆),若是再在系統上安裝 SpaceVim 就不太方便。因此,使用 SpaceVim 官方提供的 Docker Image 就是一個很是方便的選擇了。
從上面的截圖能夠看出,咱們最經常使用的命令就是sudo docker run
命令,它就是以某個 Image 爲基礎運行一個新的 Container,注意,是新的 Container 哦。也就是說,每執行一次sudo docker run
,就創建一個新的 Container,哪怕它們用的是同一個 Image。若是要啓動一個已經存在的 Container 怎麼辦呢?別擔憂,有sudo docker container start
命令。
最經常使用的參數是-i
和-t
,只有這樣,咱們纔可以和 Container 中的程序進行交互。其次,就是-p
參數,能夠把 Container 中的某個端口映射到主機的某個端口,這對網絡服務很是重要。還有-v
參數,能夠把主機的某個目錄映射到 Container 中的某個目錄,這樣,共享文件就很方便了。
使用 SpaceVim 的 Image 啓動一個 Container 後,問題來了。每次啓動這個 Container,就自動運行 nvim,進入 SpaceVim 的界面,編輯文件是不成問題,但是這個編輯器界面畢竟不是 Shell 不是嗎?咱們其它的管理工做怎麼作?
而咱們使用 ubuntu 的 Image 啓動 Container 後就很方便了,直接進入 Bash。因此問題來了,在一個 Container 中能夠執行多個程序嗎?
答案是確定的,那就是sudo docker container exec
命令,以下圖:
從上圖能夠看出,咱們進入 Ubuntu 時,直接和 Shell 進行交互,因此能夠很是方便地使用ls
、pwd
等命令,甚至可使用cat /etc/os-release
命令查看系統的版本信息。固然,還可使用apt
安裝軟件。而要想進入 SpaceVim 所在的容器,就須要使用sudo docker container exec -i spacevim-1.0 bash
命令再啓動一個 Shell,這樣就可使用ls
命令看到咱們剛纔編輯的test.c
和test.py
了。甚至可使用ps
命令查看該容器中運行的進程。
Docker 的官網就別看了,難受。買書呢?費錢!還不必定能找到優秀的。最好的辦法就是查看 Docker 的手冊頁啦。使用sudo dpkg -L docker.io
命令,能夠看到系統中安裝了好多手冊頁,以下圖:
若是輸入man docker
,就是下面這樣:
若是輸入man docker run
,就是下面這樣:
若是想本身寫 Dockfile,就輸入man Dockfile
。我就不繼續截圖了。每個手冊頁均可以從頭讀到尾,這種流暢的感受是在 Docker 的官網上查看文檔體會不到的。
運行一個 Container 後,咱們能夠在上面編輯文件、更改配置,還能夠按需安裝軟件。作了不少工做後,咱們能夠把這個 Container 打包帶走嗎?固然能夠了,使用sudo docker container commit
命令能夠基於一個 Container 再建立一個鏡像。而後使用sudo docker push
命令就能夠把這個鏡像再上傳到 dockerhub 上了。固然,這只是理想狀態,畢竟有牆的存在,並且 dockerhub 要註冊後才能上傳鏡像。因此上傳這個事就不是那麼好作啊。
不過不要緊,咱們能夠打包用 U 盤帶走。sudo docker image save
命令能夠把 Image 導出爲本地文件。使用 U 盤帶走後,使用sudo docker image load
命令能夠從這個文件再導入鏡像。
其實我關心的是顯卡。在個人上上篇隨筆中,我寫到了使用 CUDA 加速計算,而 CUDA 須要 Nvidia 的顯卡支持。若是我要用 Docker 構建一個 CUDA 的開發環境,那就須要我 Docker 中的程序可以訪問主機的顯卡資源。從理論上講,這是能夠的。畢竟 Docker 不一樣於虛擬機,Docker 是和主機共享內核的,而 Nvidia 的驅動,只是一個內核模塊。因而,我在使用 Ubuntu 鏡像的 Container 中測試了一下。使用lsmod
命令查看內核模塊,發現它確實是使用的 Nvidia 的驅動,以下圖:
另外,使用sudo aptitude install nvidia-cuda-toolkit
安裝 cuda-toolkit,也是能夠安裝的。所以,證實 Docker 中的程序能夠訪問主機上的全部硬件資源。使用 Docker 構建咱們本身的開發環境不是夢。
答案是能夠。
先來分析一下思路。在 Docker 中運行控制檯程序時,咱們須要給程序一個標準輸入輸出,就能夠和程序交互了。在 Docker 中運行 Web 服務時,咱們須要給程序一個 IP 和端口,就能夠和服務交互了。GUI 程序須要什麼呢?它們須要一個 X Server 的 Display。咱們給它就好了。
DISPLAY的格式是unix:端口
或主機名:端口
,前一種格式表示使用本地的 unix 套接字,後一種表示使用 tcp 套接字。默認狀況下,X11的服務端會監聽本地的unix:0
端口,而 DISPLAY 的默認值爲:0
,這其實是unit:0
的簡寫。所以若是在 Linux 的控制檯啓動一個圖形程序,它就會出如今當前主機的顯示屏幕中。
而 unix 套接字就是一個文件,因此,可使用-v
參數,將主機的 unix 套接字共享到 Container 中,而後,運行在 Container 中的 GUI 程序,就會出如今主機的屏幕上。
其實早在2015年的「Docker全球開發者大會」上,Docker 自家的美女程序員「傑西·弗萊澤爾(Jessie Frazelle)」就展現了一系列黑魔法同樣的鏡像。這些鏡像中的大多數都使用了圖形界面。好比,她使用這樣的命令docker run -d -v /tmp/.X11-unix:/tmp/.X11-unix jess/libreoffice
在 Docker 中運行了 LibreOffice(這只是舉例,真要運行成功還有不少細節須要完善),其中最重要的參數就是-v /tmp/.X11-unix:/tmp/.X11-unix
,也就是把主機的 unix 套接字映射到 Container 中。
OK,關於 Docker,今天就寫這麼多。我感受我又找到了新世界的大門。
該隨筆由京山遊俠在2019年03月08日發佈於博客園,引用請註明出處,轉載或出版請聯繫博主。QQ郵箱:1841079@qq.com