Docker
概述
開發一個項目可能存在兩種環境,開發、上線;兩者需要配置的環境不同。
傳統項目運作時,一個環境如 mysql 的錯誤會引發整個項目的當機。
Docker 就是為了解決項目中不同的配置而産生,即可以同時将 jar、mysql、redis 等一起打包安裝,稱為鏡像。
使用 Docker 生成鏡像,下載下傳安裝即可使用。
思想:集裝箱
Docker 核心思想:隔離,打包裝箱,每個包都是互相隔離的。
Docker 能夠最大限度的利用伺服器的資源
虛拟化技術:
- 全虛拟、半虛拟、容器技術
虛拟機技術 => 容器化技術 容器化技術不是一個完整的作業系統
兩者的優缺點和差別:
虛拟機技術:
- 資源占有率太高
- 步驟過多
- 啟動慢
- 虛拟出一套硬體,擁有一個完整的作業系統,需要在該 OS 上安裝相應的軟體和環境
容器化技術:
- 容器應用直接運作在主體本機上,不擁有獨立的核心
- 容器間互相隔離,每個容器擁有獨立的檔案系統,互不影響
- 核心級别的虛拟化
基本組成
鏡像(image)
- 通過鏡像可以建立多個容器
- 項目(服務)運作最終是在容器中運作的
容器(container)
- 利用容器技術,獨立運作一個或一組 app
- 在初學階段,可以将 container 了解為簡易的 Linux 系統
倉庫(repository)
- 存放鏡像的位置
- repository 分為 public 和 private
- Docker Hub 類比 GitHub
安裝
Centos
檢視系統核心
# uname -r
5.10.112-11.1.al8.x86_64
檢視系統版本
# cat etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
安裝步驟
更新
yum
索引
yum makecache fast
- 解除安裝舊版本
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
- 下載下傳相關工具及安裝包
yum install -y yum-utils
- 配置鏡像倉庫
yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安裝 Docker 引擎
# docker-ce 社群版 yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
檢視下載下傳鏡像
docker images
解除安裝
- 解除安裝依賴
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
- 删除資源
# /var/lib/docker 預設工作路徑 rm -rf /var/lib/docker rm -rf /var/lib/containerd
阿裡雲鏡像加速
#
sudo mkdir -p /etc/docker
#
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://rl0hzmix.mirror.aliyuncs.com"]
}
EOF
#
sudo systemctl daemon-reload
#
sudo systemctl restart docker
Ubuntu
- 解除安裝舊版本
apt-get remove docker docker-engine docker.io containerd runc
- 更新
包索引apt
apt-get update
- 安裝
依賴包,用于通過 HTTPS 來擷取倉庫apt
apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release
- 添加 Docker 官方 GPS 密鑰
mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- 将 Docker 倉庫添加到 APT 軟體源
- 安裝 Docker 引擎
apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
- 驗證
docker --version
Docker 原理
Docker 工作原理
- Docker 是一個 C/S 結構的系統,其守護程序運作在本機,通過 Socket 從用戶端通路
Docker 與 VM 的速度差別原因
- Docker 的抽象層比 VM 少;
- Docker 利用的是主控端的核心,VM 需要使用 Guest OS(重新搭載)
常用指令
幫助指令
# 檢視 Docker version
docker version
# 檢視 Docker 資訊(詳細),system info,包括鏡像和容器的數量
docker info
#
docker --help
鏡像指令
# 檢視鏡像倉庫
docker images
# 檢視鏡像倉庫所有的鏡像
docker images -a
# 檢視鏡像倉庫中鏡像的ID
docker images -q
# 參數配合使用
docker images -aq
搜尋指令
# xxx表示鏡像倉庫中的鏡像,如 mysql
docker search xxx
# 條件搜尋,???表示查詢的條件,可以是 STARS=3000
docker search xxx -filter=???
下載下傳鏡像
# xxx表示鏡像倉庫中的鏡像,如:mysql,預設最新版本,tag表示版本号
docker pull xxx[:tag]
删除鏡像
# 單個鏡像删除,ID為 IMAGE ID,NAME 為 REPOSITORY,可以通過兩種方式删除
docker rmi -f ID(NAME)
# 多個鏡像删除
docker rmi -f $(docker images -qa)
容器指令
通過鏡像啟動容器
建立、啟動
# args:
# --name "" 容器名字
# -d 背景方式運作
# -it 互動模式運作,進入容器
# -p 指定端口号,如:-p 8080:8080,不輸入參數随機指定端口
# -p 主機端口:容器端口
# -p 容器端口
# -p ip:主機端口:容器端口
# image 是鏡像的名
docker run [args] image
# e.g.
[[email protected] ~]# docker run -it centos /bin/bash
[[email protected] /]#
退出容器
# 容器停止并退出
exit
# 容器不停止退出
ctrl + P + Q
列出容器
# 列出目前正在運作的容器
docker ps
# 列出目前正在運作的容器、曆史運作過的容器即所有容器
docker ps -a
# 最近建立的num個容器
docker ps -n=num
# 隻顯示編号
docker ps -q
删除容器
# 無法删除正在運作的容器
docker rm ID
# 删除所有容器
docker rm -f $(docker ps -aq)
docker ps -a -q|xargs docker rm
啟動和停止
docker start ID
docker restart ID
# stop和kill的差別在于stop會給容器内的應用10s時間去停止服務,kill直接停止
docker stop ID
docker kill ID
start
和
run
的差別
-
:對鏡像進行建立并運作run
-
:對關閉的容器進行運作(需存在)start
其他指令
檢視日志
# 日志列印
# --tail num 顯示的num條日志
docker logs -f -t --tail num containerID
# 所有日志
dokcer logs -tf containerID
# Shell 腳本
"while true;do echo Lyn-coder;sleep 1;done"
# 背景運作
docker run -d centos /bin/sh -c "while true;do echo Lyn-coder;sleep 1;done"
檢視程序
# top
# docker top 2a7099f3b1d3
UID PID PPID C STIME TTY TIME CMD
root 14614 14594 0 19:14 ? 00:00:00 /bin/sh -c while true;do echo Lyn-coder;sleep 1;done
root 15104 14614 0 19:19 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
檢視鏡像中繼資料
# 檢視容器的詳細資訊
docker inspcet containerID
進入容器
# 進入容器新終端
docker exec -it containerID /bin/bash
# 進入容器後使用,不開啟新線程
docker attach containerID
拷貝
# container -> host
# docker cp 72446cb56e8b:/home/demo.java /home
docker cp containerID:dir dstDIr
測試執行個體
使用 Docker 安裝 tomcat
# docker hub
# --rm 用于測試,使用完畢即删除容器
docker run -it --rm tomcat:9.0
# ====================
# run
docker run -d -p 8080:8080 --name tomcat_01 tomcat:9.0
# webapps 中沒有任何檔案,将 webapps.dist 檔案夾中的檔案 copy 到 webapps
# 就不會再是404的網頁了
docker exec -it tomcat_01 /bin/bash
可視化界面
Pointer
:圖形化界面管理工具
# 安裝
docker run -d -p xxxx:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
鏡像操作
commit
# 送出
docker commit -m="msg" -a="author" containerID 鏡像名:版本
docker commit -a="Lyn-coder" -m="Tomcat webapps upgrade to test docker commit" 71b588888a1f tomcat_lyn:1.0
容器資料卷
簡要
容器之間想要實作資料共享,Docker 容器中的資料可以同步到 host
目錄的挂載,卷技術
目的:
- 資料持久化
- 容器同步操作
- 容器資料共享
使用
挂載
-v
# host-dir:主機目錄位置
# container-dir:容器目錄位置
docker run -it -v host-dir:container-dir containerID /bin/bash
Docker 與 MySQL
docker run -d -p xxxx:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxxxxx --name mysql_01 -d mysql
匿名與具名挂載
# -P 随機指定端口号,也可以指定端口号
# 匿名
docker run -d -P 容器内路徑 鏡像名
# 具名
docker run -d -P 卷名:容器内路徑 鏡像名
# all volume 卷
docker volume ls
# 卷具體資訊
docker volume inspect 卷名
不指定目錄時,Docker 容器中的卷,都存儲在
/var/lib/docker/volumes/xxx/_data
匿名挂載、具名挂載、指定路徑挂載的區分
- 匿名挂載
-v 容器内路徑
- 具名挂載
-v 卷名:容器内路徑
- 指定路徑挂載
-v /host路徑:容器内路徑
參數補充
-
:read only,隻讀,隻能從 host 對其進行操作,容器沒有這個權限-ro
-
:read write,讀寫權限-rw
DockerFile
DockerFile
用來建構 Docker 鏡像
标準檔案命名為:
Dockerfile
# 檔案指令需大寫
FROM centos
VOLUME ["volume-01", "volume-02"]
CMD echo "===== end ====="
CMD /bin/bash
# 指令
docker build -f dockerfile-01 -t lyn/centos:1.0 .
# 執行
Sending build context to Docker daemon 2.048kB
Step 1/4 : From centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume-01", "volume-02"]
---> Running in 3e130dcabdb4
Removing intermediate container 3e130dcabdb4
---> 6b05c51c3970
Step 3/4 : CMD echo "===== end ====="
---> Running in 3a575a9f422b
Removing intermediate container 3a575a9f422b
---> 4e0a395ccac0
Step 4/4 : CMD /bin/bash
---> Running in fc17b239c866
Removing intermediate container fc17b239c866
---> 21e01bdb29b2
Successfully built 21e01bdb29b2
Successfully tagged lyn/centos:1.0
# TEST
# volume-01中建立一個 txt 檔案
# 通過 inspect 檢視 挂載位置
資料卷容器
兩個及兩個以上的容器進行資料同步
--volumes-from xxx
# 21e01bdb29b2:鏡像ID
docker run -it --name docker-01 21e01bdb29b2
#
docker run -it --name docker-02 --volumes-from docker-01 21e01bdb29b2
# --volumes-from => 繼承于
- 資料卷容器的生命周期:直到所有容器都被銷毀
- 資料持久化到 host,本地資料不會被删除
DockerFile
建構鏡像的步驟:
- 編寫 DockerFile 檔案
-
建構鏡像docker build
-
釋出鏡像(Docker Hub/阿裡雲鏡像倉庫)docker push
DockerFile 原則
- 保留關鍵字必須是大寫
- 執行順序由上到下
- 注釋使用
#
- 每一條指令都會建立并送出新的鏡像層
- 面向開發,制作鏡像釋出項目需要編寫 DockerFile 檔案
DockerFile 指令
-
:指定基礎鏡像;FROM
-
:指定鏡像作者,姓名+郵箱;MAINTAINER
-
:鏡像建構運作指令;RUN
-
:增加鏡像層;ADD
-
:設定鏡像工作目錄;WORKDIR
-
:設定挂載目錄(卷);VOLUME
-
:設定暴露的端口,類比EXPOSE
;-p
-
:指定容器啟動時運作的指令,隻有最後一條指令生效;CMD
-
:指定容器啟動運作的指令,可追加指令;ENTRYPOINT
-
:建構一個被繼承的時候運作時的指令;ONBUILD
-
:将檔案拷貝到鏡像中;COPY
-
:設定環境變量;ENV
DEMO測試
# DockerFile
FROM centos
MAINTAINER author<email>
ENV MYPATH /usr/local
WORKDIR $MYPATH
# vim
RUN yum -y install vim
# ifconfig
RUN yum -y install net-tools
# 暴露端口
EXPOSE 80
# 列印
CMD echo $MYPATH
CMD echo "===== end ====="
CMD /bin/bash
=======================================================================
# 建構指令
docker build -f mydockerfile-centos -t lyn-mycentos:0.1 .
# 運作
docker run -f 鏡像name -t 鏡像[:tag] .
DEMO測試——Tomcat鏡像
注:參考狂神的視訊
步驟:
- 準備 JDK 和 Tomcat 的壓縮包
- 編寫 Dockerfile 檔案
FROM centos:7 MAINTAINER author<email> COPY readme.md /usr/local/readme.md # 使用ADD指令會自動解壓 ADD jdk-8u341-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.65.tar.gz /usr/local/ # 安裝vim RUN yum -y install vim # ENV MYPATH /usr/local WORKDIR $MYPATH # 配置環境變量 ENV JAVA_HOME /usr/local/jdk1.8.0_341 # 核心jar包 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.65 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.65 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin # 容器内端口 EXPOSE 8080 # 容器啟動時運作 CMD /usr/local/apache-tomcat-9.0.65/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.65/bin/logs/catalina.log
- 通過 Dockerfile 建構鏡像
- 運作
docker run -d -p xxxx:8080 --name lyn-tomcat -v /home/xxx/build/tomcat/test:/usr/local/apache-tomcat-9.0.65/webapps/test -v /home/xxx/build/tomcat/tomcat-logs/:/usr/local/apache-tomcat-9.0.65/logs lyn-tomcat-images
在 webapps 檔案夾的 test 檔案夾中添加 WEB-INF 檔案夾、jsp 和 xml 檔案,注意:jsp 檔案要與 WEB-INF 檔案夾同目錄
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="utf-8">
<title>Hello World!</title>
</head>
<body>
<%-- JSP Comment --%>
<h1>Hello World!</h1>
<p>
<%
System.out.println("====== Lyn-Tomcat =======");
%>
</body>
</html>
<?xml version="1.0" encoding="utf-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd">
</web-app>
鏡像釋出
步驟
- Docker Hub 賬号登入
docker login -u xxxx
- push
# 增加tag 原鏡像名稱 新鏡像名稱 docker tag xxx xxx # push docker push xxx:tag
釋出到阿裡雲鏡像
- 建立個人執行個體
- 建立命名空間
- 建立鏡像倉庫
- 根據阿裡雲中的文檔 push 到阿裡雲鏡像
Docker 網絡
Docker0
使用
ip addr
,三個網卡:
-
:本機回環位址lo
-
:阿裡雲内網位址eth0
-
:Docker0位址docker0
# 檢視容器内部 ip
docker exec -it xxxx ip addr
# 若出現 OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown 報錯
# 進入容器内部使用以下兩條指令
apt-get update
apt-get install inetutils-ping
原理
- 每個 Docker 容器啟動時,Docker 容器就會被配置設定到一個 ip;
- Docker 會帶有一個網卡 Docker0,使用的模式是橋接模式,使用的技術是 **
**evth-pair
-
:一對虛拟裝置接口,充當一個橋梁,連接配接虛拟網絡裝置exth-pair
-
- 容器在不指定網絡的情況下,都是通過 Docker0 充當路由,Docker 會配置設定給容器可用的 ip;
- 核心是使用了 Linux 的虛拟化網絡技術;
- Docker 中的網絡接口都是虛拟的;
- 每個容器對應一對網橋;
--link
--link
原理
- 在容器中的
檔案中增加對另一個容器的映射/etc/hosts
# 通過 --link 連接配接另一個容器,而不是用網絡
docker run .... --link ConatinerName ...
# 例如tomcat
docker run -d -P --name docker-web-tomcat-01 --link docker-web-tomcat-01 tomcat
--link
在現實開發中已推薦使用
自定義網絡
網絡模式
-
:橋接模式(預設);bridge
-
:不配置網絡;none
-
:和 host 共享網絡;host
# 檢視所有網絡(Docker中)
docker network ls
# 自定義網絡
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
檢視日志:
- 直接使用 run 指令運作,預設帶有參數 --net bridge,即使用 bridge 模式,使用網卡 Docker0
- 自定義網路無需配置
,即可直接連接配接另一個容器--link
網絡連通
相當于給容器再配置設定一個 ip
# 将 CONTAINER 連通到另一個網絡
# 相當于把容器加入到網絡的配置中
docker network connect NETWORK CONTAINER