狂神说Docker笔记

1.概述

一句话,带着你的开发环境一起上线,避免了别人机器上无法运行的问题
docker不是一个完整的系统,只有部分核心

DevOps(开发运维一体)

应用更快速的交付和部署
传统:一对帮助文档,安装程序。
Docker:打包镜像发布测试一键运行。
更便捷的升级和扩缩容
使用了 Docker之后,我们部署应用就和搭积木一样
项目打包为一个镜像,扩展服务器A!服务器B
更简单的系统运维
更高效的计算资源利用
Docker是内核级别的虚拟化,可以在一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨
到极致。

Docker的基本组成

在这里插入图片描述

  • 镜像(image):
    docker镜像就好比是一个目标,可以通过这个目标来创建容器服务,tomcat镜像==>run==>容器(提
    供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
  • 容器(container):
    Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的.
    启动,停止,删除,基本命令
    目前就可以把这个容器理解为就是一个简易的 Linux系统。
  • 仓库(repository):
    仓库就是存放镜像的地方!
    仓库分为公有仓库和私有仓库。(很类似git)
    Docker Hub是国外的。
    阿里云…都有容器服务器(配置镜像加速!)

2.安装Docker快速起步

安装Docker

环境准备
Linux要求内核3.0以上
所以我们先查看一下系统内核

uname -r

在这里插入图片描述
直接去官网安装
https://docs.docker.com/engine/install/
在这里插入图片描述
卸载旧版本

 sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

安装操作

	需要的安装包 
	yum install -y yum-utils
	设置镜像的仓库 
	yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
	默认是从国外的,不推荐
	推荐使用国内的 
	yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
	更新yum软件包索引
	yum makecache fast
	安装docker相关的 docker-ce 社区版 而ee是企业版
	yum install docker-ce docker-ce-cli containerd.io
	启动docker,这一步非常重要
	systemctl start docker
	使用docker version查看是否按照成功
	docker version
	测试 
	docker run hello-world

顺利启动
在这里插入图片描述

镜像加速器

还可以再快一点,找到阿里云镜像加速器
阿里云镜像加速器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.Run流程和Docker原理

Run流程

在这里插入图片描述
我们自定义个镜像拉取一下吧(拉取一个不存在的镜像肯定报错)

docker run 镜像名称

在这里插入图片描述

原理

docker容器是一个非常小的核心
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问
Docker-Server接收到Docker-Client的指令,就会执行这个命令!
在这里插入图片描述

Docker比虚拟机快的原因

1、docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
2、docker利用的是宿主机的内核,而不需要Guest OS。GuestOS: VM(虚拟机)里的的系统(OS);HostOS:物理机里的系统(OS);
少了重复的操作系统部分,就会好很多
在这里插入图片描述
因此,当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。然而避免引导、加载操作系统内核是个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟。

4.docker常用命令

帮助命令

docker version 查看版本
docker info    查看docker系统信息
docker --help  万能命令,查看所有命令信息

镜像命令

docker images #查看所有本地主机上的镜像 可以使用docker image ls代替 
docker search 镜像名称 #搜索镜像 
docker pull 镜像名称 或者 docker image pull #下载镜像
docker rmi  或者 docker image rm  # 删除镜像 

docker pull 下载镜像

在这里插入图片描述

docker images 查看所有本地的主机上的镜像

在这里插入图片描述

docker rmi 删除镜像

在这里插入图片描述
镜像命令到此为止,具体如何操作是容器命令的事情,剩下的是容器命令来操作镜像,这一切的前提是有一个Linux的镜像来操作这些

5.容器命令

说明:我们有了镜像才可以创建容器,Linux,下载centos镜像来学习
必须先拉取一个Linux的系统镜像
在这里插入图片描述

参数说明

docker run [可选参数] image | docker container run [可选参数] image
可选参数:
--name="Name" 容器名字 tomcat01 tomcat02 用来区分容器 
-d 后台方式运行 
-it 使用交互方式运行,进入容器查看内容 
-p 指定容器的端口 -p 8080(宿主机):8080(容器) 
	-p ip:主机端口:容器端口 
	-p 主机端口:容器端口(常用) 
	-p 容器端口 容器端口 
	-P(大写) 随机指定端口

运行centos
在这里插入图片描述
注意,现在是在centos内部,我们可以运行linux命令查看,centos内部和linux一样,一应俱全
在这里插入图片描述
退出的操作:exit命令(这是关闭退出)或者Ctrl+P+Q (这是保持运行退出)

列出运行状态的容器

docker ps 命令
命令如下:
默认 列出当前正在运行的容器
docker ps -a  列出所有运行的容器,包括以前运行过的
docker ps -n=? 根据n来显示最近运行的容器,1是最新的2、3、4、5....以此类推
docker ps  -q  显示容器运行的编号
也可以搭配起来整活,-aq显示所有运行的编号,随意搭配吧
docker ps -aq

删除容器

docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf 
docker rm -f $(docker ps -aq) #删除指定的容器 
docker ps -a -q|xargs docker rm #删除所有的容器(linux管道符操作)

启停容器

docker start 容器id #启动容器 
docker restart 容器id #重启容器 
docker stop 容器id #停止当前正在运行的容器 
docker stop $(docker ps -qa) #停掉当前正在运行的全部容器
docker kill 容器id #强制停止当前容器

Docker Run和Docker Start的区别

docker中run和start的区别

docker run 后面指定的是一个镜像

docker start指定的是一个容器

docker run是利用镜像生成容器,并启动容器,而docker start是启动一个之前生成过的容器

常用其他命令

后台启动容器

docker run -d 镜像名称

# 问题docker ps. 发现centos 停止了 
# 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止 
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

查看日志

docker logs --help

-tf #显示日志信息(一直更新) --tail number #需要显示日志条数 
docker logs -t --tail n 容器id #查看n行日志 
docker logs -ft 容器id #跟着日志

查看容器中的进程

docker top 容器id

查看镜像的元数据

# 命令 docker inspect 容器id 
#测试 ➜ ~ docker inspect 55321bcae33d 
[ 
	{ 
	"Id": "55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066",
	 "Created": "2020-05-15T05:22:05.515909071Z", 
	 "Path": "/bin/sh", ... 
	 } 
]

进入容器

以交互模式进入当前正在运行的容器
方式一
docker exec进入当前容器后开启一个新的终端,可以在里面操作。(常用)

# 命令 
docker exec -it 容器id bashshell
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置 

方式二
docker attach 进入容器正在执行的终端

docker attach 容器id

docker attach 55321bcae33d

将docker容器中centos里的文件拷贝到linux中

命令:

docker cp 容器id:容器内路径 主机目的路径

测试一下
先进入docker中 docker ps找到运行中的centos
并用命令进入docker容器内部 docker exec -it 容器id /bin/bash 或者 docker attach 容器id
创建一个文件touch test.java。创建完毕用ls命令查看当前docker centos里的文件,可以看到已经创建成功了
那么下一步就是把他搬到外面的centos里
在这里插入图片描述
开始拷贝
从默认路径下的/test.java 拷贝到外面linux的/software路径下

 docker cp 1746bd095f04:/test.java /software

运行,拷贝成功,香香!
在这里插入图片描述

命令关系图

在这里插入图片描述

port  	  # 查看映射端口对应的容器内部源端口
pause	  # 暂停容器
ps        # 猎户容器列表
pull      # 从docker镜像源服务器拉取指定镜像或者库镜像
push      # 推送指定镜像或者库镜像至docker源服务器
restart   # 重启运行的容器
rm        # 移除一个或多个容器
rmi       # 移除一个或多个镜像 (无容器使用该镜像才可删除,否则需要删除相关容器才可继续或 -f 强制删除)
run       # 创建一个新的容器并运行一个命令
save      # 保存一个镜像为一个 tar 包【对应 load】
search    # 在 docker hub 中搜索镜像
start     # 启动容器
stop      # 停止容器
tag       # 给源中镜像打标签
top       # 查看容器中运行的进程信息
unpause   # 取消暂停容器
version   # 查看 docker版本号
wait      # 截取容器停止时的退出状态值

6.实操

部署Nginx

先去dockerHub找镜像,再拉取镜像

docker pull nginx

查看拉取出来的镜像

docker images

已经拉取成功了
在这里插入图片描述
运行测试

~ docker run -d --name nginx00 -p 3344:80 nginx

为什么要-p,因为要打通Linux和docker之间的端口号才能访问,并且在docker内部nginx也是有自己的端口号的,
这里3344是Linux的端口号,80是docker里nginx的端口号,相当于套娃了
如果你想访问容器内的docker就要经历以下步骤
在这里插入图片描述
在这里插入图片描述
运行,返回一串id
查看一下正在运行的docker镜像服务
正常运行

docker ps

在这里插入图片描述
公网访问成功
在这里插入图片描述
思考问题
我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?→ 数据卷!

部署Tomcat

先去dockerHub找镜像,再拉取镜像

docker pull nginx

查看拉取出来的镜像

docker images

已经拉取成功了
在这里插入图片描述
运行测试

docker run -d -p 8080:8080 --name tomcat01 tomcat

Linux中的8080端口,docker下的8080接口,因为Tomcat默认给8080端口
在这里插入图片描述
外网访问测一下
在这里插入图片描述
因为没有网站,所以没有找到,我们进入这个镜像看一下,就是因为webapp下没有东西才会导致的404
发现问题:1、linux命令少了。 2.没有webapps # 阿里云镜像(阉割版),它为保证最小镜像,将不必要的都剔除了→保证最小可运行环境!
思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?要是可以在容器外部提供一个映射路径,webapps,我们在外部放置项目,就自动同步内部就好了!

可视化操作页面portainer

Docker图形化界面管理工具!提供一个后台面板供我们操作!
运行如下命令即可 打开可视化服务
docker run -d -p 8080:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
到时候访问ip+8088就可以了

用的比较少

7.Docker镜像讲解

联合文件系统

下载镜像的一层一层的pull下来的东西就是联合文件系统,把每一个文件系统里的文件进行分层处理
在这里插入图片描述
说人话就是,复用一些大家都通用的东西,在pull镜像的时候,拉取非通用的、差异的部分就可以了。

UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支 持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应 用镜像

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系 统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
在这里插入图片描述

为什么会有这种分层

这种分层的概念和Git差不多,每次来的新东西都是最新的版本

所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当
前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在这里插入图片描述
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
在这里插入图片描述
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7
是文件5的一个更新版
在这里插入图片描述
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。

这个镜像里面就有6个layer,也就是6层,到时候拉取这个image时,对六层文件进行分析,拉取差异的部分就行
在这里插入图片描述
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!

我们可以操作的只有镜像层上面的容器层是可以操作的,镜像层是没有办法直接来操作的,因为是你拉取的部分,我们只可以对最上面的容器层进行操作
在这里插入图片描述

如何提交一个我自己的镜像

commit镜像

docker commit 提交容器成为一个新的副本

命令和git原理类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]

