網(wǎng)站3網(wǎng)合一是怎么做的酒吧營銷用什么軟件找客源
輕量容器引擎Docker
Docker是什么
Docker 是一個開源項目,誕生于 2013 年初,最初是 dotCloud 公司內(nèi)部的一個業(yè)余項目。
它基于 Google 公司推出的 Go 語言實現(xiàn),項目后來加入了 Linux 基金會,遵從了 Apache 2.0 協(xié)議,項目代碼在GitHub 上進(jìn)行維護(hù)
Docker 自開源后受到廣泛的關(guān)注和討論,以至于 dotCloud 公司后來都改名為 Docker Inc,Redhat 已經(jīng)在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產(chǎn)品中廣泛應(yīng)用。
Docker 項目的目標(biāo)是實現(xiàn)輕量級的操作系統(tǒng)虛擬化解決方案,Docker 的基礎(chǔ)是 Linux 容器(LXC)等技術(shù)。
Docker的前生LXC
Linux Container容器是一種內(nèi)核虛擬化技術(shù),可以提供輕量級的虛擬化,以便隔離進(jìn)程和資源。
LXC為Linux Container的簡寫,可以提供輕量級的虛擬化,以便隔離進(jìn)程和資源,而且不需要提供指令解釋機(jī)制以及全虛擬化的其他復(fù)雜性,相當(dāng)于C++中的NameSpace,容器有效地將由單個操作系統(tǒng)管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有沖突的資源使用需求。
與傳統(tǒng)虛擬化技術(shù)相比,它的優(yōu)勢在于:
- 與宿主機(jī)使用同一個內(nèi)核,性能損耗小;
- 不需要指令級模擬;
- 不需要即時(Just-in-time)編譯;
- 容器可以在CPU核心的本地運(yùn)行指令,不需要任何專門的解釋機(jī)制;
- 避免了準(zhǔn)虛擬化和系統(tǒng)調(diào)用替換中的復(fù)雜性;
- 輕量級隔離,在隔離的同時還提供共享機(jī)制,以實現(xiàn)容器與宿主機(jī)的資源共享
Linux Container提供了在單一可控主機(jī)節(jié)點(diǎn)上支持多個相互隔離的server container同時執(zhí)行的機(jī)制,Linux Container有點(diǎn)像chroot,提供了一個擁有自己進(jìn)程和網(wǎng)絡(luò)空間的虛擬環(huán)境,但又有別于虛擬機(jī),因為lxc是一種操作系統(tǒng)層次上的資源的虛擬化。
LXC與docker的關(guān)系
docker并不是LXC替代品,docker底層使用了LXC來實現(xiàn),LXC將linux進(jìn)程沙盒化,使得進(jìn)程之間相互隔離,并且能夠可控限制各進(jìn)程的資源分配,在LXC的基礎(chǔ)之上,docker提供了一系列更強(qiáng)大的功能。
Docker 的特點(diǎn)
容器化越來越受歡迎,因為容器是:
- 靈活:即使是最復(fù)雜的應(yīng)用也可以集裝箱化。
- 輕量級:容器利用并共享主機(jī)內(nèi)核。
- 可互換:可以即時部署更新和升級。
- 便攜式:可以在本地構(gòu)建,部署到云,并在任何地方運(yùn)行。
- 可擴(kuò)展:可以增加并自動分發(fā)容器副本。
- 可堆疊:可以垂直和即時堆疊服務(wù)。
為什么使用Docker
作為一種新興的虛擬化方式,Docker 跟傳統(tǒng)的虛擬化方式相比具有眾多的優(yōu)勢。
首先,Docker 容器的啟動可以在秒級實現(xiàn),這相比傳統(tǒng)的虛擬機(jī)方式要快得多,其次,Docker 對系統(tǒng)資源的利用率很高,一臺主機(jī)上可以同時運(yùn)行數(shù)千個 Docker 容器。
Docker的優(yōu)勢
具體說來,Docker 在如下幾個方面具有較大的優(yōu)勢。
更高效的利用系統(tǒng)資源
由于容器不需要進(jìn)行硬件虛擬以及運(yùn)行完整操作系統(tǒng)等額外開銷,Docker對系統(tǒng)資源的利用率更高,無論是應(yīng)用執(zhí)行速度,內(nèi)存消耗以及文件存儲速度,都要比傳統(tǒng)虛擬機(jī)技術(shù)更高效,因此,相比虛擬機(jī)技術(shù),一個相同配置的主機(jī),往往可以運(yùn)行更多數(shù)量的應(yīng)用。
更快速的啟動時間
傳統(tǒng)的虛擬機(jī)技術(shù)啟動應(yīng)用服務(wù)往往需要數(shù)分鐘,而Docker容器應(yīng)用,由于直接運(yùn)行與宿主內(nèi)核,無須啟動完整的操作系統(tǒng),因此可以做到秒級,甚至毫秒級的啟動時間,大大的節(jié)約了開發(fā),測試,部署的時間。
一致的運(yùn)行環(huán)境
開發(fā)過程中一個常見的問題是環(huán)境一致性問題,由于開發(fā)環(huán)境,測試環(huán)境,生產(chǎn)環(huán)境不一致,導(dǎo)致有些bug并未在開發(fā)過程中被發(fā)現(xiàn),而Docker的鏡像提供了除內(nèi)核外完整的運(yùn)行時環(huán)境,確保了應(yīng)用運(yùn)行環(huán)境一致性。
持續(xù)交付和部署
對于開發(fā)和運(yùn)維人員來說,最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運(yùn)行。
使用Docker可以通過定制應(yīng)用鏡像來實現(xiàn)持續(xù)集成,持續(xù)交付,部署,開發(fā)人員可以通過Dockerfile來進(jìn)行鏡像構(gòu)建,并結(jié)合持續(xù)集成系統(tǒng)進(jìn)行集成測試,而運(yùn)維人員則可以在生產(chǎn)環(huán)境中快速部署該鏡像,甚至結(jié)合持續(xù)部署系統(tǒng)進(jìn)行自動部署
更輕松的遷移
由于Docker確保了執(zhí)行環(huán)境的一致性,使得應(yīng)用的遷移更加容易,Docker可以在很多平臺上運(yùn)行,無論是物理機(jī),虛擬機(jī),公有云,私有云,甚至是筆記本,其運(yùn)行結(jié)果是一致的,因此用戶可以很輕易的將在一個平臺上運(yùn)行的應(yīng)用,遷移到另一個平臺上,而不用擔(dān)心運(yùn)行環(huán)境的變化導(dǎo)致應(yīng)用無法正常運(yùn)行的情況。
缺點(diǎn)
隔離性
基于hypervisor的虛機(jī)技術(shù),在隔離性上比容器技術(shù)要更好,它們的系統(tǒng)硬件資源完全是虛擬化的,當(dāng)一臺虛機(jī)出現(xiàn)系統(tǒng)級別的問題,往往不會蔓延到同一宿主機(jī)上的其他虛機(jī),但是容器就不一樣了,容器之間共享同一個操作系統(tǒng)內(nèi)核以及其他組件,所以在收到攻擊之類的情況發(fā)生時,更容易通過底層操作系統(tǒng)影響到其他容器。
性能
不管是虛機(jī)還是容器,都是運(yùn)用不同的技術(shù),對應(yīng)用本身進(jìn)行了一定程度的封裝和隔離,在降低應(yīng)用和應(yīng)用之間以及應(yīng)用和環(huán)境之間的耦合性上做了很多努力,但是隨機(jī)而來的,就會產(chǎn)生更多的網(wǎng)絡(luò)連接轉(zhuǎn)發(fā)以及數(shù)據(jù)交互,這在低并發(fā)系統(tǒng)上表現(xiàn)不會太明顯,而且往往不會成為一個應(yīng)用的瓶頸(可能會分散于不同的虛機(jī)或者服務(wù)器上),但是當(dāng)同一虛機(jī)或者服務(wù)器下面的容器需要更高并發(fā)量支撐的時候,也就是并發(fā)問題成為應(yīng)用瓶頸的時候,容器會將這個問題放大,所以,并不是所有的應(yīng)用場景都是適用于容器技術(shù)的。
存儲方案
容器的誕生并不是為OS抽象服務(wù)的,這是它和虛機(jī)最大的區(qū)別,這樣的基因意味著容器天生是為應(yīng)用環(huán)境做更多的努力,容器的伸縮也是基于容器的這一disposable特性,而與之相對的,需要持久化存儲方案恰恰相反。 這一點(diǎn)docker容器提供的解決方案是利用volume接口形成數(shù)據(jù)的映射和轉(zhuǎn)移,以實現(xiàn)數(shù)據(jù)持久化的目的,但是這樣同樣也會造成一部分資源的浪費(fèi)和更多交互的發(fā)生,不管是映射到宿主機(jī)上還是到網(wǎng)絡(luò)磁盤,都是退而求其次的解決方案。
對比傳統(tǒng)虛擬機(jī)
特性 | Docker 容器 | 虛擬機(jī) |
---|---|---|
啟動 | 秒級 | 分鐘級 |
硬盤使用 | 一般為 MB | 一般為 GB |
性能 | 接近原生 | 弱于 |
系統(tǒng)支持量 | 單機(jī)支持上千個容器 | 一般幾十個 |
Docker版本
隨著Docker的不斷流行與發(fā)展,docker公司(或稱為組織)也開啟了商業(yè)化之路,Docker 從 17.03版本之后分為 CE(Community Edition) 和 EE(Enterprise Edition),我們來看看他們之前的區(qū)別于聯(lián)系。
版本區(qū)別
Docker EE
Docker EE由公司支持,可在經(jīng)過認(rèn)證的操作系統(tǒng)和云提供商中使用,并可運(yùn)行來自Docker Store的、經(jīng)過認(rèn)證的容器和插件。
Docker EE提供三個服務(wù)層次:
服務(wù)層級 | 功能 |
---|---|
Basic | 包含用于認(rèn)證基礎(chǔ)設(shè)施的Docker平臺 Docker公司的支持 經(jīng)過 認(rèn)證的、來自Docker Store的容器與插件 |
Standard | 添加高級鏡像與容器管理 LDAP/AD用戶集成 基于角色的訪問控制(Docker Datacenter) |
Advanced | 添加Docker安全掃描 連續(xù)漏洞監(jiān)控 |
大家可在該頁查看各個服務(wù)層次的價目:https://www.docker.com/pricing
Docker CE
Docker CE是免費(fèi)的Docker產(chǎn)品的新名稱,Docker CE包含了完整的Docker平臺,非常適合開發(fā)人員和運(yùn)維團(tuán)隊構(gòu)建容器APP
Docker公司認(rèn)為,Docker CE和EE版本的推出為Docker的生命周期、可維護(hù)性以及可升級性帶來了巨大的改進(jìn)。
版本說明
在此之前docker的最新版本更新到docker17.13,而在1.13的基礎(chǔ)之上,在2017年的3月1號開始,版本的格式變?yōu)槿缦?/p>
項目 | 說明 |
---|---|
版本格式 | YY.MM |
stable版本 | 每個季度發(fā)行 |
edge版本 | 每個月發(fā)行 |
當(dāng)前CE版本 | 17.03.0-ce |
小結(jié)
- Docker從17.03開始分為企業(yè)版與社區(qū)版,社區(qū)版并非閹割版,而是改了個名稱;企業(yè)版則提供了一些收費(fèi)的高級特性。
- EE版本維護(hù)期1年;CE的stable版本三個月發(fā)布一次,維護(hù)期四個月;另外CE還有edge版,一個月發(fā)布一次。
Docker使用場景
- Web 應(yīng)用的自動化打包和發(fā)布。
- 自動化測試和持續(xù)集成、發(fā)布。
- 在服務(wù)型環(huán)境中部署和調(diào)整數(shù)據(jù)庫或其他的后臺應(yīng)用。
- 從頭編譯或者擴(kuò)展現(xiàn)有的OpenShift或Cloud Foundry平臺來搭建自己的PaaS環(huán)境
Docker安裝
卸載舊版本
較舊的 Docker 版本稱為 docker 或 docker-engine ,如果已安裝這些程序,請卸載它們以及相關(guān)的依賴項。
yum remove docker \\docker-client \\docker-client-latest \\docker-common \\docker-latest \\docker-latest-logrotate \\docker-logrotate \\docker-engine
安裝Docker依賴環(huán)境
在新主機(jī)上首次安裝 Docker Engine-Community 之前,需要設(shè)置 Docker 倉庫,之后,可以從倉庫安裝和更新 Docker。
yum install -y yum-utils \\device-mapper-persistent-data \\lvm2
設(shè)置 Docker 安裝地址
在新主機(jī)上首次安裝 Docker Engine-Community 之前,需要設(shè)置 Docker 倉庫,之后,可以從倉庫安裝和更新 Docker,使用以下命令來設(shè)置穩(wěn)定的倉庫**(阿里云)**
sudo yum-config-manager \\--add-repo \\http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安裝 Docker Engine-Community
安裝最新版本的 Docker Engine-Community 和 containerd
sudo yum install -y docker-ce docker-ce-cli containerd.io
如果提示接受 GPG 密鑰,請選是。
Docker 安裝完默認(rèn)未啟動,并且已經(jīng)創(chuàng)建好 docker 用戶組,但該用戶組下沒有用戶。
Docker 鏡像加速
阿里云鏡像獲取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陸后,左側(cè)菜單選中鏡像加速器就可以看到你的專屬地址了:
配置daemon.json
可以通過修改daemon配置文件/etc/docker/daemon.json來使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
啟動 Docker
service docker start
驗證docker服務(wù)
通過運(yùn)行 hello-world 映像來驗證是否正確安裝了 Docker Engine-Community
docker run hello-world
運(yùn)行該代碼后首先會從倉庫拉取
hello-world
鏡像,然后運(yùn)行該鏡像,運(yùn)行后會輸出一個Hello from Docker!
開啟Docker自動補(bǔ)全
使用docker時無法自動補(bǔ)全鏡像名和其他參數(shù),這樣使用效率大大降低,下面是解決方法
bash-complete
yum install -y bash-completion
刷新文件
source /usr/share/bash-completion/completions/docker
source /usr/share/bash-completion/bash_completion
測試
輸入
docker p
后docker會將可選項列出來
docker p
Docker架構(gòu)
Docker總體架構(gòu)為c/s架構(gòu),模塊之間松耦合,包含了Client, Daemon, Registry, Graph, Driver, Libcontainer以及Docker Container
Docker的組件
Docker Client
是用戶界面,它支持用戶與Docker Daemon
之間通信Docker Daemon
Docker最核心的后臺進(jìn)程,運(yùn)行于主機(jī)上,處理服務(wù)請求Docker registry
是中央registry,支持擁有公有與私有訪問權(quán)限的Docker容器鏡像的備份Docker Containers
負(fù)責(zé)應(yīng)用程序的運(yùn)行,包括操作系統(tǒng)、用戶添加的文件以及元數(shù)據(jù)Docker Images
是一個只讀模板,用來運(yùn)行Docker容器DockerFile
是文件指令集,用來說明如何自動創(chuàng)建Docker鏡像
Docker 基本概念
Docker 包括三個基本概念:
鏡像
Docker 鏡像是一個特殊的文件系統(tǒng),除了提供容器運(yùn)行時所需的程序、庫、資源、配置等文件外,還包含了一些為運(yùn)行時準(zhǔn)備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等),鏡像不包含任何動態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會被改變。
分層存儲
鏡像只是一個虛擬的概念,其實際體現(xiàn)并非由一個文件組成,而是由一組文件系統(tǒng)組成,或者說,由多層文件系統(tǒng)聯(lián)合組成。
Union FS
聯(lián)合文件系統(tǒng)是(Union FS)是linux的存儲技術(shù),也是Docker鏡像的存儲方式, 它是分層的文件系統(tǒng),將不同目錄拉到同一個虛擬目錄下,下圖展示了Docker用Union FS 搭建的分層鏡像:(比如最下層是操作系統(tǒng)的引導(dǎo),上一層是Linux操作系統(tǒng),再上一層是Tomcat,jdk,再上一層是應(yīng)用代碼)
這些層是只讀的,加載完后這些文件會被看成是同一個目錄,相當(dāng)于只有一個文件系統(tǒng)。
我們可以通過docker info查看鏡像的一些信息,可以看到存儲驅(qū)動用的并不是Union FS 而是overlay2,overlay也是一個聯(lián)合文件系統(tǒng),所以上述主要介紹聯(lián)合文件系統(tǒng)的概念,至于這些存儲驅(qū)動的演變過程和優(yōu)缺點(diǎn)
鏡像構(gòu)建時,會一層層構(gòu)建,前一層是后一層的基礎(chǔ),每一層構(gòu)建完就不會再發(fā)生改變,后一層上的任何改變只發(fā)生在自己這一層。(比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當(dāng)前層標(biāo)記為該文件已刪除,在最終容器運(yùn)行的時候,雖然不會看到這個文件,但是實際上該文件會一直跟隨鏡像,因此,在構(gòu)建鏡像的時候,需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應(yīng)該在該層構(gòu)建結(jié)束前清理掉)
容器
鏡像(Image)和容器(Container)的關(guān)系,就像是面向?qū)ο蟪绦蛟O(shè)計中的 類 和 實例 一樣,鏡像是靜態(tài)的定義,容器是鏡像運(yùn)行時的實體,容器可以被創(chuàng)建、啟動、停止、刪除、暫停等。
容器的實質(zhì)是進(jìn)程,但與直接在宿主執(zhí)行的進(jìn)程不同,容器進(jìn)程運(yùn)行于屬于自己的獨(dú)立的命名空間,因此容器可以擁有自己的root文件系統(tǒng)、自己的網(wǎng)絡(luò)配置、自己的進(jìn)程空間,甚至自己的用戶 ID 空間。
容器內(nèi)的進(jìn)程是運(yùn)行在一個隔離的環(huán)境里,使用起來,就好像是在一個獨(dú)立于宿主的系統(tǒng)下操作一樣,這種特性使得容器封裝的應(yīng)用比直接在宿主運(yùn)行更加安全,也因為這種隔離的特性,很多人初學(xué) Docker 時常常會混淆容器和虛擬機(jī)。
前面講過鏡像使用的是分層存儲,容器也是如此,每一個容器運(yùn)行時,是以鏡像為基礎(chǔ)層,在其上創(chuàng)建一個當(dāng)前容器的存儲層,我們可以稱這個為容器運(yùn)行時讀寫而準(zhǔn)備的存儲層為容器存儲層。
容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也隨之消亡,因此,任何保存于容器存儲層的信息都會隨容器刪除而丟失。
倉庫
鏡像構(gòu)建完成后,可以很容易的在當(dāng)前宿主機(jī)上運(yùn)行,但是,如果需要在其它服務(wù)器上使用這個鏡像,我們就需要一個集中的存儲、分發(fā)鏡像的服務(wù),Docker Registry 就是這樣的服務(wù)。
一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個標(biāo)簽(Tag);每個標(biāo)簽對應(yīng)一個鏡像。
通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標(biāo)簽就常用于對應(yīng)該軟件的各個版本,我們可以通過<倉庫名>:<標(biāo)簽>的格式來指定具體是這個軟件哪個版本的鏡像,如果不給出標(biāo)簽,將以latest作為默認(rèn)標(biāo)簽。
以 Ubuntu 鏡像為例,ubuntu是倉庫的名字,其內(nèi)包含有不同的版本標(biāo)簽,如,14.04,16.04,我們可以通過ubuntu:14.04,或者ubuntu:16.04來具體指定所需哪個版本的鏡像,如果忽略了標(biāo)簽,比如ubuntu,那將視為ubuntu:latest
倉庫名經(jīng)常以三段式路徑形式出現(xiàn),比如demo.com/nginx-proxy:tag
,前者往往意味著 Docker Registry 多用戶環(huán)境下的用戶名,后者則往往是對應(yīng)的軟件名,但這并非絕對,取決于所使用的具體 Docker Registry 的軟件或服務(wù)
Docker部署微服務(wù)
場景介紹
我們使用Docker完成一個微服務(wù)的搭建過程
整體架構(gòu)如下
使用多個微服務(wù)進(jìn)行項目部署測試
整體服務(wù)說明
我們總共涉及到三個微服務(wù)以及兩個中間件
服務(wù)名稱 | 描述 |
---|---|
mysql | 數(shù)據(jù)庫服務(wù) |
nacos | 注冊中心 |
learn-docker-gateway | 網(wǎng)關(guān)服務(wù) |
learn-docker-web | API接口服務(wù) |
learn-docker-storage | 存儲服務(wù) |
配置文件提取
因為我們在開發(fā)中需要頻繁修改
application.yml
文件我們將配置項配置到pom
文件中打包時自動打到配置文件,這樣可以用一個pom
文件控制多個不同的服務(wù)的配置文件項的修改
pom文件定義屬性
我們需要在總
pom
文件定義全局配置,例如nacos
、mysql
等配置
<properties><mysql.addr>192.168.64.153:3306</mysql.addr><nacos.addr>192.168.64.153:8848</nacos.addr>
</properties>
配置編譯選項
在子項目的pom文件的
build
構(gòu)建配置中使用<filtering>true</filtering>
配置,這樣就可以將我們的總pom中的配置編譯進(jìn)配置文件了
<build><resources><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes></resource><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources>
</build>
配置文件配置
在子項目的
application.yml
配置文件中注意使用@xxx@
占位符來配置編譯占位配置,下面的配置就是用了@@
占位符編譯后會將pom中的配置編譯到配置文件中
server:port: @project.server.prot@
spring:application:name: learn-docker-storage######################### 數(shù)據(jù)源連接池的配置信息 #################datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.jdbc.Driverurl: jdbc:mysql://@db.addr@/employees?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCusername: rootpassword: rootinitialSize: 10minIdle: 20maxActive: 100maxWait: 60000#### nacos 配置#######cloud:nacos:server-addr: @nacos.addr@
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.demo.module.p
編譯測試
配置完后編譯項目后,可以進(jìn)入target目錄下查看編譯后的配置文件
我們看到maven已經(jīng)幫我們將配置編譯進(jìn)了配置文件中了
安裝MySQL
MySQL簡介
MySQL 是世界上最受歡迎的開源數(shù)據(jù)庫。憑借其可靠性、易用性和性能,MySQL 已成為 Web 應(yīng)用程序的數(shù)據(jù)庫優(yōu)先選擇。
查找MySQL鏡像
我們可以使用 docker search 鏡像名稱,命令來搜索鏡像
docker search mysql
參數(shù)解釋
搜索出來的有這么多鏡像,怎么選擇呢
- NAME: 鏡像倉庫源的名稱
- DESCRIPTION: 鏡像的描述
- OFFICIAL: 是否 docker 官方發(fā)布
- stars: 類似 Github 里面的 star,表示點(diǎn)贊、喜歡的意思。
- AUTOMATED: 自動構(gòu)建。
根據(jù)參數(shù),我們一般選擇 官方發(fā)布的,并且stars多的。
下載鏡像
可以使用
docker pull 鏡像名稱
來拉取鏡像,我們選擇了第一個Mysql的鏡像,我們把它給拉取下來
docker pull mysql
注意事項
- 如果不寫版本號默認(rèn)拉取最新的版本好
latest
。 - 拉取的時候是多個層一起拉取的,這樣可用讓其他鏡像復(fù)用分層
- 如果拉取的鏡像不寫倉庫地址默認(rèn)就是
docker.io/library/
下載指定版本的鏡像
我們上面下載的鏡像不符合我們的預(yù)期,我們需要Mysql5.7的鏡像
查找指定鏡像
可以登錄
https://hub.docker.com
https://hub-stage.docker.com地址搜索鏡像
輸入需要搜索的鏡像名稱,并選擇對應(yīng)鏡像名稱
選擇
tag
標(biāo)簽,這個就是版本的信息
找到符合的版本 的mysql鏡像,這里我們選擇
5.7.33
下載指定版本鏡像
剛才我們已經(jīng)找到了
5.7.33
版本的Mysql的鏡像,我們使用docker pull
命令下載,鏡像后面跟的是tag也就是版本名稱
docker pull mysql:5.7.34
我們發(fā)現(xiàn),我們的新拉取的mysql鏡像共用了 部分分層
查看鏡像
安裝完鏡像后,我們需要看一下我們的本地鏡像,使用
docker images
可用查看本地鏡像
docker images
這里有兩個鏡像,一個是最新版本的一個是我們剛才下載的
5.7.33
版本的
MySQL配置
配置MySQL忽略大小寫
創(chuàng)建MySQL掛載目錄,等會會解釋什么是掛載路徑
# 創(chuàng)建MySQL配置的文件夾
mkdir -p /tmp/etc/mysql
# 編輯my.cnf配置文件
vi /tmp/etc/mysql/my.cnf
配置MySQL忽略大小寫,在我們創(chuàng)建的MySQL配置文件掛載點(diǎn)的目錄的my.cnf文件加入如下內(nèi)容
[mysqld]
lower_case_table_names=1
創(chuàng)建MySQL數(shù)據(jù)目錄
因為默認(rèn)MySQL啟動后他的文件是在容器中的,如果我們刪除容器,數(shù)據(jù)也將會消失,我們需要將數(shù)據(jù)掛載出來。
#創(chuàng)建mysql存儲的目錄
mkdir -p /tmp/data/mysql
啟動MySql
使用
docker run
啟動容器
docker run -d -p 3306:3306 -v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ -v /tmp/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7.38
到這里MySQL已經(jīng)后臺運(yùn)行了
參數(shù)解釋
- -d:是指容器后臺運(yùn)行,如果不加
-d
,當(dāng)用戶斷開客戶端時容器會結(jié)束運(yùn)行 - -p:將容器的3306端口映射到主機(jī)的3306端口,用來暴漏端口的
- -v:這個命令是用來掛載目錄的,將本地目錄掛載到容器中,這樣容器操作的就是本地目錄
- -e:這個命令是配置環(huán)境參數(shù)的,這里
MYSQL_ROOT_PASSWORD=root
指的是用root用戶運(yùn)行mysql,可以登錄Docker容器通過ENV
命令查看 - –name:這個命令是配置Mysql的容器名稱的,如果不配置,默認(rèn)是隨機(jī)生成的名字
檢查MySQL運(yùn)行狀態(tài)
現(xiàn)在并不能確認(rèn)MySQL的運(yùn)行狀態(tài),我們需要去看下
查看容器運(yùn)行狀態(tài)
使用
docker ps
可以看到運(yùn)行中的容器
docker ps
執(zhí)行命令后,我們看到mysql的服務(wù)已經(jīng)起來了
查看MySQL運(yùn)行日志
現(xiàn)在MySQL容器起來了,并不代表MySQL已經(jīng)成功啟動,我們需要使用
docker logs
命令查看MySQL的日志
docker logs -f mysql
該命令可以查看容器日志
-f
是追蹤打印日志,可以看到MySQL已經(jīng)啟動了
客戶端連接MySQL
因為我們已經(jīng)暴漏端口了,可以使用客戶端工具連接MySQL
檢查配置的大小寫參數(shù)是否生效
SHOW VARIABLES LIKE '%case_table%';
查看容器掛載的配置文件
可以通過
docker exec -ti mysql /bin/bash
命令登錄容器,檢查掛載的配置文件情況
# 登錄容器
docker exec -ti mysql /bin/bash
該命令含義是在mysql容器中以
我們可以看到我們修改的配置文件已經(jīng)被掛載到了docker內(nèi)部,這里面用到了exec命令,主要是在docker容器中運(yùn)行命令,下面我們介紹下
命令格式
主要是在deocker容器中運(yùn)行命令
docker exec [options] container command [arg...]
命令參數(shù)
名稱 | 簡寫 | 描述 |
---|---|---|
–detach | -d | 后臺運(yùn)行模式,在后臺執(zhí)行命令相關(guān)命令 |
–detach-keys | 覆蓋容器后臺運(yùn)行的一些參數(shù)信息 | |
–env | -e | 設(shè)置環(huán)境變量 |
–interactive | -i | 展示容器輸入信息STDIN |
–privileged | 為命令提供一些擴(kuò)展權(quán)限 | |
–tty | -t | 命令行交互模式 |
–user | -u | 設(shè)置用戶名(format: <name |
–workdir | -w | 指定容器內(nèi)的目錄 |
查看掛載的數(shù)據(jù)文件
可以看下掛載的數(shù)據(jù)文件是否存在
cd /tmp/data/mysql/ && ll
我們看到數(shù)據(jù)文件已經(jīng)寫入了
MySQL準(zhǔn)備數(shù)據(jù)
MySql需要導(dǎo)入一些數(shù)據(jù)用來操作,我們用MySQL官方提供的數(shù)據(jù)庫來操作
下載并導(dǎo)入數(shù)據(jù)
下載MySQL測試數(shù)據(jù)庫
到測試數(shù)據(jù)官網(wǎng) 下載數(shù)據(jù)庫文件
直接導(dǎo)入無法導(dǎo)入,需要編輯
employees.sql
文件的一些地方
set storage_engine = InnoDB;
修改為:set default_storage_engine = InnoDB;
select CONCAT('storage engine: ', @@storage_engine) as INFO;
修改為:select CONCAT('storage engine: ', @@default_storage_engine) as INFO;
.....set default_storage_engine = InnoDB;
-- set storage_engine = MyISAM;
-- set storage_engine = Falcon;
-- set storage_engine = PBXT;
-- set storage_engine = Maria;select CONCAT('storage engine: ',@@default_storage_engine) as INFO;
.....
導(dǎo)入測試數(shù)據(jù)
下載解壓后,在本地執(zhí)行命令導(dǎo)入到mysql服務(wù)器
mysql -uroot -h192.168.64.152 -p < employees.sql
客戶端檢查數(shù)據(jù)
在登陸客戶端就能看到數(shù)據(jù)庫以及表了
安裝部署nacos
Nacos是阿里巴巴開源的一款支持服務(wù)注冊與發(fā)現(xiàn),配置管理以及微服務(wù)管理的組件。用來取代以前常用的注冊中心(zookeeper , eureka等等),以及配置中心(spring cloud config等等),Nacos是集成了注冊中心和配置中心的功能,做到了二合一。
直接運(yùn)行服務(wù)
可以直接用docker 啟動服務(wù),鏡像不存在會自動拉取
docker run -d -p 8848:8848 --name nacos --env MODE=standalone nacos/nacos-server
運(yùn)行容器后可以稍等下,等待nacos啟動成功,受環(huán)境限制啟動可能有些慢
登錄頁面測試
可以登錄服務(wù)器測試以下
用戶名:nacos 密碼:nacos
微服務(wù)打包鏡像
我們準(zhǔn)備將一個微服務(wù)打包成Docker鏡像,在各種服務(wù)器中進(jìn)行運(yùn)行,改為服務(wù)支持進(jìn)行查詢用戶信息
提前說明
因為我們剛開始進(jìn)行學(xué)習(xí)Docker,先從單個微服務(wù)開始學(xué)習(xí),我們就先部署
learn-docker-storage
服務(wù),后面隨著深入在慢慢增加其他的微服務(wù)
訪問測試
在idea中運(yùn)行
learn-docker-storage
我們配置的端口是8003,我們可以直接訪問
http://localhost:8003/storage/employe/findByID/10001
打包上傳微服務(wù)
將
learn-docker-storage
服務(wù)打包后上傳到服務(wù)器
注意配置項
這里需要檢查下maven配置的編譯屬性是否正確
<mysql.addr>192.168.64.153:3306</mysql.addr>
<nacos.addr>192.168.64.153:8848</nacos.addr>
我們發(fā)現(xiàn)是我們?nèi)萜髦袉拥牡刂?/p>
上傳打包后的微服務(wù)
將target目錄中打包完成的微服務(wù)上傳到服務(wù)器
創(chuàng)建DockerFile
Dockerfile 是一個用來構(gòu)建鏡像的文本文件,文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說明。
創(chuàng)建一個Dockerfile文件
vi Dockerfile
具體內(nèi)容如下
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD learn-docker-storage-2.0-SNAPSHOT.jar app.jar
EXPOSE 8003
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
命令解釋
- FORM:定制的鏡像都是基于 FROM 的鏡像,這里的 openjdk 就是定制需要的基礎(chǔ)鏡像,后續(xù)操作都是基于openjdk
- VOLUME:掛載一個數(shù)據(jù)卷,這里因為沒有名稱,所以是一個默認(rèn)的數(shù)據(jù)卷(后面詳細(xì)解釋)
- ADD:添加一層鏡像到當(dāng)前鏡像,這里就是添加SpringBootTest鏡像到當(dāng)前層,并改名app.jar
- EXPOSE:暴漏端口,因為我們的自己的端口是8003,所以我們暴漏8003
- ENTRYPOINT:設(shè)定容器啟動時第一個運(yùn)行的命令及其參數(shù),這里就是容器以啟動就執(zhí)行 java -jar /app.jar
打包鏡像
寫好DockerFile后就需要用
docker build
命令來構(gòu)建我們的鏡像了,這樣就可以將我們的微服務(wù)打包成一個鏡像了
構(gòu)建命令格式
構(gòu)建一個鏡像需要使用以下命令
docker bulid -t 倉庫名/鏡像名:tag .
參數(shù)解釋
-
-t: 鏡像的名字及標(biāo)簽,一般命名規(guī)則是 倉庫名/鏡像名:tag,
- 倉庫名:一般是私服或者dockerhub等地址,如果忽略默認(rèn)就是dockerhub的地址
docker.io.library/
- 鏡像名稱:就是我們的自己的服務(wù)名稱,可以隨意命名
- tag:就是我們的版本號
- 倉庫名:一般是私服或者dockerhub等地址,如果忽略默認(rèn)就是dockerhub的地址
-
.:這個
.
表示當(dāng)前目錄,這實際上是在指定上下文的目錄是當(dāng)前目錄,docker build
命令會將該目錄下的內(nèi)容打包交給 Docker 引擎以幫助構(gòu)建鏡像。
實戰(zhàn)操作
一般來說,應(yīng)該會將 Dockerfile
置于一個空目錄下,或者項目根目錄下,如果該目錄下沒有所需文件,那么應(yīng)該把所需文件復(fù)制一份過來。
一般大家習(xí)慣性的會使用默認(rèn)的文件名 Dockerfile
,以及會將其置于鏡像構(gòu)建上下文目錄中。
當(dāng)前目錄的結(jié)構(gòu)如下
構(gòu)建鏡像
進(jìn)入Dockerfile的目錄,通過如下命令構(gòu)建鏡像
docker build -t learn-docker-storage:0.0.1 .
構(gòu)建完成如果出現(xiàn)
Successfully
說明已經(jīng)構(gòu)建成功了,
查看構(gòu)建的鏡像
使用
docker images
命令查看我們構(gòu)建完成的鏡像
docker images
我們可以看到我們的鏡像就在第一個位置
運(yùn)行鏡像
剛才已經(jīng)打包完成了鏡像,現(xiàn)在我們運(yùn)行我們自己的鏡像
# 運(yùn)行容器
docker run -d -p 8003:8003 learn-docker-storage:0.0.1
# 查看運(yùn)行中的容器
docker ps
參數(shù)最后的
learn-docker-storage:0.0.1
是鏡像的名稱,如果啟動容器可以使用鏡像名稱或者鏡像ID
參數(shù)解釋
- -d:后臺運(yùn)行
- -p:映射端口,將宿主機(jī)的8080端口映射到docker內(nèi)部的8080端口上
查看啟動日志
使用
docker logs 容器ID
來查看啟動日志
docker logs -f 74c239792266
嘗試訪問服務(wù)
通過
curl
命令來訪問服務(wù)
curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool
我們發(fā)現(xiàn)服務(wù)調(diào)用成功了,我們基本實現(xiàn)了微服務(wù)改造為docker方式并運(yùn)行
刪除容器
要刪除一個容器首先需要將一個容器停止掉
停止容器
我們要把剛才運(yùn)行的容器停止掉,使用
docker stop 容器ID
停止一個容器
docker stop 3752f7088a04
停止容器后,我們在通過進(jìn)程查看是看不到容器的,但是容器還是存在我們的服務(wù)中的
查看全部容器
通過
docker ps
只能看到運(yùn)行中的容器,但是我們停止的容器是看不到的,可以加上-a
查看所有的容器
docker ps -a
我們可以看到 加上
-a
參數(shù)可以看到剛才已經(jīng)停止掉的容器
啟動停止的容器
想要啟動一個停止的容器可以使用
docker start 容器ID
docker start 3752f7088a04
這樣就把剛才已經(jīng)停止的容器啟動了
刪除容器
已經(jīng)停止的容器可以使用
docker rm 容器ID
刪除容器,但是對于運(yùn)行中的容器可以加上-f
參數(shù)強(qiáng)制刪除
docker rm -f 3752f7088a04
這樣可以將一個運(yùn)行的容器強(qiáng)制刪除,如果停止的容器可以通過通過
docker rm
刪除
docker rm 3752f7088a04
這個時候就把容器給刪除掉了
日志掛載優(yōu)化
存儲卷優(yōu)化
什么是存儲卷
“卷”是容器上的一個或多個“目錄”,此類目錄可繞過聯(lián)合文件系統(tǒng),與宿主機(jī)上的某個目錄“綁定(關(guān)聯(lián))”;
在Docker中,要想實現(xiàn)數(shù)據(jù)的持久化(所謂Docker的數(shù)據(jù)持久化即數(shù)據(jù)不隨著Container的結(jié)束而結(jié)束),需要將數(shù)據(jù)從宿主機(jī)掛載到容器中。
Docker管理宿主機(jī)文件系統(tǒng)的一部分,默認(rèn)位于 /var/lib/docker/volumes 目錄中;(最常用的方式)
存儲卷優(yōu)化寫入速度
Docker鏡像由多個只讀層疊加而成,啟動容器時,docker會加載只讀鏡像層并在鏡像棧頂部加一個讀寫層;
如果運(yùn)行中的容器修改了現(xiàn)有的一個已經(jīng)存在的文件,那該文件將會從讀寫層下面的只讀層復(fù)制到讀寫層,該文件版本仍然存在,只是已經(jīng)被讀寫層中該文件的副本所隱藏,此即“寫時復(fù)制(COW)”機(jī)制。
為了避免這種情況,構(gòu)建Dockerfile的時候應(yīng)該加入一個存儲卷
Dockerfile增加存儲卷
增加存儲卷
編寫Dockerfile增加存儲卷,增加日志存儲卷
/logs
,這會是一個匿名存儲卷
FROM openjdk:8-jdk-alpine
VOLUME /tmp /logs
ADD learn-docker-storage-1.0-SNAPSHOT.jar app.jar
EXPOSE 8003
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
構(gòu)建鏡像
因為我們原來已經(jīng)構(gòu)建了鏡像,這次使用版本號是
0.0.2
#構(gòu)建鏡像
docker build -t learn-docker-storage:0.0.2 .
# 查看鏡像列表
docker images
運(yùn)行容器
通過run命令運(yùn)行容器
# 運(yùn)行容器
docker run -d -p 8003:8003 learn-docker-storage:0.0.2
# 查看運(yùn)行中的容器
docker ps
查看存儲卷
通過
docker volume ls
可以看到存儲卷
docker volume ls
查看容器信息
我們發(fā)現(xiàn)都是匿名的存儲卷,如何來確定都是那個呢,可以通過
docker inspect 容器ID
來查看存儲新鮮
docker inspect 2041965c3e87|grep Mounts -A20
通過這個命令可以看到數(shù)據(jù)卷的名稱以及宿主機(jī)的存儲路徑,我們可以直接到宿主機(jī)打印日志
# 進(jìn)入文件掛載目錄
cd /var/lib/docker/volumes/d35de1b7e4631908b05635db4c1f114ab3aafbdf25a9843c068696e66a779c75/_data
# 輸出日志
tail -f learn-docker-storage.log
這樣就看到了我們的日志文件
驗證存儲卷
刪除容器檢查存儲卷釋放消失
# 查看運(yùn)行的容器列表
docker ps
#刪除容器
docker rm -f 2041965c3e87
#查看所有的容器列表(運(yùn)行+停止)
docker ps -a
我們看到容器已經(jīng)被刪除了,檢查我們的存儲卷
docker volume ls
發(fā)現(xiàn)存儲卷還存在,數(shù)據(jù)還是存在的,并且數(shù)據(jù)也存在
# 查看存儲卷列表
docker volume ls
# 查看存儲卷詳情
docker inspect 296ccc64d919e86bb8329bf6b08447c2ea6a118458d3fcb86d5c7c9a3177dfe0
重新運(yùn)行鏡像啟動一個新的容器
# 運(yùn)行容器
docker run -d -p 8080:8080 e1222496c69f
# 查看運(yùn)行中的容器
docker ps
啟動容器后查看存儲卷列表
# 查看存儲卷列表
docker volume ls
我們發(fā)現(xiàn)有創(chuàng)建了兩個存儲卷,查看容器詳情
docker inspect 2041965c3e87|grep Mounts -A20
我們發(fā)現(xiàn)新啟動的容器新開了一個匿名存儲卷
bind掛載共享存儲
什么是bind
Bind mounts模式和Volumes非常相似,不同點(diǎn)在于Bind mounts模式是將宿主機(jī)上的任意文件或文件夾掛載到容器,而Volumes本質(zhì)上是將Docker服務(wù)管理的一塊區(qū)域(默認(rèn)是/var/lib/docker/volumes下的文件夾)掛載到容器。
共享存儲
經(jīng)過上面的測試,我們發(fā)現(xiàn)每一個容器都是單獨(dú)用一個存儲卷,用于臨時文件沒有問題的,但是如果要讓容器都用同一個存儲路徑怎么辦呢,這個時候就用到了 bind掛載了,可以使用
-v
進(jìn)行掛載掛載剛才的存儲卷。
# 級聯(lián)創(chuàng)建文件夾
mkdir -p /tmp/data/logs
# 運(yùn)行容器,指定掛載路徑
docker run -d -v /tmp/data/logs:/logs \\
-p 8003:8003 --name learn-docker-storage \\
learn-docker-storage:0.0.2
這里面
--name
是指定docker容器的名稱,我們操作容器就可以使用名稱進(jìn)行操作了
然后使用
docker inspect
命令來檢查容器詳情
docker inspect learn-docker-storage|grep Mounts -A20
我們發(fā)現(xiàn)掛載日志的掛載方式已經(jīng)變了,由原來的volume變?yōu)榱薭ind,并且掛載路徑變?yōu)榱宋覀冏约憾x的路徑,進(jìn)入目錄查看
# 進(jìn)入目錄并瀏覽目錄文件
cd /tmp/data/logs/&&ll
# 打印日志詳情
tail -f learn-docker-storage.log
驗證共享存儲
我們也按照上面步驟驗證下bind方式掛載的存儲,先刪除容器,檢查日志文件是否存在
# 停止并刪除容器
docker rm -f learn-docker-storage
# 查看容器已經(jīng)被刪除了
docker ps -a
# 進(jìn)入日志掛載路徑查看日志是否存在
cd /tmp/data/logs/&&ll
我們發(fā)現(xiàn)容器被刪除但是日志文件還存在本地
啟動一個新的容器
# 運(yùn)行容器,指定掛載路徑
docker run -d -v /tmp/data/logs:/logs \\
-p 8003:8003 --name learn-docker-storage \\
learn-docker-storage:0.0.2
# 查看日志文件
cat learn-docker-storage.log
我們發(fā)現(xiàn)新的容器的日志文件追加進(jìn)來了
我們發(fā)現(xiàn)日志已經(jīng)追加,我們讓不同的容器掛載同一個目錄了
volume和bind的區(qū)別
對于多個容器需要共享訪問同一數(shù)據(jù)目錄,或者需要持久化容器內(nèi)數(shù)據(jù)(如數(shù)據(jù)庫)時,我們都是采用掛載目錄形式(bind mounts),將宿主機(jī)的某一目錄掛載到容器內(nèi)的指定目錄,這種方式能解決問題,但這種方式也一直有一些缺點(diǎn)
- 容器在不同的服務(wù)器部署需要根據(jù)實際磁盤掛載目錄修改路徑
- 不同操作系統(tǒng)的文件和目錄權(quán)限會搞得你昏頭轉(zhuǎn)向,火冒三丈 ?
bind mount和volume其實都是利用宿主機(jī)的文件系統(tǒng),不同之處在于volume是docker自身管理的目錄中的子目錄,所以不存在權(quán)限引發(fā)的掛載的問題,并且目錄路徑是docker自身管理的,所以也不需要在不同的服務(wù)器上指定不同的路徑,你不需要關(guān)心路徑。
清理volume掛載
volume掛載方式,會生成很多匿名的目錄,我們可以找到對應(yīng)的沒有使用的volume進(jìn)行刪除
docker volume ls
通過查看我們發(fā)現(xiàn)里面,有很多的volume,我們可以找到?jīng)]有用的刪除
docker volume rm volume_name
還可以通過命令將沒有引用的全部volume清除掉,但是這個命令很危險
docker volume prune
這樣就將我們服務(wù)器上無效的volume清除掉了
網(wǎng)絡(luò)優(yōu)化
Docker網(wǎng)絡(luò)原理
Docker使用Linux橋接,在宿主機(jī)虛擬一個Docker容器網(wǎng)橋(docker0),Docker啟動一個容器時會根據(jù)Docker網(wǎng)橋的網(wǎng)段分配給容器一個IP地址,稱為Container-IP,同時Docker網(wǎng)橋是每個容器的默認(rèn)網(wǎng)關(guān),因為在同一宿主機(jī)內(nèi)的容器都接入同一個網(wǎng)橋,這樣容器之間就能夠通過容器的Container-IP直接通信。
Docker網(wǎng)橋是宿主機(jī)虛擬出來的,并不是真實存在的網(wǎng)絡(luò)設(shè)備,外部網(wǎng)絡(luò)是無法尋址到的,這也意味著外部網(wǎng)絡(luò)無法通過直接Container-IP訪問到容器,如果容器希望外部訪問能夠訪問到,可以通過映射容器端口到宿主主機(jī)(端口映射),即docker run創(chuàng)建容器時候通過 -p 或 -P 參數(shù)來啟用,訪問容器的時候就通過[宿主機(jī)IP]:[容器端口]訪問容器。
Docker網(wǎng)絡(luò)模式
Docker網(wǎng)絡(luò)模式 | 配置 | 說明 |
---|---|---|
host模式 | –net=host | 容器和宿主機(jī)共享Network namespace。 |
container模式 | –net=container:NAME_or_ID | 容器和另外一個容器共享Network namespace。 kubernetes中的pod就是多個容器共享一個Network namespace。 |
none模式 | –net=none | 容器有獨(dú)立的Network namespace,但并沒有對其進(jìn)行任何網(wǎng)絡(luò)設(shè)置,如分配veth pair 和網(wǎng)橋連接,配置IP等。 |
overlay模式 | – driver overlay | Docker跨主機(jī)通信模式,使用分布式計算機(jī)架構(gòu)后需要使用overlay網(wǎng)絡(luò)模式 |
bridge模式 | –net=bridge | (默認(rèn)為該模式) |
host模式
如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨(dú)立的Network Namespace,而是和宿主機(jī)共用一個Network Namespace。
容器將不會虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口,但是,容器的其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿主機(jī)隔離的。
使用host模式的容器可以直接使用宿主機(jī)的IP地址與外界通信,容器內(nèi)部的服務(wù)端口也可以使用宿主機(jī)的端口,不需要進(jìn)行NAT,host最大的優(yōu)勢就是網(wǎng)絡(luò)性能比較好,但是docker host上已經(jīng)使用的端口就不能再用了,網(wǎng)絡(luò)的隔離性不好。
Host模式如下圖所示
container模式
這個模式指定新創(chuàng)建的容器和已經(jīng)存在的一個容器共享一個 Network Namespace,而不是和宿主機(jī)共享
新創(chuàng)建的容器不會創(chuàng)建自己的網(wǎng)卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口范圍等,同樣,兩個容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng)、進(jìn)程列表等還是隔離的,兩個容器的進(jìn)程可以通過 lo 網(wǎng)卡設(shè)備通信
Container模式示意圖
none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置,也就是說,這個Docker容器沒有網(wǎng)卡、IP、路由等信息。需要我們自己為Docker容器添加網(wǎng)卡、配置IP等。
這種網(wǎng)絡(luò)模式下容器只有l(wèi)o回環(huán)網(wǎng)絡(luò),沒有其他網(wǎng)卡,none模式可以在容器創(chuàng)建時通過–network=none來指定,這種類型的網(wǎng)絡(luò)沒有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
None模式示意圖
overlay模式
容器在兩個跨主機(jī)進(jìn)行通信的時候,是使用overlay network這個網(wǎng)絡(luò)模式進(jìn)行通信,如果使用host也可以實現(xiàn)跨主機(jī)進(jìn)行通信,直接使用這個物理的ip地址就可以進(jìn)行通信,overlay它會虛擬出一個網(wǎng)絡(luò)比如10.0.9.3這個ip地址,在這個overlay網(wǎng)絡(luò)模式里面,有一個類似于服務(wù)網(wǎng)關(guān)的地址,然后把這個包轉(zhuǎn)發(fā)到物理服務(wù)器這個地址,最終通過路由和交換,到達(dá)另一個服務(wù)器的ip地址。
bridge模式
當(dāng)Docker進(jìn)程啟動時,會在主機(jī)上創(chuàng)建一個名為docker0的虛擬網(wǎng)橋,此主機(jī)上啟動的Docker容器會連接到這個虛擬網(wǎng)橋上,虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,這樣主機(jī)上的所有容器就通過交換機(jī)連在了一個二層網(wǎng)絡(luò)中
從docker0子網(wǎng)中分配一個IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān),在主機(jī)上創(chuàng)建一對虛擬網(wǎng)卡veth pair設(shè)備,Docker將veth pair設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0(容器的網(wǎng)卡),另一端放在主機(jī)中,以vethxxx這樣類似的名字命名,并將這個網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中。可以通過brctl show命令查看
bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不寫–net參數(shù),就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規(guī)則,實現(xiàn)端口轉(zhuǎn)發(fā)功能??梢允褂胕ptables -t nat -vnL查看。
bridge模式如下圖所示
我們的網(wǎng)絡(luò)結(jié)構(gòu)
下圖是我們自己的網(wǎng)絡(luò)結(jié)構(gòu),我們是通過宿主機(jī)訪問Mysql容器的,剛才我們學(xué)過,默認(rèn)Docker已經(jīng)接入了一個名字叫
bridge
的橋接網(wǎng)絡(luò)
我們可以讓我們的網(wǎng)絡(luò)直接接入橋接網(wǎng)絡(luò),例如下圖
創(chuàng)建網(wǎng)絡(luò)
查看網(wǎng)絡(luò)列表
可以通過
docker network ls
命令查看網(wǎng)絡(luò)列表
# 查看網(wǎng)絡(luò)列表
docker network ls
上面就是容器默認(rèn)幾種網(wǎng)絡(luò)
創(chuàng)建一個橋接網(wǎng)絡(luò)
默認(rèn)容器啟動會自動默認(rèn)接入
bridge
的橋接網(wǎng)絡(luò),為了區(qū)分我們的服務(wù)也防止各種網(wǎng)絡(luò)問題,我們創(chuàng)建一個專用網(wǎng)絡(luò),可以通過docker network create 網(wǎng)絡(luò)名稱
來創(chuàng)建一個默認(rèn)的橋接網(wǎng)絡(luò)
# 創(chuàng)建一個橋接網(wǎng)絡(luò)
docker network create learn-docker-network
# 查看網(wǎng)絡(luò)列表
docker network ls
服務(wù)接入網(wǎng)絡(luò)
停止并刪除原有容器
停止和刪除我們的微服務(wù)以及mysql服務(wù)
# 刪除當(dāng)前運(yùn)行中的容器
docker rm -f learn-docker-storage nacos mysql
創(chuàng)建MySQL
因為我們的微服務(wù)依賴MySQL先啟動MySQL并接入網(wǎng)絡(luò),因為MySQL不需要通過宿主機(jī)訪問,所有也不需要映射端口了,–network 是配置接入哪一個網(wǎng)絡(luò)
docker run -d \\
-v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ \\
-v /tmp/data/mysql:/var/lib/mysql \\
-e MYSQL_ROOT_PASSWORD=root \\
--name mysql --network=learn-docker-network \\
mysql:5.7.38
這樣我們就把我們的MySQL服務(wù)啟動起來了并且加入了learn-docker-network的網(wǎng)絡(luò)
創(chuàng)建Nacos
我們的nacos是需要暴漏端口的,因為我們需要外部能夠看到nacos頁面,但是我們也需要我們的nacos連接到當(dāng)前網(wǎng)絡(luò)
docker run -d \\
--network=learn-docker-network \\
--name nacos --env MODE=standalone \\
nacos/nacos-server
查看網(wǎng)絡(luò)詳情
可以通過
docker network inspect 網(wǎng)絡(luò)名稱
可以查看當(dāng)前的網(wǎng)絡(luò)的詳細(xì)信息
docker network inspect learn-docker-network|grep Containers -A 20
修改微服務(wù)配置
因為需要使用自定義網(wǎng)絡(luò)訪問mysql容器以及nacos容器,需要修改微服務(wù)數(shù)據(jù)庫連接地址,
docker 網(wǎng)絡(luò)訪問 可以通過IP或者通過服務(wù)名稱都是可以的,這里我們通過服務(wù)名稱訪問,因為我們使用了maven打包的方式,我們只需要將pom文件修改就可以
<properties><mysql.addr>mysql:3306</mysql.addr><nacos.addr>nacos:8848</nacos.addr>
</properties>
修改完成后進(jìn)行編譯項目
這里將數(shù)據(jù)庫連接地址改為mysql容器的服務(wù)名稱
mysql
,nacos的連接地址變?yōu)榱?code>nacos
重新打包服務(wù)
將打包的文件上傳服務(wù)器后按照上面步驟同上面打包,打包版本為 0.0.3
docker build -t learn-docker-storage:0.0.3 .
創(chuàng)建微服務(wù)
下面就按部就班的創(chuàng)建微服務(wù)就可以,只是注意需要加入網(wǎng)絡(luò),這里這個端口需要映射外網(wǎng)訪問
docker run -d \\
-v /tmp/data/logs:/logs \\
-p 8003:8003 \\
--name learn-docker-storage \\
--network=learn-docker-network \\
learn-docker-storage:0.0.3
測試微服務(wù)
到現(xiàn)在微服務(wù)已經(jīng)啟動,我們嘗試訪問以下
curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool
訪問測試數(shù)據(jù)沒有問題,到現(xiàn)在我們服務(wù)已經(jīng)搭建完成,并且使用網(wǎng)絡(luò)進(jìn)行了優(yōu)化