docker最先基於LXC實現(LinuX Container)從0.7版本之後開始去除LXC轉而使用自行開發的libcontainer,從1.11開始,演進爲runC和containerd;docker是go語言開發,基於Linux內核的cgroup,namespace以及AUFS相似的Union FS(聯合文件系統)等技術,對進程進行封裝隔離,屬於操做系統層面的虛擬化技術,因爲隔離的進程獨立於宿主機和其餘的隔離進程,所以也稱其爲容器。
docker在容器的基礎上進行了進一步的封裝從文件系統,網絡互聯到進程隔離等,極大簡化了容器的建立和維護管理。使得docker技術比虛擬機技術更爲輕便,快捷。html
虛擬機與docker比較:
圖片引用自網絡
前端
由上面的比較圖能夠看一樣啓動一個服務;虛擬機會多一層操做系統,而docker和宿主機共用內核系統;所以docker佔用資源更少,資源利用率更高;
虛擬機與docker對比
mysql
docker優勢總結:
高效的資源利用率
快速的啓動
一致的運行環境
持續將會和部署
更輕鬆的遷移
便捷的維護和擴展linux
系統要求:CentOS7.x_x64且安裝Docker CE版本(社區版),不要使用epel倉庫自帶的docker docker從1.17後主要分docker-ce和docker-ee(企業版,你懂滴,就比如mysql企業版與社區版,若是還不明白當我沒說)nginx
如下安裝基於CentOS 7.4_x64 最小化安裝git
[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-cesql
從物理上講client <--> docker daemon <--> Registry Server
邏輯上:
Images:
鏡像只讀,分層鏡像機制,最後一層可讀寫,可共享,或理解爲OS
Containers:容器:
是從鏡像啓動建立的,相似程序與進程的關係,而Images鏡像就是程序文件,運行起來成爲進程;鏡像是靜態定義,容器是鏡像運行時的實體;容器能夠被建立,啓動,中止,刪除,暫停;容器實質是進程;docker
Registry:Image Repositories (存放共享的鏡像庫,相似yum庫)docker官方提供倉庫地址hub.docker.comubuntu
容器的狀態與指令:
經常使用狀態如:
created:docker create(不經常使用),docker run 指令從鏡像建立並運行
running:docker run 指令從鏡像建立並運行
paused:docker paused 暫停容器
stopped:docker stop 中止運行某容器,或經過docker kill容器
狀態間轉化如圖:
centos
以上指令都可經過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 "<h1> Busybox httpd server</h1>" >/data/html/index.html / # cat /data/html/index.html <h1> Busybox httpd server</h1> / # 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 <san@san.com>" 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 <h1> Busybox httpd server</h1>
至此基於運行中的容器製做鏡像完成!
此時產生一個問題,運行中的鏡像進入是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<h1>Busybox httpd server from Dockerfile.</h1>
[root@docker ~]#cat Dockerfiel
FROM busybox:latest MAINTAINER "san" "<san@san.com>" #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" "<san@san.com>" ---> 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 && ...這種方式;
將鏡像文件導出爲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 <h1>c1</h1> [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 "<h1> Test Page in App1</h1>" >/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 <h1> Test Page in App1</h1> [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 }]
注意問題:掛載volume到容器,若是容器中有內容則複製到宿主機目錄,通常刪除容器不會刪除volume,若是要一併刪除須要加--volumw|-v選項
單獨刪除 docker volume rm 命令
多個容器使用同一個宿主目錄
[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
以上是docker學習中整理的筆記不免有錯漏之處,歡迎指正!