經(jīng)過上兩篇實戰(zhàn)Windows Server Docker系列文章,大家對安裝Windows Docker服務以及如何打包現(xiàn)有IIS應用為docker鏡像已經(jīng)有了基本認識。接下來我們來簡單講講一些最基本的運維問題。鑒于到目前為止我們只談到單服務器部署。這里暫時不涉及集群模式下的復雜生產(chǎn)環(huán)境運維。

本主題將涵蓋下面這些主要內(nèi)容,由于這個主題包含的內(nèi)容較多,將分成上下兩篇發(fā)布:

上篇

  • 遠程操作Windows Docker服務器

  • 自動化Docker編譯和部署

  • Windows Docker網(wǎng)絡配置和端口映射

下篇

  • 負載均衡和反向代理

  • 日志解析和監(jiān)控

遠程操作Windows Docker服務器

和Linux下的Docker服務默認通過TCP 2375/2376端口執(zhí)行docker命令不同,Windows Docker服務默認只支持本機基于命名管道來執(zhí)行docker命令。如果安裝完Windows Docker服務后,在命令窗口執(zhí)行netstat -an,可以看到,服務器并不監(jiān)聽2375或者2376這樣的端口。當然,我們可以通過修改daemon.json這個配置文件(關于如何修改daemon.json文件,請參考本系列的第一篇),來開啟2375/2376端口。2375端口和linux下的2375端口一樣,用于非TLS的遠程連接;而2376則支持基于證書的安全連接。對于,開發(fā)測試環(huán)境,一般開啟2375端口就行,而對于生產(chǎn)環(huán)境,則應該使用2376端口,基于TLS安全連接來遠程管理Docker服務器。

要開啟2375端口,只需要如下在daemon.json添加hosts配置項,然后重啟Docker服務:

{
    "hosts": ["tcp://0.0.0.0:2375"]
}

要開啟2376端口也類似,就是稍微復雜一點,需要生成和配置證書,具體的可以參考微軟的這篇官方文檔這里就不詳述了。

開啟2375端口之后,可以通過在命令窗口執(zhí)行如下的netstat命令,確保2375端口已經(jīng)正確監(jiān)聽:

netstat -an | findstr 2375

如果返回類似下面,就說明已經(jīng)在監(jiān)聽了:

  TCP    0.0.0.0:2375           0.0.0.0:0              LISTENING
  TCP    [::]:2375              [::]:0                 LISTENING

只是開始監(jiān)聽還不夠,要允許外部機器能夠遠程訪問本機的2375端口,我們還要添加防火墻的Inbound規(guī)則,可以通過下面的powershell命令開啟:

New-NetFirewallRule -DisplayName 'Docker TCP Inbound' -Profile @('Domain', 'Public', 'Private') -Direction Inbound -Action Allow -Protocol TCP -LocalPort 2375

接下來,我們就可以嘗試從安裝了Docker client的遠程機器,訪問這臺Windows Docker服務器了。Docker client有各種跨平臺版本,所以只要是相兼容的版本,我既可以從Windows的docker client,也可以從linux的docker client通過2375端口遠程訪問docker服務器。

當我們從當前機器,比如你的開發(fā)機訪問一臺遠程docker服務器時,我們需要為docker client指定目標HOST。一般有兩種方式:一種是可以通過在每個docker命令執(zhí)行時,添加-H server_name_or_ip參數(shù),另一種是設置DOCKER_HOST環(huán)境變量,這樣,就不需要每個docker命令都帶-H參數(shù)了。例如,下面的命令會列出遠程服務器1.2.3.4的所有docker images:

docker -H 1.2.3.4 images
docker -H tcp://1.2.3.4 imagesdocker -H tcp://1.2.3.4:2375 images

上面的幾種指定host的語法都是可以的,如果使用默認的2375端口,最簡單的就可以用第一種,少打不少字符。如果要指定DOCKER_HOST環(huán)境變量,那么必須使用完整的格式,比如:

SET DOCKER_HOST=tcp://1.2.3.4:2375

