Docker入门六部曲——容器
原文鏈接:http://www.dubby.cn/detail.html?id=8734
準備
- 已經安裝好Docker 1.13或者以上的版本。
- 讀完的上一篇文章(基本引導)。
- 簡單的測試一下你的本地環境是否已經OK了:docker run hello-world。
介紹
讓我們開始構建一個Docker應用吧。這篇文章介紹的是,Docker整個結構層次中最底層的一個,那就是容器。上一個層級是服務,服務定義了容器的行為,這會在下一篇文章中介紹。最后一個,也是最高的一個層級,是堆棧,定義了所有服務的交互,這在之后也會被介紹。
- Stack(堆棧)
- Services(服務)
- Container(容器)——你正在看的
走進新的開發環境
在沒有Docker的時候,如果你想寫一個Python應用,你首先要做的是安裝一個Python的運行環境。但是,你的機器的環境必須是這樣,才能使得應用可以正常執行,而且,服務器也必須有這樣的環境。
有了Docker,你可以直接通過鏡像來獲得一個Python的運行環境,不需要安裝哦。然后把你的代碼和這個鏡像放到一起,當然還要加上你的代碼所需的依賴。
這些融合在一起,就形成了一個新的鏡像,定義這個融合邏輯的就是Dockerfile。
使用Dockerfile來定義一個容器
 
