鏡像的概念
鏡像可以理解為應用程式的集裝箱,而docker用來裝卸集裝箱,
docker鏡像含有啟動容器所需要的檔案系統及其內容,因此,其用于創建并啟動容器,
docker鏡像采用分層構建機制,最底層為bootfs,其上為rootfs
bootfs:用于系統引導的檔案系統,包括bootloader和kernel,容器啟動完成后會被卸載以節約記憶體資源
rootfs:位于bootfs之上,表現為docker容器的根檔案系統
傳統模式中,系統啟動之時,內核掛載rootfs會首先將其掛載為“只讀”模式,完整性自檢完成后將其重新掛載為讀寫模式
docker中,rootfs由內核掛載為“只讀”模式,而后通過“聯合掛載”技術額外掛載一個“可寫”層
注意:當洗掉容器時,這個容器自有的“可寫”層會一起被洗掉

docker鏡像層

位于下層的鏡像稱為父鏡像(parrent image),最底層的稱為基礎鏡像(base image);
最上層為“可讀寫”層,其下的均為“只讀”層,
docker存盤驅動
docker提供了多種存盤驅動來實作不同的方式存盤鏡像,下面是常用的幾種存盤驅動:
- AUFS
- OverlayFS
- Devicemapper
- Btrfs
- VFS
AUFS
AUFS(AnotherUnionFS)是一種Union
FS,是檔案級的存盤驅動,AUFS是一個能透明覆寫一個或多個現有檔案系統的層狀檔案系統,把多層合并成檔案系統的單層表示,簡單來說就是支持將不同目錄掛載到同一個虛擬檔案系統下的檔案系統,這種檔案系統可以一層一層地疊加修改檔案,無論底下有多少層都是只讀的,只有最上層的檔案系統是可寫的,當需要修改一個檔案時,AUFS創建該檔案的一個副本,使用CoW將檔案從只讀層復制到可寫層進行修改,結果也保存在可寫層,在Docker中,底下的只讀層就是image,可寫層就是Container,AUFS檔案系統據說有3W行代碼,而ext4檔案系統卻只有4000-5000行左右代碼,這些代碼是要被整合進內核的,后來AUFS申請要被合并進內核代碼的時候,linuz覺得它這代碼太過臃腫,于是拒絕了,因此AUFS這個檔案系統一直以來就不是linux內核中自有的檔案系統,想用AUFS這個檔案系統的話,必須自己向內核打補丁并去編譯使用它,但redhat系列的作業系統一向以穩定著稱,不會干這種出格的事,所以在redhat系列作業系統中使用AUFS并無可能,而ubuntu上的docker默認使用的就是AUFS,
OverlayFS
Overlay是Linux內核3.18后支持的,也是一種Union
FS,和AUFS的多層不同的是Overlay只有兩層:一個upper檔案系統和一個lower檔案系統,分別代表Docker的鏡像層和容器層,當需要修改一個檔案時,使用CoW將檔案從只讀的lower復制到可寫的upper進行修改,結果也保存在upper層,在Docker中,底下的只讀層就是image,可寫層就是Container,目前最新的OverlayFS為Overlay2,AUFS和Overlay都是聯合檔案系統,但AUFS有多層,而Overlay只有兩層,所以在做寫時復制操作時,如果檔案比較大且存在比較低的層,則AUSF會慢一些,而且Overlay并入了linux
kernel mainline,AUFS沒有,目前AUFS已基本被淘汰,
DeviceMapper
Device
mapper是Linux內核2.6.9后支持的,提供的一種從邏輯設備到物理設備的映射框架機制,在該機制下,用戶可以很方便的根據自己的需要制定實作存盤資源的管理策略,AUFS和OverlayFS都是檔案級存盤,而Device
mapper是塊級存盤,所有的操作都是直接對塊進行操作,而不是檔案,Device
mapper驅動會先在塊設備上創建一個資源池,然后在資源池上創建一個帶有檔案系統的基本設備,所有鏡像都是這個基本設備的快照,而容器則是鏡像的快照,所以在容器里看到檔案系統是資源池上基本設備的檔案系統的快照,并沒有為容器分配空間,當要寫入一個新檔案時,在容器的鏡像內為其分配新的塊并寫入資料,這個叫用時分配,當要修改已有檔案時,再使用CoW為容器快照分配塊空間,將要修改的資料復制到在容器快照中新的塊里再進行修改,OverlayFS是檔案級存盤,Device
mapper是塊級存盤,當檔案特別大而修改的內容很小,Overlay不管修改的內容大小都會復制整個檔案,對大檔案進行修改顯然要比小檔案要消耗更多的時間,而塊級無論是大檔案還是小檔案都只復制需要修改的塊,并不是整個檔案,在這種場景下,顯然device
mapper要快一些,因為塊級的是直接訪問邏輯盤,適合IO密集的場景,而對于程式內部復雜,大并發但少IO的場景,Overlay的性能相對要強一些,
docker registry
啟動容器時,docker daemon會試圖從本地獲取相關的鏡像,本地鏡像不存在時,其將從Registry中下載該鏡像并保存到本地,
Registry用于保存docker鏡像,包括鏡像的層次結構和元資料,用戶可以自建Registry,亦可使用官方的Docker Hub,
docker registry的分類:
- Sponsor Registry:第三方的Registry,供客戶和Docker社區使用
- Mirror Registry:第三方的Registry,只讓客戶使用
- Vendor Registry:由發布docker鏡像的供應商提供的registry
- Private Registry:通過設有防火墻和額外的安全層的私有物體提供的registry
docker registry的組成:
- Repository
- 由某特定的docker鏡像的所有迭代版本組成的鏡像倉庫
- 一個Registry中可以存在多個Repository
- Repository可分為“頂層倉庫”和“用戶倉庫”
- 用戶倉庫名稱格式為“用戶名/倉庫名”
- 每個倉庫可包含多個Tag(標簽),每個標簽對應一個鏡像
- Index
- 維護用戶帳戶、鏡像的檢驗以及公共命名空間的資訊
- 相當于為Registry提供了一個完成用戶認證等功能的檢索介面
Docker
Registry中的鏡像通常由開發人員制作,而后推送至“公共”或“私有”Registry上保存,供其他人員使用,例如“部署”到生產環境,
docker鏡像的制作
多數情況下,我們做鏡像是基于別人已存在的某個基礎鏡像來實作的,我們把它稱為base
image,比如一個純凈版的最小化的centos、ubuntu或debian,那么這個最小化的centos鏡像從何而來呢?其實這個基礎鏡像一般是由Docker
Hub的相關維護人員,也就是Docker官方手動制作的,這個基礎鏡像的制作對于Docker官方的專業人員來說是非常容易的,但對于終端用戶來說就不是那么容易制作的了,
Docker Hub
Docker Hub is a cloud-based registry service which allows you to link
to code repositories, build your images and test them, stores manually
pushed images, and links to Docker Cloud so you can deploy images to
your hosts.It provides a centralized resource for container image discovery,
distribution and change management, user and team collaboration, and
workflow automation throughout the development pipeline.

