最近在學習docker,現將比較常用的doker命令以及自己的理解整理如下:
docker中的鏡像,類似于java中的Class,容器,是基于這個鏡像構建出的實例,類似于根據Class構造出的一個個實例對象。
systemctl start docker
systemctl stop docker
systemctl restart docker
systemctl enable docker
//如果是在運行中 輸入命令后 會看到綠色的active
systemctl status docker
docker version
docker info
docker --help
docker pull --help

docker images
docker search 鏡像名
docker search --filter=STARS=9000 mysql
/*搜索 STARS >9000的mysql鏡像
docker pull 鏡像名
docker pull 鏡像名:tag
//沒加tag 就默認拉取最新鏡像
docker pull mysql
docker pull mysql :5.7.21
docker run 鏡像名
docker run 鏡像名:tag

運行后出現tocat默認占用的8080,說明端口已經啟動,但是鼠標沒有回單原本服務器。
使用ctrl + c ,但這種操作方式其實不對
docker中 run 命令是十分復雜的 有什么持久運行 映射端口 設置容器別名 數據卷掛載等
#刪除一個鏡像,ID可以模糊匹配,只要能和其他的鏡像區分開就行)
docker rmi -f 鏡像名/ID
#刪除多個 鏡像ID或名稱用空格隔開
docker rmi -f 鏡像名/ID 鏡像名/ID 鏡像名/ID
#刪除全部鏡像 -a 顯示全部 -a 只顯示ID
docker rmi -f $(docker images -aq)
docker image rm 鏡像名/ID
鏡像的基礎命令大概就這些
將鏡像打包為tar壓縮文件,方便轉移和保存,可以在任何一臺安裝了docker的服務器上加載這個鏡像。
docker save 鏡像名/ID -o 保存位置與姓名
docker save nginx -o /mynginx.tar
docker load -i 鏡像保存文件位置
加載文件 恢復為鏡像

有時候需要對一個鏡像進行分類或者版本迭代操作,比如一個微服務已經打為docker鏡像,但是想根據環境進行區分為develop環境與alpha環境,這時可以使用Tag對鏡像做標簽添加以作區分,版本迭代邏輯也是如此
app:1.0.0 基礎鏡像
# 分離為開發環境
app:develop-1.0.0
# 分離為alpha環境
app:alpha-1.0.0
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker tag 源鏡像名:TAG 想要生成新的鏡像名:新的TAG
# 如果省略TAG 則會為鏡像默認打上latest TAG
docker tag aaa bbb
# 上方操作等于 docker tag aaa:latest bbb:test
# 根據鏡像 quay.io/minio/minio 添加一個新的鏡像 名為 aaa 標簽Tag設置為1.2.3
docker tag quay.io/minio/minio:1.2.3 aaa:1.2.3
# 根據鏡像 app-user:1.0.0 添加一個新的鏡像 名為 app-user 標簽Tag設置為alpha-1.0.0
docker tag app-user:1.0.0 app-user:alpha-1.0.0
docker run 鏡像產生一個該鏡像具體容器實例,docker容器的啟動需要鏡像的支持。
docker ps
--包含正在運行 和已停止的
docker ps -a
# -it 表示 與容器進行交互式啟動 -d 表示可后臺運行容器 (守護式運行) --name 給要運行的容器 起的名字 /bin/bash 交互路徑
docker run -it -d --name 要取的別名 鏡像名:Tag /bin/bash
例如我們要啟動一個redis 把它的別名取為redis001 并交互式運行 需要的命令 —我這里指定版本號為5.0.5
#1. 拉取redis 鏡像
docker pull redis:5.0.5
#2.命令啟動
docker run -it -d --name redis001 redis:5.0.5 /bin/bash

#3.查看已運行容器
docker ps

發現看到了 redis 使用了6379 端口 那么我們在關閉防火墻或開啟了安全組的情況下 是否可以進行訪問呢?
為了區分,使用linux 命令 查看一下
# netstat是控制臺命令,是一個監控TCP/IP網絡的非常有用的工具,它可以顯示路由表、實際的網絡連接以及每一個網絡接口設備的狀態信息
netstat -untlp

redis容器啟動占用的 6379端口netstat 沒有顯示出來
因為:占用的6379端口 僅僅是在容器中內部本身的端口,與宿主機的6379端口并無聯系,我們通過宿主機Ip:6379訪問此redis示例,自然找不到。
每一個 Docker容器都是獨立和安全的應用平臺(我們可以理解為,每一個docker容器都相當于在我們的服務器上占用資源然后開辟了屬于自己的一個空間(也可以理解為服務器))

這是Docker 一大特點,每個容器之間環境都是隔離的!!!
我們甚至可以在一個服務器上,使用docker鏡像,來跑出N個 mysql實例(盡管,他們的默認端口都是一樣的,但還是那句話,容器間,環境是隔離的。A容器中的3306 與B容器的3306毫無關系,因為其不在一個世界呀!)
默認情況下,我們是無法通過宿主機(安裝docker的服務器)端口來直接訪問容器的 ,因為docker容器自己開辟空間的端口與宿主機端口沒有聯系…
如果外部想要訪問容器,那必須得讓容器中的端口與宿主機的端口建立聯系綁定起來,這個正式的概念叫做 容器端口映射
有了端口映射,我們就可以將宿主機端口與 容器端口綁定起來,比如 我們建立宿主機的6379端口與容器redis6379端口綁定起來,那么再訪問宿主機Ip:6379 就可以訪問到對應容器了!
接下來 進行 容器端口映射演示:
-p 宿主機端口:容器端口
還是使用前方的 redis 鏡像 嘗試 將6379端口 映射到服務器的8888 如果成功了的話 那么咱們訪問服務器的8888端口就會訪問到咱們的 docker 中 的容器 redis002
-p 8888:6379 解析 將容器內部的 6379端口與docker 宿主機(docker裝在哪臺服務器 哪臺服務器就是宿主機)8888 端口進行映射 那通過外部訪問宿主機8888端口 即可訪問到 docker 容器 6379 端口了
docker run -itd --name redis002 -p 8888:6379 redis:5.0.5 /bin/bash

在運行后 發現服務器的 8888 端口顯示已被docker-proxy 所占用了 那么此時咱再用工具進行連接測試呢?

那么容器端口映射存在限制:雖說每個容器之間,環境都是隔離的,但是宿主機每個端口都是一個,8888端口被redis002容器綁定了,那么其他所有的容器都不可以使用8888這個端口了。
docker exec -it 容器名/容器ID /bin/bash
#進入 前面的 redis001容器
docker exec -it redis001 /bin/bash

可以看到 已經從主機alibyleilei 跳到了容器ID 對應下的 /data 已經是進入到容器內部了
推薦使用 exec 方式
docker attach 容器名/容器ID
從容器內 退出到自己服務器中 需注意 兩個退出命令的區別
#-----直接退出 未添加 -d(持久化運行容器) 時 執行此參數 容器會被關閉
exit
# 優雅退出 --- 無論是否添加-d 參數 執行此命令容器都不會被關閉
Ctrl + p + q
docker stop 容器ID/容器名
docker restart 容器ID/容器名
docker start 容器ID/容器名
docker kill 容器ID/容器名
無論容器是否開啟 都可以進行拷貝
#docker cp 容器ID/名稱:文件路徑 要拷貝到外部的路徑 | 要拷貝到外部的路徑 容器ID/名稱:文件路徑
#從容器內 拷出
docker cp 容器ID/名稱: 容器內路徑 容器外路徑
#從外部 拷貝文件到容器內
docker cp 容器外路徑 容器ID/名稱: 容器內路徑
docker logs -f --tail=要查看末尾多少行 默認all 容器ID

在運維的時候,通常給一些軟件喜歡設置開機自啟動,例如 mysql、redis,這樣測試環境服務器重啟時可節省不少運維時間成本,那么我們如果是docker容器 是否也可以設置開機自啟動容器呢?
可以
啟動容器時,使用docker run命令時 添加參數--restart=always 便表示,該容器隨docker服務啟動而自動啟動
docker run -itd --name redis002 -p 8888:6379 --restart=always redis:5.0.5 /bin/bash
簡單來講,就是將容器內的數據與外部宿主機文件綁定起來,類似一個雙持久化,當容器刪除時,宿主機文件數據目錄仍在,下次啟動容器只要將數據目錄指向宿主機數據所在位置即可恢復!
-v 宿主機文件存儲位置:容器內文件位置
如此操作,就將 容器內指定文件掛載到了宿主機對應位置,-v命令可以多次使用,即一個容器可以同時掛載多個文件
-v 宿主機文件存儲位置:容器內文件位置 -v 宿主機文件存儲位置:容器內文件位置 -v 宿主機文件存儲位置:容器內文件位置
示例:
# 運行一個docker redis 容器 進行 端口映射 兩個數據卷掛載 設置開機自啟動
docker run -d -p 6379:6379 --name redis505 --restart=always -v /var/lib/redis/data/:/data -v /var/lib/redis/conf/:/usr/local/etc/redis/redis.conf redis:5.0.5 --requirepass "password"
但是還要刪除容器
不想刪容器,又想讓這個容器設置開機自啟動,修改其啟動配置即可
docker update --restart=always 容器Id 或者 容器名
或
docker container update --restart=always 容器Id 或者 容器名
具體看博客:
https://blog.csdn.net/weixin_46822367/article/details/122044031https://blog.csdn.net/leilei1366615/article/details/106269231
需求:
外部修改 同步到容器 或類似于宿主機與容器間的端口映射
數據卷的大致概念就是個可供容器使用的特殊目錄,它繞過文件系統,可以提供很多有用的特性:
數據卷可以在容器之間共享和重用
對數據卷的修改會立馬生效
對數據卷的更新,不會影響鏡像
卷會一直存在,直到沒有容器使用
簡單使用:
docker volume create mydata
docker volume ls
docker volume inspect mydata
docker rename 容器ID/容器名 新容器名

運行的容器可能在鏡像的基礎上做了一些修改,需要保存起來,封裝成一個更新的鏡像,這時候我們就需要使用 commit 命令來構建一個新的鏡像
docker commit -m="提交信息" -a="作者信息" 容器名/容器ID 提交后的鏡像名:Tag
拉取一個tomcat鏡像 并持久化運行且設置與宿主機進行端口映射
docker pull tomcat
docker run -itd -p8080:8080 --name tom tomcat /bin/bash
但是訪問端口,發現訪問404,這是由于配置阿里云鏡像后,所拉取的鏡像都是最基礎的,僅僅包含其容器必要數據
就需要使用提交命令,將運行的tomcat容器打包為一個全新的鏡像
docker commit -a="leilei" -m="第一次打包鏡像,打包后直接訪問還會404嗎" 231f2eae6896 tom:1.0
接下來 運行咱自己打包的鏡像 tom:1.0
設置容器名字為lei 映射端口為6500:8080
docker run -d -it -p6500:8080 --name lei tom:1.0 /bin/bash
訪問6500 端口進入到了 tomcat 首頁 說明 咱commit 鏡像成功了
sudo docker info | grep "Docker Root Dir"

du -hs /var/lib/docker/
# 首先我們需要先停止docker
systemctl stop docker
# 創建新工作目錄文件夾
mkdir -p /docker-data
# 原docker數據遷移
cp -r /var/lib/docker
docker system df
# 刪除異常停止的容器
docker rm `docker ps -a | grep Exited | awk '{print $1}'`
# 刪除名稱或標簽為none的鏡像
docker rmi -f `docker images | grep '<none>' | awk '{print $3}'`
注意,此命令只要是鏡像無容器使用(容器正常運行)都會被刪除,包括容器臨時停止:
docker system prune -a
find / -type f -size +100M -print0 | xargs -0 du -h | sort -nr
=================
本文主要參考:
https://blog.csdn.net/leilei1366615/article/details/106267225