前言:在docker1.12中默認增長了swarm mode 編排功能,而且官方支持更多的插件來進行docker的網路和外接存儲插件,不過目前測試swarm mode的功能並非特別理想,還存在一些問題,之後文章可能會講到,固然畢竟swarm是在docker1.12中新加進來的,想必之後會作的更好,趕超mesos+marathon和kubernetes仍是頗有但願的。
1.Docker存儲驅動詳解:html
http://blog.csdn.net/zhangyifei216/article/details/50697855
須要注意的是,docker默認支持集中存儲驅動:devicemapper,aufs,overlay,btrfs等。在ubuntu系列,默認的的存儲驅動是aufs,這種方式是比較適合上生產的;在centos系列上默認的存儲驅動是devicemapper,這種方式目前不建議上生產,由於默認使用的是/dev/loop1虛擬設備進行存儲數據的,這樣可能致使數據的不穩定,以及將來的不可擴展(官方建議是使用devicemapper的時候使用direct-lvm)。node
詳細的存儲驅動官方文檔以下:
https://docs.docker.com/engine/userguide/storagedriver/selectadriver/#select-a-storage-driverpython
Device Mapper:
Ubuntu默認使用AUFS做爲存儲驅動,可是AUFS並無被包括在Linux的主線內核中。CentOS中可使用Device Mapper做爲存儲驅動,這是在2.6.9內核版本引入的新功能。咱們須要先確認是否啓用該功能(相應的包爲device-mapper):linux
# ll /sys/class/misc/device-mapper lrwxrwxrwx 1 root root 0 Jul 20 14:27 /sys/class/misc/device-mapper -> ../../devices/virtual/misc/device-mapper
然而從官方文檔以及上面的各類存儲驅動比較圖中能夠看到,devicemapper在centos上默認使用的/dev/loop設備仍是不建議在生產中使用的。然而解決這個問題辦法就兩種,使用lvm方式存放在存儲上,或者直接使用額外的分區。
http://www.youruncloud.com/blog/92.htmlgit
使用官方建議的direct-lvm模式進行搭建docker存儲:
https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/github
DOCKER_STORAGE_OPTIONS="--storage-driver devicemapper --storage-opt dm.fs=xfs --storage-opt dm.thinpooldev=/dev/mapper/centos-docker--pool --storage-opt dm.use_deferred_removal=true --storage-opt dm.use_deferred_deletion=true "
2.基本環境搭建redis
# uname -r 3.10.0-327.el7.x86_64 # cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 必需要使用centos7的yum源,由於安裝過程當中須要依賴某些組件,好比libgroup之類的
不建議直接使用docker官方的docker yum源進行安裝,由於會依據系統版本去選擇docker版本,不能指定相應的版本進行選擇安裝。本篇文章將使用docker1.12進行部署。
能夠直接在github上獲取docker各個版本包:
https://github.com/docker/docker/releases
http://yum.dockerproject.org/repo/main/centos/7/Packages/
上面連接中提供了全部的docker核心包,詳細包以下:docker
能夠直接使用yum localinstall進行安裝部署。默認會從centos7的官方源中安裝依賴(audit-libs-python.x86_64 0:2.4.1-5.el7 checkpolicy.x86_64 0:2.1.12-6.el7 libcgroup.x86_64 0:0.41-8.el7 libseccomp.x86_64 0:2.2.1-1.el7 libsemanage-python.x86_64 0:2.1.10-18.el7 libtool-ltdl.x86_64 0:2.4.2-20.el7 policycoreutils-python.x86_64 0:2.2.5-20.el7 python-IPy.noarch 0:0.75-6.el7 setools-libs.x86_64 0:3.3.7-46.el7 ) #yum localinstall docker-engine-1.12.0-1.el7.centos.x86_64.rpm docker-engine-debuginfo-1.12.0-1.el7.centos.x86_64.rpm docker-engine-selinux-1.12.0-1.el7.centos.noarch.rpm -y
# docker version Client: Version: 1.12.0 API version: 1.24 Go version: go1.6.3 Git commit: 8eab29e Built: OS/Arch: linux/amd64 Cannot connect to the Docker daemon. Is the docker daemon running on this host? 注意:以上顯示當前docker版本爲1.12,而且docker 服務端程序沒有啓動。可使用默認的dockerd啓動,也可使用默認 systemctl status docker .同時也可使用docker --help查看相關功能特性
# dockerd INFO[0000] libcontainerd: new containerd process, pid: 10622 WARN[0000] containerd: low RLIMIT_NOFILE changing to max current=1024 max=4096 WARN[0001] devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man docker` to refer to dm.thinpooldev section. WARN[0001] devmapper: Base device already exists and has filesystem xfs on it. User specified filesystem will be ignored. INFO[0001] [graphdriver] using prior storage driver "devicemapper" INFO[0001] Graph migration to content-addressability took 0.00 seconds WARN[0001] mountpoint for pids not found INFO[0001] Loading containers: start. INFO[0001] Firewalld running: false INFO[0001] Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address INFO[0001] Loading containers: done. INFO[0001] Daemon has completed initialization INFO[0001] Docker daemon commit=8eab29e graphdriver=devicemapper version=1.12.0 INFO[0001] API listen on /var/run/docker.sock 注意:其實在提示中咱們能夠看出來使用的橋接網絡docker0的172.17.0.0/16,而且用的是devicemapper存儲引擎,以及當前docker的版本。
經過centos系統自帶的systemd服務管理docker:json
#systemctl restart/stop/start/reload/status docker ubuntu
# docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 1.12.0 Storage Driver: devicemapper #默認使用的存儲引擎,centos使用devicemapper,ubuntu系列使用的是aufs Pool Name: docker-8:2-34118597-pool Pool Blocksize: 65.54 kB Base Device Size: 10.74 GB Backing Filesystem: xfs #當前系統使用的文件系統 Data file: /dev/loop0 #docker的數據存儲設備,默認使用的是本地虛擬的一塊設備,侷限是最大隻能承受100G。 Metadata file: /dev/loop1 #docker的元數據存儲設備 Data Space Used: 11.8 MB Data Space Total: 107.4 GB Data Space Available: 31.06 GB Metadata Space Used: 581.6 kB Metadata Space Total: 2.147 GB Metadata Space Available: 2.147 GB Thin Pool Minimum Free Space: 10.74 GB Udev Sync Supported: true Deferred Removal Enabled: false Deferred Deletion Enabled: false Deferred Deleted Device Count: 0 Data loop file: /var/lib/docker/devicemapper/devicemapper/data #docker數據存儲文件 WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device. Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata #元數據存儲目錄 Library Version: 1.02.107-RHEL7 (2015-10-14) Logging Driver: json-file Cgroup Driver: cgroupfs #cgroup驅動使用的是cgroupfs Plugins: #當前docker使用的插件 Volume: local #volume默認使用的是本地,以後咱們會擴展使用nfs Network: null overlay bridge host #默認使用的是本地橋接方式,overlay方式能夠支持多主機之間的容器互相通訊,固然也可使用一些第三方插件,好比pipnetwork Swarm: inactive #swarm目前是能夠用的,一種docker集羣編排方式 Runtimes: runc Default Runtime: runc Security Options: seccomp Kernel Version: 3.10.0-327.el7.x86_64 #內核以及操做系統相關信息 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 4 Total Memory: 3.702 GiB Name: xxxxx ID: JUNK:WIJU:463W:VBKM:YT2X:FTE3:F5G4:T5DK:2HTP:HPFB:J4ER:3Y72 Docker Root Dir: /var/lib/docker #docker默認的家目錄,數據相關的最後都會存儲在這個地方 Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ WARNING: bridge-nf-call-iptables is disabled WARNING: bridge-nf-call-ip6tables is disabled Insecure Registries: 127.0.0.0/8 注意:上面bridge-nf-call-iptables的警告是內核沒有開啓橋接模式的iptables。這個應該只是影響nat表中的prerouting鏈,因此以後的實驗中應該用不到,可是若是想要開啓的話執行如下命令。 #echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables #echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
使用dockerd –help能夠查看docker啓動相關的參數:
https://docs.docker.com/engine/reference/commandline/dockerd/
#dockerd --help(其實dockerd就至關於以前的docker -d) -b, --bridge #指定容器使用的網絡接口,默認爲docker0,也能夠指定其餘網絡接口 --bip #指定橋接地址,即定義一個容器的私有網絡 --cgroup-parent #爲全部的容器指定父cgroup --cluster-advertise #爲集羣設定一個地址或者名字 --cluster-store #後端分佈式存儲的URL --cluster-store-opt=map[] #設置集羣存儲參數 --config-file=/etc/docker/daemon.json #指定配置文件 -D #啓動debug模式 --default-gateway #爲容器設定默認的ipv4網關(--default-gateway-v6) --dns=[] #設置dns --dns-opt=[] #設置dns參數 --dns-search=[] #設置dns域 --exec-opt=[] #運行時附加參數 --exec-root=/var/run/docker #設置運行狀態文件存儲目錄 --fixed-cidr #爲ipv4子網綁定ip -G, --group=docker #設置docker運行時的屬組 -g, --graph=/var/lib/docker #設置docker運行時的家目錄 -H, --host=[] #設置docker程序啓動後套接字鏈接地址 --icc=true #是內部容器能夠互相通訊,環境中須要禁止內部容器訪問 --insecure-registry=[] #設置內部私有註冊中心地址 --ip=0.0.0.0 #當映射容器端口的時候默認的ip(這個應該是在多主機網絡的時候會比較有用) --ip-forward=true #使net.ipv4.ip_forward生效,其實就是內核裏面forward --ip-masq=true #啓用ip假裝技術(容器訪問外部程序默認不會暴露本身的ip) --iptables=true #啓用容器使用iptables規則 -l, --log-level=info #設置日誌級別 --live-restore #啓用熱啓動(重啓docker,保證容器一直運行1.12新特性) --log-driver=json-file #容器日誌默認的驅動 --max-concurrent-downloads=3 #爲每一個pull設置最大併發下載 --max-concurrent-uploads=5 #爲每一個push設置最大併發上傳 --mtu #設置容器網絡的MTU --oom-score-adjust=-500 #設置內存oom的平分策略(-1000/1000) -p, --pidfile=/var/run/docker.pid #指定pid所在位置 -s, --storage-driver #設置docker存儲驅動 --selinux-enabled #啓用selinux的支持 --storage-opt=[] #存儲參數驅動 --swarm-default-advertise-addr #設置swarm默認的node節點 --tls #使用tls加密 --tlscacert=~/.docker/ca.pem #配置tls CA 認證 --tlscert=~/.docker/cert.pem #指定認證文件 --tlskey=~/.docker/key.pem #指定認證keys --userland-proxy=true #爲迴環接口使用用戶代理 --userns-remap #爲用戶態的namespaces設定用戶或組
注意:由於默認的dockerd參數不必定適合咱們使用的環境,所以在啓動的時候咱們須要針對實際狀況去配置相應的參數,好比docker數據家目錄以及默認容器的私有地址等等
#!/bin/bash pvcreate /dev/vda1 vgcreate docker /dev/vda1 lvcreate --wipesignatures y -n thinpool docker -l 95%VG lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG lvconvert -y --zero n -c 512K --thinpool docker/thinpool --poolmetadata docker/thinpoolmeta echo "activation { thin_pool_autoextend_threshold=80 thin_pool_autoextend_percent=20 }" > /etc/lvm/profile/docker-thinpool.profile lvchange --metadataprofile docker-thinpool docker/thinpool echo "Print the vgs:" vgdisplay echo "Print the lvs:" lvdisplay lvs -o+seg_monitor systemctl daemon-reload systemctl start docker
2.修改和配置centos7中docker啓動配置文件:
centos系統的配置文件/usr/lib/systemd/system/docker.service,這個是模板文件:
#mkdir /etc/systemd/system/docker.service.d #touch /etc/systemd/system/docker.service.d/docker.conf #cat /etc/systemd/system/docker.service.d/docker.conf # #線上詳細配置 ExecStart=/bin/dockerd --storage-driver=devicemapper --storage-opt=dm.thinpooldev=/dev/mapper/docker-thinpool --storage-opt dm.use_deferred_removal=true -D -H tcp://0.0.0.0:5256 -H unix:///var/run/docker.sock --pidfile=/var/run/docker.pid --swarm-default-advertise-addr=172.25.47.210 --bip=10.0.0.1/24 --icc=false --insecure-registry=172.25.46.8:5001 注意: #存儲驅動參數--storage-opt詳情 dm.thinpooldev 爲docker存儲的thin pool指定一個可用的塊存儲設備(默認的是/dev/loop設備;生產環境建議使用direct-lvm) dm.basesize 當建立一個基礎設備(用來限制images和container的大小)的時候,指定大小。默認會給一個容器10G。須要注意的是,base device size 可用在docker重啓的時候增長。可是每次修改完配置後必須把相應的/var/lib/docker底下的相關目錄刪除掉。不然重啓會檢測失敗。 dm.fs 爲base device指定使用的文件系統類型(ext4,xfs默認) dm.mkfsarg 指定額外的格式化參數(--storage-opt "dm.mkfsarg=-O ^has_journal") dm.datadev/dm.metadatadev 設置docker存儲的data和metadata,不過已通過時了,目前使用的基本都是dm.thinpooldev參數(--storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1)
修改完配置文件以後須要刷新下配置:
systemctl daemon-reload
systemctl restart docker
查看相關日誌:
journalctl -u docker
ubuntun系統的配置文件默認在/etc/default/docker
[Unit] Description=Redis container Requires=docker.service After=docker.service [Service] Restart=always ExecStart=/usr/bin/docker start -a redis_server ExecStop=/usr/bin/docker stop -t 2 redis_server [Install] WantedBy=default.target
若是把這個容器做爲一個系統服務,須要將上面的配置添加到文件/etc/systemd/system/docker-redis_server.service.
若是須要傳入參數到到容器裏面,好比–env那你必須使用docker run,而不是docker start,這樣在每次服務啓動的時候會建立一個新的容器。
[Service] ... ExecStart=/usr/bin/docker run --env foo=bar --name redis_server redis ExecStop=/usr/bin/docker stop -t 2 redis_server ExecStopPost=/usr/bin/docker rm -f redis_server ...
啓動上面的docker容器:
systemctl daemon-reload
systemctl start docker-redis_server.service
systemctl enable docker-redis_server.service
1.首先咱們得確認docker在啓動的時候支持熱加載選項,兩種方式以下:
docker已啓動,又不想中止,能夠增長一個配置文件到docker服務的配置文件中
#vim /etc/docker/daemon.json { "live-restore": true }
修改完配置以後必須發送一個SIGHUB
信號給docker守護進程以便從新加載配置。
要麼就在啓動的時候加上--live-restore參數
2.這種熱啓動其實能夠用在docker的升級期間。可是若是你是跳過一個版本去升級的,守護進程可能不會從新加載鏈接到容器,若是不能鏈接到容器的話,你就必須手動的去管理容器了,守護進程不會去關掉這些斷開鏈接的容器。
3.熱重啓用在restart docker守護進程的時候,能夠減小用戶的卡頓(可是前提是重啓的時候主配置不能變,好比網橋啦,還有數據存儲目錄啦)
4.熱重啓對運行中的容器的影響。守護進程的長時間卡頓可能影響運行中的容器。由於容器進程會寫FIFO日誌,以便供守護進程消費,若是守護進程不可用,不能消費容器輸出內容,buffer酒會慢,而且堵塞不能寫進日誌。默認的buffer大小爲64k,此時必須重啓docker去刷新buffer。
buffer大小的修改:
/proc/sys/fs/pipe-max-size
5.熱重啓和swarm 模式
熱重啓參數和docker swarm模式不兼容,當docker1⃣️swarm模式運行,整個docker流程主要用來管理任務和保證容器按照必定的服務標準運行。
1.使用systemd管理docker
#systemctl stop/start/status/enable/restart docker `默認systemd管理的服務都會放在/usr/lib/systemd/system/docker.service類此這樣的目錄.固然也是能夠自定義加載配置文件的`
2.自定義docker啓動選項
有多種推薦的方式去自定義修改docker啓動參數,這裏推薦的一種就是使用systemd的drop-in文件去加載相應的參數。其實就是建立一個目錄/etc/systemd/system/docker.service.d,而後在目錄裏面加載相應的配置文件*.conf.
注意:這種方式須要注意會默認包含/etc/systemd/system/docker.service,由於這個文件是從/lib/systemd/system/docker.service複製過來的
# cat /etc/systemd/system/docker.service.d/docker.conf [Service] ExecStart= ExecStart=/bin/dockerd -D -H tcp://0.0.0.0:5256 -H unix:///var/run/docker.sock --pidfile=/var/run/docker.pid --swarm-default-advertise-addr=172.25.47.210 --bip=10.0.0.1/24 --icc=false -g /export/lib/docker --insecure-registry=172.25.46.8:5001
須要注意的是,必須配置兩個execstart才能正確啓動docker
使用systemctl show能夠查看服務相關的配置,好比如下查看啓動時加載參數:
也能夠查看docker環境加載配置
systemctl show docker | grep EnvironmentFile
EnvironmentFile=-/etc/sysconfig/docker (ignore_errors=yes)
# systemctl show docker | grep ExecStart ExecStart={ path=/bin/dockerd ; argv[]=/bin/dockerd -D -H tcp://0.0.0.0:5256 -H unix:///var/run/docker.sock --pidfile=/var/run/docker.pid --swarm-default-advertise-addr=172.25.47.210 --bip=10.0.0.1/24 --icc=false -g /export/lib/docker --insecure-registry=172.25.46.8:5001 ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
配置運行時目錄以及存儲引擎相關:
其實上面的啓動配置中已經加載了運行時目錄爲-g /export/lib/docker 設置存儲引擎–storage-driver=overlay/devicemapper/aufs
配置http代理
#cat /etc/systemd/system/docker.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=http://proxy.example.com:80/" 若是:內部的docker registries 不須要經過代理去鏈接,能夠按照如下配置: Environment="HTTP_PROXY=http://proxy.example.com:80/" "NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"
刷新配置查看配置文件正確後重啓:
systemctl daemon-reload
systemctl show –property=Environment docker
systemctl restart docker
示例:
# docker ps --format '{{json .Names}}' "xxbandy-1" "xxbandy" # docker ps --format '{{json .Ports}}' "0.0.0.0:2221-\u003e8000/tcp" "0.0.0.0:2222-\u003e8000/tcp" #docker inspect --format '{{json .Config}}' xxbandy {"Hostname":"jupyterhub","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"8000/tcp":{}},"Tty":true,"OpenStdin":true,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["bash"],"Image":"172.25.46.8:5001/jupyter","Volumes":null,"WorkingDir":"/export","Entrypoint":null,"OnBuild":null,"Labels":{"build-date":"20160701","license":"GPLv2","name":"CentOS Base Image","vendor":"CentOS"}} # docker inspect --format '{{json .NetworkSettings.IPAddress}}' xxbandy "10.0.0.2" # docker inspect --format '{{json .NetworkSettings.Ports}}' xxbandy {"8000/tcp":[{"HostIp":"0.0.0.0","HostPort":"2222"}]} 默認是map映射格式: # docker inspect --format '{{ .NetworkSettings.Ports}}' xxbandy map[8000/tcp:[{0.0.0.0 2222}]]
1.docker使用docker stats命令來查看容器的運行狀態,支持查看CPU ,MEM,NET等狀態。
# docker stats --no-stream xxbandy CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS xxbandy 0.01% 123.2 MiB / 3.702 GiB 3.25% 6.632 MB / 4.066 MB 52.11 MB / 6.328 MB 0
2.Cgroups
linux容器技術依賴於cgroup技術,經過cgroup相關文件能夠暴露出來cpu,內存以及I/0的使用狀況。cgroup經過一個pseudo-filesystem暴露使用詳情,所以你能夠在/sys/fs/cgroup中去找到相關的查找。固然也有一些老的linux系統會將cgroup掛載在/cgroup下,這個能夠查看cgroup包具體講一些軟件裝在什麼地方。固然也能夠直接使用如下命令發現當前系統掛載點:
# grep cgroup /proc/mounts
3.列舉cgroup能夠管控的資源信息:
# cat /proc/cgroups
固然也可使用/proc/pid/cgroup查看一個進程屬於哪一個控制組信息,或者經過查看某一個正在運行容器使用的內存限制:/sys/fs/cgroup/memory/docker/longid/.
4.內存,cpu,block I/O上的限制:
可使用memory.stat文件進行內存上的限制,
# cat /sys/fs/cgroup/memory/docker/memory.stat cache 20082688 rss 0 rss_huge 0 mapped_file 6488064 swap 0 pgpgin 4903 pgpgout 0 pgfault 0 pgmajfault 0 inactive_anon 0 active_anon 0 inactive_file 13438976 active_file 6643712 unevictable 0 hierarchical_memory_limit 9223372036854775807 hierarchical_memsw_limit 9223372036854775807 total_cache 20082688 total_rss 3604480 total_rss_huge 0 total_mapped_file 6488064 total_swap 0 total_pgpgin 7694 total_pgpgout 2422 total_pgfault 5083 total_pgmajfault 0 total_inactive_anon 0 total_active_anon 3604480 total_inactive_file 13438976 total_active_file 6643712 total_unevictable 0
上圖中前半部分沒有以total_開頭的是在cgroups中有關進程的統計,後半部分包含sub-cgrouops的統計。
cache:這個被cgroup控制進程的內存值會在block設備上分配一個block,當在讀寫disk上的文件,這個值會增長。這也是被tmpfs使用的內存值
rss:這個值不會和磁盤上的一致:stacks,heaps, anonymous memory maps
mapped_file:表示映射到cgroup裏面進程的內存量,不會告訴你使用了多少內存信息,只會告訴你他怎樣被使用的。
swap:cgroup中被進程使用的當前swap值
可使用cpuacct.stat文件對容器的cpu進行相關限制:
顯示當前全部容器中進程佔用的cpu # cat /sys/fs/cgroup/cpu,cpuacct/docker/cpuacct.stat user 1153 system 717
/sys/fs/cgroup/blkio目錄中存放block I/O相關信息
5.網絡資源的測量:
網絡資源部直接由cgroup控制,網絡接口直接存在於network namespace。內核可以經過一組進程計算每一個包和發送/接受字節的長度,可是這些值通常並無什麼用。
So,通常會使用如下工具進行收集網絡情況信息:
# iptables -I OUTPUT -p tcp --sport 80 # iptables -nxvL OUTPUT Chain OUTPUT (policy ACCEPT 3 packets, 396 bytes) pkts bytes target prot opt in out source destination 0 0 tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:80