Linux Docker 自學筆記 (1)

過去要架設網站伺服器的第一步就是要購買伺服器硬體,但隨著雲端服務的進步,現在已可以直接跟雲端主機商租賃主機即可。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年標榜不會取代虛擬機,而是做為應用程式的容器。

使用方法:

  1. 虛擬機上面安裝Docker,在Dockeer上面跑application
  2. 在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

  1. 應用程式的可攜性,開發好一次應用程式,可以部署到多個平台上面,不可以安裝在windows上面,但可以安裝在所有的Linux上面。
  2. Containers 可以在Linux 系統執⾏,可以佈署到雲端環境,個人電腦,資料中心與實體伺服器等…。維運人員不需要管硬體配置,因為這些都已被研發人員設定在container上面,維運人員只要執行container即可。
  3. 可以視需要啟動上百個containers(如感恩節購物檔期、聖誕節購物檔期…等),不需要時可以立即停⽤。維運人員最喜歡docker的叢集。視需求啟動docker,若不需要就關閉docker。
  4. 研發人員不需要為了開發程式,而特地安裝作業系統。

當初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

安裝前準備

官網資料如下:

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 (or amd64), armhf, and arm64 architectures.

  • 由於ubuntu只能安裝於linux 64bit版本,所以要先確認自己的linux是不是64位元的版本,語法為:

    uname -a

移除舊版本

官網資料如下:

Uninstall old versions

Older versions of Docker were called docker, docker.io, or docker-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

大致上安裝的方式有以下數種方式:

  1. 使用安裝倉庫,比較難,因為要接到docker倉庫,但是不同機器的安裝版比較會一致,所以最推薦,參考網址:Install Docker Engine on Ubuntu | Docker Docs
  2. 手動安裝,要有一點技巧,通常手動安裝會遇到相依性的問題,所以不建議手動安裝
  3. 直接動腳本(測試開發使用,通常用於要抓最新的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]

放倉庫

有三種發行版本:

  1. x86_64 / amd64
  2. armhf
  3. 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*

image

確認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-cedocker-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引擎

image

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 use sudo 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帳號:
image

移除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的生命週期

  1. 建立/啟動container
  2. 停止container
  3. 移除停用的container
  4. 刪除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 (查詢主機名稱)
    image
  • 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名稱對照表)
    image
    也可以印證之前所說的:每一個container都有其IP address
  • ip addr show (查ip)
    image
    container回傳,沒有安裝ip這個指令。
  • apt install python3 (安裝python3)
    先查詢有沒有安裝python3,指令:python3 -V
    image
    如果沒有,再使用指令 apt install python3 來安裝。
    image

虛擬機是一個完整的作業系統,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
image

如果要建立同名的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
4個讚