Docker Hub provides the following major features:
- Image Repositories
- Find and pull images from community and official libraries, and manage, push to, and pull from private images libraries to which you have access.
- Automated Builds
- Automatically create new images when you make changes to a source code repository.
- Webhooks
- A feature of Automated Builds, Webhooks let you trigger actions after a successful push to a repository.
- Organizations
- Create work groups to manage access to image repositories.
- GitHub and Bitbucket Integration
- Add the Hub and your Docker Images to your current workflows.
docker鏡像的獲取
To get Docker images from a remote registry(such as your own Docker
registry)and add them to your local system, use the docker pull
command:
docker pull <registry>[:<port>]/[<namespace>/]<name>:<tag>
The is a host that provides the docker-distribution service on TCP
(default:5000)Together, and identify a particular image controlled by at the
registry
- Some registries also support raw ;for those, is optional
- When it is included, however, the additional level of hierarchy that provides is usefull to distinguish between images with the same
The additional level of hierarchy of
| Namespace | Examples(/) |
|---|---|
| organization | redhat/kubernetes, google/kubernetes |
| login(username) | Alice/application, bob/application |
| role | devel/database, test/database, prod/database |
鏡像的生成
鏡像的生成途徑:
- Dockerfile
- 基于容器制作
- Docker Hub automated builds

