Docker 入門指南
Docker 入門指南
目錄
- 基礎概念
- 安裝教程
- 基本操作
- 常用安裝
- 構建操作
- 容器編排
壹.基礎概念
什麼是Docker?
Docker是基於Go開發的應用容器引擎,屬於 Linux 容器的一種封裝,提供簡單易用的容器使用介面。
解決難題:
- 環境配置不一致
- 虛擬機累贅(資源佔用大、啟動慢等)
虛擬機與容器的差別
主要用途:
提供一次性的環境。比如,本地測試他人的軟體、持續集成的時候提供單元測試和構建的環境。
提供彈性的雲服務。因為 Docker 容器可以隨開隨關,很適合動態擴容和縮容,組建微服務架構。
當人們說 “Docker” 時,他們通常是指 Docker Engine,它是一個客戶端-伺服器應用程式, 由 Docker 守護進程、REST API、命令行介面(CLI)組成。
結構
結構
- 客戶端調用 Docker
- Docker 從 Registry 拉取鏡像(image)
- 通過鏡像生成容器(container)實例
鏡像 image
Docker 把應用程式及其依賴,打包在 image 文件裡面。image 文件可以看作是容器的模板。Docker 根據 image 文件生成容器的實例
image 文件是通用的。一般來說,為了節省時間,我們應該盡量使用別人製作好的 image 文件。即使要訂製,也應該基於別人的 image 文件進行加工,而不是從零開始製作。
容器 container
容器是一個鏡像的可運行的實例,可以使用 Docker REST API 或者 CLI 來操作容器,容器可以擁有自己的 root 文件系統、自己的網路配置、自己的進程空間,甚至自己的用戶 ID 空間。
容器內的進程是運行在一個隔離的環境里,使用起來,就好像是在一個獨立於宿主的系統下操作一樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。
註冊表(倉庫)registry
存放鏡像的地方(公有/私有)
為了方便共享,image 文件製作完成後,可以上傳到網上的倉庫。Docker 的官方倉庫 Docker Hub 是最重要、最常用的 image 倉庫。
UnionFS 聯合文件系統
聯合文件系統(UnionFS)是一種分層、輕量級並且高性能的文件系統,它支援對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下。
聯合文件系統是 Docker 鏡像的基礎。鏡像可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以製作各種具體的應用鏡像。
特性:一次同時載入多個文件系統,但從外面看起來只能看到一個文件系統。聯合載入會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄。
鏡像載入原理
Docker的鏡像是由多層文件系統組成:
分層
bootfs(boot file system)主要包含 bootloader 和 kernel。bootloader 主要是引導載入kernel,完成後整個內核就都在記憶體中了。此時記憶體的使用權已由bootfs轉交給內核,系統卸載 bootfs。可以被不同的 Linux 發行版共用。
rootfs(root file system),包含典型Linux系統標準目錄和文件。相當於各種不同作業系統發行版(Ubuntu,Centos等)。因為底層直接用Host的kernel,rootfs只包含最基本的命令,工具和程式就可以了。 當進行修改或者更新時,會在當前鏡像層上新建新的層級。
分層結構
容器啟動時會在最上層創建一個可讀寫的容器層(其它層只讀)
不同鏡像的相同文件層無需再次下載
貳.安裝
不同版本安裝
Tips:需要卸載舊版本
Ubuntu
# 更新apt軟體包索引並允許使用儲存庫
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加Docker的官方GPG密鑰
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
# 設置穩定的存儲庫
$ echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] //download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安裝最新的Docker引擎
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
# 運行hello world
$ sudo docker run hello-world
# 顯示輸出:
> Hello from Docker!
Centos
# 安裝所需的軟體包。
$ sudo yum install -y yum-utils
# 使用以下命令來設置穩定的存儲庫。
$ sudo yum-config-manager --add-repo //download.docker.com/linux/centos/docker-ce.repo
# 安裝DOCKER引擎
# (centos8 此步containerd.io版本過低,解決方案://www.backendcloud.cn/2020/03/16/centos8installdocker/ )
$ sudo yum install docker-ce docker-ce-cli containerd.io
# 開機自啟並啟動
$ sudo systemctl enable docker
$ sudo systemctl start docker
# 測試安裝效果
$ docker version
Raspberry Pi OS (Raspbian)
# 不能直接使用存儲庫安裝,需要使用腳本二進位安裝:
# 註:其實無論什麼發行版都可以通過二進位安裝,也可以通過腳本自動安裝,不過要注意,使用腳本前需要確認腳本是否安全,並且因為腳本是全自動,也可能會安裝很多其他的東西 /滑稽
$ curl -fsSL //get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
$ sudo usermod -aG docker $USER
# 開機自啟,並啟動
$ sudo systemctl enable docker
$ sudo systemctl start docker
# 一般arm架構無法直接使用X86的image,需要使用Dockerfile重新構建arm版或使用別人編譯好的arm架構版image
# 可以在 docker Hub 搜 arm 或 rpi
# 還有常見的arm架構倉庫: arm32v7、arm64v8、hypriot
Manjaro
# 如果你的系統也和 Manjaro 一樣有包管理器的話那就簡單多了,這裡舉 pacman 或 yay 的例子:
# 更新包管理器
$ sudo pacman -Syu
# 安裝docker
$ sudo pacman -S docker
# 完事,確認下
$ sudo docker version
# 設置開機自啟並啟動
$ sudo systemctl enable docker
$ sudo systemctl start docker
其他系統
# win和mac官方都有桌面版可以直接下載安裝,並且還可以附帶UI操作介面應用
# win版需要開啟 WSL2 或者 Hyper_v 後才能安裝,但是以上2者跟虛擬機不兼容
# Debian 和 Fedora 在 Docker 官網文檔也有安裝方法
安裝後的通用操作
設置中國鏡像源
# 阿里加速服務://??????.mirror.aliyuncs.com (需自己申請個人加速服務地址,加速服務不只是提供鏡像加速,還有 docker 在各種作業系統的安裝文檔和加速,註冊地址://cr.console.aliyun.com/undefined/instances/mirrors)
# 或者一些其他的鏡像(建議使用阿里的鏡像):
# 官方 - //registry.docker-cn.com
# 網易 - //hub-mirror.c.163.com
# Azure 中國鏡像 - //dockerhub.azk8s.cn
# 這裡僅展示ubuntu和centos的操作,對於 Docker for Windows、Docker for Mac 在設置中編輯 daemon.json ,增加和下面一樣的字元串即可
# 使用vim編輯
$ sudo vim /etc/docker/daemon.json
# 複製進去:
{
"registry-mirrors": ["//??????.mirror.aliyuncs.com","//registry.docker-cn.com"]
}
# 或者命令寫入:
$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["//??????.mirror.aliyuncs.com"]
}
EOF
# 然後重啟服務
$ sudo systemctl daemon-reload && sudo systemctl restart docker
# 查看是否成功(看Registry Mirrors項):
$ docker info
設置用戶組
設置用戶組,打 docker 命令不用加 sudo
# 添加組,一般安裝完會自動創建好了
$ sudo groupadd docker
# 把docker命令加入組中
$ sudo usermod -aG docker $USER
重新登錄或:
$ su ${USER}
設置開機自啟
# 用 systemctl 管理服務的 linux 版本可以直接這樣:
# 開機自啟並啟動
$ sudo systemctl enable docker
# 重新啟動
$ shutdown -r now
# 查看是否啟動狀態
$ systemctl status docker
其他安裝
docker-compose
# Win和Mac安裝完docker後自帶docker-compose
# linux上安裝docker-compose:
# 下載
$ sudo curl -L "//github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 設置可執行許可權
$ sudo chmod +x /usr/local/bin/docker-compose
# 安裝完成,查看版本
$ docker-compose --version
# 如需卸載:
$ sudo rm /usr/local/bin/docker-compose
叄.基本操作
docker命令圖解
小Tisp1:linux中的命令行參數
-後面跟縮寫,如 -a,-q,-aq(相當於-a -q) –後面跟完整參數名,如–all,–quiet
小Tisp2:命令行中換行:
win換行: ^
linux換行: \
小Tisp3:win的路徑輸入:
還像在win中【d:\】嗎?不對喲,是:
/d/tool/DockerDesktop/minio/data
基本資訊
資訊查看
# 顯示docker的基本資訊
$ docker version
# 系統資訊,鏡像和容器的數量
$ docker info
# 查看docker事件
$ docker events [OPTIONS]
# 全部幫助
$ docker --help
# 個別命令幫助
$ docker [命令] --help
倉庫 registry
docker search
# 搜索鏡像
docker search [OPTIONS] 鏡像名
# 相當於在 hub.docker.com 頁面搜索
選項:
-f,--filter filter 過濾輸出
--format string 格式化輸出
--limit int 最大搜索結果數(默認為25)
--no-trunc 不截斷輸出
示例:
docker search mysql
docker login
# 登錄到registry
docker login [OPTIONS] [SERVER]
常用選項:
-p ,--password 密碼
-u ,--username 用戶名
示例:
docker login
>輸入帳號
>輸入密碼
# 登錄到私有registry
docker login localhost:8080
docker login -u username -p userpasswd 192.168.1.33:5000
# 註銷
docker logout [SERVER]
鏡像 image
docker images
docker images [OPTIONS] [REPOSITORY[:TAG]]
docker images = docker image ls
常用選項:
-a , --all # 顯示所有(默認隱藏中間影像)
--digests # 顯示摘要
-f , --filter filter # 過濾輸出
--format string # 格式化輸出
--no-trunc # 不截斷輸出(ID縮寫是12位,不截斷輸出就是64位)
-q , --quiet # 只顯示id
示例:
# 只顯示ID
docker images -aq
docker pull
# 拉取鏡像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
# 默認倉庫為docker.io/library/
# 默認版本為:latest
# 所以docker pull mysql 等價於 docker pull docker.io/library/mysql:latest
docker rmi
# 刪除鏡像
docker rmi [OPTIONS] IMAGE [IMAGE...]
常用選項:
-f 強制刪除影像
# 刪除所有( linux 小技巧)
$ docker rmi -f $(docker images -aq)
# 或
$ docker images -qa | xargs docker rmi
docker import 與 export
# 導出鏡像
docker export [OPTIONS] CONTAINER
常用選項:
-o,--output 寫入文件,而不是STDOUT
例子:
docker export exampleimage > exampleimage.tar
# 或
docker export --output="exampleimage.tar" exampleimage
# 導入鏡像
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
常用選項:
-c, --change 將Dockerfile指令應用於創建的映像(支援的Dockerfile指令: CMD| ENTRYPOINT| ENV| EXPOSE| ONBUILD| USER| VOLUME|WORKDIR)
-m,--message 設置導入影像的提交消息
--platform API 1.32+ ;如果伺服器支援多平台,則設置平台
示例:
# 遠程
docker import //example.com/exampleimage.tgz
# 本地
docker import /path/to/exampleimage.tgz
# 或
cat exampleimage.tgz | docker import - exampleimagelocal:new
# 本地目錄
sudo tar -c . | docker import - exampleimagedir
容器 container
基礎操作
# 啟動容器
docker start
# 重啟容器
docker restart
# 停止容器
docker stop
# 殺掉容器
docker kill
# 查看容器元數據(詳細資訊)
docker inspect
# 查看內容佔用
docker stats
# 查看容器中的進程資訊
docker top
docker ps
# 查看容器列表
docker ps [OPTIONS]
docker ps = docker container ls
常用選項:
-a,--all 顯示所有容器(默認顯示正在運行)
-f,--filter 過濾輸出
--format 使用Go模板格式化輸出
-n,--last 顯示n個最後創建的容器
-l ,--latest 顯示最新創建的容器
--no-trunc 不要截斷輸出
-q, --quiet 僅顯示容器ID
-s, --size 顯示文件總大小
docker run
# 運行容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# run的時候如果本地沒有鏡像的話,會自動執行拉取操作
常用選項:
-d,--detach 在後台運行容器並列印容器ID
-e,-env list 設置環境變數
-h,--hostname string 容器主機名
--mount mount 綁定卷
--name string 分配名稱
--network 連接到網路
--rm 退出時自動刪除容器
-v,-volume list 映射卷
-p 指定容器的埠 如-p 8080:8080
例子:
-p ip:主機埠:容器埠
-p 主機埠:容器埠
-p 容器埠
-i 互動式操作。
-t --tty 分配一個偽TTY連接終端
-m --memory bytes 記憶體限制
--privileged 賦予最高許可權(危,無限制,有主機許可權)
--restart string 重啟策略,參數示例:
--restart=always 自啟
--restart=on-failure:3 非正常退出 重試3次
--restart=unless-stopped 不嘗試啟動
示例:
# 容器停止後自動刪除
docker run --rm hello-world
# 後台運行並給它命名
docker run -itd --name uuu ubuntu
# run並且以終端模式進入該容器
docker run -it ubuntu /bin/bash
# 輸入 exit 回車 停止並退出容器
# 或快捷鍵 Ctrl + P + Q 不停止容器的退出
# 運行並映射卷到主機
docker run -p 3306:3306 --name mysql -v "$(pwd)"/docker_v/mysql/conf:/etc/mysql/conf.d mysql
docker rm
# 刪除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]
常用選項:
-f, --force 強制刪除正在運行的容器(使用SIGKILL)
-l ,--link 刪除指定的鏈接
-v,--volumes 刪除與容器關聯的匿名卷
示例:
# 刪除指定容器 不能刪除正在運行的容器,如果強制刪除 rm -f
docker rm 容器id
# 刪除所有容器
docker rm -f $(docker ps -aq)
# 刪除所有容器
docker ps -a -q|xargs docker rm
docker logs
# 查看容器日誌
docker logs [OPTIONS] CONTAINER
常用選項::
--details 顯示詳細資訊
-f,--follow 跟隨日誌輸出
--since string 顯示自時間戳
--tail string 顯示行數
-t,--timestamps顯示時間戳
例子:
docker logs
docker logs -f -t --tail 10 容器名或id
docker exec
# 連接容器終端(進入容器)
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
# 也可以用 docker attach 進入容器終端
常用選項:
-d,--detach 在後台運行命令
-e,-env 環境變數
-i,--interactive 即使未連接STDIN仍保持打開狀態(互動式操作)
-t,--tty分配偽TTY(終端)
# 同上面的run中操作一樣,這一步可以在運行後進入到容器中,如:
docker exec -it uuu /bin/bash
# 區別
# docker exec 進入容器後開啟一個新的終端,可以在裡面操作(常用)
# docker attach 進入容器正在執行的終端,不會啟動新的進程
docker cp
# 拷貝容器中的文件
docker cp 容器名/id:容器內路徑 主機文件路徑
示例:
#拷貝容器數據到主機
docker cp 容器名:/home/file /home
docker update
#更新基礎設置
docker update [OPTIONS] CONTAINER [CONTAINER...]
常用選項:
-c cpu權重
-m 記憶體限額
--restart 重啟策略
示例:
# 更新某個容器的重啟策略,使其重啟自動啟動
docker update --restart=always <CONTAINER ID>
其他操作
docker volume create
# 創建卷
docker volume create [OPTIONS] [VOLUME]
選項:
-d , --driver 默認local 指定卷驅動程式名稱
--label 設置卷的元數據
--name 指定卷名
-o , --opt 設置驅動程式特定選項
示例:
# 創建一個卷
docker volume create hello
# 使用這個卷
docker run -d -v hello:/world busybox ls /world
掛載卷說明
# 將容器內的目錄,掛載到宿主機上或其他容器內,實現同步和共享,並且刪除日期後掛載到本地的文件也不會消失
# 指定目錄掛載:
dokcer run -it -v 主機內目錄:容器內目錄 鏡像名/id
# 匿名掛載:
docker run -d -v 容器內目錄 鏡像名/id
# 具名掛載
docker run -d -v 卷名:容器內目錄 鏡像名/id
# 查看所有掛載的卷:
docker volume ls
# 查看卷資訊
docker volume inspect 卷名
# 所有docker容器內的卷,在未指定主機內目錄時,都會創建在:/var/lib/docker/volumes/卷名/_data 下
示例:
# minio文件伺服器,指定目錄掛載
docker run -p 9000:9000 --name minio -d \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=admin123456" \
-v /home/cc/minio/data:/data \
-v /home/cc/minio/config:/root/.minio minio/minio server /data
# 數據卷容器(多個容器共享一個卷)
docker run -it --name 容器02 --volumes from 容器01 鏡像名/id
docker network create
# 創建一個網路
docker network create [OPTIONS] NETWORK
常用選項:
-d , --driver 驅動程式,默認bridge,可選overlay或第三方或自定義
--config-from 從中複製配置的網路
--ipv6 啟用IPv6網路
--label 在網路上設置元數據
network創建參數挺多的,這裡不贅述,感興趣可以看下官網文檔
示例:
# 創建一個overlay 模式的網路
docker network create -d overlay my-network
# 容器連接至該網路
docker run -itd --network=my-network busybox
網路模式說明
# 查看IP
$ ip addr
# 查看docker0
$ ip addr show docker0
bridge 模式
bridge模式
# 當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋
# 這個docker0 也作為容器的默認網關,主機也可以ping通容器,但是容器之間是隔離的
# 不寫–net參數,默認就是bridge模式。使用docker run -p時,docker 實際是在iptables做了DNAT規則,實現埠轉發功能。可以使用iptables -t nat -vnL查看。
# 新建一個網路
$ docker network create -d bridge my-net
# 運行一個容器並連接到新建的 my-net 網路
$ docker run -it --rm --name busybox1 --network my-net busybox sh
# 加入系統網路的應用,可以互相ping通,如我可以在其他加入了my-net的容器里:
$ ping busybox
> PING busybox (172.19.0.2): 56 data bytes
> 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.064 ms
> 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.143 ms
# 如果你有多個容器之間需要互相連接,推薦使用Docker Compose。
Host 模式
# 如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個 Network Namespace
示例:
$ docker run -tid --net=host --name docker_host1 ubuntu-base:v3
Container 模式
# 這個模式指定新創建的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享
# 示例,獨立的 docker_bri1 網路:
$ docker run -tid --net=container:docker_bri1 \
--name docker_con1 ubuntu-base:v3
None 模式
None 模式
# Docker 容器擁有自己的 Network Namespace,但是,並不為 Docker 容器進行任何網路配置(如有需要,自己手動配置)
肆.常用安裝
Portainer
# 可視化管理介面
# 其他類似的還有:Rancher、cAdvisor
安裝示例:
$ docker volume create portainer_data
$ docker run -d --name portainer --restart unless-stopped -p 9000:9000 \
-v ~/docker_v/portainer/data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer-ce:latest
安裝後能很方便的管理 docker:
Mysql
# MySQL(5.7.19)的默認配置文件是 /etc/mysql/my.cnf 文件。
# 如果想要自定義配置,建議向 /etc/mysql/conf.d 目錄中創建 .cnf 文件。
具體操作:
# 這裡已經把配置文件my.cnf放到了~/docker_v/mysql/conf:
# 然後運行命令:
$ docker run -p 3306:3306 --name mysql \
-v ~/docker_v/mysql/conf:/etc/mysql/conf.d \
-v ~/docker_v/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-itd mysql:5.7.29
Nginx
$ docker run -d -p 80:80 --name nginx \
-v /root/nginxFile/html:/usr/share/nginx/html \
-v /root/nginxFile/conf:/etc/nginx \
-v /root/nginxFile/log:/var/log/nginx \
nginx
# 如果想拷下原版的配置出來改的話:
# 新建個臨時容器
$ docker run -d -p 127.0.0.1:8080:80 --rm --name mynginx -v "$PWD/html":/usr/share/nginx/html nginx
# 把容器中的nginx配置拷出來
$ docker cp mynginx:/etc/nginx .
$ docker stop mynginx
# 然後重新跑下上面 Nginx 的 docker run
Registry
# 私有倉庫安裝示例
【本地版:
$ docker run -d \
-p 5000:5000 \
--name registry
--restart=always
-v /opt/data/registry:/var/lib/registry \
registry
# 用curl查看倉庫中的鏡像
$ curl -XGET 127.0.0.1:5000/v2/_catalog
# 查看鏡像列表
$ curl -XGET 127.0.0.1:5000/v2/image_name/tags/list
【許可權認證版:
# 創建保存帳號密碼的文件
$ mkdir /opt/data/auth
# 創建帳號和密碼
$ docker run --entrypoint htpasswd registry -Bbn username userpasswd > auth/htpasswd
$ docker run -d -p 5000:5000 --restart=always --name registry \
-v /opt/data/registry:/var/lib/registry \
-v /opt/data/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry
# 登錄&退出
$ docker login -u username -p userpasswd 127.0.0.1:5000
$ docker logout 127.0.0.1:5000
【外網訪問-白名單版(前面2版之一的基礎上):
# 如果不想用127.0.0.1:5000作為倉庫地址,而是用區域網或者外網IP訪問,會有錯誤。
# 這是因為 Docker 默認不允許非 HTTPS 方式推送鏡像。我們可以通過 Docker 的配置選項來取消這個限制
# Ubuntu 14.04, Debian 7 Wheezy:
# 對於使用 upstart 的系統而言,編輯/etc/default/docker文件,在其中的DOCKER_OPTS中增加如下內容:
DOCKER_OPTS="--insecure-registries=192.168.199.100:5000"
# Ubuntu 16.04+, Debian 8+, centos 7
# 對於使用 systemd 的系統,在/etc/docker/daemon.json中增加如下內容
{
"insecure-registries": [
"192.168.199.100:5000"
]
}
# 對於 Docker for Windows、Docker for Mac 在設置中編輯daemon.json增加和上邊一樣的字元串即可。
# 重新啟動服務:
$ sudo service docker restart
【外網訪問-https版(前面2版之一的基礎上):
# 創建證書目錄
$ mkdir -p certs
# 生成證書的操作這裡不贅述,將你生成的或者已有的.crt和.key文件直接拷貝到certs路徑
# 如果使用的是intermediate證書:
# 若是.crt和.pem文件:
$ cat domain.crt intermediate-certificates.pem > certs/domain.crt
# 若是.crt和IntermediateCA.crt文件
$ cat ssl_certificate.crt IntermediateCA.crt > certs/domain.crt
# 運行容器時加以下參數:
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:80 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
伍.其他構建類操作
推送鏡像
docker commit
# 提交容器成為一個新鏡像
docker commit -m="描述資訊" -a="作者" 容器id 目標鏡像名:[tag]
docker tag
# 給某個鏡像創建一個標籤(標記版本號)
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
示例:
docker tag id或名字 fedora/httpd:version1.0
docker tag httpd:test fedora/httpd:version1.0.test
# 要推送至私有註冊表時需要加上私有地址和埠:
docker tag 0e5574283393 myregistryhost:5000/fedora/httpd:version1.0
docker push
docker push [OPTIONS] NAME[:TAG]
常用選項:
-a ,--all-tags 將所有標記的影像推送到存儲庫中
示例:
# 推送至私有註冊表
docker image push registry-host:5000/用戶名/rhel-httpd:latest
# 推送至中央註冊表(需先docker login)
docker image push 用戶名/rhel-httpd:latest
# 推送全部tag版本
docker image push --all-tags registry-host:5000/用戶名/rhel-httpd
構建鏡像
dockerFile
# 新建一個dockerFile,從頭構建一個屬於自己的鏡像。
dockerFile命令:
FROM 基礎鏡像:Centos/Ubuntu
MAINTAINER 鏡像作者+郵箱
RUN 鏡像構建的時候需要運行的命令
ADD 為鏡像添加內容(壓縮包)
WORKDIR 鏡像工作目錄(進入容器時的目錄)
VOLUME 掛載的目錄
EXPOSE 暴露埠配置
CMD/ENTRYPOINT 指定這個容器啟動時要運行的命令(CMD替代先前命令,ENTRYPOINT在先前命令後追加)
COPY 類似於ADD,將文件拷貝到鏡像中
ENV 構建時設置環境變數
# 每個保留關鍵字(指令)都必須是大寫字母
# 從上到下順序執行
# "#" 表示注釋
# 每一個指令都會創建提交一個新的鏡像層並提交
docker build
# 從Dockerfile構建映像
docker build [OPTIONS] PATH | URL | -
常用選項:
--add-host 添加自定義主機到IP的映射(host:ip)
--build-arg 設置構建時變數
--compress 使用gzip壓縮構建上下文
--file , -f Dockerfile的名稱(默認為「 PATH / Dockerfile」)
--label 設置影像的元數據
-m, --memory 記憶體限制
--rmtrue 成功構建後刪除中間容器
-t , --tag 格式的標籤
--target 設置要構建的目標構建階段。
--ulimitUlimit 選項
整體流程:
# 構建鏡像(文件名為 Dockerfile 時 -f 可省略,並且最後的.不要忽略)
docker build -f 文件路徑 -t 標籤 .
# 運行鏡像
docker run
# 發布鏡像
docker push
實戰例子(基於GDAL環境部署):
dockerFile:
# 基於我編譯好的一個鏡像
FROM nibbbbbbbb/gdal-ubuntu-full:v1
MAINTAINER chenbihao
USER root
# 更換中國鏡像源
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
# 進入目錄
WORKDIR /usr/local/
# 創建項目文件夾,並將外部文件夾內容添加進去
RUN mkdir demo ADD ./demo ./demo
# 設置編碼 (gdal鏡像默認編碼是POSIX)
ENV LANG C.UTF-8
# 開放埠
EXPOSE 8080
# 啟動命令
CMD ["java","-Dfile.encoding=utf-8","-jar","/usr/local/demo/demo.jar","--spring.profiles.active=dev"]
構建docker鏡像:
$ docker build -t nibbbbbbbb/gdal-ubuntu-full:v1-app .
完成!
多階段構建
# 多階段構建可以在一個 Dockerfile 中使用多個 FROM 語句。
# 每個 FROM 指令都可以使用不同的基礎鏡像,並表示開始一個新的構建階段。
# 你可以很方便的將一個階段的文件複製到另外一個階段,在最終的鏡像中保留下你需要的內容即可。
比如,以下是同一個 dockerFile:
FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server
FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
EXPOSE 8080
CMD [ "app-server" ]
# 然後build
docker build -t cnych/docker-multi-stage-demo:latest .
# 這樣實現了先在 go 環境中編譯,編譯完後複製到新的 alpine 鏡像中(因為 alpine 只有5MB)
陸.容器編排
限於篇幅原因這裡不細講了,僅大致介紹。
Compose、Machine 和 Swarm 集群是 Docker 官方容器編排三劍客。
Kubernetes(k8s)是 google 開源的一個擁有強大生態的容器編排平台。
Compose
# Compose 是用於定義和運行多容器 Docker 應用程式的工具。
# 通過 Compose,你可以使用 YAML 文件來配置應用程式的服務。然後,使用一個命令,就可以從配置中創建並啟動所有服務。
# Compose 可在所有環境中工作:生產,開發,測試以及CI工作流。
# 使用 Compose 基本上是一個三步過程:
# 使用定義您的應用環境,Dockerfile 以便可以在任何地方複製它。
# 定義組成應用程式的服務,docker-compose.yml 以便它們可以在隔離的環境中一起運行。
# 運行 docker compose up,然後 Docker compose 命令啟動並運行您的整個應用程式。
一個docker-compose.yml看起來像這樣:
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
# Compose具有用於管理應用程式整個生命周期的命令:
# 啟動,停止和重建服務
# 查看正在運行的服務的狀態
# 流運行服務的日誌輸出
# 在服務上運行一次性命令
Machine
# Docker Machine是 Docker 官方提供的一個工具,它可以幫助我們在遠程的機器上安裝 Docker,或者在虛擬機 host 上直接安裝虛擬機並在虛擬機中安裝 Docker。
# 我們還可以通過 docker-machine 命令來管理這些虛擬機和 Docker。
# Docker Machine 支援多種後端驅動,包括虛擬機、本地主機和雲平台等。
Swarm集群
# Swarm 是使用 SwarmKit 構建的 Docker 引擎內置(原生)的集群管理和編排工具。
# Docker Swarm是 Docker 官方三劍客項目之一,提供 Docker 容器集群服務,是 Docker 官方對容器雲生態進行支援的核心方案。
# 使用它,用戶可以將多個 Docker 主機封裝為單個大型的虛擬 Docker 主機,快速打造一套容器雲平台。
# Swarm mode 內置 kv 存儲功能,提供了眾多的新特性,比如:具有容錯能力的去中心化設計、內置服務發現、負載均衡、路由網格、動態伸縮、滾動更新、安全傳輸等。使得 Docker 原生的 Swarm 集群具備與Mesos、Kubernetes競爭的實力。
Kubernetes
# Kubernetes 縮寫是 k8s(k+8個字母+s)
# Google 在 2014 年開源了 Kubernetes 項目。
# Kubernetes 是一個可移植的、可擴展的開源平台,用於管理容器化的工作負載和服務,可促進聲明式配置和自動化。 Kubernetes 擁有一個龐大且快速增長的生態系統。Kubernetes 的服務、支援和工具廣泛可用。
# 容器是打包和運行應用程式的好方式。在生產環境中,你需要管理運行應用程式的容器,並確保不會停機。 例如,如果一個容器發生故障,則需要啟動另一個容器。如果系統處理此行為,會不會更容易?
# 這就是 Kubernetes 來解決這些問題的方法! Kubernetes 為你提供了一個可彈性運行分散式系統的框架。 Kubernetes 會滿足你的擴展要求、故障轉移、部署模式等。 例如,Kubernetes 可以輕鬆管理系統的 Canary 部署。
# Kubernetes 提供:
- 服務發現和負載均衡
Kubernetes 可以使用 DNS 名稱或自己的 IP 地址公開容器,如果進入容器的流量很大, Kubernetes 可以負載均衡並分配網路流量,從而使部署穩定。
- 存儲編排
Kubernetes 允許你自動掛載你選擇的存儲系統,例如本地存儲、公共雲提供商等。
- 自動部署和回滾
你可以使用 Kubernetes 描述已部署容器的所需狀態,它可以以受控的速率將實際狀態 更改為期望狀態。例如,你可以自動化 Kubernetes 來為你的部署創建新容器, 刪除現有容器並將它們的所有資源用於新容器。
- 自動完成裝箱計算
Kubernetes 允許你指定每個容器所需 CPU 和記憶體(RAM)。 當容器指定了資源請求時,Kubernetes 可以做出更好的決策來管理容器的資源。
- 自我修復
Kubernetes 重新啟動失敗的容器、替換容器、殺死不響應用戶定義的 運行狀況檢查的容器,並且在準備好服務之前不將其通告給客戶端。
- 密鑰與配置管理
Kubernetes 允許你存儲和管理敏感資訊,例如密碼、OAuth 令牌和 ssh 密鑰。 你可以在不重建容器鏡像的情況下部署和更新密鑰和應用程式配置,也無需在堆棧配置中暴露密鑰。