😀😀😀创作不易,各位看官点赞收藏.
文章目录
- Docker 学习笔记
- 1、容器
- 2、Docker 安装
- 3、Docker 常用命令
- 4、Docker 镜像
- 5、自定义镜像
- 5.1、镜像推送到阿里云
- 5.2、镜像私有库
- 6、数据卷
- 7、Docker 软件安装
- 8、Docker File
- 8.1、常见保留字
- 8.2、虚悬镜像
- 8.3、Docker 构建运行服务镜像
- 9、Docker 网络
- 10、Docker-Compose容器编排
- 11、Docker 监控工具 Portainer
Docker 学习笔记
在微服务的环境下,项目模块部署和服务化成为问题。传统开发是直接将项目部署到服务器上,可能出现项目需要的版本和环境不一致和多个服务下环境版本冲突问题,这就给项目发布和运维造成很大麻烦,往往出现开发的环境能跑,而运维的环境不能跑。Docker采用容器技术,将项目、需要的环境打成一个镜像,将镜像放在容器中运行,每个容器之间相互不影响,也可以实现跨平台部署每个Docker去加载同一个镜像文件加载的内容都是一样的。
1、容器
虚拟机:
一种带环境安装的解决方案,在Windows下安装Linux系统就是通过将Linux的镜像文件通过虚拟机可以与Windows物理系统下进行交互,在Windows下就是一个应用程序。但是虚拟机有占用资源多,步骤复杂及启动慢等缺点。(在硬件上实现虚拟化)
虚拟化容器技术:
Linux容器不是模拟整个操作系统而是对进程进行隔离,将软件运行需要的资源打包成一个镜像,在容器中运行镜像文件。这样需要的资源少,而且部署到任何环境中软件都能运行。(在操作系统上实现虚拟化)
Docker:一种虚拟化容器技术,基于软件镜像可以秒启动各种软件。每一个容器都是一个完整的运行环境,容器之间相互隔离。每个容器都是一个简易版的Linux系统。
Docker是一个C/S架构,C端通过Docker daemon守护进程连接到Docker主机,发送一些列操作指令。然后在Docker引擎上,查看是否有镜像,如果有镜像就形成一个个容器实例,如果没有镜像就去仓库拉下来一个镜像进行操作。
Docker工作流程:
- Docker客户端与守护进程建立通信,并发送指令请求并提供Docker Server功能使其可以接受客户端的请求。
- Docker引擎执行Docker执行内部的一些列工作,每个工作已Job的形式存在,每个容器就是一个Job。
- 当需要Docker网络管理时,通过网络管理驱动Network driver创建并配置Docker容器网络环境。
2、Docker 安装
docker官网:https://docs.docker.com/
docker hub镜像仓库地址:https://hub.docker.com/
Docker 并不是一个通用的工具,必须运行在Linux内核下。可以在Windows下安装一个虚拟机来跑Docker。Docker最基本的是三要素:镜像、容器、仓库。容器就是一个 最小Linux环境+运行在其中的镜像应用程序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-28V3IT1z-1690515838077)(https://jx-image-storage.oss-cn-hangzhou.aliyuncs.com/image/image-20220926153055055.png)]
卸载之前的docker:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装gcc和gcc- c++
yum -y install gcc
yum -y install gcc- c++
配置安装:
yum install -y yum-utils # 下载依赖的包
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 配置安装地址,使用阿里云的镜像仓库
yum makecache fast # 更新yum包
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin # 安装
启动docker:
systemctl start docker # 启动
docker version # 检查docker版本
docker images # 查看docker安装的镜像
systemctl enable docker # 开机自动启动
配置阿里云镜像加速:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eLovpSd0-1690515838078)(https://jx-image-storage.oss-cn-hangzhou.aliyuncs.com/image/image-20220926161645401.png)]
mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["xxxxxxxx"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
卸载Docker:
# 停止docker
systemctl stop docker
# 移除docker
yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 删除配置文件
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
3、Docker 常用命令
Docker启动命令:
# 启动、重启、停止
systemctl start/restart/stop docker
# 查看docker状态
systemctl status docker
# 开启自启
systemctl enable docker
# 概要信息
docker info
# 帮助文档
docker --help
# 具体命令文档
docker 命令 --help
镜像命令:
# 查看docker中的镜像
docker images
# REPOSITORY: 仓库名,TAG:版本,IMAGE ID: 镜像id不重复,CREATED:创建时间,SIZE:大小
# 列出本地所有镜像(包含历史印象层)
docker images -a
# 只显示id
docker images -q
# 从远程仓库查询镜像
docker search xxxx(镜像名称) [--limit n]
# 下载,获取指定版本号,不写tag就是默认最新版本,或者:last也是最新版本
docker pull 镜像名称[:tag]
# 查看docker中的镜像数、容器、数据卷、缓存等使用信息
docker system df
# 删除镜像,根据名称或者id删除
docker rmi 镜像名称、id
# 删除多个
docker rmi 名称1:tag 名称2::tag
# 删除全部镜像
docker rmi $(docker images -qa)
# 如果镜像在使用中,需要强制删除,可以使用-f
docker rmi -f 镜像名称
虚悬镜像:仓库名和tag都是<none>
的镜像,但是也有大小,一般没有什么用建议删除。
容器命令:
# 创建并启动一个容器
docker run 镜像名称或id
# 参数
# --name="容器新名称"
# -d 后台运行容器并返回容器的id
# -i 以交互式运行容器,通常与-t同时使用
# -t 重新分配终端进行操作,通常与-i同时使用
# -p 指定端口映射,-p hostPort:containerPort,
# 启动一个ubuntu的容器,并打开一个Ubuntu的终端
docker run --name="u1" ubuntu /bin/bash
# 查看docker中运行的容器
docker ps [-a 所有在运行及运行过的容器][-l 显示最近创建容器][-q 只显示容器编号][-n x显示最近创建的x个容器]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8oTsVuff-1690515838078)(https://jx-image-storage.oss-cn-hangzhou.aliyuncs.com/image/image-20220926231642383.png)]
# 退出容器,直接退出,容器停止
exit
# 退出容器,退出容器终端,但是容器依然运行
ctrl+p+q
# 启动已停止的容器
docker start 容器名称或id
# 重启容器
docker restart 容器名或id
# 停止容器
docker stop 容器名或id
# 强制停止容器
docker kill 容器名或id
# 删除已停止的容器
docker rm [-f 强制删除在运行的容器] 容器名或id
# 一次删除多个容器,删除所有容器
docker rm -f $(docker ps -a -q)
# 参数删除,先进行查询,然后将查询的结果通过管道符传入
docker ps -a -q | xargs docker rm -f
# 后台运行容器(守护式容器:容器在后台默默运行)
docker run -d 镜像名
# Docker后台运行程序必须要有一个前台进程,如果容器运行命令不是一直挂起的命令,启动后就会自动退出
docker run -d ubuntu /bin/bash # 没有前台程序并且不是一直挂起命令启动后就会自动退出(Docker机制问题)
# 解决方案:将程序以前台命令运行或者使用一些挂起命令
# 以redis为例:
docker run -it redis # 以前台模式启动容器,退出容器,容器自动停止
docker run -d redis # 以后台模式启动容器,由于redis有前台进程,容器就会自动在后天运行不会停止
# 查看容器日志
docker logs 容器名或id
# 查看容器进程,类似Linux中的top命令
docker top 容器名或id
# 查看容器内部的细节,返回的是json串,包含了容器的所有细节
docker inspect 容器名或id
# 进入正在运行的容器中并执行命令
docker exec -it 容器名或id 运行命令
docker attach 容器名或id
# exec:在容器中打开新的终端,并可以启动新的进程,exit退出容器不会停止
# attach:直接进入容器的启动命令终端,不会启动新的进程,exit退出容器容器会停止
# 例如进入redis容器
docker exec -it redis /bin/bash
# 从容器拷贝文件到主机
docker cp 容器名称或id:容器内路径 目的主机路径
# 导出容器,它导出的是一个tar文件
docker export 容器名或id > 主机上存放路径
# 导入导出的镜像
cat xx.tar | docker import - 镜像用户/镜像名称:tag
4、Docker 镜像
镜像:一种轻量级的、可执行的独立软件包,把应用程序和配置依赖打成一个可交付的运行环境。Docker只有通过镜像才能生成一个实例容器。
UnionFS联合文件系统:一种分层、轻量并且高性能的文件系统,支持对文件修改来作为一次次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。特点:一次可以加载多个文件系统,但是只能看到一个文件系统,联合加载会把各个文件系统叠加起来,这样最后的文件系统会包含所有的底层文件和目录。Docker的镜像实际是一层一层的文件系统,就是联合文件系统。
Docker镜像加载原理:Docker最底层是引导文件系统
bootfs
,这一层和Linux系统一样,包含了boot加载器和内核(bootfs
:包含bootloader:boot加载器
和kernel:Linux内核
)。boot加载器加载完后,整个内核就在内存中此时内存的使用权由boot加载器转交给内核并卸载掉boot加载器。rootfs
层:在bootfs
之上,包含的是Linux系统中标准的文件,它是各个不同操作系统的发行版。不同的Linux发行版会公用bootfs
,只有rootfs
不同。
Docker采用镜像分成最大的好处就是共享资源,方便复制迁移。例如多个镜像可以从同一个Base镜像构建而来,Docker主机上就只保留一份基础镜像,在内存中也只需加载Base镜像,这样就可以通过在Base镜像启动多个容器。Docker镜像的每一层都是可以被共享的。Docker的镜像层都是只读的,只有容器层可以写。当容器启动,一个新的可写层加载到镜像层的上面,称为容器层。
5、自定义镜像
commit命令:提交一个容器副本,使之成为一个新的镜像。
# 由容器获取一个新的镜像
docker commit -m="提交信息" -a="作者" 容器名或容器id 新镜像名:tag
# 这就可以通过扩展当前的镜像,创建新的镜像,类似Java中的继承,这也是为什么Docker中为什么要分层。
5.1、镜像推送到阿里云
在阿里云官网找到镜像服务并开启个人版的镜像服务,然后创建一个命名空间。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ib6a3616-1690515838079)(https://jx-image-storage.oss-cn-hangzhou.aliyuncs.com/image/image-20221001191032743.png)]
创建一个阿里云镜像仓库,在管理页面获取镜像操作的脚本命令。
# 推送镜像命令:
docker login --username=xxx(个人阿里云账号) registry.cn-hangzhou.aliyuncs.com
docker tag [推送镜像id] registry.cn-hangzhou.aliyuncs.com/liujixing/db_1:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/liujixing/db_1:[镜像版本号]
# 拉取阿里云上的镜像
docker pull registry.cn-hangzhou.aliyuncs.com/liujixing/db_1:[镜像版本号]
5.2、镜像私有库
私有库:在本地搭建一个私有库,不会将镜像放在公网上。
- 下载Docker私有仓库镜像
docker pull registry
- 修改配置文件并重启docker
vim /etc/docker/daemon.json
{
# 设置私库的地址和端口号
"insecure-registries": ["192.168.59.111:5000"], #添加此段,“,”不可少,ip是本机IP地址
"registry-mirrors": ["xxx"] # 阿里云加速
}
systemctl restart docker
- 运行私有库镜像
# 前者是主机,后者是容器
docker run -d -p 5000:5000 -v /liujixing/docker_registry:/tmp/registry --privileged=true registry
- 按格式打包镜像并上传到私库
docker tag 镜像名称:1.3 私服端口:5000/私服镜像名称:1.3
docker push 打包好的镜像
# 查看是否上传成功
curl -XGET http://xxxx:5000/v2/_catalog
- 测试下载私服上的镜像
docker pull ip:端口/镜像名称:tag
注意避坑:
- 在云服务器上一定打开对应对口的防火墙。
- 修改docker的
daemon.json
文件一定要重启(配置私服主机时)。 - 启动好私服镜像一定要检查端口是否映射正确。
6、数据卷
Docker数据卷:将容器的数据文件保存到主机当中,以至于当容器停止后容器中的数据全部都消失,类似于
redis
中的rdb
和aof
。使用数据卷来达到容器重要数据的备份。
# --privileged=true 打开docker到主机目录映射的权限
# -v 主机绝对路径:容器绝对路径,设置数据卷,如果不设置默认是容器中的/usr/lib/registry
docker run --privileged=true -v 主机绝对路径:容器绝对路径 镜像名
特点:
- 数据卷可以在容器间相互共享。
- 数据卷中的数据时实时更新的。
- 数据卷的更改不会包含在镜像的更新中。
- 数据卷的生命周期一直持续到没有容器使用。
挂载数据卷:
# 挂载了数据卷,可以挂载多个,一个 -v 对应一个挂载
docker run -d -it --name="redis_new" --privileged=true -v /tmp/docker_data/redis_new:/tmp/docker_data redis /bin/bash
# 在容器的映射目录下创建一个文件dockerin.txt,并在主机上的映射文件上查看发现主机上也实时更新了
# 在主机上创建一个dockerout.txt,然后进入容器中也会发现有这么一个文件
# 映射路径下,主机和容器之间的数据相互共享
# 查看容器上的数据卷挂载,返回json字符串
docker inspect 容器名或id
# 查看数据卷
docker volume ls
# 删除一个容器连同数据卷也删除
docker rm -v containerId|containerName
# 删除数据卷
docker volume rm 数据卷名称
# 删除所有数据卷
docker volume rm $(docker volume ls)
# 删除没有用的数据卷
docker volume prune
当容器停止后重启时,会同步挂载到主机上的目录,容器上的映射文件会实时与主机上映射文件保持一致。
数据卷读写(
rw
)和只读权限(ro
): 数据卷映射时,默认是容器内是可读和可写,也可以指定容器内的读写权限,这就限制了容器内部数据同步到主机。
# 在容器映射后面添加:ro
docker run -d -it --name="redis_new" --privileged=true -v /tmp/docker_data/redis_new:/tmp/docker_data:ro redis /bin/bash
数据卷的继承与共享:容器2可以去继承容器1的数据卷的映射规则,相当于容器1和容器2都同时挂载到了主机上的同一个目录。
# 启动一个容器,并且容器的数据卷规则继承另一个容器
docker run -d -it --privileged=true -volumes-from 父容器名或id 镜像名
子容器继承父容器的数据卷规则,当父容器停止,子容器依然可以同步主机,当父容器重启,父容器也依然可以同步主机的映射数据。
7、Docker 软件安装
Tomcat
- 镜像拉取
docker pull tomcat
# 查看端口占用情况
lsof -i 协议:端口号
- 启动tomcat
docker run -d -it --name="tomcat1" --privileged=true
-v /usr/server/tomcat/webapps:/usr/local/tomcat/webapps
-p 8080:8080
tomcat
- 进入容器,查看tomcat是否启动
docker exec -it xx /bin/bash
ps -ef | grep tomcat
MySQL
- 拉取镜像
docker pull mysql
- 启动
MySQL
docker run -d -it -p 3306:3306 --privileged=true
-v /usr/server/mysql/log:/var/log/mysql
-v /usr/server/mysql/data:/var/lib/data
-v /usr/server/mysql/conf:/etc/mysql/conf.d
-e MYSQL_ROOT_PASSWORD=liuhongjun --name mysql
mysql
# docker run -d -it -p 3306:3306 --privileged=true -v /usr/server/mysql/log:/var/log/mysql -v /usr/server/mysql/data:/var/lib/data -v /usr/server/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=liuhongjun --name mysql mysql
- 解决容器
MySQL
字符编码问题
- 主机上的映射文件的
conf
文件下创建my.cnf
文件(MySQL8
是下面这样,其它版本不知道)
vim my.cnf
# 输入下面内容
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8
collation-server = utf8_unicode_ci
init_connect='SET NAMES utf8'
- 重启
MySQL
并进入容器查看字符编码(在MySQL
中查看)
# 查看编码命令
SHOW VARIABLES LIKE 'character%'
redis
- 拉取镜像
docker pull redis:7.0.5
- 启动redis
docker run -p 6379:6379 --privileged=true \
--name redis7.0.5_1 \
-v /usr/server/redis/conf/redis.conf:/etc/redis/redis.conf \
-v /usr/server/redis/data:/data \
-d redis:7.0.5 \
redis-server /etc/redis/redis.conf \
--appendonly yes
注意避坑:
- 一定要先将配置文件创建到主机得映射路径上,然后在启动容器,不然挂载可能出现问题。
- 不要修改配置文件的
daemonize
为yes,修改后会启动失败。
- 连接测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZnneoye-1690515838081)(https://jx-image-storage.oss-cn-hangzhou.aliyuncs.com/image/image-20221003025441713.png)]
Gitea
- 拉取镜像
docker pull gitea/gitea
- 启动容器
docker run -d --name=gitea_1 --privileged=true --restart=always
-p 10022:22 -p 13000:3000
-v /usr/server/gitea:/data
gitea/gitea
8、Docker File
DockerFile: 是用来构建docker镜像的文本文件,是一条条构建镜像的指令和参数构成的脚本。一般使用dockerfile文件打包新镜像,并把镜像运行到容器中,主要分三步:编写文件、build文件、run镜像。
- 每条保留字指令都必须为大写,并且后面必须跟至少一个参数。
- 每条指令按照从上到下执行。
#
表示注释。- 每条指令都会创建一个新的镜像层对镜像进行提交。
DockerFile执行流程:
8.1、常见保留字
-
FROM:一般是第一条命令,指定基础镜像来之哪个镜像。
-
MAINTAINER:指定这个镜像的作者是谁和作者邮箱。
-
RUN:这个命令是在docker build构建时运行的命令,一般有两种格式 shell 和 exec。
-
shell:相当于在终端执行脚本,例如 RUN yum -y install vim。会在构建镜像时会安装 vim。
-
exec:可执行文件,例如 RUN [ “可执行文件”, “参数1”, “参数2” ]。
-
-
EXPOSE:当前容器对外暴露出的端口。
-
WORKDIR:指定创建容器后,终端默认登录进来的工作目录。
-
USER:指定镜像以什么用户执行,默认是root。
-
ENV:用来在构建镜像过程中的环境变量,这个环境变量可以在后续的任何 RUN 命令中使用,也可以在其它指令中使用。
# 变量
ENV PATH /usr/local
# 使用变量
WORKDIR $PATH
- VOLUME:容器卷,用于数据保存和持久化工作,
- ADD:将宿主机上的文件拷贝进镜像,并且自动处理 URL 和解压 tar 压缩包。
- COPY:将宿主机上的文件拷贝到镜像中,
COPY 源文件路径 目标文件路径
,目标文件路径不用事先创建好。 - CMD:指定容器启动后需要干的事情。
注意:
1、DockerFile中可以有多个CMD命令,但是只有最后一个生效。
2、 CMD命令会被 docker run 之后的参数替换掉。
# 在dockerfile中的cmd命令,在运行容器时会启动tomcat
CMD ["catalina.sh", "run"]
# 如果在执行运行容器的命令在run后面添加参数,会被tomcat后面的参数覆盖掉cmd
docker run tomcat /bin/bash
3、RUN 是在构建镜像时运行,而 CMD 是在运行镜像时执行的。
- ENTRYPOINT:在容器启动时需要运行的命令,类似 CMD 但是不会被 docker run 后面的参数覆盖掉,而且 docker run 后面的参数会作为参数传递给 ENTRYPOINT。
# 格式
ENTRYPOINT ["执行的命令", "参数1", "参数2"]
# ENTRYPOINT可以和CMD一起使用,一起使用时CMD相当于是给ENTRYPOINT传参数。
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.cnf"]
8.2、虚悬镜像
虚悬镜像:仓库名、标签名都是
<none>
的镜像称为虚悬镜像,俗称:dangling image。这种镜像存在缺陷,建议删除。
# 在 docker build 没有指定仓库名、标签名就会构建一个虚悬镜像,`docker build .`
# 查看当前的虚悬镜像
docker images ls -f dangling=true
# 删除所有的虚悬镜像
docker images prune
8.3、Docker 构建运行服务镜像
使用 Dockerfile 构建一个可以运行 jar 的镜像,这样只要云翔镜像容器就可以直接启动服务。
- 编写 Dockerfile 文件:
# 需要一个有java环境的基础镜像,这个需要自己构建也可以使用仓库中的
FROM java8:1.0
# 自定义工作目录时不能PATH,可能会覆盖基础镜像的路径,导致命令运行失败
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 添加jar包
ADD xxx.jar $MYPATH/jars/xxx.jar
RUN bash -c 'touch $MYPATH/jars/xxx.jar'
# 也可以使用COPY命令添加jar包
# COPY test.jar $MYPATH/jars/test.jar
# 暴露端口
EXPOSE 8080
# 运行镜像时执行命令
ENTRYPOINT ["java","-jar","./jars/xxx.jar"]
- 构建镜像:
# 运行构建命令, 注意后面有一个点,不能缺少
docker build -t java_test:1.0 .
- 运行镜像:
# 运行命令
docker run -d -p 8081:8080 java_test:1.0
- 测试:
注意:在 Dockerfile 中的数据挂载是匿名挂载,VOLUME /usr/local/oas/file/
,它会将容器中指定的目录挂载到宿主机上的 /var/lib/docker/volumes/
中的随机目录下,这种方式自定义不强,一般采用 -v 的方式进行挂载。
nohup命令:
nohup java -jar xx.jar >>/mylog.log 2>&1 &
# >>/mylog.log 将日志信息追加到指定文件,还有一种是>将日志信息重定向到新文件
# 0:标准输入信息
# 1:标准信息
# 2:标准错误信息
# &:后台运行程序,关闭窗口程序不会停止
# 2>&1:将错误和标准信息都输出到指定文件中
9、Docker 网络
Docker 启动后,会在宿主机上创建一个名为 docker0 的虚拟网桥,负责配置docker与宿主机的网络连接以及容器与容器之间的网络连接。
Docker 服务默认创建一个 docker0 网桥,它在内核层联通;了其它物理或虚拟网卡,这将所有容器和宿主机放到同一个网络段,让宿主机和网络通过网桥相互通信。
常见命令:
# 查看容器网络模式,默认创建3个网络模式
docker network ls
# 创建自定义网络类型,自定义网络模式默认驱动都是bridge
docker network create xxxx
# 查看模式详情
docker network inspect xxx
# 清除没用的网络模式
docker network prune
# 删除网络模式
docker network rm xxx
应用:
- 容器间的网络互连以及端口映射。
- 容器 IP 变动时,可以通过容器名称进行访问。(每次重启 docker 容器时,容器的 IP 可能会变化)
Docker 网络模式:
网络模式 | 命令 | 作用 |
---|---|---|
bridge(默认) | –network bridge | 为每一个容器分配一个 IP 地址,并将容器连接到 docker0 这个虚拟网桥上 |
host | –network host | 容器不会虚拟自己的网卡,而是使用宿主机网卡,宿主机有什么,这个容器就有什么 |
none | –network none | 容器不会有网络配置。 |
container | –network container:容器名称 | 容器不会创建自己的网卡,而是和指定一个已创建的容器共享它的网卡,已创建容器停止后,自己就会断网 |
查看容器网络配置:
# 起一个容器
docker run -it centos:centos7 /bin/bash
# 查看容器详情
docker inspect 容器id
重启容器时,容器配置的 IP 地址可能会发生变化。
bridge网络模式:
docker0 网桥上有一堆接口,每一个接口叫 veth,每个容器也有一个网卡接口 eth0,当启动一个容器时会将容器的网卡接口和网桥上的接口一一配对,分配自己的 ip 地址。由于容器都是连接到网桥的接口上,所以容器与容器之间都是相互连通的。
# 创建两个容器
docker run -it centos:centos7 /bin/bash
- 宿主机上的网卡:出现对应的容器网卡对接到 docker0 网桥上。
- 容器中的网卡:容器与网桥上的接口都是一一匹配的。
host 网络模式:直接使用宿主机的 ip 地址与外界通信,不创建容器自己的网卡。
none 网络模式:没有配置虚拟网卡,相当于没有网络设置,只有一个本地回环地址。
# 起none网络模式的容器
docker run -it --network=none centos:centos7 bin/bash
container 网络模式:新建容器会与运行的一个容器共享一个网卡和端口,新建容器不会虚拟新的网卡。除了网络是共享的,其它功能都是隔离的。
自定义网络模式:创建的网络模式默认使用 bridge 驱动,可以使用容器名在容器之间相互连接。(容器的 ip 地址是动态的)
# 创建自定义网络
docker network create xxx
# 使用自定义网络来运行容器
docker run -it -d --network=my_network --name t1 centos:centos7 /bin/bash
docker run -it -d --network=my_network --name t2 centos:centos7 /bin/bash
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aLoZN8S1-1690515838084)(https://jx-image-storage.oss-cn-hangzhou.aliyuncs.com/image/image-20230522000300284.png)]
10、Docker-Compose容器编排
docker-compose:是 docker 官方开源的项目,负责实现对 docker 容器集群的快速编排。你只需要定义一个 docker-compose.yml 文件,定义好多个容器间调用关系,然后只需要一个命令可以快速关闭、启动这些容器。
随着实例化的容器越来越多,对这些容器的管理成为一个问题。还有就是容器启动可能存在先后顺序,需要先启动某个容器,然后再启动容器,这就需要一个管理者来进行管理,就是 docker-compose。它允许用户通过一个单独的 docker-compose.yml 配置文件来定义一组关联的应用容器作为一个项目。
# 下载安装docker-compose
curl -SL https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 修改文件权限
chmod +x /usr/local/bin/docker-compose
# 测试是否安装完成
docker-compose --version
# 卸载
rm $DOCKER_CONFIG/cli-plugins/docker-compose
docker-compose使用步骤:
- 编写 Dockerfile 定义各个微服务应用并构建其镜像。
- 使用 docker-compose.yml 定义一个完整工程单元,安排应用中各个容器服务。
- 执行 docker-compose up 命令启动运行整个工程,完成一键部署。
docker-compose常用命令:
# 查看帮助
docker-compose -h
# 启动docker-compose的所有服务,加了-d这些服务在后台运行
docker-compose up [-d]
# 停止并删除容器、网络、数据卷、镜像
docker-compose down
# 进入启动的服务实例
docker-compose exec yml中的服务id /bin/bash
# 查看运行的所有容器
docker-compose ps
# 查看运行的所有容器的线程
docker-compose top
# 查看某个容器的输出日志
docker-compose logs yml中的服务id
# 检查配置,加了-q后检查配置,有问题才会输出
docker-compose config [-q]
# 重启服务、启动服务、停止服务
docker-compose restart/start/stop
编写 docker-compose.yml 文件:
# 使用3以上的
version : '3.8'
# 需要启动的服务
services:
# 服务名,唯一即可
redis:
# 容器名:--name,不加这个字段,容器名默认为 当前文件夹名-服务名-id
container_name: redis1
# 运行的镜像
image: redis:latest
# 映射端口
ports:
- "6379:6379"
# 使用的网络模式
networks:
- test_network
# 传递的参数
#environment:
# 数据卷挂载
volumes:
# 在docker中中运行redis需要将后台运行关闭,不然运行不了
- ./redis/conf/redis.conf:/etc/redis/redis.conf
- ./redis/data:/data
# 依赖于什么服务镜像,这些镜像需要先启动
# depends_on:
# 运行时执行的命令,相当于 CMD
command:
redis-server /etc/redis/redis.conf
# tomcat
tomcat:
container_name: tomcat1
image: tomcat:latest
ports:
- "8080:8080"
networks:
- test_network
volumes:
- ./tomcat/webapps:/usr/local/tomcat/webapps
- ./tomcat/conf/sever.xml:/usr/local/tomcat/conf/server.xml
# 定义网络,用于创建自定义网络模式,网络模式是bridge,名称是 当前文件夹_t
networks:
test_network:
检查文件配置是否正确:
# 如果没有信息输出则文件正确
docker-compose config -q
使用编排来启动容器:
# 容器以后台运行,可以指定启动对应服务,不写这是全部启动
docker-compose up -d [服务名1] [服务名2]
11、Docker 监控工具 Portainer
Portainer:是一个图形化界面的 Docker 管理工具,可以在这个界面对容器进行操作。
# 安装命令,它也是可以跑在docker上的
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest