Docker
Docker容器是一种轻量级的虚拟化技术,它可以在操作系统级别隔离出一个独立的运行环境。每个Docker容器都包含了一个完整的应用程序以及其所依赖的所有组件。
和传统的虚拟机相比,Docker容器更加轻量级,不需要额外的操作系统,而是共享主机操作系统的内核。这使得Docker容器的启动和停止速度都比虚拟机快,占用的资源也更少。同时,Docker容器也比虚拟机更加灵活,可以快速地扩展、部署和管理。
总的来说,Docker容器相比虚拟机更加精简、高效,对于快速部署、持续集成和交付等场景非常适用。而虚拟机则更适合需要完全隔离、安全性要求较高的场景。
Docker架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker包括三个基本概念,镜像image,容器container,仓库repository。镜像和容器的关系类似于类与实例的关系,镜像是静态的模板,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。从镜像容器角度,可以把容器看作成一个简易的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
仓库可以看成一个代码控制中心,用来保存镜像。可以将镜像发布到仓库上,再拉取下来即可。类似于github,该仓库也分为public和private。
docker build 本地文件构建镜像
docker pull 从仓库拉取镜像
docker run 根据镜像创建一个实例并执行
Docker安装
docker并非一个通用的容器工具,其依赖于已存在并运行的Linux内核环境。
Docker实质上是在已经运行的Linux下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的Linux主机。
因此,Docker必须部署在Linux内核的系统上,如果其他系统想部署Docker就必须安装一个虚拟Linux环境。
Getting start
1.克隆入门版存储库
git clone https://github.com/docker/getting-started.git
实际上就是克隆了一个简单的前后端开发的网页
2.查看
git clone下来的文件就在当前命令行目录对应的目录下
cd gitting-started/app
然后使用如下命令创建一个Dockerfile
type nul > Dockerfile
使用文本编辑器打开Dockerfile,添加以下内容:
# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
EXPOSE 3000
3.构建容器映像
docker build -t getting-start .
注意:docker build命令末尾的 **.**告诉docker应该在当前目录中查找Dockerfile
查看Dockerfile中的配置
FROM node:18-alpine
#配置构建器要从node:18-alpine映象开始。但是,由于你的机器上没有它,Docker需要下载镜像。
WORKDIR /app
COPY . .
RUN yarn install --production
#Docker下载镜像后,Dockerfile中的指令会复制到应用程序中,并使用yarn安装应用程序的依赖项。CMD指令指定从该映像启动容器时要运行的默认命令。
CMD ["node", "src/index.js"]
EXPOSE 3000
-t标志标记您的图像。简单地将其视为最终图像的人类可读的名称。由于您将映像命名为getting-started,因此在运行容器时可以引用该映像。
启动应用程序容器
docker run -dp 3000:3000 getting-started
您可以使用-d
标志以“分离”模式(在后台)运行新容器。您还可以使用-p
标志创建主机端口3000到容器端口3000之间的映射。 如果没有端口映射,您将无法访问应用程序。
镜像加速器配置
阿里云容器镜像服务 ACR,个人版。根据文档进行配置即可。
为什么docker要比虚拟机快
(1)docker有着比虚拟机更少的抽象层
由于docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源.
因此在CPU、内存利用率上docker将会在效率上有明显优势。
(2)docker利用的是宿主机的内核,而不需要加载操作系统OS内核当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。进而避免引导、加载操作系统内核返回等比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个docker容器只需要几秒钟。
帮助启动类命令
启动docker:systemctl start docker
停止docker:systemctl stop docker
重启docker:systemctl restart docker
查看docker状态:systemctl status docker
开启启动:systemctl enable docker
查看docker概要信息 docker info
查看docker总体帮助文档 docker --help
查看docker命令帮助文档 docker 具体命令 --help
镜像命令 image
1.查看本地镜像 docker images
docker images
列出本地主机的镜像
-a 列出所有镜像
-q 只显示镜像id
2.搜索镜像 docker search
docker search
在远程仓库中查看是否存在镜像
各个字段含义
当我们需要使用某个镜像时,可以利用该指令来进行搜索,一般选有OFFICIAL认证的镜像,靠谱!
search查出来的镜像不一定全部对我们有用,可以使用–limit来限制列出镜像的个数,例如:
docker search --limit 5 redis 列出点赞数最高的前五项
3.下载镜像 docker pull
docker pull 镜像名[:TAG]
没有TAG默认为最新版,即latest版本
4.查看镜像\容器\数据卷所占的空间 docker system df
docker system df
5.删除镜像 docker rmi
docker rmi 镜像名/镜像ID
rm为remove的缩写,i为镜像image
docker rmi -f 镜像ID
docker rmi -f 镜像名:TAG 镜像名2:TAG
docker rmi -f ${docker images -qa} docker支持参数传递,删除全部镜像,用了提桶跑路
面试题:docker虚悬镜像是什么?
虚悬镜像就是指仓库名、标签都是的镜像
容器命令 container
1.启动容器 docker run
docker run 容器名
docker run -it 容器名
i标记interactive,保持stdin,即使未连接
t为tty,为终端
-it就开启了一个可以交互的终端
![image-20231122170017382](https://i-blog.csdnimg.cn/blog_migrate/d9349859315fa07f269056cc767f7985.png)
启动一个交互式的ubuntu应用
docker run -it ubuntu /bin/bash
在使用docker运行容器时,需要指定容器的启动命令来确定容器的行为。如果没有指定启动命令,Docker会尝试执行容器的默认命令。对Ubuntu镜像而言,其默认命令是/bin/bash,在容器中启动一个bash终端。
2.容器列表 docker ps
docker ps
3.退出、启动、重启、停止、强停、删除容器
退出容器 ,且容器停止或者容器不停止
exit 退出,容器停止
ctrl+p+q 退出,容器不停止
启动已经停止运行的容器
docker start
重启
docker restart
停止
docker stop
强制停止
docker kill
删除已经停止的容器
docker rm
删除未停止的,强制删除
docker rm -f 容器名/id
4.重要
有镜像才能创建容器
启动守护式容器
docker run -d 容器服务在后台运行,即启动守护式容器
但是需要注意一些特殊情况,容器运行的命令如果不是一直挂起的命令(比如运行top,tail),就是会自动退出的,这是docker的自身的机制。
一般启动容器后,需要用docker ps检查一下容器是否还在运行。
docker run -d ubuntu
然后使用docker ps发现ubuntu容器已经停止。
查看容器日志
docker logs 容器id
查看容器内运行的进程
docker top 容器id
查看运行容器内部细节
docker inspect 容器id
volumes : 容器卷
进入运行的容器并与命令行重新交互
docker exec 类似于docker run
docker exec -it 容器id(不是镜像名) /bin/bash
演示使用ubuntu或者centos镜像
docker attach 容器id
从容器拷贝数据到实例
docker cp 容器id:容器内路径 目的主机路径
导入和导出容器
导出容器
docker export 容器ID > 文件名.tar
导入容器
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
Docker镜像
镜像 是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
只有通过这个镜像文件才能生成Docker容器实例
由此,我们可以观察到Docker采用的是一种分层文件系统。
bootfs作为镜像的的最底层,主要包含bootloader和kernel, bootloader主要是引导加载kernel。boot加载完后,内存的使用权由bootfs转交给内核,此时系统会卸载bootfs。
rootfs则是典型的Linux系统中的/dev,/proc等标准目录和文件。
镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用
比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
Commit命令–容器增强
commit提交容器副本使之成为一个新的镜像,与Docker采用的这种分层文件系统息息相关,新的镜像在原有镜像文件系统的基础上向上逐渐增加文件层。
docker commit -m "提交信息" -a "作者" 容器id 仓库名:TAG版本号
实例:存储一个带有vim命令的ubuntu镜像
docker exec -it a09506b9164f /bin/bash
apt-get update
apt-get install vim
docker commit -m="add vim cmd" -a="wyj" a09506b9164f wyj/mybuntu:1.1
本地镜像发布到阿里云
![image-20240101155046799](https://i-blog.csdnimg.cn/blog_migrate/3985dd6771050455e768219753cd0982.png)
使用Dockerfile或者commit命令生成image,然后将image推送到远程仓库中。
使用阿里云远程仓库时,需要在阿里云容器镜像服务个人实例中先定义命名空间,然后创建镜像仓库,选择本地仓库源提交。
docker私有库
将本地镜像发布到私有库
dockerhub官方公共镜像仓库,由于部署在外网,且部分涉密项目不适合上传至公共库,此时则需要使用私有库。
-
下载镜像docker registry
-
运行私有库registry,相当于本地有个私有docker hub
docker run -d -p 5000:5000 -v /wyj/myregistry/:/tmp/registry --privileged=true registry
网络请求先访问到主机端口,然后再通过主机端口映射到docker里的容器端口,完成一次网络通信。
默认情况下,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便宿主机联调
-
案例演示创建一个新镜像,ubuntu安装ifconfig命令
重新启动ubuntu docker run -it ubuntu /bin/bash 更新apt-get apt-get update 安装net-tools apt-get install net-tools
安装完成后
docker commit -m="ifconfig cmd add" -a="wyj" 1480beaaacc4 wyj/ubuntu:1.2
-
curl验证私服库上有什么镜像
curl -XGET http://47.113.199.154:5000/v2/_catalog
-
将新镜像wyjubuntu:1.2修改为符合私服规范的Tag
docker tag wyjubuntu:1.2 47.113.199.154:5000/wyjubuntu:1.2
相当于克隆了一份镜像
-
修改配置文件使之支持http
配置文件在设置阿里云镜像加速器时配置过。
由于docker默认不允许以http方式推送镜像,通过配置选项来取消这个限制。
vim /etc/docker/daemon.json
配置完后不生效,则重启docker
systemctl restart docker docker run -d -p 5000:5000 -v /wyj/myregistry/:/tmp/registry --privileged=true registry
-
push推送到私服库
docker push 47.113.199.154:5000/wyjubuntu:1.2
-
curl验证私服库上有什么镜像
curl -XGET http://47.113.199.154:5000/v2/_catalog
-
pull到本地并运行
docker rmi -f 镜像名 docker pull 47.113.199.154:5000/wyjubuntu:1.2 docker run -it 47.113.199.154:5000/wyjubuntu:1.2 /bin/bash
容器数据卷
privileged=true 参数作用,扩大容器的权限解决挂载目录没有权限的问题。
docker run -d -p 5000:5000 -v /wyj/myregistry/:/tmp/registry --privileged=true registry
其中-v设置,通过数据卷将容器中的数据备份到宿主机中,备份的数据与docker容器的生存周期相独立。
添加容器卷
privileged 有特权的
docker run -it --privileged=true -v /宿主机绝对路径:/容器内目录 镜像名
主机修改与容器修改双方互通。
查看数据卷是否挂载成功
docker inspect 容器id
binds对应挂载目录
启动ubuntu容器
docker修改,主机同步获得
主机修改,docker同步获得
docker容器stop,主机修改,docker启动后查看数据是否同步? -->同步
容器卷ro和rw读写规则
ro规则,read-only
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data:ro ubuntu
容器目录:ro 镜像名 定义了容器只能读取不能写
如果宿主机写入内容,则可以同步给容器内,容器可以读取到。
rw则为可读可写规则
容器卷之间的继承
容器1完成与宿主机的映射
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name u1 ubuntu
容器2继承容器1的卷规则,–volumes-from u1
docker run -it --privileged=true --volumes-from u1 --name u2 ubuntu
docker常用软件的安装
docker安装redis
创建宿主机目录
mkdir -p /app/redis
将一个redis.conf文件拷贝进/app/redis目录
cp redis.conf /app/redis
修改redis配置文件,
vim redis.conf
设置守护模式不打开
daemonize no
docker启动命令
docker run -p 6379:6379 --name myr3 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis redis-server /etc/redis/redis.conf
docker run -p 6379:6379 --name myr3 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -v /app/redis/dumpfiles:/app/redis/dumpfiles -d redis redis-server /etc/redis/redis.conf
docker exec -it myr3 /bin/bash
redis-cli -a 密码
set k1 v1
get k1
docker run -p 6380:6380 \
--name spzx_redis \
--privileged=true \
-v /app/redis/spzx_redis.conf:/etc/redis/redis.conf \
-v /app/redis/data:/data \
-v /app/redis/dumpfiles:/app/redis/dumpfiles \
-d redis redis-server /etc/redis/redis.conf
docker run -p 6380:6380 \
--name spzx_redis \
--privileged=true \
-v /project/redis/spzx_redis/redis.conf:/etc/redis/redis.conf \
-v /project/redis/data:/data \
-v /project/redis/dumpfiles:/app/redis/dumpfiles \
-d redis redis-server /etc/redis/redis.conf