SpringCloud(十) – Docker

1、Docker安裝

1.1 卸載舊版本(否者會安裝出錯)

sudo yum remove docker \
         docker-client \
         docker-client-latest \
         docker-common \
         docker-latest \
         docker-latest-logrotate \
         docker-logrotate \
         docker-engine

1.2 安裝一些需要的環境

 yum install -y yum-utils device-mapper-persistent-data lvm2

1.3 Docker CE 鏡像源站

Docker CE 鏡像源站 # yum-config-manager --add-repo//mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

1.3 安裝最新版本

sudo yum install docker-ce

1.4 查看版本資訊

docker 

docker -v 

1.5 配置 騰訊雲 Docker 鏡像源加速鏡像

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
   "registry-mirrors": [
       "//mirror.ccs.tencentyun.com"
  ]
}
EOF

1.6 Docker 基礎命令

配置開機啟動# systemctl enable docker

啟動docker# systemctl start docker

查看docker資訊# docker info

關閉docker# systemctl stop docker

重新docker# systemctl reload docker

1.7 hello-world

docker run hello-world

2、Docker 核心操作命令

2.1 鏡像操作

2.1.1 查看鏡像

列出本機上所有的鏡像# docker images
參數 
 -a 列出本地所有的鏡像
 -q 只顯示鏡像ID
 --digests 顯示鏡像摘要資訊

REPOSITORY:表示鏡像的倉庫源名稱
TAG:鏡像的標籤,同一倉庫源可以有多個 TAG,代表這個倉庫源的不同個版本,latest最新
IMAGE ID:鏡像ID
CREATED:鏡像創建時間
SIZE:鏡像大小

2.1.2拉取鏡像

2.1.2.1 搜索需要的鏡像

dockerhub://hub.docker.com/search?q=mysql

2.1.2.2 找到需要的版本

2.1.2.3 複製命令 執行

2.1.3 刪除鏡像

docker mri -f 鏡像名/鏡像ID

docker rmi -f $(docker images -aq) 刪除全部鏡像

2.2 容器操作

2.2.1 根據鏡像創建並啟動容器

docker run [OPTIONS] IMAGE  #根據鏡像新建並啟動容器。IMAGE是鏡像ID或鏡像名稱

OPTIONS說明:
	--name=「容器新名字」:為容器指定一個名稱
	--rm:退出時刪除容器 
	-d:後台運行容器,並返回容器ID,也即啟動守護式容器
	-i:以交互模式運行容器,通常與-t同時使用
	-t:為容器重新分配一個偽輸入終端,通常與-i同時使用
	-p:指定埠映射
	
實例:
docker run -itd --name mysql01 -p 3306:3306 mysql:5.7.30
此命令會創建容器,但是啟動容器失敗,命令不完整,下面實戰會重新使用

因為我們伺服器上本來就安裝有mysql所以需要停止mysql服務
service mysqld stop
如果不能停止可以參考://blog.csdn.net/weixin_29009881/article/details/113280951

2.2.2 列出所有容器

docker ps 列出所有正在運行的容器

帶參
	-a  列出所有的容器
	-l  列出最近創建的容器
	-n 3  列出最近創建的3個容器
	-q 只顯示容器ID,先啟動容器
	--no-trunc  顯示當前所有正在運行的容器完整資訊

2.2.3 容器啟動,停止,刪除

docker start 容器ID或容器名稱 #啟動容器

docker restart 容器ID或容器名稱  #重新啟動容器

docker stop 容器ID或容器名稱 #停止容器

docker kill 容器ID或容器名稱 #強制停止容器

docker rm 容器ID或容器名稱 #刪除容器

docker rm -f 容器ID或容器名稱 #強制刪除容器

docker rm -f $(docker ps -a -q) #刪除多個容器

2.2.4 查看容器日誌

docker logs -f -t --since="日期"  --tail 容器ID或容器名稱

實例:
docker logs -f -t --since="2022-01-10" --tail=10 mysql01

