一、何為docker
docker最早基于LXC實作(LinuX Container)從0.7版本以後開始去除LXC轉而使用自行開發的libcontainer,從1.11開始,演進為runC和containerd;docker是go語言開發,基于Linux核心的cgroup,namespace以及AUFS類似的Union FS(聯合檔案系統)等技術,對程序進行封裝隔離,屬于作業系統層面的虛拟化技術,由于隔離的程序獨立于主控端和其他的隔離程序,是以也稱其為容器。
docker在容器的基礎上進行了進一步的封裝從檔案系統,網絡互聯到程序隔離等,極大簡化了容器的建立和維護管理。使得docker技術比虛拟機技術更為輕便,快捷。
虛拟機與docker比較:
圖檔引用自網絡
由上面的比較圖可以看同樣啟動一個服務;虛拟機會多一層作業系統,而docker和主控端共用核心系統;是以docker占用資源更少,資源使用率更高;
虛拟機與docker對比
docker優點總結:
高效的資源使用率
快速的啟動
一緻的運作環境
持續将會和部署
更輕松的遷移
便捷的維護和擴充
二、dcoker安裝
系統要求:CentOS7.x_x64且安裝Docker CE版本(社群版),不要使用epel倉庫自帶的docker docker從1.17後主要分docker-ce和docker-ee(企業版,你懂滴,就好比mysql企業版與社群版,如果還不明白當我沒說)
以下安裝基于CentOS 7.4_x64 最小化安裝
[root@docker ~]# uname -r
3.10.0-693.21.1.el7.x86_64
[root@docker ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
#禦載自帶元件
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine -y
#安裝依賴元件
[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
#添加國内源
yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
#添加官方源
[root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#最新版的docker CE 使用以下指令
[root@docker ~]# yum-config-manager --enable docker-ce-edge
#測試版docker ce 使用以下指令 (可選)
[root@docker ~]# yum-config-manager --enable docker-ce-test
#安裝docker ce
[root@docker ~]# yum makecache fast
[root@docker ~]# yum install install docker-ce
#注意官方docker-ce可能有點慢~
#或使用腳本自動安裝
[root@docker ~] # curl -fsSL get.docker.com -o get-docker.sh
[root@docker ~]# sh get-docker.sh --mirror Aliyun
#安裝完檢視版本資訊
[root@docker ~]# docker --version
Docker version 18.04.0-ce, build 3d479c0
#啟動docker
[root@docker ~]# systemctl start docker
以上表示安裝成功docker-ce版本,以下的示例測試均在此基礎上進行;如果是ubuntu安裝docker請參考這裡ubuntu安裝docker-ce
三、docker元件
從實體上講client <--> docker daemon <--> Registry Server
邏輯上:
Images:
鏡像隻讀,分層鏡像機制,最後一層可讀寫,可共享,或了解為OS
Containers:容器:
是從鏡像啟動建立的,類似程式與程序的關系,而Images鏡像就是程式檔案,運作起來成為程序;鏡像是靜态定義,容器是鏡像運作時的實體;容器可以被建立,啟動,停止,删除,暫停;容器實質是程序;
Registry:Image Repositories (存放共享的鏡像庫,類似yum庫)docker官方提供倉庫位址hub.docker.com
容器的狀态與指令:
常用狀态如:
created:docker create(不常用),docker run 指令從鏡像建立并運作
running:docker run 指令從鏡像建立并運作
paused:docker paused 暫停容器
stopped:docker stop 停止運作某容器,或通過docker kill容器
狀态間轉化如圖:
以上指令均可通過docker --help 或docker COMMAND --help擷取子指令幫助
檢視docker相關資訊:
docker --version
Docker version 18.03.0-ce, build 0520e24
擷取docker daemon運作的資訊
docker info
鏡像相關操作
列出本機鏡像:
docker images
拉取下載下傳鏡像:
docker pull 庫/鏡像名:版本 預設是docker.io/鏡像名:lastest
删除鏡像:
删除關確定沒有容器使用
docker rmi 鏡像名|鏡像ID
查找鏡像:
docker search 鏡像名
[root@docker ~]# docker search busybox
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
busybox Busybox base image. 1239 [OK]
progrium/busybox 66 [OK]
說明:STARS可了解為擷取的贊,OFFICIAL OK表示官方出的
示例:拉取busybox
[root@docker ~]# docker pull busybox
Using default tag: latest
注意:沒有指定倉庫,預設從docker.io上擷取最新latest版本
容器相關常用操作
docker run 選項 鏡像:建立并運作一個容器
選項如下:
--rm 運作容器停止退出後删除容器
--it 互動式運作容器
-d 背景daemon運作(和--rm不可同時出現)
--name 指定容器名
-p [port:port] 把容器中的端口映射出來
docker ps :檢視運作中的容器
docker ps -a:檢視所有的容器(包括停止狀态)
docker start :啟動處于停止狀态的容器
docker inspect 容器:查運作中容器資訊
docker network ps :檢視docker 網絡接口
docker attach:附加至某運作狀态的容器的終端裝置;(運作在背景中的容)
docker exec:讓運作中的容器運作一個額外的程式(容器中有程式前台占終端運作情況下,後面有執行個體)
docker logs:輸出容器内部程式運作時輸出到終端的資訊
docker stats:動态方式顯示容器的資源占用狀态
docker top:顯示容器運作的程序
docker kill :停止容器(容器牌前台運作時)
docker stop:停止容器
docker tag 鏡像 新鏡像:标記鏡像
docker login -u 使用者名: 登入(預設docker.io需要注冊)使用者名
docker pull 鏡像:預設從docker.io倉庫擷取最新版本鏡像,如是私有倉庫需要登入
docker push 鏡像:登入後可push(預設docker.io)倉庫
docker rename:重命名容器
docker restart: 重新開機容器
docker pause:暫停容器
docker unpause:從暫停狀态恢複
docker rm :删除容器,需要注意的是容器隻能是關閉狀态才能删除
或運作進docker run --rm 表示運作停止後就删除容器
示例:從busybox鏡像啟動容器b1 前台運作
[root@docker ~]# docker run --rm -it --name b1 busybox
#
按crtl + p +q 從終端拆除(轉入背景)
#檢視容器
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
356979c81de8 busybox "sh" About a minute ago Up About a minute b1
說明:可以看到運作狀态是up 容器名指定為b1 可以通過docker stop b1 停止 (由于 --rm選項)即容器删除
[root@docker ~]# docker stop b1
b1
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
示例:背景啟動容器 b1
[root@docker ~]# docker run -d -it --name b1 busybox
b8548d53a69999b0c351dc779ebf18cdcfd40dc4d749bc7a6cec300d3ad958e5
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8548d53a699 busybox "sh" 17 seconds ago Up 16 seconds b1
[root@docker ~]# docker stop b1
b1
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8548d53a699 busybox "sh" 49 seconds ago Exited (137) 14 seconds ago b1
說明:通過背景啟動模式,在停止運作後 容器處于退出停止狀态,并不會删除,下次可以通過 docker start b1再次啟動,--rm和-d不能同時存在。
四、鏡像制作
鏡像制作有兩種方式,基于容器制作和基于(已有)鏡像制作;
基于(運作中)容器制作
在容器中完成操作後制作
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]
示例:基于busybox 鏡像啟動容器b1并在容器裡啟動httpd服務 并以此運作的容器制作鏡像
運作容器(進入容器操作)
[root@docker ~]# docker run -it --name b1 busybox
/ # mkdir -pv /data/html
created directory: '/data/'
created directory: '/data/html'
/ # echo " Busybox httpd server" >/data/html/index.html
/ # cat /data/html/index.html
Busybox httpd server
/ # httpd -h /data/html
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
....省略....
/ # netstat -ntpul
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::80 :::* LISTEN 8/httpd
按ctrl +p +q 進入背景(拆除終端)
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
477cf5b3abca busybox "sh" 4 minutes ago Up 4 minutes b1
從以上可以看出在b1容器中啟動了http 并偵聽在80端口上;拆除終端進入了背景運作;
基于運作中的b1容器制作鏡像并打上新的标簽名"docker.io/dyc2005/bbox:v0.1.1-httpd"
[root@docker ~]# docker commit -p -a "san <[email protected]>" b1 docker.io/dyc2005/bbox:v0.1.1-httpd
sha256:c4e8c59c4b577a568002789e7c266828a8e86dd9fdd825b05f91933a5e9710f0
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dyc2005/bbox v0.1.1-httpd c4e8c59c4b57 6 seconds ago 1.15MB
busybox latest 8ac48589692a 9 days ago 1.15MB
此時新的鏡像ID和busybox(産生b1容器)鏡像ID已經 不同了,此時也可通過
docker push 推到鏡像庫中
驗證:
基于新的鏡像背景啟動容器b2
補充:與上面效果類似
[root@docker ~]# docker commit -a "san" -c 'CMD ["/bindocke/httpd","-f","-h","/data/html"]' b1 docker.io/dyc2005/bbox:v0.1.2-httpd
#運作制作好的鏡像:
[root@docker ~]# docker run --name h2 -it dyc2005/bbox:v0.1.2-httpd
[root@docker ~]# docker exec h2 ps
PID USER TIME COMMAND
1 root 0:00 /bin/httpd -f -h /data/html
8 root 0:00 ps
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7147cb559d9 dyc2005/bbox:v0.1.3-httpd "/bin/httpd -f -h /d…" 22 seconds ago Up 21 seconds h2
[root@docker ~]# docker run -it -d --name b2 docker.io/dyc2005/bbox:v0.1.1-httpd httpd -f -h /data/html
b93754954d61b1a477ef361fcb348962b9b10004221263d9f4c69db193730a61
#檢視b2的資訊檢視ip
[root@docker ~]# docker inspect b2 |grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
#通路b2
[root@docker ~]# curl http://172.17.0.3
Busybox httpd server
至此基于運作中的容器制作鏡像完成!
此時産生一個問題,運作中的鏡像進入是docker attach b2
但你發現終端卡在那裡,由于httpd(容器中)前台運作,無法修改網頁
解決方法:
[root@docker ~]# docker exec -it b2 /bin/sh
/ # netstat -ntpul
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::80 :::* LISTEN 1/httpd
/ #
通過 docker exec 就可以進行運作在容器前端的中修改容器中的内容!這也是attach與exec指令的差別所在!
另外本次運作鏡像端口沒有做映射,後面會提到!一般不推薦如此制作鏡像;制作鏡像推薦使用Dockerfile檔案
基于鏡像制作
編輯 Dockerfile,而後根據此檔案制作;
詳細說明參照這裡
以下給出執行個體:
主控端上建立bbox
[root@docker ~]# mkdir -pv bbox/data
[root@docker ~]# cat /data/html/index.html
Busybox httpd server from Dockerfile.
[root@docker ~]#cat Dockerfiel
FROM busybox:latest
MAINTAINER "san" "<[email protected]>"
#COPY index.html /data/html/
COPY data /data/
VOLUME /data/html
EXPOSE 80/tcp
ENV epel_repo_file http://172.16.0.188/epel.repo
ADD ${epel_repo_file} /etc/yum.repos.d/
RUN /bin/adduser -D myuser && \
/bin/mkdir /tmp/dir -pv
注意請自行模拟一個可通路的http能通路到的epel.repo
在bbox目錄中運作
[root@docker bbox]# docker build -t docker.io/dyc2005/busybox/v.1.1-httpd ./
Sending build context to Docker daemon 4.096kB
Step 1/8 : FROM busybox:latest
---> 8ac48589692a
Step 2/8 : MAINTAINER "san" "<[email protected]>"
---> Using cache
---> 3105f31095b2
Step 3/8 : COPY data /data/
---> Using cache
---> 355f7a29fd45
Step 4/8 : VOLUME /data/html
---> Using cache
---> 4111c015d683
Step 5/8 : EXPOSE 80/tcp
---> Using cache
---> 6f2ef2457118
Step 6/8 : ENV epel_repo_file http://172.16.0.188/epel.repo
---> Using cache
---> d1ac10e625c4
Step 7/8 : ADD ${epel_repo_file} /etc/yum.repos.d/
Downloading [==================================================>] 10B/10B
---> 943a7f280b6e
Step 8/8 : RUN /bin/adduser -D myuser && /bin/mkdir /tmp/dir -pv
---> Running in 15bb73b0690d
created directory: '/tmp/dir'
Removing intermediate container 15bb73b0690d
---> e2ff30f1beb2
Successfully built e2ff30f1beb2
Successfully tagged dyc2005/busybox/v.1.1-httpd:latest
##檢視新生成的鏡像并運作
[root@docker bbox]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dyc2005/busybox/v.1.1-httpd latest e2ff30f1beb2 52 seconds ago 1.15MB
[root@docker bbox]# docker run -it --rm --name d1 dyc2005/busybox/v.1.1-httpd
/ # id myuser
uid=1000(myuser) gid=1000(myuser) groups=1000(myuser)
/ # ls /tmp/dir/
/ # ls /tmp/
dir
/ #
可以看出新生成的鏡像已經完成了指定的操作
到此鏡像制作的兩咱方法已經小試牛刀的示範完,推薦用dockerfile檔案生成鏡像,Dockerfile中的每一行的指令都是一層
是以建議使用command && command && ...這種方式;
五、鏡像的導入與導出以及使用Volume(外部的目錄)
将鏡像檔案導出為tar檔案
docker save #鏡像儲存成檔案(在沒有倉庫的情況下)
Save one or more images to a tar archive (streamed to STDOUT by default)
docker save [OPTIONS] IMAGE [IMAGE...]
示例:docker save -o /root/nginx-v0.1.0.tar 4481eeccc973
從tar檔案導入鏡像
docker load ##從檔案導入成鏡像
Load an image from a tar archive or STDIN
docker load [OPTIONS]
--input, -i Read from tar archive file, instead of STDIN
--quiet, -q false Suppress the load output
示例
# docker load -i nginx-v0.1.0.tar
重新打标簽
[root@docker ~]# docker tag 4481eeccc973 docker.io/dyc2005/nginx.v0.1.0
Bind mount volume :容器内和主控端上都是使用者指定
[root@docker ~]# run -it --name bbox1 -v /data/html busybox:v1.0
[root@docker ~]# cat /var/lib/docker/volumes/163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05/_data# cat index.html
c1
[root@docker ~]#docker inspect -f {{.Config.Volume}}{{.Mounts}} bbox1
Docker-managed volume :容器内使用者指定,主控端上的目錄預設在/var/lib/docker/volumes 由docker指定
[root@docker ~]#docker run -it -v HOSTDIR:VOLUME --name bbox2 busybox:v1.0
[root@docker ~]# mkdir -pv /tmp/data(主控端上)
[root@docker ~]# echo " Test Page in App1" >/tmp/data/index.html
[root@docker ~]# docker run --name h2 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd
[root@docker ~]# curl http://172.17.0.2
Test Page in App1
[root@docker ~]# docker inspect -f {{.Mounts}} bbox2
列出volume卷:
[root@docker ~]#docker inspect -f {{.Mounts}} bbox2
docker volume list
DRIVER VOLUME NAME
local 163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05
檢視詳細資訊
[root@docker ~]#docker inspect -f {{.Mounts}} bbox2
docker volume inspect
163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05
[
{
"CreatedAt": "2018-04-09T18:10:46+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05/_data",
"Name": "163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05",
"Options": {},
"Scope": "local"
}
]
或
[root@docker ~]# inspect -f {{.Mounts}} bbox2
[{volume 163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05 /var/lib/docker/volumes/163a16717cb1d859869cdd7a87a3ad91b04e754ff26130d9145fe0c4ccf94e05/_data /data/html local true }]
[root@docker ~]# docker run --name h1 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd
[root@docker ~]# docker run --name h2 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd
或複制其他主機使用的volume
[root@docker ~]# docker run --name h1 -d -it -v /tmp/data:/data/html dyc2005/bbox:v0.1.3-httpd
[root@docker ~]# docker run --name h3 -it --rm --volumes-from h1 dyc2005/bbox:v0.1.0
#cd /data/html/
/data/html # ls
index.html