1、了解Docker的前生LXC
LXC為L(zhǎng)inux Container的簡(jiǎn)寫(xiě)?梢蕴峁┹p量級(jí)的虛擬化,以便隔離進(jìn)程和資源,而且不需要提供指令解釋機(jī)制以及全虛擬化的其他復(fù)雜性。相當(dāng)于C++中的NameSpace。容器有效地將由單個(gè)操作系統(tǒng)管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有沖突的資源使用需求。
與傳統(tǒng)虛擬化技術(shù)相比,它的優(yōu)勢(shì)在于:
- 與宿主機(jī)使用同一個(gè)內(nèi)核,性能損耗。
- 不需要指令級(jí)模擬;
- 不需要即時(shí)(Just-in-time)編譯;
- 容器可以在CPU核心的本地運(yùn)行指令,不需要任何專(zhuān)門(mén)的解釋機(jī)制;
- 避免了準(zhǔn)虛擬化和系統(tǒng)調(diào)用替換中的復(fù)雜性;
- 輕量級(jí)隔離,在隔離的同時(shí)還提供共享機(jī)制,以實(shí)現(xiàn)容器與宿主機(jī)的資源共享。
總結(jié):Linux Container是一種輕量級(jí)的虛擬化的手段。
Linux Container提供了在單一可控主機(jī)節(jié)點(diǎn)上支持多個(gè)相互隔離的server container同時(shí)執(zhí)行的機(jī)制。Linux Container有點(diǎn)像chroot,提供了一個(gè)擁有自己進(jìn)程和網(wǎng)絡(luò)空間的虛擬環(huán)境,但又有別于虛擬機(jī),因?yàn)閘xc是一種操作系統(tǒng)層次上的資源的虛擬化。
2、LXC與docker什么關(guān)系?
docker并不是LXC替代品,docker底層使用了LXC來(lái)實(shí)現(xiàn),LXC將linux進(jìn)程沙盒化,使得進(jìn)程之間相互隔離,并且能夠課哦內(nèi)閣制各進(jìn)程的資源分配。
在LXC的基礎(chǔ)之上,docker提供了一系列更強(qiáng)大的功能。
3、什么是docker
- docker是一個(gè)開(kāi)源的應(yīng)用容器引擎,基于go語(yǔ)言開(kāi)發(fā)并遵循了apache2.0協(xié)議開(kāi)源。
- docker可以讓開(kāi)發(fā)者打包他們的應(yīng)用以及依賴(lài)包到一個(gè)輕量級(jí)、可移植的容器中,然后發(fā)布到任何流行的linux服務(wù)器,也可以實(shí)現(xiàn)虛擬化。
- 容器是完全使用沙箱機(jī)制,相互之間不會(huì)有任何接口(類(lèi)iphone的app),并且容器開(kāi)銷(xiāo)極其低。
4、docker官方文檔
https://docs.docker.com/
5、為什么docker越來(lái)越受歡迎
官方話語(yǔ):
容器化越來(lái)越受歡迎,因?yàn)槿萜魇牵?/div>
- 靈活:即使是最復(fù)雜的應(yīng)用也可以集裝箱化。
- 輕量級(jí):容器利用并共享主機(jī)內(nèi)核。
- 可互換:您可以即時(shí)部署更新和升級(jí)。
- 便攜式:您可以在本地構(gòu)建,部署到云,并在任何地方運(yùn)行。
- 可擴(kuò)展:您可以增加并自動(dòng)分發(fā)容器副本。
- 可堆疊:您可以垂直和即時(shí)堆疊服務(wù)。
鏡像和容器(contalners)
通過(guò)鏡像啟動(dòng)一個(gè)容器,一個(gè)鏡像是一個(gè)可執(zhí)行的包,其中包括運(yùn)行應(yīng)用程序所需要的所有內(nèi)容包含代碼,運(yùn)行時(shí)間,庫(kù)、環(huán)境變量、和配置文件。
容器是鏡像的運(yùn)行實(shí)例,當(dāng)被運(yùn)行時(shí)有鏡像狀態(tài)和用戶進(jìn)程,可以使用docker ps 查看。
容器和虛擬機(jī)
容器時(shí)在linux上本機(jī)運(yùn)行,并與其他容器共享主機(jī)的內(nèi)核,它運(yùn)行的一個(gè)獨(dú)立的進(jìn)程,不占用其他任何可執(zhí)行文件的內(nèi)存,非常輕量。
虛擬機(jī)運(yùn)行的是一個(gè)完成的操作系統(tǒng),通過(guò)虛擬機(jī)管理程序?qū)χ鳈C(jī)資源進(jìn)行虛擬訪問(wèn),相比之下需要的資源更多。
6、docker版本
- Docker Community Edition(CE)社區(qū)版
- Enterprise Edition(EE) 商業(yè)版
7、docker和openstack的幾項(xiàng)對(duì)比
8、容器在內(nèi)核中支持2種重要技術(shù)
docker本質(zhì)就是宿主機(jī)的一個(gè)進(jìn)程,docker是通過(guò)namespace實(shí)現(xiàn)資源隔離,通過(guò)cgroup實(shí)現(xiàn)資源限制,通過(guò)寫(xiě)時(shí)復(fù)制技術(shù)(copy-on-write)實(shí)現(xiàn)了高效的文件操作(類(lèi)似虛擬機(jī)的磁盤(pán)比如分配500g并不是實(shí)際占用物理磁盤(pán)500g)
1)namespaces 名稱(chēng)空間
2)control Group 控制組
cgroup的特點(diǎn)是:
- cgroup的api以一個(gè)偽文件系統(tǒng)的實(shí)現(xiàn)方式,用戶的程序可以通過(guò)文件系統(tǒng)實(shí)現(xiàn)cgroup的組件管理
- cgroup的組件管理操作單元可以細(xì)粒度到線程級(jí)別,另外用戶可以創(chuàng)建和銷(xiāo)毀cgroup,從而實(shí)現(xiàn)資源載分配和再利用
所有資源管理的功能都以子系統(tǒng)的方式實(shí)現(xiàn),接口統(tǒng)一子任務(wù)創(chuàng)建之初與其父任務(wù)處于同一個(gè)cgroup的控制組
四大功能:
- 資源限制:可以對(duì)任務(wù)使用的資源總額進(jìn)行限制
- 優(yōu)先級(jí)分配:通過(guò)分配的cpu時(shí)間片數(shù)量以及磁盤(pán)IO帶寬大小,實(shí)際上相當(dāng)于控制了任務(wù)運(yùn)行優(yōu)先級(jí)
- 資源統(tǒng)計(jì):可以統(tǒng)計(jì)系統(tǒng)的資源使用量,如cpu時(shí)長(zhǎng),內(nèi)存用量等
- 任務(wù)控制:cgroup可以對(duì)任務(wù)執(zhí)行掛起、恢復(fù)等操作
9、了解docker三個(gè)重要概念
1)image鏡像
docker鏡像就是一個(gè)只讀模板,比如,一個(gè)鏡像可以包含一個(gè)完整的centos,里面僅安裝apache或用戶的其他應(yīng)用,鏡像可以用來(lái)創(chuàng)建docker容器,另外docker提供了一個(gè)很簡(jiǎn)單的機(jī)制來(lái)創(chuàng)建鏡像或者更新現(xiàn)有的鏡像,用戶甚至可以直接從其他人那里下周一個(gè)已經(jīng)做好的鏡像來(lái)直接使用
2)container容器
docker利用容器來(lái)運(yùn)行應(yīng)用,容器是從鏡像創(chuàng)建的運(yùn)行實(shí)例,它可以被啟動(dòng),開(kāi)始、停止、刪除、每個(gè)容器都是互相隔離的,保證安全的平臺(tái),可以吧容器看做是要給簡(jiǎn)易版的linux環(huán)境(包括root用戶權(quán)限、鏡像空間、用戶空間和網(wǎng)絡(luò)空間等)和運(yùn)行再其中的應(yīng)用程序
3)repostory倉(cāng)庫(kù)
倉(cāng)庫(kù)是集中存儲(chǔ)鏡像文件的滄桑,registry是倉(cāng)庫(kù)主從服務(wù)器,實(shí)際上參考注冊(cè)服務(wù)器上存放著多個(gè)倉(cāng)庫(kù),每個(gè)倉(cāng)庫(kù)中又包含了多個(gè)鏡像,每個(gè)鏡像有不同的標(biāo)簽(tag)
倉(cāng)庫(kù)分為兩種,公有參考,和私有倉(cāng)庫(kù),最大的公開(kāi)倉(cāng)庫(kù)是docker Hub,存放了數(shù)量龐大的鏡像供用戶下周,國(guó)內(nèi)的docker pool,這里倉(cāng)庫(kù)的概念與Git類(lèi)似,registry可以理解為github這樣的托管服務(wù)
10、docker的主要用途
官方就是Bulid 、ship、run any app/any where,編譯、裝載、運(yùn)行、任何app/在任意地放都能運(yùn)行。
就是實(shí)現(xiàn)了應(yīng)用的封裝、部署、運(yùn)行的生命周期管理只要在glibc的環(huán)境下,都可以運(yùn)行。
運(yùn)維生成環(huán)境中:docker化。
- 發(fā)布服務(wù)不用擔(dān)心服務(wù)器的運(yùn)行環(huán)境,所有的服務(wù)器都是自動(dòng)分配docker,自動(dòng)部署,自動(dòng)安裝,自動(dòng)運(yùn)行
- 再不用擔(dān)心其他服務(wù)引擎的磁盤(pán)問(wèn)題,cpu問(wèn)題,系統(tǒng)問(wèn)題了
- 資源利用更出色
- 自動(dòng)遷移,可以制作鏡像,遷移使用自定義的鏡像即可遷移,不會(huì)出現(xiàn)什么問(wèn)題
- 管理更加方便了
11、docker改變了什么
- 面向產(chǎn)品:產(chǎn)品交付
- 面向開(kāi)發(fā):簡(jiǎn)化環(huán)境配置
- 面向測(cè)試:多版本測(cè)試
- 面向運(yùn)維:環(huán)境一致性
- 面向架構(gòu):自動(dòng)化擴(kuò)容(微服務(wù))
二、docker架構(gòu)
1、總體架構(gòu)
- distribution 負(fù)責(zé)與docker registry交互,上傳洗澡鏡像以及v2 registry 有關(guān)的源數(shù)據(jù)
- registry負(fù)責(zé)docker registry有關(guān)的身份認(rèn)證、鏡像查找、鏡像驗(yàn)證以及管理registry mirror等交互操作
- image 負(fù)責(zé)與鏡像源數(shù)據(jù)有關(guān)的存儲(chǔ)、查找,鏡像層的索引、查找以及鏡像tar包有關(guān)的導(dǎo)入、導(dǎo)出操作
- reference負(fù)責(zé)存儲(chǔ)本地所有鏡像的repository和tag名,并維護(hù)與鏡像id之間的映射關(guān)系
- layer模塊負(fù)責(zé)與鏡像層和容器層源數(shù)據(jù)有關(guān)的增刪改查,并負(fù)責(zé)將鏡像層的增刪改查映射到實(shí)際存儲(chǔ)鏡像層文件的graphdriver模塊
- graghdriver是所有與容器鏡像相關(guān)操作的執(zhí)行者
2、docker架構(gòu)2
如果覺(jué)得上面架構(gòu)圖比較亂可以看這個(gè)架構(gòu):
從上圖不難看出,用戶是使用Docker Client與Docker Daemon建立通信,并發(fā)送請(qǐng)求給后者。
而Docker Daemon作為Docker架構(gòu)中的主體部分,首先提供Server的功能使其可以接受Docker Client的請(qǐng)求;而后Engine執(zhí)行Docker內(nèi)部的一系列工作,每一項(xiàng)工作都是以一個(gè)Job的形式的存在。
Job的運(yùn)行過(guò)程中,當(dāng)需要容器鏡像時(shí),則從Docker Registry中下載鏡像,并通過(guò)鏡像管理驅(qū)動(dòng)graphdriver將下載鏡像以Graph的形式存儲(chǔ);當(dāng)需要為Docker創(chuàng)建網(wǎng)絡(luò)環(huán)境時(shí),通過(guò)網(wǎng)絡(luò)管理驅(qū)動(dòng)networkdriver創(chuàng)建并配置Docker容器網(wǎng)絡(luò)環(huán)境;當(dāng)需要限制Docker容器運(yùn)行資源或執(zhí)行用戶指令等操作時(shí),則通過(guò)execdriver來(lái)完成。
而libcontainer是一項(xiàng)獨(dú)立的容器管理包,networkdriver以及execdriver都是通過(guò)libcontainer來(lái)實(shí)現(xiàn)具體對(duì)容器進(jìn)行的操作。當(dāng)執(zhí)行完運(yùn)行容器的命令后,一個(gè)實(shí)際的Docker容器就處于運(yùn)行狀態(tài),該容器擁有獨(dú)立的文件系統(tǒng),獨(dú)立并且安全的運(yùn)行環(huán)境等。
3、docker架構(gòu)3
再來(lái)看看另外一個(gè)架構(gòu),這個(gè)個(gè)架構(gòu)就簡(jiǎn)單清晰指明了server/client交互,容器和鏡像、數(shù)據(jù)之間的一些聯(lián)系。
這個(gè)架構(gòu)圖更加清晰了架構(gòu)
docker daemon就是docker的守護(hù)進(jìn)程即server端,可以是遠(yuǎn)程的,也可以是本地的,這個(gè)不是C/S架構(gòu)嗎,客戶端Docker client 是通過(guò)rest api進(jìn)行通信。
docker cli 用來(lái)管理容器和鏡像,客戶端提供一個(gè)只讀鏡像,然后通過(guò)鏡像可以創(chuàng)建多個(gè)容器,這些容器可以只是一個(gè)RFS(Root file system根文件系統(tǒng)),也可以ishi一個(gè)包含了用戶應(yīng)用的RFS,容器再docker client中只是要給進(jìn)程,兩個(gè)進(jìn)程之間互不可見(jiàn)。
用戶不能與server直接交互,但可以通過(guò)與容器這個(gè)橋梁來(lái)交互,由于是操作系統(tǒng)級(jí)別的虛擬技術(shù),中間的損耗幾乎可以不計(jì)。
三、docker架構(gòu)2各個(gè)模塊的功能(帶完善)
主要的模塊有:Docker Client、Docker Daemon、Docker Registry、Graph、Driver、libcontainer以及Docker container。
1、docker client
docker client 是docker架構(gòu)中用戶用來(lái)和docker daemon建立通信的客戶端,用戶使用的可執(zhí)行文件為docker,通過(guò)docker命令行工具可以發(fā)起眾多管理container的請(qǐng)求。
docker client可以通過(guò)一下三宗方式和docker daemon建立通信:tcp://host:port;unix:path_to_socket;fd://socketfd。,docker client可以通過(guò)設(shè)置命令行flag參數(shù)的形式設(shè)置安全傳輸層協(xié)議(TLS)的有關(guān)參數(shù),保證傳輸?shù)陌踩?/div>
docker client發(fā)送容器管理請(qǐng)求后,由docker daemon接受并處理請(qǐng)求,當(dāng)docker client 接收到返回的請(qǐng)求相應(yīng)并簡(jiǎn)單處理后,docker client 一次完整的生命周期就結(jié)束了,當(dāng)需要繼續(xù)發(fā)送容器管理請(qǐng)求時(shí),用戶必須再次通過(guò)docker可以執(zhí)行文件創(chuàng)建docker client。
2、docker daemon
docker daemon 是docker架構(gòu)中一個(gè)常駐在后臺(tái)的系統(tǒng)進(jìn)程,功能是:接收處理docker client發(fā)送的請(qǐng)求。該守護(hù)進(jìn)程在后臺(tái)啟動(dòng)一個(gè)server,server負(fù)載接受docker client發(fā)送的請(qǐng)求;接受請(qǐng)求后,server通過(guò)路由與分發(fā)調(diào)度,找到相應(yīng)的handler來(lái)執(zhí)行請(qǐng)求。
docker daemon啟動(dòng)所使用的可執(zhí)行文件也為docker,與docker client啟動(dòng)所使用的可執(zhí)行文件docker相同,在docker命令執(zhí)行時(shí),通過(guò)傳入的參數(shù)來(lái)判別docker daemon與docker client。
docker daemon的架構(gòu)可以分為:docker server、engine、job。daemon
3、docker server
docker server在docker架構(gòu)中時(shí)專(zhuān)門(mén)服務(wù)于docker client的server,該server的功能時(shí):接受并調(diào)度分發(fā)docker client發(fā)送的請(qǐng)求,架構(gòu)圖如下:
- 在Docker的啟動(dòng)過(guò)程中,通過(guò)包gorilla/mux(golang的類(lèi)庫(kù)解析),創(chuàng)建了一個(gè)mux.Router,提供請(qǐng)求的路由功能。在Golang中,gorilla/mux是一個(gè)強(qiáng)大的URL路由器以及調(diào)度分發(fā)器。該mux.Router中添加了眾多的路由項(xiàng),每一個(gè)路由項(xiàng)由HTTP請(qǐng)求方法(PUT、POST、GET或DELETE)、URL、Handler三部分組成。
- 若Docker Client通過(guò)HTTP的形式訪問(wèn)Docker Daemon,創(chuàng)建完mux.Router之后,Docker將Server的監(jiān)聽(tīng)地址以及mux.Router作為參數(shù),創(chuàng)建一個(gè)httpSrv=http.Server{},最終執(zhí)行httpSrv.Serve()為請(qǐng)求服務(wù)。
- 在Server的服務(wù)過(guò)程中,Server在listener上接受Docker Client的訪問(wèn)請(qǐng)求,并創(chuàng)建一個(gè)全新的goroutine來(lái)服務(wù)該請(qǐng)求。在goroutine中,首先讀取請(qǐng)求內(nèi)容,然后做解析工作,接著找到相應(yīng)的路由項(xiàng),隨后調(diào)用相應(yīng)的Handler來(lái)處理該請(qǐng)求,最后Handler處理完請(qǐng)求之后回復(fù)該請(qǐng)求。
需要注意的是:Docker Server的運(yùn)行在Docker的啟動(dòng)過(guò)程中,是靠一個(gè)名為”serveapi”的job的運(yùn)行來(lái)完成的。原則上,Docker Server的運(yùn)行是眾多job中的一個(gè),但是為了強(qiáng)調(diào)Docker Server的重要性以及為后續(xù)job服務(wù)的重要特性,將該”serveapi”的job單獨(dú)抽離出來(lái)分析,理解為Docker Server。
4、engine
Engine是Docker架構(gòu)中的運(yùn)行引擎,同時(shí)也Docker運(yùn)行的核心模塊。它扮演Docker container存儲(chǔ)倉(cāng)庫(kù)的角色,并且通過(guò)執(zhí)行job的方式來(lái)操縱管理這些容器。
在Engine數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)與實(shí)現(xiàn)過(guò)程中,有一個(gè)handler對(duì)象。該handler對(duì)象存儲(chǔ)的都是關(guān)于眾多特定job的handler處理訪問(wèn)。舉例說(shuō)明,Engine的handler對(duì)象中有一項(xiàng)為:{“create”: daemon.ContainerCreate,},則說(shuō)明當(dāng)名為”create”的job在運(yùn)行時(shí),執(zhí)行的是daemon.ContainerCreate的handler。
5、job
一個(gè)Job可以認(rèn)為是Docker架構(gòu)中Engine內(nèi)部最基本的工作執(zhí)行單元。Docker可以做的每一項(xiàng)工作,都可以抽象為一個(gè)job。例如:在容器內(nèi)部運(yùn)行一個(gè)進(jìn)程,這是一個(gè)job;創(chuàng)建一個(gè)新的容器,這是一個(gè)job,從Internet上下載一個(gè)文檔,這是一個(gè)job;包括之前在Docker Server部分說(shuō)過(guò)的,創(chuàng)建Server服務(wù)于HTTP的API,這也是一個(gè)job,等等。
Job的設(shè)計(jì)者,把Job設(shè)計(jì)得與Unix進(jìn)程相仿。比如說(shuō):Job有一個(gè)名稱(chēng),有參數(shù),有環(huán)境變量,有標(biāo)準(zhǔn)的輸入輸出,有錯(cuò)誤處理,有返回狀態(tài)等。
6、docker registry
Docker Registry是一個(gè)存儲(chǔ)容器鏡像的倉(cāng)庫(kù)。而容器鏡像是在容器被創(chuàng)建時(shí),被加載用來(lái)初始化容器的文件架構(gòu)與目錄。
在Docker的運(yùn)行過(guò)程中,Docker Daemon會(huì)與Docker Registry通信,并實(shí)現(xiàn)搜索鏡像、下載鏡像、上傳鏡像三個(gè)功能,這三個(gè)功能對(duì)應(yīng)的job名稱(chēng)分別為”search”,”pull” 與 “push”。
其中,在Docker架構(gòu)中,Docker可以使用公有的Docker Registry,即大家熟知的Docker Hub,如此一來(lái),Docker獲取容器鏡像文件時(shí),必須通過(guò)互聯(lián)網(wǎng)訪問(wèn)Docker Hub;同時(shí)Docker也允許用戶構(gòu)建本地私有的Docker Registry,這樣可以保證容器鏡像的獲取在內(nèi)網(wǎng)完成。
7、Graph
Graph在Docker架構(gòu)中扮演已下載容器鏡像的保管者,以及已下載容器鏡像之間關(guān)系的記錄者。一方面,Graph存儲(chǔ)著本地具有版本信息的文件系統(tǒng)鏡像,另一方面也通過(guò)GraphDB記錄著所有文件系統(tǒng)鏡像彼此之間的關(guān)系。
Graph的架構(gòu)如下:
其中,GraphDB是一個(gè)構(gòu)建在SQLite之上的小型圖數(shù)據(jù)庫(kù),實(shí)現(xiàn)了節(jié)點(diǎn)的命名以及節(jié)點(diǎn)之間關(guān)聯(lián)關(guān)系的記錄。它僅僅實(shí)現(xiàn)了大多數(shù)圖數(shù)據(jù)庫(kù)所擁有的一個(gè)小的子集,但是提供了簡(jiǎn)單的接口表示節(jié)點(diǎn)之間的關(guān)系。
同時(shí)在Graph的本地目錄中,關(guān)于每一個(gè)的容器鏡像,具體存儲(chǔ)的信息有:該容器鏡像的元數(shù)據(jù),容器鏡像的大小信息,以及該容器鏡像所代表的具體rootfs。
8、driver
Driver是Docker架構(gòu)中的驅(qū)動(dòng)模塊。通過(guò)Driver驅(qū)動(dòng),Docker可以實(shí)現(xiàn)對(duì)Docker容器執(zhí)行環(huán)境的定制。由于Docker運(yùn)行的生命周期中,并非用戶所有的操作都是針對(duì)Docker容器的管理,另外還有關(guān)于Docker運(yùn)行信息的獲取,Graph的存儲(chǔ)與記錄等。因此,為了將Docker容器的管理從Docker Daemon內(nèi)部業(yè)務(wù)邏輯中區(qū)分開(kāi)來(lái),設(shè)計(jì)了Driver層驅(qū)動(dòng)來(lái)接管所有這部分請(qǐng)求。
在Docker Driver的實(shí)現(xiàn)中,可以分為以下三類(lèi)驅(qū)動(dòng):graphdriver、networkdriver和execdriver。
graphdriver主要用于完成容器鏡像的管理,包括存儲(chǔ)與獲取。即當(dāng)用戶需要下載指定的容器鏡像時(shí),graphdriver將容器鏡像存儲(chǔ)在本地的指定目錄;同時(shí)當(dāng)用戶需要使用指定的容器鏡像來(lái)創(chuàng)建容器的rootfs時(shí),graphdriver從本地鏡像存儲(chǔ)目錄中獲取指定的容器鏡像。
在graphdriver的初始化過(guò)程之前,有4種文件系統(tǒng)或類(lèi)文件系統(tǒng)在其內(nèi)部注冊(cè),它們分別是aufs、btrfs、vfs和devmapper。而Docker在初始化之時(shí),通過(guò)獲取系統(tǒng)環(huán)境變量”DOCKER_DRIVER”來(lái)提取所使用driver的指定類(lèi)型。而之后所有的graph操作,都使用該driver來(lái)執(zhí)行。
graphdriver的架構(gòu)如下:
networkdriver的用途是完成Docker容器網(wǎng)絡(luò)環(huán)境的配置,其中包括Docker啟動(dòng)時(shí)為Docker環(huán)境創(chuàng)建網(wǎng)橋;Docker容器創(chuàng)建時(shí)為其創(chuàng)建專(zhuān)屬虛擬網(wǎng)卡設(shè)備;以及為Docker容器分配IP、端口并與宿主機(jī)做端口映射,設(shè)置容器防火墻策略等。networkdriver的架構(gòu)如下:
execdriver作為Docker容器的執(zhí)行驅(qū)動(dòng),負(fù)責(zé)創(chuàng)建容器運(yùn)行命名空間,負(fù)責(zé)容器資源使用的統(tǒng)計(jì)與限制,負(fù)責(zé)容器內(nèi)部進(jìn)程的真正運(yùn)行等。在execdriver的實(shí)現(xiàn)過(guò)程中,原先可以使用LXC驅(qū)動(dòng)調(diào)用LXC的接口,來(lái)操縱容器的配置以及生命周期,而現(xiàn)在execdriver默認(rèn)使用native驅(qū)動(dòng),不依賴(lài)于LXC。具體體現(xiàn)在Daemon啟動(dòng)過(guò)程中加載的ExecDriverflag參數(shù),該參數(shù)在配置文件已經(jīng)被設(shè)為”native”。這可以認(rèn)為是Docker在1.2版本上一個(gè)很大的改變,或者說(shuō)Docker實(shí)現(xiàn)跨平臺(tái)的一個(gè)先兆。execdriver架構(gòu)如下:
9、libcontainer
libcontainer是Docker架構(gòu)中一個(gè)使用Go語(yǔ)言設(shè)計(jì)實(shí)現(xiàn)的庫(kù),設(shè)計(jì)初衷是希望該庫(kù)可以不依靠任何依賴(lài),直接訪問(wèn)內(nèi)核中與容器相關(guān)的API。
正是由于libcontainer的存在,Docker可以直接調(diào)用libcontainer,而最終操縱容器的namespace、cgroups、apparmor、網(wǎng)絡(luò)設(shè)備以及防火墻規(guī)則等。這一系列操作的完成都不需要依賴(lài)LXC或者其他包。libcontainer架構(gòu)如下:
另外,libcontainer提供了一整套標(biāo)準(zhǔn)的接口來(lái)滿足上層對(duì)容器管理的需求。或者說(shuō),libcontainer屏蔽了Docker上層對(duì)容器的直接管理。又由于libcontainer使用Go這種跨平臺(tái)的語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn),且本身又可以被上層多種不同的編程語(yǔ)言訪問(wèn),因此很難說(shuō),未來(lái)的Docker就一定會(huì)緊緊地和Linux捆綁在一起。而于此同時(shí),Microsoft在其著名云計(jì)算平臺(tái)Azure中,也添加了對(duì)Docker的支持,可見(jiàn)Docker的開(kāi)放程度與業(yè)界的火熱度。
暫不談Docker,由于libcontainer的功能以及其本身與系統(tǒng)的松耦合特性,很有可能會(huì)在其他以容器為原型的平臺(tái)出現(xiàn),同時(shí)也很有可能催生出云計(jì)算領(lǐng)域全新的項(xiàng)目。
10、docker container
Docker container(Docker容器)是Docker架構(gòu)中服務(wù)交付的最終體現(xiàn)形式。
Docker按照用戶的需求與指令,訂制相應(yīng)的Docker容器:- 用戶通過(guò)指定容器鏡像,使得Docker容器可以自定義rootfs等文件系統(tǒng);
- 用戶通過(guò)指定計(jì)算資源的配額,使得Docker容器使用指定的計(jì)算資源;
- 用戶通過(guò)配置網(wǎng)絡(luò)及其安全策略,使得Docker容器擁有獨(dú)立且安全的網(wǎng)絡(luò)環(huán)境;
- 用戶通過(guò)指定運(yùn)行的命令,使得Docker容器執(zhí)行指定的工作。
四、docker簡(jiǎn)單使用
1、安裝
- yum install docker -y
- systemctl enable docker
- systemctl start docker
注意:?jiǎn)?dòng)前應(yīng)當(dāng)設(shè)置源
vim /usr/lib/systemd/system/docker.service
這里設(shè)置阿里的,注冊(cè)阿里云賬戶號(hào)每個(gè)用戶都有:
[root@web1 ~]# vim /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target
Wants=docker-storage-setup.service
Requires=docker-cleanup.timer
[Service]
Type=notify
NotifyAccess=main
EnvironmentFile=-/run/containers/registries.conf
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
Environment=GOTRACEBACK=crash
Environment=DOCKER_HTTP_HOST_COMPAT=1
Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
ExecStart=/usr/bin/dockerd-current --registry-mirror=https://rfcod7oz.mirror.aliyuncs.com #這個(gè)值可以登陸阿里云賬號(hào)請(qǐng)參考下圖
--add-runtime docker-runc=/usr/libexec/docker/docker-runc-current
--default-runtime=docker-runc
--exec-opt native.cgroupdriver=systemd
--userland-proxy-path=/usr/libexec/docker/docker-proxy-current
--init-path=/usr/libexec/docker/docker-init-current
--seccomp-profile=/etc/docker/seccomp.json
$OPTIONS
$DOCKER_STORAGE_OPTIONS
$DOCKER_NETWORK_OPTIONS
$ADD_REGISTRY
$BLOCK_REGISTRY
$INSECURE_REGISTRY
$REGISTRIES
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
Restart=on-abnormal
KillMode=process
[Install]
WantedBy=multi-user.target
2、docker版本查詢
[root@web1 ~]# docker version
Client:
Version: 1.13.1
API version: 1.26
Package version: docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64
Go version: go1.10.3
Git commit: b2f74b2/1.13.1
Built: Wed May 1 14:55:20 2019
OS/Arch: linux/amd64
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Package version: docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64
Go version: go1.10.3
Git commit: b2f74b2/1.13.1
Built: Wed May 1 14:55:20 2019
OS/Arch: linux/amd64
Experimental: false
3、搜索下載鏡像
docker pull alpine #下載鏡像
docker search nginx #查看鏡像
docker pull nginx
4、查看已經(jīng)下載的鏡像
[root@web1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zxg/my_nginx v1 b164f4c07c64 8 days ago 126 MB
zxg/my_nginx latest f07837869dfc 8 days ago 126 MB
docker.io/nginx latest e445ab08b2be 2 weeks ago 126 MB
docker.io/alpine latest b7b28af77ffe 3 weeks ago 5.58 MB
docker.io/centos latest 9f38484d220f 4 months ago 202 MB
[root@web1 ~]#
5、導(dǎo)出鏡像
docker save nginx >/tmp/nginx.tar.gz
6、刪除鏡像
docker rmi -f nginx
7、導(dǎo)入鏡像
docker load
8、默認(rèn)配置文件
vim /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target
Wants=docker-storage-setup.service
Requires=docker-cleanup.timer
[Service]
Type=notify
NotifyAccess=main
EnvironmentFile=-/run/containers/registries.conf
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
Environment=GOTRACEBACK=crash
Environment=DOCKER_HTTP_HOST_COMPAT=1
Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
ExecStart=/usr/bin/dockerd-current --registry-mirror=https://rfcod7oz.mirror.aliyuncs.com
--add-runtime docker-runc=/usr/libexec/docker/docker-runc-current
--default-runtime=docker-runc
--exec-opt native.cgroupdriver=systemd
--userland-proxy-path=/usr/libexec/docker/docker-proxy-current
--init-path=/usr/libexec/docker/docker-init-current
--seccomp-profile=/etc/docker/seccomp.json
$OPTIONS
$DOCKER_STORAGE_OPTIONS
$DOCKER_NETWORK_OPTIONS
$ADD_REGISTRY
$BLOCK_REGISTRY
$INSECURE_REGISTRY
$REGISTRIES
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
Restart=on-abnormal
KillMode=process
[Install]
WantedBy=multi-user.target
~
~
~
~
如果更改存儲(chǔ)目錄就添加
--graph=/opt/docker
如果更改DNS——默認(rèn)采用宿主機(jī)的dns
--dns=xxxx的方式指定
9、運(yùn)行hello world
這里用centos鏡像echo一個(gè)hello word
[root@web1 overlay2]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zxg/my_nginx v1 b164f4c07c64 8 days ago 126 MB
zxg/my_nginx latest f07837869dfc 8 days ago 126 MB
docker.io/nginx latest e445ab08b2be 2 weeks ago 126 MB
docker.io/alpine latest b7b28af77ffe 3 weeks ago 5.58 MB
docker.io/centos latest 9f38484d220f 4 months ago 202 MB
[root@web1 overlay2]# docker run centos echo "hello world"
hello world
[root@web1 overlay2]#
10、運(yùn)行一個(gè)容器-run
[root@web1 overlay2]# docker run -it alpine sh #運(yùn)行并進(jìn)入alpine
/ #
/ #
/ #
/ #
/ #
/ # ls
bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr
/ # cd tmp
/tmp # exit
后臺(tái)運(yùn)行(-d后臺(tái)運(yùn)行)(--name添加一個(gè)名字)
[root@web1 overlay2]# docker run -it -d --name test1 alpine
ac46c019b800d34c37d4f9dcd56c974cb82eca3acf185e5f8f80c8a60075e343
[root@web1 overlay2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac46c019b800 alpine "/bin/sh" 5 seconds ago Up 3 seconds test1
[root@web1 overlay2]#
還有一種-rm參數(shù),ctrl+c后就刪除,可以測(cè)試環(huán)境用,生成環(huán)境用的少
[root@web1 overlay2]# docker run -it --rm --name centos nginx
^C[root@web1 overlay2]#
##另開(kāi)一個(gè)窗口
[root@web1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3397b96ea7bd nginx "nginx -g 'daemon …" 27 seconds ago Up 25 seconds 80/tcp centos
ac46c019b800 alpine "/bin/sh" 4 minutes ago Up 4 minutes test1
[root@web1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac46c019b800 alpine "/bin/sh" 4 minutes ago Up 4 minutes test1
[root@web1 ~]#
11、如何進(jìn)入容器
三種方法,上面已經(jīng)演示了一種
第一種,需要容器本身的pid及util-linux,不推薦,暫時(shí)不演示了
第二種,不分配bash終端的一種實(shí)施操作,不推薦,這種操作如果在開(kāi)一個(gè)窗口也能看到操作的指令,所有人都能看到
[root@web1 overlay2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fc796e928d7 nginx "sh" 2 minutes ago Up 8 seconds 80/tcp mynginx
ac46c019b800 alpine "/bin/sh" 12 minutes ago Up 12 minutes test1
[root@web1 overlay2]# docker attach mynginx
#
#
#
#
# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# exit
[root@web1 overlay2]# docker attach mynginx
You cannot attach to a stopped container, start it first
[root@web1 overlay2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac46c019b800 alpine "/bin/sh" 13 minutes ago Up 13 minutes test1
[root@web1 overlay2]#
第三種:exec方式,終端時(shí)分開(kāi)的,推薦
[root@web1 overlay2]# docker exec -it mynginx sh
#
#
#
# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# exit
[root@web1 overlay2]#
[root@web1 overlay2]#
[root@web1 overlay2]#
[root@web1 overlay2]# docker pa
docker: 'pa' is not a docker command.
See 'docker --help'
[root@web1 overlay2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fc2d091cfe9 nginx "nginx -g 'daemon …" 45 seconds ago Up 43 seconds 80/tcp mynginx
ac46c019b800 alpine "/bin/sh" 16 minutes ago Up 16 minutes test1
12、查看docker進(jìn)程及刪除容器
上面已經(jīng)演示:
[root@web1 overlay2]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fc796e928d7 nginx "sh" 2 minutes ago Up 8 seconds 80/tcp mynginx
ac46c019b800 alpine "/bin/sh" 12 minutes ago Up 12 minutes test1
[root@web1 overlay2]# docker ps -a #-a :顯示所有的容器,包括未運(yùn)行的
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fc796e928d7 nginx "sh" 4 minutes ago Exited (0) About a minute ago mynginx
ac46c019b800 alpine "/bin/sh" 15 minutes ago Up 15 minutes test1
3bf234febeaa alpine "sh" 17 minutes ago Exited (0) 16 minutes ago youthful_lumiere
ab113c63f0b4 centos "echo 'hello world'" 31 minutes ago Exited (0) 31 minutes ago infallible_torvalds
b326027dcf42 zxg/my_nginx "nginx" 8 days ago Exited (0) 8 days ago my_nginx
4f1f1ca319f2 centos "bash" 8 days ago Exited (137) 8 days ago musing_lichterman
64b4e32991c7 nginx "nginx -g 'daemon …" 12 days ago Exited (0) 12 days ago mynginx1
aee506fe7b5a alpine "sh" 12 days ago Created infallible_haibt
70620c73b9a0 alpine "sh" 12 days ago Created gallant_volhard
7655cbf87bb0 alpine "sh" 12 days ago Created agitated_brahmagupta
33fb949372e8 fce289e99eb9 "/hello" 12 days ago Created elastic_dijkstra
9de47616aea4 fce289e99eb9 "/hello" 13 days ago Created confident_fermi
[root@web1 overlay2]# docker rm 9fc796e928d7 #rm時(shí)刪除一個(gè)或多個(gè)容器
9fc796e928d7
13、查看容器詳細(xì)信息
并不需要進(jìn)入到容器里面,通過(guò)查看詳細(xì)信息看到了剛才運(yùn)行的nginx,宿主機(jī)curl ip地址訪問(wèn)一下運(yùn)行情況。
[root@web1 overlay2]# docker inspect mynginx
[
{
"Id": "6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010",
"Created": "2019-08-07T08:57:48.864538933Z",
"Path": "nginx",
"Args": [
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 119948,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-08-07T08:57:49.417992182Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:e445ab08b2be8b178655b714f89e5db9504f67defd5c7408a00bade679a50d44",
"ResolvConfPath": "/var/lib/docker/containers/6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010/hostname",
"HostsPath": "/var/lib/docker/containers/6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010/hosts",
"LogPath": "",
"Name": "/mynginx",
"RestartCount": 0,
"Driver": "overlay2",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "journald",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "docker-runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": -1,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Name": "overlay2",
"Data": {
"LowerDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a-init/diff:/var/lib/docker/overlay2/d8e95505fc3894eb30b48e4b0f48ab5e89d99c09a07c79c0b057c611621e31eb/diff:/var/lib/docker/overlay2/b2a6a25974bf17398b698a27208711574be3c69a2cd06658bbe838359f373a27/diff:/var/lib/docker/overlay2/d4610bc89b3ba8ad6ab30ea895fc3a06efff15db493d86ac9bc100e04abbab67/diff",
"MergedDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a/merged",
"UpperDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a/diff",
"WorkDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a/work"
}
},
"Mounts": [],
"Config": {
"Hostname": "6fc2d091cfe9",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.17.2",
"NJS_VERSION=0.3.3",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"ArgsEscaped": true,
"Image": "nginx",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers "
},
"StopSignal": "SIGTERM"
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "3ece36008fbc5f3f46d3d251cf803c1478cc14032d74a36747e4ed8a115b81df",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": null
},
"SandboxKey": "/var/run/docker/netns/3ece36008fbc",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "898de81d97d54d2b60aeb6cc77ef1b4f9b481d1b72f542faa496494594024eac",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3", #看到ip地址
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "2edae9131e77500a56d251b94ab2cdf0bc86f8df9f2453fa46bf4bab2f7be99f",
"EndpointID": "898de81d97d54d2b60aeb6cc77ef1b4f9b481d1b72f542faa496494594024eac",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03"
}
}
}
}
]
[root@web1 overlay2]# curl 172.17.0.1 #訪問(wèn)一下
Welcome to nginx on Fedora!
This page is used to test the proper operation of the
nginx HTTP server after it has been
installed. If you can read this page, it means that the
web server installed at this site is working
properly.
Website Administrator
This is the default index.html page that
is distributed with nginx on
Fedora. It is located in
/usr/share/nginx/html.
You should now put your content in a location of
your choice and edit the root configuration
directive in the nginx
configuration file
/etc/nginx/nginx.conf.
[root@web1 overlay2]#
14、查看日志
-f 掛起這個(gè)終端,動(dòng)態(tài)查看日志
[root@web1 ~]# docker logs -f mynginx
參考文章:
參考1:https://cloud.tencent.com/developer/article/1006116
參考2:https://yq.aliyun.com/articles/65145
參考3:https://blog.51cto.com/10085711/2068290
參考4:https://www.cnblogs.com/zuxing/articles/8717415.html
【免責(zé)聲明】本文僅代表作者本人觀點(diǎn),與CTI論壇無(wú)關(guān)。CTI論壇對(duì)文中陳述、觀點(diǎn)判斷保持中立,不對(duì)所包含內(nèi)容的準(zhǔn)確性、可靠性或完整性提供任何明示或暗示的保證。請(qǐng)讀者僅作參考,并請(qǐng)自行承擔(dān)全部責(zé)任。
相關(guān)閱讀:
- ·Docker 擁抱 Kubernetes、GitHub 發(fā)布新特性......2017-10-20 10:37:05
- ·想投資容器?那你得看看這個(gè)!2017-08-31 15:37:14
- ·Docker:給云計(jì)算插上奔騰的芯2016-07-04 14:27:25
- ·Docker容器技術(shù)為何如此重要?2015-10-14 10:40:26
- ·騰訊劉永峰:Docker時(shí)代,公有云面臨的挑戰(zhàn)和機(jī)遇2014-09-29 13:16:30
- ·成功客戶體驗(yàn)的五大基石2019-08-20 11:01:20
- ·數(shù)字自助服務(wù)的做與不做2019-08-20 10:25:23
- ·如何描繪客戶體驗(yàn)的情感旅程2019-08-20 10:13:39
- ·呼叫中心的腦洞: GDPR、區(qū)塊鏈與信息共享聯(lián)盟2019-08-20 09:49:00
- ·京東云魏偉:做最懂視頻的云2019-08-19 16:20:34
評(píng)論排行
- uc營(yíng)銷(xiāo)管家——高效率的銷(xiāo)售軟件(28)
- 代替人工撥打電話的軟件:亮劍天下自動(dòng)...(15)
- 商路通技術(shù)總監(jiān)黃河專(zhuān)訪:技術(shù)上叫板的瘋子(13)
- 華晨汽車(chē)客服中心通過(guò)CC-CMM應(yīng)用級(jí)L1認(rèn)證(7)
- 因科美E350不需電話會(huì)議平臺(tái)就能實(shí)現(xiàn)多...(6)
- 小米擠下HTC,居中國(guó)消費(fèi)者常用手機(jī)第五(6)
- 億倫公司推出新版本“智能外呼營(yíng)銷(xiāo)平臺(tái)”(5)
- 小米擠下HTC,居中國(guó)消費(fèi)者常用手機(jī)第五(5)
- 技術(shù)上叫板的瘋子(5)
- 客服人生:入職凡客四年半的她,剛“被...(4)
- 騰訊EC與金倫合作 開(kāi)啟云聯(lián)絡(luò)中心新里程(4)
- 葡萄牙電信攜手華為部署LTE商用服務(wù) (4)
- 金倫企呼云呼叫中心備受媒體及用戶關(guān)注(4)
- 殺毒先鋒2.0新版發(fā)布,功能升級(jí)(4)
- 華為與瑞星建立云計(jì)算虛擬化防病毒戰(zhàn)略...(3)
- 塔迪蘭Aeonix統(tǒng)一通信和協(xié)作(UC&C)解...(3)
- 電話、電話、更多的電話:如何管理?(3)
- 《中國(guó)呼叫中心人力資源管理白皮書(shū)》出版(3)
- 未來(lái)的聯(lián)絡(luò)中心:克服商業(yè)與技術(shù)變革帶...(3)
- 搭建自動(dòng)外呼系統(tǒng)、電話營(yíng)銷(xiāo)管理系統(tǒng)、...(3)