Docker基础学习
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极
Docker的常用命令
帮助命令
docker version # 查看docker版本信息
docker info # 查看docker详细信息。包括镜像和容器的数量
docker 命令 --help
镜像命令
docker images 查看所有本地的主机上的镜像
[root@iZzj5iufefpw7dZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
fastapi latest 7ad89582ee8e 14 hours ago 976MB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a, --all # 列出所有镜像
-q, --quiet # 只显示镜像的id
docker search 搜索镜像
[root@iZzj5iufefpw7dZ ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11197 [OK]
mariadb MariaDB Server is a high performing open sou… 4255 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 833 [OK]
docker pull 下载镜像
# 下载镜像 docker pull 镜像名[:tag]
[root@iZzj5iufefpw7dZ ~]# docker pull mysql
Using default tag: latest # 如果不写 tag,默认就是latest
latest: Pulling from library/mysql
33847f680f63: Pull complete # 分层下载,docker image 的核心 联合文件系统
5cb67864e624: Pull complete
1a2b594783f5: Pull complete
b30e406dd925: Pull complete
48901e306e4c: Pull complete
603d2b7147fd: Pull complete
802aa684c1c4: Pull complete
715d3c143a06: Pull complete
6978e1b7a511: Pull complete
f0d78b0ac1be: Pull complete
35a94d251ed1: Pull complete
36f75719b1a9: Pull complete
Digest: sha256:8b928a5117cf5c2238c7a09cd28c2e801ac98f91c3f8203a8938ae51f14700fd # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
docker pull mysql === docker pull docker.io/library/mysql:latest # 等价
# 指定版本下载
[root@iZzj5iufefpw7dZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
33847f680f63: Already exists
5cb67864e624: Already exists
1a2b594783f5: Already exists
b30e406dd925: Already exists
48901e306e4c: Already exists
603d2b7147fd: Already exists
802aa684c1c4: Already exists
5b5a19178915: Pull complete
f9ce7411c6e4: Pull complete
f51f6977d9b2: Pull complete
aeb6b16ce012: Pull complete
Digest: sha256:be70d18aedc37927293e7947c8de41ae6490ecd4c79df1db40d1b5b5af7d9596
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
[root@iZzj5iufefpw7dZ ~]# docker rmi -f 容器id # 删除指定的容器
[root@iZzj5iufefpw7dZ ~]# docker rmi -f 容器id 容器id 容器id # 删除多个容器
[root@iZzj5iufefpw7dZ ~]# docker rmi -f $(docker images -aq) # 删除全部容器
容器命令
说明:我们有了镜像才可以创建容器,linux,下载centos镜像来测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字 tomcat01 tomcat02,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
-P 随机指定端口
# 测试,启动并进入容器
[root@iZzj5iufefpw7dZ ~]# docker run -it centos /bin/bash
[root@e4eccc01b495 ~]# ls # 查看容器内的centos,基础版本,很多命令是不完善的
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 从容器中退回主机
[root@e4eccc01b495 ~]# exit
exit
列出所有的运行的容器
# docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 显示容器的编号
[root@iZzj5iufefpw7dZ /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
566a3ab5aae0 fastapi "uvicorn run:app --h…" 2 days ago Up 2 days 0.0.0.0:8000->80/tcp, :::8000->80/tcp fastapi
[root@iZzj5iufefpw7dZ /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
566a3ab5aae0 fastapi "uvicorn run:app --h…" 2 days ago Up 2 days 0.0.0.0:8000->80/tcp, :::8000->80/tcp fastapi
退出容器
exit # 直接容器停止并退出
Ctrl + P + Q # 容器不停止退出
删除容器
docker rm 容器id # 删除指定容器,不能删除
docker rm -f $(docker ps -aq) # 删除所有的容器
启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
常用其他命令
后台启动容器
# 命令 docker run -d 镜像名[root@iZzj5iufefpw7dZ /]# docker run -d fastapi# 问题docker ps,发现 fastapi停止了# 常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
查看日志
docker logs -f -t --tail number 容器id
# 显示日志
- tf # 显示日志
--tail number # 要显示日志条数
[root@iZzj5iufefpw7dZ ~]# docker logs -f -t --tail 10 566a3ab5aae0
2021-08-05T02:18:06.924180040Z INFO: 89.248.164.165:33792 - "GET http%3A//www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 Not Found
2021-08-05T03:23:52.601647421Z INFO: 112.95.158.82:57967 - "GET /docs HTTP/1.1" 200 OK
2021-08-05T03:23:53.855487015Z INFO: 112.95.158.82:57967 - "GET /openapi.json HTTP/1.1" 200 OK
查看容器中进程信息 ps
# 命令 docker top 容器id
[root@iZzj5iufefpw7dZ ~]# docker top 566a3ab5aae0
UID PID PPID C STIME TTY TIME CMD
root 8419 8399 0 Aug02 ? 00:21:32 /usr/local/bin/python /usr/local/bin/uvicorn run:app --host 0.0.0.0 --port 80
查看镜像的元数据
# 命令
docker inspect 容器id
[root@iZzj5iufefpw7dZ ~]# docker inspect 566a3ab5aae0
[
{
"Id": "566a3ab5aae022f35a486b92383b75e50dc1af4287e73001c157f88400381b7a",
"Created": "2021-08-02T14:47:45.894256197Z",
"Path": "uvicorn",
"Args": [
"run:app",
"--host",
"0.0.0.0",
"--port",
"80"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 8419,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-08-02T14:47:57.473210172Z",
"FinishedAt": "2021-08-02T14:47:56.225609945Z"
进入当前正在运行的容器
# 我们通常都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id /bin/bash
# 测试
[root@iZzj5iufefpw7dZ ~]# docker exec -it 566a3ab5aae0 /bin/bash
root@566a3ab5aae0:/app# ls
READ.md coronavirus hello_world.py pydantic_tutorial.py run.py
__pycache__ coronavirus.sqlite3 pydantic_tutorial.json requirements.txt turorial
root@566a3ab5aae0:/app# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Aug02 ? 00:21:33 /usr/local/bin/python /usr/local/bin/uvicorn run:app --host 0.0.0.0 --port 80
root 14 0 0 14:43 pts/0 00:00:00 /bin/bash
root 22 14 0 14:45 pts/0 00:00:00 ps -ef
# 方式二
docker attach 容器id
[root@iZzj5iufefpw7dZ ~]# docker attach 566a3ab5aae0
当前正在执行的代码...
# 两者区别
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(*)
# docker atrtach # 进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的
# 测试(从fastapi容器里面把run.py拷贝到linux/home里面)
# 查看当前主机目录下
[root@iZzj5iufefpw7dZ home]# ls
www
# 进入docker容器内部
[root@iZzj5iufefpw7dZ ~]# docker exec -it 566a3ab5aae0 /bin/bash
root@566a3ab5aae0:/app# ls
READ.md coronavirus hello_world.py pydantic_tutorial.py run.py
__pycache__ coronavirus.sqlite3 pydantic_tutorial.json requirements.txt turorial
root@566a3ab5aae0:/app# exit
exit
root@566a3ab5aae0:/app# pwd
/app
# 进行docker拷贝到主机上
[root@iZzj5iufefpw7dZ ~]# docker cp 566a3ab5aae0:/app/run.py /home
# 进入home查看文件
[root@iZzj5iufefpw7dZ ~]# cd ..
[root@iZzj5iufefpw7dZ /]# ls
bin boot dev etc home lib lib64 lost+found media mnt opt patch proc root run sbin srv sys tmp usr var www
[root@iZzj5iufefpw7dZ /]# cd home
[root@iZzj5iufefpw7dZ home]# ls
run.py www
commit镜像
提交一个自己的镜像
docker coomit 提交容器成为一个新的副本
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试:
https://www.bilibili.com/video/BV1og4y1q7M4?p=20&spm_id_from=pageDriver
容器数据卷
方式一:直接使用命令来挂载 -v
docker run -v 主机目录,容器目录
# 测试
[root@iZzj5iufefpw7dZ ~]# docker run -it -v /home/test:/home centos /bin/bash # docker run -it -v /你项目的目录:/你想映射linux的目录 容器名 /bin/bash
# 启动起来过后我们可以通过 docker inspect 容器id 来查看具体卷是如何挂载的
实战:配置Mysql
# 获取镜像
[root@iZzj5iufefpw7dZ ~]# docker pull mysql:5.7
# 运行容器,需要做数据挂载! # 安装启动mysql,需要配置密码,注意!
# 官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@iZzj5iufefpw7dZ ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 启动成功之后,我们在本地使用 Navicat 来测试一下
# Navicat -连接到服务器的3310 --- 3310 和容器内的 3306映射,这个时候我们就可以连接上了!
具名挂载
# 具名挂载
[root@iZzj5iufefpw7dZ ~]# docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx nginx
4f15cf703803df7cf6331b11d0d625d3220aeba3a2ffc1533ba78ecb73262052
[root@iZzj5iufefpw7dZ ~]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的 具名挂载
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库!)
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、# 表示注释
4、每一个指令都会创建提交一个新的镜像,并提交!
DockerFile的指令:
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
COPY # 类似ADD,将我们拷贝到镜像中
ENV # 构建的时候设置环境变量
实战:
创建一个自己的centos
# 1、 编写Dockerfile的文件
[root@iZzj5iufefpw7dZ dockerfile]# cat mydockerfile-centos
FROM cents
MAINTAINER ranyong<1311518086@qq.com>
ENV MYPATH /user/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
# 2、通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag版本号] .
Successfully built bae171a28f1e
Successfully tagged mycentos:01
# 3、测试运行
对比:之前的原声centos
我们增加之后的镜像
我们平时拿到一个镜像,可以研究一下是如何构建的
CMD 和 ENTRYPOINT 区别
测试CMD
# 编写dockerfile文件
[root@iZzj5iufefpw7dZ dockerfile]# vim dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
# 构建镜像
[root@iZzj5iufefpw7dZ dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest ./
# run运行,发现我们的ls-a 命令生效
[root@iZzj5iufefpw7dZ dockerfile]# docker run 57cd92e3cc58
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 想追加一个命令 -l ls -al
[root@iZzj5iufefpw7dZ dockerfile]# docker run 57cd92e3cc58 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
# cmd的情况下 -l 替换了cmd["ls","-a"]命令,-l不是命令所以报错!!
测试ENTRYPOINT
[root@iZzj5iufefpw7dZ dockerfile]# vim dockerfile-cmd-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
[root@iZzj5iufefpw7dZ dockerfile]# docker build -f dockerfile-cmd-entrypoint -t entrypoint-test ./
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in e66a45b9395e
Removing intermediate container e66a45b9395e
---> 564b61033875
Successfully built 564b61033875
Successfully tagged entrypoint-test:latest
[root@iZzj5iufefpw7dZ dockerfile]# docker run 564b61033875
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 我们的追加命令,是直接拼接在我们的ENTRYPOINT 命令后面
[root@iZzj5iufefpw7dZ dockerfile]# docker run 564b61033875 -l
total 56
drwxr-xr-x 1 root root 4096 Aug 8 10:14 .
drwxr-xr-x 1 root root 4096 Aug 8 10:14 ..
-rwxr-xr-x 1 root root 0 Aug 8 10:14 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Aug 8 10:14 dev
drwxr-xr-x 1 root root 4096 Aug 8 10:14 etc
drwxr-xr-x 2 root root 4096 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 2020 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 166 root root 0 Aug 8 10:14 proc
dr-xr-x--- 2 root root 4096 Dec 4 2020 root
drwxr-xr-x 11 root root 4096 Dec 4 2020 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Aug 7 14:48 sys
drwxrwxrwt 7 root root 4096 Dec 4 2020 tmp
drwxr-xr-x 12 root root 4096 Dec 4 2020 usr
drwxr-xr-x 20 root root 4096 Dec 4 2020 var