一、单容器
1.1概念简介
Docker三个重要概念:
- 仓库(Repository);
- 镜像(Image);
- 容器(Container). *Docker的三个重要概念是仓库(Repository)、镜像(Image)和容器(Container)**。具体如下:
- **镜像(Image)**:Docker镜像是创建容器的基础,它类似于虚拟机的镜像,是一个只读的模板,包含了操作系统、软件运行环境以及用户应用程序。镜像是用于创建Docker容器的蓝图,通过版本管理和增量文件系统,Docker提供了一套简单的机制来创建和更新现有的镜像。
- **容器(Container)**:Docker容器是从镜像创建的应用运行实例。容器可以启动、开始、停止和删除,而且它们之间是相互隔离的,互不影响。容器利用了Linux内核的特性来实现应用的运行和隔离,因此相比传统的虚拟化技术,容器更加轻量级,启动速度快,资源消耗少。可以把容器看作是由镜像这个“类”实例化出的一个独立运行的“对象”。
- **仓库(Repository)**:Docker仓库用来集中存放和管理镜像文件,类似于代码仓库。仓库分为公共仓库和私有仓库。公共仓库如Docker Hub提供了大量的官方和第三方镜像供用户下载使用。私有仓库则是企业内部用于存储自己创建的镜像的地方,通常用于提高镜像下载的速度和安全性。
1.2底层原理
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
DockerServer接收到Docker-Client的指令,就会执行这个命令!
1.3Docker基本命令
Docker指令处理单条使⽤外,还⽀持赋值、解析变量、嵌套使⽤.
Docker指令的基本⽤法
docker + 命令关键字(COMMAND) + 参数
docker pull <image>
:从注册表(如Docker Hub)下载映像。docker build -t <image_name> <path>
:从Dockerfile构建映像,其中<path>
是包含Dockerfile的目录。docker image ls
:列出本地计算机上可用的所有映像。docker run -d -p <host_port>:<container_port> --name <container_name> <image>
:从映像运行容器,将主机端口映射到容器端口。docker container ls
:列出所有正在运行的容器。docker container stop <container>
:停止正在运行的容器。docker container rm <container>
:从本地计算机中删除已停止的容器。docker image rm <image>
:从本地计算机中删除映像。
-----帮助命令-----
docker version # docker版本信息
docker info # 系统级别的信息,包括镜像和容器的数量
docker 命令 --help
docker info
docker info
命令用于获取Docker的系统信息,包括版本、容器数量、存储驱动、网络配置等。以下是一些常见的输出信息:
Containers:
当前运行的容器数量。Images:
当前存在的镜像数量。Storage Driver:
使用的存储驱动名称和版本号。System Time:
系统时间。ID:
Docker守护进程的ID。Logging Driver:
日志驱动程序的名称和版本号。Cgroup Driver:
Cgroup驱动程序的名称和版本号。Operating System:
操作系统的名称和版本号。Kernel Version:
内核版本号。Architecture:
CPU架构(x86_64)。CPUs:
CPU核心数。Total Memory:
总内存大小。Name:
Docker主机名。Labels:
Docker主机标签。
-----镜像命令-----
docker search
docker search
命令用于在Docker Hub上搜索镜像。以下是一些常见的输出信息:
NAME
: 镜像名称。DESCRIPTION
: 镜像描述。STARs
: 该镜像的收藏数·。IS FOR
: 该镜像适用的平台。OFFICIAL
: 是否为官方镜像。AUTOMATION
: 是否支持自动化构建。LAST UPDATED
: 最后更新时间。
docker images
docker images
命令用于列出本地主机上的所有Docker镜像。以下是一些常见的输出信息:
REPOSITORY
: 镜像仓库名称。TAG
: 镜像标签。IMAGE ID
: 镜像ID。CREATED
: 创建时间。SIZE
: 镜像大小。
docker rmi
`docker rmi`命令用于删除本地的一个或多个Docker镜像。
以下是一些常见的用法示例:
1. 删除单个镜像:
docker rmi myimage:latest
2. 同时删除多个镜像:
docker rmi myimage:latest myrepo/myotherimage:v1.0
3. 强制删除镜像(包括正在运行的容器所使用的镜像):
docker rmi -f myimage:latest
4. 删除所有未使用的镜像:
docker image prune -a
在执行`docker rmi`命令时,需要注意以下几点:
- 如果指定的镜像正在被容器使用或存在依赖关系,则无法直接删除。在这种情况下,可以先停止并删除相关容器,然后再尝试删除镜像。
- 使用`-f`选项可以强制删除镜像,但这可能会导致数据丢失,因此请谨慎使用。
- -`docker rmi`命令与`docker rm`命令不同,`docker rm`用于删除容器,而`docker rmi`用于删除镜像。
docker pull
`docker pull`命令用于从Docker Hub或其他Docker镜像仓库下载一个或多个镜像到本地。
以下是一些常见的用法示例:
1. 下载单个镜像:
docker pull nginx
2. 同时下载多个镜像:
docker pull nginx redis
3. 指定版本号下载镜像:
docker pull nginx:1.19.0
4. 使用标签(tag)下载镜像:
docker pull nginx:alpine
5. 从私有仓库下载镜像:
docker pull myregistry.com/myrepo/myimage:latest
6. 在下载过程中显示进度信息:
docker pull --progress nginx
7. 指定下载时的代理服务器:
docker pull --proxy=http://myproxy.com:8080 nginx
-----容器命令-----
docker ps
docker ps
命令用于列出当前运行的Docker容器。以下是一些常见的输出信息:
CONTAINER ID
: 容器ID。IMAGE
: 镜像名称和标签。COMMAND
: 启动容器时执行的命令。CREATED
: 容器创建时间。STATUS
: 容器状态,如“Up”表示正在运行,“Exited”表示已停止。PORTS
: 容器暴露的端口号和绑定的主机端口号。NAMES
: 容器名称。
docker ps —no-trunc
`docker ps --no-trunc`命令用于列出所有正在运行的Docker容器,并显示完整的容器信息。
docker run
`docker run`命令用于从Docker镜像创建并启动一个新的容器。
以下是一些常见的用法示例:
1. 运行一个基于Ubuntu的容器,并在其中执行bash shell:
docker run -it ubuntu bash
2. 运行一个基于Nginx的容器,并将主机的80端口映射到容器的80端口:
docker run -d -p 80:80 --name mynginx nginx
3. 运行一个基于Python的容器,并将当前目录挂载到容器的/app目录:
docker run -v $(pwd):/app python myscript.py
4. 运行一个基于Node.js的容器,并将容器的8080端口映射到主机的8080端口:
docker run -d -p 8080:8080 --name mynodejs node myapp.js
在执行`docker run`命令时,需要注意以下几点:
- `-d`选项表示以后台模式运行容器。
- `-p`选项用于将主机的端口映射到容器的端口。
- `--name`选项用于指定容器的名称。
- `-v`选项用于将主机的目录或文件挂载到容器中。
- `CMD`和`ENTRYPOINT`指令用于指定容器启动时要执行的命令。
docker run运行原理
docker start/stop
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前的容器
退出容器
exit # 直接退出容器并关闭
Ctrl + P + Q # 容器不关闭退出
后台启动容器
# 命令 docker run -d 镜像名
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos
# 问题 docker ps, 发现centos停止了
# 常见的坑, docker 容器使用后台运行, 就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx, 容器启动后,发现自己没有提供服务,就会立即停止,就是没有程序了
总结
每个容器被创建之后,都会分配⼀个ContainerID作为容器的唯⼀标识,后续对容器的启动、停⽌、修改、删除等操作,都可以通过这个ID来完成.
1.4常见单容器命令
查看日志
docker logs -tf --tail number 容器id
查看容器中进程信息ps
# 命令 docker top 容器id
具体来说:
- UID: 用户ID,表示启动该进程的用户。
- PID: 进程ID,是操作系统中唯一标识一个进程的数字。
- PPID: 父进程ID,即创建当前进程的进程的ID。
- C: CPU使用率,显示了进程自创建以来占用CPU的时间。
- STIME: 进程开始时的系统时间。
- TTY: 终端类型,? 表示没有关联到特定的终端设备。
- TIME: 进程消耗的CPU时间总和。
- CMD: 启动进程的命令行。
查看镜像的元数据
docker inspect 容器id
进入当前正在运行的容器
# 我们通常容器使用后台方式运行的, 需要进入容器,修改一些配置
# 命令
docker exec -it 容器id /bin/bash
从容器中拷贝文件到主机
docker cp 容器id:容器内路径 目的地主机路径
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker cp 7af535f807e0:/home/Test.java /home
1.5docker run的参数和选项
![](https://i-blog.csdnimg.cn/blog_migrate/6f010ca48c7cf6448d4d21e301148ae4.png)
二、docker-compose介绍
2.1基础介绍
⼀个项⽬的完整环境包括:
- 应⽤(app);
- 数据库(MySQL);
- 缓存(Redis).
例如
docker-compose
容器编排⼯具,允许⽤户在⼀个模版(YAML格式)中定义⼀组相关联的容器,会根据--link等参数对启动的优先级进⾏排序.
2.2主从架构
读写分离实现⽅式
基于程序实现;
基于MySQL⾃带主从同步机制.
节点说明
binlog
- 记录master节点‘增删改查’语句;
relaybinlog
- 记录从master复制过来的SQL语句;
I/O Thread
- ⽤于与master节点通信,传输SQL语句信息;
SQL Thread
- ⽤于从relaybinlog⽂件中读取SQL,并在salve中执⾏.
2.3binary log相关命令
2.4主从同步的作⽤
1.实时灾备;
2.⽤于故障切换;
3.读写分离负载均衡;
4.业务隔离.
主从同步可能引发的问题
1.数据⼀致性问题;
2.从库更新延迟问题.
MySQL可选的主从架构
三、 Docker镜像特性![](https://i-blog.csdnimg.cn/blog_migrate/681d959b2566f76cab8e8d94c1c10b36.png)
3.1Docker镜像特性
- 容器创建时需要制定镜像,每个镜像都有唯⼀的标示Image ID;
- 与Container ID类似,默认都是128位的,可以使⽤前16位缩略形式;
- 也可以使⽤镜像名与版本号(TAG)两部分组成唯⼀标识,如果忽略TAG,默认使⽤latest.
镜像的分层
- 已有的分层只能读不能修改;
- 上层镜像优先级⼤于底层镜像.
3.2Docker镜像加载原理
3.3Dockerfile
dockerfile是用来构建dokcer镜像的文件!命令参数脚本!
Dockerfile由⼀条⼀条的指令组成,每条指令都对应Linux下的⼀条命令. Docker程序将这些Dockerfile指令翻译成真正的Linux命令. Dockerfile有⾃⼰书写的格式和⽀持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile. Docker程序读取Dockerfile,根据指令⽣成定制的image.
docker build -t lowyard/jdk-tomcat .
另外一种方法
容器 -> 镜像
docker commit ContainerID
ImageName:ImageTag⼯作在前台的进程(⾄少⼀个)!!!
构建步骤:
1、编写一个dockerfile文件
2、docker build构建成为一个镜像
3、docker run运行镜像
4、docker push发布镜像(DockerHub、阿里云镜像仓库!)
基础知识:
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
基础指令![](https://i-blog.csdnimg.cn/blog_migrate/511ff42936e70be179bd723f32be44b3.png)
CMD和ENTRYPOINT的区别
追加命令,是直接拼接在我们的ENTRYPOINT命令的后面
3.3实战构建cenos
编写一个dockerfile文件
docker build构建成为一个镜像
docker build -f mydockerfile-cento-test -t mycentos:0.1 .
docker run运行镜像
3.4实战构建tomcat
基础知识TomCat目录结构说明
#TomCat目录结构说明:
bin:该目录存放TomCat二进制可执行文件,常用的有startup.bat和shutdown.bat文件,startup.bat用来启动Tomcat,shutdown.bat用来停止Tomcat;
conf:TomCat服务器的配置目录,主要有server.xml(配置服务器信息,如修改端口号,添加虚拟主机等)、tomcat-users.xml(TomCat用户与角色信息,对TomCat后台管理)和web.xml(Web项目部署描述符文件);
lib:Tomcat所需的jar包; logs:存放TomCat的日志文件;
temp:存放Tomcat的临时文件; webapps:存放所部署的Web项目; work:存放Web项目部署运行时生成的文件,如java和class文件; RUNNING.txt:可查看如何配置TomCat环境变量。
1、准备镜像文件tomcat压缩包,jdk的压缩包!
2、编写dockerfile.文件
FROM centos:7
MAINTAINER yanyu<1994124137@qq.com>
ADD jdk-8u201-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.86.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_201
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.86
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.86
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.86/bin/startup.sh &tail -F /usr/local/apache-tomcat-9.0.86/logs/catalina.out
3、构建镜像
4.测试运行
docker run -d -p 8088:8080 --name diytomcat -v /home/yanyu/build/tomcat/test:/usr/local/apache-tomcat-9.0.86/webapps/test -v /home/yanyu/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.86/logs diytomcat
在Docker中运行一个名为diytomcat的镜像,并将容器命名为diytomcat。容器的8088端口映射到主机的8088端口。同时将主机上的/home/yanyu/build/tomcat/test目录挂载到容器中的/usr/local/apache-tomcat-9.0.86/webapps/test目录,将主机上的/home/yanyu/build/tomcat/tomcatlogs/目录挂载到容器中的/usr/local/apache-tomcat-9.0.86/logs目录。
注意防火墙8088端口开启和8080是tomcat默认端口
-
访问测试
-
发布项目(由于做了卷挂载, 我们直接在本地编写项目就可以发布了)
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
</web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello. xiaofan</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-----my test web logs------");
%>
</body>
</html>
发现:项目部署成功, 可以直接访问ok!
我们以后开发的步骤:需要掌握Dockerfile的编写! 我们之后的一切都是使用docker进行来发布运行的!
四、容器数据卷
4.1 docker的理解回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享技术!Docker容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录挂载到linux目录上面!
**总结: **容器的持久化和同步操作!容器间数据也是可以共享的!
4.2 使用数据卷
直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录
实战:安装MySQL
1.获取镜像
2.运行容器
docker run -d -p 3304:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456b --name diymysql mysql
-d # 后台运行
-p # 端口隐射
-v # 卷挂载
-e # 环境配置
--name # 容器的名字
匿名和具名挂载
匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx # -P 随机指定端口
这种情况就是匿名挂载,我们在-v 后面只写了容器内的路径,没有写容器外的路径!
查看所有volume的情况
docker volume
命令用于管理Docker卷
Docker卷是Docker容器中持久化存储数据的一种方式,它允许在容器之间共享和重用数据。使用Docker卷,可以将容器内的数据与宿主机进行分离,实现数据的持久化和迁移。
以下是一些常用的
docker volume
命令:
创建卷:使用
docker volume create
命令可以创建一个新卷。例如,要创建一个名为myvolume
的卷,可以使用以下命令:docker volume create myvolume
列出卷:使用
docker volume ls
命令可以列出所有可用的卷。例如,要列出所有的卷,可以使用以下命令:docker volume ls
查看卷信息:使用
docker volume inspect
命令可以查看指定卷的详细信息。例如,要查看名为myvolume
的卷的信息,可以使用以下命令:docker volume inspect myvolume
删除卷:使用
docker volume rm
命令可以删除一个或多个卷。例如,要删除名为myvolume
的卷,可以使用以下命令:docker volume rm myvolume
挂载卷到容器:使用
docker run
命令时,可以通过-v
选项将卷挂载到容器中。例如,要将名为myvolume
的卷挂载到容器的/data
目录,可以使用以下命令:docker run -d --name mycontainer -v myvolume:/data myimage
通过使用
docker volume
命令,你可以方便地管理Docker卷,并在容器之间共享和重用数据。
具名挂载
所有docker容器内的卷,没有指定目录的情况下都是在
/var/lib/docker/volumes/xxxxx/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是
具名挂载
总结
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /主机路径:容器内路径 # 指定路径挂载
拓展
# 通过 -v 容器内容路径 ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内容无法操作
DockerFile容器
数据卷容器
多个mysql同步数据!
--volumes-from
`--volumes-from` 是一个在 Docker 命令中使用的标志,它允许你从一个或多个容器挂载(共享)卷。使用这个标志,你可以让新的容器访问其他容器中已经定义的卷,从而重用数据和配置。
以下是 `--volumes-from` 标志的一些典型用途:
1. **创建新容器时挂载现有容器的卷**:
当你运行一个新容器时,可以使用 `--volumes-from` 标志来指定一个或多个现有容器的名字,从而挂载那些容器的卷到新容器中。
例如,如果你有一个名为 `my_existing_container` 的容器,并且你想创建一个新的容器 `my_new_container` 来共享 `my_existing_container` 的卷,你可以运行以下命令:
docker run -d --name my_new_container --volumes-from my_existing_container my_image
这将会启动 `my_new_container` 并挂载 `my_existing_container` 的所有卷到新容器中。
2. **管理卷的生命周期**:
由于卷是独立于容器的生命周期的,使用 `--volumes-from` 可以帮助你在容器之间迁移数据,甚至在容器被删除后保留数据。3. **实现容器间的数据共享**:
如果你想要在多个容器之间共享数据,而不是通过外部存储或者网络,`--volumes-from` 提供了一种方便的机制来实现这一点。需要注意的是,从 Docker 1.9 开始,`--volumes-from` 的功能被 `--mount` 标志所取代,后者提供了更加灵活和强大的卷挂载选项。因此,对于较新版本的 Docker,建议使用 `--mount` 而不是 `--volumes-from`。
例如,使用 `--mount` 的替代命令可能是这样的:
docker run -d --name my_new_container \ --mount source=my_existing_container,target=/data,type=volume my_image
在这个命令中,`source` 参数指定了现有容器的名字,`target` 参数指定了在新容器中挂载的路径,`type` 参数指定了挂载类型为 `volume`。
结论
容器之间配置信息的传递, 数据卷容器的声明周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
五、Docker仓库
Docker Hub
1.地址 注册自己的账号
2.确定这个账号可以登录
3.在我们的服务器上提交自己的镜像
阿里云镜像
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间
commit镜像
docker commit 提交容器成为一个新的版本
# 命令和git 原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="xiaofan" -m="add webapps app" d798a5946c1f tomcat007:1.0