歡迎光臨
每天分享高質量文章

Docker新手指南

什麼是容器?

容器只是實現流程隔離的一種方式。與虛擬機器不同,它們不透過模擬硬體實現隔離,而是透過使用現有的Linux核心功能實現隔離。
在一個典型的Unix / Linux作業系統中,所有行程共享相同的使用者空間,但是透過在Linux 2.6+中引入的新功能,您可以建立一個自己單獨擁有的獨立環境(如檔案樹、執行緒等)的行程。這些與其他核心技術相結合的特性是容器背後的魔力。
在本文中,我將介紹基本的Docker命令和概念。閱讀完畢後,您將能夠採用一些Docker功能來加速和簡化您的日常工作流程。

安裝Docker

在OS X / Windows中使用安裝嚮導安裝Docker是一項簡單的任務。可以在Docker社群頁面上找到適用於作業系統的安裝程式。在Linux上,Docker通常在分發包管理器中可以找到。
在Fedora[1]中安裝Docker:
sudo dnf install docker
啟動行程:
sudo systemctl start docker
使Docker行程開機自啟動:
sudo systemctl enable docker

在其他使用Systemd的Linux發行版中,這些步驟類似。

入門

Hello World
一旦你完成安裝,我們可以嘗試一個容器的Hello World應用:
#sudo is only for Linux
sudo docker run --name hello -it busybox echo "Hello World!" # Hello World!
只有在執行某些Linux發行版時才需要使用sudo,但請記住,Docker需要管理員許可權才能建立遏制。在編寫本文時,在OSX和Windows中使用一些基於Linux的虛擬機器,所以Docker命令可以在這些系統中沒有特權使用者的情況下執行。
如何工作

sudo docker run <options> <image> <command to run inside the container>
run引數項建立並執行一個容器,其中一個特點是Docker將容器的生命週期和執行行程進行了系結(在這個例子中是Linux的echo命令),這意味著當行程結束後容器也跟隨終止了。
  • Name:我們設定容器的名稱,如果你不選擇任何Docker將隨機選擇一個。

  • It:互動式的,它將我們的終端連線到容器虛擬TTY的輸出,允許與正在執行的行程互動。

  • Busybox:這是建立容器的基礎映像,可以認為帶有應用程式執行所需的檔案和檔案夾組成的zip檔案。 Docker Hub中有一個完整的社群基礎映象,使用busybox[2]是因為它非常輕便,壓縮後只有715 KB

  • Echo:正如前所述,echo是執行的命令,包含在busybox映象中。

如果想檢查命令是否在busybox中可用,可輸入如下命令:
sudo docker run -it busybox ls /bin/
列出快取的映象
當你第一次執行Docker命令時,映象被下載並被快取以加快速度。可以使用以下命令檢查本地映象:
sudo docker images
守護行程樣式下執行
在某些情況下,我們不想直接與某些應用程式(如伺服器)進行互動,此時我們希望生成該行程並傳回終端以繼續工作,Docker為我們提供了一種使用守護行程樣式執行行程的方法,像如下命令使用-d引數這樣:
sudo docker run -d --name snooze busybox sleep 15
這個行程將在後臺執行15s後退出。
列出後臺執行的容器
一旦容器在後臺執行,可以使用如下ps命令檢查容器狀態:
sudo docker ps
殺死執行的容器
停止一個容器很簡單:
sudo docker stop [name of your container]
#例如
sudo docker stop snooze
該命令會停止執行的容器,但是Docker服務會將建立的容器和其關聯的命令快取在磁碟中。如果你想再次重覆執行同樣的命令,只需要執行:
sudo docker start snooze
如果想改變配置並重用容器名,需要停止並刪除容器,假設我們想改變snooze容器為休眠10秒而不是15秒:
#stop & clean
sudo docker stop snooze
sudo docker rm snooze
#re-create
sudo docker run -d --name snooze busybox sleep 10

掛載

引數v允許我們將主機的檔案掛載、對映到容器的檔案夾。建立一個檔案如:
echo 'Hello World' > hello
現在我們使用busybox中提供的獨立文字編輯器來開啟檔案:
#使用容器的VIM開啟檔案
sudo docker run -it busybox vi hello
沒有任何反應,這是因為vi行程是孤立的,無法訪問容器外的檔案。為瞭解決這個問題,我們需要掛載該檔案夾,以便我們的編輯器能夠找到該檔案。
#the :z in /app:z -> is for SELinux, non-Linux can ignore this.
sudo docker run -it -v "$(pwd)":/app:z busybox vi app/text
這將掛載當前目錄$pwd為容器內的/app目錄。如果目錄在容器內不存在,將自動建立,然後,使用vi開啟檔案位置vi app/hello。
一些實驗:
  • 引數v將改寫容器內的以前的檔案夾。如果存在,它將被替換為提供的檔案夾

  • 該命令從字面上是掛載檔案夾,因此容器一旦被殺死,容器對該檔案夾所做的每個更改都將被保留,如果您希望將資料庫資料儲存在容器生命週期之外,這是一個好方式

  • 容器將有權訪問您的系統資源(共享檔案夾),所以要小心。