-f : 查看實時日誌
-t : 查看日誌產生的日期
--since : 此參數指定了輸出日誌開始日期,即只輸出指定日期之後的日誌
--tail=10 : 查看最後的10條日誌

2.2.5 進入和退出容器

2.2.5.1 進入容器
方式一(推薦):
docker exec -it 容器名/容器ID /bin/bash
# /bin/bash  交互路徑,因為載入容器後運行bash ,docker中必須要保持一個進程的運行。打開一個shell交互窗口,可以操作。

示例:docker exec -it mysql01 /bin/bash

方式二:
docker attach 容器名/容器ID
#前提是容器啟動後,必須是啟動了終端交互窗口,才可以直接用,比如此命令,進入mysql容器,默認就不能直接打開終端

示例:docker attach mysql01
2.2.5.2 退出容器
方式一(推薦):
ctrl + p + q  # 執行此命令容器都不會被關閉
# 注意:有的瀏覽器會佔用這個快捷鍵

方式二:
exit # 直接退出 執行此參數 容器會被關閉

2.2.6 拷貝文件

# 無論容器是否開啟 都可以進行相互拷貝

docker cp 容器ID/名稱:容器內路徑  容器外路徑  # 從容器內 拷出

docker cp 容器外路徑 容器ID/名稱:容器內路徑   # 從外部 拷貝文件到容器內

3、Docker 實戰

3.1 Docker容器-MySQL

3.1.1 拉取鏡像

docker pull mysql:5.7.30

3.1.2 命令啟動

# 先刪除之前那個沒有配置初始密碼的mysql01

docker run -itd --name mysql01 -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 mysql:5.7.30

# 注意:
# 指定初始密碼,容器啟動成功,就可以直接進行登錄操作
# 埠映射 -p 外部伺服器埠:容器埠

3.1.3 查看容器

docker ps

3.1.4 進入容器

dockerexec -it mysql01 /bin/bash

3.1.5 登錄服務

mysql -uroot -proot

# 如果服務沒有啟動,就先啟動服務 service mysql start

3.1.6 測試遠程連接

3.2 Docker容器-Redis

3.2.1 拉取鏡像

docker pull redis:5.0.14

3.2.2 命令啟動

docker run -itd --name redis01 -p 6379:6379 redis:5.0.14

3.2.3 查看容器

docker ps -a

3.2.4 進入容器

docker exec -it redis01 /bin/bash

3.2.5 登錄服務

 cd /usr/local/bin/ # 進入redis安裝目錄
 
 redis-cli # 進入服務端
 
 ping

3.2.6 測試遠程連接

3.3 Docker 圖形化工具 Portainer

參考鏈接://blog.csdn.net/m0_67900727/article/details/123550536

3.3.1 拉取鏡像

docker pull portainer/portainer

3.3.2 運行Portainer容器

docker run -p 9000:9000 -p 8000:8000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /mydata/portainer/data:/data \
-d portainer/portainer

第一次登錄的時候需要創建管理員帳號,訪問地址://192.168.5.78:9000/

3.3.3 訪問

4、自定義提交鏡像

4.1 docker commit

運行的容器可能在鏡像的基礎上做了一些修改,有時候我們希望保存起來,封裝成一個更新的鏡像,這時候我們就需要使用 commit 命令來構建一個新的鏡像;

4.1.1 拉取一個tomcat鏡像並創建運行容器

docker pull tomcat:8.5.78-jdk8-corretto # 拉取鏡像

docker run -itd -p 8080:8080 --name tomcat01 tomcat:8.5.78-jdk8-corretto # 創建並運行容器