实战测试
# 1、启动一个默认的tomcat 
docker run -d -p 8080:8080 tomcat bash
# 2、发现这个默认的tomcat 是没有webapps应用,官方的镜像默认webapps下面是没有文件的! 
docker exec -it 容器id bash
# 3、拷贝文件进去 ,或者做个修改
# 4、将操作过的容器通过commit调教为一个镜像!我们以后就使用我们修改过的镜像即可,这就是我们自己 的一个修改的镜像。 
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG] 
docker commit -a="kuangshen" -m="add webapps app" 容器id tomcat02:1.0

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我们使用虚
拟机的快照。
在这里插入图片描述

docker exec -it b8b89ac14ce6 bash

在这里插入图片描述
做个修改就新建一个文件吧

 touch cc.test

在这里插入图片描述
注意,提交这个操作不能在Docker中进行,要退回到linux中再操作

docker commit -m="描述信息" -a="作者" 容器id 目标镜像名: [TAG]
docker commit -m="add test" -a="cc's Tomcat" 容器id tomcat:1.0

在这里插入图片描述
查看一下本地镜像,已经提交成功了
在这里插入图片描述

8.容器数据卷(重要)

是Docker中的一种同步机制,将docker容器内部的某个文件夹与Linux系统中的某个文件夹进行同步绑定
数据如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!

