天天看點

Docker-Context

  1. Docker-Dockerfile入門 - 1 中我們提到了build中

    .

    的作用,當時說的是代表目前目錄其實說的并不準确具體,我們今天來說一下這個問題,如果了解不對請指正
  2. 之前提到了Docker context ,那麼這到底是個什麼東西,有什麼作用,在 <>中大緻意思是這樣解釋的:
    表面在本機執行docker build,但是其實是有一個docker daemon在運作的,是以你所執行的指令與産生的結果都是與docker服務互動後的結果,這是一種C/S架構的東西,是以建構其實并非是在本地執行,而是在服務端完成的
  3. 是以我們指定了

    .

    這個上下文路徑後,docker會根據這個上下文路徑來去建構鏡像,我們來測試一下
  4. 首先最簡單的建構操作如下
    [qidai@qidai-pc cc]$ docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    nginx               latest              881bd08c0b08        9 days ago          109MB
    ubuntu              latest              47b19964fb50        5 weeks ago         88.1MB
    centos              latest              1e1148e4cc2c        3 months ago        202MB
    [qidai@qidai-pc cc]$ tree .
    .
    └── file
    0 directories, 1 file
    [qidai@qidai-pc cc]$ docker build -t x:x -f file .
    Sending build context to Docker daemon  2.048kB
    Step 1/2 : FROM nginx
     ---> 881bd08c0b08
    Step 2/2 : RUN touch succ /
     ---> Running in a57757a928f2
    Removing intermediate container a57757a928f2
     ---> 8ce68f7c4572
    Successfully built 8ce68f7c4572
    Successfully tagged x:x           
    • tree

      :linux指令,列出目前目錄結構
    • 同時我們也知道了用來建構的檔案不一定是叫Dockerfile,Dockerfile隻是docker的預設檔案名而已
  5. 剛才為docker指定了上下文,為

    .

    ,這時候docker知道這個路徑後, docker會将這個目錄下的所有東西打包上傳到服務端,然後進行解析建構
  6. 現在我們全部用錯誤的建構來說明docker的context路徑問題,
  7. 先說一下

    -f

    參數的問題
    • 建構如下
      [qidai@qidai-pc cc]$ cd ..
      [qidai@qidai-pc test]$ tree .
      .
      └── cc
          └── file
      1 directory, 1 file
      [qidai@qidai-pc test]$ docker build -t s:s -f cc/file .
      Sending build context to Docker daemon   2.56kB
      Step 1/2 : FROM nginx
       ---> 881bd08c0b08
      Step 2/2 : RUN touch succ /
       ---> Running in ef1fa8e3bb07
      Removing intermediate container ef1fa8e3bb07
       ---> 416623a1c3f7
      Successfully built 416623a1c3f7
      Successfully tagged s:s           
    • 更改建構路徑
      [qidai@qidai-pc test]$ docker build -f s:s -f cc/nofile .
      unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /run/media/qidai/_yingpan/test/cc/nofile: no such file or directory
      [qidai@qidai-pc test]$ docker build -t s:s -f cc .
      Sending build context to Docker daemon   2.56kB
      Error response from daemon: unexpected error reading Dockerfile: read /var/lib/docker/tmp/docker-builder684771877/cc: is a directory           
    • 如上我們就很清楚了,首先

      -f

      參數指定的Dockerfile的具體路徑在本地是必須存在的,這個無可質疑,如果本地都不存在那麼本地的機器就會跟你爆出不存在的錯誤,其次那就是本地存在,而且本地不報錯了,這就通過過了第一步的本地審查,是以就打包上傳到docker伺服器,在伺服器中解析,發現cc并不是具體的建構檔案的路徑,是以會給你再次報錯,我們從兩次的報錯中的路徑也可以看出來,

      /run/media

      是本地檢查,而

      /var/lib/tmp/...

      是docker的檢查
  8. 然後我們在說一下後面的

    .

    的問題
    • [qidai@qidai-pc cc]$ cd ..
      [qidai@qidai-pc test]$ tree .
      .
      └── cc
          └── file
      1 directory, 1 file
      [qidai@qidai-pc test]$ docker build -t s:s -f cc/file .
      Sending build context to Docker daemon   2.56kB
      Step 1/2 : FROM nginx
       ---> 881bd08c0b08
      Step 2/2 : RUN touch succ /
       ---> Running in ef1fa8e3bb07
      Removing intermediate container ef1fa8e3bb07
       ---> 416623a1c3f7
      Successfully built 416623a1c3f7
      Successfully tagged s:s           
    • [qidai@qidai-pc test]$ docker build -t s:s -f cc/file cc
      Sending build context to Docker daemon  2.048kB
      Step 1/2 : FROM nginx
       ---> 881bd08c0b08
      Step 2/2 : RUN touch succ /
       ---> Using cache
       ---> 416623a1c3f7
      Successfully built 416623a1c3f7
      Successfully tagged s:s
      [qidai@qidai-pc test]$ docker build -t s:s -f cc/  cc
      Sending build context to Docker daemon  2.048kB
      Error response from daemon: unexpected error reading Dockerfile: read /var/lib/docker/tmp/docker-builder657763113: is a directory           
    • 如上,我們給出的context路徑其實是上傳後的伺服器的相對路徑,當給出的context為

      cc

      的時候,那麼docker就會在

      context_path/cc/

      下去找建構檔案,這時候會根據

      -f

      參數去找建構檔案,然後開始建構, 而上面第二次建構就不行了,依舊傳入的context為

      cc

      ,然後根據

      -f

      找建構檔案,但是

      -f

      并沒有具體指定檔案,是以建構失敗
    • 當然也可以指定本機的絕對路徑為docker的context路徑,如下
      [qidai@qidai-pc test]$ docker build -t s:s -f cc/file .
      Sending build context to Docker daemon   2.56kB
      Step 1/1 : FROM nginx
       ---> 881bd08c0b08
      Successfully built 881bd08c0b08
      Successfully tagged s:s
      [qidai@qidai-pc test]$ pwd
      /run/media/qidai/_yingpan/test
      [qidai@qidai-pc test]$ docker build -t s:s -f cc/file /run/media/qidai/_yingpan/test
      Sending build context to Docker daemon   2.56kB
      Step 1/1 : FROM nginx
       ---> 881bd08c0b08
      Successfully built 881bd08c0b08
      Successfully tagged s:s           
  9. 知道了路徑問題後,我們再來看一下Dockerfile中的檔案問題,拿

    COPY

    指令來說
    • 建構檔案内容如下
      FROM nginx
      COPY cc/file /file.bak           
    • 建構過程
      [qidai@qidai-pc test]$ tree .
      .
      └── cc
          └── file
      1 directory, 1 file
      [qidai@qidai-pc test]$ docker build -t a:a -f cc/file .
      Sending build context to Docker daemon   2.56kB
      Step 1/2 : FROM nginx
       ---> 881bd08c0b08
      Step 2/2 : COPY cc/file /file.bak
       ---> 9b5b8bcc0246
      Successfully built 9b5b8bcc0246
      Successfully tagged a:a           
    • 如果我們将

      COPY

      的源目的位址改一下呢 ?,如下
      [qidai@qidai-pc test]$ touch /home/qidai/tempFile   #本機建立一個檔案
      [qidai@qidai-pc test]$ cat cc/file
      FROM nginx
      COPY /home/qidai/tempFile /file.bak  #想法是将本機内的指定檔案複制到容器
      [qidai@qidai-pc test]$ docker build -t s:s -f cc/file .
      Sending build context to Docker daemon   2.56kB
      Step 1/2 : FROM nginx
       ---> 881bd08c0b08
      Step 2/2 : COPY /home/qidai/tempFile /file.bak
      COPY failed: stat /var/lib/docker/tmp/docker-builder527470065/home/qidai/tempFile: no such file or directory           
    • 如上我們就可以看到了,建構檔案中也是應用的是context的相對路徑,是以想将我們的檔案複制到容器内隻能是将檔案放入我們指定的context目錄下(

      COPY

      ADD

      指令不能拷貝上下文之外的本地檔案)
  10. 下面是我自己畫的一張圖,更直覺的展示了Docker指令和目錄路徑之間的關聯,如果有異議請評論指出,謝謝
Docker-Context