亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么利用Docker構建開發環境

發布時間:2021-07-30 18:22:49 來源:億速云 閱讀:102 作者:chen 欄目:云計算

這篇文章主要講解了“怎么利用Docker構建開發環境”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么利用Docker構建開發環境”吧!

大背景–虛擬化技術歷史

計算機虛擬化技術由來已久,從硬件仿真到全虛擬化,再到準虛擬化和操作系統虛擬化,各種技術粉墨登場,種類繁多,說實在的有點眼花繚亂和復雜;但用戶的核心訴求一直是比較簡單的,降低信息技術(IT)的運營成本,提高資源利用率,提高安全性和可靠性等等;雖說用戶的核心訴求比較簡單,但每個時代的需求場景卻是不同的。在大型機時代,虛擬化技術被用來支持多個用戶能夠同時使用大型機,在x86架構時代,隨著企業服務的大規模部署,虛擬化技術主要是用來提高企業資源的利用率,而現如今,隨著云計算時代的到來,人們對應用的安全性、隔離性越來越高,對于部署的標準化以及虛擬機的性能要求越來越高。現如今,一種叫Linux容器的虛擬化技術逐漸得到廣泛的應用,它的優點有許多,本文不一一贅述,有太多的文章可以參考。

什么是Docker?

docker的英文本意是碼頭工人,也就是搬運工,這種搬運工搬運的是集裝箱(Container),集裝箱里面裝的可不是商品貨物,而是任意類型的App,Docker把App(叫Payload)裝在Container內,通過Linux Container技術的包裝將App變成一種標準化的、可移植的、自管理的組件,這種組件可以在你的latop上開發、調試、運行,最終非常方便和一致地運行在production環境下。

Docker的核心底層技術是LXC(Linux Container),Docker在其上面加了薄薄的一層,添加了許多有用的功能。  這篇stackoverflow上的問題和答案很好地詮釋了Docker和LXC的區別,能夠讓你更好的了解什么是Docker, 簡單翻譯下就是以下幾點:

  • Docker提供了一種可移植的配置標準化機制,允許你一致性地在不同的機器上運行同一個Container;而LXC本身可能因為不同機器的不同配置而無法方便地移植運行;

  • Docker以App為中心,為應用的部署做了很多優化,而LXC的幫助腳本主要是聚焦于如何機器啟動地更快和耗更少的內存;

  • Docker為App提供了一種自動化構建機制(Dockerfile),包括打包,基礎設施依賴管理和安裝等等;

  • Docker提供了一種類似git的Container版本化的機制,允許你對你創建過的容器進行版本管理,依靠這種機制,你還可以下載別人創建的Container,甚至像git那樣進行合并;

  • Docker Container是可重用的,依賴于版本化機制,你很容易重用別人的Container(叫Image),作為基礎版本進行擴展;

  • Docker Container是可共享的,有點類似github一樣,Docker有自己的INDEX,你可以創建自己的Docker用戶并上傳和下載Docker Image;

  • Docker提供了很多的工具鏈,形成了一個生態系統;這些工具的目標是自動化、個性化和集成化,包括對PAAS平臺的支持等;

那么Docker有什么用呢?對于運維來說,Docker提供了一種可移植的標準化部署過程,使得規模化、自動化、異構化的部署成為可能甚至是輕松簡單的事情;而對于開發者來說,Docker提供了一種開發環境的管理方法,包括映像、構建、共享等功能,而后者是本文的主題。

Docker的安裝和構成

Docker官方本身提供了非常具體的安裝教程,這里不說具體的安裝過程,請參考  Docker安裝(Mac系統),重要的是描述下原理和安裝完成后的結構,好對Docker更好的了解。 由于LXC本身不支持Mac內核,因此需要跑一個VirtualBox虛擬機(  TinyCoreLinux)來安裝,幸好Docker社區提供了一個非常方便的工具boot2docker(其實就是一個VBoxManage的包裝shell腳本),用于安裝Mac下的整個Docker環境。具體的結構如下:

怎么利用Docker構建開發環境

