第一本Docker書
自動精簡配置: thin-provisioning
加載device-mapper模塊
sudo mpdprobe dm_mod
查看docker進程
docker ps -l
docker ps
docker ps -a
啟動一個容器
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
列出前幾個鏡像
docker top
執(zhí)行命令
docker exec -d ID touch /etc/new_config_file
docker exec -t -i ID /bin/bash
docker stop
顯示最后x個容器
docker ps -n -x
自動重啟容器
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}}'
獲取多個容器信息
docker inspect --format '{{ .Name}} {{ .Status.Running}}' testName1 testName2
容器存放位置
所有容器都存在/var/lib/docker/containers
刪除容器
docker rm testname
運行中的容器如法刪除
刪除所有容器
docker rm ``docker ps -a -q\
-q 只返回容器ID
列出所有容器
docker images
鏡像 倉庫 Registry
通過在倉庫后邊加一個冒號和標(biāo)簽名來指定該倉庫中的某個鏡像
docker run -t -i -name new_container ubuntu:12.04 /bin/bash
倉庫分類
用戶倉庫(user repository)
頂層倉庫(top-level repository)
只看fedora鏡像
docker images fedora
查找鏡像
dockert search
docker search puppet
構(gòu)建鏡像
docker login
信息保存在$HOME/.dockercfg
docker commit 倉庫名/鏡像名
指定更多信息
docker commit -m 'A new custom image ' --author='James' ID 倉庫名/鏡像名:tag
Dockerfile
注釋使用#
指定都是大寫
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ū)褂萌萜鞯闹付ǘ丝?br>
Docker 不會自動打開端口, 可以向外部公開多個端口
docker build -t='repo/image'
.dockerignore 用來設(shè)置那些文件不會被商場到構(gòu)建上下文中
不使用緩存機制
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 用來控制docker 在運行時應(yīng)該公開那些網(wǎng)絡(luò)接口該外部使用
Docker分配端口
- Docker 可以在宿主機上隨機選擇一個位于49000-49900的一個較大的端口號來映射到容器上得80端口
- 可以在docker宿主機中指定一個具體的端口號來映射到容器中的80端口上
docker port testname 80
-p 80:80
-p 8080:80
127.0.0.1:80:80
-P 公開在dockerfile中的EXPOSE指定的所有端口號
Docker指令
CMD
指定容器被啟動時要運行的命令
會被覆蓋, 只能使用最后一個
/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è)置一個工作目錄, ENTRYPOINT和CMD或/ 指定的程序會在整個目錄下執(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
用來在鏡像構(gòu)建過程中設(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
指定該鏡像會以什么樣的用戶去執(zhí)行
USER nginx
USER user
USER user:group
USER uid
USER uid:gid
USER uid:group
USER user:gid
VOLUME
像基于鏡像創(chuàng)建的容器添加卷
一個卷可以存在于一個或者多個容器內(nèi)的特定目錄, 這個目錄可以繞過聯(lián)合文件系統(tǒng)并提供如下共享數(shù)據(jù)或者對數(shù)據(jù)進行持久化的功能
- 可以在容器間共享和重用
- 一個容器可以不是必須和其他容器共享卷
- 對卷的修改是立時生效的
- 對卷的修改不會對更新鏡像產(chǎn)生影響
- 卷會一直存在知道沒有任何容器再使用它
為基于此鏡像的容器創(chuàng)建一個名為/opt/project的掛載點VOLUME ["/opt/project"]
添加多個卷
VOLUME ["/opt/project", "/data"]
ADD
將構(gòu)建環(huán)境下的文件和目錄復(fù)制到鏡像中
ADD software.lic /opt/application/software.lic
以“/”結(jié)尾的判斷為目錄, 否為判斷為文件
ADD 會將合法的歸檔文件指定源文件的是時候,自動將歸檔文件進行解壓
木i的目錄不存在的話,會創(chuàng)建全路徑,權(quán)限為0755 UID=0 GID=0
ADD會使構(gòu)建緩存無效
ADD添加文件愛你和目錄, 使用Dockerfile中的后續(xù)指令不能繼續(xù)使用
COPY
類似ADD
只關(guān)心在構(gòu)建上下文中復(fù)制本地文件, 為不會做文件提取和解壓
COPY conf.d/ /etc/apache2
ONBUILD
為鏡像添加觸發(fā)器 trigger
當(dāng)一個鏡像被用作其他其他鏡像的基礎(chǔ)鏡像時,該鏡像中的觸發(fā)器將會被執(zhí)行
觸發(fā)器會在構(gòu)建過程中插入新的指令
ONBUILD ADD . /app/src
ONBUILD RUN cd /app/src &&make
ONBUILD 觸發(fā)器會按照父鏡像中指定的順序執(zhí)行并只能被繼承一次
只能在子鏡像中執(zhí)行, 不會在孫子鏡像中執(zhí)行
*FROM MAINTAINER ONBUILD本身 不能放在ONBUILD中,防止產(chǎn)生遞歸
推送
docker push testname
docker push repo/image
自動構(gòu)建
刪除
docker rm repo/img
從容器中運行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收購
在測試中使用Docker
使用docker測試靜態(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進入后臺, 強制其在前臺運行, 要想保持dokcer的活躍狀態(tài),需要其中運行的進程不能中斷
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ù)指定了卷的源目錄和容器中的目的目錄,這兩個目錄通過: 來分隔 如果目的目錄不存在 docker會自動創(chuàng)建一個
可以增加rw 或ro 來指定目的目錄的讀寫狀態(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是一個Docker網(wǎng)絡(luò)的網(wǎng)關(guān)地址 也是所有docker容器的網(wǎng)管地址
doker會默認(rèn)使用172.17.x.x作為子網(wǎng)地址, 除非這個子網(wǎng)已被占用,如果整個子網(wǎng)被占用了,docker會在172.16.~172.30這個范圍嘗試創(chuàng)建子網(wǎng)
docker0是一個熏雞的以太網(wǎng)橋, 用于連接容器和本地宿主網(wǎng)絡(luò)
veth 開頭的網(wǎng)絡(luò)
docker每創(chuàng)建一個容器就會創(chuàng)建一組互聯(lián)的網(wǎng)絡(luò)接口,這組接口其中一端作為容器里的eth0接口, 而另一端同意命名為類似vethc6a這種名字, 作為宿主機的一個接口
防火墻規(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)建了連個容器間的父子連接
需要兩個參數(shù) 一個是要連接的容器的名字, 另一個是連接容器的別名
連接讓父容器有能力訪問子容器,并且把自容器的一些連接細(xì)節(jié)分享給父容器,這些細(xì)節(jié)有助于配置應(yīng)用程序并使用這個連接
連接也能得到安全上的好處
出于安全原因, 可以強制docker之允許有連接的容器之間進行互相通信,需要在啟動docker守護進程時加上--icc=false 關(guān)閉所有設(shè)有連接的容器間的通訊
被連接容器必須運行在同一個docker宿主機上,不同docker宿主機上運行的容器無法連接
修改容器中的hosts
cat /etc/hosts
172.17.0.33 id
172.17.0.31 db
--volume-from
把指定容器里的所有卷都加入新創(chuàng)建的容器里
如果刪除了最后一個使用卷的容器, 卷就部存在了
docker start jame/blog 重啟編譯運行
docker run --rm 容器進程運行完畢后 自動刪除容器
備份
docker run --rm --volume-from james-blog -v $PWD:/backup ubuntu tar cvf /back/james-blog/backup.tar /var/www/html/
-h 設(shè)置容器的主機名
服務(wù)發(fā)現(xiàn)
服務(wù)發(fā)現(xiàn)是分布式應(yīng)用程序之間管理相互關(guān)系的一種機制, 一個分布式程序一般由多個組件組成, 這些組件可以都放在一臺機器上,也可以分布在多個數(shù)據(jù)中心,甚至分布在不同的地理區(qū)域,這些組件通常可以為其他組件提供服務(wù)或者為其他組件消費服務(wù)。
服務(wù)發(fā)現(xiàn)允許某個組件在想要與其他組件自動找到對方, 由于這應(yīng)用本身是分布式的, 服務(wù)發(fā)現(xiàn)機制也需要是分布式的,而且服務(wù)發(fā)現(xiàn)作為分布式應(yīng)用不同組件之間的膠水, 其本身還需要是足夠動態(tài), 可靠, 適應(yīng)性強, 而且可以快速且一直的共享于這些服務(wù)的數(shù)據(jù)
Docker 主要關(guān)注分布式應(yīng)用以及面向服務(wù)架構(gòu)與微服務(wù)架構(gòu)
consul
Consul 是一個使用一致性算法的特殊數(shù)據(jù)存儲器
Consul使用Raft一致性算法來提供確定的寫入機制, consul暴露了鍵值存儲系統(tǒng)和服務(wù)分類系統(tǒng), 并提供高可用性,高容錯性能力, 并保證強一致性服務(wù),可以將自己注冊到consul并且高可用分布式方式共享這些信息
Consul其他功能
- 提供了數(shù)據(jù)API進行服務(wù)分類, 代替了大部分傳統(tǒng)服務(wù)發(fā)現(xiàn)工具的鍵值對存儲
- 提供了兩類接口來查詢信息, 基于內(nèi)置DNS服務(wù)的DNS查詢接口和基于HTTP的RESTAPI查詢接口, 選擇合適的接口, 尤其是基于DNS的接口可以很方便的將Consul與發(fā)現(xiàn)環(huán)境集成
- 提供了服務(wù)監(jiān)控,也稱作Aka健康監(jiān)控, Consul內(nèi)置了強大的服務(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接入點
- 8500 |HTTPAPI 用于提供HTTP API和網(wǎng)頁界面
8301+udp 8302+udp 8300 8400 用于可處理后臺通信將多個consul節(jié)點組成集群
獲取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 : 提供了與存儲Docker鏡像的Docker Registry集成的功能
- DockerHub API 提供了與Docker Hub集成的功能
- Docker Remote API 提供了與Docker守護進程進行集成的功能
都是RESTAPI風(fēng)格
綁定
Docker守護進程綁定宿主機套接字 unix:///var/run/docker.sock
Docker 需要root權(quán)限運行
啟動配置文件
- /etc/default/docker
- /etc/init/docker.conf
- /etc/sysconfig/docker
- /usr/lib/systemd/system/docker.service
編輯啟動項
/usr/lib/systemd/system/docker.service
ExecStart=/usrt/bin/docker -d --selinux enabled -H tcp://0.0.0.0:2375
Docker 守護進程能夠綁定到一個接口上
重新加載和啟動Docker守護集成
systemctl --system daemon-reload
Docker 守護進程之間的網(wǎng)絡(luò)連接是沒有經(jīng)過認(rèn)證的, 是對外開放的
返回json散列數(shù)據(jù)
curl htpp://docker.example.com:2375/info
使用python的json工具, 對API返回結(jié)果進行格式化處理
curl http://docker.example.com:2375/images/json|python -mjson.tool
查詢
curl "http://docker.exampl.com:2375/images/search?term=jamtur01"|python -mjson.tool
獲取正在運行的容器
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è)置主機名*
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)證
建立證書授權(quán)中心
mkdir /etc/docker
cd /etc/docker
echo 01>|sudo tee ca.srl
openssl genrsa -des3 -out ca-key.pem
創(chuàng)建CA證書
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ù)器證書
對CSR進行簽名
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)建客戶端證書和密鑰
創(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
對客戶端CSR進行簽名
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到運行的Docker客戶端的宿主機上
復(fù)制到~/.docker目錄下