開啟遠程訪問之后,當需要從開發(fā)或者編譯環(huán)境編譯和發(fā)布docker鏡像時,我們就不需要像上一篇中那么蛋疼的先copy發(fā)布出來的應用網(wǎng)站文件到docker服務器,然后在服務器上執(zhí)行docker build了,只需要直接從開發(fā)環(huán)境執(zhí)行docker build,就能直接在遠程docker服務器上生成和運行docker鏡像了。

自動化Docker編譯和部署

docker的命令行工具,有許多子命令和參數(shù)。如果要經(jīng)常編譯和運行docker鏡像,我們當然不希望每次都手打所有參數(shù),例如,下面的命令編譯一個docker鏡像,并運行一個docker容器,每次手打一邊實在沒啥樂趣:

docker build -t iis-demo:1.0 .
docker run --ip 172.24.128.2 -p 80 -v "c:/temp:c:/inetpub/logs/LogFiles" -e "env1=LIVE1" -e "env2=LIVE2" -e "HOSTS=1.2.3.4:TEST.COM" iis-demo:1.0

為了簡化這個過程,通常我們會寫一些帶參數(shù)的powershell腳本;或者,我們可以使用另一個docker的必備命令行工具:docker-compose

docker-compose是一個docker官方發(fā)布的docker容器編排工具,用于通過yml格式的配置文件來簡化docker命令的執(zhí)行。例如,上面這兩個編譯并運行docker容器的腳本,如果我們定義如下這個docker-compose.yml配置文件:

version: "2.1"services:
  iis-demo:    build: .    image: "iis-demo:1.0"    ports:
    - "80"    networks:      nat:        ipv4_address: 172.24.128.2    volumes:
    - "c:/temp:c:/inetpub/logs/LogFiles"    environment:
    - "env1=LIVE1"
    - "env2=LIVE2"
    - "HOSTS=1.2.3.4:TEST.COM"networks:  nat:    external: true

那么,我們就可以在docker-compose.yml所在的目錄,通過下面這一條命令,就能自動編譯docker鏡像,并且運行一個docker容器了:

docker-compose up

是不是超級簡單?事實上,docker-compose幾乎包裝了所有通過docker命令行可以執(zhí)行的參數(shù),而且,一個docker-compose.yml文件,可以包含多個相關的docker鏡像的配置,比如,你的這個應用可能依賴于某一個DB,或者另一個應用的,那么,寫在一個yml文件里,就能很方便的一鍵編譯,一鍵發(fā)布,一鍵關閉這些相關容器。限于篇幅,本文就不細說docker-compose各種功能了,大家可以參看官方文檔和示例自行摸索。

這里簡單講一下,在windows下,如何安裝docker-compose。

  • 首先,docker-compose是一個客戶端工具,也就是,它應該安裝于安裝了docker client的機器,并不需要安裝于docker服務器;

  • 對Windows版本的docker-compose來說,它就是一個單個文件的.exe文件,你只需要從官網(wǎng)下載Windows版本的.exe文件,將文件名改成docker-compose.exe,然后隨便放到任何方便訪問的目錄就可以了。我比較懶,一般直接丟到c:\windows\system32目錄,那樣就不需要設置額外的PATH路徑,就能在任何當前目錄下,在命令窗口直接執(zhí)行了。

有了,docker-compose,我們也可以很簡單的設置我們的docker服務器每次機器啟動之后,自動運行指定的docker容器,只需要配置一個機器的啟動腳本,每次機器啟動后自動運行docker-compose up,就可以了。

有人可能想問,如何為windows設置自動啟動腳本?一個簡單的方法是,使用NSSM這個小工具。例如,下載nssm的exe到本地后,只需要在命令行執(zhí)行:

nssm install "Docker Startup" command param1 param2 ...

就能將指定的命令變成自動開機執(zhí)行的windows service了。是不是很方便?網(wǎng)上介紹NSSM也文章也很多的,大家可以搜索一些,這里我就給幾個link,不過多介紹了:

Windows Docker網(wǎng)絡配置和端口映射