如圖所示,安裝完成后,具體情況如下:

  • 在Mac的home目錄~/.boot2docker下創建了虛擬機所需要的文件,其中boot2docker.iso是虛擬機映像,這是一個由CD-ROM引導的TinyCoreLinux系統;而boot2docker-vm.vmdk文件則是你的虛擬機磁盤,你所有的持久化數據都存放在這里,包括docker創建的lxc容器等文件。

  • 在Mac下,docker被分為客戶端docker-client和服務端docker-daemon兩部分,如果是在linux(比如ubuntu),實際上則是同一個可執行文件同時充當客戶端和服務端。docker-daemon可以監聽unix scoket,也可以在tcp socket(默認端口為4234),docker-client會通過一個叫DOCKER_HOST的環境變量讀取服務地址和端口,因此你應該在你的bash_profile文件里面添加這么一行:

    export DOCKER_HOST=tcp://127.0.0.1:4243

docker-daemon跑在虛擬機上,這個程序實際上就是接收docker-client發送過來的消息命令,創建、啟動和銷毀lxc容器,以及docker本身的版本管理、映像存儲等等 運行你的第一個docker容器 安裝完成后,就差不多可以開始創建和運行docker容器了,在這之前,你首先得下載一個Image,什么是Image?我們先來了解docker的2個基礎概念:  Image和  Container

Container和Image 在Docker的世界里,Image是指一個只讀的層(Layer),這里的層是AUFS里的概念,最直觀的方式就是看一下docker官方給出的圖:

怎么利用Docker構建開發環境

Docker使用了一種叫AUFS的文件系統,這種文件系統可以讓你一層一層地疊加修改你的文件,最底下的文件系統是只讀的,如果需要修改文件,AUFS會增加一個可寫的層(Layer),這樣有很多好處,例如不同的Container可以共享底層的只讀文件系統(同一個Kernel),使得你可以跑N多個Container而不至于你的硬盤被擠爆了!這個只讀的層就是Image!而如你所看到的,一個可寫的層就是Container。

那Image和Container的區別是什么?很簡單,他們的區別僅僅是一個是只讀的層,一個是可寫的層,你可以使用docker commit 命令,將你的Container變成一個Image,也就是提交你所運行的Container的修改內容,變成一個新的只讀的Image,這非常類似于git commit命令,感覺真棒!

實際上這就是Docker對Container映像的版本管理基石,AUFS文件系統實在是太美妙了,更多細節可以參考DotCloud的  這篇文章。

運行和退出

在了解了Image和Container的概念后,我們可以開始下載一個Image,Docker的好處就是提供了一個類似github的Image倉庫管理,你可以非常方便pull別人的Image下來運行,例如,我們可以下載一個ubuntu Image:

docker pull ubuntu:13.10

這里的13.10是一個Tag,類似于git的tag,這里的tag可以為你制定一個ubuntu的版本。下載完成后,執行docker images命令可以列出你已經下載或者自己構建的image:(請允許我使用可愛的馬賽克 :) )

怎么利用Docker構建開發環境

你可以看到ubuntu:13.10的大小為178MB,以及它的IMAGE ID。 現在我們開始運行一個Container,命令很簡單,例如我們想運行一個執行Shell終端的Container:

怎么利用Docker構建開發環境

如你看到的,你已經進入到一個Shell里面,可以執行你想執行的任何命令,就和在ubuntu里面一樣,進去后默認是在根目錄/下,可以看到經典的unix/linux目錄結構,以及你所運行的bash版本等信息。你可以給你的Container定一個名字,通過–name選項,例如這里命名了shell,日后你就可以直接用這個名字引用Contanier。

退出一個Container也很簡單,你直接exit就好了。 其他更多的命令這里不做贅述,因為官方的文檔已經非常全面,這里只是給一個直觀的初步印象。下面進入主題。

利用Docker搭建開發環境

我們先看看程序員在搭建開發環境時遇到的一些問題:

  • 軟件安裝麻煩,比如很多公司都使用redhat,一般開發人員又不給root,安裝一個nginx或者是mysql都得自己下載編譯安裝 權限問題,沒有root,一些軟件無法運行,例如dnsmasq;

  • 沒有root,無法修改hosts,無法netstat -nptl,無法tcpdump,無法iptable 

  • 隔離性差,例如不同的開發人員如果在同一臺主機環境下共享開發,雖然是用戶隔離,但端口如果不規范可能會沖突;同一個Mysql如果權限管理不好很有可能誤刪別人的數據 

  • 可移植性差,例如和生產環境不一致,開發人員之間也無法共享;更嚴重的情況是當有新人入職時,通常需要又折騰一遍開發環境,無法快速搭建 

