docker 筆記
2016-10-02 14:47:25

一般的 vm 與 docker 差在哪?

一般的 vm 會在 hypervisor上再架一個完整的 Guest OS,接著才會安裝對應的 library 與 application。而 docker 會是基於 Docker Engine上跑多個 container,每一個 container 都是一支獨立的 user process,共用 Host OS 的 Kernel。

一般的 vmdocker
Applications 01Applications 02Applications 03
libraries 01libraries 02libraries 03
Guest OS 01Guest OS 02Guest OS 03
Hyervisor (例如:VirtualBox)
Host OS
Container 01
Application 01
Libraries 01
Container 02
Application 02
Libraries 02
Container 03
Application 03
Libraries 03
Docker Engine
Host OS

Refs

基本名詞

Docker Client

一個工具用來讓使用者可以對 Docker Daemon 送指令與設定。

Docker Daemon

一個跑在 Host Machine 的程式,用來操作 Docker。

Dockerfile, Image and Container
Dockerfile, Image and Container

Dockerfile

一個檔案用來定義一個 Docker Image 要怎麼產生的,也就是 Docker Image 的原始檔。裡面包含了多個指令來描述 Docker Image 要怎麼被建立。在整個 Docker 的運作中只會被讀取用來建立 Docker Image,而不會被 Docker 更改。

Docker Image

一個檔案用來定義怎麼建立 Docker Container,它是 Dockerfile 生成的產物,包含了跑一個應用程式所需的執行環境與函式庫。可以使用build這個指令來從 Dockerfile 建立 Docker Image。Docker Image一旦被建立之後,它不會被更改,但可以使用這個 image 去建立另一個新的 image。

Docker Container

Docker Container 是一個 Docker Image 的可執行實體(runnable instance),當它被建立的時候,除了包含了對應的 Docker Image 外,Docker 還會建立一個對應的 read-write file system 與並做一些初始化與網路設定。當它被執行時,Docker Container 會有一隻對應的正在執行中的 process。可以使用create指令從 Docker Image 來建立一個 Docker Container。使用start執行 Docker Container。一個正在執行中的 Docker Container 也有stop, restart等指令可以使用。

Docker Register

用來存放 Docker Image 的地方,當需要使用 Docker Image 時,可以直接從 Docker Register 下載而不用重新 build image。

Refs

指令

docker ps

列出正在執行(running)的container。

  • -a 列出所有的containger。

docker run [image]

取得image、建立container並執行。

  • -t 分配一個虛擬終端(pseudo-tty)並綁定到container的標準輸入。
  • -i 使用interaction模式,讓container的標準輸入保持開啟狀態,使用者可以由此輸入指令。
  • 如果需要一個console連到container,則 -i 與 -t 必須要一起用,可以縮寫成 -it 。
  • --rm 當離開container時,清除所有的資料與file system,要注意的是會連volumn都會一起刪。

docker search [keyword]

查詢Docker Hub上的image。

docker images

列出所有的image。

docker stop [container]

停止目前正在運作的container。

docker rm [container]

移除container。

docker inspect [container]

取得目前container的資訊。

docker attach [container]

連線至指定的container,但多個attach指令到同一個container的話,會共用相同的console。

docker exec [container] [command]

連線至指定的container並執行對應的指令。跟run一樣有 -it 參數可以使用,例如可以使用docker exec -it [container] bash

使用範例

範例:一個建立phoenix環境的Dockerfile

FROM elixir:1.4.2-slim

RUN apt-get update && apt-get upgrade -y && \
    apt-get install -y curl sudo && \
    curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - && sudo apt-get install -y nodejs

RUN mix local.hex --force && \
    mix archive.install --force https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez

CMD ["/bin/bash"]

範例:起一個mysql的docker,並且讓host的mysql client可以連到它。

  • 建立一個 docker-compose.yml 如下:
version: "3"
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: "yit0v5911gcfckbd1guk2ctumrdcy8nb"
    ports:
      - "7364:3306"
  • 執行docker-compose up
  • 連線mysql -h 127.0.0.1 -P 7364 -u root -p

範例:起一個 debian server 與 mysql server 的docker,並且讓 debian server 可以連到 mysql server。

  • 建立一個 docker-compose.yml 如下:
version: "3"
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: "lvkn9ey1bcty55ghmyedncr79ycdcvgo"
  server:
    image: debian:jessie
    stdin_open: true
    tty: true
  • 執行docker-compose up
  • 執行docker attach [debian_server_container_name]進入 server 的 container。其中debian_server_container_name即是對應debian container的name。當你執行docker-compose up的時候,log就會顯示container的名稱。
  • 安裝 mysql-clientroot@210978bba57f:/# apt-get update && apt-get upgrade && apt-get install mysql-client
  • 連線至mysqlroot@210978bba57f:/# mysql -hdb -P3306 -uroot -p。其中我們把host設成db,這是因為docker compose的功能,它將同一個compose下的service都放在同一個private network中,而在compose.yml裡設定的service名稱就可以用來代表server對應的ip位址。

Refs

Note

  • docker run -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME/.Xauthority:/root/.Xauthority --net=home

Resources

Links

Books