不正宗 docker 入門教程-啓動一個容器(1/3)

從命名上就知道這是一篇簡單粗暴的 docker新手入門教程, 爲何要簡單粗暴? 我認爲有自學能力的人幫他入門就夠了, 不能自學的一時半會兒也教不會, 不符合入門教程的初衷, 建議出門左拐去找找視頻教程...

本章目標

  1. 大概瞭解 docker 是個什麼玩意
  2. 知道經常使用的 docker 指令參數, 能啓動一個容器(否則還想怎麼樣? 上天嗎?)

安裝環境

強烈推薦使用 Docker for MacDocker for Windows, 這兩個工具已經將 Kitematicdocker-compose 集成好了, 至於這兩個工具是作什麼的我們後面再說, win10 版本須要專業版的, 否則開啓不了Hyper-Vwin7 就別想了,不支持...html

怎麼安裝在 阿里雲鏡像容器服務 裏面都說的很清楚了, 連國內鏡像源都給你安排好了, 我們就進入下一話題nginx

PS: 若是是 CentOS 6 的就須要升級一下系統內核了, centOS6.5 安裝docker, 畢竟都 8102 年了, docker 又是個比較新的東西, 對於稍微久一點的系統的支持就不那麼友好

運行第一個容器

安裝完環境以後就啓動一個鏡像開開眼兒git

docker run -d -p 8080:80 --name local_nginx nginx

而後訪問 http://localhost:8080/ 就能看到 nginx 的初始界面了
run-imagegithub

中間發生了什麼呢?redis

  1. docker run 運行鏡像的起手式, 詳情查看 docker run --help
  2. -d 啓動 docker 守護進程
  3. -p 8080:80 將本地的 8080 端口綁定到容器的 80 端口上
  4. --name local_nginx 分配一個容器名, 不寫的話會默認分配要給, 不過這個仍是頗有用的
  5. nginx 指定運行的鏡像名,若是沒有指定標籤則默認是 latest, 這裏實際上是啓動nginx:latest鏡像

如今能夠查看一下本機都在運行着什麼鏡像docker

PS D:\docker_study> docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
6732fa239270        nginx              "nginx -g 'daemon of…"   18 minutes ago      Up 18 minutes       0.0.0.0:8080->80/tcp   local_nginx

docker ps 只能看到正在運行中的容器, 想看到所有的就是 docker ps -aubuntu

進入這個容器的命令:segmentfault

docker exec -it 6732fa239270 /bin/bash
#或
docker exec -it local_nginx /bin/bash

解釋一下:centos

  1. docker exec 在容器中執行命令
  2. -i 保持stdin打開
  3. -t 分配一個僞終端(tty)
  4. 6732fa239270 或 local_nginx 這裏你也發現了, 能夠是經過 CONTAINER ID 也能夠是 NAMES 這裏的 CONTAINER ID分爲128位長ID和32位短ID, 不過做用都是同樣的
  5. /bin/bash 運行容器中的 /bin/bash 腳本

進入容器中感受其實和進入一個虛擬機同樣, 可是容器和虛擬機有點區別, 這個咱們下一小節會講到bash

關閉容器

docker stop 6732fa239270 或 local_nginx

什麼是容器?什麼是鏡像?

image-container

以前咱們使用 VirtualBox 裝虛擬機的時候有裝盤鏡像, 可是啓動後就是一個個的虛擬機了, 不過在 docker 中和虛擬機仍是有點區別

就拿上圖來講, container就是鏡像的實例化, image 是容器的底層支撐, 其實他們的關係用代碼中的類Class來比喻是最合適的:

  • Class 就是咱們實際開發中寫的一個代碼集合, Object 是 Class 實例化以後生成的一種資源變量
  • Image 也是預先寫好的邏輯, 並存在一個地方, Container 是 Image 啓動以後生成的一個虛擬系統
  • 實例化出來的 Object 不會影響到 Class 中的內容
  • 已經啓動的 Container 也不會影響到 Image 中的邏輯
  • Class 能夠繼承別的 Class, 從而繼承它的特性
  • Image 也是能夠繼承別的 Image, 並在它的基礎上構建新的鏡像
  • 一個 Object 對應着一個 Class, 可是 一個 Class 能夠實例化無數個 Object
  • 同理, 一份 Image 能夠生成無數個 Container, 這就是方便集羣化部署的所在