這些問題可以通過在本地搭建虛擬機來解決,但虛擬機是一個很笨重的解決方案,Docker是一個非常輕量級的方案,而且還擁有虛擬機沒有的一些功能,例如標準化Image,Image共享等,更重要的是,利用Docker,你可以運行非常多的容器,在你的Mac下搭建一個分布式的開發環境根本不是什么大的問題,而且對內存、磁盤和cpu的消耗相比傳統的虛擬機要低許多,這些都要歸功于AUFS和LXC這兩大神奇的技術。

構建基礎Image

想要搭建一個節省磁盤空間和擴展性良好的開發環境,最重要的第一步就是構建一個基礎性的Image,比如你的主要開發語言是Ruby,那么你肯定需要一個已經安裝好以下工具的基礎Image:

  • ruby 

  • bundler 

  • gem 

然后在此基礎上,你可以擴展這個基礎的Image(下面叫base)為不同的開發環境,例如rails,或者是nats。當然,你的這個base也可以從別人的Image擴展而來,還記得我們剛剛pull下來的ubuntu:13.10這個Image嗎?你可以從這個Image擴展開始構建你的base,如何做呢?Docker提供了一種標準化的DSL方式,你只需要編寫一個Dockerfile,運行docker build指令,就可以構建你自己的Image,這有點像Makefile和make命令一樣,只是大家要構建的內容和構建語言不同。

Dockerfile的語法請參考  Dockerfile Reference,這里給出上面提到的Ruby開發的base Dockerfile示例:

FROM ubuntu:13.10 
RUN apt-get update 
RUN apt-get install -y ruby ruby-dev gem 
RUN gem install bundler

這里只用到了很簡單的2個指令:FROM和RUN,FROM指定了我們要擴展的Image,RUN指定我們要運行的命令,這里是安裝ruby,gem、bundler等軟件。寫好Dockerfile后,運行以下指令就可以創建你的base image了:

docker build --rm -t dev:base .

-t 選項是你要構建的base image的tag,就好比ubuntu:13.10一樣 –rm 選項是告訴Docker在構建完成后刪除臨時的Container,Dockerfile的每一行指令都會創建一個臨時的Container,一般你是不需要這些臨時生成的Container的 如你所想,我們可以像運行ubuntu:13.10那樣運行我們的base了:

docker run -i -t --name ruby dev:base irb

這里我們使用dev:base這個Image運行了一個irb解釋器(Ruby的交互式解釋器)。 在構建完base之后,你可以依樣畫葫蘆構建你的rails環境,很簡單,只需要FROM dev:base,然后RUN安裝你的rails組件就可以了,不再贅述。最終你可能構建的開發環境是這樣的:

怎么利用Docker構建開發環境

如上圖所示,base和service都是從ubutnu:13.10繼承而來,他們作為不同的基礎開發環境,base是ruby開發環境(也許命名為dev:ruby更為合適?),而service是一些基礎數據服務,例如mysql,memcache,我建議將這些第三方組件集中在一個Container中,因為他們的環境不經常修改,可以作為一種底層服務Container運行,除非你需要構建分布式的服務,例如memcache集群,那可以繼續拆分。

指定Image入口

當你構建完你的base Image和其他應用的Image之后,你就可以啟動這些Image了,還記得前面我們給出的運行命令嗎?

docker run -i -t --name shell dev:base /bin/bash

這里我們運行了一個bash,這樣你就可以在shell里面執行你所想要執行的任何命令了,但是我們有時候并不想每次都啟動一個shell,接著再在shell里面啟動我們的程序,比如一個mysql,而是想一啟動一個容器,mysql服務就自動運行了,這很簡單,Dockerfile提供了CMD和ENTRYPOINT這2個指令,允許你指定一個Image啟動時的默認命令。CMD和ENTRYPOINT的區別是CMD的參數可以由docker run指令指定的參數覆蓋,而ENTRYPOINT則不可以。例如我們想運行一個memcached服務,可以這么寫Dockerfile:

FROM ubuntu:13.10 
RUN apt-get install -y memcached CMD memcached -u root -p 40000

或者可以這么寫:

FROM ubuntu:13.10 
RUN apt-get install -y memcached ENTRYPOINT ["memcached", "-u", "root", "-p", "40000"]

注意不要把memcached啟動為后臺進程,即加上-d選項,否則docker啟動的container會馬上stop掉,這點我也覺得比較意外。 接著我們build這個Image:

docker build -t dev:memcache .

這樣,當你build完你的Image后,你可以直接將該Image運行為一個容器,它會自動啟動mysql服務:

docker run --name memcache_service -d dev:memcache

注意使用-d (detach) 選項,這樣這個container就會作為后臺進程運行了,接著你可以使用docker ps命令查看是否有在運行。

