
Docker簡介(一)
百度百科:Docker
為什么要使用Docker
變復雜的安裝配置為一條命令解決:秒級啟動鏡像,資源消耗極少;
Containers vs VMs
- VMs = Server + Host OS + Hypervisor(Type2)+ Guest OS + Bins/Libs +(App A | App A' | App B)
- Containers = Server + Host OS + Docker Engine + ((Bins/Libs +App A | App A') | (Bins/Libs +App B))
- 結(jié)論:Docker去除了傳統(tǒng)虛機的Guest OS層,免除了對應overhead
- Docker Engine 替代了VM中的Guest OS + Hypervisor(Type2)層
Docker使得部署密度前所未有的高:
- 32核/64G內(nèi)存,
- 開4*4虛機(4核,4G內(nèi)存),開8~16個虛機極限了;
- BAE:200個容器,系統(tǒng)資源還是很閑;
每個Docker進程可以忽略其存在,他的厚度和Hypervisor差不多,相當于一個轉(zhuǎn)換器,在這個角度,Docker和Wine有點兒像。
Docker vs WINE
- WINE:wine is not emulator
- 在Linux下運行Windows程序的黑科技:Office、魔獸爭霸、暗黑
- 做一個二進制的翻譯,把Windows的調(diào)用劫持,轉(zhuǎn)換為Linux調(diào)用
- Docker的位置和WINE很像,但都是Linux,所以不用做太多的轉(zhuǎn)換
Docker和Linux
- Linux = kernel + GNU(Glibc + ls等命令)
- Docker = kernel + libc + 應用
- 命令比如,Yum (偽裝成CentOS)、Apt(偽裝成 Ubuntu)
Docker這么設計,效率非常高基本上就是占了點兒磁盤,消耗基本上就是資源隔離
Docker、Vagrant、VMs
ThinkPad R400,雙核,4G內(nèi)存,Win10 OS;
啟動一個虛擬機跑一個Redmine系統(tǒng)來配合開發(fā)驗證,基本上卡得就動不了了;啟動停止也慢;操作起來像慢鏡頭;
啟動4-8個CentOS 6.6Vagrant服務,基本上不影響系統(tǒng)操作。只有啟動停止耗時較長;
Docker,基本上無感:不影響系統(tǒng),啟動停止都是秒級的;
基本概念
三個基本組件:鏡像、容器、倉庫;
鏡像
- Docker鏡像(Image)就是一個只讀的模版。鏡像可以用來創(chuàng)建Docker容器
容器
- Docker利用容器(Container)來運行應用
- 容器是從鏡像創(chuàng)建的運行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平臺
- 可以把容器看做是一個簡易版的Linux環(huán)境(包括root用戶權(quán)限、進程空間、用戶空間和網(wǎng)絡空間等)和運行在其中的應用程序。
- 鏡像是只讀的,容器在啟動的時候創(chuàng)建一層可寫層作為最上層
倉庫
- 倉庫(Repository)是集中存放鏡像文件的場所。有時候會把倉庫和倉庫注冊服務器(Registry)混為一談,并不嚴格區(qū)分。實際上,倉庫注冊服務器上往往存放著多個倉庫,每個倉庫又包含了多個鏡像,每個鏡像有不同的標簽(tag)
- 倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式
快速安裝
Linux下安裝
- Docker目前只能安裝在64位平臺上
- 內(nèi)核版本不低于3.10,實際上內(nèi)核越新越好,過低的內(nèi)核版本容易造成功能的不穩(wěn)定
- 盡量采用最新版的內(nèi)核、docker-engine
- 拒絕在CentOS6上運行Docker(太坑了),CentOS 不支持AUFS,不穩(wěn)定;
- 可以嘗試用:bnied/kernel-ml-aufs
- CentOS上 = Docker + devicemapper(需要root)
- Ubuntu上 = Docker + AUFS
- sudo curl -sSL https://get.docker.com/ | sh
- sudo chkconfig docker on(先啟動dockerd服務,然后再運行Docker命令)
- dockerd這個服務千萬不要重啟:重啟所有容器都掛,那就是運行事故了
Mac & Windows平臺安裝
多用來學習Docker。我的安裝日志:Docker的第一次親密接觸
Mac安裝:Get started with Docker for Mac
Windows安裝:Get started with Docker for Windows
基本操作
docker ps
默認列出當前運行的所有容器
加上-a 參數(shù)列出所有運行、運行過的容器(沒有刪除的)
[AnInputForce@teach ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48f6c0b28e09 jenkins "/bin/tini -- /usr/lo" 41 hours ago Up 36 hours 0.0.0.0:50000->50000/tcp, 0.0.0.0:8081->8080/tcp myjenkins
acfdad773539 gitlab/gitlab-ce:latest "/assets/wrapper" 42 hours ago Up 42 hours 0.0.0.0:2022->22/tcp, 0.0.0.0:2080->80/tcp, 0.0.0.0:2443->443/tcp gitlab
- 為什么我這里沒用root也能跑:
- 我們把用戶加入docker這個組,默認就有docker這個權(quán)限了
[AnInputForce@teach ~]$ cat /etc/group | grep docker
docker:x:1001:work,AnInputForce
- 避免線上用root權(quán)限,也可以給docker加上一個setuid權(quán)限[^在linux中"chmod u+s "這個命令是做什么的?]
- 示例賬號沒有root權(quán)限,所以賦權(quán)不成功
[AnInputForce@teach ~]$ which docker
/usr/bin/docker
[AnInputForce@teach ~]$ ll /usr/bin/docker
-rwxr-xr-x 1 root root 13914088 10月 12 01:36 /usr/bin/docker
[AnInputForce@teach ~]$ chomod u+s /usr/bin/docker
chmod: 更改"/usr/bin/docker" 的權(quán)限: 不允許的操作
[在linux中"chmod u+s "這個命令是做什么的?]: “為了方便普通用戶執(zhí)行一些特權(quán)命令,SUID/SGID程序允許普通用戶以root身份暫時執(zhí)行該程序,并在執(zhí)行結(jié)束后再恢復身份?!?chmod u+s 就是給某個程序的所有者以setuid權(quán)限,可以像root用戶一樣操作。
docker ps結(jié)果字段注釋
[AnInputForce@teach ~]$ docker run centos uname -a
Linux 60364ce6d60c 4.8.5-1.el7.centos.x86_64 #1 SMP Fri Oct 28 09:27:15 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
[AnInputForce@teach ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48f6c0b28e09 jenkins "/bin/tini -- /usr/lo" 42 hours ago Up 36 hours 0.0.0.0:50000->50000/tcp, 0.0.0.0:8081->8080/tcp myjenkins
acfdad773539 gitlab/gitlab-ce:latest "/assets/wrapper" 42 hours ago
[AnInputForce@teach ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
60364ce6d60c centos "uname -a" 53 seconds ago Exited (0) 52 seconds ago adoring_mcclintock
f53886776491 ubuntu "/bin/bash" 14 hours ago Exited (0) 14 hours ago admiring_chandrasekhar
48f6c0b28e09 jenkins "/bin/tini -- /usr/lo" 42 hours ago Up 36 hours 0.0.0.0:50000->50000/tcp, 0.0.0.0:8081->8080/tcp myjenkins
acfdad773539 gitlab/gitlab-ce:latest "/assets/wrapper" 42 hours ago Up 42 hours 0.0.0.0:2022->22/tcp, 0.0.0.0:2080->80/tcp, 0.0.0.0:2443->443/tcp gitlab
[AnInputForce@teach ~]$
- CONTAINER ID #容器ID
- IMAGE #采用哪個鏡像
- COMMAND #當前運行的命令
- CREATED #起跑日期
- STATUS #狀態(tài)
- PORTS #端口
- NAMES #名字(自己起全局唯一)
command的設計場景
- 我跑一個腳本一樣的命令
docker run centos uname -a
- 我跑一個虛擬機一樣的命令
docker run centos tail -f /etc/hosts
port
查看容器已經(jīng)做了端口映射的端口被映射到了哪個端口上。docker ps 也可以看到。這個命令或許為了方便二次開發(fā);
比如我本機啟動了個叫webserver的nginx容器,映射了本機80端口到容器的80端口:
ChinaDreams:etc kangcunhua$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
70d241e335b5 nginx "nginx -g 'daemon off" 6 days ago Up 4 days 0.0.0.0:80->80/tcp, 443/tcp webserver
ChinaDreams:etc kangcunhua$ docker port webserver 80
0.0.0.0:80
Docker 默認訪問外邊是可以的,做了NAT。
[AnInputForce@teach ~]$ docker run centos ping -c 3 g.cn
PING g.cn (203.208.51.84) 56(84) bytes of data.
64 bytes from 203.208.51.84: icmp_seq=1 ttl=53 time=4.19 ms
64 bytes from 203.208.51.84: icmp_seq=2 ttl=53 time=4.24 ms
64 bytes from 203.208.51.84: icmp_seq=3 ttl=53 time=4.19 ms
--- g.cn ping statistics ---
3 packets transmitted, 3 received, 0% packet loss,
外邊訪問里邊需要配置端口映射,后續(xù)講(比較坑)
docker pull
以下三條命令一個作用:從官方dockerhub下載Ubuntu鏡像
- docker pull ubuntu
- docker pull ubutu:12:04
- docker pull http://registry.hub.docker.com/ubuntu:12.04...
docker images
docker images
docker rmi:刪鏡像(比較危險,刪之前關閉鏡像啟動的所有容器)
[AnInputForce@teach ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7 0584b3d2cf6d 11 days ago 196.5 MB
centos latest 0584b3d2cf6d 11 days ago 196.5 MB
ubuntu latest f753707788c5 4 weeks ago 127.2 MB
ubuntu 14.04 1e0c3dd64ccd 4 weeks ago 187.9 MB
#####docker run
- 啟動一個交互式的命令行容器
[AnInputForce@teach ~]$ docker run -it centos /bin/bash
- i:交互,t:tty
- 建議如下:
* docker run —name="centos" -itd centos tail -f /etc/hosts
* docker exec -it centos /bin/bash
* -p 映射端口
* -v映射目錄
- stop/rm
* docker stop centos
* docker rm centos
* docker rm -f centos
#####docker rm命令演示
啟動一個交互式容器
[AnInputForce@teach ~]$ docker run -it centos /bin/bash
[root@69719220cdb6 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.3 0.0 11784 2912 ? Ss 04:48 0:00 /bin/bash
root 15 0.0 0.0 47432 3212 ? R+ 04:49 0:00 ps aux
退出容器后查看進程,刪除容器
[AnInputForce@teach ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69719220cdb6 centos "/bin/bash" 10 minutes ago Exited (0) About a minute ago serene_murdock
97aff7c4e9a7 centos "ping -c 3 g.cn" 36 minutes ago Exited (0) 36 minutes ago berserk_fermat
2437fdcc6023 centos "uname -a" 43 minutes ago Exited (0) 43 minutes ago lonely_wright
[AnInputForce@teach ~]$
[AnInputForce@teach ~]$ docker rm 69719220cdb6
69719220cdb6
[AnInputForce@teach ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
97aff7c4e9a7 centos "ping -c 3 g.cn" 43 minutes ago Exited (0) 43 minutes ago berserk_fermat
2437fdcc6023 centos "uname -a" 50 minutes ago Exited (0) 50 minutes ago lonely_wright
[AnInputForce@teach ~]$ docker rm 69719220cdb6
Error response from daemon: No such container: 69719220cdb6
#####docker exec進入容器
- docker run —name="centos_kch" -itd centos tail -f /etc/hosts
- docker exec -it centos_kch /bin/bash #進入交互式bash
- run 命令可以啟動一個容器(如果沒有則啟動,然后運行命令),exec的目標必須是一個啟動的容器
[AnInputForce@teach ~]$ docker run --name="centos_kch" -itd centos tail -f /etc/hosts
6b6a260a95754e2c2b4942506bd53d3aecacc26568b6242613b39648afa16876
[AnInputForce@teach ~]$ docker exec -it centos_kch /bin/bash
[root@6b6a260a9575 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4364 784 ? Ss+ 05:43 0:00 tail -f /etc/hosts
root 7 0.0 0.0 11760 2924 ? Ss 05:43 0:00 /bin/bash
root 21 0.0 0.0 47432 3216 ? R+ 05:45 0:00 ps aux
[root@6b6a260a9575 /]#
好玩的
ps aux | grep tail :我們是可以在宿主機上看到Docker容器中的進程的
但是,我們在宿主機中殺不掉,因為docker的資源隔離做得好
[AnInputForce@teach ~]$ ps aux | grep tail
root 2773 0.0 0.0 18036 220 ? S 11月12 0:00 /bin/bash /opt/gitlab/bin/gitlab-ctl tail
root 9369 0.0 0.0 4364 784 pts/14 Ss+ 13:43 0:00 tail -f /etc/hosts
AnInput+ 9486 0.0 0.0 112672 2228 pts/11 R+ 13:43 0:00 grep --color=auto tail
[AnInputForce@teach ~]$ sudo killall tail #當然此用戶沒有sudo權(quán)限
#####結(jié)論:
如果有root還干不掉的進程,一個場景就是宿主機上運行的Docker容器里的進程:雖然可以看到,但是殺不掉。因為Docker優(yōu)秀的資源隔離特性。