Docker_Study
00x1 前言
在Docker出现之前,人们使用的是虚拟机技术,通过软件
模拟的具有完整硬件
系统功能的、运行在一个完全隔离
环境中的完整计算机系统
。
![image-20230410100236526](https://gitee.com/viat_rain/image/raw/master/pic/image-20230410100236526.png)
但是其资源占用多,启动多。而容器化技术不是一个模拟的完整的操作系统
![image-20230410100542464](https://gitee.com/viat_rain/image/raw/master/pic/image-20230410100542464.png)
区别:
- 传统的虚拟机,可以虚拟出一条硬件,运行一个完整的操作系统,在这个操作系统上安装和运行所需的软件
- 容器内的应用可以直接运行在宿主主机的内核中,容器没有自己的内核,也不用虚拟硬件 (轻便)
- 每个容器是相互隔离的,每个容器内都有属于自己的文件系统,之间互不影响
00x2 Docker介绍
基本组成
镜像:docker镜像就好比一个模板,我们可以通过这个模板来创建容器服务,tomcat镜像=>run>tomcat01容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的
容器:docker利用容器技术,独立运行一个或者一组应用 通过镜像来创建
启动,停止,删除,基本命令!
目前就可以把这个容器理解为就是一个简易的linux系统
仓库:仓库就是存放 镜像(image)的地方!,仓库又可以分为 公有仓库和私有仓库
Docker安装流程
基本命令
# 搜索镜像
docker search 镜像名
# 拉取镜像
docker pull 镜像名
# 运行镜像
docker run 镜像名
# 查看已下载镜像
docker images
# 查看容器
docker ps -a
# 运行/停止容器
docker start/stop 容器ID
# 删除容器
docker rm 容器ID
# 删除镜像
docker rmi 镜像ID
# 进入容器
docker exec -it
工作原理
Docker是一个Client-Server结构的系统,Docker守护进程即Server端运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
下面这个架构就简单清晰指明了server/client交互,容器和镜像、数据之间的一些联系。
![image-20230410104739769](https://gitee.com/viat_rain/image/raw/master/pic/image-20230410104739769.png)
docker cli 用来管理容器和镜像,客户端提供一个只读镜像,然后通过镜像可以创建多个容器,这些容器可以只是一个RFS(Root file system根文件系统),也可以是一个包含了用户应用的RFS,容器再docker client中只是要给进程,两个进程之间互不可见。
用户不能与server直接交互,但可以通过与容器这个桥梁来交互,由于是操作系统级别的虚拟技术,中间的损耗几乎可以不计。
然而docker架构中的模块有:Docker Client、Docker Daemon、Docker Registry、Graph、Driver、libcontainer以及Docker container。这里不一一做介绍
00x3 镜像
创建镜像
除了从Docker镜像仓库拉取镜像外,我们可以根据自己的需求创建镜像
- 从已经创建的容器中更新镜像,并且提交这个镜像
创建容器常用的参数说明:
创建容器命令:docker run
-i:表示运行容器
-t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。
--name :为创建的容器命名。
-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。
-d:在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i -t两个参数,创建后就会自动进去容器)。
-p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p做多个端口映射
使用commit命令来提交容器副本
docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
参数说明
-m: 提交的描述信息
-a: 指定镜像作者
e218edb10161:容器 ID
runoob/ubuntu:v2: 指定要创建的目标镜像名
我们还可以用 docker history
具体查看镜像内的历史记录,如果比较 nginx:latest
的历史记录,我们会发现新增了我们刚刚提交的这一层。
- 使用 Dockerfile 指令来创建一个新的镜像
使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
eg.
runoob@runoob:~$ cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "[email protected]"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
其中每一条指令都会在镜像上创建一个新的层
docker build -t runoob/centos:6.7 .
-t :指定要创建的目标镜像名
. :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
Dockerfile
FROM指令
from:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
构建镜像
docker build -t nginx:v3 .
最后一个 . 是上下文路径,如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
RUN指令与CMD指令
RUN指令在docker build时执行,有两种格式
shell格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
CMD是在docker run时运行,如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
ENTRYPOINT指令
不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
eg.
VOLUME 定义匿名卷
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile
中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
格式为:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
docker run -d -v mydata:/data xxxx
在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代了 Dockerfile 中定义的匿名卷的挂载配置。
ENV指令与ARG指令
设置环境变量,在后续的指令中,就可以使用这个环境变量。(设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用,其意义在于方便维护)其中ARG指令只能在docker build时设置,也就是说,构建好的镜像内不存在此参数,构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
ARG <参数名>[=<默认值>]
EXPOSE指令
声明端口,在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
EXPOSE <端口1> [<端口2>...]
HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
LABEL
LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
ONBUILD <其它指令>
00x4 Dockerfile多阶段构建
使用多个FROM images as name
语句 分阶段构建docker
00x5 Docker compose
之前学习了如何使用dockerfile生成单个容器,然而,在实际工作中,我们常常遇到多个容器搭配使用的情况,compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
yml 配置指令参考
compose默认模板文件为yaml格式
version: '2'
services:
web:
image: vulhub/cacti:1.2.22
ports:
- "8080:80"
depends_on:
- db
entrypoint:
- bash
- /entrypoint.sh
volumes:
- ./entrypoint.sh:/entrypoint.sh
command: apache2-foreground
db:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=cacti
每个服务都需要根据image指定镜像或者build命令指定dockerfile文件,如果使用 build
指令,在 Dockerfile
中设置的选项(例如:CMD
, EXPOSE
, VOLUME
, ENV
等) 将会自动被获取,无需在 docker-compose.yml
中重复设置。
build
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
context指定Dockerfile文件夹路径
dockerfile指令指定Dockerfile文件名,默认的模板文件名称为 docker-compose.yml
使用 cache_from
指定构建镜像的缓存
cache_from:
- alpine:latest
- corp/web_app:3.14
cache_from
指定了使用哪些镜像作为缓存。如果Docker构建过程中需要下载依赖或者执行耗时的操作,可以使用之前已经缓存的镜像,从而加速构建。在这个例子中,使用了两个缓存镜像:alpine:latest
和corp/web_app:3.14
。alpine:latest
是一个官方镜像,提供了一个轻量级的Linux发行版,而corp/web_app:3.14
则是一个私有镜像
cap_add, cap_drop
指定容器内核能力(capacity)分配
command
覆盖容器启动后默认执行的命令。
command: echo "hello world"
cgroup_parent
指定父 cgroup
组,意味着将继承该组的资源限制。
例如,创建了一个 cgroup 组名称为 cgroups_1
。
cgroup_parent: cgroups_1
container_name
指定容器名称。默认将会使用 项目名称_服务名称_序号
这样的格式。
container_name: docker-web-container
devices
指定设备映射关系。
devices:
\- "/dev/ttyUSB1:/dev/ttyUSB0"
depends_on
表明依赖关系
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
这里先启动db与redis再启动web服务
healthcheck
通过命令检查容器是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
volumes
数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER
)或者数据卷名称(VOLUME:CONTAINER
),并且可以设置访问模式 (HOST:CONTAINER:ro
)。
该指令中路径支持相对路径。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
version: "3"
services:
my_src:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
标签:容器,Study,指令,镜像,Docker,Dockerfile,docker
From: https://www.cnblogs.com/vitara/p/17304572.html