之前對 docker 只是簡單的使用,會操作基本命令。這週末對 docker 進行了複習,這次才真正理解了 docker 的精髓,原來之間的 docker 命令只是簡單的入門。理解數據卷、使用 dockerfile 纔是在實際項目中可能使用的。
希望這個博客可以系統的幫你瞭解 docker,領略它的精髓。
1 Docker 概述
1.1 爲了解決什麼問題?
開發對項目開發完畢後,交給測試人員進行測試的時候會因爲環境和配置的問題而導致項目的差異。
開發人員利用Docker可以在安裝的時候,把原始環境一模一樣地複製過來,消除協作編碼時“在我的機器上可以正常運行”的問題。
集羣部署過程中爲了解決在多臺服務器上重複安裝軟件,配置環境。通過鏡像將系統所需要的環境進行打包,達到應用程序跨平臺間的無縫接軌運作
1.2 優點
DevOps(開發、運維)
-
應用更快速的交付和部署
- 傳統:一對幫助文檔,安裝程序。
- Docker:打包鏡像發佈測試一鍵運行。
-
更便捷的升級和擴縮容
- 使用了 Docker之後,我們部署應用就和搭積木一樣
- 項目打包爲一個鏡像,擴展服務器A!服務器B
-
更簡單的系統運維
- 在容器化之後,我們的開發,測試環境都是高度一致的
-
更高效的計算資源利用
- Docker是內核級別的虛擬化,可以在一個物理機上可以運行很多的容器實例!服務器的性能可以被壓榨到極致。
2 Docker安裝
2.1 環境要求
Linux 內核 3.0 以上,使用命令進行查看
[root@iz2ze5d0fgh0v0c0oi7xmzz ~]# uname -r
3.10.0-1062.1.1.el7.x86_64
# 查看配置
[root@iz2ze5d0fgh0v0c0oi7xmzz ~]# 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"
2.2 下載
參考官網文檔 https://docs.docker.com/engine/install/
#1.卸載舊版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#2.需要的安裝包
yum install -y yum-utils
#3.設置鏡像的倉庫, 默認是從國外的,不推薦,可以設置爲阿里雲的
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#推薦使用國內的
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#4.更新yum軟件包索引
yum makecache fast
#5.安裝docker相關的 docker-ce 社區版 而ee是企業版
yum install docker-ce docker-ce-cli containerd.io
#6. 使用docker version查看是否按照成功
docker version
#7. 測試
docker run hello-world
# 查docker鏡像
docker images
2.3 卸載 docker
#1. 卸載依賴
yum remove docker-ce docker-ce-cli containerd.io
#2. 刪除資源
rm -rf /var/lib/docker
# /var/lib/docker 是docker的默認工作路徑!
2.4 添加阿里雲的鏡像加速
針對Docker客戶端版本大於 1.10.0 的用戶
您可以通過修改daemon配置文件/etc/docker/daemon.json來使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xy8nrzhm.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3 Docker命令
幫助命令
docker version
docker info
# 查看幫助
docker --help
3.1 鏡像命令
# 查看本地鏡像
docker images
# 列出本地所有鏡像
>docker images -a
# 查看本地鏡像只顯示 ImageId
docker images -q
# 顯示鏡像的摘要信息
docker images --digests
# 顯示完整的鏡像信息
docker images --no-trunc
docker search 某個鏡像名字
# 搜索https://hub.docker.com上某個鏡像
docker search tomcat
# 搜索點贊超過30的tomcat
docker search -s 30 tomcat
docker pull 某個鏡像名字
# 下載鏡像,默認是最新版本
docker pull tomcat
# 同
docker pull tomcat:lastest
docker rmi 鏡像名字
docker rmi tomcat
# 加入 -f ,強制刪除
docker rmi -f tomcat
# 刪除多個鏡像
docker rmi -f tomcat nginx
# 刪除全部
docker rmi -f $(docker images -qa)
3.2 容器命令
# 鏡像id 新建容器並啓動
docker run
# 列出所有運行的容器 docker container list
docker ps
# 刪除指定容器
docker rm 容器id
#啓動容器
docker start 容器id
#重啓容器
docker restart 容器id
#停止當前正在運行的容器
docker stop 容器id
#強制停止當前容器
docker kill 容器id
退出容器
# 容器直接退出
exit
# 容器不停止退出
ctrl +P +Q
刪除容器
docker rm 容器id #刪除指定的容器,不能刪除正在運行的容器,如果要強制刪除 rm -rf
docker rm -f $(docker ps -aq) #刪除指定的容器
docker ps -a -q|xargs docker rm #刪除所有的容器
3.3 操作命令
後臺啓動命令
docker run -d centos
進入當前正在運行的容器
# 方式一
docker exec -it 55321bcae33d /bin/bash
# 方式二
docker attach 55321bcae33d
##### 區別 ####
#docker exec #進入當前容器後開啓一個新的終端,可以在裏面操作。(常用)
#docker attach # 進入容器正在執行的終端
從容器內拷貝數據到主機上
# 1、先進入容器中
docker exec -it dv321bcae33d /bin/bash
# 2、進行復制
docker cp dv321bcae33d:/text.txt / #拷貝
3.4 Demo
docker啓動 nginx
# 啓動運行 Nginx,指定端口
docker run -d -p 8002:80 nginx
啓動 tomcat
# 拉取 tomcat
docker pull tomcat
# 啓動
# -p 宿主機端口:容器內部端口
docker run -d -p 8001:8080 --name tomcat docker.io/tomcat
# 進入容器
docker exec -it 133a6c5addd3 /bin/bash
# 發現 webapps 下沒有文件,解決辦法,將 webapps.dist 下的文件進行復制到 webapps
cp -r webapps.dist/* webapps
再次訪問,沒有問題
curl localhost:8001
4 Docker鏡像
所有的 Docker鏡像都起始於一個基礎鏡像層,當進行修改或培加新的內容時,就會在當前鏡像層之上,創建新的鏡像層。
4.1 commit 鏡像
使用 commit 製作自己的鏡像
由於 docker 上的 tomcat webapps 下沒有文件,解決辦法,將 webapps.dist 下的文件進行復制到 webapps,然後將這個新的進行進行提交保存,這樣下次使用 tomcat 鏡像,可以直接使用自己的(即 webapps 有文件的)
# docker commit -m="描述信息" -a="作者" 容器id 目標鏡像名:[TAG]
docker commit -m="add webapps app" -a="wmding" 133a6c5addd3 my_tomcat:1.0
# 再次啓動 d320039e29a2 爲新鏡像的 id
docker run -d -p 8001:8080 d320039e29a2
5 容器數據卷
5.1 使用數據卷
# 方式一
docker run -it -v 主機目錄:容器內目錄
# 掛載
docker run -it -p 8080:8001 -v /home/test:/home d320039e29a2 /bin/bash
# 查看
docker inspect 容器id
docker inspect 156ab0613b8f
如下:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Y3ipTBsC-1592147939783)(/Users/wmding/Desktop/image-20200614101259245.png)]
使用掛載就實現了,主機和容器的連接,實現了數據的同步,
# 停止正在運行的容器
docker stop 156ab0613b8f
# 在主機中添加一個文件,看是否容器類是否可以數據同步
# 啓動容器
docker start 156ab0613b8f
# 進入正在運行的容器
docker attach 156ab0613b8f
使用這種方式,之後只需要在本地修改即可,容器內會自動同步,就不容進去容器中進行修改了。
安裝MySQL
# 獲取鏡像
docker pull mysql:5.7
# 注意,在啓動mysql時需要制定密碼
docker run --name some-mysql -e MY_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 啓動
-d 後臺啓動
-p 端口映射
-v 卷掛載
-e 環境配置
--name 容器名字
docker run -d -p 3301:3306 -v /home/mysql/conf:/ect/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql_5.7 docker.io/mysql
# 啓動後,使用工具在進行連接,測試完成
5.2 具名和匿名掛載
上邊的掛載,是指定了要掛載的目錄;如果不指定目錄,即爲匿名掛載,如下:
# 匿名掛載
# -v 容器內地址,然後會默認在主機上的 docker 目錄下,新建一個映射的文件
docker run -d -p 8001:80 -v /ect/nginx nginx
# 查看該容器掛載的卷
docker inspect 5bec313d13f7
# /var/lib/docker/volumes/578996253fdb969e9d5e05c623503735a5f351359041423ca0360dc1d1783a17/_data
# 具名掛載,指定了主機的文件名,但是沒有指定路徑,會默認在 docker 目錄中
docker run -d -p 8002:80 -v nginx_test:/ect/nginx nginx
# 查看掛載的卷
docker inspect ee4c4f0ee362
# /var/lib/docker/volumes/nginx_test/_data
#######
"Mounts": [
{
"Type": "volume",
"Name": "nginx_test",
"Source": "/var/lib/docker/volumes/nginx_test/_data",
"Destination": "/ect/nginx",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
#######
總結
三種掛載:
-
匿名掛載
- -v 容器內路徑
-
具名掛載
- -v 卷名:容器內路徑
-
指定路徑掛載
-v /宿主機路徑:容器內路徑
# 通過 -v 容器內路徑:
ro rw 改變讀寫權限
ro #readonly 只讀
rw #readwrite 可讀可寫
docker run -d -P --name nginx01 -v nginx_test:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v nginx_test:/etc/nginx:rw nginx
# ro 只要看到ro就說明這個路徑只能通過宿主機來操作,容器內部是無法操作!
6 DockerFile
Dockerfile 就是用來構建docker鏡像的構建文件,命令腳本。
- 編寫一個 dockerfile 文件
- docker build 構建一個鏡像
- docker run 運行鏡像
- docker push 發佈鏡像
6.1 Dockerfile 構建過程
-
每個關鍵字指令,都必須是大寫字母
-
執行順序,從上到下
-
#
表示註釋 -
每一個指令都會創建提交一個新的鏡像層,並提交。
Dockerfile 是面向開發的,做鏡像,就需要編寫 dockerfile逐漸成爲了我們交付的標準。
Dockerfile:構建文件,定義了一切步驟,源代碼
DockerImages:通過Dockerfile 構建生成的鏡像,最終發佈和運行的產品
Docker容器:容器就是鏡像運行起來提供服務的
6.2 Dockerfile 命令
# 基礎鏡像,一切從這裏構建
FROM
# 鏡像是誰寫的,姓名 + 郵箱
MAINTAINER
# 鏡像構建的時候需要的命令
RUN
# 添加內容
ADD
# 鏡像的工作目錄
WORKDIR
# 掛載的目錄
VOLUME
# 暴露端口
EXPOSE
# 指定這個容器啓動的時候要運行的命令
CMD
# 指定這個容器啓動的時候要運行的命令,可以追加命令
ENTRYPOINT
# 當構建一個被繼承 Dockerfile ,這個時候就會運行 ONBUILD 命令,觸發指令
ONBUILD
# 複製,將文件拷貝到容器中
COPY
# 構建的時候設置環境變量
ENV
Centos 的官方例子
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20200504" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-05-04 00:00:00+01:00"
CMD ["/bin/bash"]
6.3 實例
6.3.1 編寫 Dockerfile
FROM centos
MAINTAINER wmding<[email protected]>
# 設置工作目錄
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 8001
CMD echo $MAPATH
CMD echo "----end----"
CMD /bin/bash
6.3.2 docker build 鏡像
# 命令 docker build -f 文件路徑 -t 鏡像名:[tag] .
docker build -f dockerfile-centos -t mycentos:1.0 .
# 一定要注意這個點 .
6.3.3 啓動
# 因爲在構建鏡像的時候寫版本號了,這裏要需要有版本號,否則會要從遠端查詢
docker run -it mycontos:1.0
列出本地進行的變更歷史,可以使用這個命令查看其他鏡像是如何製作的
docker history aadfdfdke
6.4 CMD 和 ENTRYPOINT區別
CMD # 指定這個容器啓動的時候要運行的命令,只有最後一個會生效,可被替代
ENTRYPOINT # 指定這個容器啓動的時候要運行的命令,可以追加命令
測試cmd
# 編寫dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 構建鏡像
$ docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
# 運行鏡像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
# 想追加一個命令 -l 成爲ls -al
$ docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
# cmd的情況下 -l 替換了CMD["ls","-l"]。 -l 不是命令所有報錯
測試ENTRYPOINT
# 編寫dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我們的命令,是直接拼接在我們得ENTRYPOINT命令後面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 May 16 06:32 dev
drwxr-xr-x 1 root root 4096 May 16 06:32 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64 ....
6.5 Tomcat 鏡像
6.5.1 準備鏡像文件
事先下載好 tomcat 和 jdk 文件,編寫 README
6.5.2 編寫 dockerfile
FROM centos
MAINTAINER wmding<[email protected]>
COPY README /usr/local/README #複製文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #複製解壓
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #複製解壓
RUN yum -y install vim
ENV MYPATH /usr/local #設置環境變量
WORKDIR $MYPATH #設置工作目錄
ENV JAVA_HOME /usr/local/jdk1.8.0_231 #設置環境變量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #設置環境變量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #設置環境變量 分隔符是:
EXPOSE 8080 #設置暴露的端口
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out # 設置默認命令
6.5.3 構建鏡像
# 因爲dockerfile命名使用默認命名 因此不用使用-f 指定文件
$ docker build -t mytomcat:0.1 .
6.5.4 運行鏡像
$ docker run -d -p 8080:8080 --name tomcat01 -v /home/docker_test/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/docker_test/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
6.6 SpringBoot微服務打包Docker鏡像
6.6.1 構建SpringBoot項目
自行構建
6.6.2 打包項目
mvn package
6.6.3 編寫dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
6.6.4 構建鏡像
# 1.複製 jar 和 dockerfile到服務器
# 2.構建鏡像
docker build -t xxxxx:xx .