歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Docker基礎與高級

Docker基礎與高級

日期:2017/2/28 14:25:41   编辑:Linux教程

最近在學習 Docker 看到國外一個牛人和自己的實踐顧寫下此篇文章,以用來為故而知新!

1. Docker 是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後發布到任何流行的 Linux 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app)。幾乎沒有性能開銷,可以很容易地在機器和數據中心中運行。最重要的是,他們不依賴於任何語言、框架或包括系統。


2.

CentOS 6/7系列安裝Docker http://www.linuxidc.com/Linux/2014-07/104768.htm

Docker的搭建Gitlab CI 全過程詳解 http://www.linuxidc.com/Linux/2013-12/93537.htm

Docker安裝應用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

在 Docker 中使用 MySQL http://www.linuxidc.com/Linux/2014-01/95354.htm

在Ubuntu Trusty 14.04 (LTS) (64-bit)安裝Docker http://www.linuxidc.com/Linux/2014-10/108184.htm

Docker安裝應用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 14.04安裝Docker http://www.linuxidc.com/linux/2014-08/105656.htm

阿裡雲CentOS 6.5 模板上安裝 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm


1.Docker安裝


2.devicemapper


3.玩轉net namespace


•3.1. ENV(環境變量)


port map直接使用docker默認分配的IP對外提供服務(測試中)

•5.1. 使用參數以及將docker0的ip配為機房內網網段


Docker COMMAND

•6.1. docker參數


•6.2. run


搭建私有Registry注冊中心

•7.1. 下載軟件


•7.2. 啟動服務


•7.3. 使用


•7.4. 套一層透明代理(不推薦,有bug)


•7.5. Web UI


docker with HTTPS

•8.2.1. 創建CA(證書頒發中心)


•8.2.2. 創建服務端公鑰和私鑰


•8.2.3. 創建客戶端公鑰和私鑰


•8.2.4. 移除服務端私鑰、客戶端私鑰密碼


•8.2.5. 使用


•8.2.6. 管理


•8.1. 原理


•8.2. 使用


Docker Web-UI(shipyard)

•9.5.1. 頁面上的Images(http://192.168.1.1:8000/images/)進行鏡像刪除要注意


•9.5.2. server端管理


•9.5.3. 不建議生產使用,可作為學習借鑒


•9.4.1. 登錄頁面


•9.4.2. 接受agent注冊


•9.3.1. 下載鏡像


•9.3.2. 啟動容器(自動注冊到server)


•9.2.1. 下載鏡像


•9.2.2. 啟動容器(自動完成部署)


•9.2.3. 驗證


•9.1. 工作原理


•9.2. server配置


•9.3. agent配置


•9.4. 頁面配置


•9.5. 注意


鏡像制作

•10.1. 遠程編譯Dockerfile


11.內置bridge(nat)和自建網絡橋接使用區別Docker Event事件監聽

•12.1. 方法1:使用remote api


•12.2. 方法2:使用unix socket


•12.3. 方法3: 使用docker events命令


神器

•13.1. nsenter(無需sshd、無需attach也可以登錄容器)


FAQ

•14.5.1. HTTP code 403 while uploading metadata: invalid character ‘<‘ looking for beginning of value


•14.5.2. dial tcp 127.0.0.1:5000: connection refused


•14.1. sshd服務起不來


•14.2. ulimit無法更改open-file、max processes


•14.3. 改變/var/lib/docker路徑


•14.4. 將指定鏡像標識為latest


•14.5. docker push報錯


•14.6. CMD 和 ENTRYPOINT的區別


tag: cloud, virtual, docker, lxc

1. Docker安裝

按照官方說明:紅帽6、centos均通過epel源,執行yum install docker-io進行docker安裝,啟動服務是service docker start


經測試,紅帽6、centos也可以通過在官網上下載編譯好的二進制文件到本地也可以使用,但需要提前手動執行service cgconfig start來掛載cgroup,然後./docker-latest -d來啟動服務。
下載地址:https://get.docker.io/builds/Linux/x86_64/docker-latest

https://get.docker.io/builds/Linux/x86_64/docker-1.0.1

但是官方提示需要內核大於3.8版本,否則可能會有問題。el>3.8

2. devicemapper

擴容存儲池大小、擴容容器文件系統大小
https://www.dockboard.org/resizing-docker-containers-with-the-device-mapper-plugin/

實驗成功,但是一旦容器關閉再啟動,就會報錯,還得根據文檔再做一次dmsetup load; dmsetup resume才能成功啟動容器(但是如果不先啟動容器,就無法使用dmsetup命令來resume),因此能否用於生產環境有待繼續探索


3. 玩轉net namespace

首先要支持ip netns指令。而紅帽6及epel均不支持,解決方法:
yum install -y http://rdo.fedorapeople.org/rdo-release.rpm
yum update -y iproute


ip netns
直接執行這個命令(或ip netns list)讀取的是/var/run/netns下的文件名,因此若不存在/var/run/netns,需要mkdir -p /var/run/netns


配置像LXC一樣的網絡
I. 宿主配置
1. 宿主上升級iproute包,以便支持ip netns指令:
yum install -y http://rdo.fedorapeople.org/rdo-release.rpm
yum update -y iproute

2. 在宿主上配置好橋接:
一. 方法1(不推薦): 敲命令配置橋接(很容易導致網絡中斷,需要ILO連上操作)
1) 創建橋接網卡br1並激活:brctl addbr br1; ip link set br1 up
2) 配置br1的mac地址,和宿主准備橋接的網卡mac相同,通常為內網網卡eth1:ip link set br1 address xx:xx:xx:xx:xx:xx
3) 給br1配置一個ip地址,或者將eth1的ip地址配置在br1上,2種方法任選其一都可行:
前者:
ifconfig br1 192.168.2.1 netmask 255.255.255.0
後者:
ifconfig eth1 0.0.0.0; ifconfig br1 192.168.2.2 netmask 255.255.255.0
4) 配置宿主網關,從br1出
ip ro del default
ip ro add default via 192.168.2.254 dev br1
5) 將eth1橋接至br1:
brctl addif br1 eth1
二. 方法2(推薦):寫網卡配置文件
ifcfg-br1:
DEVICE="br1"
TYPE="Bridge"
NM_CONTROLLED="no"
ONBOOT="yes"
BOOTPROTO="static"
IPADDR=192.168.2.2
NETMASK=255.255.255.0