容器的持久化和同步操作!容器间也是可以数据共享的!

说穿了就是一种同步机制
在这里插入图片描述

使用数据卷

方式一 :直接使用命令挂载 -v (v是volume的缩写)

-v, --volume list Bind mount a volume 
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口 
docker run -it -v /home/ceshi:/home centos /bin/bash #通过 docker inspect 容器id 查看

先进入容器内部创建一个同步的测试文件夹(docker目录下)
在这里插入图片描述
再开一个Linux窗口,创建一个目标同步的文件夹
在这里插入图片描述在Linux,设置一下目标挂载卷路径

docker run -it -v /synTest:/synTest centos /bin/bash

在这里插入图片描述
进入docker容器查看一下相关镜像的具体信息

docker inspect 容器id 查看具体容器的信息

在这里插入图片描述
创建文件进行测试
在这里插入图片描述

实战MySQL部署以及数据同步到Linux

先拉取MySQL

docker pull mysql

在这里插入图片描述
可以看到,已经下载好了
官方提示要设置一下密码
https://hub.docker.com/_/mysql
在这里插入图片描述

$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
$docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0

数据挂载设置

后台启动MySQL,端口映射,Linux的3310映射到docker3306,数据挂载到目标位置
注意:数据挂载是可以通过挂载多个的,按顺序-v挂载就可以了,下面这行命令就是同时挂载conf文件和mysql数据到外面Linux的/mySqlDockerSyn目录下