簡單的說 Container 就是 Image 的兒子, 模樣和 Image 預想的同樣, 可是 Container 運行以後會發生一些改變, 並且這種改變是能夠保存的

經常使用的運行參數和命令

我們先不說構建鏡像的事兒(那是下一章的話題), 這裏先了解一下 docker run 命令中比較經常使用的參數:

-it 創建一個可在終端交互的容器

好比:

docker run -it --name local_nginx nginx:latest /bin/bash
# 或
docker exec -it local_nginx bin/bash

-p 用於宿主機和容器的端口綁定

綁定多個端口就設置多個映射

docker run -d -p 8088:80 -p 4433:443 nginx:latest
# 或    不寫本地端口, docker 將幫你自動分配
docker run -d -p :80 -p :443 nginx:latest
# 或    加上 ip 就綁本地指定的 ip
docker run -d -p 127.0.0.1:8088:80 -p :443 nginx:latest
# 或    照樣不寫本地端口就隨機分配
docker run -d -p 127.0.0.1::80 -p :443 nginx:latest

經過 docker ps 能夠看一下上面兩行命令的執行狀態

➜  test docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
57f65b46bd87        nginx:latest        "nginx -g 'daemon of…"   1 second ago         Up 3 seconds        0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   happy_zhukovsky
0c035ebabe44        nginx:latest        "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:8088->80/tcp, 0.0.0.0:4433->443/tcp     ecstatic_haibt

-v 將宿主機的卷掛載到容器中的指定目錄

docker run -d -p 8088:80 -v /Users/gpf/Documents/docker_study/docker_test/www/:/usr/share/nginx/html/ nginx:latest

這裏本地的目錄要寫絕對路徑, 否則會報錯, 這樣一來, 本地的/Users/gpf/Documents/docker_study/docker_test/www/ 就是容器中的/usr/share/nginx/html/, 就能夠本地更改代碼, 而後容器中運行

-d 後臺運行

想查看日誌的話就 docker logs [containerID] 就行

docker exec 執行 docker 容器中的命令

一般就是用來進入容器中搞七搞八的

docker exec -it 57f65b46bd87 /bin/bash
# 或
docker exsec -it local_nginx /bin/bash

這裏注意兩點:

  • containerID 在不少狀況下均可以用 container Name 來代替, 不少狀況是等價的
  • 命令最後的 /bin/bash 不是必須這麼填, 而是執行的容器中的腳本, 若是你的鏡像是 alpine版的就是 sh, 由於這個版本中就沒有 bash 這個命令

docker ps 容器的運行狀態

docker stop [containerID 或 name] 中止容器

目前版本也增長了 docker container stop [containerID 或 name] 其實做用是同樣的, 不過 docker container 命令底下還有不少別的命令, docker 給各模塊的命令作了細分

docker rm [containerID 或 name] 刪除指定未運行的容器, 一個或多個

docker rm 6dee0a9b5232 582f708af9d3

docker rmi [imageID 或 tag] 刪除宿主機指定的鏡像

這裏要注意若是這個鏡像還有容器在使用就不能刪除掉, 這個時候要先把對應的容器刪掉才行
刪除指定鏡像的容器

docker stop $(docker ps | grep '這裏寫imageName' | awk '{ print $1}')
docker rm $(docker ps | grep '這裏寫imageName' | awk '{ print $1}')

刪除臨時構建的鏡像

docker rmi $(docker images | grep '<none>' | awk '{ print $3}')

prune 大殺器

