学习思想而非学技术,技术日新月异,唯有思想长盛不衰,润泽后生
学习资料:
【狂神说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、Docker概述
1.1 Docker 为什么会出现
一款产品上线:面临问题:
问题1:开发 和 上线 俩套环境
问题2:开发人员 和 运维人员 ,开发测试可运行,上线就运行不了
问题3:环境配置十分麻烦,每个机器都要部署环境(集群 Redis、ES、Hadoop 等等)
问题4: 发布 jar包 时 又要 部署(Mysql、ES、Redis、jdk 等等)费时的环境,希望jar + 环境一起发布
问题5:部署的环境不能跨平台 windows 与 Linux
Docker 给以上问题提出了解决方案
传统:开发打jar包 给运维来部署
现在:开发即负责打包又负责部署,全栈开发
开发人员 打jar包带上环境(这里的环境称为镜像) – Docker 仓库(商店) – 运维人员下载 镜像 可直接运行
docker 的 思想 来源于 集装箱 ,打包装箱,相互隔离
虚拟机非常笨重,而docker十分小巧。
开源:开放源代码
1.2 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 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。
2、 虚拟化技术和容器化技术
? 虚拟化技术特点:1.资源占用多 2.冗余步骤多 3.启动很慢
? 容器化技术:容器化技术不是模拟的一个完整的操作系统
? 虚拟机非常笨重,而docker十分小巧。
比较Docker和虚拟机的不同:
? 虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
? Docker容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟硬件。
? 每个容器都是相互隔离的,每个容器都有属于自己的文件系统,互不影响。
DevOps (Dev:开发,Ops:运维)
容器化带来的好处:
- 应用更快速的交付和部署
传统:一堆帮助文档,安装程序 Docker :打包镜像发布测试,一键运行 - 更便捷的升级和扩缩容
使用了Docker之后,我们部署应用就和搭积木一样! 项目打包为一个镜像,扩展服务器A !服务器B - 更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的. - 更高效的计算资源利用:
Docker是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
3、 Docker的基本组成
Docker的基本组成图如下:
Client:客户端
DOCKER_HOST:docker的主机(服务器)
Registry: 远程仓库
基本组成
-
镜像(image ): docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像==> run ==> tomcatOI容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的). ? 开发人员 打jar包带上环境(这里的环境称为镜像) -
容器(container ): Docker用容器技术,独立运行Y或者一个组应用,通过镜像来创建的。启动,停止,删除,基本命令!目前就可以把这个容器理解为就是一个简易的linux系统 镜像启动后出现容器 (镜像相当于类,容器相当于实例。一个镜像可以创建多个容器) -
仓库(repository ): 仓库就是存放镜像的地方!仓库分为公有仓库和私有仓库!Docker Hub (默认是国外的)
4、 Docker的安装
在 CentOS | 上安装 Docker 引擎Docker 文档
环境准备
Linux CentOS7
1、查看系统的内核:uname -r
系统内核版本为3.10.0
[root@192 ~]
3.10.0-1160.el7.x86_64
2、查看系统配置cat /etc/os-release
[root@192 ~]
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
4.1 开始安装
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
4.2 hello-world镜像测试
1、下载hello-world镜像进行测试
docker run hello-world
[root@192 ~]# clear
[root@192 ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
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
Docker的卸载
1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
2、删除资源 ./var/lib/docker 是docker的默认工作路径
rm -rf /var/lib/docker
5、配置阿里云镜像加速
本地机器无法使用
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
6、Docker原理
6.1 Docker容器运行流程
启动一个容器,docker run 的运行流程如下图:
6.2 底层原理
Docker是一个Client-Server(客户端-服务器)结构的系统,Docker的守护进程运行在主机上,通过Socker从客户端访问!Docker Server(服务器)接收到Docker-Client(客户端)的指令,就会执行这个指令!
Docker为什么比VMWare(虚拟机)快?
1、Docker比虚拟机更少的抽象层
2、docker利用宿主机的内核,而VM需要的是Guest OS(虚拟机操作系统)
? Docker新建一个容器的时候,不需要像虚拟机一样重新加载一个操作系统内核,直接利用宿主机的操作系统,而虚拟机是需要加载Guest OS(虚拟机操作系统)。Docker和VM的对比如下:
7、Docker常用命令
命令的帮助文档地址:https://docs.docker.com/engine/reference/commandline/docker/
7.1 全部命令
[root@192 ~]# docker --help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:【选项】
--config string
-c, --context string
-D, --debug
-H, --host list
-l, --log-level string
--tls
--tlscacert string
--tlscert string
--tlskey string
--tlsverify
-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
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
scan* Docker Scan (Docker Inc., v0.12.0)
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:【命令】
attach
build
commit
cp
create
diff
events
exec
export
history
images
import
info
inspect
kill
load
login
logout
logs
pause
port
ps
pull
push
rename
restart
rm
rmi
run
save
search
start
stats
stop
tag
top
unpause
update
version
wait
Run 'docker COMMAND --help' for more information on a command.
7.2 基础命令
docker version #查看docker的版本信息
docker info #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令(可查看可选的参数)
docker COMMAND --help
docker --help #列出所有命令
7.3 镜像命令
拉取(下载)一个镜像
docker pull mysql
docker pull mysql:5.7
[root@192 ~]
Using default tag: latest
latest: Pulling from library/mysql
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 ~]
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]
查看其可选参数
[root@192 ~]# docker search --help
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
-f, --filter filter
--format string
--limit int
--no-trunc
搜索收藏数大于3000的镜像
[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 ~]
[root@192 ~]
Untagged: hello-world:latest
Untagged: hello-world@sha256:507ecde44b8eb741278274653120c2bf793b174c06ff4eaa672b713b3263477b
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
docker rmi -f 【镜像id】 【镜像id】 【镜像id】 ...
docker rmi -f $(docker images)
7.4 容器命令
镜像启动后出现容器
(镜像相当于类,容器相当于实例。一个镜像可以创建多个容器)
(镜像相当于你安装系统时下载的镜像文件,而容器呢就相当于你安装好的系统)
1、先拉取一个centos镜像
docker pull centos
[root@192 ~]
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是启动一个已经存在的容器
docker run [可选参数] image
--name="名字"
-d
-it
-p
-p ip:主机端口:容器端口
-p 主机端口:容器端口
-p 容器端口
-P
[root@192 ~]# docker start --help
Usage: docker start [OPTIONS] CONTAINER:容器id [CONTAINER...]
Options:
-a, --attach
--detach-keys string
-i, --interactive
进入容器
docker run -it centos /bin/bash
[root@192 ~]
[root@b8f211692996 /]
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
退出容器exit
[root@b8f211692996 /]
exit
列出容器
docker ps
docker ps -a
docker ps -n=?
docker ps -q
[root@192 ~]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8f211692996 centos "/bin/bash" 14 minutes ago Up 14 minutes zealous_lichterman
[root@192 ~]
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
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
Stop one or more running containers
Options:
-t, --time int
[root@192 ~]
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 ~]
Error response from daemon: No such container: centos
[root@192 ~]
eb679ca2e254
[root@192 ~]
b8f211692996
[root@192 ~]
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
7.5 其他常用命令
日志的查看
[root@192 ~]# docker logs --help
Usage: docker logs [OPTIONS] CONTAINER
Options:
--details
-f, --follow
--since string
-n, --tail string 、、从日志的末尾显示的行数(default "all")
-t, --timestamps
--until string
docker logs -tf 【容器id】
docker logs --tail number 【容器id】
[root@192 ~]
2b8ed9e4dcb655547b3c2aa28cd849179190ec03ecca2aabf9c7a44155b13097
[root@192 ~]
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 ~]
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
查看容器中进程信息
docker top 容器id
[root@192 ~]
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 ~]
[
{
"Id": "2b8ed9e4dcb655547b3c2aa28cd849179190ec03ecca2aabf9c7a44155b13097",
"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 ~]
[root@2b8ed9e4dcb6 /]
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@48c706c3a876 /]
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 目的主机路径 容器id:容器内路径
[root@192 ~]
[root@7b605b457f23 /]
[root@7b605b457f23 home]
[root@7b605b457f23 home]
Hello.txt
1、在容器中新建文件
[root@iZwz99sm8v95sckz8bd2c4Z ~]
[root@c703b5b1911f /]
[root@c703b5b1911f home]
[root@c703b5b1911f home]
[root@c703b5b1911f home]
test.java
[root@c703b5b1911f home]
exit
[root@iZwz99sm8v95sckz8bd2c4Z ~]
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 ~]
[root@iZwz99sm8v95sckz8bd2c4Z ~]
hai pan test.java
[root@7b605b457f23 home]
exit
2.copy文件
[root@192 ~]
[root@192 桌面]
Kuang
[root@192 桌面]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@192 桌面]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b605b457f23 centos "/bin/bash" 3 minutes ago Exited (0) 2 minutes ago tender_burnell
[root@192 桌面]
[root@192 桌面]
hello.txt Kuang
常用命令小节
8、docker 练习
8.1 部署Nginx
(Nginx:是一个高性能的HTTP和反向代理web服务器)
1、搜索nginx
https://hub.docker.com/_/nginx
[root@192 ~]
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 16232 [OK]
//...
2、拉取nginx
[root@192 ~]
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 ~]
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest c316d5a335a5 4 days ago 142MB
3、启动nginx镜像
[root@192 ~]
b93af0c28d2baca7b03dc34eaf6d0b8778abdb989e091d9461351a48b12fb706
[root@192 ~]
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 ~]
<!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 ~]
root@b93af0c28d2b:/
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
8.2 部署Tomcat
1、搜索tomcat
[root@192 ~]
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementati… 3248 [OK]
2、拉取tomcat
docker pull tomcat:9.0
[root@192 ~]
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 ~]
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
0c6b8ff8c37e: Already exists
bc5c573a9ab7: Pull complete
f9f34f3a3d27: Pull complete
Digest: sha256:28ef9f9a08f812de2f7f1de9076f39c911e5f92615ea168693964fbc2247701c
Status: Downloaded newer image for tomcat:latest
b55631abdbffbe3bf156050846e71f03834f8984bf4fe96952ddda46e209967b
[root@192 ~]
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
4、测试,windows(外网)访问成功
5、进入tomcat容器
docker exec -it nginx01 /bin/bash
[root@192 ~]
root@b55631abdbff:/usr/local/tomcat
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
root@b55631abdbff:/usr/local/tomcat/webapps.dist
ROOT docs examples host-manager manager
root@b55631abdbff:/usr/local/tomcat/webapps.dist
root@b55631abdbff:/usr/local/tomcat/webapps.dist/examples
META-INF WEB-INF index.html jsp servlets websocket
root@b55631abdbff:/usr/local/tomcat/webapps.dist/examples
<!--
-->
<!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
思考问题
? 每次部署项目都要进入容器是不是太麻烦,可以通过修改外部影响容器内部就好了。
8.3 部署 ElasticSearch+Kibana
部署难点
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 ~]
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 ~]
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 ~]
{
"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 ~]
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 索引中的数据进行搜索、查看、交互操作。您可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现。
9、图形化管理工具Portaniner安装
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 ~]
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 ~]
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) 查看镜像列表
10、Docker镜像详解
10.1 什么是镜像
? 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。
? 所以应用直接打包镜像,就可以用于运行
? 获得镜像的途径:
- 自己制作镜像DockerFile
- 远程仓库下载
- 别人copy给你
10.2 联合文件系统
UnionFS (联合文件系统)
? Docker的镜像实际上由一层一层的文件系统组成(下载镜像时分层下载可印证),这种层级的文件系统是UnionFS联合文件系统。
? UnionFS (联合文件系统)是一种分层、轻量级并且高性能的文件系统,它支持对文研系统的修改 ? 作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。 ? 特性:一次同时加载多个文件系统,但从外面看起来,只能看到外文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
作用:比如tomcat下载了centos,则mysql就不用下载了。相同层可复用
思考:为什么Docke也像要采用这种分层的结构呢? 最大的好处,莫过于是资源共享了 !比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只高要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享. 查看镜像分层的方式可以通过docker image inspect 命令!
docker image inspect redis
[root@192 ~]
[
{
"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镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层!
11、提交自己镜像
使用docker commit 命令提交容器成为一个新的版本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
? 由于默认的Tomcat镜像的webapps文件夹中没有任何内容,需要从webapps.dist中拷贝文件到webapps文件夹。下面自行制作镜像:就是从webapps.dist中拷贝文件到webapps文件夹下,并提交该镜像作为一个新的镜像。使得该镜像默认的webapps文件夹下就有文件。具体步骤如下:
1、启动Tomcat
docker run -it -p 8080:8080 tomcat
docker exec -it d55df6cdafe8 /bin/bash
2、制作(修改)镜像,拷贝cp -r webapps.dist/* webapps
root@d55df6cdafe8:/usr/local/tomcat
root@d55df6cdafe8:/usr/local/tomcat/webapps
root@d55df6cdafe8:/usr/local/tomcat/webapps
root@d55df6cdafe8:/usr/local/tomcat
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
root@d55df6cdafe8:/usr/local/tomcat
root@d55df6cdafe8:/usr/local/tomcat/webapps
ROOT docs examples host-manager manager
3、windows访问
4、提交自己镜像,提交到本地(之后再发布到远程仓库)
docker commit -m="add webapps app" -a="一个平凡de人" 6df1e2c4a350 tomcat02:1.0
[root@192 ~]
sha256:e699f08da20e848d7a9bd7c8953b63500abe1ea6a6605838dc9f97876857c229
[root@192 ~]
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时候,快照保存虚拟机状态,之后可状态回滚!
12、容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
使用卷技术的原因:容器的持久化和同步操作!容器间也是可以数据共享的!
12.1 使用数据卷
挂载后 主机目录和容器目录共享一个目录资源,容器目录也可以理解为是主机目录的快捷方式
方式一 :直接使用命令挂载 -v
docker run -it -v 主机目录:容器目录 -p 主机端口:容器内端口
docker inspect 容器id
1、挂载并进入命令行/bin/bash
docker run -it -v /home/ceshi:/home centos /bin/bash
[root@192 ~]
[root@a40aea147d6d /]
[root@a40aea147d6d home]
[root@192 ~]
[root@192 home]
ceshi
2、查看挂载
docker inspect 【容器id】
[root@192 home]
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
3、测试挂载
挂载后 主机目录和容器目录共享一个目录资源,容器目录也可以理解为是主机目录的快捷方式
[root@a40aea147d6d home]
[root@a40aea147d6d home]
test.txt
[root@192 home]
ceshi
[root@192 home]
[root@192 ceshi]
test.txt
[root@192 ceshi]
[root@192 ceshi]
This is test data
[root@a40aea147d6d home]
This is test data
就算容器关闭,数据依旧一致。
12.2 MySQL同步数据实战
1、获取mysql镜像
docker pull mysql
2、运行容器,挂载倆个数据目录,配置密码-e MYSQL_ROOT_PASSWORD=password
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 ~]
05574ce7407c7745ee28951f5ccc032062b83b9d9486ef6062a1d321df2ad0c8
3、测试连接,在windows上用数据库连接工具测试连接mysql容器·
4、文件目录映射成功
[root@192 mysql]
[root@192 mysql]
conf data
[root@192 mysql]
[root@192 data]
auto.cnf ca-key.pem
binlog.000001 ca.pem
binlog.000002 client-cert.pem ib_buffer_pool ibtmp1 performance_schema server-key.pem
binlog.index client-key.pem ibdata1
5、linux中,一个数据库对应一个目录,一个数据表对应一个文件
(1)创建数据库
(2)成功看到test目录
(3)创建数据表
(4)成功看到文件
容器数据持久化
假设我们将容器删除,发现我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能。
12.3 具名挂载和匿名挂载
卷指容器被挂载的主机目录
匿名挂载
1、匿名挂载就是不指定主机目录进行挂载(没有给卷(主机目录)起名就是匿名)
docker run -d -P --name nginx01 -v /etc/nginx nginx
2、查看所有的volume(卷)的情况
docker volume ls
[root@192 ~]
DRIVER VOLUME NAME
local 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c
local 8ecbc00746d9bea6a8095e65ead44e30b5cbf49f7409bc58aff9fab4b10cf0f4
local d745315f9e2d743c1a83edc5312809efba67693b8a01a27eb0a49a4ff572a450
3、指定卷来查看挂载
docker volume inspect 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c
[root@192 ~]
[
{
"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]
DRIVER VOLUME NAME
local 7ef9dee8a0efcf74601d3ce615fc1a74a96008d861648d5f415c581ce426b44c
local 8ecbc00746d9bea6a8095e65ead44e30b5cbf49f7409bc58aff9fab4b10cf0f4
local d745315f9e2d743c1a83edc5312809efba67693b8a01a27eb0a49a4ff572a450
local juming-nginx
3、指定卷来查看挂载
[root@192 home]
[
{
"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 /宿主机路径:容器内路径
拓展
通过 -v 容器内路径: ro rw 改变读写权限
ro
rw
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就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
13、 初始Dockerfile
什么是Dockerfile
Dockerfile 是用来构建docker镜像的构建文件,是一段命令脚本。
创建Dockerfile
1、创建docker的测试目录
[root@192 _data]
[root@192 home]
2、创建Dockerfile脚本文件,通过这个脚本可以生成镜像,
Dockerfile脚本文件内容分析:
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
[root@192 docker-test-volume]
[root@192 docker-test-volume]
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 ~]
REPOSITORY TAG IMAGE ID CREATED SIZE
kuangshen/centos latest 6b3e9b445d81 3 hours ago 231MB
4、启动镜像,查看容器
docker run -it /kuangshen/centos /bin/bash
[root@b68f2c5c965b /]
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
14、 数据卷容器
14.1 数据卷容器
容器挂载数据卷,实现容器间的数据同步和资源共享!
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 ~]
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 /]
[root@eb991bf17656 volume01]
- docker02容器内成功看到docker01创建的文件
[root@fa68f1afa235 /]
[root@fa68f1afa235 volume01]
docker.txt
5、再加个docker03试试,也有docker01创建的文件
docker run -it --name docker03 --volumes-from docker01 kuangshen/centos
[root@e4ad9cb37d01 /]
[root@e4ad9cb37d01 volume01]
docker.txt
6、小结
14.2 Mysql容器实现数据同步
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)
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
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、连接数据库测试
结论
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
15、Dockerfile(重点)
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(基础镜像)开始
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,那我们也可以!
15.1 DockerFile构建过程
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 |
15.2 Dockerfile实战
创建一个自己的centos镜像
官方的centos许多命令都没有,所以我们创建一个自己的centos镜像
1、创建工作目录
[root@192 dockerfile]
/home/dockerfile
[root@192 dockerfile]
2、编写Dockerfile文件 (文件名:centos-dockerfile)
FROM centos
MAINTAINER root<id_07221888@qq.com>
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
FROM centos
MAINTAINER root<id_07221888@qq.com>
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 /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]
IMAGE CREATED CREATED BY SIZE COMMENT
d1dc36cf8d9e 6 days ago /bin/sh -c
<missing> 6 days ago /bin/sh -c
<missing> 6 days ago /bin/sh -c
<missing> 6 days ago /bin/sh -c ln -s usr/local/bin/docker-entryp… 34B
<missing> 6 days ago /bin/sh -c
<missing> 6 days ago /bin/sh -c
<missing> 6 days ago /bin/sh -c
<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
<missing> 6 days ago /bin/sh -c #(nop) ENV MYSQL_VERSION=8.0.28-… 0B
<missing> 6 days ago /bin/sh -c #(nop) ENV MYSQL_MAJOR=8.0 0B
<missing> 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
<missing> 6 days ago /bin/sh -c #(nop) ENV GOSU_VERSION=1.14 0B
<missing> 6 days ago /bin/sh -c apt-get update && apt-get install… 9.34MB
<missing> 6 days ago /bin/sh -c groupadd -r mysql && useradd -r -… 329kB
<missing> 7 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 7 days ago /bin/sh -c
使用我们平时拿到一个镜像,可以研究一下是什么做的
15.3 CMD 和 ENTRYPOINT区别
- CMD : 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。(替代的方式)
- ENTRYPOINT : 指定这个容器启动的时候要运行的命令,可以追加命令。(追加的方式)
测试cmd
1、编写dockerfile文件
[root@192 dockerfile]
FROM centos
CMD ["ls","-a"]
2、 构建镜像
docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
[root@192 dockerfile]
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]
.
..
.dockerenv
bin
dev
etc
4、想追加一个命令 -l 成为ls -al
docker run cmd-test:0.1 ls -al
[root@192 ~]
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]
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]
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
15.4 Dockerfile制作tomcat镜像
1、准备镜像文件
准备tomcat 和 jdk到当前目录,编写好README
Apache Tomcat? - Apache Tomcat 9 Software Downloads
[root@192 tomcat]
apache-tomcat-9.0.58.tar.gz jdk-8u60-linux-x64.tar.gz
[root@192 tomcat]
/root/桌面/Kuang/tomcat
[root@192 tomcat]
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<id_07221888@qq.com>
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<1204598429@qq.com>
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镜像来发布运行!
15.5 发布镜像到DockerHub(常用)
1、登录远程仓库( https://hub.docker.com/)
2、终端登录
[root@192 ~]
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 ~]
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/
Login Succeeded
4、提交 push镜像
[root@192 ~]
REPOSITORY TAG IMAGE ID CREATED SIZE
cmd-test 0.1 3a12f3d5b2a5 18 hours ago 231MB
(1) 先打标签
docker tag 3a12f3d5b2a5 dockerywl/cmd-test:0.1
(2) 再提交 push镜像
docker push dockerywl/cmd-test:0.1
[root@192 ~]
The push refers to repository [docker.io/dockerywl/cmd-test]
74ddd0ec08fa: Pushing [================> ] 77.74MB/231.3MB
(3) push成功
发布到阿里云镜像服务上
看官网 很详细https://cr.console.aliyun.com/repository/
15.6 保存传输
保存后拷贝的U盘交给别人使用
1、保存(压缩)成backup.tar
[root@192 ~]
Usage: docker save [OPTIONS] IMAGE [IMAGE...]
将一个或多个镜像保存到tar存档文件(默认情况下流到STDOUT)
Options:
-o, --output string 写入一个文件,而不是STDOUT
docker save 镜像 -o 文件名
[root@192 ~]
[root@192 ~]
backup.tar
2、加载(解压)镜像压缩文件backup.tar
[root@192 ~]
Usage: docker load [OPTIONS]
从tar存档文件或STDIN加载镜像
Options:
-i, --input string 从tar存档文件读取,而不是STDIN
-q, --quiet 抑制负载输出
docker load -i backup.tar
[root@192 ~]
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
15.7 Docker所有流程小结(重点)
= 容器内安装工具 =
tomcat 容器
Linux apt 命令 | 菜鸟教程 (runoob.com)
apt update
apt install -y iproute2
apt-get install inetutils-ping
apt install vim
apt update && apt install -y iproute2 && apt-get install inetutils-ping
16、Docker网络详解
容器编排、集群部署
16.1 理解Docker 0(不推荐使用)
不推荐使用:Docker 0 不支持 ping 容器名
清空所有环境
docker rmi -f $(docker images)
docker rm -f $(docker ps -aq)
[root@192 ~]
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
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
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 (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 (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 ~]
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 ~]
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
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
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 (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中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥一对就没了!
16.2 –link(不推荐使用)
思考一个场景
? 我们编写了一个微服务,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 ~]
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 ~]
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不通
16.3 Docker网络探究
docker network
[root@192 ~]
NETWORK ID NAME DRIVER SCOPE
297f07c51979 bridge bridge local
87a8f8309bfa host host local
51b67872ea20 none null local
[root@192 ~]
Usage: docker network COMMAND
Manage networks
Commands:
connect
create
disconnect
inspect
ls
prune
rm
1、查看docker0的网络信息
docker network inspect 297f07c51979
[root@192 ~]
[
{
"Name": "bridge",
"Id": "297f07c5197942c2a4bc867abd31c61f6f804f1b7fc08b6e7b3da2839c77bc34",
"Created": "2022-02-03T17:50:16.517397962+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "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",
"EndpointID": "ea7126991ab6eab6d65f0bc8c0135d014446c919c9ceee1e94d1ddd8c07e5c80",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"95cac41f93906a08c79b49e84ed490b220032ee954c27b243835de6cb035bb56": {
"Name": "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 ~]
[
{
"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",
}
}
}
}
]
3、查看容器tomcat03详细信息,得到连接信息
docker inspect 4e6aae2d99dd
"HostConfig": {
"Links": [
"/tomcat02:/tomcat03/tomcat02"
],
}
4、容器tomcat03配置了网络映射 将主机名(tomcat02)与ip地址host映射(不推荐使用)。
cat /etc/hosts
16.4 自定义网络
查看所有的docker网络
[root@192 ~]
NETWORK ID NAME DRIVER SCOPE
297f07c51979 bridge bridge local
87a8f8309bfa host host local
51b67872ea20 none null local
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
自定义一个网络
1、默认参数 -net bridge
$ docker run -d -P --name tomcat01 tomcat 等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
2、创建网络的命令
[root@192 ~]
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable
--aux-address map
--config-from string
--config-only
-d, --driver string
--gateway strings
--ingress
--internal
--ip-range strings
--ipam-driver string
--ipam-opt map
--ipv6
--label list
-o, --opt map
--scope string
--subnet strings
3、自定义一个网络(创建网络),名字为mynet
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@192 ~]
6293fb8f0a642641dc0f6043b7a666690406db6423070b08f6af38a67e96e64f
4、查看自定义的网络mynet
$ docker network inspect mynet
[root@192 ~]
[
{
"Name": "mynet",
"Id": "6293fb8f0a642641dc0f6043b7a666690406db6423070b08f6af38a67e96e64f",
"Created": "2022-02-04T10:06:47.753633784+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
}
]
创建容器,配置网络
1、创建容器01、02
docker run -it --name centos-net01 --net mynet centos
docker run -it --name centos-net02 --net mynet centos
2、再次查看自定义的网络mynet,可见多了新增容器01、02的网络配置
[root@192 ~]
[
{
"Name": "mynet",
"Containers": {
"0c9e72313626017f9143fef9bfe9acb70f0ed46c352c8f6ed0612675c666379d": {
"Name": "centos-net01",
"EndpointID": "a228cec33c9019f31999f9b8c9ced3e60d3e611ae395d147b0db2ea920fce4ed",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"c31a887225dfa9572bc47703d838932590d9a5188b1fe13e82cd5851e286b497": {
"Name": "centos-net02",
"EndpointID": "7f4864f0e52fb36149cfffa78bde3ee88e38ea20202eca4c0b4ec5136e62ec94",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
3、在自定义的网络下,服务可以互相ping通,不用使用–link
docker exec -it centos-net01 ping centos-net02
[root@192 ~]
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 ~]
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 ~]
127.0.0.1 localhost
192.168.0.3 c31a887225df
[root@192 ~]
127.0.0.1 localhost
192.168.0.2 0c9e72313626
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
16.5 网络连通
解决问题,网段不同如何ping通
1、创建容器 centos01,测试ping 容器名失败
$ docker run -dit --name centos01 centos
$ docker exec -it centos01 ping centos-net01
[root@192 ~]
ping: centos-net01: Name or service not known
2、解决方法:docker network connect
[root@192 ~]
[root@192 ~]
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings
--driver-opt strings
--ip string
--ip6 string
--link list
--link-local-ip strings
3、将网络mynet与 centos01容器连通
$ docker network connect mynet centos01
4、查看mynet
[root@192 ~]
[
{
"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",
"EndpointID": "e79c29a2d531dd69b766ee6253f1562d7a8bcbc6accfab23cb6df5cdbaa6a7a0",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
- centos01容器的hosts文件(一个容器两个ip)
[root@192 ~]
127.0.0.1 localhost
172.17.0.2 dac669405175
192.168.0.3 dac669405175
[root@192 ~]
127.0.0.1 localhost
192.168.0.2 0c9e72313626
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 连通!
17、Redis集群部署实战
17.1 部署
环境
三主三从
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 ~]
[root@192 redis]
node-1 node-2 node-3 node-4 node-5 node-6
[root@192 conf]
[root@192 conf]
redis.conf
[root@192 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]
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]
[
{
"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 ~]
/data
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
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.
17.2 测试Redis集群
Redis三种模式:主从模式, 哨兵模式, 集群模式(推荐)
1、redis-cli -c 代表进入集群
/data
127.0.0.1:6379>
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_known_nodes:6
cluster_size:3
2、查看节点信息
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
OK
172.38.0.12:6379> get name
"zs"
(2)停止redis-2
[root@192 ~]
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
"zs"
(4)查看节点信息cluster nodes
我们使用docker之后,所有的技术都会慢慢变得简单起来!
18、SpringBoot微服务打包Docker镜像
18.1 构建SpringBoot项目
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人";
}
}
18.2 打jar包
1、 双击Maven package打包
2、打包成功
3、测试jar是否可以运行,访问127.0.0.1:8080/hello运行成功
$ java -jar demo1-0.0.1-SNAPSHOT.jar
4、idea安装docker插件
18.3 上传jar包
在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]
/home/idea
[root@192 idea]
demo1-0.0.1-SNAPSHOT.jar Dockerfile
18.4 构建镜像
1、构建镜像
$ docker build -t springboot .
[root@192 idea]
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]
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]
b8d1f65da8a8b71975b336952af497ba946d801294b1ac42d266da41ba1b6a0c
[root@192 idea]
hello,一个平凡de人
4、外网访问192.168.64.131:8080/hello
18.5 发布
1、 登录
$ docker login -u 【你的用户名】 -p 【你的密码】
2、打标签
$ docker tag f107ab2a9246 dockerywl/springboot
3、再提交 push镜像
$ docker push dockerywl/springboot
总结
以后我们使用了Docker之后,给别人交付就是一个镜像即可!
|