docker入門(利用docker部署web應用)docker服務啟動,重啟,關閉命令
前言:本課程是在慕課網上學習 第一個docker化的java應用 課程時所做的筆記,供本人複習之用
目錄
第一章 什麼是docker
1.1 docker的發展史
2010年幾個年輕人成立了一個做PAAS平臺的公司dotCloud.起初公司發展的不錯,不但拿到過一些融資,還獲得了美國著名孵化器YCombinator的支援,後來微軟谷歌亞馬遜這樣的大廠商也紛紛加入PAAS平臺,競爭十分激烈,dotCloud舉步維艱.
2013年可能是公司發展的不是很好,工程師又不想自己的努力付之東流,於是他們決定將他們的核心技術開源.這項技術就是docker.當時docker的功能就是將linux容器中的應用程式碼打包,可以輕鬆的在伺服器之間進行遷移.
無心插柳柳成蔭,docker技術風靡全球,於是dotCloud公司改名為dockerInc,並全面投入到docker的開發之中.
2014.6 Docker釋出了第一個版本 Docker1.0
2014.7 獲得C輪融資 $4000W
2015.4 獲得D輪融資 $9500W
至今已經發布到docker
1.2 docker國內應用史
由此看出,不管開發測試還是運維,絕大多數人都應該會接觸到docker.所以學docker還是很有必要的.
1.3 什麼是Docker
docker是一個用來裝應用的容器,就像杯子可以裝水,筆筒可以放筆,書包可以放書,可以把hello word放在docker中,可以把網站放入docker中,可以把任何想得到的程式放在docker中.
官方解釋:
第二章 瞭解docker
2.1 docker思想
2.1.1 集裝箱
沒有集裝箱之前運輸貨物,東西零散容易丟失,有了集裝箱之後貨物不容易丟失,我們可以把貨物想象成程式,目前我們要把程式部署到一臺新的機器上,可能會啟動不起來,比如少一些配置檔案什麼的或者少了什麼資料,有了docker的集裝箱可以保證我們的程式不管執行在哪不會缺東西.
2.1.2 標準化
1. 運輸方式
docker運輸東西有一個超級碼頭,任何地方需要貨物都由鯨魚先送到超級碼頭,然後再由鯨魚從超級碼頭把貨物送到目的地去.對應的技術來說,比如我們要把桌上型電腦的應用部署到筆記本上,我們可能選擇用QQ發過去或者用U盤拷過去,docker就標準化了這個過程,我們只需在臺式機上執行一個docker命令,把鯨魚派過來,把程式送到超級碼頭去,再在筆記本上執行一個docker命令,然後由鯨魚把程式從超級碼頭送到筆記本上去.
2. 儲存方式
當我們把程式儲存到筆記本上時,我們需要一個目錄,且我們要記住這個目錄,因為下次我們可能還要修改,有了docker之後我們就不用記住了程式在哪裡了,我們使用的時候只需要一條命令就行了.
3. API介面
docker提供了一系列rest api的介面,包含了對docker也就是對我們的應用的一個啟動停止檢視刪除等等,如當我們要啟動tomcat時我們要執行startup命令,當我們要停止時要執行shutdown命令,如果不是tomcat,我們可能還需要一些別的命令.有了docker我們記docker的命令就可以對其進行操作.
2.1.3 隔離
我們在使用虛擬機器時有自己的cpu,硬碟,記憶體,完全感覺不到外面主機的存在,docker也差不多,不過它更輕量,我們建立虛擬機器可能要幾分鐘,但是docker只需要一秒.最底層的技術時linux一種核心的限制機制,叫做LXC,LXC是一種輕量級的容器虛擬化技術.最大效率的隔離了程序和資源.通過cgroup,namespace等限制,隔離程序組所使用的物理資源,比如CPU,MEMORY等等,這個機制在7,8年前已經加入到linux核心了,直到2013年docker出世的時候才火起來,大家可能奇怪為什麼這麼好的技術埋沒這麼多年都沒人發現呢?英雄造時勢,時勢造英雄,如果沒有云計算,敏捷開發,高頻度的彈性伸縮需求,沒有IT行業這麼多年長足的發展,也就沒有docker.
2.2 docker解決的問題
2.2.1 系統環境不一致
開發:我本地沒問題.運維:伺服器沒問題. 這個問題就變成了皮球.
如果一個應用要正常的啟動起來需要什麼?比如java web應用.
需要一個作業系統,作業系統之上要jdk,tomcat,我們的程式碼,配置檔案.
作業系統的改變可能會導致我們的應用開不起來,比如我們呼叫了某些系統命令.
jdk版本也可能導致程式的執行失敗.比如class檔案需要1.7編譯,我們裝了個1.6的jdk.
tomcat版本也能導致失敗,比如舊的版本一些配置在新版本中不再支援.
程式碼的話就比如應用了C盤,D盤的一個檔案,或者是用了系統的一些環境編碼.
配置的話我們可能少了某個配置檔案等等.
下面docker來了,它把作業系統,jdk,tomcat,程式碼,配置全部放到集裝箱裡.再打包放到鯨魚上,由鯨魚給我們送到伺服器上,在我的機器上怎麼執行,在別的機器上也怎麼執行.不會有任何的問題.一句話就是docker解決了執行環境不一致所帶來的問題.
2.2.2 系統好卡,哪個哥們又寫死迴圈了
如果有根別人共用伺服器的同學可能有這樣的體會,莫名其妙發現自己的程式掛了,一查原因要不是記憶體不夠了,要不是硬碟滿了,還有就是發現某個服務變慢了,甚至敲終端都比較卡,但是linux本身就是一個多使用者的作業系統本身就可以供多個使用者使用,docker的隔離性可以解決這個問題,就算別人的程式還是死迴圈瘋狂吃CPU,還是封裝瘋狂打日誌把硬碟佔滿,還是記憶體洩漏,把記憶體佔滿,都不會導致我們的程式執行錯誤.因為docker在啟動的時候就限定好了,它最大使用的CPU硬碟,如果超過了,就會殺掉對應程序.
2.2.3 雙11來了,伺服器撐不住了
大部分系統業務量並不是每天都比較平均的,特別是一些電商系統,每天總有那麼幾天業務量是平時的幾倍甚至幾十倍,如果按雙11的規模去準備伺服器那麼對於平時的規模來說又是極大的浪費,所以就在節日前臨時擴充套件機器,過完節再把多餘的節點下線,這就給運維帶來了非常大的工作量,一到過節就在各個機器上部署各種各樣的服務,我們啟動程式需要java,tocmat等等,並且還可能起不來還要除錯,這是非常噁心的工作,有了docker一切都變得美好了,只要點一下伺服器就可以從10臺變成100臺甚至1000,1W臺.都是分分鐘的事情.
為什麼會這麼快呢?都是用標準的方式把我們的程式運過來,下載過來,再用標準的方式把它執行起來,就可以做到只要在每臺機器上都執行一兩條命令,就可以讓程式正常跑起來,並且不用擔心有問題.
第三章 走進docker
映象就是上面說的集裝箱,倉庫就是超級碼頭,容器就是我們執行程式的地方.docker執行程式的過程就是去倉庫把映象拉到本地,然後用一條命令把映象執行起來變成容器.
build:構建,就是構建映象.
ship:運輸,運輸映象,從倉庫和主機運輸.
run:執行的映象就是一個容器.
build,ship,run和映象,倉庫,容器是一一對應的.
3.1 映象
映象的英文名交image.前面我們講到了集裝箱,鯨魚拖著的所有集裝箱就是一個映象.
從本質上來說映象就是一系列檔案,可以包括我們應用程式的檔案,也可以包括我們應用的執行環境的檔案,既然是檔案,那麼是以什麼樣的格式在本地儲存的呢?
說到儲存格式,就要提到linux的一個儲存技術,叫做聯合檔案系統,是一種分層的檔案系統,可以將不同的目錄掛到同一個虛擬檔案系統下.
比如test1下有三個資料夾,test2下有兩個資料夾,還有一個readme檔案.聯合檔案系統就是可以在一個資料夾(test)中看到多個資料夾(test1,test2)中的內容.
通過這種方式可以實現檔案的分層,test1可以把它看作第一層,test2可以把它看作第二層,每一層有每一層自己的檔案,docker就是利用了這種分層的概念實現了映象儲存.
下圖就是映象的儲存格式,這張圖是分層的,最下面一層,上面也是一層層的好像集裝箱羅列在一起.這就是映象最直觀的儲存方式.下面是作業系統的引導,上面是linux作業系統,再上面是一些相關的軟體,如果是我們自己的程式,就可以是tomcat,jdk,再往上是應用程式碼,每一層是我們自己都可以控制得,最上面一層先忽略不看,因為這是和容器有關的.注意一點,docker映象系統的每一層都是隻讀的,然後把每一層載入完成之後這些檔案都會被看成是同一個目錄,相當於只有一個檔案系統.docker的這種檔案系統被稱之為映象.
圖13.2 容器
為了便於理解,大家可以把容器想象成虛擬機器,每個虛擬機器都有自己的檔案系統,可以把圖1整個一部分看成是檔案系統,與虛擬機器系統的區別是這裡面的檔案系統是一層一層的,並且最下面的n層都是隻讀的,只有上面一層是可寫的.為什麼要有可寫的這層呢?大家的程式執行起來,勢必會要寫一些日誌,寫一些檔案,或者對系統的某一些檔案做一些修改,所以容器在最上面一層建立了可讀可寫的檔案系統.
在程式的執行過程中,如果要寫映象檔案時,因為映象的每一層都是隻讀的,它會把檔案的每一層拷到檔案的最上層,然後再對它進行修改,修改之後,當我們的應用讀一個檔案時會從頂層進行查詢,如果沒有才會找下一層.
由於容器的最上一層是可以修改的,映象是不能修改的,這樣就能保證映象可以生成多個容器獨立執行,沒有任何干擾.
3.3 倉庫
我們的映象是要在其它機器上執行,如何進行傳輸呢?
這就用到了docker倉庫,我們要先把我們的映象傳到docker倉庫中,再由目的地把docker倉庫拉過去,這就完成了這樣的一次傳輸過程.
誰提供了這樣的倉庫呢?docker自己提供了,hub.docker.com,但是非常慢,為了解決這個問題,國內很多公司也在做自己的倉庫.比較知名的是由網易蜂巢提供的https://c.163yun.com/hub#/m/home/
第四章 centos下docker安裝
因為我這裡使用的是centos所以就在centos下安裝.
參考部落格與網站:
https://www.jb51.net/article/161580.htm
https://blog.csdn.net/jsnhux/article/details/89847109
https://docs.docker.com/install/linux/docker-ce/centos/
1.Docker 要求 CentOS 系統的核心版本高於 3.10,檢視本頁面的前提條件來驗證你的CentOS 版本是否支援 Docker 。
通過uname -r命令檢視你當前的核心版本
2. 如果安裝過請先解除安裝
- yum remove docker \
- docker-client \
- docker-client-latest \
- docker-common \
- docker-latest \
- docker-latest-logrotate \
- docker-logrotate \
- docker-engine
3.安裝依賴設定yum倉庫
安裝依賴:
- yum install -y yum-utils \
- device-mapper-persistent-data \
- lvm2
設定倉庫:
- yum-config-manager \
- --add-repo \
- https://download.docker.com/linux/centos/docker-ce.repo
4. 安裝docker
yum install docker-ce docker-ce-cli containerd.io
5.啟動並加入開機啟動
systemctl start docker
systemctl enable docker
6.驗證是否安裝成功
docker version
docker run hello-world
顯示如下即安裝成功!
- Unable to find image 'hello-world:latest' locally
- latest: Pulling from library/hello-world
- 1b930d010525: Pull complete
- Digest: sha256:0e11c388b664df8a27a901dce21eb89f11d8292f7fca1b3e3c4321bf7897bffe
- Status: Downloaded newer image for hello-world:latest
- Hello from Docker!
- This message shows that your installation appears to be working correctly.
- To generate this message, Docker took the following steps:
- (amd64)
- executable that produces the output you are currently reading.
- to your terminal.
- To try something more ambitious, you can run an Ubuntu container with:
- Share images, automate workflows, and more with a free Docker ID:
- https://hub.docker.com/
- For more examples and ideas, visit:
- https://docs.docker.com/get-started/
第五章 docker初體驗
5.1 docker基本命令
1.docker pull [options] NAME[:TAG]
通過此命令可以docker遠端倉庫拉取映象到本地.
name是拉取映象的名稱,:TAG表示是可選的,如果不選表明時latest,如果選擇表明是指定版本的.
options是拉去的一些引數.
當不加請求地址的時候回去docker的官網拉取映象.
2.docker images [options] [REPOSITORY[:TAG]]
options是選項,後面是指定映象的名稱.這個用的不多,可能當本地映象非常多的時候要指定檢視某一個映象.
IMAGE ID 其實是一個64位的字串,它可以唯一標識我們的映象,這裡只顯示了16位,後面的被截掉了.
3. docker run [options] IMAGE[:TAG] [COMMAND] [ARG..]
IMAGE是映象的名字
COMMAND是執行起來的時候要執行什麼命令.
ARG表示這條命令執行需要的引數.
5.2 docker執行映象流程
docker pull:首先docker pull向docker daemon傳送了一條命令pull,告訴docker daemon要拉取某一個映象,docker daemon會在本機檢查映象是否存在,如果存在且版本就是我們想要拉取的版本,它就不會做任何的操作.如果不存在下一步它會到docker的倉庫中找我們要拉取的映象名字,如果找到了就會有docker倉庫傳送到我們的本地,把我們要的映象傳送到我們的本地來.
docker run:首先把命令傳送到我們的docker daemon,docker daemon會先檢查映象在本機是否存在,如果不存在相當於執行了一個docker pull的過程,下載回來之後會以一定方式把映象執行起來變成docker容器.
第六章 docker執行nginx
6.1 執行nginx映象
我們開啟網易蜂巢映象中心https://c.163yun.com/hub#/m/home/
搜尋nginx,可以看到有兩個nginx,他們的名字和頭上和圖示都不一樣,一個是鯨魚,一個是兩個球.
帶有鯨魚的映象表示這個映象是從官網的映象中心複製過來的.這個映象與docker的映象是一摸一樣的.我們使用此映象.
點進去,會有下載地址,複製裡面的地址,然後拉取映象.
複製到系統中執行.
執行完後可以檢視映象狀態
在前臺執行容器命令如下,輸入後容器就會執行,按ctrl+c可以終止容器的執行.
docker run hub.c.163.com/library/nginx
在後臺執行容器:
docker run -d hub.c.163.com/library/nginx
檢視執行的容器:
docker ps
更多關於執行的命令:
docker run --help
因為我們在平時執行的時候需要除錯容器內部的設定、檢視一下日誌等等.我們可以通過如下命令進入容器內部:
命令的大體內容:
命令具體內容:
docker exec -it 02963d2002b bash
-i保證我們的輸入有效,即使在沒有detach的情況下也能執行.
-t表示將分配給我們一個偽終端.我們將在偽終端輸入我們的內容.
後面跟著的是容器的id,即我們上面用ps查詢出來的id,這個id可以少寫幾位,它會自動識別.
可輸入如下命令瞭解更多:
docker exec --help
輸入命令後發現我們前面的標識也變了,相當於進入了一個新的電腦.
可以查詢一下nginx在什麼位置
which nginx
開啟ps檢視一下當前執行的程序.我這裡提示沒有ps命令.我從網上查了一下發現是因為當前系統沒有安裝這個命令,然後我安裝了一下.從命令可以看出,這個nginx容器附帶的系統應該是ubuntu不是centos.
安裝ps命令:
- apt-get update
- apt-get install procps
利用ps命令檢視程序,可以發現nginx已經在運行了.
ps -ef
輸入 exit即可退出返回原來的系統.
6.2 docker網路
6.2.1 網路介紹
上面我們只運行了nginx,並沒有用瀏覽器進行訪問,這裡我們嘗試用瀏覽器訪問,但是之前我們要了解一下docker網路.
我們直到docker的隔離性,網路也是個隔離性的一部分,linux使用了名稱空間來進行資源的隔離,比如pid namespace就是用來隔離程序的,mount namespace是用來隔離檔案系統的,network namespace 是用來隔離網路的.每一個network namespace都提供了一個獨立的網路環境,包括網絡卡路由iptable規則等等,都是與以其它的network space隔離的.
1. docker容器在預設情況下,一般會分配一個獨立的network-namespace,也就是網路型別中的Bridge模式.
在使用Bridge時就涉及到了一個問題,既然它有獨立的namesapce,這就需要一種技術使容器內的埠可以在主機上訪問到,這種技術就是埠對映,docker可以指定你想把容器內的某一個埠可以在容器所在主機上的某一個埠它倆之間做一個對映,當你在訪問主機上的埠時,其實就是訪問容器裡面的埠.
2. 還有一種型別是Host模式,如果在啟動容器的時候指定使用Host模式,那麼這個容器將不會獲得一個獨立的network namespace,而是和主機共同使用一個,這個時候容器將不會虛擬出自己的網絡卡,配置出自己的ip.而是使用宿主機上的ip和埠.也就是說在docker上使用網路和在主機上使用網路是一樣的.
3. 還有一種網路型別是None.也就是沒有網路,這種情況docker將不會和外界的任何東西進行通訊.
6.2.2 實際訪問埠
剛才我們在執行nginx映象的時候並沒有指定埠對映,所以我們這裡停掉nginx容器.
docker stop containerId
1. -p(小寫)是開放一個容器的埠到主機上
在後臺執行,開放主機8080埠對映到容器的80埠上.
docker run -d -p 8080:80 hub.c.163.com/library/nginx
檢視主機8080埠是否開啟
netstat -na |grep 8080
是開啟的那麼訪問 主機ip:8080 即可訪問到nginx.
2. -P(大寫)是開放容器所有的埠到主機上一個隨機的埠.
停掉剛才的docker服務.
使用大P
docker run -d -P hub.c.163.com/library/nginx
可以看到隨機給我的埠是32768
然後用 ip:32768去訪問即可訪問到nginx.
第七章 docker部署第一個java web應用
我們還需要學習Dockerfile,它告訴docker我們怎樣製作我們的映象,我們映象的每一步操作分別是什麼,寫好Dockerfile後我們私用docker build命令執行Dockerfile裡面的每一件事情.最終會把Dockerfile構建出來.
在這裡因為是做一個演示,所以我們使用了一個開源的java web應用Jpress.
7.1 製作自己的映象
1. 從網易的映象中心找一個tomcat的映象
docker pull hub.c.163.com/library/tomcat:latest
因為tomat映象肯定有jdk,所以我們就不用單獨再裝jdk了.
2.編寫dockerfile
我們需要建立一個dockerfile告訴docker需要做什麼,這裡我建立了Dockerfile,並將我們的web檔案放到了和它同一個目錄下.
首先我們的映象是要執行在tomcat中的,所以填寫 from tomcat,以tomcat為基礎.maintainer是所有者的意思.因為war包是要放在webapps中的,所以我們使用copy命令複製到tomcat的webapps.
為什麼webapps在local中?我們可以去下載映象的網站查詢,向下拉就好了.具體網址 :https://c.163yun.com/hub#/m/repository/?repoId=2955
這裡說一個個人猜想,每個容器都包含一個自己的系統,所以這裡的/usr/local/tomcat/webapps指的是tomcat容器中的位置,那麼哪裡指定是tomcat容器呢?就是在一開始的from指定的.
- from hub.c.163.com/library/tomcat
- maintainer zhangchen 61037
- COPY jpress.war /usr/local/tomcat/webapps
3.構建容器
注意這裡是有個點的,點標明是在根據當前目錄構建
docker build .
可以使用docker images檢視映象是否build成功
發現一個none,表明構建成功了.
可以重新構建給它起個名字 -t是給映象指定一個tag
docker build -t jpress:latest .
更多的引數查詢:
docker build --help
7.2 執行自己的映象
執行我們製作的映象並指定埠
docker run -d -p 8080:8080 jpress
訪問我們的網站,發現網站已經可以正常訪問了.
然後發現它要求我們安裝自己的資料庫,所以我們利用docker安裝mysql.
在映象中心搜尋並拉取mysql
docker pull hub.c.163.com/library/mysql:latest
在映象中心檢視配置,並配置root使用者密碼
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 hub.c.163.com/library/mysql
發現我們沒有建立資料庫,於是停止這個容器的執行,並在與劇中建立jpress資料庫.
docker stop4be94fb2df1d3a28c1
ocker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=jpress hub.c.163.com/library/mysql
這樣我們的資料庫就建立成功了.
進入網站後要輸入網站資訊,輸入資料庫地址時,注意不要輸入localhost,因為我們jpress是執行在容器內的,我們會訪問tomcat容器內的3306,我們應該用ifconfig查詢我們本機的ip地址.我這裡的內網ip是172.17.10.68
以上都做完後,我們的網站就可以跑起來了.
http://59.110.164.62:8080/jpress/
docker啟動命令,docker重啟命令,docker關閉命令
啟動 systemctl start docker
守護程序重啟sudo systemctl daemon-reload
重啟docker服務systemctl restart docker
重啟docker服務sudo service docker restart
關閉dockerservice docker stop
關閉dockersystemctl stop docker