#启动命令顺带设置mysql用户名和密码
 -d 后台运行 
 -p 端口映射 
 -v 卷挂载 
 -e 环境配置 
 -- name 容器名字
 docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /mySqlDockerSyn:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql1 mysql:8.0

在这里插入图片描述
此时测试一下连接MySQL,默认是root
在这里插入图片描述
此时我们在容器内部新建一个Test数据库,这个时候Linux就默认同步过来了
在这里插入图片描述

具名挂载和匿名挂载

所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data 下

具名挂载

写清楚我们想要挂载的位置

具名挂载 ➜ ~ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

匿名挂载

不写具体同步到哪里,只同步到默认的位置,挂载到容器内路径。这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路劲!

# 匿名挂载 -v 容器内路径! 
docker run -d -P --name nginx01 -v /etc/nginx nginx

总结

三种挂载: 匿名挂载、具名挂载、指定路径挂载 -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(read Only) 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

数据卷容器

说白了就是容器与容器之间进行数据同步
命名的容器挂载数据卷!哪个容器被挂载了,哪个容器被同步了,那个被挂载的容器就是父容器

这里提一个极端情况,就是父容器被删除了子容器会怎么样
这个就像u盘的插拔一样,只要是被拷贝出来的,即便容器被删了(u盘拔出了),也不耽误他原来已经备份好的数据

实现容器间的数据同步

docker run(启动容器) --volumes-from 容器名 路径/文件名称

结论:
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的

9.DockerFile(重要)

dockerFile也是一种容器数据卷
Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像。

编写一个DockerFile

# 创建一个dockerfile文件,名字可以随便 建议Dockerfile 
# 文件中的内容 指令(大写) 参数 
FROM centos #以centos为基础
VOLUME ["volume01","volume02"] #创建两个容器
CMD echo "----end----" # 控制台输出end
CMD /bin/bash #以命令行进行输入
#这里的每个命令,就是镜像的一层!