基于容器制作鏡像
Create a new image from container’s changes
Usage:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
| Options | Default | Description |
|---|---|---|
| —author, -a | Author (e.g., “John Hannibal Smith hannibal@a-team.com”) | |
| -c, --change list | Apply Dockerfile instruction to the created image | |
| -m, --message string | Commit message | |
| -p, --pause | true | Pause container during commit |
下載centos系統鏡像
[root@hfnt ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
[root@hfnt ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 300e315adb2f 7 months ago 209MB
使用鏡像啟動容器并進入容器
[root@hfnt ~]# docker run -it --name centos-nginx centos /bin/bash
[root@5634002b21a0 /]#
安裝epel源和nginx
[root@5634002b21a0 /]# yum install -y nginx
[root@5634002b21a0 /]# yum install -y epel-release
配置nginx為前臺啟動模式
[root@5634002b21a0 /]# vi /etc/nginx/nginx.conf
daemon off;#添加以下內容
啟動nginx
[root@5634002b21a0 /]# /usr/sbin/nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
[root@5634002b21a0 /]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 [::]:80 [::]:*
在創建鏡像時,我們不能關閉容器,必須使其處于運行狀態,所以我們必須要另起一個終端,然后執行
[root@hfnt ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5634002b21a0 centos "/bin/bash" 9 minutes ago Up 9 minutes centos-nginx
[root@hfnt ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5634002b21a0 centos "/bin/bash" 9 minutes ago Up 9 minutes centos-nginx
[root@hfnt ~]# docker commit -m "nginx" -a "centos-nginx" -c 'CMD ["/usr/sbin/nginx"]' 5634002b21a0 centos-nginx
sha256:e14437ec4d807def5810aa6162a2c75d2875414c2741c0a9ab3d898d76c96c7c
[root@hfnt ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-nginx latest e14437ec4d80 25 seconds ago 318MB
centos latest 300e315adb2f 7 months ago 209MB
[root@hfnt ~]# docker run --name nginx -p 8888:80 -d centos-nginx
e135f06af0432ddd2c5f06f058d71264b7fcf319948a0b4856d2e9d9de69c0b9
–name nginx 為容器定義名稱,名稱為nginx
-p 8888:80 將宿主機的8888埠映射到容器內的80埠
-d 指定該容器在后天運行
cetnos-nginx 指定使用centos-nginx鏡像來創建容器
[root@hfnt ~]# curl 172.17.0.3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
/*<![CDATA[*/
body {
background-color: #fff;
color: #000;
font-size: 0.9em;
font-family: sans-serif,helvetica;
margin: 0;
padding: 0;
}
:link {
color: #c00;
}
:visited {
color: #c00;
}
a:hover {
color: #f50;
}
h1 {
text-align: center;
margin: 0;
padding: 0.6em 2em 0.4em;
background-color: #900;
color: #fff;
font-weight: normal;
font-size: 1.75em;
border-bottom: 2px solid #000;
}
h1 strong {
font-weight: bold;
font-size: 1.5em;
}
h2 {
text-align: center;
background-color: #900;
font-size: 1.1em;
font-weight: bold;
color: #fff;
margin: 0;
padding: 0.5em;
border-bottom: 2px solid #000;
}
hr {
display: none;
}
.content {
padding: 1em 5em;
}
.alert {
border: 2px solid #000;
}
img {
border: 2px solid #fff;
padding: 2px;
margin: 2px;
}
a:hover img {
border: 2px solid #294172;
}
.logos {
margin: 1em;
text-align: center;
}
/*]]>*/
</style>
</head>
<body>
<h1>Welcome to <strong>nginx</strong> on Red Hat Enterprise Linux!</h1>
<div class="content">
<p>This page is used to test the proper operation of the
<strong>nginx</strong> HTTP server after it has been
installed. If you can read this page, it means that the
web server installed at this site is working
properly.</p>
<div class="alert">
<h2>Website Administrator</h2>
<div class="content">
<p>This is the default <tt>index.html</tt> page that
is distributed with <strong>nginx</strong> on
Red Hat Enterprise Linux. It is located in
<tt>/usr/share/nginx/html</tt>.</p>
<p>You should now put your content in a location of
your choice and edit the <tt>root</tt> configuration
directive in the <strong>nginx</strong>
configuration file
<tt>/etc/nginx/nginx.conf</tt>.</p>
<p>For information on Red Hat Enterprise Linux, please visit the <a href="http://www.redhat.com/">Red Hat, Inc. website</a>. The documentation for Red Hat Enterprise Linux is <a href="http://www.redhat.com/docs/manuals/enterprise/">available on the Red Hat, Inc. website</a>.</p>
</div>
</div>
<div class="logos">
<a href="http://nginx.net/"><img
src="nginx-logo.png"
alt="[ Powered by nginx ]"
width="121" height="32" /></a>
<a href="http://www.redhat.com/"><img
src="poweredby.png"
alt="[ Powered by Red Hat Enterprise Linux ]"
width="88" height="31" /></a>
</div>
</div>
</body>
</html>
使用瀏覽器訪問容器內的nginx
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kAKV21Oa-1627485323666)(C:\Users\Teng\AppData\Roaming\Typora\typora-user-images\image-20210728225803692.png)]](https://img.uj5u.com/2021/07/31/251717311603335.png)
將我們做好的鏡像push上去
[root@hfnt ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: wssz123123
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@hfnt ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-nginx latest e14437ec4d80 8 minutes ago 318MB
centos latest 300e315adb2f 7 months ago 209MB
[root@hfnt ~]# docker tag e14437ec4d80 wssz123123/centos-nginx:0.1
[root@hfnt ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-nginx latest e14437ec4d80 10 minutes ago 318MB
wssz123123/centos-nginx 0.1 e14437ec4d80 10 minutes ago 318MB
centos latest 300e315adb2f 7 months ago 209MB
[root@hfnt ~]# docker push wssz123123/centos-nginx:0.1
The push refers to repository [docker.io/wssz123123/centos-nginx]
1b8bc3e1561c: Pushed
2653d992f4ef: Pushed
0.1: digest: sha256:8944ed277d7362e83ea8fea88e3194b6ac5c0125f99d06c882d3e31149ee92a6 size: 741



轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/291155.html
標籤:其他
