第一本Docker書(shū)
自動(dòng)精簡(jiǎn)配置: thin-provisioning
加載device-mapper模塊
sudo mpdprobe dm_mod
查看docker進(jìn)程
docker ps -l
docker ps
docker ps -a
啟動(dòng)一個(gè)容器
docker run -i -t ubuntu /bin/bash
docker attach 重新附加到容器上
查看日志
docker logs vID
docker logs -f ID/Name
-f 與tail -f 很相似
docker logs --tail 10 ID
docker logs --tail 0 -f ID
列出前幾個(gè)鏡像
docker top
執(zhí)行命令
docker exec -d ID touch /etc/new_config_file
docker exec -t -i ID /bin/bash
docker stop
顯示最后x個(gè)容器
docker ps -n -x
自動(dòng)重啟容器
docker run --restart=always --name test -d ubuntu /bin/bash-c "while true; do echo hello world; sleep 1; done;"
always
on-failure
--restart=on-failure:5 設(shè)置重啟次數(shù)
查看更多內(nèi)容
docker inspect
*inspect -f --format * 選定查看信息
查看狀態(tài)
docker inspect --format '{{ .Status.Running}}' testname
docker inspect --format '{{ .NetworkSetting.IPAddress}}'
獲取多個(gè)容器信息
docker inspect --format '{{ .Name}} {{ .Status.Running}}' testName1 testName2
容器存放位置
所有容器都存在/var/lib/docker/containers
刪除容器
docker rm testname
運(yùn)行中的容器如法刪除
刪除所有容器
docker rm ``docker ps -a -q\
-q 只返回容器ID
列出所有容器
docker images
鏡像 倉(cāng)庫(kù) Registry
通過(guò)在倉(cāng)庫(kù)后邊加一個(gè)冒號(hào)和標(biāo)簽名來(lái)指定該倉(cāng)庫(kù)中的某個(gè)鏡像
docker run -t -i -name new_container ubuntu:12.04 /bin/bash
倉(cāng)庫(kù)分類
用戶倉(cāng)庫(kù)(user repository)
頂層倉(cāng)庫(kù)(top-level repository)
只看fedora鏡像
docker images fedora
查找鏡像
dockert search
docker search puppet
構(gòu)建鏡像
docker login
信息保存在$HOME/.dockercfg
docker commit 倉(cāng)庫(kù)名/鏡像名
指定更多信息
docker commit -m 'A new custom image ' --author='James' ID 倉(cāng)庫(kù)名/鏡像名:tag
Dockerfile
注釋使用#
指定都是大寫(xiě)
Version 0.0.1
FROM ubuntu:14.04
MAINTAINER James "James@163.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi , I am you container '> /usr/share/nginx/html/index.html
EXPOSE 80
默認(rèn)使用 /bin/sh -c
也可以使用
RUN ['apt-get', 'install', '-y', 'nginx']
該容器內(nèi)的應(yīng)用程序?qū)?huì)使用容器的指定端口
Docker 不會(huì)自動(dòng)打開(kāi)端口噪裕, 可以向外部公開(kāi)多個(gè)端口
docker build -t='repo/image'
.dockerignore 用來(lái)設(shè)置那些文件不會(huì)被商場(chǎng)到構(gòu)建上下文中
不使用緩存機(jī)制
docker build --no-cache -t='repo/iamge'
ENV REFRESHED_AT 2014-07-01
列出構(gòu)建歷史
docker history testname
docker run -d -p 80 --name new_container repo/image nginx -g 'daemo off'
-p 用來(lái)控制docker 在運(yùn)行時(shí)應(yīng)該公開(kāi)那些網(wǎng)絡(luò)接口該外部使用
Docker分配端口
- Docker 可以在宿主機(jī)上隨機(jī)選擇一個(gè)位于49000-49900的一個(gè)較大的端口號(hào)來(lái)映射到容器上得80端口
- 可以在docker宿主機(jī)中指定一個(gè)具體的端口號(hào)來(lái)映射到容器中的80端口上
docker port testname 80
-p 80:80
-p 8080:80
127.0.0.1:80:80
-P 公開(kāi)在dockerfile中的EXPOSE指定的所有端口號(hào)
Docker指令
CMD
指定容器被啟動(dòng)時(shí)要運(yùn)行的命令
會(huì)被覆蓋, 只能使用最后一個(gè)
/bin/true
CMD["/bin/bash"]
推薦使用數(shù)組
Dockerfile中只能指定一條CMD指令
ENTRYPOINT
ENTRYPOINT ["/usr/sbin/nginx"]
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off"]
巧妙工作
docker run -t -i repo/image -g 'daemon off'
ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]
docker run --entrypoint 覆蓋ENTRYPOINT
WORKDIR
在容器內(nèi)部設(shè)置一個(gè)工作目錄, ENTRYPOINT和CMD或/ 指定的程序會(huì)在整個(gè)目錄下執(zhí)行
WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
ENTRYPOINT ["rackup"]
將容器內(nèi)工作目錄設(shè)為/var/log
docker run -ti -w /var/log ubuntu pwd
ENV
用來(lái)在鏡像構(gòu)建過(guò)程中設(shè)置環(huán)境變量
ENV RVM_PATH /home/rvm
可以在后續(xù)的任何RUN指令中使用
ENV TRAGET_DI /opt/app
WORKDIR TARGET_DIR
docker run -e
使用-e 傳遞環(huán)境變量
docker run -ti -e 'WEB_PORT=8080' ubuntu
USER
指定該鏡像會(huì)以什么樣的用戶去執(zhí)行
USER nginx
USER user
USER user:group
USER uid
USER uid:gid
USER uid:group
USER user:gid
VOLUME
像基于鏡像創(chuàng)建的容器添加卷
一個(gè)卷可以存在于一個(gè)或者多個(gè)容器內(nèi)的特定目錄, 這個(gè)目錄可以繞過(guò)聯(lián)合文件系統(tǒng)并提供如下共享數(shù)據(jù)或者對(duì)數(shù)據(jù)進(jìn)行持久化的功能
- 可以在容器間共享和重用
- 一個(gè)容器可以不是必須和其他容器共享卷
- 對(duì)卷的修改是立時(shí)生效的
- 對(duì)卷的修改不會(huì)對(duì)更新鏡像產(chǎn)生影響
- 卷會(huì)一直存在知道沒(méi)有任何容器再使用它
為基于此鏡像的容器創(chuàng)建一個(gè)名為/opt/project的掛載點(diǎn)VOLUME ["/opt/project"]
添加多個(gè)卷
VOLUME ["/opt/project", "/data"]
ADD
將構(gòu)建環(huán)境下的文件和目錄復(fù)制到鏡像中
ADD software.lic /opt/application/software.lic
以“/”結(jié)尾的判斷為目錄, 否為判斷為文件
ADD 會(huì)將合法的歸檔文件指定源文件的是時(shí)候,自動(dòng)將歸檔文件進(jìn)行解壓
木i的目錄不存在的話,會(huì)創(chuàng)建全路徑椒惨,權(quán)限為0755 UID=0 GID=0
ADD會(huì)使構(gòu)建緩存無(wú)效
ADD添加文件愛(ài)你和目錄, 使用Dockerfile中的后續(xù)指令不能繼續(xù)使用
COPY
類似ADD
只關(guān)心在構(gòu)建上下文中復(fù)制本地文件潮罪, 為不會(huì)做文件提取和解壓
COPY conf.d/ /etc/apache2
ONBUILD
為鏡像添加觸發(fā)器 trigger
當(dāng)一個(gè)鏡像被用作其他其他鏡像的基礎(chǔ)鏡像時(shí)康谆,該鏡像中的觸發(fā)器將會(huì)被執(zhí)行
觸發(fā)器會(huì)在構(gòu)建過(guò)程中插入新的指令
ONBUILD ADD . /app/src
ONBUILD RUN cd /app/src &&make
ONBUILD 觸發(fā)器會(huì)按照父鏡像中指定的順序執(zhí)行并只能被繼承一次
只能在子鏡像中執(zhí)行, 不會(huì)在孫子鏡像中執(zhí)行
*FROM MAINTAINER ONBUILD本身 不能放在ONBUILD中嫉到,防止產(chǎn)生遞歸
推送
docker push testname
docker push repo/image
自動(dòng)構(gòu)建
刪除
docker rm repo/img
從容器中運(yùn)行Registry
docker run -p 5000:5000 registry
docker tag docker.example.com:5000/repo/image
docker push docker.example.com:5000/repo/image
docker run -t -i docker.example.com:5000/repo/image /bin/bash
Quary 私有Registryr托管服務(wù) 現(xiàn)已被CoreOS收購(gòu)
在測(cè)試中使用Docker
使用docker測(cè)試靜態(tài)網(wǎng)站
mkdir sample
cd sample
touch Dockerfile
cd sample
mkdir nginx && cd nginx
touch global.conf
touch nginx.conf
Dokcerfile 文件
#A Dockerfile for nginx web
#Version 0.0.1
FROM ubuntu:14.04
MAINTAINER James James@example.com
ENV REFRESHED_AT 2014-07
RUN apg-get update
RUN apt-get -y install nginx
RUN mkdir -p /var/www/html
ADD nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
global.conf文件
server{
listen 0.0.0.0:80;
server_name _;
root /var/www/html/website;
index index.html index.htm;
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;
}
nginx 文件
user www-data;
work_process 4;
pid /run/nginx.pid;
daemon off;
event{}
http{
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
type_hash_max_size 2048;
include /etc/nginx/mime.type;
default_type application/octect_stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_diable "mise6";
include /etc/nginx/conf/*.conf;
}
daemon off; 防止nginx進(jìn)入后臺(tái)沃暗, 強(qiáng)制其在前臺(tái)運(yùn)行, 要想保持dokcer的活躍狀態(tài)何恶,需要其中運(yùn)行的進(jìn)程不能中斷
docker build -t jamtu01/nginx
創(chuàng)建網(wǎng)站
touch sample
mkdir website&&cd website
touch index.html
docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website jamtu01/nginx nginx
-v 參數(shù)指定了卷的源目錄和容器中的目的目錄孽锥,這兩個(gè)目錄通過(guò): 來(lái)分隔 如果目的目錄不存在 docker會(huì)自動(dòng)創(chuàng)建一個(gè)
可以增加rw 或ro 來(lái)指定目的目錄的讀寫(xiě)狀態(tài)
-v $PWD/website:/var/www/html/websit:ro
web應(yīng)用
#Version 0.0.1
FROM ubuntu:14.04
MAINTAINER James james@example.com
ENV REFRESHED_AT 2016-05-01
RUN apt-get update
RUN apt-get -y install ruby ruby-dev build-essential redis-tools
RUN mkdir -p /opt/webapp
EXPOSE 4567
CMD ["/opt/webapp/bin/webapp"]
docker build jamtu01/sinatra
檢查端口映射
docker port webapp 4567
Redis鏡像
#version 0.0.1
FROM ubuntu:14.04
MAINTAINER jame james@example.com
ENV REFRESHED_AT 2016-5-1
RUN apt-get update
RUN apt-get -y install redis-server redis-tools
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
CMD []
docker有自己的網(wǎng)絡(luò)
- 端口綁定到本地網(wǎng)絡(luò)
- 內(nèi)部網(wǎng)絡(luò) dokcer0
docker0接口有符合RFC1918的私有IP地址, 范圍172.16~ 172.30 接口本身地址 172.17.42.1是一個(gè)Docker網(wǎng)絡(luò)的網(wǎng)關(guān)地址 也是所有docker容器的網(wǎng)管地址
doker會(huì)默認(rèn)使用172.17.x.x作為子網(wǎng)地址, 除非這個(gè)子網(wǎng)已被占用惜辑,如果整個(gè)子網(wǎng)被占用了唬涧,docker會(huì)在172.16.~172.30這個(gè)范圍嘗試創(chuàng)建子網(wǎng)
docker0是一個(gè)熏雞的以太網(wǎng)橋, 用于連接容器和本地宿主網(wǎng)絡(luò)
veth 開(kāi)頭的網(wǎng)絡(luò)
docker每創(chuàng)建一個(gè)容器就會(huì)創(chuàng)建一組互聯(lián)的網(wǎng)絡(luò)接口盛撑,這組接口其中一端作為容器里的eth0接口碎节, 而另一端同意命名為類似vethc6a這種名字, 作為宿主機(jī)的一個(gè)接口
防火墻規(guī)則和Nat配置
Docker容器互聯(lián)
docker run -d --name redis jamtur01/redis
docker run -p 4567 --name webapp --link redis:db -t -i -v $PWD/webapp:/opt/webapp jamtru01/sinamtra /bin/bash
--link
創(chuàng)建了連個(gè)容器間的父子連接
需要兩個(gè)參數(shù) 一個(gè)是要連接的容器的名字撵彻, 另一個(gè)是連接容器的別名
連接讓父容器有能力訪問(wèn)子容器钓株,并且把自容器的一些連接細(xì)節(jié)分享給父容器实牡,這些細(xì)節(jié)有助于配置應(yīng)用程序并使用這個(gè)連接
連接也能得到安全上的好處
出于安全原因陌僵, 可以強(qiáng)制docker之允許有連接的容器之間進(jìn)行互相通信,需要在啟動(dòng)docker守護(hù)進(jìn)程時(shí)加上--icc=false 關(guān)閉所有設(shè)有連接的容器間的通訊
被連接容器必須運(yùn)行在同一個(gè)docker宿主機(jī)上创坞,不同docker宿主機(jī)上運(yùn)行的容器無(wú)法連接
修改容器中的hosts
cat /etc/hosts
172.17.0.33 id
172.17.0.31 db
--volume-from
把指定容器里的所有卷都加入新創(chuàng)建的容器里
如果刪除了最后一個(gè)使用卷的容器碗短, 卷就部存在了
docker start jame/blog 重啟編譯運(yùn)行
docker run --rm 容器進(jìn)程運(yùn)行完畢后 自動(dòng)刪除容器
備份
docker run --rm --volume-from james-blog -v $PWD:/backup ubuntu tar cvf /back/james-blog/backup.tar /var/www/html/
-h 設(shè)置容器的主機(jī)名
服務(wù)發(fā)現(xiàn)
服務(wù)發(fā)現(xiàn)是分布式應(yīng)用程序之間管理相互關(guān)系的一種機(jī)制, 一個(gè)分布式程序一般由多個(gè)組件組成题涨, 這些組件可以都放在一臺(tái)機(jī)器上偎谁,也可以分布在多個(gè)數(shù)據(jù)中心,甚至分布在不同的地理區(qū)域纲堵,這些組件通逞灿辏可以為其他組件提供服務(wù)或者為其他組件消費(fèi)服務(wù)。
服務(wù)發(fā)現(xiàn)允許某個(gè)組件在想要與其他組件自動(dòng)找到對(duì)方席函, 由于這應(yīng)用本身是分布式的铐望, 服務(wù)發(fā)現(xiàn)機(jī)制也需要是分布式的,而且服務(wù)發(fā)現(xiàn)作為分布式應(yīng)用不同組件之間的膠水茂附, 其本身還需要是足夠動(dòng)態(tài)正蛙, 可靠, 適應(yīng)性強(qiáng)营曼, 而且可以快速且一直的共享于這些服務(wù)的數(shù)據(jù)
Docker 主要關(guān)注分布式應(yīng)用以及面向服務(wù)架構(gòu)與微服務(wù)架構(gòu)
consul
Consul 是一個(gè)使用一致性算法的特殊數(shù)據(jù)存儲(chǔ)器
Consul使用Raft一致性算法來(lái)提供確定的寫(xiě)入機(jī)制乒验, consul暴露了鍵值存儲(chǔ)系統(tǒng)和服務(wù)分類系統(tǒng), 并提供高可用性蒂阱,高容錯(cuò)性能力锻全, 并保證強(qiáng)一致性服務(wù),可以將自己注冊(cè)到consul并且高可用分布式方式共享這些信息
Consul其他功能
- 提供了數(shù)據(jù)API進(jìn)行服務(wù)分類录煤, 代替了大部分傳統(tǒng)服務(wù)發(fā)現(xiàn)工具的鍵值對(duì)存儲(chǔ)
- 提供了兩類接口來(lái)查詢信息虱痕, 基于內(nèi)置DNS服務(wù)的DNS查詢接口和基于HTTP的RESTAPI查詢接口, 選擇合適的接口辐赞, 尤其是基于DNS的接口可以很方便的將Consul與發(fā)現(xiàn)環(huán)境集成
- 提供了服務(wù)監(jiān)控部翘,也稱作Aka健康監(jiān)控, Consul內(nèi)置了強(qiáng)大的服務(wù)監(jiān)控系統(tǒng)
構(gòu)建Consul
mkdir consul
cd consul
touch Dockerfile
#Version 0.0.1
FROM ubuntu:14.04
MAINTAINER james jam@example.com
ENV REFREESHED_AT 2016-5-2
RUN apt-get update
RUN apt-get -qqy install url unzip
ADD https://dl.binray.com/mitchellh/consul/0.3.1_linux_amd64.zip /tmp/consul.zip
RUN cd /usr/sbin && unzip /tmp/consul.zip && chmod +x /usr/sbin/consul && rm /tmp/consul.zip
ADD https://dl.binary.com/mitchellh/consul/0.3.1_web_ui.zip /tmp/webui.zip
RUN cd /tmp && unzip webui.zip && mv dist/ webui/
ADD consul.json /config/
EXPOSE 53/udp 8300 8301 8301/udp 8302 8302/udp 8400 8500
VOLUME ["/data"]
ENTRYPOIN ["/usr/sbin/consul", "agent", "-config-dir=/config"]
CMD []
consul.json
{
"data_dir" : "/data",
"UI_dir" : "/webui",
"client_addr" : "0.0.0.0",
"ports" : {
"dns" : 53
}
"rescursor" : "8.8.8.8"
}
- 53/udp | DNS服務(wù)器
- 8300 |服務(wù)器使用的RPC
- 8301+udp |serf服務(wù)器使用LAN端口
- 8302+udp |serf服務(wù)器使用的WAN端口
- 8400 |命令行RPC接入點(diǎn)
- 8500 |HTTPAPI 用于提供HTTP API和網(wǎng)頁(yè)界面
8301+udp 8302+udp 8300 8400 用于可處理后臺(tái)通信將多個(gè)consul節(jié)點(diǎn)組成集群
獲取IP地址
PUBLIC_IP="$(ifconfig eth0 |awk -F '*|:' '/inet addr/{print $4'})"
/etc/default/docker
DOCKER_OPTS='--dns 172.17.42.1 --dns 8.8.8.8 --dns-search service .consul'
Docker API
在Doker生態(tài)系統(tǒng)中有三種API
- Registry API : 提供了與存儲(chǔ)Docker鏡像的Docker Registry集成的功能
- DockerHub API 提供了與Docker Hub集成的功能
- Docker Remote API 提供了與Docker守護(hù)進(jìn)程進(jìn)行集成的功能
都是RESTAPI風(fēng)格
綁定
Docker守護(hù)進(jìn)程綁定宿主機(jī)套接字 unix:///var/run/docker.sock
Docker 需要root權(quán)限運(yùn)行
啟動(dòng)配置文件
- /etc/default/docker
- /etc/init/docker.conf
- /etc/sysconfig/docker
- /usr/lib/systemd/system/docker.service
編輯啟動(dòng)項(xiàng)
/usr/lib/systemd/system/docker.service
ExecStart=/usrt/bin/docker -d --selinux enabled -H tcp://0.0.0.0:2375
Docker 守護(hù)進(jìn)程能夠綁定到一個(gè)接口上
重新加載和啟動(dòng)Docker守護(hù)集成
systemctl --system daemon-reload
Docker 守護(hù)進(jìn)程之間的網(wǎng)絡(luò)連接是沒(méi)有經(jīng)過(guò)認(rèn)證的响委, 是對(duì)外開(kāi)放的
返回json散列數(shù)據(jù)
curl htpp://docker.example.com:2375/info
使用python的json工具新思, 對(duì)API返回結(jié)果進(jìn)行格式化處理
curl http://docker.example.com:2375/images/json|python -mjson.tool
查詢
curl "http://docker.exampl.com:2375/images/search?term=jamtur01"|python -mjson.tool
獲取正在運(yùn)行的容器
curl -s "http://docker.example.com:2375/containers/json" |python -mjson.tool
獲取所有容器
http://docker.example.com:2375/container/json?all=1
創(chuàng)建容器
curl -X POST "Content-Type: application/json http://docker.example.com:2375/containers/create -d {"image":"jamtur01/jenkyll"}" *創(chuàng)建容器并設(shè)置主機(jī)名*
curl -X POST -H Content-Type: application/json http://docker.example.com:2375/containers/ID/start -d {"publishAllPorts":true}*使用容器ID查詢?nèi)萜?
curl http://docker.example.com:2375/containers/containerID/json| python mjson.tool`
認(rèn)證
采用TLS/SSL認(rèn)證
建立證書(shū)授權(quán)中心
mkdir /etc/docker
cd /etc/docker
echo 01>|sudo tee ca.srl
openssl genrsa -des3 -out ca-key.pem
創(chuàng)建CA證書(shū)
openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem
創(chuàng)建服務(wù)器密鑰
openssl x509 -req -days 365 server-key.pem -out server.csr
common name 或CN 要么為Docker服務(wù)器的FQDN 要么為允許任何服務(wù)器上使用該服務(wù)器證書(shū)
對(duì)CSR進(jìn)行簽名
openssl x509 -req -days 365 -ins server.csr -CA ca.pem -CAkey ca-key.pem -out server-cert.pem
移除服務(wù)器端密鑰
openssl rsa -in server-key.pem -out server-key.pem
chmod 0600 /etc/server-key.pem
chmod 0600 /etc/server-cert.pem
chmod 0600 /etc/ca-key.pem
chmod 0600 /etc/ca.pem
在systemd中啟用dockerTLS
ExecStart = /usr/bin/docker -d -H tcp://0.0.0.0:2376 --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem
創(chuàng)建客戶端證書(shū)和密鑰
創(chuàng)建客戶端密鑰
openssl genrsa -des3 -out client-key.pem
創(chuàng)建客戶端csr
openssl req -new client-key.pem -out client.src
添加客戶端認(rèn)證屬性
echo extendedKeyUsage=clientAuth > extfile.cnf
對(duì)客戶端CSR進(jìn)行簽名
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAKey ca-key.pem -out cient-cert.pem -extfile extfile.cnf
移除客戶端密鑰
openssl rsa -in client-key.pem -out client-key
復(fù)制ca.pem client-cert窖梁。pem client-key.pem到運(yùn)行的Docker客戶端的宿主機(jī)上
復(fù)制到~/.docker目錄下