這一手仍是慎用,一些狀況下可形成 rm -rf /* 的效果

#移除全部未使用的鏡像
docker image prune
#移除全部未運行的容器
docker container prune
#移除全部未使用的本地卷
docker volume prune
...
PS: 由於有這一手, 因此能夠看出官方的態度, 他們貌似也許可能沒準大概差很少不建議把容器當成虛擬機同樣把全部的東西都堆在一個鏡像裏面, 那樣搞不止構建出來的鏡像臃腫, 並且維護性移植性不好, 從目前網上的 docker 鏡像資源來講, 基礎鏡像 alpine > debian > ubuntu > centos, 優先使用最小的基礎構建, 而後整個 image 只爲一個服務而構建, 好比 redis 鏡像裏只要 redis, 沒有什麼 MySQL, memcache 什麼的, 多個獨立的 service 才組成一個 APP, 裏面各個組件替換的話不用考慮其餘組件的環境依賴什麼的, 固然, 這個也是看業務的實際須要, 不能爲了拆分而拆分, 在這之間能找到最合適本身的纔是工具給咱們帶來的便利

docker network 容器之間的互聯

若是隻是在一個容器裏搞來搞去就真的是虛擬機了, docker 的強大之處就是它內部維護一個網絡, 處在相同網絡的容器是能夠互通的

# 新建一個 docker 網絡, -d bridge 是指定網絡模式, 當前是橋接網絡
docker network create -d bridge nginx_swarm
# 啓動兩個 nginx 容器, 分別命名 nginx_swarm_a nginx_swarm_b , 二者都加入了 nginx_swarm 這個網絡  --rm 是當容器中止後自動刪除
docker run -it --rm  --name nginx_swarm_a --network nginx_swarm  nginx /bin/bash
docker run -it --rm  --name nginx_swarm_b --network nginx_swarm  nginx /bin/bash

注意, 咱們並沒把接口暴露出去, 如今隨便在一個容器中 ping 另外一個容器

# 這是在 nginx_swarm_a 中
# 沒有 ping 命令的先裝一個 ping
# apt-get update && apt-get install -y iputils-ping
root@73d04107780f:/# ping -c 3 nginx_swarm_b
PING nginx_swarm_b (172.18.0.3) 56(84) bytes of data.
64 bytes from nginx_swarm_b.nginx_swarm (172.18.0.3): icmp_seq=1 ttl=64 time=0.084 ms
64 bytes from nginx_swarm_b.nginx_swarm (172.18.0.3): icmp_seq=2 ttl=64 time=0.161 ms
64 bytes from nginx_swarm_b.nginx_swarm (172.18.0.3): icmp_seq=3 ttl=64 time=0.146 ms

--- nginx_swarm_b ping statistics ---

docker 能自動的把 server name 轉換成 ip, 咱們只須要標明請求的是哪一個容器, 而不是還要記住它的 ip 地址(固然 ip 地址也能設置)

總結

弄明白如下幾點啓動一個容器應該是沒什麼問題了:

  1. 國內必定要使用國內鏡像源, 否則會痛不欲生, 國內 docker 倉庫鏡像對比
  2. 分清鏡像和容器的概念, 容器就是基於鏡像構建出來的一個實例
  3. 不要往容器中保存數據, 容器應該是無狀態的, 須要持久化保存的就docker run -v xx:xx 或者 docker create volume ... 用獨立的捲來保存
  4. docker 不是虛擬機
  5. 分清楚宿主機端口和容器端口
  6. 處在相同network下的容器才能經過容器明互相訪問

參考資料:
Docker — 從入門到實踐
nginx 官方鏡像

下一章:
不正宗 docker 入門教程 構建一個鏡像(2/3)

相關

  1. 不正宗 Docker 入門教程-啓動一個容器(1/3)
  2. 不正宗 Docker 入門教程-構建一個鏡像(2/3)
  3. 不正宗 Docker 入門教程-使用 Docker-Compose (3/3)

博客原文

相關文章
相關標籤/搜索