# 訪問埠8080,發現訪問404 
docker exec -it tomcat01 /bin/bash
進入tomcat的安裝目錄,進入webapps目錄,會發現 下一個文件都沒有 ,訪問肯定404
文件都在webapps.dist
將webapps.dist下的內容拷貝到webapps目錄下
cp -r webapps.dist/* webapps/

4.1.2 打包成新鏡像

docker commit -m="第一次打包鏡像,tomcat首次訪問404" -a="KH96" tomcat01 tomcat:8.5.78-kh9x

語法:
	docker commit -m="提交資訊" -a="作者資訊" 容器名/容器ID 提交後的鏡像名:Tag

4.1.3 用新的鏡像創建新的容器

docker stop tomcat01 # 停止tomcat01容器
docker rm -f tomcat01 # 刪除tomcat01容器
docker images -a # 查看我們新打包的鏡像

# 重新創建並運行新的容器 tomcat02
docker run -itd -p 8080:8080 --name tomcat02 tomcat:8.5.78-kh9x

# 再次測試訪問
可以看到tomcat服務的首頁;

4.2 Dockerfile

Dockerfile是一個包含用於組合映像的命令的文本文檔。可以使用在命令行中調用任何命令。 Docker通過讀取Dockerfile中的指令自動生成映像。

4.2.1 常用命令

4.2.1.1 FROM (from)
語法: FROM <image> 或者 FROM <image>:<tag>

含義: 基礎image,必須寫在第一行,指定在哪個基礎鏡像上創建鏡像,可以是官方遠程倉庫中的,也可以本地倉庫。
4.2.1.2 MAINTAINER (maintainer)
語法: MAINTAINER <name>

含義: 申明作者,用於將image的作者相關的資訊寫入到image中,輔助使用,一般放FROM命令後面
4.2.1.3 WORKDIR (workdir)
語法: WORKDIR <path>

含義: 設置容器的工作目錄,之後的命令RUN 、CMD 、ENTRYPOINT命令都是基於此工作目錄,如果不存在則會創建目錄,也可以在 docker run命令中用 -w參數覆蓋掉WORKDIR指令的設置

注意:為了避免出錯,推薦WORKDIR指令中只使用絕對路徑,進入容器後默認也是此目錄
4.2.1.4 ADD (add)
語法: ADD <src> <dest>

<src>相對被構建的源目錄的相對路徑,也可以是一個遠程的文件url; 
<dest> 是container中的絕對路徑

含義:它的基本作用是從宿主機系統的文件系統上複製文件到目標容器的文件系統。

1)如果源是一個URL,那該URL的內容將被下載並複製到容器中。
2)如果如果文件是可識別的壓縮格式,則docker會幫忙解壓縮。
3)如果要ADD本地文件,則本地文件必須在 docker build <PATH>,指定的path目錄下,默認當前目錄。
4)ADD只有在build鏡像的時候運行一次,後面運行container的時候不會再重新載入了。
4.2.1.5 ENV (env)
語法: ENV <key> <value>

含義: 用於設置環境變數,在image中設置一個環境變數。

注意: 設置了後,後續的RUN命令都可以使用,container啟動後,可以通過docker inspect查看這個環境變數,也可以通過在docker run --env key=value時設置或修改環境變數。
4.2.1.6 RUN (run)
語法: RUN <command>

含義: 它接受命令作為參數並用於創建鏡像,並在鏡像構建的過程中執行。

注意: RUN可以運行任何被基礎image支援的命令,RUN指令創建的中間鏡像會被快取,並會在下次構建中使用。如果不想使用這些快取鏡像,可以在構建時指定--no-cache參數,如:docker build --no-cache
4.2.1.7 CMD (cmd)
語法: CMD ["executable","param1","param2"]
	 CMD command param1 param2
	 
含義:用於container啟動時指定的操作。該操作可以是執行自定義腳本,也可以是執行系統命令。該指令只能在文件中存在一次,如果有多個,則只執行最後一條。

區別:CMD用於指定在容器啟動時所要執行的命令,而RUN用於指定鏡像構建時所要執行的命令。
4.2.1.8 ENTRYPOINT (entrypoint)
語法: ENTRYPOINT ["executable", "param1", "param2"]
	 ENTRYPOINT command param1 param2 
	 
含義:這個命令和CMD功能一樣。指定容器啟動時執行的命令,可以多次設置,但是只有最後一個有效。

指令的使用分為兩種情況:
	獨自使用: 如果你還使用了CMD命令且CMD是一個完整的可執行的命令,那麼CMD指令和ENTRYPOINT會互相覆蓋,只有最後一個CMD或者ENTRYPOINT有效。 
			# CMD指令將不會被執行,只有ENTRYPOINT指令被執行
			CMD echo 「Hello, World!」
			ENTRYPOINT ls -l
	
	CMD指令配合使用: 和CMD指令配合使用來指定ENTRYPOINT的默認參數,這時CMD指令不是一個完整的可執行命令,僅僅是參數部分;ENTRYPOINT指令只能使用JSON方式指定執行命令,而不能指定參數。
			FROM centos
			CMD ["-l"]
			ENTRYPOINT ["/usr/bin/ls"]
4.2.1.9 USER (user)
語法: USER <user>

含義: 設置指令,設置啟動容器的用戶,默認是root用戶。
4.2.1.10 EXPOSE (expose)
語法: EXPOSE <port> [<port>...]

含義: 暴露容器內部埠,可以設置多個

例如: EXPOSE 5000,暴露的是容器內部埠,不是主機埠,如果外部想使用這個埠需要在運行時映射。
docker run -d -p 127.0.0.1:8080:5000 hello-world

4.2.2 Dockerfile構建jdk+tomcat鏡像

4.2.2.1 資源添加
創建一個目錄存放資源# mkdir Dockerfile-tomcat

把jdk壓縮包和tomcat壓縮包放到 Dockerfile-tomcat 的目錄下面

4.2.2.1 編輯Dockerfile
# 新建一個空文件Dockerfile,編輯Dockerfile內容。
# vi Dockerfile

Dockerfile內容:

# 基礎鏡像
FROM centos:7.6.1810

# 作者資訊
MAINTAINER kh9x <[email protected]>

# 容器工作目錄
WORKDIR /usr/local/

# 在宿主機/usr/local/docker路徑下,上傳壓縮包,並添加tomcat和jdk到鏡像中,ADD會自動解壓
ADD jdk-8u192-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.73.tar.gz /usr/local/

# 設置環境變數
ENV JAVA_HOME /usr/local/jdk1.8.0_192/
ENV PATH $JAVA_HOME/bin:$PATH
ENV CATALINA_HOME=/usr/local/apache-tomcat-8.5.73


# 配置啟動文件的許可權
RUN chmod +x /usr/local/apache-tomcat-8.5.73/bin/*.sh

# 指定於外界交互的埠
EXPOSE 8080

# 定義在容器啟動之後的運行程式,保持docker容器運行
ENTRYPOINT /usr/local/apache-tomcat-8.5.73/bin/startup.sh && /bin/bash && tail -f /usr/local/apache-tomcat-8.5.73/logs/catalina.out
4.2.2.3 執行構建命令構建(tomcat+jdk)服務鏡像
執行命令# docker build -t 鏡像名:tag . 

舉例# docker build -t tomcat:8.5.73-jdk8-kh96 .

注意:-t為執行鏡像的名稱,千萬不要忽略結尾處的 . ,它表示當前上下文目錄。不是Dockerfile的默認目錄

構建完成後查看鏡像# docker images

4.2.2.4 創建並啟動容器 並 訪問
先停止commit自定義提交的鏡像tomcat02# docker stop tomcat02

創建並啟動容器# docker run -itd -p8080:8080 --name tomcat03 tomcat:8.5.73-jdk8-kh96

通過伺服器映射埠,訪問docker容器tomcat

4.2.3 Dockerfile構建jdk+Springboot項目鏡像

4.2.3.1 資源添加
創建一個目錄存放資源# mkdir Dockerfile-springbootProject

把項目jar包放到 Dockerfile-springbootProject 的目錄下面

4.2.3.2 編輯Dockerfile
FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]
4.2.3.3 執行構建命令構建(jdk+Springboot)服務鏡像
構建鏡像 # docker build -t springboot:jdk8-springboot .

構建完成後查看鏡像# docker images

4.2.3.4 創建並啟動容器
創建並啟動容器# docker run -itd -p8080:8080 --name springboot01 springboot:jdk8-springboot

查看容器# dockers ps

4.2.3.5 postman訪問請求

5、掛載共享數據

5.1 掛載測試

5.1.1 創建容器並指定掛載路徑

語法# -v [宿主機路徑]:[鏡像路徑]

創建容器mysql03 
將  宿  主 機  的/usr/local/kh96/docker/mount-test 
掛載到 
   容器mysql03的/usr/local/kh96/docker/mount-test

主要命令#  -v  /usr/local/kh96/docker/mount-test:/usr/local/kh96/docker/mount-test

完整命令
# docker run -itd --name mysql03 -e MYSQL_ROOT_PASSWORD=root -p 3310:3306 -v  /usr/local/kh96/docker/mount-test:/usr/local/kh96/docker/mount-test  mysql:5.7.30

查看容器#docker ps

5.1.2 查看掛載資訊

查看容器詳細資訊# docker inspect mysql03

5.1.3 修改測試

5.1.3.1 宿主機:

修改宿主機上的內容後:

5.1.3.2 容器:

查看容器上的內容也發生了變化

5.1.4 停止容器後,修改宿主機上的內容

5.1.4.1 宿主機:

5.1.4.2 容器:

5.1.4.3 總結

關閉容器後,修改數據也會同步。

5.2 掛載宿主機mysql 數據和配置文件 到mysql容器 (想錯了)

5.2.1 錯誤

5.2.1.1 mysql:Job for mysqld.service failed because the control process exited with error
#本來想掛載配置文件和數據文件
# 使用一下命令
docker run -itd --name mysql03 -e MYSQL_ROOT_PASSWORD=root -p 3310:3306 -v /etc/my.cnf:/etc/my.cnf -v /var/lib/mysql:/var/lib/mysql mysql:5.7.30

# 但是創建容器後無法啟動;

# 後面就只掛載了mysql數據文件
docker run -itd --name mysql03 -e MYSQL_ROOT_PASSWORD=root -p 3310:3306 -v /var/lib/mysql:/var/lib/mysql mysql:5.7.30

#容器myslq03可以正常啟動,遠程也可以正常連接,但是宿主機上的mysql無法啟動了;
報錯資訊#mysql:Job for mysqld.service failed because the control process exited with error

後面一直根據查詢網上的解決方法都沒有解決;

5.2.1.2 InnoDB: The innodb_system data file ‘ibdata1’ must be writable

最後看十查看mysql的錯誤日誌,然後根據
錯誤日誌# InnoDB: The innodb_system data file 'ibdata1' must be writable
查到解決方式# chmod -R 777 /var/lib/mysql

解決問題部落格原文連接:
//blog.csdn.net/weixin_40744265/article/details/91398308
//blog.csdn.net/saywhat_sayhello/article/details/81294687


後面突然理解錯了,我以為是將宿主機的配置文件和數據掛進去然後進行數據的同步;

5.3 將mysql03容器的配置文件 和 數據文件 掛載到宿主機 備份 (正確思路)

# 創建兩個文件夾,存放容器的配置文件和數據文件
mkdir /usr/local/kh96/docker/mount-mysql03/conf
mkdir /usr/local/kh96/docker/mount-mysql03/data

# 創建並mysql03容器並掛載 配置文件和數據文件到 宿主機
docker run -itd --name mysql03 -e MYSQL_ROOT_PASSWORD=root -p 3310:3306 -v /usr/local/kh96/docker/mount-mysql03/conf:/etc/mysql/conf.d -v /usr/local/kh96/docker/mount-mysql03/data:/var/lib/mysql mysql:5.7.30


# 創建並運行成功,遠程連接成功;

5.3.1 遠程連接:

5.3.2 宿主機上存在容器mysql03的文件:

5.3.3 容器mysql03中的文件:

5.3.4 查看掛載資訊

查看容器詳細資訊# docker inspect mysql03 

5.4 匿名掛載,具名掛載,指定路徑掛載

5.4.1 匿名掛載

匿名掛載# -v 容器內路徑
沒有寫宿主機上的地址,會放在 /var/lib/docker/volumes 下
5.4.1.1 匿名掛載mysql02
docker run -itd --name mysql02 -e MYSQL_ROOT_PASSWORD=root -p 3308:3306  -v /var/lib/mysql mysql:5.7.30
5.4.1.2 查看容器的掛載資訊
查看容器詳細資訊# docker inspect mysql02

5.4.1.3 查看數據卷資訊
查看所有的數據卷# docker volume ls

5.4.2 具名掛載

具名掛載#-v 卷名:容器內路徑
沒有寫宿主機上的地址,會放在 /var/lib/docker/volumes 下
5.4.2.1 具名掛載 mysql02
docker run -itd --name mysql02 -e MYSQL_ROOT_PASSWORD=root -p 3308:3306  -v mysql02-volume:/var/lib/mysql mysql:5.7.30
5.4.2.2 查看容器的掛載資訊
查看容器mysql02的詳細資訊# docker inspect mysql02

5.4.2.3 查看數據卷的資訊
查看所有的數據卷# docker volume ls

5.4.3 指定路徑掛載

指定路徑掛載# -v /宿主機路徑:容器內路徑:讀寫許可權

讀寫許可權:
	rw :可讀可寫的許可權
	ro : 可讀許可權
5.4.3.1 指定路徑掛載mysq03
5.3 的mysql03 掛載就是指定路徑掛載

docker run -itd --name mysql03 -e MYSQL_ROOT_PASSWORD=root -p 3310:3306 -v /usr/local/kh96/docker/mount-mysql03/conf:/etc/mysql/conf.d -v /usr/local/kh96/docker/mount-mysql03/data:/var/lib/mysql mysql:5.7.30
5.4.3.2 查看容器的掛載資訊
查看容器mysql03的詳細資訊# docker inspect mysql03

5.4.3.3 查看數據卷的資訊
查看所有的數據卷# docker volume ls

所有的docker容器內的卷,沒有指定目錄的情況下都是在 /var/lib/docker/volumes/xxxx/_data 下,如果指定了目錄,docker volume ls 是查看不到的。

5.4.4 數據卷刪除

掛載在宿主上的數據卷不會自動刪除,容器刪除後,數據卷任然存在;需要手動刪除;

5.4.4.1 查詢所有沒有被使用的數據卷
# 刪除容器 mysql02
# 兩次操作,存在個 mysql02的數據卷

# docker volume ls --filter dangling=true

5.4.4.2 刪除數據卷
docker volume rm docker volume rm mysql02-volume c5e4ad96bc9eef3ffb987fdf930848c35284e5dc5f20ffe77ed850fc47647bf5

6、Docker常用命令

attach      # 當前shell下 attach連接指定運行的鏡像
build       # 通過Dockerfile訂製鏡像
commit      # 提交當前容器為新的鏡像
cp          # 拷貝文件
create      # 創建一個新的容器
diff        # 查看docker容器的變化
events      # 從服務獲取容器實時時間
exec        # 在運行中的容器上運行命令
export      # 導出容器文件系統作為一個tar歸檔文件[對應import]
history     # 展示一個鏡像形成歷史
images      # 列出系統當前的鏡像
import      # 從tar包中導入內容創建一個文件系統鏡像
info        # 顯示全系統資訊
inspect     # 查看容器詳細資訊
kill        # kill指定docker容器
load        # 從一個tar包或標準輸入中載入一個鏡像[對應save]
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       # 啟動容器
stats       Display a live stream of container(s) resource usage statistics
stop        # 停止容器
tag         # 給源中鏡像打標籤
top         # 查看容器中運行的進程資訊
unpause     # 取消暫停容器
update      Update configuration of one or more containers 
version     # 查看 docker版本號
wait        # 截取容器停止時的退出狀態值