ifcfg-eth1:
DEVICE="eth1"
BRIDGE="br1"
BOOTPROTO="none"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"

注意:要在/etc/sysconfig/network-scripts/ifup-eth裡if [ "${TYPE}" = "Bridge" ]; then -> fi段落最後(fi前)加個ip link set br1 address $(get_hwaddr eth1),防止橋接網卡mac地址隨機生成導致網絡暫時中斷

service network restart # 重啟網絡生效

II. 容器配置:
1. 啟動docker容器:
docker run -t -i -d --name="net_test" --net=none centos:latest /bin/bash
記錄下輸出(即CONTAINER ID),然後通過docker inspect -f '{{.State.Pid}}' CONTAINER ID獲得該容器的pid(也即容器首進程在宿主上的pid),假設為1000
2. 為容器創建網卡命名空間,建立點對點連接(容器命名空間網卡和宿主上生成的網卡點對點)
mkdir -p /var/run/netns #創建網絡命名空間目錄,ip netns會讀取該目錄下的文件名
ln -s /proc/1000/ns/net /var/run/netns/1000 #將網絡命名空間文件軟鏈接到/var/run/netns,以便ip netns能夠讀取
ip link add vethA type veth peer name vethB #在宿主上創建2張直連網卡(vethA與vethB直連),將vethA作為容器裡的網卡,vethB作為宿主上能看到的網卡
ip link set vethB up # 激活網卡vethB
ip link set vethA netns 1000 # 將剛才創建的網卡歸位網絡命名空間
配置vethA網卡參數:
ip netns exec 1000 ip link set vethA name eth1
ip netns exec 1000 ip addr add 192.168.2.3/24 dev eth1
ip netns exec 1000 ip link set eth1 up
ip netns exec 1000 ip route add default via 192.168.2.254 dev eth1
brctl addif br1 vethB # 將eth1橋接至br1
3. 測試:
docker attach登錄容器,查看是否能ping通網關及其他子網或公網


3.1. ENV(環境變量)

Dockerfile支持ENV參數,表示啟動容器時候設置變量。

只在CMD啟動的進程export設置變量,而不是將變量賦值命令寫入/etc/profile等腳本裡,因此通過ssh方式登錄容器獲得的shell是沒有這個變量的

4. port map

docker支持端口映射,通過iptables DNAT將宿主上的端口轉發至容器ip對應端口。

雖然配置了端口映射後,在宿主上通過netstat -lntpu可以看到docker進程會監聽這個端口,但是還沒發現其作用,因為流量直接從iptables就進入容器裡。

docker run -p、docker run -P、docker port作用:
docker run -P 就是將image定好的port給做個端口映射(若沒指定-p,則外部端口隨機)
docker run -p "8080:80" 啟動容器時候做端口映射:宿主的0.0.0.0:8080 -> 容器80
docker run -P -p "8080:80" 假如image已經有一個port 22的配置,那麼就會做2個端口映射:宿主0.0.0.0:xxxxx -> 容器22、宿主0.0.0.0:8080 -> 容器80
docker port 是查看容器已經做了端口映射的端口被映射到了哪個端口上,其實直接用docker ps就能看到,使用docker port可能是為了方便二次開發


5. 直接使用docker默認分配的IP對外提供服務(測試中)

5.1. 使用參數以及將docker0的ip配為機房內網網段

將宿主eth1橋接到docker0上,將docker0的ip更改為原來eth1的ip(機房內網網段)

存在一個問題:docker run時候分配的ip是從1開始,到254。因此存在和網關或者其他機器ip沖突的可能,無法避免。因此docker分配ip不會做ping檢查是否存活


docker run分配出去的ip,docker kill並且docker rm都不會收回並重新使用,而是重啟docker daemon才會將ip收回

–iptables=false
使用這個參數後,就不會再往iptables裡生成nat、forward等信息了。