微軟官方,主要就這一篇文檔介紹了windows容器的網(wǎng)絡設置。介紹得其實并不是很深入。主要來說,它介紹了Windows Docker支持的幾種網(wǎng)絡模式,例如:nat、transparent、overlay、l2bridge。其中,最常用的,大家最容易理解的,也是Windows Docker服務安裝后的默認模式是nat模式。簡單的說,就是:

  • 宿主機上運行的所有的容器,都屬于一個子網(wǎng)段,每個容器運行時,可以靜態(tài)指定網(wǎng)段內(nèi)可用的ip,或者自動分配一個網(wǎng)段內(nèi)的ip;

  • 子網(wǎng)段內(nèi)的ip,在宿主機外部無法直接訪問,只能從宿主機上直接訪問;

  • 可以通過docker命令的-p參數(shù),設置靜態(tài)或者動態(tài)的宿主機ip到容器ip的端口映射,這樣宿主機的外部網(wǎng)絡,就可以通過宿主機的ip和端口,間接訪問到容器內(nèi)的網(wǎng)站了;

例如,在上面的示例中的docker run --ip 172.24.128.2 -p 80 ...里,-p 80這個參數(shù)就會導致docker命令執(zhí)行時,動態(tài)分配一個宿主機上的端口,映射到容器ip的80端口上。如果我們執(zhí)行上面的docker run命令,或者docker-compose up命令后,在命令窗口執(zhí)行docker ps,可以看到下面的正在運行的容器:

0f0e07424d80        iis-demo:latest     "C:\\SetHostsAndSta..."   5 minutes ago       Up 4 minutes        0.0.0.0:39924->80/tcp        windowsdockeriisdemo_iis-demo_1

其中,0.0.0.0:39924就是指的,對宿主機上任意ip的39924端口的訪問,已經(jīng)被映射到這個容器的子網(wǎng)ip的80端口了。

但是,這里有個坑,很深的坑,讓我一度差點懷疑人生,甚至重裝了機器的坑!??!——如果你在宿主機上的瀏覽器里,訪問比如http://localhost:39924/iis-demo,按這個端口映射,你天真的以為就能訪問到容器內(nèi)的網(wǎng)站,尤其示玩過linux下容器的小伙伴,更絕對會認為它能訪問。但是,它其實不能!!什么原因呢?我為此一度差點崩潰,最后,在某個windows docker的github issuer中,有開發(fā)人員解釋說,這個是因為windows版本的實現(xiàn)問題,在宿主機本機,這個映射的端口無法訪問,但是,在宿主機外部,訪問宿主機上的ip加這個端口是可以訪問的??!只允許從外部訪問!!WTF?這是什么鬼的道理?不過,反正,現(xiàn)狀就是如此,也只能忍了。

除了使用動態(tài)分配的端口,如果我們把參數(shù)改成例如-p 80:80,那么就能通過宿主機的ip:80端口,訪問到容器內(nèi)的網(wǎng)站了。再提醒一遍,記住,只能從宿主機外部訪問?。?/p>

微軟的官方文檔,除了介紹了幾種常見的網(wǎng)絡模式如何配置,還提到了一些Windows版本的Docker相對于linux版本的docker沒有實現(xiàn)的功能,下面的這些docker命令的參數(shù),對Windows Docker無效:

  • --add-host

  • --dns-opt

  • --dns-search

  • --aux-address

  • --internal

  • --ip-range

其中,最遺憾的就是--add-host參數(shù)沒有實現(xiàn)。--add-host參數(shù)原本是用于為容器內(nèi)的系統(tǒng)的hosts文件添加靜態(tài)dns解析的,這是一個非常常用的功能,沒有它,部署到容器內(nèi)的應用可能無法解析某些服務器名稱或者域名。當然,我們可以自己實現(xiàn)類似功能,例如,在上一篇 docker化現(xiàn)有iis應用中,我們就實現(xiàn)了一個通過環(huán)境變量,傳入,并設置hosts的簡單功能,從而避免了這個參數(shù)沒實現(xiàn)帶來的痛點。

http://www.cnblogs.com/teddyma/p/Windows-Server-Docker-3.html