创建一个dockerfile文件,名字可以随便 建议Dockerfile 文件中的内容 指令(大写) 参数

docker build -f /文件地址 -t 自定义的dockerFile名称 .

我们本身已经在dockerFile目录下,向着目标位置进行build生成我们自定义的image
在这里插入图片描述

 docker build -f dockerFile -t centosbycc:1.0 .

构建成功
在这里插入图片描述
看一下可以支配的镜像
在这里插入图片描述

Docker File基础

基础知识:

  • 1、每个保留关键字(指令)都是必须是大写字母
  • 2、执行从上到下顺序
  • 3、# 表示注释
  • 4、每一个指令都会创建提交一个新的镜像曾,并提交!
    dockerFile build完run起来就有这些东西
    在这里插入图片描述
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成企业交付的标准,必须要掌握!

DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。
Docker容器:容器就是镜像运行起来提供服务。
# DockerFile常用指令 
FROM # 基础镜像,一切从这里开始构建 
MAINTAINER # 镜像是谁写的, 姓名+邮箱 
RUN # 镜像构建的时候需要运行的命令 
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录 
VOLUME # 挂载的目录 
EXPOSE # 保留端口配置 
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。 
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指 令。
COPY # 类似ADD,将我们文件拷贝到镜像中 ENV # 构建的时候设置环境变量!

手写一个DockerFile并运行

创建一个dockerFile文件

docker build -f dockerFileCentos -t mycentos:1.0 .

vim myDockerFIle/dockerFileCentos

== 提一个知识点,就是docker的centos里面,是极简版的,没有命令,想要用命令就得自己yum拉取命令,例如之前的/bin/bash 就是带着命令进行操作==
dockerFile内容

FROM centos:7 # 基础镜像,一般其他的镜像的开头是FROM scarth,代表一个普通开始,:7代表下载centos7,下载8的话就容易无法联网,第一行是不可以写注释的!
MAINTAINER cc<123456@qq.com> # 标注制作人名称和联系邮箱

ENV MYPATH /usr/local # 设置一个叫MYPATH的环境路径
WORKDIR $MYPATH # 将MYPATH路径设置为镜像的工作路径

RUN yum -y install vim     # yum一个vim编辑器
RUN yum -y install net-tools # yum ip等等命令

EXPOSE 80 # 对外暴露80端口

CMD echo $MYPATH # 输出工作路径
CMD echo "-----end----" # 输出结束
CMD /bin/bash
通过这个文件构建镜像
 docker build -f 文件路径 -t 镜像名:[tag] .

在dockerFile目录下运行

 docker build -f dockerFileCentos -t mycentos:1.0 .

遇到个坑Error response from daemon: dockerfile parse error line 1: FROM requires either one or three arguments
问题来自于FROM 基础镜像 的第一个注释,会被认为是评论!
我们把第一行注释删掉

这里注释只做演示使用,实际跑起来强烈建议删掉避免不必要的麻烦
在这里插入图片描述

构建成功。太长了,没截完
在这里插入图片描述
查看一下镜像

docker images

在这里插入图片描述
构建好了就可以push到dockerHub之类的,但这就都是后话了

CMD 和 ENTRYPOINT区别

CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替 代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令

偷个懒CMD 和 ENTRYPOINT区别

10.Tomcat部署实战

准备两个tar安装文件,还有一个DockerFile
在这里插入图片描述

编写DockerFile

FROM centos:7
MAINTAINER cc<123456@qq.com>

COPY README /usr/local/README

ADD apache-tomcat-9.0.63.tar.gz /usr/local/
ADD jdk-11.0.13_linux-x64_bin.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local #定义一个MYPATH的路径,以便后面调用

WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk-11.0.13_linux-x64_bin #设置环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.63
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 # 设置默认命令

构建镜像,最后那个点是当前路径下进行构建。

 docker build -f tomcatCc -t tomcatcc:1.0 .

