学习思想而非学技术,技术日新月异,唯有思想长盛不衰,润泽后生
学习资料:
【狂神说Java】Docker最新超详细版教程通俗易懂_哔哩哔哩_bilibili
Docker快速入门总结笔记_huangjhai的博客-CSDN博客
(74条消息) docker 进阶 之容器数据卷 DockerFile Docker网络 — 狂神说_cheng的博客-CSDN博客
官网:https://www.docker.com/
文档地址: https://docs.docker.com/ (Docker 官网文档超级详细)
仓库地址:https://hub.docker.com/
Docker中文文档 Docker概述-DockerInfo
Docker 中文文档(译)_nickDaDa的博客-CSDN博客_docker中文文档
一款产品上线:面临问题:
问题1:开发 和 上线 俩套环境
问题2:开发人员 和 运维人员 ,开发测试可运行,上线就运行不了
问题3:环境配置十分麻烦,每个机器都要部署环境(集群 Redis、ES、Hadoop 等等)
问题4: 发布 jar包 时 又要 部署(Mysql、ES、Redis、jdk 等等)费时的环境,希望jar + 环境一起发布
问题5:部署的环境不能跨平台 windows 与 Linux
Docker 给以上问题提出了解决方案
传统:开发打jar包 给运维来部署
现在:开发即负责打包又负责部署,全栈开发
开发人员 打jar包带上环境(这里的环境称为镜像) – Docker 仓库(商店) – 运维人员下载 镜像 可直接运行
docker 的 思想 来源于 集装箱 ,打包装箱,相互隔离
虚拟机非常笨重,而docker十分小巧。
开源:开放源代码
1、基本介绍
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
官网:https://www.docker.com/
文档地址: https://docs.docker.com/ (Docker 官网文档超级详细)
仓库地址:https://hub.docker.com/
2、应用场景
Web 应用的自动化打包和发布。
自动化测试和持续集成、发布。
在服务型环境中部署和调整数据库或其他的后台应用。
从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
3、Docker 的优势
Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。
(1) 快速,一致地交付您的应用程序。
Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。
容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案:
您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。
(2) 响应式部署和扩展
Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。
Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。
(3) 在同一硬件上运行更多工作负载
Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。
虚拟化技术特点:1.资源占用多 2.冗余步骤多 3.启动很慢
容器化技术:容器化技术不是模拟的一个完整的操作系统
虚拟机非常笨重,而docker十分小巧。
比较Docker和虚拟机的不同:
虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
Docker容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟硬件。
每个容器都是相互隔离的,每个容器都有属于自己的文件系统,互不影响。
DevOps (Dev:开发,Ops:运维)
容器化带来的好处:
Docker的基本组成图如下:
Client:客户端
DOCKER_HOST:docker的主机(服务器)
Registry: 远程仓库
基本组成
镜像(image ):
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像==> run ==> tomcatOI容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的).
开发人员 打jar包带上环境(这里的环境称为镜像)
容器(container ):
Docker用容器技术,独立运行Y或者一个组应用,通过镜像来创建的。启动,停止,删除,基本命令!目前就可以把这个容器理解为就是一个简易的linux系统
镜像启动后出现容器
(镜像相当于类,容器相当于实例。一个镜像可以创建多个容器)
仓库(repository ):
仓库就是存放镜像的地方!仓库分为公有仓库和私有仓库!Docker Hub (默认是国外的)
在 CentOS | 上安装 Docker 引擎Docker 文档
环境准备
Linux CentOS7
1、查看系统的内核:uname -r
系统内核版本为3.10.0
[root@192 ~]# uname -r
3.10.0-1160.el7.x86_64
2、查看系统配置cat /etc/os-release
[root@192 ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
卸载旧版本
旧版本的 Docker 被称为 或 .如果已安装这些项,请将其以及关联的依赖项一起卸载。
[root@192 ~]# sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
Docker的安装步骤
1、下载需要的安装包
yum install -y yum-utils
2、设置阿里云的Docker镜像仓库
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3、更新yum软件包索引
yum makecache fast
4、安装docker相关的配置
docker-ce 是社区版,docker-ee 企业版
yum install docker-ce docker-ce-cli containerd.io
出现了completed(或 完毕!)即安装成功。
5、启动Docker
# 启动Docker
systemctl start docker
# 查看当前版本号,是否启动成功
docker version
# 设置开机自启动
systemctl enable docker
1、下载hello-world镜像进行测试
docker run hello-world
[root@192 ~]# clear
[root@192 ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally //本地没在到 hello-world 镜像
latest: Pulling from library/hello-world // pull 远程拉取 hello-world 镜像
2db29710123e: Pull complete // pull完成
Digest: sha256:507ecde44b8eb741278274653120c2bf793b174c06ff4eaa672b713b3263477b
Status: Downloaded newer image for hello-world:latest
Hello from Docker! //运行成功
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
2、查看下载的hello-world镜像
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 4 months ago 13.3kB //hello-world镜像
Docker的卸载
1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
2、删除资源 ./var/lib/docker
是docker的默认工作路径
rm -rf /var/lib/docker
本地机器无法使用
1、进入阿里云官网,搜索容器镜像服务
2、同时执行官方的命令
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://2y5oty1p.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docke
启动一个容器,docker run
的运行流程如下图:
Docker是一个Client-Server(客户端-服务器)结构的系统,Docker的守护进程运行在主机上,通过Socker从客户端访问!Docker Server(服务器)接收到Docker-Client(客户端)的指令,就会执行这个指令!
Docker为什么比VMWare(虚拟机)快?
1、Docker比虚拟机更少的抽象层
2、docker利用宿主机的内核,而VM需要的是Guest OS(虚拟机操作系统)
Docker新建一个容器的时候,不需要像虚拟机一样重新加载一个操作系统内核,直接利用宿主机的操作系统,而虚拟机是需要加载Guest OS(虚拟机操作系统)。Docker和VM的对比如下:
命令的帮助文档地址:https://docs.docker.com/engine/reference/commandline/docker/
[root@192 ~]# docker --help
Usage: docker [OPTIONS] COMMAND
// docker [选项] 命令
A self-sufficient runtime for containers //翻译:容器的自给自足运行时
Options:【选项】
--config string //客户端配置文件的位置 (default "/root/.docker")
-c, --context string //用于连接到守护进程的上下文的名称(覆盖DOCKER_HOST env变量和默认上下文设置 "docker context use")
-D, --debug //启用调试模式
-H, --host list //守护进程 socket(s) 连接
-l, --log-level string //设置日志级别 ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls //使用 TLS; 隐含 --tlsverify
--tlscacert string //仅由此CA签名的信任证书(default "/root/.docker/ca.pem")
--tlscert string //TLS证书文件路径 (default "/root/.docker/cert.pem")
--tlskey string //TLS密钥文件的路径 (default "/root/.docker/key.pem")
--tlsverify //使用TLS并验证远端
-v, --version //打印版本信息并退出
Management Commands:【管理命令】
app* Docker App (Docker Inc., v0.9.1-beta3)
builder Manage(管理) builds
buildx* Docker Buildx (Docker Inc., v0.7.1-docker)
config Manage Docker configs
container Manage containers //containers:容器
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists //管理Docker镜像清单和清单列表
network Manage networks
node Manage Swarm nodes //群节点
plugin Manage plugins //插件
scan* Docker Scan (Docker Inc., v0.12.0) //Scan:扫描
secret Manage Docker secrets //密码
service Manage services
stack Manage Docker stacks
swarm Manage Swarm //群
system Manage Docker
trust Manage trust on Docker images // trust:信任
volume Manage volumes //卷
Commands:【命令】
attach //将本地标准输入、输出和错误流附加到运行的容器 attach:附加
build //从Dockerfile构建一个映像
commit //根据容器的更改创建一个新镜像
cp //在容器和本地文件系统之间复制文件/文件夹
create //创建一个新容器
diff //检查容器文件系统中文件或目录的更改
events //从服务器获取实时事件 events:事件
exec //在运行的容器中运行命令 exec:执行
export //将容器的文件系统导出为tar存档文件 export:导出
history //显示一个镜像的历史
images //镜像的列表
import //从tarball文件中导入内容以创建文件系统映像
info //显示整个系统的信息
inspect //返回Docker对象的底层信息 inspect:检查
kill //杀死一个或多个正在运行的容器
load //从tar存档文件或STDIN加载镜像
login //登录到Docker注册表
logout //从Docker注册表注销
logs //获取容器的日志
pause //暂停一个或多个容器中的所有进程 pause:暂停
port //列出容器的端口映射或特定映射
ps //容器的列表
pull //从仓库(registry)中拉取镜像或存储库
push //将镜像或存储库推送到仓库(registry)
rename //重命名一个容器
restart //重新启动一个或多个容器
rm //移除一个或多个容器
rmi //移除一个或多个镜像
run //在新容器中运行命令
save //将一个或多个镜像保存到tar存档文件(默认情况下流到STDOUT)
search //在Docker Hub搜索镜像
start //启动一个或多个停止的容器
stats //显示容器资源使用统计的实时流
stop //停止一个或多个正在运行的容器
tag //创建引用SOURCE_IMAGE的标记TARGET_IMAGE
top //显示容器的运行进程
unpause //取消暂停一个或多个容器中的所有进程 unpause:不暂停
update //更新一个或多个容器的配置
version //查看Docker版本信息
wait //阻塞直到一个或多个容器停止,然后打印它们的退出代码
Run 'docker COMMAND --help' for more information on a command.
docker version #查看docker的版本信息
docker info #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令(可查看可选的参数)
docker COMMAND --help
docker --help #列出所有命令
拉取(下载)一个镜像
//docker pull 镜像[:tag] tag:版本(版本默认最新)
docker pull mysql
docker pull mysql:5.7 //指定版本
[root@192 ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
# == 分层下载,docker iamge的核心联合文件系统 ==
6552179c3509: Pull complete
d69aa66e4482: Pull complete
3b19465b002b: Pull complete
#...
Digest: sha256:92d27b8222bbcf53bc42c70ca7cd1010d6c0527efc61f14980ce77c50932bef4 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址
# 下载成功
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest d1dc36cf8d9e 3 days ago 519MB
hello-world latest feb5d9fea6a5 4 months ago 13.3kB
#等价于
docker pull mysql 等价于 docker pull docker.io/library/mysqlzlatest
分层下载,比如mysql5.7 与 mysql 8.0 有层一致就不用重新下载
docker images
查看本地主机的所有镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker images
[镜像的仓库源 镜像的标签 镜像的id 镜像的创建时间 镜像的大小]
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
# 可选参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id
docker search
搜索镜像
[root@192 ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12043 [OK]
mariadb MariaDB Server is a high performing open sou… 4613 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 901 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 439 [OK]
//...
// STARS:收藏数
查看其可选参数
[root@192 ~]# docker search --help
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
-f, --filter filter //根据所提供的条件过滤输出
--format string //使用Go模板的漂亮打印搜索
--limit int //搜索结果的最大数目(默认25个)
--no-trunc //不截断输出
搜索收藏数大于3000的镜像
// STARS:收藏数
[root@192 ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12043 [OK]
mariadb MariaDB Server is a high performing open sou… 4613 [OK]
在仓库搜索
https://hub.docker.com/search?q=mysql&type=image
删除镜像
docker rmi -f 【镜像id】
[root@192 ~]# clear
[root@192 ~]# docker rmi -f feb5d9fea6a5
Untagged: hello-world:latest
Untagged: hello-world@sha256:507ecde44b8eb741278274653120c2bf793b174c06ff4eaa672b713b3263477b
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
docker rmi -f 【镜像id】 【镜像id】 【镜像id】 ...
docker rmi -f $(docker images)
镜像启动后出现容器
(镜像相当于类,容器相当于实例。一个镜像可以创建多个容器)
(镜像相当于你安装系统时下载的镜像文件,而容器呢就相当于你安装好的系统)
1、先拉取一个centos镜像
docker pull centos
[root@192 ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
运行容器
run是新建一个容器(直接使用容器会自动退出),start是启动一个已经存在的容器
//image:镜像名字或id
docker run [可选参数] image
//参数说明
--name="名字" //指定容器名字
-d //后台方式运行 若没有提供服务则自动退出(停止)
-it //使用交互方式运行,进入容器查看内容
-p //指定容器的端口(小写的P)
-p ip:主机端口:容器端口 //配置主机端口映射到容器端口(小写的P)
-p 主机端口:容器端口
-p 容器端口
-P //随机指定端口(大写的P)
[root@192 ~]# docker start --help
// CONTAINER:容器id
Usage: docker start [OPTIONS] CONTAINER:容器id [CONTAINER...]
//启动一个或多个停止的容器
Options:
-a, --attach //附加STDOUT/STDERR和前向信号
--detach-keys string //覆盖用于分离容器的键序列
-i, --interactive //将容器的STDIN
进入容器
docker run -it centos /bin/bash
[root@192 ~]# docker run -it centos /bin/bash
[root@b8f211692996 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
退出容器
exit
# exit 停止并退出容器(后台方式运行则仅退出)
# Ctrl+P+Q 不停止容器退出
[root@b8f211692996 /]# exit
exit
列出容器
docker ps // 列出当前正在运行的容器
docker ps -a // 列出所有容器的运行记录
docker ps -n=? // 显示最近创建的n个容器
docker ps -q // 只显示容器的编号
[root@192 ~]# docker ps #列出当前正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8f211692996 centos "/bin/bash" 14 minutes ago Up 14 minutes zealous_lichterman
[root@192 ~]# docker ps -a # 列出所有容器的运行记录
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0f009b5ce7d7 centos "/bin/bash" 3 minutes ago Exited (0) About a minute ago cool_lovelace
b8f211692996 centos "/bin/bash" 14 minutes ago Up 14 minutes zealous_lichterman
9d6d432cfc32 feb5d9fea6a5 "/hello" 19 hours ago Exited (0) 19 hours ago wizardly_booth
53ef5a5247a6 feb5d9fea6a5 "/hello" 19 hours ago Exited (0) 19 hours ago eloquent_chatterjee
停止容器
[root@192 ~]# docker stop --help
// CONTAINER:容器(但要用容器id才行)
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
//翻译:停止一个或多个正在运行的容器
Stop one or more running containers
Options:
-t, --time int //在杀死它之前等待几秒钟 (default 10)
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb679ca2e254 centos "/bin/bash" 4 minutes ago Up 4 minutes blissful_robinson
b8f211692996 centos "/bin/bash" 26 minutes ago Up 26 minutes zealous_lichterman
[root@192 ~]# docker stop centos
Error response from daemon: No such container: centos
[root@192 ~]# docker stop eb679ca2e254
eb679ca2e254
[root@192 ~]# docker stop b8f211692996
b8f211692996
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
删除容器
docker rm 容器id # 删除指定的容器,不能删除正在运行的容器
docker rm -f 容器id # 强制删除,包括正在运行的容器
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -a -q|xargs docker rm # 删除所有的容器
启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前运行的容器
docker kill 容器id #强制停止当前容器
日志的查看
[root@192 ~]# docker logs --help
Usage: docker logs [OPTIONS] CONTAINER
//获取容器的日志
Options:
--details //显示提供给日志的额外细节
-f, --follow //跟踪日志输出
--since string //显示自定义时间戳以来的日志 (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
-n, --tail string 、、从日志的末尾显示的行数(default "all")
-t, --timestamps //显示时间戳
--until string //在时间戳之前显示日志 (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
//常用:
docker logs -tf 【容器id】
docker logs --tail number 【容器id】 //num为要显示的日志条数
#docker容器后台运行,必须要有一个前台的进程,否则会自动停止
#编写shell脚本循环执行,使得centos容器保持运行状态
[root@192 ~]# docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
2b8ed9e4dcb655547b3c2aa28cd849179190ec03ecca2aabf9c7a44155b13097
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b8ed9e4dcb6 centos "/bin/sh -c 'while t…" 3 seconds ago Up 2 seconds beautiful_elion
[root@192 ~]# docker logs -tf --tail 10 2b8ed9e4dcb6
2022-01-31T02:32:36.215664841Z hi
2022-01-31T02:32:41.224798220Z hi
2022-01-31T02:32:46.227706348Z hi
2022-01-31T02:32:51.243402617Z hi
2022-01-31T02:32:56.257314943Z hi
2022-01-31T02:33:01.284139739Z hi
2022-01-31T02:33:06.294600809Z hi
# Ctrl + Shift + c 退出
查看容器中进程信息
docker top 容器id
[root@192 ~]# docker top 2b8ed9e4dcb6
UID PID PPID C STIME TTY TIME CMD
root 11156 11135 0 11:31 ? 00:00:00 /bin/sh -c while true;do echo hi;sleep 5;done
root 11886 11156 0 11:43 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5
查看容器的元数据
docker inspect 容器id
[root@192 ~]# docker inspect 2b8ed9e4dcb6 # 显示的id是 真实id 的 缩写
[
{
"Id": "2b8ed9e4dcb655547b3c2aa28cd849179190ec03ecca2aabf9c7a44155b13097",# 真实id
"Created": "2022-01-31T02:32:35.769096414Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo hi;sleep 5;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
进入当前正在运行的容器
因为通常我们的容器都是使用后台方式来运行的,有时需要进入容器修改配置
// 方式一
docker exec -it 【容器id】 /bin/bash
// 方式二
docker attach 【容器id】
方式一:进入容器后开启一个新的终端,可以在里面操作 (常用)
[root@192 ~]# docker exec -it 2b8ed9e4dcb6 /bin/bash
[root@2b8ed9e4dcb6 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 查看进程
[root@48c706c3a876 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:38 ? 00:00:00 /bin/sh -c while true;do echo hi;sleep 5;done
root 12 0 0 03:38 pts/0 00:00:00 /bin/bash
root 28 1 0 03:38 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5
root 29 12 0 03:38 pts/0 00:00:00 ps -ef
方式二:进入容器正在执行的终端,不会启动新的进程
[root@192 ~]# docker attach 2b8ed9e4dcb6
hi
hi
hi
//...
拷贝操作
(还可以使用 -v 卷技术)
拷贝操作的命令如下:
//将容器的文件拷贝到主机中
docker cp 容器id:容器内路径 目的主机路径
//docker cp 7b605b457f23:/home/Hello.txt hello.txt
//将宿主机的文件拷贝到容器中
docker cp 目的主机路径 容器id:容器内路径
[root@192 ~]# docker run -it centos /bin/bash
[root@7b605b457f23 /]# cd home/
[root@7b605b457f23 home]# touch Hello.txt
[root@7b605b457f23 home]# ls
Hello.txt
1、在容器中新建文件
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker exec -it c703b5b1911f /bin/bash
[root@c703b5b1911f /]# cd home
[root@c703b5b1911f home]# ls
#touch 新建文件
[root@c703b5b1911f home]# touch test.java
[root@c703b5b1911f home]# ls
test.java
[root@c703b5b1911f home]# exit
exit
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c703b5b1911f centos "/bin/sh -c 'while t…" 35 minutes ago Up 35 minutes pedantic_banach
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker cp c703b5b1911f:/home/test.java /home
[root@iZwz99sm8v95sckz8bd2c4Z ~]# ls /home
hai pan test.java
[root@7b605b457f23 home]# exit
exit
2.copy文件
[root@192 ~]# cd 桌面
[root@192 桌面]# ls
Kuang
[root@192 桌面]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@192 桌面]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b605b457f23 centos "/bin/bash" 3 minutes ago Exited (0) 2 minutes ago tender_burnell
# ...
[root@192 桌面]# docker cp 7b605b457f23:/home/Hello.txt hello.txt
[root@192 桌面]# ls
hello.txt Kuang # 成功
常用命令小节
(Nginx:是一个高性能的HTTP和反向代理web服务器)
1、搜索nginx
https://hub.docker.com/_/nginx
[root@192 ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16232 [OK]
//...
2、拉取nginx
[root@192 ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
5eb5b503b376: Pull complete
1ae07ab881bd: Pull complete
78091884b7be: Pull complete
091c283c6a66: Pull complete
55de5851019b: Pull complete
b559bad762be: Pull complete
Digest: sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@192 ~]# docker images # 下载成功
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest c316d5a335a5 4 days ago 142MB
3、启动nginx镜像
[root@192 ~]# docker run -d --name nginx01 -p 8801:80 nginx
b93af0c28d2baca7b03dc34eaf6d0b8778abdb989e091d9461351a48b12fb706
[root@192 ~]# docker ps #运行成功
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b93af0c28d2b nginx "/docker-entrypoint.…" 13 seconds ago Up 11 seconds 0.0.0.0:8801->80/tcp, :::8801->80/tcp nginx01
-p 8801:80
通过端口映射将 主机的8801端口 与 容器的80端口 连通,从而暴露 容器的80端口
4、测试连接nginx
[root@192 ~]# curl localhost:8801
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1> # 连接成功
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
5、进入nginx容器
[root@192 ~]# docker exec -it nginx01 /bin/bash
root@b93af0c28d2b:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
1、搜索tomcat
[root@192 ~]# docker search tomcat
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementati… 3248 [OK]
2、拉取tomcat
docker pull tomcat:9.0
[root@192 ~]# docker pull tomcat:9.0
9.0: Pulling from library/tomcat
0c6b8ff8c37e: Pull complete
# ...
Digest: sha256:c1cbd0fcc6d937c79d9f84ad6747b8ace4846a7ddf44f9344695c61f7443fa02
Status: Downloaded newer image for tomcat:9.0
docker.io/library/tomcat:9.0
3、启动Tomcat
docker run -d -p 8002:8080 --name tomcat01 tomcat
[root@192 ~]# docker run -d -p 8002:8080 --name tomcat01 tomcat
Unable to find image 'tomcat:latest' locally # 没有发现最新版
latest: Pulling from library/tomcat
0c6b8ff8c37e: Already exists # 下载Tomcat9.0时已下载
# ...
bc5c573a9ab7: Pull complete # 补充下载
f9f34f3a3d27: Pull complete
Digest: sha256:28ef9f9a08f812de2f7f1de9076f39c911e5f92615ea168693964fbc2247701c
Status: Downloaded newer image for tomcat:latest
b55631abdbffbe3bf156050846e71f03834f8984bf4fe96952ddda46e209967b #启动成功,容器id
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b55631abdbff tomcat "catalina.sh run" 33 seconds ago Up 30 seconds 0.0.0.0:8002->8080/tcp, :::8002->8080/tcp tomcat01
5、进入tomcat容器
docker exec -it nginx01 /bin/bash
[root@192 ~]# docker exec -it tomcat01 /bin/bash
root@b55631abdbff:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
(容器中的命令是少了,阿里云镜像默认下载的是最小的镜像,保证最小的运行环境。)
6、部署网站
在webapps.dist文件在个tomcat网站代码
root@b55631abdbff:/usr/local/tomcat# cd webapps.dist/
root@b55631abdbff:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@b55631abdbff:/usr/local/tomcat/webapps.dist# cd examples/
root@b55631abdbff:/usr/local/tomcat/webapps.dist/examples# ls
META-INF WEB-INF index.html jsp servlets websocket
root@b55631abdbff:/usr/local/tomcat/webapps.dist/examples# cat index.html
<!--
# ...
-->
<!DOCTYPE HTML><html lang="en"><head>
<meta charset="UTF-8">
<title>Apache Tomcat Examples</title>
</head>
<body>
<p>
<h3>Apache Tomcat Examples</H3>
<p></p>
<ul>
<li><a href="servlets">Servlets examples</a></li>
<li><a href="jsp">JSP Examples</a></li>
<li><a href="websocket/index.xhtml">WebSocket Examples</a></li>
</ul>
</body></html>
将webapps.dist的网站代码copy到webapps中让服务器运行
root@b55631abdbff:/usr/local/tomcat# cp -r webapps.dist/* webapps
思考问题
每次部署项目都要进入容器是不是太麻烦,可以通过修改外部影响容器内部就好了。
部署难点
ElasticSearch是什么: ElasticSearch从入门到精通,史上最全(持续更新,未完待续,每天一点点)_Null的博客-CSDN博客
ElasticSearch是 智能搜索,分布式的搜索引擎
ElasticSearch暴露的端口多、十分耗内存、数据一定要放安全目录
ElasticSearch是一个日志切割管理的工具
部署 ElasticSearch
正常安装ElasticSearch后太消耗内存,导致Linux太卡了,需要添加 -e ES_JAVA_OPTS="-Xms128m -Xmx512m"
配置ElasticSearch的虚拟机占用的内存大小。
1、安装并启动
docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx512m" elasticsearch:7.6.2
[root@192 ~]# docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx512m" elasticsearch:7.6.2
Unable to find image 'elasticsearch:7.6.2' locally
7.6.2: Pulling from library/elasticsearch
ab5ef0e58194: Pull complete
c4d1ca5c8a25: Pull complete
941a3cc8e7b8: Pull complete
43ec483d9618: Pull complete
c486fd200684: Pull complete
1b960df074b2: Pull complete
1719d48d6823: Pull complete
Digest: sha256:1b09dbd93085a1e7bca34830e77d2981521a7210e11f11eda997add1c12711fa
Status: Downloaded newer image for elasticsearch:7.6.2
c097654fbab08d26f803e150b54c471336a9ba24283595ba64f33d87aba33c62
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c097654fbab0 elasticsearch:7.6.2 "/usr/local/bin/dock…" 2 minutes ago Up 2 minutes 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch01
2、测试连接ElasticSearch
[root@192 ~]# curl localhost:9200
{
"name" : "c097654fbab0",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "HtBpQlrcR_mI-Suj8qzW8w",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
3、查看资源占用情况
docker stats
[root@192 ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c097654fbab0 elasticsearch01 0.25% 420MiB / 2.406GiB 17.05% 3.71kB / 2.75kB 0B / 1.74MB 44
Kibana
Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作。您可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作。您可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。
Portaniner是Docker的图形化管理工具,类似的工具还有Rancher(CI/CD再用)
(Portaniner平时比较少用)
1、下载运行Portaniner镜像并运行,设置本机映射端口为8088
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
[root@192 ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
a2300fd28637: Pull complete
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
b3b421cc14a11d7a4119eb8b3144c8f4796d7ad078ff9e1ecbdf8044b3e1a4cd
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b3b421cc14a1 portainer/portainer "/portainer" 29 seconds ago Up 27 seconds 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp flamboyant_cray
2、windows(外网)访问成功
(1) 第一次登录设置admin用户的密码 (测试中为了好记可以设置成12345678)
(2) 选择Local(本地)
# 安装时要加上
-v "/var/run/docker.sock:/var/run/docker.sock"
(3) 主页
(4) 查看镜像列表
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。
所以应用直接打包镜像,就可以用于运行
获得镜像的途径:
- 自己制作镜像DockerFile
- 远程仓库下载
- 别人copy给你
UnionFS (联合文件系统)
Docker的镜像实际上由一层一层的文件系统组成(下载镜像时分层下载可印证),这种层级的文件系统是UnionFS联合文件系统。
UnionFS (联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文研系统的修改
作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到外文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
作用:比如tomcat下载了centos,则mysql就不用下载了。相同层可复用
思考:为什么Docke也像要采用这种分层的结构呢?
最大的好处,莫过于是资源共享了 !比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只高要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享.
查看镜像分层的方式可以通过docker image inspect
命令!
docker image inspect redis
[root@192 ~]# docker image inspect redis
[
{
"Id": "sha256:f1b6973564e91aecb808142499829a15798fdc783a30de902bb0c4133fee19ad",
"RepoTags": [
"redis:latest"
],
# ...
"RootFS": {
"Type": "layers",
"Layers": [ # 这里指示了分层信息
"sha256:7d0ebbe3f5d26c1b5ec4d5dbb6fe3205d7061f9735080b0162d550530328abd6",
"sha256:92b6c42121d80f330a80c20afa928e19c31ab3a5fe7cf9c91517fa8cc468b33f",
"sha256:65845b69eb5c3291dd610ddf2f61f524ab206f9754900d9f3512fcbc2d38604f",
"sha256:7048818d16571a765e2b0cf82c20d627abebccec73ac3d7b7973501000e6e05d",
"sha256:c61d5cbf862134aad34822e96d9efc009cca19ad604419cb3f8cf8857eb18372",
"sha256:ff503dae4eb68eb7a71095e5b1b1b123f42d37e923222038b64fba5a80b13307"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层.
举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,
就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子).
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常里要.下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件.
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux上可用的存储引擎有AUFS、Overlay2. Device hopper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的
文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[ 1] 0
下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层!
使用docker commit
命令提交容器成为一个新的版本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
由于默认的Tomcat镜像的webapps文件夹中没有任何内容,需要从webapps.dist中拷贝文件到webapps文件夹。下面自行制作镜像:就是从webapps.dist中拷贝文件到webapps文件夹下,并提交该镜像作为一个新的镜像。使得该镜像默认的webapps文件夹下就有文件。具体步骤如下:
1、启动Tomcat
// 启动Tomcat 一定要配置端口映射 `-p 8080:8080`
docker run -it -p 8080:8080 tomcat
//开多一个终端
// 进入容器
docker exec -it d55df6cdafe8 /bin/bash
2、制作(修改)镜像,拷贝cp -r webapps.dist/* webapps
root@d55df6cdafe8:/usr/local/tomcat# cd webapps
root@d55df6cdafe8:/usr/local/tomcat/webapps# ls
root@d55df6cdafe8:/usr/local/tomcat/webapps# cd ..
root@d55df6cdafe8:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@d55df6cdafe8:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@d55df6cdafe8:/usr/local/tomcat# cd webapps
root@d55df6cdafe8:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
3、windows访问
4、提交自己镜像,提交到本地(之后再发布到远程仓库)
//docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -m="add webapps app" -a="一个平凡de人" 6df1e2c4a350 tomcat02:1.0
[root@192 ~]# docker commit -m="add webapps app" -a="一个平凡de人" 6df1e2c4a350 tomcat02:1.0
sha256:e699f08da20e848d7a9bd7c8953b63500abe1ea6a6605838dc9f97876857c229
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 1.0 e699f08da20e 35 seconds ago 684MB # 自己镜像
tomcat latest 413407dddb5e 4 days ago 680MB
redis latest f1b6973564e9 5 days ago 113MB
portainer/portainer latest 580c0e4e98b0 10 months ago 79.1MB
elasticsearch 7.6.2 f29a1ee41030 22 months ago 791MB
5、测试
(1)启动
docker run -it -p 8080:8080 tomcat02:1.0
(2)windows访问,测试成功
小节
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们以前学习VM时候,快照保存虚拟机状态,之后可状态回滚!
docker的理念回顾
将应用和环境打包成一个镜像
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
使用卷技术的原因:容器的持久化和同步操作!容器间也是可以数据共享的!
挂载后 主机目录和容器目录共享一个目录资源,容器目录也可以理解为是主机目录的快捷方式
方式一 :直接使用命令挂载 -v
//-v, --volume list 绑定挂载卷
docker run -it -v 主机目录:容器目录 -p 主机端口:容器内端口
//通过 查看挂载
docker inspect 容器id
1、挂载并进入命令行/bin/bash
docker run -it -v /home/ceshi:/home centos /bin/bash
[root@192 ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@a40aea147d6d /]# cd /home
[root@a40aea147d6d home]# ls # 空
[root@192 ~]# cd /home
[root@192 home]# ls
ceshi # 找到ceshi目录
2、查看挂载
docker inspect 【容器id】
[root@192 home]# docker inspect a40aea147d6d
# ...
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", # 挂载成功 主机目录
"Destination": "/home", # 挂载成功 容器目录
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
# ...
3、测试挂载
挂载后 主机目录和容器目录共享一个目录资源,容器目录也可以理解为是主机目录的快捷方式
[root@a40aea147d6d home]# touch test.txt # 创建文件
[root@a40aea147d6d home]# ls
test.txt
[root@192 home]# ls
ceshi
[root@192 home]# cd ceshi/
[root@192 ceshi]# ls
test.txt # 挂载成功,也test.txt文件
# 向文件写入数据
[root@192 ceshi]# echo "This is test data" > test.txt
[root@192 ceshi]# cat test.txt
This is test data
# 容器内目录也有数据
[root@a40aea147d6d home]# cat test.txt
This is test data
就算容器关闭,数据依旧一致。
1、获取mysql镜像
docker pull mysql
2、运行容器,挂载倆个数据目录,配置密码-e MYSQL_ROOT_PASSWORD=password
# -e 环境配置,配置mysql密码
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
[root@192 ~]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
05574ce7407c7745ee28951f5ccc032062b83b9d9486ef6062a1d321df2ad0c8
# 启动成功之后,我们在本地使用sqlyog来测试一下
# sqlyog-连接到服务器的3306--和容器内的3306映射
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
3、测试连接,在windows上用数据库连接工具测试连接mysql容器·
4、文件目录映射成功
[root@192 mysql]# cd /home/mysql/
[root@192 mysql]# ls
conf data
[root@192 mysql]# cd data
[root@192 data]# ls
auto.cnf ca-key.pem #ib_16384_0.dblwr ib_logfile0 mysql public_key.pem undo_001
binlog.000001 ca.pem #ib_16384_1.dblwr ib_logfile1 mysql.ibd server-cert.pem undo_002
binlog.000002 client-cert.pem ib_buffer_pool ibtmp1 performance_schema server-key.pem
binlog.index client-key.pem ibdata1 #innodb_temp private_key.pem sys
5、linux中,一个数据库对应一个目录,一个数据表对应一个文件
(1)创建数据库
(2)成功看到test目录
(3)创建数据表
(4)成功看到文件
容器数据持久化
假设我们将容器删除,发现我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能。
卷指容器被挂载的主机目录
匿名挂载
1、匿名挂载就是不指定主机目录进行挂载(没有给卷(主机目录)起名就是匿名)
# -v 容器内路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx
2、查看所有的volume(卷)的情况
docker volume ls
[root@192 ~]# docker volume ls
DRIVER VOLUME NAME
local 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c #这些字符串就代表匿名卷(目录),是匿名挂载
local 8ecbc00746d9bea6a8095e65ead44e30b5cbf49f7409bc58aff9fab4b10cf0f4
local d745315f9e2d743c1a83edc5312809efba67693b8a01a27eb0a49a4ff572a450
3、指定卷来查看挂载
docker volume inspect 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c
[root@192 ~]# docker volume inspect 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c
[
{
"CreatedAt": "2022-02-01T21:04:59+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c/_data",# 挂载的目录
"Name": "7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c",
"Options": null,
"Scope": "local"
}
]
具名挂载
1、具名挂载就是指定了主机目录进行挂载(有给卷(主机目录)起名就是具名(有具体的名))
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
2、查看所有的volume(卷)的情况
[root@192 home]# docker volume ls
DRIVER VOLUME NAME
local 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c
local 8ecbc00746d9bea6a8095e65ead44e30b5cbf49f7409bc58aff9fab4b10cf0f4
local d745315f9e2d743c1a83edc5312809efba67693b8a01a27eb0a49a4ff572a450
local juming-nginx #有具体的名,具名挂载
3、指定卷来查看挂载
[root@192 home]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-02-01T21:16:26+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", # 挂载的目录
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定绝对路径的目录的情况下都是在/var/lib/docker/volumes/xxxx/_data
下的,
如果指定了目录,docker volume ls
是查看不到的。
小节
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
拓展
通过 -v 容器内路径: ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
什么是Dockerfile
Dockerfile 是用来构建docker镜像的构建文件,是一段命令脚本。
创建Dockerfile
1、创建docker的测试目录
[root@192 _data]# cd /home
[root@192 home]# mkdir docker-test-volume
2、创建Dockerfile脚本文件,通过这个脚本可以生成镜像,
Dockerfile脚本文件内容分析:
# 文件中的内容 指令(大写) 参数
#镜像是一层一层的,这里的每个命令,就是镜像的一层!
FROM centos # 指定镜像
VOLUME ["volume01","volume02"] # 挂载目录
CMD echo "----end----" # CMD 执行命令行命令
CMD /bin/bash
[root@192 docker-test-volume]# vim dockerfile01
[root@192 docker-test-volume]# cat dockerfile01
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
3、执行Dockerfile脚本文件,构建镜像
docker build -f /home/docker-test-volume dockerfile01 -t /kuangshen/centos .
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kuangshen/centos latest 6b3e9b445d81 3 hours ago 231MB #构建成功
# ...
4、启动镜像,查看容器
docker run -it /kuangshen/centos /bin/bash
[root@b68f2c5c965b /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
# 找到挂载的目录volume01、volume02
容器挂载数据卷,实现容器间的数据同步和资源共享!
1、启动父容器docker01
docker run -it --name docker01 kuangshen/centos
2、启动容器docker02并挂载到父容器docker01的共享卷,命令--volumes-from 容器列表
docker run -it --name docker02 --volumes-from docker01 kuangshen/centos
3、查看容器运行
[root@192 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa68f1afa235 kuangshen/centos "/bin/sh -c /bin/bash" 11 seconds ago Up 10 seconds docker02
eb991bf17656 kuangshen/centos "/bin/sh -c /bin/bash" 2 minutes ago Up 2 minutes docker01
4、在父容器docker01的共享卷中创建文件,看docker02共享卷的变化
[root@eb991bf17656 /]# cd volume01
[root@eb991bf17656 volume01]# touch docker.txt
[root@fa68f1afa235 /]# cd volume01
[root@fa68f1afa235 volume01]# ls
docker.txt
5、再加个docker03试试,也有docker01创建的文件
docker run -it --name docker03 --volumes-from docker01 kuangshen/centos
[root@e4ad9cb37d01 /]# cd volume01
[root@e4ad9cb37d01 volume01]# ls
docker.txt
6、小结
docker03创建的文件docker01、docker02也同步共享。
删除docker01,docker02和docker03依旧保持数据同步和资源共享。
容器挂载后双向资源绑定,双向拷贝。
1、启动mysql01,绑定端口3306,配置密码-e MYSQL_ROOT_PASSWORD=password
,挂载卷-v
docker run -it --name mysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /etc/mysql/conf.d -v /var/lib/mysql mysql
2、启动mysql02(绑定端口3307)、mysql03(绑定端口3308)
# mysql02
docker run -it --name mysql02 --volumes-from mysql01 -p 3100:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /etc/mysql/conf.d -v /var/lib/mysql mysql
# mysql03
docker run -it --name mysql03 --volumes-from mysql01 -p 330:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /etc/mysql/conf.d -v /var/lib/mysql mysql
3、连接数据库测试
结论
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
1、 编写一个dockerfile文件
2、 docker build 构建称为一个镜像
3、 docker run运行镜像
4、 docker push发布镜像(DockerHub 、阿里云仓库)
官方的镜像
官方仓库搜索:https://hub.docker.com/_/centos
点击版本跳转到Github,看到dockerfile文件:
docker 99%的镜像都是从FROM scratch(基础镜像)开始
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,那我们也可以!
DockerFile脚本文件语法
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序
3、#表示注释
4、每一个指令都会创建提交一个新的镜像曾,并提交!
Dockerfile
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成企业交付的标准,必须要掌握!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。
Docker容器:容器就是镜像运行起来提供服务。
DockerFile的指令
指令 | 解释 | 小写 |
---|---|---|
FROM | 基础镜像,一切从这里开始构建 | from |
MAINTAINER | 镜像是谁写的, 姓名+邮箱(翻译:维护人员) | maintainer |
RUN | 镜像构建的时候需要运行的命令 | run |
ADD | 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录 | add |
WORKDIR | 镜像的工作目录 | workdir |
VOLUME | 挂载的目录 | volume |
EXPOSE | 保留端口配置(开放的端口) | expose |
CMD | 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。 | cmd |
ENTRYPOINT | 指定这个容器启动的时候要运行的命令,可以追加命令(入口点) | entrypoint |
ONBUILD | 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。 | onbuild |
COPY | 类似ADD,将我们文件拷贝到镜像中 | copy |
ENV | 构建的时候设置环境变量! | env |
创建一个自己的centos镜像
官方的centos许多命令都没有,所以我们创建一个自己的centos镜像
1、创建工作目录
[root@192 dockerfile]# pwd
/home/dockerfile
[root@192 dockerfile]# vim centos-dockerfile
2、编写Dockerfile文件 (文件名:centos-dockerfile)
FROM centos
MAINTAINER root<[email protected]>
ENV MYPATH /usr/local # 设置环境变量
WORKDIR $MYPATH # 镜像的工作目录,进入镜像的初始目录
# RUN: 镜像构建的时候需要运行的命令
RUN yum -y install vim # 新增 vim 工具
RUN yum -y install net-tools # 新增 网络 工具 有ifconfig命令
EXPOSE 80 # 开放的端口
CMD echo $MYPATH # CMD:容器启动的时候要运行的命令
CMD echo "-----end----"
CMD /bin/bash
FROM centos
MAINTAINER root<[email protected]>
ENV MYPATH /usr/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
3、通过这个文件构建镜像
# 命令 docker build -f 文件路径 -t 镜像名:[tag] .
docker build -f /home/dockerfile/centos-dockerfile -t mycentos:0.1 .
Step 5/10 : RUN yum -y install vim
---> Running in 64495d343335
CentOS Linux 8 - AppStream 68 B/s | 38 B 00:00
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
The command '/bin/sh -c yum -y install vim' returned a non-zero code: 1
因为没有vim这个rpm包。vim命令在vim-ehanced这个包内。
yum失败的可以在yum之前加一个更新软件源
systemctl stop firewalld.service # 停止防火墙
4、启动镜像
列出镜像的变更历史
docker history 镜像
[root@192 dockerfile]# docker history mysql
IMAGE CREATED CREATED BY SIZE COMMENT
d1dc36cf8d9e 6 days ago /bin/sh -c #(nop) CMD ["mysqld"] 0B
<missing> 6 days ago /bin/sh -c #(nop) EXPOSE 3306 33060 0B
<missing> 6 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B
<missing> 6 days ago /bin/sh -c ln -s usr/local/bin/docker-entryp… 34B
<missing> 6 days ago /bin/sh -c #(nop) COPY file:c112ec3a02a7b818… 13.2kB
<missing> 6 days ago /bin/sh -c #(nop) COPY dir:2e040acc386ebd23b… 1.12kB
<missing> 6 days ago /bin/sh -c #(nop) VOLUME [/var/lib/mysql] 0B
<missing> 6 days ago /bin/sh -c { echo mysql-community-server m… 384MB
<missing> 6 days ago /bin/sh -c echo 'deb http://repo.mysql.com/a… 55B
6 days ago /bin/sh -c #(nop) ENV MYSQL_VERSION=8.0.28-… 0B
6 days ago /bin/sh -c #(nop) ENV MYSQL_MAJOR=8.0 0B
6 days ago /bin/sh -c set -ex; key=' 859BE8D7C586F53843… 2.29kB
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 52.2MB
<missing> 6 days ago /bin/sh -c mkdir /docker-entrypoint-initdb.d 0B
<missing> 6 days ago /bin/sh -c set -eux; savedAptMark="$(apt-ma… 4.06MB
6 days ago /bin/sh -c #(nop) ENV GOSU_VERSION=1.14 0B
6 days ago /bin/sh -c apt-get update && apt-get install… 9.34MB
6 days ago /bin/sh -c groupadd -r mysql && useradd -r -… 329kB
7 days ago /bin/sh -c #(nop) CMD [" bash"] 0B
<missing> 7 days ago /bin/sh -c #(nop) ADD file:c51141702f568a28a… 69.3MB
使用我们平时拿到一个镜像,可以研究一下是什么做的
测试cmd
1、编写dockerfile文件
[root@192 dockerfile]# cat dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
2、 构建镜像
docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
[root@192 dockerfile]# docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
---> Running in 462edab225f4
Removing intermediate container 462edab225f4
---> 3a12f3d5b2a5
Successfully built 3a12f3d5b2a5
Successfully tagged cmd-test:0.1
3、运行镜像
[root@192 dockerfile]# docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
etc
# ..
# 列出了 容器内 根目录所有文件夹
4、想追加一个命令 -l 成为ls -al
docker run cmd-test:0.1 ls -al
[root@192 ~]# docker run cmd-test:0.1 ls -al
total 0
drwxr-xr-x. 1 root root 6 Feb 2 13:53 .
drwxr-xr-x. 1 root root 6 Feb 2 13:53 ..
-rwxr-xr-x. 1 root root 0 Feb 2 13:53 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Feb 2 13:53 dev
# ...
测试ENTRYPOINT
1、编写dockerfile文件
vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
2、构建镜像
docker build -f dockerfile-test-entrypoint -t entrypoint-test:0.1 .
[root@192 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
entrypoint-test 0.1 390f47c46bdd 9 seconds ago 231MB
3、想追加一个命令 -l
docker run entrypoint-test:0.1 -l
[root@192 dockerfile]# docker run entrypoint-test:0.1 -l
total 0
drwxr-xr-x. 1 root root 6 Feb 2 13:59 .
drwxr-xr-x. 1 root root 6 Feb 2 13:59 ..
-rwxr-xr-x. 1 root root 0 Feb 2 13:59 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
# ...
1、准备镜像文件
准备tomcat 和 jdk到当前目录,编写好README
Apache Tomcat® - Apache Tomcat 9 Software Downloads
[root@192 tomcat]# ls
apache-tomcat-9.0.58.tar.gz jdk-8u60-linux-x64.tar.gz
[root@192 tomcat]# pwd
/root/桌面/Kuang/tomcat
[root@192 tomcat]# ls
apache-tomcat-9.0.58.tar.gz Dockerfile jdk-8u60-linux-x64.tar.gz readme.txt
2、编写dokerfile,官方命名Dockerfile
,build 会自动寻找,就不用-f 指定了
FROM centos
MAINTAINER root<[email protected]>
COPY readme.txt /usr/local/readme.txt #复制文件
ADD jdk-8u60-linux-x64.tar.gz /usr/local/ #复制解压
ADD apache-tomcat-9.0.58.tar.gz /usr/local/
ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_60 #设置环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools/jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.58 #设置环境变量
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.58
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #设置环境变量 分隔符是:
EXPOSE 8080 #设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.58/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.58/bin/logs/catalina.out # 设置默认命令
FROM centos #
MAINTAINER cheng<[email protected]>
COPY README /usr/local/README #复制文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #复制解压
RUN yum -y install vim
ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_231 #设置环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #设置环境变量 分隔符是:
EXPOSE 8080 #设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out # 设置默认命令
3、构造镜像
docker build -t diytomcat .
构建失败
4、运行镜像
docker run -d -p 8080:8080 --name tomcat01 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
5、访问测试
6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
发现:项目部署成功,可以直接访问!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
1、登录远程仓库( https://hub.docker.com/)
2、终端登录
[root@192 ~]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
登录到Docker注册表。
如果没有指定服务器,则由守护进程定义默认值。
Options:
-p, --password string Password
--password-stdin 从stdin获取密码
-u, --username string Username
3、登录成功
docker login -u 【你的用户名】 -p 【你的密码】
[root@192 ~]# docker login -u 【你的用户名】 -p 【你的密码】
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
4、提交 push镜像
[root@192 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
cmd-test 0.1 3a12f3d5b2a5 18 hours ago 231MB
# ...
(1) 先打标签
# docker tag 镜像id 你的账户名/镜像仓库名:tag名
docker tag 3a12f3d5b2a5 dockerywl/cmd-test:0.1
(2) 再提交 push镜像
# docker push 作者/镜像:TAG(版本)
docker push dockerywl/cmd-test:0.1
[root@192 ~]# docker push dockerywl/cmd-test:0.1
The push refers to repository [docker.io/dockerywl/cmd-test]
74ddd0ec08fa: Pushing [================> ] 77.74MB/231.3MB
(3) push成功
发布到阿里云镜像服务上
看官网 很详细https://cr.console.aliyun.com/repository/
保存后拷贝的U盘交给别人使用
1、保存(压缩)成backup.tar
[root@192 ~]# docker save --help
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
将一个或多个镜像保存到tar存档文件(默认情况下流到STDOUT)
Options:
-o, --output string 写入一个文件,而不是STDOUT
docker save 镜像 -o 文件名
[root@192 ~]# docker save redis -o backup.tar
[root@192 ~]# ls
backup.tar # 成功
2、加载(解压)镜像压缩文件backup.tar
[root@192 ~]# docker load --help
Usage: docker load [OPTIONS]
从tar存档文件或STDIN加载镜像
Options:
-i, --input string 从tar存档文件读取,而不是STDIN
-q, --quiet 抑制负载输出
docker load -i backup.tar
[root@192 ~]# docker load -i backup.tar
92b6c42121d8: Loading layer [==================================================>] 338.4kB/338.4kB
65845b69eb5c: Loading layer [==================================================>] 4.274MB/4.274MB
7048818d1657: Loading layer [==================================================>] 27.8MB/27.8MB
c61d5cbf8621: Loading layer [==================================================>] 2.048kB/2.048kB
ff503dae4eb6: Loading layer [==================================================>] 3.584kB/3.584kB
Loaded image: redis:latest # 成功
tomcat 容器
Linux apt 命令 | 菜鸟教程 (runoob.com)
# 先执行
apt update
# 安装 ip 查看工具
apt install -y iproute2
# 安装 ping 命令工具
apt-get install inetutils-ping
# 安装 vim 命令工具
apt install vim
apt update && apt install -y iproute2 && apt-get install inetutils-ping
容器编排、集群部署
不推荐使用:Docker 0 不支持 ping 容器名
清空所有环境
# 删除所有镜像
docker rmi -f $(docker images)
# 删除所有的容器
docker rm -f $(docker ps -aq)
[root@192 ~]# ifconfig
# docker0地址 有路由器的功能。
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
# ...
# 本机地址
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.64.130 netmask 255.255.255.0 broadcast 192.168.64.255
# ...
# 本机回环地址
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
# ...
Linux主机 与 容器 互相ping通
1、新建容器
docker pull tomcat
docker run -it -d -P --name tomcat01 tomcat /bin/bash
2、进入为容器安装 ip 查看工具
docker attath 容器id
# 常用
apt update && apt install -y iproute2
3、查看容器内网ip
docker分配的容器内网ip : 172.17.0.2
root@138f304dfa38:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
# veth-pair技术 6 与 7 成对
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
4、可以ping通 (毕竟tomcat提供的服务外网都可以访问,肯定ping的通)
[root@192 ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.085 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.048/0.061/0.085/0.018 ms
5、进入为容器安装 ping 命令工具
apt-get install inetutils-ping
6、 容器 ping通 Linux主机
root@138f304dfa38:/usr/local/tomcat# ping 192.168.64.130
PING 192.168.64.130 (192.168.64.130): 56 data bytes
64 bytes from 192.168.64.130: icmp_seq=0 ttl=64 time=0.294 ms
64 bytes from 192.168.64.130: icmp_seq=1 ttl=64 time=0.125 ms
^C--- 192.168.64.130 ping statistics ---
7 packets transmitted, 7 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.125/0.181/0.294/0.056 ms
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术!
https://www.cnblogs.com/bakari/p/10613710.html
veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。
(成对:Linux 主机网卡 6,7成对,则容器网卡7,6成对)
Linux 主机 再次执行 ip addr
,多了个网卡
[root@192 ~]# ip addr
1: lo: # ...
2: ens33: # ...
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:a4:0b:89:6b brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
# ...
# 多了个网卡
7: veth568cc5e@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether de:55:c0:b4:58:42 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::dc55:c0ff:feb4:5842/64 scope link
valid_lft forever preferred_lft forever
2、再启动一个tocmat02容器,执行 ip addr
,又多了个网卡
docker run -it -d -P --name tomcat02 tomcat
[root@192 ~]# ip addr
# ...
# veth-pair技术 7 与 6 成对,Linux主机则为6 与 7成对
7: veth568cc5e@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether de:55:c0:b4:58:42 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::dc55:c0ff:feb4:5842/64 scope link
valid_lft forever preferred_lft forever
# veth-pair技术 9 与 8 成对
9: veth7668013@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 7a:c2:eb:86:ae:9f brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::78c2:ebff:fe86:ae9f/64 scope link
valid_lft forever preferred_lft forever
3、进入tocmat02容器,为容器安装 ip 查看工具,ip:172.17.0.2
apt update && apt install -y iproute2
root@443a02110963:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
root@443a02110963:/usr/local/tomcat#
4、tomcat01与tocmat02 可以相互ping 通
root@443a02110963:/usr/local/tomcat# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.129 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.279 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.142 ms
^C--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.129/0.183/0.279/0.068 ms
结论
tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥一对就没了!
思考一个场景
我们编写了一个微服务,database url=ip: 项目不重启,数据库ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?(高可用)
实现ping 通 容器名
–link 作用
docker run --link可以用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。
测试
1、准备centos01、centos02
$ docker run -it -d --name centos01 centos
$ docker run -it -d --name centos02 centos
2、实现ping不通容器名
$ docker exec -it centos02 ping centos01
[root@192 ~]# docker exec -it centos02 ping centos01
ping: centos01: Name or service not known
3、运行一个tomcat03 ,加上参数--link centos02
,连接centos02
$ docker run -it --name centos03 --link centos02 centos /bin/bash
[root@a04540580e1b /]# ping centos02
PING centos02 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.118 ms
64 bytes from centos02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.110 ms
^C
--- centos02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 0.110/0.114/0.118/0.004 ms
[root@a04540580e1b /]#
4、用centos03 ping centos02 可以ping通
docker exec -it centos03 ping centos02
[root@192 ~]# docker exec -it centos03 ping centos02
PING centos02 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.071 ms
64 bytes from centos02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.154 ms
^C
--- centos02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 0.071/0.112/0.154/0.042 ms
但是用tomcat02 ping tomcat03 ping不通
docker network
[root@192 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
297f07c51979 bridge bridge local # bridge:桥接 docker0
87a8f8309bfa host host local
51b67872ea20 none null local
[root@192 ~]# docker network --help
Usage: docker network COMMAND
Manage networks # 管理网络
Commands:
connect # 将容器连接到网络
create # 创建网络
disconnect # 断开一个容器与网络的连接
inspect # 显示一个或多个网络的详细信息
ls # 网络列表
prune # 删除所有未使用的网络
rm # 删除一个或多个网络
1、查看docker0的网络信息
docker network inspect 297f07c51979
[root@192 ~]# docker network inspect 297f07c51979
[
{
"Name": "bridge",
"Id": "297f07c5197942c2a4bc867abd31c61f6f804f1b7fc08b6e7b3da2839c77bc34",
"Created": "2022-02-03T17:50:16.517397962+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default", # default
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16", # 网段
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"78904cf546599b37473b34ff4a5bf5f1af3a632e5bd80ff8e72904d7ed339c45": {
"Name": "tomcat02", # tomcat02
"EndpointID": "ea7126991ab6eab6d65f0bc8c0135d014446c919c9ceee1e94d1ddd8c07e5c80",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16", # tomcat02 的 ip 地址
"IPv6Address": ""
},
"95cac41f93906a08c79b49e84ed490b220032ee954c27b243835de6cb035bb56": {
"Name": "tomcat01", # tomcat01
"EndpointID": "4c10c4fe891272787fc69121be3f929a830fef79eca92c507f5fdccad9d83145",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
# ...
},
"Labels": {}
}
]
2、查看容器tomcat02详细信息
docker inspect 容器id
[root@192 ~]# docker inspect 78904cf54659
[
{
"Id": "78904cf546599b37473b34ff4a5bf5f1af3a632e5bd80ff8e72904d7ed339c45",
"Created": "2022-02-03T12:13:25.377988982Z",
"Path": "/bin/bash",
"Args": [],
"State": { # 主题
"Status": "running",
"Running": true, # 运行
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 9965,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-02-03T12:44:20.630270698Z",
"FinishedAt": "2022-02-03T12:34:37.648949082Z"
},
"Config": {
"Hostname": "78904cf54659",
"Domainname": "",
"User": "",
# ...
"Env": [# 环境配置
"PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"JAVA_HOME=/usr/local/openjdk-11",
"LANG=C.UTF-8",
"JAVA_VERSION=11.0.13",
# ...
],
"Cmd": [
"/bin/bash"
],
"Image": "tomcat", # 镜像
"Volumes": null,
"WorkingDir": "/usr/local/tomcat", # 工作目录
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "5ed43e901e7b9b49937e06d39a5f1fe73709437d70beaf8b07d3e56c48affcdf",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8080/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "49169"
},
{
"HostIp": "::",
"HostPort": "49169"
}
]
},
# ...
"Networks": {
"bridge": { # 桥接
# ...
"Gateway": "172.17.0.1", # 网关
"IPAddress": "172.17.0.3", # ip
# ...
}
}
}
}
]
3、查看容器tomcat03详细信息,得到连接信息
docker inspect 4e6aae2d99dd
# ...
"HostConfig": {
# ...
"Links": [
"/tomcat02:/tomcat03/tomcat02"
],
# ...
}
# ...
4、容器tomcat03配置了网络映射 将主机名(tomcat02)与ip地址host映射(不推荐使用)。
cat /etc/hosts
查看所有的docker网络
[root@192 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
297f07c51979 bridge bridge local # bridge:桥接 docker0
87a8f8309bfa host host local
51b67872ea20 none null local
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
自定义一个网络
1、默认参数 -net bridge
# 启动时 --net bridge 是默认带上的,bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat 等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
2、创建网络的命令
[root@192 ~]# docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable # 启用手动容器附件
--aux-address map # map网络驱动使用的辅助IPv4或IPv6地址(默认map[])
--config-from string # 要复制配置的网络
--config-only # 创建仅配置网络
-d, --driver string # 管理网络的驱动程序(默认为“bridge”)
--gateway strings # IPv4或IPv6主子网网关
--ingress # 创建群路由-mesh网络
--internal # 限制外部用户访问网络
--ip-range strings # 从子范围分配容器ip
--ipam-driver string # IP地址管理驱动程序(默认为“default”)
--ipam-opt map # map设置IPAM驱动的特定选项(default map[])
--ipv6 # 启用ipv6组网功能
--label list # list设置网络元数据
-o, --opt map # 设置驱动程序的特定选项(默认map[])
--scope string # 控制网络范围
--subnet strings # CIDR格式的子网,表示一个网段
3、自定义一个网络(创建网络),名字为mynet
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@192 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
6293fb8f0a642641dc0f6043b7a666690406db6423070b08f6af38a67e96e64f
4、查看自定义的网络mynet
$ docker network inspect mynet
[root@192 ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "6293fb8f0a642641dc0f6043b7a666690406db6423070b08f6af38a67e96e64f",
"Created": "2022-02-04T10:06:47.753633784+08:00",
"Scope": "local",
"Driver": "bridge", #网络模式 bridge(桥接)
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16", # 子网 192.168.0.2 ~ 192.168.255.254
"Gateway": "192.168.0.1" # 网关
}
]
},
# ...
}
]
创建容器,配置网络
1、创建容器01、02
# 接 /bin/bash 直接进命令行
docker run -it --name centos-net01 --net mynet centos
docker run -it --name centos-net02 --net mynet centos
2、再次查看自定义的网络mynet,可见多了新增容器01、02的网络配置
[root@192 ~]# docker network inspect mynet
[
{
"Name": "mynet",
# ...
"Containers": {
"0c9e72313626017f9143fef9bfe9acb70f0ed46c352c8f6ed0612675c666379d": {
"Name": "centos-net01", # centos-net01
"EndpointID": "a228cec33c9019f31999f9b8c9ced3e60d3e611ae395d147b0db2ea920fce4ed",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16", # ip地址: 192.168.0.2
"IPv6Address": ""
},
"c31a887225dfa9572bc47703d838932590d9a5188b1fe13e82cd5851e286b497": {
"Name": "centos-net02", # centos-net02
"EndpointID": "7f4864f0e52fb36149cfffa78bde3ee88e38ea20202eca4c0b4ec5136e62ec94",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16", # ip地址: 192.168.0.3
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
3、在自定义的网络下,服务可以互相ping通,不用使用–link
docker exec -it centos-net01 ping centos-net02
[root@192 ~]# docker exec -it centos-net01 ping centos-net02
PING centos-net02 (192.168.0.3) 56(84) bytes of data.
64 bytes from centos-net02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from centos-net02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.077 ms
64 bytes from centos-net02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.081 ms
64 bytes from centos-net02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.110 ms
^C
--- centos-net02 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 0.072/0.085/0.110/0.014 ms
[root@192 ~]# docker exec -it centos-net02 ping centos-net01
PING centos-net01 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from centos-net01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.095 ms
^C
--- centos-net01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1003ms
rtt min/avg/max/mdev = 0.049/0.072/0.095/0.023 ms
4、查看host映射,映射 ip 对应 容器id
[root@192 ~]# docker exec -it centos-net02 cat /etc/hosts
127.0.0.1 localhost
# ...
192.168.0.3 c31a887225df # ip 对应 容器id(centos-net01 的ip)
[root@192 ~]# docker exec -it centos-net01 cat /etc/hosts
127.0.0.1 localhost
# ...
192.168.0.2 0c9e72313626 # ip 对应 容器id(centos-net02 的ip)
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
解决问题,网段不同如何ping通
1、创建容器 centos01,测试ping 容器名失败
$ docker run -dit --name centos01 centos
$ docker exec -it centos01 ping centos-net01
[root@192 ~]# docker exec -it centos01 ping centos-net01
ping: centos-net01: Name or service not known
2、解决方法:docker network connect
[root@192 ~]# clear
[root@192 ~]# docker network connect --help
# NETWORK:工作网络(mynet)
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network # 将容器连接到网络中
Options:
--alias strings # 为容器添加网络范围的别名
--driver-opt strings # 网络驱动选项
--ip string # IPv4地址(例如172.30.100.104)
--ip6 string # IPv6地址(例如,2001:db8:: 33)
--link list # 添加链接到另一个容器
--link-local-ip strings # 为容器添加链路本地地址
3、将网络mynet与 centos01容器连通
$ docker network connect mynet centos01
4、查看mynet
[root@192 ~]# docker inspect mynet
[
{
"Name": "mynet",
# ...
"Containers": {
"0c9e72313626017f9143fef9bfe9acb70f0ed46c352c8f6ed0612675c666379d": {
"Name": "centos-net01",
"EndpointID": "b09c89b344437d0a166567d03358cdb6f2c05a6833813501285ed516abe641df",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"c31a887225dfa9572bc47703d838932590d9a5188b1fe13e82cd5851e286b497": {
"Name": "centos-net02",
"EndpointID": "eda6dd675c194a84e6d398ee8c16cc6b42d67fb91069264d00d05ada7dd5633b",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"dac6694051750f990fa6fac796795d60b8e4578d9b72f90fbc9519b54e6498ac": {
"Name": "centos01", # 新增centos01
"EndpointID": "e79c29a2d531dd69b766ee6253f1562d7a8bcbc6accfab23cb6df5cdbaa6a7a0",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16", # 公网ip
"IPv6Address": ""
}
},
# ...
[root@192 ~]# docker exec -it centos01 cat /etc/hosts
127.0.0.1 localhost
# ...
# dac669405175 是 centos01容器自己的 容器id
172.17.0.2 dac669405175 # 私网ip => 容器id
192.168.0.3 dac669405175 # 公网ip => 容器id
[root@192 ~]# docker exec -it centos-net01 cat /etc/hosts
127.0.0.1 localhost
# ...
192.168.0.2 0c9e72313626 # 私网(公网)ip => 容器id
5、再次测试,centos01与 centos-net01、centos-net02 均可ping通
$ docker exec -it centos01 ping centos-net01
$ docker exec -it centos01 ping centos-net02
$ docker exec -it centos-net01 ping centos01
$ docker exec -it centos-net02 ping centos01
结论
假设要跨网络操作别人,就需要使用docker network connect
连通!
环境
三主三从
1、创建网卡
$ docker network create redisnet --subnet 172.38.0.0/16
2、通过脚本创建六个redis配置文件
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >> /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
[root@192 ~]# cd /mydata/redis/
[root@192 redis]# ls
node-1 node-2 node-3 node-4 node-5 node-6
[root@192 conf]# cd /mydata/redis/node-1/conf
[root@192 conf]# ls
redis.conf
[root@192 conf]# cat redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.11
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
3、通过脚本创建和运行六个redis容器,--ip
指定ip,-v
挂载redis配置文件和数据
for port in $(seq 1 6);\
do \
docker run -p 637${port}:6379 -p 1667${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done
docker run -p 6371:6379 -p 16671:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6372:6379 -p 16672:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6373:6379 -p 16673:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6374:6379 -p 16674:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6375:6379 -p 16675:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6376:6379 -p 16676:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisnet --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
4、查看创建的redis容器
(秒退的,可以用docker logs redis-1 查看日志)
[root@192 conf]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49e9e62c7fff redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 20 seconds ago Up 19 seconds 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16676->16379/tcp, :::16676->16379/tcp redis-6
691b11db10c8 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 21 seconds ago Up 20 seconds 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16675->16379/tcp, :::16675->16379/tcp redis-5
fc37037e7ae9 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 22 seconds ago Up 20 seconds 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16674->16379/tcp, :::16674->16379/tcp redis-4
85ef9071ac9b redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 22 seconds ago Up 21 seconds 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16673->16379/tcp, :::16673->16379/tcp redis-3
44b92119b2b3 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 23 seconds ago Up 21 seconds 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16672->16379/tcp, :::16672->16379/tcp redis-2
269b8eb57942 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 23 seconds ago Up 22 seconds 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16671->16379/tcp, :::16671->16379/tcp redis-1
5、查看网络redisnet的信息(Containers字段内省略了数据)
[root@192 conf]# docker inspect redisnet
[
{
"Name": "redisnet",
# ...
"Containers": {
"269b8eb57942dd3c816247251c1d4a0299c86d8dbfa45c1e60fd68b1e0b5e470": {
"Name": "redis-1",
"IPv4Address": "172.38.0.11/16",
},
"44b92119b2b3573e1a8e15a1e435cd3c1cde30a6fc3f960189a88f715e962fec": {
"Name": "redis-2",
"IPv4Address": "172.38.0.12/16",
},
"49e9e62c7ffff2955194095818f4b806e609329350456e65c2bec9f5932bd8f6": {
"Name": "redis-6",
"IPv4Address": "172.38.0.16/16",
},
"691b11db10c8403b999386caec7ad20dad535aa0d0e3f9d98214423b328f23de": {
"IPv4Address": "172.38.0.15/16",
},
"85ef9071ac9bbacc25cda715a695819e32fa17945956ae2c744e43b841e27af6": {
"Name": "redis-3",
"IPv4Address": "172.38.0.13/16",
},
"fc37037e7ae9ed007bef0290f3610f3a3cbbde744189a7b3e3a112b9497e7e5a": {
"Name": "redis-4",
"IPv4Address": "172.38.0.14/16",
}
},
# ...
5、创建集群,(redis默认没有bash,所以用 /bin/sh)
(1)进入redis-1容器
[root@192 ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof nodes.conf
/data #
(2) 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:637
9 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460 # 三主三从
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 7866a044a62217acc264e0780724baebfcbdf9ec 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: e2210b65a712c43fce9cb11a40605d4ae6afc61c 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: a2d9d996b447f724860502d4230434d8fbef45bb 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: eaa1f8ba8de966a6fffaed6b43e0226d95caffb9 172.38.0.14:6379
replicates a2d9d996b447f724860502d4230434d8fbef45bb
S: 35fcc7906fda3c977cf6fe09ebfd4632c8288449 172.38.0.15:6379
replicates 7866a044a62217acc264e0780724baebfcbdf9ec
S: 59c81a95ed20b8964246dee3bfc333e25960275a 172.38.0.16:6379
replicates e2210b65a712c43fce9cb11a40605d4ae6afc61c
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 7866a044a62217acc264e0780724baebfcbdf9ec 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 35fcc7906fda3c977cf6fe09ebfd4632c8288449 172.38.0.15:6379
slots: (0 slots) slave
replicates 7866a044a62217acc264e0780724baebfcbdf9ec
M: a2d9d996b447f724860502d4230434d8fbef45bb 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 59c81a95ed20b8964246dee3bfc333e25960275a 172.38.0.16:6379
slots: (0 slots) slave
replicates e2210b65a712c43fce9cb11a40605d4ae6afc61c
M: e2210b65a712c43fce9cb11a40605d4ae6afc61c 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: eaa1f8ba8de966a6fffaed6b43e0226d95caffb9 172.38.0.14:6379
slots: (0 slots) slave
replicates a2d9d996b447f724860502d4230434d8fbef45bb
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Redis三种模式:主从模式, 哨兵模式, 集群模式(推荐)
1、redis-cli -c 代表进入集群
/data # redis-cli -c
127.0.0.1:6379>
127.0.0.1:6379> cluster info
cluster_state:ok
# ..
cluster_known_nodes:6 # 节点:6
cluster_size:3 # 集群数量:3
# ...
2、查看节点信息
# master(主) slave(从)
127.0.0.1:6379> cluster nodes
35fcc7906fda3c977cf6fe09ebfd4632c8288449 172.38.0.15:6379@16379 slave 7866a044a62217acc264e0780724baebfcbdf9ec 0 1643970509988 5 connected
a2d9d996b447f724860502d4230434d8fbef45bb 172.38.0.13:6379@16379 master - 0 1643970508952 3 connected 10923-16383
59c81a95ed20b8964246dee3bfc333e25960275a 172.38.0.16:6379@16379 slave e2210b65a712c43fce9cb11a40605d4ae6afc61c 0 1643970509257 6 connected
e2210b65a712c43fce9cb11a40605d4ae6afc61c 172.38.0.12:6379@16379 master - 0 1643970508000 2 connected 5461-10922
eaa1f8ba8de966a6fffaed6b43e0226d95caffb9 172.38.0.14:6379@16379 slave a2d9d996b447f724860502d4230434d8fbef45bb 0 1643970509000 4 connected
7866a044a62217acc264e0780724baebfcbdf9ec 172.38.0.11:6379@16379 myself,master - 0 1643970507000 1 connected 0-5460
3、高可用测试
(1)存值(由redis-2处理)
127.0.0.1:6379> set name zs
-> Redirected to slot [5798] located at 172.38.0.12:6379 # 12 => redis-2
OK
172.38.0.12:6379> get name
"zs"
(2)停止redis-2
[root@192 ~]# docker stop redis-2
redis-2
(3)依旧可取(此时由redis-6处理,redis-6顶上了)。高可用
127.0.0.1:6379> get name
-> Redirected to slot [5798] located at 172.38.0.16:6379 # 16 => redis-6
"zs"
(4)查看节点信息cluster nodes
我们使用docker之后,所有的技术都会慢慢变得简单起来!
package com.example.demo.colltroller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloColltroer {
@RequestMapping("/hello")
public String hello(){
return "hello,一个平凡de人";
}
}
1、 双击Maven package打包
2、打包成功
3、测试jar是否可以运行,访问127.0.0.1:8080/hello运行成功
$ java -jar demo1-0.0.1-SNAPSHOT.jar
4、idea安装docker插件
在idea项目根目录创建并编写Dockerfile文件
FROM java:11
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
将jar包和Dockerfile上传到服务器
[root@192 idea]# pwd
/home/idea
[root@192 idea]# ls
demo1-0.0.1-SNAPSHOT.jar Dockerfile
1、构建镜像
$ docker build -t springboot .
[root@192 idea]# docker build -t springboot .
Sending build context to Docker daemon 16.57MB
Step 1/5 : FROM java:8
# ...
Successfully built f107ab2a9246
Successfully tagged springboot:latest
2、查看镜像
[root@192 idea]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
springboot latest f107ab2a9246 2 minutes ago 660MB
# ...
3、运行springboot容器,访问127.0.0.1:8080/hello
docker run -dit -p 8080:8080 --name hello springboot
[root@192 idea]# docker run -dit -p 8080:8080 --name hello springboot
b8d1f65da8a8b71975b336952af497ba946d801294b1ac42d266da41ba1b6a0c
[root@192 idea]# curl 127.0.0.1:8080/hello
hello,一个平凡de人
4、外网访问192.168.64.131:8080/hello
1、 登录
$ docker login -u 【你的用户名】 -p 【你的密码】
2、打标签
# docker tag 镜像id 你的账户名/镜像仓库名:tag名
$ docker tag f107ab2a9246 dockerywl/springboot
3、再提交 push镜像
# docker push 作者/镜像:TAG(版本)
$ docker push dockerywl/springboot
总结
以后我们使用了Docker之后,给别人交付就是一个镜像即可!