1、安裝docker
通過Docker源安裝最新版本。要安裝最新的 Docker 版本,首先需要安裝 apt-transport-https
支持,之後通過添加源來安裝。
方法一:(已驗證)
$ sudo apt-get install apt-transport-https
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update
$ sudo apt-get install lxc-docker
方法二:
sudo apt-get purge docker.io
curl -s https://get.docker.io/ubuntu/ | sudo sh
sudo apt-get update
sudo apt-get install lxc-docker
2、啓動docker
$ sudo service docker start
3、快速停用或刪除容器
(1)停用全部運行中的容器:
docker stop $(docker ps -q)
(2)刪除全部容器:
docker rm $(docker ps -aq)
(3)一條命令實現停用並刪除容器:
docker stop $(docker ps -q) & docker rm $(docker ps -aq)
4、docker使用--以mysql爲實例說明
(1)拉取mysql鏡像
sudo docker pull mysql
(2)查看docker鏡像
docker images
(3)運行一個mysql實例
docker run --name sampson-mysql -p 3308:3308 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
5b6bf6f629bfe46b4c8786b555d8db1947680138b2de1f268f310a15ced7247a
run 運行一個容器
--name 後面是這個鏡像的名稱
-p 3308:3308 表示在這個容器中使用3308端口(第二個)映射到本機的端口號也爲3308(第一個)
-d 表示後臺運行
mysql:5.6 要啓動的mysql版本
-e MYSQL_ROOT_PASSWORD=123456 mysql默認密碼
(4)連接myql
容器內連接:
(1)通過主機命令進入sampson-mysql容器:docker exec -it sampson-mysql bash
(2)連接mysql:root@1651d1cab219:/# mysql -uroot -p
5、網絡處理
用兩臺docker容器做datanode,當時配置Docker網絡時,使用了Bridge模式,docker0網段(172.0.1.x),宿主機網段(192.1.1.x),使用外部客戶端請求下載HDFS文件,去指定的datanode上拉去數據時,外部客戶端無法連接到內部的docker容器,拋出的等待超時異常,並重試下載,更換請求的下載地址爲可連接的宿主機datanode後, 才成功下載數據。
於是,想要對docker的網絡配置進行修改,將docker容器的IP地址設置成與宿主機同網段,並且相互連通。
這裏先要來說一下docker網絡的四種方式:
1.Host模式:
Host 模式並沒有爲容器創建一個隔離的網絡環境。
該模式下的Docker 容器會和Host宿主機共享同一個網絡namespace, Docker Container可以和宿主機一樣,使用宿主機的eth0,實現和外界的通信。
Host模式特點包括:
- 容器沒有隔離的 network namespace
- 容器的 IP 地址同 Docker host 的 IP 地址
- 注意:容器中服務端口號不能與Host宿主機上已經使用的端口號相沖突
- host 模式能夠和其它模式共存
2.Container模式
Container網絡模式是 Docker 中一種較爲特別的網絡的模式。處於這個模式下的 Docker 容器會共享其他容器的網絡環境,因此,至少這兩個容器之間不存在網絡隔離,而這兩個容器又與宿主機以及除此之外其他的容器存在網絡隔離。
3.None模式
None 網絡就是什麼都沒有的網絡。掛在這個網絡下的容器除了 lo,沒有其他任何網卡。需要我們自行去配置。
4.Bridge模式
Docker 容器默認使用Bridge模式的網絡。
Docker的Bridge模式和VM虛擬機的Bridge模式不同,雖然也叫Bridge,但實質上類似於VM的NAT模式。
原理是在宿主機上虛出一塊網卡bridge0,然後所有容器會橋接在這塊網卡的網段上。默認情況下容器能訪問外部網絡,但外部網絡無法訪問容器,需要通過暴露容器端口的方式(docker run -p)讓外部網絡訪問容器內的服務。
看完了上面的介紹,當前使用的Bridge模式不適合場景,修改網絡配置。
寫一下曾經試過的幾種方法:
注意:
如果你需要宿主機與Docker容器互通,前面兩種辦法不要試!!!不好使!!!
如果你僅需要Docker容器與宿主機網段相同,容器與其他同網段節點相互通信,不與宿主機進行通信,可以使用第一種方法!!
第一種辦法:
創建docker macvlan
Docker官方在1.12版本之後引入了macvlan網絡驅動,可以更簡單的爲容器配置橋接網絡
介紹一下macvlan:
macvlan的原理是在宿主機物理網卡上虛擬出多個子網卡,通過不同的MAC地址在數據鏈路層進行網絡數據轉發的,它是比較新的網絡虛擬化技術,需要較新的內核支持(Linux kernel v3.9–3.19 and 4.0+)
來源: http://www.louisvv.com/archives/695.html
docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=em1 mynet
參數說明:
-d macvlan 創建macvlan網絡,使用macvlan網絡驅動
–subnet 指定宿主機所在網段
–gateway 指定宿主機所在網段網關
-o parent 繼承指定網段的網卡
測試一下:運行容器
docker run --net=mynet --ip=192.168.1.100 --name=test -itd centos /bin/bash
使用宿主機去ping 192.168.1.100,這時,問題出現了
[root@node1 ~]# ping 192.168.1.100
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
From 192.168.1.100 icmp_seq=1 Destination Host Unreachable
From 192.168.1.100 icmp_seq=2 Destination Host Unreachable
From 192.168.1.100 icmp_seq=3 Destination Host Unreachable
目的地址不可達,使用別的機器去ping 192.168.1.100,ping通了,進入容器內,也ping不同宿主機。
使用macVLAN模式的容器,無法ping通宿主機,宿主機也無法ping通該容器,對其他同網段的服務器和容器都可以聯通。
第二種辦法:
在網上找到的另一種辦法,編輯網卡配置文件
# vi ifcfg-eno16777736
TYPE=Ethernet
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=eno16777736
UUID=2b04503d-4c0d-4f0f-8790-7b6203739892
DEVICE=eno16777736
ONBOOT=yes
BRIDGE=br0
# vi ifcfg-br0
DEVICE=br0
TYPE=Bridge
BOOTPROTO=static
ONBOOT=yes
DELAY=0
STP=yes
IPADDR=192.168.1.50
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS=114.114.114.114
重啓網絡的時候,整個網絡都down了,需要去機房弄服務器接顯示器修改,查找相關資料的時候,帖子大多是複製粘貼的,不知道該他們真正的試過了沒有,此方法並不靠譜。
第三種辦法:
使用pipework爲docker容器配置獨立IP
安裝pipework
wget https://github.com/jpetazzo/pipework/archive/master.zip
unzip master.zip
cp pipework-master/pipework /usr/local/bin/
chmod +x /usr/local/bin/pipework
創建兩個容器實例,並不需要默認docker0網橋分配的172.17.0.1網段,設置爲–net=none
docker run -itd –name test1 –net=none -h test1 centos /bin/bash
docker run -itd –name test1 –net=none -h test2 centos /bin/bash
接下來,使用pipework命令爲容器設置固定IP
[root@node1 ~]# pipework br0 test1 192.168.1.52/[email protected]
[root@node2 ~]# pipework br0 test2 192.168.1.53/[email protected]
pipework包含了200多行的shell腳本
通過network namespace,veth pair以及linux bridge完成容器網絡的設置,執行過程大概包括:
查看主機是否包含br0網橋,如果不存在就創建,向容器實例test1添加一塊網卡,並配置固定IP:192.168.1.53,若test1已經有默認的路由,則刪除掉,將@後面的192.168.1.1設置爲默認路由的網關,將test1容器實例連接到創建的br0上。
進入test1容器中,測試與test2容器和網關的連通性
[root@test1 ~]# ping 192.168.1.53
PING 192.168.1.53 (192.168.1.53) 56(84) bytes of data.
64 bytes from 192.168.1.53: icmp_seq=1 ttl=64 time=0.296 ms
64 bytes from 192.168.1.53: icmp_seq=2 ttl=64 time=0.131 ms
[root@test1 ~]# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.762 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.209 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.238 ms
說明上面的配置沒有問題
但是這時,還沒有完,宿主機是ping不同容器的
宿主機有兩個網卡,em1和em2,em1作爲管理口192.168.1.50,em2沒有使用,現在,我們只需要將宿主機的em2網卡添加到br0網橋即可
[root@node1 ~]# brctl addif br0 em2
[root@node1 ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.02d111808f50 no em2
veth1pl18006
veth1pl184096
veth1pl184872
docker0 8000.0242a42ada41 no
然後再進行相關的測試
使用宿主機去ping 52/53
[root@node1 ~]# ping 192.168.1.52
PING 192.168.1.52 (192.168.1.52) 56(84) bytes of data.
64 bytes from 192.168.1.52: icmp_seq=1 ttl=64 time=0.109 ms
64 bytes from 192.168.1.52: icmp_seq=2 ttl=64 time=0.114 ms
64 bytes from 192.168.1.52: icmp_seq=3 ttl=64 time=0.111 ms
[root@node1 ~]# ping 192.168.1.53
PING 192.168.1.53 (192.168.1.53) 56(84) bytes of data.
64 bytes from 192.168.1.53: icmp_seq=1 ttl=64 time=0.119 ms
64 bytes from 192.168.1.53: icmp_seq=2 ttl=64 time=0.128 ms
64 bytes from 192.168.1.53: icmp_seq=3 ttl=64 time=0.131 ms
進入容器去ping宿主機
[root@test1 ~]# ping 192.168.1.50
PING 192.168.1.50 (192.168.1.50) 56(84) bytes of data.
64 bytes from 192.168.1.50: icmp_seq=1 ttl=64 time=0.035 ms
64 bytes from 192.168.1.50: icmp_seq=2 ttl=64 time=0.049 ms
64 bytes from 192.168.1.50: icmp_seq=3 ttl=64 time=0.024 ms
[root@test2 ~]# ping 192.168.1.50
PING 192.168.1.50 (192.168.1.50) 56(84) bytes of data.
64 bytes from 192.168.1.50: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 192.168.1.50: icmp_seq=2 ttl=64 time=0.030 ms
64 bytes from 192.168.1.50: icmp_seq=3 ttl=64 time=0.033 ms
再使用window主機去測試
正在 Ping 192.168.1.52 具有 32 字節的數據:
來自 192.168.1.52 的回覆: 字節=32 時間=18ms TTL=64
來自 192.168.1.52 的回覆: 字節=32 時間=1ms TTL=64
來自 192.168.1.52 的回覆: 字節=32 時間=4ms TTL=64
192.168.1.52 的 Ping 統計信息:
數據包: 已發送 = 3,已接收 = 3,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
最短 = 1ms,最長 = 18ms,平均 = 7ms
正在 Ping 192.168.1.53 具有 32 字節的數據:
來自 192.168.1.53 的回覆: 字節=32 時間=20ms TTL=64
來自 192.168.1.53 的回覆: 字節=32 時間=7ms TTL=64
來自 192.168.1.53 的回覆: 字節=32 時間=11ms TTL=64
來自 192.168.1.53 的回覆: 字節=32 時間=2ms TTL=64
192.168.1.53 的 Ping 統計信息:
數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
最短 = 2ms,最長 = 20ms,平均 = 10ms
到這裏,問題總算解決了,在ambari上添加兩臺新配置的容器節點,並分配datanode角色,將原有的bridge網絡節點刪除即可,外部客戶端請求下載HDFS文件不再拋出異常
注意:pipework目前還有缺陷,容器重啓後IP設置會自動消失,需要重新設置。