過去要架設網站伺服器的第一步就是要購買伺服器硬體,但隨著雲端服務的進步,現在已可以直接跟雲端主機商租賃主機即可。LabVIEW360也是這樣喔,過去都要買伺服器,但現在只要跟雲端主機商購買即可。關於LabVIEW360主機的演進可以參考這裡:歷代LabVIEW360主機 - 張家凱 Ph.D.
什麼是Docker
Docker就是具有作業系統等級的應用程式,因為每一個容器(container)都具有網路、磁碟、記憶體
DevOps
公司分成兩塊,一個是研發人員,另一個是維運人員。需要規範兩者個各自工作,這樣兩者就可以很快地溝通,並解決問題。DevOps (Development和Operations的組合詞)是一種架構,一種規範。主要是規範研發人員與維運人員要做哪些事。大家都會遵循DevOps的架構。
Deveolpers(研發人員)的需求:
- 自由快速的建立與佈署應用程式
- 視需要定義與包裝應用程式
IT Operations(維運人員)的需求:
- 依需要快速與彈性的改變設定
- 標準化,安全性與管理
傳統應用程式的部屬
- 一個實體機器執行一個作業系統應用程式
- 樹薯需要花很多成本購買機器,也要花很多時間安裝作業系統應用程式
- 擴充困難、移植困難、受限於廠商
Hypervisor為主的虛擬化
- ⼀台實體伺服器可以包含很多個應⽤程式
- 每⼀個應⽤程式在⼀台虛擬機內執⾏,一台實體機器可以切成很多虛擬機,不同的應用程式可以分別在不同的虛擬機執行
- 較佳的資源共享池
- ⼀台實體伺服器分割成多台虛擬機
- 擴充容易
- ⽤於雲端虛擬機
- 快速彈性佈署
- 使⽤者付費模式
Container跟VM的差異
Container 是應用程式等級的建置,Container不需要理會作業系統,因為他是應用程式等級的。
VM 是infrastructure 等級的建置,把⼀台實體機視為多台虛擬機。
一開始大家認為Docker會取代虛擬機,但是Docker在2017年標榜不會取代虛擬機,而是做為應用程式的容器。
使用方法:
- 虛擬機上面安裝Docker,在Dockeer上面跑application
- 在Docker裡面啟動另一個Docker
Docker
- 開放源專案,將應⽤程式打包、運送並在lightweight container(輕量級的容器)內執⾏,注意是container,不是作業系統
- 可以在熱門的64 位元核心的Linux上執⾏(不可以在windows上面執行)
- 不須使⽤hypervisor,伺服器資源可以適當的運⽤,而且可以降低添購伺服器資源的額外成本,如:伺服器有64GB記憶體,有10個Docker,則這10個Docker都可以看到並使用這64GB的記憶體,所以不需要額外做資源分散。
- 很多雲端平台支援(其實是所有雲端都支援),包含Amazon EC2、Google Compute Engine、Microsoft Azure、Digital Ocean、OpenStack、IBM Softlayer、Exoscale以及Rackspace,另外Google率先玩K8S,其可以在docker上面啟動docker
為什麼要使用Docker
- 應用程式的可攜性,開發好一次應用程式,可以部署到多個平台上面,不可以安裝在windows上面,但可以安裝在所有的Linux上面。
- Containers 可以在Linux 系統執⾏,可以佈署到雲端環境,個人電腦,資料中心與實體伺服器等…。維運人員不需要管硬體配置,因為這些都已被研發人員設定在container上面,維運人員只要執行container即可。
- 可以視需要啟動上百個containers(如感恩節購物檔期、聖誕節購物檔期…等),不需要時可以立即停⽤。維運人員最喜歡docker的叢集。視需求啟動docker,若不需要就關閉docker。
- 研發人員不需要為了開發程式,而特地安裝作業系統。
當初Docker的由來
每一個開發的軟體所需準備的硬體都不相同,造成研發人員與維運人員的溝通困難。所以參考來自貨櫃的靈感,Docker是程式碼的裝箱。把不同的應用程式包裝在不同的docker上面。
最流行的docker images
nginx, httpd, busybox, postgres, redis, alpine, treafik, memcached, ubuntu, mongo
在vmware安裝ubuntu桌面板
每天開啟Linux的起手式
https://forum.stdb.org/t/topic/31120
安裝Docker
上圖貨櫃狀的東西就是container,必須要先安裝Linux機器,才可以安裝Docker。Docker daemon:Docker服務;Docker client:Docker指令。
- 機器本身是localhost 也是Docker host
- localhost 代表電腦本身
- Docker host 代表執行containers 的電腦
- 當Docker 安裝在Linux 上,Docker 用戶端、Docker 服務、以及所有的containers 都在localhost上運作
- 這表示可以用localhost 的埠號對應到Docker container 的埠號,例如localhost:8000 或
0.0.0.0:8376,這就是port mapping
安裝前準備
- 先進到docker官網:https://www.docker.com
- 或是在google輸入關鍵字:docker ubuntu install,進入到這個網頁 Install Docker Engine on Ubuntu | Docker Docs
官網資料如下:
OS requirements
To install Docker Engine, you need the 64-bit version of one of these Ubuntu versions:
- Ubuntu Focal 20.04 (LTS)
- Ubuntu Bionic 18.04 (LTS)
- Ubuntu Xenial 16.04 (LTS)
Docker Engine is supported on
x86_64
(oramd64
),armhf
, andarm64
architectures.
- 由於ubuntu只能安裝於linux 64bit版本,所以要先確認自己的linux是不是64位元的版本,語法為:
uname -a
移除舊版本
官網資料如下:
Uninstall old versions
Older versions of Docker were called
docker
,docker.io
, ordocker-engine
. If these are installed, uninstall them:$ sudo apt-get remove docker docker-engine docker.io containerd runc
It’s OK if
apt-get
reports that none of these packages are installed.The contents of
/var/lib/docker/
, including images, containers, volumes, and networks, are preserved. If you do not need to save your existing data, and want to start with a clean installation, refer to the uninstall Docker Engine section at the bottom of this page.
- 移除舊版本
- apt-get remove docker docker-engine docker.io
- /var/lib/docker/的內容,包括images、containers 與 networks 會被保留
從Docker文件可以查詢到安裝的方法,因為文件內容過於豐富,所以僅列出網址,請同學自行瀏覽:Install Docker Engine on Ubuntu | Docker Docs
大致上安裝的方式有以下數種方式:
- 使用安裝倉庫,比較難,因為要接到docker倉庫,但是不同機器的安裝版比較會一致,所以最推薦,參考網址:Install Docker Engine on Ubuntu | Docker Docs
- 手動安裝,要有一點技巧,通常手動安裝會遇到相依性的問題,所以不建議手動安裝
- 直接動腳本(測試開發使用,通常用於要抓最新的docker)
安裝docker套件
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
新增公鑰
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) <[email protected]>
sub rsa4096 2017-02-22 [S]
放倉庫
有三種發行版本:
- x86_64 / amd64
- armhf
- arm64
我們使用:x86_64 / amd64
所以指令為:
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
會更新倉庫清單
檢查倉庫清單
指令
ls -l /etc/apt/sources.list*
確認docker倉庫出現的位置
指令
grep -n 'docker' /etc/apt/sources.list
INSTALL DOCKER ENGINE (安裝Docker引擎)
有兩個步驟,首先要先看Docker的版本,
驗證apt是從正確的倉庫下載套件
apt-cache policy docker-ce
更新倉庫清單
apt-get update
列出所有可用的版本
apt-cache madison docker-ce
apt-cache madison docker-ce-cli
須注意,docker-ce跟docker-ce-cli都要安裝才可以。
安裝docker-ce與docker-ce-cli (要注意這兩個版本必須一致)
指令
apt install docker-ce docker-ce-cli
檢查Docker 資訊
docker info
檢查Docker 版本
docker version
檢查/啟動Docker 服務
systemctl list-unit-files | grep 'docker'
systemctl status docker.service
升級docker
安裝好Docker 後,升級是很容易的
驗證Docker 是否安裝正確
docker run hello-world
使用apt 指令升級
apt update
apt install docker-ce docker-ce-cli
apt install containerd.io
docker的指令
docker container run
docker info
docker images # 舊指令
docker image ls # 新指令
Docker引擎
Docker架構
Docker群組
- 預設Docker 服務使用/var/run/docker.sock 的 Unix socket,接收外來的要求
- 如果系統有 docker 群組,Docker 會把 docker.sock 設定為 docker 群組擁有
- 任何屬於 docker 群組的使用者都有執行 docker指令 的權限
- 檢查是否有 docker 群組
- cat /etc/group | grep ‘docker’
根據docker文件的說法,
The
docker
group is created but no users are added to it. You need to usesudo
to run Docker commands. Continue to Linux postinstall to allow non-privileged users to run Docker commands and for other optional configuration steps.
安裝完docker之後,會建立一個docker
的群組,但是群組內沒有任何使用者。若有需要,可以把特定的使用這家到docker群組內。除了系統管理員,只有在docker群組的使用這可以執行docker指令。
我們來驗證一下,有docker群組但是沒有docker帳號:
移除docker
sudo apt-get purge docker-ce docker-ce-cli containerd.io
所有跟docker相關的資料都放在這個目錄 /var/lib/docker
,所以移除docker之後,可以把 /var/lib/docker
目錄清空,語法如下:
sudo rm -rf /var/lib/docker
安裝完docker的後續動作
參考官網doc的說明,安裝完docker之後,根據自身管理需求,可以把使用者加到docker群組中。
Docker container
container是遞送軟體的單位,只能在64位元的核心上運行。不論host的發行版本,但是container與host的架構要一致。
另外,只要linux可以執行的軟體,container也一定可以執行。
Docker的思維
採用貨櫃的觀念,把貨品放在貨櫃裡面。貨品就是image,貨櫃就是container。研發人員在意的就是或對裡面的東西,也就是container裡面的東西。container裡面就是image,image就是作業環境,image裡面跑的就是我們的應用程式,研發人員在意的是程式碼,程式庫,要灌的套件為何,要啟動那些應用程式,資料要如何儲存,如何表達。
維運人員要注意的是container外部,要查詢日誌,確認如何設定,遠端如何存取,port-mapping,檢查container是否正常運作,網路設定。我們現階段只要先知道如何啟動/停止container即可。
Docker的生命週期
- 建立/啟動container
- 停止container
- 移除停用的container
- 刪除image
練習建立互動式container,即「可直接在container裡面下指令」
docker container run -i -t ubuntu /bin/bash
-i
: 讓container 的STDIN 維持開啟,使用互動式(interactive) shell 時需要,要求給鍵盤
-t
: 知會Docker 指定⼀個pseudo-tty 給container,可以啟動⼀個互動式shell 給新的container,要求給螢幕
首先Docker 會檢查本端是否有ubuntu image,如果沒有,則會連線到Docker公司的Docker Hub
registry下載image 來建立新的container,Container 內有網路功能,IP 位址與⼀個橋接介⾯(docker0)與本機溝通,最後Docker在container 內透過/bin/bash 指令啟動⼀個Bash shell
Docker官方文件的指令:
- docker container create,建立一個新的container,但是不啟動
- docker container run,嘗試啟動某container,如果找不到此container,就建立一個container,並啟動它
若要建立container,只有以上兩種方法可以建立container。container start,container restart不算,它們無法建立新的container。
使用互動式Container
Base image 是⼀個的Ubuntu 作業環境,可以做自己想要的設定
hostname
(查詢主機名稱)
cat /etc/os-release
(檢查現在的ubuntu是第幾版)
ps -elf
(process,檢查目前有哪些程式在跑,它們輪流使用CPU;ps有兩種風格,一種是unix風格,另一種是柏克萊風格)
開啟新的terminal視窗
使用指令ps -elf | wc -l
,可以看到作業系統啟動幾個process,一個完整的作業系統大約啟動300個process,一個container作業環境啟動4個process。通常container是1個process,只做單一的工作。dpkg -l
(詢問安裝了幾個套件)
cat /etc/apt/sources.list
(詢問倉庫位置)
cat /etc/hosts
(主機、IP名稱對照表)
也可以印證之前所說的:每一個container都有其IP addressip addr show
(查ip)
container回傳,沒有安裝ip這個指令。apt install python3
(安裝python3)
先查詢有沒有安裝python3,指令:python3 -V
如果沒有,再使用指令apt install python3
來安裝。
虛擬機是一個完整的作業系統,container是一個簡單的作業環境
目前除了google的雲端環境,其他的docker的container裡面不能再跑docker的container。
檢查系統資源
uname -r (查詢核心)
nproc (查詢CPU數量)
free -ht (查詢記憶體容量)
df -h (查詢硬碟)
離開container
方法一:exit
方法二:ctrl + d
container仍然存在,可以使用下列的指令列出所有的container:
docker container ls -a
除了google雲端之外,所有container內都不能下docker指令,有安裝 docker-ce-cli
套件的地方就可以下docker指令。
Container命名法則
Docker 有三種方式識別containers
- Short UUID (例如f7cbdac22a02)
- Longer UUID
- Name (例如python_dev)
Docker 會對每⼀個新建立的container 自動產生⼀個隨機的名稱
也可以利用–name 選項來指定固定的container名稱
docker container run --name my_linux -i -t ubuntu /bin/bash
合法的container 名稱包含:
- [a-zA-Z0-9_.-]
- 文數字、底線、句點與 “-”
Container 名稱必須唯⼀
對已存在的container 重新命名
docker container rename agitated_darwin my-linux
如果要建立同名的container,必須先刪除已存在的container
docker container rm my-linux
重啟互動式Container
⼀旦離開互動式container,shell 停止運作,container 就會停止
如果要再⼀次使用互動式container,就必須要重新啟動該container
列出所有的containers:
docker container ls -a
重新啟動container
docker container start my_linux
離開container但不關閉container (detach)
組合鍵:ctrl+p,ctrl+q
重接到互動式session
docker container attach my_linux
可能需要按[Enter] 取得提示字元
停止執行中的container
docker container stop NAME
docker指令
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
-- config string |
Location of client config files (default “/root/.docker”) | |
---|---|---|
-c, | --context string |
Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with “docker context use”) |
-D, | --debug |
Enable debug mode |
-H, | --host list |
Daemon socket(s) to connect to |
-l, | --log-level string |
Set the logging level (`“debug” |
--tls |
Use TLS; implied by --tlsverify |
|
--tlscacert string |
Trust certs signed only by this CA (default “/root/.docker/ca.pem”) | |
--tlscert string |
Path to TLS certificate file (default “/root/.docker/cert.pem”) | |
--tlskey string |
Path to TLS key file (default “/root/.docker/key.pem”) | |
--tlsverify |
Use TLS and verify the remote | |
-v, | --version |
Print version information and quit |
Management Commands:
command | info |
---|---|
builder | Manage builds |
config | Manage Docker configs |
container | Manage containers |
context | Manage contexts |
engine | Manage the docker engine |
image | Manage images |
network | Manage networks |
node | Manage Swarm nodes |
plugin | Manage plugins |
secret | Manage Docker secrets |
service | Manage services |
stack | Manage Docker stacks |
swarm | Manage Swarm |
system | Manage Docker |
trust | Manage trust on Docker images |
volume | Manage volumes |
Commands:
command | info |
---|---|
attach | Attach local standard input, output, and error streams to a running container |
build | Build an image from a Dockerfile |
commit | Create a new image from a container’s changes |
cp | Copy files/folders between a container and the local filesystem |
create | Create a new container |
diff | Inspect changes to files or directories on a container’s filesystem |
events | Get real time events from the server |
exec | Run a command in a running container |
export | Export a container’s filesystem as a tar archive |
history | Show the history of an image |
images | List images |
import | Import the contents from a tarball to create a filesystem image |
info | Display system-wide information |
inspect | Return low-level information on Docker objects |
kill | Kill one or more running containers |
load | Load an image from a tar archive or STDIN |
login | Log in to a Docker registry |
logout | Log out from a Docker registry |
logs | Fetch the logs of a container |
pause | Pause all processes within one or more containers |
port | List port mappings or a specific mapping for the container |
ps | List containers |
pull | Pull an image or a repository from a registry |
push | Push an image or a repository to a registry |
rename | Rename a container |
restart | Restart one or more containers |
rm | Remove one or more containers |
rmi | Remove one or more images |
run | Run a command in a new container |
save | Save one or more images to a tar archive (streamed to STDOUT by default) |
search | Search the Docker Hub for images |
start | Start one or more stopped containers |
stats | Display a live stream of container(s) resource usage statistics |
stop | Stop one or more running containers |
tag | Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE |
top | Display the running processes of a container |
unpause | Unpause all processes within one or more containers |
update | Update configuration of one or more containers |
version | Show the Docker version information |
wait | Block until one or more containers stop, then print their exit codes |