磁盤映射

大部分時候你會需要把你host主機(宿主)上的目錄映射到Container里面,這樣你就非常方便地在host主機上編輯代碼,然后直接就可以在Container里面運行它們,而不用手動copy到Container里面再重啟Container。按理將host的目錄映射到guest(指Container)上應該是一件很容易的事情,就好像VMWare那樣,但可惜的是,由于Mac上的Docker多了一層虛擬機,因此多了一層周折,你必須先VM上的目錄通過sshfs mount到host(指Mac)上,然后再將你的目錄或文件copy到這個mount的目錄,再將VM上的這個目錄映射到Container里,聽起來比較拗口,畫個圖會清晰很多。

怎么利用Docker構建開發環境

如上圖所示,VM里面的/mnt/sda1/dev/目錄(你需要自己創建)通過sshfs命令mount到了host主機(Mac)的~/workspace/dev/目錄 ,而VM里的/mnt/sda1/dev/目錄又被映射到了Container的/src/目錄下,這樣你就可以在Container里面的/src/目錄下訪問你的host文件了。具體如何做呢?首先你需要安裝sshfs命令,然后將VM的password寫到一個文件中,例如~/.boot2docker/b2d-passwd,在用sshfs命令mount起VM的/mnt/sda1/dev目錄:

brew install sshfs 
cat tcuser > ~/.boot2docker/b2d-passwd 
sshfs docker@localhost:/mnt/sda1/dev ~/workspace/dev -p 2022 -o reconnect -o password_stdin < ~/.boot2docker/b2d-passwd

接著你在run一個Container的時候需要通過-v選項來將/mnt/sda1/dev/映射到/src目錄:

docker run -i -t dev:base -v /mnt/sda1/dev:/src /bin/bash

這樣你就可以在你的Container的/src目錄下看到你host里的文件了。 磁盤映射還有2個地方需要注意:

  • 你的文件實際上是存儲在VM里面的,也就是說你需要將你的目錄或者文件copy到VM里面,你sshfs之后,就是copy到~/workspace/dev目錄下 

  • 千萬不要sshfs mount非/mnt/sda1下的目錄,因為VM里面跑的是TinyCoreLinux,這個OS的rootfs是臨時性的(放在內存的,實際上就是boot2docker.iso文件里面的一個rootfs),因此其根目錄/下的東西(包括/home)根本不會持久化,只有/mnt/sda1這個目錄下的才能持久化。如果你放在/home目錄下,只要VM一重啟,就會丟失的,/mnt/sda1則不會,實際上就是那個~/.boot2docker-vm.vmdk文件掛載到了/mnt/sda1目錄下 

端口映射

和磁盤映射一樣,你有時候會需要將Container的端口映射到host主機上,同樣蛋疼的是,由于多了一層VM,端口映射也顯得比較麻煩。首先你需要設置VirtualBox的端口映射,然后再將Container的端口映射到你的VM里面:

怎么利用Docker構建開發環境

具體是這么做的,通過2條命令:

boot2docker ssh -L 8000:localhost:8000 
docker run -i -t -p 8000:8000

也就是說在docker run的時候通過-p選項指定要映射的端口到VM,而boot2docker ssh命令則是將VM的8000端口映射到了host(Mac)的8000端口,這樣你就可以通過Mac的localhost:8000訪問Container的8000端口了。 其實,有另一種解決方案就是你不用映射到host(Mac),而是直接登錄到VM里面進行訪問就好了,boot2docker ssh就可以登錄到VM,這樣就類似于你的host是ubuntu,但這種解決方案的問題是這個ubuntu太弱了(TinyCoreLinux),如果你在這個ubuntu里面開發代碼,或者是運行瀏覽器,是非常蛋疼的事情,關鍵還是這個ubuntu是每次重啟都會復原的!所以我建議還是做多一層映射好了。 最后,實際上在VM里面,你是可以直接訪問所有的Container的端口的,因為VM到Container的網絡都是橋接的。

其他的一些坑

在使用的過程中,還遇到一些不少的坑:

  1. /etc/hosts文件無法修改,這樣你就不能自己做域名解析 

  2. VM的系統時間是UTC +0000的,而且貌似無法修改 

  3. Container的IP無法指定為靜態IP,因此每次重啟Container時,IP可能會變化 

第1個問題的解決方案是通過安裝dnsmasq軟件來做域名解析:

# 首先,在你的Container里面安裝dnsmasq軟件:

