Docker 很是棒! 它使軟件開發者無需擔憂配置和依賴性,在任何地方打包,發送和運行他們的應用程序。而在與 Kubernetes 相結合後,它使應用集羣部署和管理變得更方便。這使得 Docker 深受軟件開發者的喜好,愈來愈多的開發者開始使用 Docker。html
那麼 Docker 究竟是什麼?程序員
它是構建、測試、部署和發佈容器化應用的平臺。稱其爲平臺是由於 Docker 實際上是一套用於管理與容器相關的全部事物的工具。做爲 Docker 的核心,接下來咱們將深刻探討容器。web
容器提供了在計算機上的隔離環境中安裝和運行應用程序的方法。在容器內運行的應用程序僅可以使用於爲該容器分配的資源,例如:CPU,內存,磁盤,進程空間,用戶,網絡,卷等。在使用有限的容器資源的同時,並不與其餘容器衝突。您能夠將容器視爲簡易計算機上運行應用程序的隔離沙箱。sql
這個概念聽起來很熟悉,有些相似於虛擬機。但它們有一個關鍵的區別:容器使用的一種很是不一樣的,輕量的技術來實現資源隔離。容器利用了底層 Linux 內核的功能,而不是虛擬機採用的 hypervisor 的方法。換句話說,容器調用 Linux 命令來分配和隔離出一組資源,而後在此空間中運行您的應用程序。咱們快速來看下兩個這樣的功能:docker
簡單的講就是,Linux namespace 容許用戶在獨立進程之間隔離 CPU 等資源。進程的訪問權限及可見性僅限於其所在的 Namespaces 。所以,用戶無需擔憂在一個 Namespace 內運行的進程與在另外一個 Namespace 內運行的進程衝突。甚至能夠同一臺機器上的不一樣容器中運行具備相同 PID 的進程。一樣的,兩個不一樣容器中的應用程序可使用相同的端口。後端
Cgroups 容許對可用資源設置限制和約束。例如,您能夠在一臺擁有 16 G 內存的計算機上建立一個 Namespace ,限制其內部進程可用內存爲 1 GB。瀏覽器
到這,您可能已經猜到 Docker 的工做原理了。當您請求 Docker 運行容器時,Docker 會在您的計算機上設置一個資源隔離的環境。而後 Docker 會將打包的應用程序和關聯的文件複製到 Namespace 內的文件系統中,此時環境的配置就完成了。以後 Docker 會執行您指定的命令運行應用程序。服務器
簡而言之,Docker 經過使用 Linux namespace 和 cgroup(以及其餘一些命令)來協調配置容器,將應用程序文件複製到爲容器分配的磁盤,而後運行啓動命令。Docker 還附帶了許多其餘用於管理容器的工具,例如:列出正在運行的容器,中止容器,發佈容器鏡像等許多其餘工具。網絡
與虛擬機相比,容器更輕量且速度更快,由於它利用了 Linux 底層操做系統在隔離的環境中運行。虛擬機的 hypervisor 建立了一個很是牢固的邊界,以防止應用程序突破它,而容器的邊界不那麼強大。另外一個區別是,因爲 Namespace 和 Cgroups 功能僅在 Linux 上可用,所以容器沒法在其餘操做系統上運行。此時您可能想知道 Docker 如何在 macOS 或 Windows 上運行? Docker 實際上使用了一個技巧,並在非 Linux 操做系統上安裝 Linux 虛擬機,而後在虛擬機內運行容器。架構
讓咱們利用目前爲止學到的全部內容,從頭開始建立和運行 Docker 容器。若是你尚未將 Docker 安裝在你的機器上,能夠參考這裏[1]安裝 Docker。在這個示例中,咱們將建立一個 Docker 容器,下載一個用 C語言寫的 Web 服務,編譯並運行它,而後使用瀏覽器訪問這個 Web 服務。
咱們將從全部 Docker 項目開始的地方從建立一個 Dockerfile 開始。此文件描述瞭如何建立用於運行容器的 Docker 鏡像。既然咱們尚未聊到鏡像,那麼讓咱們看一下鏡像的官方定義[2]:
鏡像是一個可執行包,其包含運行應用程序所需的代碼、運行時、庫、環境變量和配置文件,容器是鏡像的運行時實例。
簡單的講,當你要求 Docker 運行一個容器時,你必須給它一個包含以下內容的鏡像:
在 Docker 的世界,使用別人的鏡像做爲基礎鏡像來建立本身的鏡像是十分廣泛的。例如,官方 reds Docker 鏡像就是基於 Debian 文件系統快照(rootfs tarball),並安裝在其上配置 Redis。
在咱們的示例中,咱們選擇 Alpine Linux 爲基礎鏡像。當您在 Docker 中看到 「alpine」 時,它一般意味着一個精簡的基本鏡像。 Alpine Linux 鏡像大小隻有約爲5 MB!
在您的計算機建立一個新目錄(例如 dockerprj),而後新建一個 Dockerfile 文件。
umermansoor:dockerprj$ touch Dockerfile
將以下內容粘貼到 Dockerfile:
# Use Alpine Linux rootfs tarball to base our image on FROM alpine:3.9 # Set the working directory to be '/home' WORKDIR '/home' # Setup our application on container's file system RUN wget http://www.cs.cmu.edu/afs/cs/academic/class/15213-00/www/class28/tiny.c \ && apk add build-base \ && gcc tiny.c -o tiny \ && echo 'Hello World' >> index.html # Start the web server. This is container's entry point CMD ["./tiny", "8082"] # Expose port 8082 EXPOSE 8082
這個Dockerfile 包含建立鏡像的內容說明。咱們建立鏡像基於 Alpine Linux(rootfs tarball),並將工做目錄設置爲 /home 。接下來下載,編譯並建立了一個用 C 編寫的簡單 Web 服務器的可執行文件,而後指定在運行容器時要執行的命令,並將容器端口 8082 暴露給主機。
如今,咱們就能夠構建鏡像了。在 Dockerfile 的同級目錄運行 docker build 命令:
umermansoor:dockerprj$ docker build -t codeahoydocker .
若是這個命令成功了,您將看到:
Successfully tagged codeahoydocker:latest
此時咱們的鏡像就建立成功了,該鏡像主要包括:
既然成功構建了鏡像,那麼咱們可使用以下命令運行容器。
umermansoor:dockerprj$ docker run -p 8082:8082 codeahoydocker:latest
讓咱們瞭解下這裏發生了什麼。
經過 docker run 命令,咱們請求 Docker 基於 codeahoydocker:latest 鏡像建立和啓動一個容器。-p 8082:8082 將本地的 8082 端口映射到容器的 8082 端口(容器內的 Web 服務器正在監聽 8082 端口上的鏈接)。打開你的瀏覽器並訪問 localhost:8082/index.html 。你將能夠看到 Hello World 信息。
最後我想補充一點,雖然 Docker 很是棒,並且對於大多數項目來講它是一個不錯的選擇,但咱們並不是到處都要使用它。在個人工做中,Docker 與 Kubernetes 結合使用,能夠很是輕鬆地部署和管理後端微服務,咱們沒必要爲每一個服務配置新的運行環境。另外一方面,對於性能密集型應用程序,Docker 可能不是最佳選擇。我經手的其中一個項目必須處理來自移動遊戲客戶端的 TCP 長鏈接(每臺機器1000個),這時 Docker 網絡出現了不少問題,致使沒法將它用於該項目。
分享免費學習資料
針對於Java程序員,我這邊準備免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)
爲何某些人會一直比你優秀,是由於他自己就很優秀還一直在持續努力變得更優秀,而你是否是還在知足於現狀心裏在竊喜!但願讀到這的您能點個小贊和關注下我,之後還會更新技術乾貨,謝謝您的支持!
資料領取方式:加入Java技術交流羣963944895
,點擊加入羣聊,私信管理員便可免費領取