在这里插入图片描述
看一下docker镜像

docker images

在这里插入图片描述

跑起来!
-v是一些运行参数

docker run -d -p 8080:8080 --name tomcatcc -v

/bin/bash是引入命令

 docker run -it b69b758cad01 /bin/bash

运行结果(偷来的),可以看到都编排成功了

[root@iZ1608aqb7ntn9Z 20210806]# vim DockerFile2
# -----------写入文件--------------

FROM centos
  
COPY ymx /opt/Docker/20210806/ymx

ADD jdk8.tar.gz /usr/local
ADD tomcat.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_141
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin

EXPOSE 8080

# -----------写入文件完成--------------
[root@iZ1608aqb7ntn9Z 20210806]# ls
Dockerfile  DockerFile2  ymx
[root@iZ1608aqb7ntn9Z 20210806]# cp /tmp/jdk8.tar.gz jdk8.tar.gz
[root@iZ1608aqb7ntn9Z 20210806]# cp /tmp/tomcat.tar.gz tomcat.tar.gz
[root@iZ1608aqb7ntn9Z 20210806]# ls
Dockerfile  DockerFile2  jdk8.tar.gz  tomcat.tar.gz  ymx
[root@iZ1608aqb7ntn9Z 20210806]# docker build -f ./DockerFile2 -t mytomcat9 . 
Sending build context to Docker daemon    197MB
Step 1/11 : FROM centos
......
Successfully built 86a9a8dd939a
Successfully tagged mytomcat9:latest
[root@iZ1608aqb7ntn9Z 20210806]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED             SIZE
mytomcat9             latest    86a9a8dd939a   26 seconds ago      667MB
......
[root@iZ1608aqb7ntn9Z 20210806]# docker run -it mytomcat9 /bin/bash
[root@ed5fd71834e2 local]# ls
apache-tomcat-9.0.44  bin  etc  games  include  jdk1.8.0_141  lib  lib64  libexec  sbin  share  src
[root@ed5fd71834e2 local]# java -version
java version "1.8.0_141"
Java(TM) SE Runtime Environment (build 1.8.0_141-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.141-b15, mixed mode)

Push到远程服务器(DockerHub 阿里云)

DockerHub的Push方法

必须注册账号,不注册不行
https://hub.docker.com/

docker login -u 账户 # 回车之后会显示输入密码
password:密码

在这里插入图片描述
提交镜像

docker push 镜像名:版本号

在这里插入图片描述
在这里插入图片描述
这里我们选择第二种

先改tag版本号
docker tag 容器id 用户名/tomcatcc:2.0
再进行push
docker push 用户名/tomcatcc:2.0

push成功
在这里插入图片描述

阿里云的Push方法

看官网 很详细https://cr.console.aliyun.com/repository/

$ sudo docker login --username=zchengx registry.cn-shenzhen.aliyuncs.com 
$ sudo docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/dsadxzc/cheng:[镜像 版本号] 
 # 修改id 和 版本 sudo docker tag a5ef1f32aaae registry.cn-shenzhen.aliyuncs.com/dsadxzc/cheng:1.0 # 修改版本 
$ sudo docker push registry.cn-shenzhen.aliyuncs.com/dsadxzc/cheng:[镜像版本号]

总结Docker流程

在这里插入图片描述

11.Docker网络

理解Docker0

查看一下本机的ip

ip addr

在这里插入图片描述
跑一个Tomcat镜像看一下它里面的ip

docker run tomcatId

启动之后,在回到Linux里查看ip
可以发现

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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
=======================docker网卡以及docker分配的地址===========================
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:0b:db:58 brd ff:ff:ff:ff:ff:ff
    inet 172.23.22.131/20 brd 172.23.31.255 scope global dynamic eth0
       valid_lft 307272014sec preferred_lft 307272014sec
    inet6 fe80::216:3eff:fe0b:db58/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:9b:b8:a2:d4 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:9bff:feb8:a2d4/64 scope link 
       valid_lft forever preferred_lft forever