apt-get install dnsmasq

# 將以下文本添加到 /etc/dnsmasq.conf文件的最后:

listen-address=127.0.0.1 resolv-file=/etc/resolv.dnsmasq.conf conf-dir=/etc/dnsmasq.d user=root

# 接著在/etc/dnsmasq.d/目錄下新建一個文件,隨意起個名字

vi /etc/dnsmqsq.d/dns.conf

# 指定你要映射的域名,例如google.com,則將下面貼進dns.conf文件

address="/google.com/172.17.0.4"

# 最后退出容器,重啟啟動容器時,通過-dns選項指定域名服務器

docker run -i -t -dns 127.0.0.1 -dns 8.8.8.8 dev:base /bin/bash

# 一定要注意上面添加google的域名服務器8.8.8.8,否則你訪問不了外網

# 進去Container后,啟動dnsmasq,這樣你就能夠ping google.com了

/etc/init.d/dnsmasq start

第2個問題的解決方案就稍微麻煩些,起碼我沒有找到更好的解決方案,我是將boot2docker.iso文件重新制作一次來解決這個問題的:

# 首先你需要將boot2docker.iso文件mount到一個目錄下

hdiutil mount ~/.boot2docker/boot2docker.iso

# 系統會mount到/Volumes/boot2docker目錄下,然后你最好將這下面的東西copy出來到一個另外的目錄,這樣我們好制作一張新的ISO

cp -r /Volumes/boot2docker/* ~/tmp/

# 接著我們修改以下文件

vi ~/tmp/boot/isolinux/isolinux.cfg

# 將其中的以下這行修改:

append loglevel=3 user=docker console=ttyS0 console=tty0 nomodeset norestore base

# 修改為:(其實就是加了tz的啟動參數),然后保存

append tz=CST-8 loglevel=3 user=docker console=ttyS0 console=tty0 nomodeset norestore base

# 接著你必須在ubuntu環境下重新制作ISO文件,你可以利用docker跑一個ubuntu,哈哈,假設你將boot2docker目錄copy到了ubuntu的/src/目錄下,那么接著這么做

# 安裝xorriso命令

apt-get install xorriso

# 構建ISO映射

xorriso -as mkisofs -J -R -V boot2docker -no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -o /boot2docker.iso /src/

# 這樣就生成了/boot2docker.iso文件,最后你就可以替換到VM的啟動ISO文件了,然后重啟VM了

boot2docker restart

# 最后你必須設置你的VM為正確的時間,使用date -s 命令,最后用date命令查看,你就能看到CST時區的正確時間了

Sun Mar 30 00:27:13 CST 2014

# 對于你啟動的container,你都必須重新設置TZ環境變量,否則即使VM是CST-8,你的container還是UCT +00:00的時間

export TZ='CST-8'

第三個問題暫時無法解決(可能需要編輯底層的LXC配置文件)。

docker的限制以及后續的一些想法

docker其實還是有一些限制的:

  • 要求你的環境是Linux的,而且內核必須很新(>= 2.6.27 (29)),這其實是LXC本身的限制,和docker無關 

  • docker的Container目前host是不能修改的,當然有解決方案(dnsmasq) 

  • docker的Container也暫時無法指定靜態IP 

用docker作為開發環境甚至是生產環境其實還有很多地方值得嘗試:

  • 在團隊內部構建本地的倉庫,標準化所有的開發環境,使得團隊的新人可以快速上手 

  • 在生產環境部署docker,這其實是PAAS的虛擬化和自動化的一種方式,利用LXC和Docker能夠更便捷地實施PAAS 

  • 嘗試用docker做分布式集群模擬和測試,成本會更加低廉,更加容器維護 

感謝各位的閱讀,以上就是“怎么利用Docker構建開發環境”的內容了,經過本文的學習后,相信大家對怎么利用Docker構建開發環境這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丽江市| 大丰市| 洛阳市| 奉化市| 商水县| 屯昌县| 马公市| 奇台县| 柳江县| 双鸭山市| 中阳县| 白朗县| 垦利县| 兴安盟| 宁陕县| 平陆县| 黄龙县| 同江市| 龙口市| 德江县| 关岭| 鄱阳县| 蕲春县| 达日县| 昌图县| 曲阜市| 南丹县| 张北县| 稷山县| 饶河县| 隆尧县| 金乡县| 海安县| 临朐县| 永兴县| 诸城市| 襄樊市| 巴中市| 嘉黎县| 台中县| 太白县|