您好,登錄后才能下訂單哦!
《深入剖析Kubernetes - 08 | 白話容器基礎(四):重新認識Docker容器》
1、Dockerfile 制作
制作rootfs 常用的方式:Dockerfile
#?使用官方提供的?Python?開發鏡像作為基礎鏡像 FROM?python:2.7-slim #?將工作目錄切換為?/app WORKDIR?/app #?將當前目錄下的所有內容復制到?/app?下 ADD?.?/app #?使用?pip?命令安裝這個應用所需要的依賴 RUN?pip?install?--trusted-host?pypi.python.org?-r?requirements.txt #?允許外界訪問容器的?80?端口 EXPOSE?80 #?設置環境變量 ENV?NAME?World #?設置容器進程為:python?app.py,即:這個?Python?應用的啟動命令 CMD?["python",?"app.py"]
注意事項:
1、ENTRYPOINT 和 CMD 為容器啟動必需參數,docker會提供一個默認的ENTRYPOINT : /bin/sh -c ,故在不指定ENTRYPOINT 時,直接指定CMD,實際上執行的命令是/bin/sh -c CMD
2、ADD 和 COPY 的區別:ADD 可以如果添加的是一個壓縮包,會自動解壓,COPY不會
3、每個指令都會生成對應的鏡像層,所以在寫RUN的時候可以通過連接符寫多個命令,避免產生過多的鏡像層,例如:
RUN?ln?-s?/data/services/nginx?/usr/local/nginx?&&?\ ????mkdir?-p?/data/weblog/nginx?&&?\ ????/etc/init.d/nginx?start
創建完dockerfile 通過以下命令構建鏡像(在Dockerfile所在目錄下)
#?docker?build?-t?test-images?.
然后通過docker push 上傳到鏡像倉庫
#?docker?tag?test-images?test/nginx:1.14.2? #?docker?push?test/nginx:1.14.2
也可以通過commit的方式創建容器鏡像,具體做法如下;
docker?exec?-it?4ddf4638572d?/bin/sh #?在容器內部新建了一個文件 root@4ddf4638572d:/app#?touch?test.txt root@4ddf4638572d:/app#?exit #?將這個新建的文件提交到鏡像中保存 $?docker?commit?4ddf4638572d?geektime/helloworld:v2
docker commit 其實就是在容器起來后,加上最上層的讀寫層,還有原先鏡像中的只讀層構成鏡像。其中只讀層在宿主機上是共享的,不會占用額外空間。
根據聯合文件系統,在鏡像rootfs上做的任何更改都會在最上層先復制一層,再此基礎上進行修改,也就是所謂的寫時復制(copy on write)
2、docker exec 實現原理
宿主機上可以看到容器執行的進程,通過PS 看到進程pid后(假設為25686),在/proc/25686/ns 這個目錄下,可以看到全部ns對應的文件
ls?-l??/proc/25686/ns total?0 lrwxrwxrwx?1?root?root?0?Aug?13?14:05?cgroup?->?cgroup:[4026531835] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?ipc?->?ipc:[4026532278] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?mnt?->?mnt:[4026532276] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?net?->?net:[4026532281] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?pid?->?pid:[4026532279] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?pid_for_children?->?pid:[4026532279] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?user?->?user:[4026531837] lrwxrwxrwx?1?root?root?0?Aug?13?14:05?uts?->?uts:[4026532277]
然后通過setns() 的系統調用,即可將進程加入到對應的ns中。
setns() 需要2個參數,第一個參數是要加入的namespace文件路徑,如/proc/25686/ns/net;第二個參數是要執行的程序,如/bin/bash
當docker啟動時指定--net=host,則容器啟動時不會為進程啟動network namespace,容器跟宿主機共享一個網絡棧。
3、voluem實現機制
主要解決宿主機和容器之間文件互通的問題,例如:
(1) 宿主機上如何訪問到容器產生的文件
(2) 容器怎么訪問到宿主機上的文件
在docker上,可以通過以下兩種方式實現
$?docker?run?-v?/test?... $?docker?run?-v?/home:/test?...
第一種方式相當于在宿主機本地創建一個temp目錄,再掛載到容器的/test目錄
第二種方式則是將宿主機上的/home目錄掛載到容器的/test目錄
本質上是使用了linux的bind mount機制,其主要作用是允許將一個目錄或文件而不是這塊設備掛載到指定目錄上。其原理是一個inode替換的過程,在linux中,inode存放的文件內容的對象,而dentry則存放的是指向這個對象的指針。故這個掛載的過程,實際上就是修改指針,指向另外一個inode,執行umount 時則將指針指向回原來的inode。
注意:
1、在掛載目錄上做的操作并不會影響源目錄
2、對于掛載目錄的修改,執行docker commit 時不會生效,只會創建對應的空目錄
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。