這樣啟動的容器,登錄容器能看到網關是宿主docker0的ip,這樣網絡是通的,是可以訪問外網,但路是這麼走的:
1. 容器裡的數據包將數據經過point-to-point網卡傳送到宿主的對應veth網卡上
2. 宿主veth網卡接收到數據包後發現網關是254,於是通過icmp數據包告知網關是254,然後容器發送數據包時自動將網關更改為254,可以從ping的輸出看到:
[ 17:37:23-root@21e77bf38fc0:~ ]#ping www.baidu.com
PING www.a.shifen.com (115.239.210.27) 56(84) bytes of data.
64 bytes from 115.239.210.27: icmp_seq=1 ttl=55 time=13.9 ms
From 192.168.3.1: icmp_seq=2 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=2 ttl=55 time=13.6 ms
From 192.168.3.1: icmp_seq=3 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=3 ttl=55 time=13.6 ms
From 192.168.3.1: icmp_seq=4 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=4 ttl=55 time=14.0 ms
From 192.168.3.1: icmp_seq=5 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=5 ttl=55 time=14.7 ms
From 192.168.3.1: icmp_seq=6 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=6 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=7 ttl=55 time=13.7 ms
From192.168.3.1: icmp_seq=8 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=8 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=9 ttl=55 time=13.6 ms
64 bytes from 115.239.210.27: icmp_seq=10 ttl=55 time=13.5 ms
From 192.168.3.1: icmp_seq=11 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=11 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=12 ttl=55 time=14.1 ms
64 bytes from 115.239.210.27: icmp_seq=13 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=14 ttl=55 time=13.6 ms
64 bytes from 115.239.210.27: icmp_seq=15 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=16 ttl=55 time=13.8 ms
From 192.168.3.1: icmp_seq=17 Redirect Host(New nexthop: 192.168.3.254)
64 bytes from 115.239.210.27: icmp_seq=17 ttl=55 time=13.6 ms
64 bytes from 115.239.210.27: icmp_seq=18 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=19 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=20 ttl=55 time=14.1 ms
64 bytes from 115.239.210.27: icmp_seq=21 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=22 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=23 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=24 ttl=55 time=13.9 ms
64 bytes from 115.239.210.27: icmp_seq=25 ttl=55 time=14.2 ms
64 bytes from 115.239.210.27: icmp_seq=26 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=27 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=28 ttl=55 time=13.8 ms
64 bytes from 115.239.210.27: icmp_seq=29 ttl=55 time=13.9 ms
64 bytes from 115.239.210.27: icmp_seq=30 ttl=55 time=14.1 ms
64 bytes from 115.239.210.27: icmp_seq=31 ttl=55 time=13.9 ms
64 bytes from 115.239.210.27: icmp_seq=32 ttl=55 time=13.9 ms
64 bytes from 115.239.210.27: icmp_seq=33 ttl=55 time=14.0 ms
64 bytes from 115.239.210.27: icmp_seq=34 ttl=55 time=13.7 ms
64 bytes from 115.239.210.27: icmp_seq=35 ttl=55 time=14.0 ms
64 bytes from 115.239.210.27: icmp_seq=36 ttl=55 time=14.4 ms
64 bytes from 115.239.210.27: icmp_seq=37 ttl=55 time=13.9 ms

docker服務啟動時候會把內核參數ip.forward給打開(數據包轉發)

6. Docker COMMAND

6.1. docker參數

–api-enable-cors
開啟cors,以便浏覽器能夠通過ajax調用。但是若開啟了tls,使用cors就變得困難了,目前網絡上還未找到解決方案


6.2. run

–link:2個容器互通
其實就做3件事:
1. 若有端口映射,則在iptables的FORWARD鏈裡將端口ACCEPT
2. /etc/hosts:做link的容器的/etc/hosts能看到被link的容器的hosts條目
3. 環境變量:做link的容器可以看到被link的容器的環境變量(僅為--env變量),如:ALIAS_ENV_變量名、ALIAS_NAME=xxx


–volume: 目錄共享
支持2種模式:
1. 從宿主掛載:-v /tmp:/tmp/foo 表示將宿主的/tmp目錄掛載至容器的/tmp/foo目錄,可讀可寫,和mount --bind的效果類似
2. 容器之間共享:
啟動第一個容器時帶參數-v /tmp/foo表示在宿主上創建/var/lib/docker/vfs/dir/xxxxx(id,但不是容器id),然後掛進容器的/tmp/foo目錄;
啟動第二個容器時帶參數--volumes-from=b5f8320cf019(*第一個容器id)表示和第一個容器共享掛載,因此第二個容器啟動後也能從df -h看到/tmp/foo目錄被掛載。從inspect也可以很容易看出來(2個容器的inspect以下內容相同):
"Volumes": {
"/opt": "/var/lib/docker/vfs/dir/a7b1b03773d9391718b8524e7ac001bb877eb6d0596fa2a4328435d8c49f2415"
},
"VolumesRW": {
"/opt": true
}

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-11/109612p2.htm

Copyright © Linux教程網 All Rights Reserved