Dockerfile是用來定義你的容器。對于一些資源訪問,比如網卡、磁盤,在容器里都是虛擬化的,和宿主機都是隔離的,因此,你必須把容器內的資源和宿主機的資源做一個映射;還需要指定你想要把哪些文件copy到你的容器里(比如你的代碼)。當然,你還希望這個寫好的Dockerfile在任何地方運行都是一樣的。
Dockerfile
創建一個空目錄,然后在里面新建一個文件Dockerfile:
# 使用Python官方鏡像作為鏡像的基礎
FROM python:2.7-slim# 設置工作空間為/app
WORKDIR /app# 把當前目錄下的文件拷貝到 容器里的/app里
ADD . /app# 安裝requirements.txt中指定的依賴
RUN pip install -r requirements.txt# 開放80端口
EXPOSE 80# 設置 NAME 這個環境變量
ENV NAME World# 當容器啟動時,運行app.py
CMD ["python", "app.py"]?
這個Dockerfile中需要的幾個文件還沒有準備好,app.py和requirements.txt,所以我們繼續吧。
應用
在Dockerfile同一個目錄下,創建這兩個文件。因為ADD命令需要把這些拷貝進容器里。而且app.py中的服務器輸入端口也正好是80,這會因為配置了EXPOSE而暴露出來。
requirements.txt:
Flask
Redis?
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)app = Flask(__name__)@app.route("/")
def hello():try:visits = redis.incr("counter")except RedisError:visits = "<i>cannot connect to Redis, counter disabled</i>"html = "<h3>Hello {name}!</h3>" \"<b>Hostname:</b> {hostname}<br/>" \"<b>Visits:</b> {visits}"return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)if __name__ == "__main__":app.run(host='0.0.0.0', port=80)可以看出,pip install -r requirements.txt安裝了Flask和Redis的庫,應用打印出NAME這個環境變量和socket.gethostname。最后,因為Redis沒有運行(pip安裝的只是使用Redis的庫,并不是Redis本身),所以我們應該做嘗試連接Redis,如果連接失敗就打印錯誤信息。
注意:在容器內部訪問主機名時,會檢索容器的ID,類似于進程ID。
構建應用
就這樣!你不需要安裝Python,不需要安裝requirements.txt中指定的任何依賴。看起來,你什么都沒做,但是其實你已經做完了。
執行ls(默認為類Unix環境):
$ ls
?  demo ls
Dockerfile       app.py           requirements.txt?
現在來執行構建命令。這個會創建一個Docker鏡像,-t可以讓你給鏡像自定義一個名字:
docker build -t friendlyhello .?
你肯定要問要,你的鏡像在哪里?他就在你的本地Docker鏡像注冊中心:
$ docker imagesREPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398?
運行你的應用
運行,當然還要映射端口號,我們需要使用-p:
docker run -p 4000:80 friendlyhello?
你可以看到Python啟動是提醒你訪問http://0.0.0.0:80。但是不要忘記這個響應是從容器內返回的哦,而我們把容器內的80端口映射到宿主機的4000端口了,所以,我們應該訪問http://localhost:4000。
打開瀏覽器,可以看到:
你也可以使用curl來看響應內容:
$ curl http://localhost:4000<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>?
按鍵CTRL+C可以退出Docker。
現在試試在后臺運行這個Docker應用:
docker run -d -p 4000:80 friendlyhello?
執行完后臺運行的命令后,你可以獲得一個容器的ID
?  demo docker run -d -p 4000:80 friendlyhello
b0054baaca448f3b30b01004de98be45fbb9aaccd850137629220bbc730b0a1a?
你也可以使用docker ps來看到縮短的容器ID:
?  demo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
b0054baaca44        friendlyhello       "python app.py"     About an hour ago   Up About an hour    0.0.0.0:4000->80/tcp   keen_beaver?
當然也可以在http://localhost:4000上看到這個容器ID。你可以使用docker stop來結束這個進程,后面要加上容器ID哦:
?  demo docker stop b0054baaca44
b0054baaca44?
分享你的鏡像
為了展示Docker的便捷性,我們來嘗試上傳這個鏡像吧,然后再證明可以run anywhere。
注冊中心就是一個鏡像的倉庫的集合——有點類似GitHub(代碼倉庫)。一個賬號可以創建很多個倉庫。docker默認情況下就是Docker公共注冊中心。
我們這里使用Docker的公共注冊中心,僅僅是因為他是免費而且是默認的。不過還是有很多公開的注冊中心可以選擇的,甚至你可以設置一個私服。
登錄
如果你沒有賬號,那你需要先注冊一個。
然后在你的本機上使用:
docker login- 1
給鏡像打標簽
鏡像的標記一般這樣命名username/repository:tag。tag是可選的,不過推薦使用tag,這樣可以給鏡像加一個版本。建議把倉庫名和標簽名都起得有意義一些,比如get-started:part1。這樣會把鏡像放到get-started倉庫里,打上part1的標簽。
語法是docker tag image username/repository:tag,現在開始用命令來嘗試打標簽吧:
?  demo docker tag friendlyhello dubbyyoung/get-started:part1
?  demo docker images                                        
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
dubbyyoung/get-started   part1               4ac5012183e0        4 hours ago         194 MB
friendlyhello            latest              4ac5012183e0        4 hours ago         194 MB
python                   2.7-slim            d962f7a9f2f1        2 days ago          182 MB
hello-world              latest              1815c82652c0        9 days ago          1.84 kB
?  demo ?
推送到遠端
推送的命令是:
docker push username/repository:tag?
我執行的結果是:
?  demo docker push dubbyyoung/get-started:part1
The push refers to a repository [docker.io/dubbyyoung/get-started]
b57286e58751: Pushed 
7b71bca6a91c: Pushed 
cdc93fd01629: Pushed 
553c628e7577: Mounted from library/python 
8f02c55c4e74: Mounted from library/python 
15d2fe96bb43: Mounted from library/python 
0d960f1d4fba: Mounted from library/python 
part1: digest: sha256:6d816f3a86c74e8855cef96750ff1da98eb11747c4a31cbb486b92dd20e075e6 size: 1787?
隨時隨地都可以執行了
到了這一步,你可以使用docker run在任何一個機器上運行了:
docker run -p 4000:80 username/repository:tag?
如果本地沒有這個鏡像,Docker會自動去遠端拉取:
?  demo docker run -p 4000:80 dubbyyoung/get-started:part1* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)?
注意:如果你不指定標簽
:tag,那么缺省的就是:latest,不管是構建的時候還是運行的時候。
總結
以上是生活随笔為你收集整理的Docker入门六部曲——容器的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 2022-2028年中国乙丙橡胶行业市场
- 下一篇: Docker入门六部曲——Swarm