29: veth666f0e9@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:87:48:4a:b2:b1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::87:48ff:fe4a:b2b1/64 scope link 
       valid_lft forever preferred_lft forever

我们再次进入容器内部,查看一下容器内的地址
可以看到,docker内部也是会有地址的
在这里插入图片描述

那么容器与Linux通信的话是否可以ping通?
答案是可以的
在这里插入图片描述

容器与容器之间都是Docker内部随便连接,随便ping都能通,但是这个ping不是真ping,是先ping到linux的路由上,再经路由表转发到目标的容器上

在这里插入图片描述
结论:tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用 ip

那docker和linux,镜像与镜像连接是怎么做到的呢
就是veth-pair技术

veth-pair技术

我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker, 就会有一个docker0桥接模式,使用的技术是veth-pair技术!
Linux网卡科普
在这里插入图片描述
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件,速度和你带宽一致)
只要容器删除,对应的网桥一对就没了!
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可
以处理这个问题,可以通过名字来进行访问容器?类似cloud的Feign通过名字调用

容器互联–Link

先测试一下两个镜像之间用容器名字来ping看看是否能成功

docker exec -it Tomcat01 ping Tomcat02

在这里插入图片描述
怎么解决呢?只能用–Link来进行指定的名字和名字的连接
运行一个Tomcat03来指定和Tomcat02来连接

docker run -d -P --name tomcat03 --link tomcat02 tomcat

这样是可以ping通的
在这里插入图片描述
在这里插入图片描述
但是这种玩法有坑,反向ping有概率ping不通
为什么?
因为反向ping没有绑定目标的容器
在这里插入图片描述

容器互联自定义网络(常用)

查看一下docker网络
在这里插入图片描述
因为docker0,默认情况下不能通过容器名进行访问。需要通过–link进行设置连接。这样的操作比较麻烦,更推荐的方式是自定义网络,容器都使用该自定义网络,就可以实现通过容器名来互相访问了。
下面查看network的相关命令

docker network --help

在这里插入图片描述
注意那个inspect的选项,我们借助这个选项来查看一下网桥bridge

docker network inspect bridge

网桥中的详细信息
在这里插入图片描述
以上都是docker给你创建的,那么这个时候我们自己创建一个自定义的网络
查看 network create命令的相关参数

docker network help

在这里插入图片描述
下面自定义一个网络

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

具体参数说明:

--driver bridge   #指定bridge驱动程序来管理网络
--subnet 192.168.0.0/16 #指定网段的CIDR格式的子网(规定子网号)
--gateway 192.168.0.1 	#指定主子网的IPv4或IPv6网关
最后挂上自己自定义的名字

创建成功在这里插入图片描述
此时再看看网络信息:docker network inspect 自定义的网桥名

 docker network inspect mynet

可以看到我们自定义的网络ip已经上来了
在这里插入图片描述

用自定义网络跑容器

用自定义的网络启动两个tomcat,再查看一下网络状态