網路

選項p允許我們公開一個隔離的埠並透過特定的主機埠重定向。
為了說明網路如何與容器配合工作,首先讓我們開始編寫一個簡單的JavaScript指令碼來啟動伺服器。我們將在本地機器上執行此操作,因此我們來編寫一些程式碼。
require('http')
 .createServer((req, res) => { res.end('Hello World!') }).listen(8080)
我們將呼叫這個檔案index.js,它簡單的建立了一個等待8080埠連線的伺服器。當有人連線它時,它會傳送“Hello World!”
下一步是在容器內執行指令碼,可以執行如下命令:
sudo docker run -it -v "$(pwd)":/app:z --name myserver mhart/alpine-node node app/index.js
這裡的新事物是基礎映象mhart/alpine-node,它將拉取一個Node.JS容器,然後像以前一樣使用-v掛載檔案夾,然後執行隔離節點的app/index.js行程。
讓我們看看我們的伺服器是否工作:
sudo docker exec -it myserver wget -qO- localhost:8080
# Hello World
這個命令是測試伺服器在容器內工作,獲得hello world反饋。現在我們試下從主機連線伺服器,開啟終端,執行:
curl http://localhost:8080
#curl: (7) Failed to connect to localhost port 8080: Connection refused
我們無法連線,因為容器的網路是隔離的,我們需要實現埠轉:
# stopping our container
sudo docker stop myserver  
sudo docker rm myserver
sudo docker run -it -v "$(pwd)":/app:z -p 8080:8080 --name myserver \
mhart/alpine-node node app/index.js
現在試下在瀏覽器中開啟網址http://locahost:8080,你會看到hello world。
恭喜!你已經寫了一個完美的容器化NodeJS應用。其中一個最大的好處是你可以在不安裝NodeJS的情況下實現NodeJS應用,並且您可以使用此功能來安裝其他型別的軟體,如資料庫,其他微服務等。

快速提示

在我的日常工作中,我總是需要整合MongoDB和Redis,但安裝這些通常是一個痛苦的過程,我透過在.zshrc中建立一些bash指令碼來解決了這個問題。
function new_mongo {
 docker run -d --name mongodb -p  27017:27017 mongo
}
# the : here means image tag, usually if the image is done correctly
# like in this case tag version match the Redis version
function new_redis {
 docker run -d  --name redis  -p 6379:6379 redis:3.2
}
function stop_mongo {
 docker stop mongodb
 docker rm mongodb
}
function stop_redis {
 docker stop redis
 docker rm redis
}
在你的.bashrc或者.zshrc底部新增這一行,然後執行source ~/.bashrc || source ~/.zshrc,這樣你就可以實現上面的功能了。
new_mongo # it will spin up a new mongodb instance. 
new_redis # it will spin up a new redis instance.
# to stop this containers
stop_mongo
stop_redis
現在,您將能夠以零配置按需部署本地MongoDB或Redis實體,並且一個優勢(至少在我看來)是這些實體中的資料是短暫的,這意味著當您終止容器時,它將重置資料庫以及釋放佔用的空間。

Linux安全

如果你在Fedora使用引數v執行掛載檔案夾的命令,會遇到如下錯誤:
sudo docker run -it -v "$(pwd)":/app busybox ls app/text
#ls: can't open '.': Permission denied
這是因為SELinux[3]預設策略將禁止任何主機上的讀寫操作,以防止駭客在容器外執行操作,SELinux透過在核心級上的安全規則來保護您。
要將檔案夾安裝在支援SELinux的機器中,您需要指定z引數,這將更改SELinux背景關係,並允許容器執行掛載動作。
# "$(pwd)" will get the actual directory, is equivalent to do pwd
docker run -it -v "$(pwd)":/app:z busybox /bin/sh
另一種方式(但不推薦)是暫時禁用這種保護:
su -c "setenforce 0"
完成後開啟保護:
su -c "setenforce 1"
相關連結:
  1. https://getfedora.org/es/workstation/

  2. https://hub.docker.com/r/library/busybox/tags/

  3. https://en.wikipedia.org/wiki/Security-Enhanced_Linux

原文連結:https://dzone.com/articles/docker-for-beginners

Kubernetes零基礎進階培訓

本次培訓內容包括:容器原理、Docker架構及工作原理、Docker網路與儲存方案、Harbor、Kubernetes架構、元件、核心機制、外掛、核心模組、Kubernetes網路與儲存、監控、日誌、二次開發以及實踐經驗等,點選瞭解具體培訓內容

4月20日正式上課,點選閱讀原文連結即可報名。
贊(0)

分享創造快樂