docker web程序本地化_docker化java web应用
一.簡介
Docker是一個使用Go語言開發的開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的機器上。Docker的發展速度和火爆程度著實令人驚嘆,一發不可收拾,形成了席卷整個IT界的新浪潮。學完本課程你將了解到什么是docker,docker的思想以及諸如鏡像,倉庫,容器等核心概念。你將學會怎樣運行一個容器,如何搭建私有倉庫,怎么寫dockerfile以及怎樣把自己的應用放到容器中運行。
Docker為什么這么火?它確實解決了大部分企業的痛點,比如快速的持續集成、服務的彈性伸縮、部署簡單、解放運維,更重要的是為企業節省了機器資源。目前有非常多的公司在生產環境中大規模的使用Docker,京東618在2015年的618大促中,大膽啟用了基于Docker的容器技術來承載大促的關鍵業務,在2016年11月份,阿里超大規模Docker化之路,在2015年的3月份,騰訊萬臺規模的Docker應用實踐。Docker已成為IT從業人員的必備技能,不管你是從事開發、測試、運維,在今后的工作中,都會接觸到Docker。
二.什么是Docker
1.Docker歷史
2010 dotCloud PAAS
2013年docker開源
2014年6月,Docker1.0
2014年7月,C輪$4000萬
2015年4月,D輪$9500萬
至今Docker1.13
2.什么是Docker?
Docker是一個用來裝應用的容器,就像杯子可以裝水,筆筒可以放筆,書包可以放書一樣,你可以把Hello World放到Docker里,你可以把網站放到Docker里,你可以把任何你想得到的程序放到Docker里。
Docker is the world's leading software containerization platform,Docker是世界領先的軟件容器化平臺。
Docker公司開發的,開源,托管在github。
跨平臺,支持Windows、Macos、Linux。
三.理解Docker
1.Docker思想
a.集裝箱:把運行程序放到新的機器上去,Docker集裝箱保證我們程序不管放在哪都可以正常運行。
b.標準化:
運輸方式標準化(Docker運輸程序它有一個超級碼頭,任何一個地方需要貨物的時候,都由鯨魚送到超級碼頭,然后再由鯨魚把貨物送到目的地去。對應技術來說,假如你要把你的臺式機上的應用部署到你的筆記本上,用Docker就標準化了這個過程,只需在臺式機上執行一個命令,把鯨魚派過來,把程序送到超級碼頭去,再在你的筆記本上執行一個Docker命令,由鯨魚把程序從超級碼頭送到筆記本上去)
存儲方式標準化(把程序拷貝到筆記本上的時候,得給它指定一個目錄,還得記住這個命令,因為下次有改動一些東西的時候,可能還需要繼續往這傳,有了Docker之后就不用了,因為存儲方式標準化,不需要關心應用存儲在什么地方,要運行它或停止它的時候,只需執行一個命令就可以了)
API接口標準化(Docker提供了一系列的resful API接口,包含了對Docker應用的控制(啟動、停止、查看、刪除等),如當你要啟動你的程序的時候,你可能需要執行tomcat startup命令,停止的時候執行shutdown命令,如果不是tomcat命令,需要用別的命令來控制它。有了Docker接口標準化后,只需要執行同樣的命令就能控制所有的應用。
c.隔離
在用虛擬機時,有自已可用內存、CPU、硬盤,完全感覺不到外面主機的存在,Docker差不多,不過它的技術更加的輕量,可以實現快速的創建和銷毀。比如你創建一個虛擬機可能要等個幾分鐘,而創建Docker只需要1秒。最底層的技術實際上就是Linux的一種內核的限制機制,叫做LXC(LXC是一種輕量級的容器虛擬化技術,它最大效率的隔離了進程和資源,通過CGoup、NameSpace的限制,隔離進程組所使用的物理資源,比如CPU、Memory、IO等),其實這個機制早在7、8年前就加到了Linux內核了,直到2013年Docker出世時它才火起來。云計算、敏捷開發、高頻率的彈性伸縮需求、IT行業這些年的長足發展造就了Docker的火爆。
2.Docker解決了什么問題?
a.Docker解決了運行環境不一致帶來的問題。
如果一個應用要能運行起來,需要最底層的操作系統,操作系統上它依賴JDK、Tomcat、代碼、配置文件。
1).操作系統變了可能導致程序運行失敗,比如我的程序調用了系統的某些命令,換了個系統調不起來了。
2).JDK版本也可能導致程序運行失敗,比如Class文件是JDK1.7編譯的,機器上裝了一個1.6的JDK,就會出現Class版本識別不了。
3).Tomcat版本也可能導致失敗,比如舊版本的配置在新版本中不再支持了。
4).代碼更是有可能了,比如你的代碼依賴了磁盤D盤的一個文件,或者用了系統的環境編碼等等。
5).配置也是一樣,要不是你的配置是和系統相關的,換了個環境就跑不起來
Docker把操作系統、JDK、Tomcat、代碼、配置都一個個的給放到集裝箱里,再打包放到鯨魚上,由鯨魚給我們送到服務器上,在你的機器上怎么運行,在服務器上也將怎么運行,不會有任何的問題。
b.系統好卡,哪個哥們又寫死循環了?!
如果有和別人共用服務器呢,可能會有這樣的體會,莫名其妙的發現程序掛了,一查原因,要不是內存不夠,要不是硬盤滿了,或者突然發現某一個服務變慢了,甚至終端都比較卡,Linux本身是一個多租戶的操作系統,可以供多個人使用,怎么辦呢?用Docker,Dockder的隔離性就完全解決了這個問題。它是怎么解決的呢?如果把大家的程序都放到Docker里運行,就算別人的程序還是死循環,瘋狂吃CPU,或者是瘋狂的打日志把磁盤占滿,或者是占用大量的內存,內存泄露,都不會導致別人的程序運行錯誤,只會導致自已的程序錯誤,因為Docker在啟動的時候就給它限定好了最大使用的CPU、內存、硬盤,如果它超過了,就殺掉。
c.雙十一來了,服務器撐不住啦!
大家知道,業務系統的業務量不一定是平均的,特別是電商系統,每年總是有那么幾天,業務量會比平時多幾倍,甚至幾十倍,如果按平時的量去準備服務器,到雙十一肯定撐不住,但要是按雙十一的規模去準備服務器,平時就是極大的浪費,所以就只能在節日前臨時擴展機器,過完節再把多余的節點下線,這就給運維帶來非常大的工作量,一到這種節日就需要在各種機器上部署各種各樣的服務,大家知道,我啟動一個程序,我要裝操作系統、JDK、Tomcat等好多好多東西,還有可能啟不來,還要調試,這是一個非常繁重的工作。Docker讓這一切變得非常美好了,只需要點一下鼠標,就可以立馬從10臺服務器變成100臺,甚至1000、1000臺,都是分分鐘的事,因為Docker不管在哪臺機器上,不管要運行什么服務,都是用標準的方式把我們的程序運過來,再用標準的方式把它運行起來,這樣就可以做到,我只要在每臺機器上執行一兩條命令就可以讓程序跑起來,并且不用擔心會不會有問題。
Docker的標準化讓快速擴展、彈性伸縮變得簡單。
四.走進Docker
1.Docker里有三個核心詞匯:Build、Ship、Run
鏡像就是集裝箱,倉庫就是超級碼頭,容器就是運行程序的地方,用Docker運行一個程序的過程就是去倉庫把鏡像拉到本地,然后用一條命令把鏡像運行起來,變成容器。
Build:構建,就是構建鏡像。
Ship:運輸,運輸鏡像,從倉庫、主機上運輸。
Run:運行的鏡像,就是一個容器。
2.Docker鏡像
鏡像的英文名是image,前面我們講到了集裝箱,想像一下,鯨魚馱著的所有集裝箱都是一個鏡像,那么從本質上來說,鏡像到底是什么呢?
其實鏡像就是一系列的文件,它可以包括我們運行程序的文件,也可以包括我們應用運行環境的文件,既然都是文件,Docker把它保存到本地了嗎?答案是肯定的。但是它以什么格式保存的呢?說到鏡像的存儲格式,就要提到Linux的存儲技術,叫做聯合文件系統Union File System(UFS),它是一種分層的文件系統,它可以將不同的目錄掛到同一個虛擬文件系統下。
比如test1目錄下有三個文件夾,test2目錄下有一個文件README、兩個文件夾,聯合文件系統就是可以在同一個文件夾下看到這里的五個文件夾和一個文件README,也就是這兩個文件夾的集合。
通過這樣一種方式呢,聯合文件系統就可以實現文件的分層,比如test1可以看做第一層,test2可以看做第二層,每一層有每一層的文件,Docker就是利用了這種分層的概念來實現了鏡像存儲,下面就是鏡像的存儲格式圖。
很明顯地可以看到這張圖是分層的,下面有一層,上面也是一層一層的,一個個集裝箱挪在一起,這就是鏡像最直觀的存儲形式,這個例子它的最底層是操作系統的引導,上面是具體的Linux操作系統,再上面是相關的軟件(如果是我們的程序,那可能就是JDK、Tomcat),最上面一層先忽略不看,是下面講容器時要看到的一種。
Docker鏡像每一層文件系統都是只讀的,把每一層加載完成之后呢,這些文件都會被看作是同一個目錄,相當只有一個文件系統,Docker的這種文件系統被稱作為鏡像。
3.Docker容器
容器的本質就是一個進程,為了便于理解,可以想像成一個虛擬機,每個虛擬機都有自已的文件系統,可以把整個這一部分看作是容器的文件系統,相當于虛擬機里面所有的文件系統,它和虛擬機的區別是它這里的文件系統是一層一層的,并且這下面的N層都是只讀的,只有上面一層是可寫的。為什么要有可寫的這一層呢?想一想如果大家的程序運行起來,勢必會要寫一些日志,寫一些文件,或者對系統的某一些文件做一些修改,這是大部分程序都有的需求,所以容器在最上面一層創建了一個可讀可寫的文件系統。
如果程序在運行過程中要寫一個鏡像里面的一個文件,這種情況將發生什么呢?因為鏡像的每一層都是只讀的,所以它在寫這個文件之前會把這個文件這一層拷到文件的最上一層,然后再對它進行修改,修改了之后,當我們的應用讀一個文件的時候會從頂層開始查找,如果沒有才會找下一層,因為我們這個文件已被拷到最上一層了,所以會在最上一層找到它最新的內容。由于容器的最上一層是可以修改的,而鏡像是不可以修改的,這樣就可以保證同一個鏡像可以生成多個容器獨立運行,而它們之間沒有任何的干擾。
4.Docker倉庫
構建鏡像的目的就是為了在其它的機器或環境運行我的程序,那我就需要把我的鏡像傳到目的地去,我該如何完成傳輸過程?這就用到了Docker倉庫,我需要先把我的鏡像傳到Docker倉庫里去,目的地再從倉庫把我的鏡像拉過去,這就完成了這樣的一個傳輸過程。誰提供Dockder倉庫呢?肯定有一個中央服務器提供給我地址去訪問它,是誰提供了這樣的服務呢?Docker自已就提供了,提供服務的地址就是:hub.docker.com。但這這個網站在開始的時候在國內訪問不了,現在雖然可以訪問了,但是下載鏡像的速度非常的慢。為了解決這個問題,國內很多的公司做自已的倉庫,比較知名的倉庫有163yun.com/product/repo(網易蜂巢的一個鏡像中心),這里有一些我們常用的鏡像,這些倉庫都是其它公司給我們提供好的中心,我們可以把鏡像傳過去,如果我的鏡像比較私密,不想讓別人看到,只是內部的人使用的話,Docker也支持我們自已搭建一個鏡像中心,比如我們是一個內網的環境,可以把我們的鏡像中心在內網搭建起來,最后我們在鏡像的傳輸過程放到內網的Docker倉庫里就行了。
五.Docker安裝
1.Windows安裝
Docker對Win10做了原生的支持。
運行docker version,輸出Client和Server信息,則說明已安裝OK,如下所示:
2.MacOS安裝
3.Linux安裝
Redhat&CentOS的安裝詳見《》。
Docker是在Ubuntu上開發的,對Ubuntu支持是最好的,下面以Ubuntu為例演示安裝過程。
a.檢查內核版本,檢查其值是否大于3.10
切入到root用戶,將apt-get更新到最新版本。
b.apt-get install -y docker.io安裝Docker
這種安裝方式是用系統自帶的安裝包,可能不是Docker的最新版本,如要安裝Docker最新版本,可以使用curl -s https://get.docker.com|sh
這句話的意思就是把get.docker.com網頁的內容拿過來,執行sh,這是Docker提供的一種安裝方式。
c.service docker start啟動Docker
d.執行docker version查看docker是否安裝OK
六.Docker初體驗
1.第一個Docker鏡像
docker pull [OPTIONS] NAME[:TAG]:從Docker遠程倉庫拉取鏡像到本地。NAME是要拉取的鏡像的名稱,后面的TAG是可選的,如果不加默認是:laster,表示鏡像的最新版本,用TAG就會下載TAG指定的版本。OPTIONS是拉取的一些參數。
docker images [OPTIONS] [REPOSITORY[:TAG]]:查看本機有哪些鏡像,也可以驗證pull是否成功,其中,REPOSITORY表示鏡像的名稱。
實例:pull hello-world鏡像
在此設置使用docker國內鏡像DaoCloud,右鍵點擊桌面右下角的docker圖標,選擇Settings。
在Daemon標簽下的Registry mirrors列表中加入下面的鏡像地址:http://141e5461.m.daocloud.io,點擊 Apply,Docker服務將會自動重啟生效。
然后,再pull hello-world鏡像。
REPOSITORY:鏡像的名字
TAG:latest,最新版
IMAGE_ID:是一個64位的字符串,它可以唯一的標識我們的鏡像,這里只顯示16位,后面在顯示時自動被截掉了
CREATED:創建時間,說明這個hello-world在五周以前被修改過
SIZE:大小,只有1.84k
如果是Linux系統,則按如下操作設置國內鏡像:
1.修改或創建daemon.json文件:vi /etc/docker/daemon.json
將以下配置寫入到文件中,保存并退出:
{"registry-mirrors": ["https://registry.docker-cn.com"]
}
2.重啟docker:systemctl restart docker.service
2.第一個Docker容器
docker run [OPTIONS] IMAGE[:TAG][COMMAND][ARG...]:IMAGE表示鏡像的名字,COMMAND表示這個鏡像在運行起來的時候要執行什么命令,ARG表示這條命令所依賴的參數。
表明運行成功。
最左邊Client是我們在本機的Docker?Client,就是我們執行命令的時候Docker?Client的部分,中間這部分DOCKER_HOST也是在我們本機的Docker服務(Docker?Daemon),最右邊是Docker的遠程倉庫。
Docker?Client輸入docker pull,將會向Docker Daemon發起pull命令,告訴Docker Daemon要拉取某一個鏡像,Docker Daemon會先在本機Images去檢查鏡像是否存在,如果存在且版本就是你所要拉取的版本,就不會做任何的操作,如果不存在將會去Docker倉庫找我們需要拉取的鏡像名字,如果找到了就會從Docker倉庫傳到我們本地,把我們要的鏡像拉到本地來。
Docker?Client輸入docker run,第一步也是把我們的命令發到本地的Docker Daemon,Docker Daemon會檢查這個鏡像是否在本機已經存在,如果不存在,將會執行一個相當于Docker pull的過程去遠端Docker倉庫把鏡像下載回來,然后通過一定的方式把這個鏡像運行起來,變成Docker容器。
七.Docker運行Nginx
1.運行nginx鏡像
Nginx是一個Web服務器,是一個持久運行的容器,上面我們的hello-world是前臺運行的(因為我們能看到它打印出的運行結果),運行Nginx可以選擇前臺運行,也可以選擇后臺運行,如果一個前臺運行的鏡像,可以用Ctrl+C結束進程,進程結束了,鏡像也就結束了,所以說Nginx最好的運行方式是后臺運行。成功運行Nginx后,可以進入容器內部看看Nginx容器到底是什么樣的。
docker run -d library/nginx命令的返回字符串代表容器的ID,docker ps看到的CONTAINER ID是一樣的。
-d表示后臺運行,如果想了解更到docker run參數,可以運行docker run --help查看。
docker exec --help可以看到命令的詳細解釋,這就是在一個運行的容器中運行一個命令。
docker exec -it 30d bash
2.docker網絡
a.網絡類型
bridge模式
docker的隔離性,網絡也是隔離性的一部分,Linux用了namespace來進行資源的隔離,比如PIDNameSpace就是用來隔離進程的,Mount NameSpace用來隔離文件系統的,Network?NameSpace是用來隔離網絡的,每一個Network?NameSpace都提供了一份獨立的網絡環境,包括網卡、路由、iptable規則等等,都是與其它的Network?NameSpace隔離的,Docker容器在默認情況下都是分配一個獨立的Network?NameSpace,也就是網絡類型中的bridge模式。
Host模式
如果啟動容器的時候,指定使用Host模式,那么這個容器將不會獲得一個獨立的Network?NameSpace,而是和主機共同使用一個,這個時候,容器將不會虛擬出自已的網卡,配置自已的IP等等,而是會使用宿主機上的IP和端口,也就是在Docker里使用網絡的時候和在主機上使用網絡是一樣的。
None模式
Docker將不會和外界的任何東西進行通信。
b.端口映射
在使用bridge模式的時候,就涉及到了一個問題,既然它使用了網絡有獨立的NameSpace,這就需要一種技術使容器內的端口可以在主機上訪問到,這種技術就是端口映射。Docker可以指定你想把容器內的某一個端口可以在容器所在主機上的某一個端口做一個映射,當你在訪問主機上的這個端口的時候,其實就是訪問容器里面的那個端口。
docker run --help可以看到,-p會開放一個容器的端口到主機上,默認是空的,-P是開放所有的端口到一個隨機的端口。
如上先把原來的nginx容器停掉,再指定映射端口啟動,并檢查8080端口確實已被占用,這時通過瀏覽器輸入localhost:8080即可正常訪問到nginx,如下所示:
我們再用-P方式來運行一下。
用docker ps可以看到端口映射的情況,在我本機上開了一個32768的隨機端口映射到容器里的80端口,用netstat -ano|findstr "32768"檢查一下實際端口也是啟動了。
此時用localhost:8080就不可以訪問了,用localhost:32768可以正常訪問。
八.Docker化Java web應用
1.制作自已的鏡像
Dockerfile:告訴Docker,我要怎么樣來制作我的鏡像,我要制作鏡像每一步操作是什么。
docker build:用來執行Dockerfile里面所描述的每一件事情,最終會把Docker鏡像構建出來。
2.將下載下來的SpringMVC配置到Eclipse中,將其Export成war包
將生成的SpringMVC.war包拷貝到E:\develop目錄下
3.下載基礎library/tomcat鏡像
docker pull library/tomcat
4.以上面tomcat基礎鏡像為起點,制作鏡像
編寫Dockerfile
from library/tomcat
MAINTAINER bijian xxx@126.com
COPY SpringMVC.war/usr/local/tomcat/webapps
構建鏡像,命令:docker build E:\develop
如果不知道命令參數時,可以用docker build --help命令查看參數。
5.運行自已的鏡像
命令:docker run -d -p 8888:8080 springmvc
此時,在瀏覽器上輸入http://localhost:8888/,能正常打開tomcat主頁,表明Tomcat啟動成功。
輸入http://localhost:8888/SpringMVC/greet,頁面輸出內容如下:
運行正常,在這里我們的SpringMVC項目不依賴數據庫,假如我們的項目還依賴mysql,那么可以通過pull library/mysql下載library/mysql鏡像。
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=000000 -e MYSQL_DATABASE=springmvc library/mysql命令運行mysql鏡像,docker restart?7532592dac95重啟tomcat應用springmvc。
九.小結
1.集裝箱,標準化,隔離
2.鏡像、容器、倉庫(BUID、SHIP、RUN)
構建鏡像,運行容器,鏡像通過倉庫來傳輸,Docker集裝箱的思想就體現在鏡像上,我們的鏡像是分層的,一層一層的,每一層的東西都是固定的,一個鏡像打好后,就好像一個大大的集裝箱,它里面的東西是固定的文件,不會發生變化。
Docker標準化思想在我們使用各種Docker命令時應該也會體會到,不管是在啟動一個鏡像的方式,還是在下載和運行一個鏡像的時候,都會發現我們所做的操作是基本差不多的。
Docker的隔離思想,網絡隔離、進程隔離、磁盤隔離,容器運行起來,就有自已的進程空間、磁盤、網絡。
3.docker命令pull,build,run,stop,restart,exec...
docker pull:下拉鏡像
docker build:構建鏡像
docker run:運行一個容器
docker stop:停止容器
docker restart:重啟一個容器
docker exec:進行容器的內部
總結
以上是生活随笔為你收集整理的docker web程序本地化_docker化java web应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 智改数转水循环在线监测系统,提升企业生产
- 下一篇: 树 ---树