[root@iZ8vb4qrjoahmfuzp7tlbhZ ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat 
d77f23b808889613e2e4e9c6f12b109f78316ad1909a2d9a17780bbdfd806592
[root@iZ8vb4qrjoahmfuzp7tlbhZ ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat 
75c10009eb39f40922cf16c9d9087562561f85e5925819b4d6128bc3922d91d2
[root@iZ8vb4qrjoahmfuzp7tlbhZ ~]# docker network inspect mynet

在这里插入图片描述
ping测试一下,正向连接和反向连接都试试,都是可以连通的
在这里插入图片描述
可以发现,在我们的自定义网络下,容器之间既可以通过容器名也可以通过ip地址进行网络通信。 我们自定义的网络默认已经帮我们维护了容器间的网络通信问题,这是实现网络互联的推荐方式。

Docker网络之间的互联

两个不同的网桥下,想这么连接,是不可以的,连不上
没有设置的情况下,不同网络间的容器是无法进行网络连接的。如图,两个不同的网络docker0和自定义网络mynet的网络模型图:
在这里插入图片描述
在默认网络bridge下启动容器tomcat-01,尝试连接mynet网络下的tomcat-net-01容器。
在这里插入图片描述
可以看到是无法网络连接的。不同Docker网络之间的容器需要连接的话需要把作为调用方的容器注册一个ip到被调用方所在的网络上。需要使用

docker connect命令

下面设置容器tomcat-01连接到mynet网络上。并查看mynet的网络详情,可以看到给容器tomcat-01分配了一个ip地址。

docker network connect 定定义的网桥号 目标容器名称
docker network connect mynet tomcat-01

在这里插入图片描述

设置完成后我们就可以实现不同网络之间的容器互联了。
在这里插入图片描述

12.实战

Redis集群部署

集群Redis架构图
在这里插入图片描述
一旦主机挂掉了,那么从机就变成主机顶上去
在这里插入图片描述
为Redis专门创建一个网卡

docker network create redis --subnet 172.38.0.0/16

通过脚本创建六个redis配置
这里用了一个for循环来实现六个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

粘贴完毕回车就可以运行
在这里插入图片描述

创建完配置文件就要开始运行
通过脚本运行六个redis
下面启动6个Redis容器,设置对应的容器数据卷挂载

#第1个Redis容器
docker run -p 6371:6379 -p 16371: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 redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第2个Redis容器
docker run -p 6372:6379 -p 16372: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 redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第3个Redis容器
docker run -p 6373:6379 -p 16373: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 redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第4个Redis容器
docker run -p 6374:6379 -p 16374: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 redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第5个Redis容器
docker run -p 6375:6379 -p 16375: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 redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#第6个Redis容器
docker run -p 6376:6379 -p 16376: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 redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

或者用脚本一次性启动6个也可以

for port in $(seq 1 6); \
do
docker run -p 637${port}:6379 -p 1637${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 redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done

启动完成
在这里插入图片描述
此时进入redis1容器设置一下创建集群
由于redis内部本身并没有bash命令所以要以sh命令运行

docker exec -it redis-1 /bin/sh #redis默认没有bash

在这里插入图片描述
设置负载均衡

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

在这里插入图片描述
构建完成
在这里插入图片描述
进入redis

redis-cli -c

在这里插入图片描述
查看节点信息cluster nodes,可以清楚的看到Redis节点的主从关系。
在这里插入图片描述
因为我们是主从的架构,所以我们停掉一个主机,来看看从机能不能顶上来
停掉三号机
在这里插入图片描述
在这里插入图片描述
稍等一下redis完成选举机制,推选出最新的主机
再次进入redis,可以看到,查询之前的信息也是可以查到的,实现了高可用的目的
在这里插入图片描述

分布式SpringBoot项目打包镜像

如果要打包SpringBoot,那我先得有一个SpringBoot项目吧,新建一个项目然后写一个Controller层
在这里插入图片描述
在这里插入图片描述
先在本地测一下,没毛病,好用
在这里插入图片描述
mvn package打包起来,同级目录下创建Dockerfile
在这里插入图片描述
Dockerfile内容

FROM java:8             #以java8为基础版本

COPY *.jar /app.jar  # 从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

CMD ["--------server.port:8080---------"] # 输出

EXPOSE 8080		# 设置端口号

ENTRYPOINT ["java","-jar","app.jar"] # 自动运行java -jar jar包的命令

把jar包和Dockerfile上传到服务器中,注意创建的时候,名字最好是Dockerfile,不要其他的容易构建的时候报错
在这里插入图片描述在这里插入图片描述
直接构建!
在这里插入图片描述
查看镜像,跑起来就好了,最后测试
在这里插入图片描述
因为80端口我有个项目被占用了,这里就改别的端口号:容器映射来进行访问(后台运行)

docker run -d -p 12138:8080 ccdocker 

在这里插入图片描述
各位江湖再见啦~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值