Docker
视频推荐这个up主的https://www.bilibili.com/video/BV1og4y1q7M4/?p=40
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口
为什么会出现Docker?(why)
一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心许多东西,这也是很多互联网公司不得不面对的问题,特别是各个版本迭代之后,不同版本环境的兼容,对运维人员都是考验。 环境配置十分麻烦,每一个机器都要部署环境(集群Redis,Es,Mysql…),很费时费力,能不能从根本解决问题?项目能不能带上环境打包那?上线时可不可以把原始的环境一模一样的复制过来?
答案是可以的:
Docker可以将能运行一个应用程序的所有环境及配置一起打包,形成一个镜像。将这个镜像通过docker复制到另一台机器上,那么这台机器也就具有了原始机器上的环境和配置。那么这个应用程序直接运行即可。
docker通过隔离机制,可以将服务器利用到极致!
Docker容器虚拟化对比传统虚拟机
Docker容器虚拟化对比传统虚拟机
传统虚拟机:资源占用十分多,冗余步骤多,启动慢…
容器化:容器化技术不是模拟的一个完整的操作系统,容器内的应用是直接运行在宿主机的内核中,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
传统虚拟机 | Docker容器 | |
---|---|---|
磁盘占用 | 几个GB到几十个GB左右 | 几十MB到几百MB左右 |
CPU内存占用 | 虚拟操作系统非常占用CPU和内存 | Docker引擎占用极低 |
启动速度 | (从开机到运行项目)几分钟 | (从开启容器到运行项目)几秒 |
安装管理 | 需要专门的运维技术 | 安装、管理方便 |
应用部署 | 每次部署都费时费力 | 从第二次部署开始轻松简捷 |
耦合性 | 多个应用服务安装到一起,容易互相影响 | 每个应用服务一个容器,达成隔离 |
系统依赖 | 无 | 需求相同或相似的内核,目前推荐是Linux |
Docker三大要素
-
镜像(image):一台机器上打包好的应用程序和其依赖的环境配置。镜像可以创建容器,相当于模板,一个镜像可以创建多个容器
-
容器(container):Docker利用容器独立运行一个或一组应用。容器是由镜像创建的运行实例。
-
仓库(repository):仓库是集中存放镜像的地方。类似Maven的中心仓库,或者github一样。DockerHub
Docker的安装
帮助文档:
1.卸载旧版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2.安装yum-utils软件包
$ sudo yum install -y yum-utils
3.设置稳定的存储库。
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #默认是境外的,就是下面那个
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #推荐使用阿里云的
4.安装最新版本的 docker社区版(Docker CE)
$ yum install -y docker-ce docker-ce-cli containerd.io
更新软件包索引
$ yum makecache fast
5.启动docker
$ systemctl start docker
$ systemctl enable docker #设置开机自启动
使用docker version查看是否成功
6.通过运行 hello-world 镜像验证是否正确安装了Docker CE 。
$ docker run hello-world
卸载docker
1、卸载Docker Engine,CLI和Containerd软件包:
$ sudo yum remove docker-ce docker-ce-cli containerd.io
2、主机上的映像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷:
$ sudo rm -rf /var/lib/docker
配置镜像加速器
配置阿里云镜像加速器可使效率达到更高
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://5dmdrc8c.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Run的流程和Docker原理
Run的流程
Docker底层原理
Docker是一个Client - server 结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!
DockerServer 接收到 Docker-Client的指令,就会执行这个命令!
Docker为什么比VM快?
1、docker有着比虚拟机少的抽象层
2、docker利用的是宿主机的内核,VM需要是 Guest OS
新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,
虚拟机是加载 Guest OS,分钟级别的,而docker是利用 宿主机的操作系统,省略了这个复杂的过程,秒级的!
Docker的常用命令
辅助命令
$ docker version #显示 Docker 版本信息。
$ docker info #显示 Docker 系统信息,包括镜像和容器数。
$ docker --help #帮助命令
镜像命令
1.查看镜像信息
$ docker images [options] #列出本地所有镜像
-a #列出所有镜像(包含中间映像层)
-q #只显示镜像id
--digests #显示镜像摘要信息
--no-trunc #不截断输出(默认截断过长的列) 完整展示
参数说明:
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
2.搜索镜像
$ docker search [options] 镜像名 #去dockerhub上查询当前镜像
-s 指定值 #列出收藏数不少于指定值的镜像
--no-trunc #不截断输出(默认截断过长的列) 完整展示
参数说明:
NAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
OFFICIAL: 是否 docker 官方发布
STSRS: 类似 Github 里面的 star,表示点赞、喜欢的意思。
AUTOMATED: 自动构建。
--filter=STARS=3000 #搜索出来的镜像 stars大于30000的 就是收藏大于30000的
3.下载镜像
$ docker pull 镜像名
$ docker pull 镜像名:版本 #不指定版本 默认最新版本
4.删除镜像
$ docker rmi 镜像名:版本 #未指定版本删除最新版本 也可以使用id删除
-f #强制删除
$ docker rmi -f $(docker images -aq) #删除全部
容器命令
1.运行容器
$ docker run [OPTIONS] 镜像名 [cmd] #镜像名新建并启动容器
-i #以交互模式运行容器,通常与-t同时使用
-t #为容器重新分配一个伪终端,通常与-i同时使用
--name 别名 #为容器指定一个名字
-d #启动守护式容器(在后台启动容器),并返回容器ID
-p 映射端口号:原始端口号 #指定端口号启动,指定端口映射
-P #主机自动分配端口号,随机端口映射
--rm #当容器停止自动移除
例:$ docker run -it --name myTomcat -p 8888:8080 tomcat
$ docker run -d --name myTomcat -P tomcat
注意:
#如果启动报以下错误:
docker: Error response from daemon: driver failed programming external connectivity on endpoint myTomcaaa (1148dccd5673fab421495087d352adc5428ab6ab7cf9f3fd708b662a25d92641): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 32807 -j DNAT --to-destination 172.17.0.5:8080 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1)).
#原因:
#docker服务启动时定义的自定义链DOCKER由于某种原因被清掉
#重启docker服务及可重新生成自定义链DOCKER
#解决:
#重启docker服务后再启动容器
systemctl restart docker
docker start foo
2.退出容器
$ exit #容器停止退出
$ Ctrl+p+q #容器不停止退出
3.查看运行的容器
$ docker ps #列出所有正在运行的容器
-a #显示所有的容器,包括未运行的。
-l #显示最近创建的一个容器
-n 数值 #显示最近n个创建的容器
-q #静默模式,只显示容器编号
--no-trunc #不截断输出(默认截断过长的列) 完整展示
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
- created(已创建)
- restarting(重启中)
- running(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称
4.删除容器
$ docker rm 容器名字/容器id #删除容器
$ docker rm -f 容器名字/容器id #删除正在运行的容器
$ docker rm -f $(docker ps -aq) #删除所有容器
5.启动容器
$ docker start 容器名字/容器id #开启容器
$ docker restart 容器名字/容器id #重启容器
6.停止容器
$ docker stop 容器名字/容器id #正常停止容器运行
$ docker kill 容器名字/容器id #立即停止容器运行
7.查看容器日志
$ docker logs [OPTIONS] 容器名字/容器id
-t #加入时间
-f #跟随最新的日志打印
--tail 数字 #显示最后多少条
8.查看容器内的进程
$ docker top 容器名字/容器id
9.查看容器内部细节
$ docker inspect 容器名字/容器id
10.进入容器
$ docker exec [options] 容器名字/容器id 容器内命令 #进入容器后开启一个新的终端
-i #以交互模式运行容器,通常与-t一起使用
-t #分配一个伪终端
eg:
docker exec -it centoss ls
docker exec -it mytomcat /bin/bash
$ docker attach 容器名字/容器id #进入容器正在执行的终端,不会启动新的进程!
11.拷贝
$ docker cp 容器名字/容器id:容器内资源路径 宿主机目录路径 #将容器内资源拷贝到主机上
eg:
[root@localhost~]docker cp centoss:/aaa.txt /root/
$ docker cp 宿主机目录路径 容器名字/容器id:容器内资源路径 #将宿主机内资源拷贝到容器
eg:
[root@localhost~]docker cp /root/bbb.txt centoss:/
宿主机:Docker安装在哪谁就是宿主机 centos
容器:在Docker种根据镜像启动的就是容器 centos容器
12.把一个容器副本打包镜像
$ docker commit -a="作者" -m="描述信息" 容器ID 目标镜像名称:TAG
例:docker commit -a="nan" -m="witout docs" b35d35f72b8d mytomcat:1.2
1.从dockerHub上下载tomcat镜像到本地并成功运行
2.删除上一步镜像产生的容器的doc目录
3.以当前没有doc目录的tomcat为模板commit生成一个新的镜像
4.启动新的镜像并和原来的对比
安装练习
安装Nginx
[root@VM-0-11-centos home]# docker search nginx 搜索镜像,建议去docker官网搜索,可以看到详细信息和帮助文档
[root@VM-0-11-centos home]# docker pull nginx 下载镜像
[root@VM-0-11-centos home]# docker run -d --name nginx1 -p 3344:80 nginx 启动nginx -d后台运行 --name给容器起别名 -p 宿主机端口:容器端口
[root@VM-0-11-centos home]# curl localhost:3344 本机自测 出现Welcome to nginx!
[root@VM-0-11-centos home]# docker exec -it nginx1 /bin/bash 进入容器
如果你是在云服务器上操作的,并且可以访问需要执行以下几步
[root@VM-0-11-centos ~]# service firewalld start 开启防火墙
Redirecting to /bin/systemctl start firewalld.service
[root@VM-0-11-centos ~]# firewall-cmd --zone=public --add-port=3344/tcp --permanent 开启安全组端口3344
success
[root@VM-0-11-centos ~]# systemctl restart firewalld.service 重启防火墙
端口暴露的概念
安装tomcat
[root@VM-0-11-centos home]# docker pull tomcat 下载tomcat
[root@VM-0-11-centos home]# docker images
[root@VM-0-11-centos ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat 启动tomcat 现在访问服务器3355会报404,因为tomcat不是完整的
[root@VM-0-11-centos ~]# docker exec -it tomcat01 /bin/bash 进入容器 你发现ls命令都用不了
此时发现两个问题:
1、liunx命令少了
2、webapps是空的
是云服务器的原因,默认是最小的镜像,所有的不必要的都剔除掉
只保证最小可运行的环境
root@0cef063938ad:/usr/local/tomcat# ls #发现tomcat下有webapps.dist webapps的输出目录
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@0cef063938ad:/usr/local/tomcat# cd webapps.dist/ #cd到webapps.dist
root@0cef063938ad:/usr/local/tomcat/webapps.dist# ls # root在webapps.dist中
ROOT docs examples host-manager manager
root@0cef063938ad:/usr/local/tomcat/webapps.dist# cd .. # cd到tomcat
root@0cef063938ad:/usr/local/tomcat# cp -r webapps.dist/* webapps # 把webapps.dist的所用文件拷贝到webapps中
root@0cef063938ad:/usr/local/tomcat# cd webapps
root@0cef063938ad:/usr/local/tomcat/webapps# ls # 拷贝成功,现在就可以访问成功了
ROOT docs examples host-manager manager
root@0cef063938ad:/usr/local/tomcat/webapps#
部署es+kibana
问题一 : es暴露的端口很多
问题二 :es十分耗内存
问题三 :es的数据一般放置到安全目录!
$ docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 下载启动es
[root@VM-0-11-centos ~]# docker ps 此时会很耗内存,可能会卡一点
[root@VM-0-11-centos home]# curl localhost:9200 访问9200端口 会出现You Know, for Search
[root@VM-0-11-centos home]# docker stats 查看内存 这个时候发现es站的内存是非常大的,我是1核2g的服务器,es占用了70%
[root@VM-0-11-centos home]# docker stop 907dc4d2455b 停止es
关闭es,增加内存的限制,修改配置文件 可以通过-e进行环境的修改 分配空间最小为64m,最大为512m
$ docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPS="-Xms64m -Xmx512m" elasticsearch:7.6.2
[root@VM-0-11-centos home]# docker ps
[root@VM-0-11-centos home]# docker stats 3d5b66c4af52
[root@VM-0-11-centos home]# curl localhost:9200
使用kibana连接es
portainer可视化面板安装
portainer是docker图形化管理工具,提供䘝后台面板供我们操作!
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer 下载
访问测试:外网:8088 要把云服务器的安全组8088端口打开
Docker镜像
镜像是什么?
镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。
UnionFS(联合文件系统)
Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像实际是由一层一层的文件系统组成。 这种层级的文件系统叫UnionFS.
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。在docker镜像的最底层就是bootfs。这一层与Linux/Unix系统是一样的,包含boot加载器(bootloader)和内核(kernel)。当boot加载完后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时会卸载bootfs。
rootfs(root filesystem),在bootfs之上,包含的就是典型的linux系统中的/dev,/proc,/bin,/etc等标准的目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu/CentOS等等。
我们平时安装进虚拟机的centos都有1到几个GB,为什么docker这里才200MB?对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令,工具,和程序库就可以了,因为底层直接使用Host的Kernal,自己只需要提供rootfs就行了。由此可见不同的linux发行版,他们的bootfs是一致的,rootfs会有差别。因此不同的发行版可以共用bootfs。
linux :centos6 centos7 macos unbatu
为什么docker镜像要采用这种分层结构呢?
最大的一个好处就是资源共享。比如:有多个镜像都是从相同的base镜像构建而来的,那么宿主机只需在磁盘中保存一份base镜像。同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
特点:Docker镜像都是只读的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为容器层,容器层之下都叫镜像层。
commit镜像
docker commit 提交容器成为一个新的镜像
$ docker commit -a=“作者” -m=“描述信息” 容器ID 目标镜像名称:TAG
默认的tomcat是没有webapps应用的,是镜像的原因,官方的惊醒默认 webapps下面是没有文件的!
我们拷贝进去了基础的文件,可以再把它打包成一个新的镜像!
[root@VM-0-11-centos home]# docker run -d -p 8080:8080 tomcat 启动
[root@VM-0-11-centos home]# docker exec -it c39fbddd6bb39fc099b43d484e0062ad8f900a6a854e32d156e683f03c703707 /bin/bash 进入tomcat
root@c39fbddd6bb3:/usr/local/tomcat# cp -r webapps.dist/* webapps # 把webapps.dist的所用文件拷贝到webapps中
root@c39fbddd6bb3:/usr/local/tomcat/webapps# exit
[root@VM-0-11-centos home]# docker ps
[root@VM-0-11-centos home]# docker commit -a="zhangsan" -m="add webapps app" c39fbddd6bb3 tomcat1:1.0 打包成镜像
[root@VM-0-11-centos home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat1 1.0 c68cf1b31ea6 54 seconds ago 653MB 新的镜像
tomcat latest 2703bbe9e9d4 35 hours ago 648MB 旧的镜像
Docker容器数据卷
什么是容器数据卷
简单来说就是做数据持久化的。类似磁带,移动硬盘或者U盘。或者类似Redis中的rdb和aof文件。主要做容器数据的持久化和容器之间数据共享。
卷就是目录或者文件,存在一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过UnionFile System提供一些用于持久储存或者共享数据的特性。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。
数据卷的特点
1、数据卷可在容器之间共享或重用数据。
2、卷中的更改可以直接生效。
3、数据卷中的更改不会包含在镜像的更新中。
4、数据卷的生命周期一直持续到没有容器使用它为止。
5、数据卷也可以完成主机到容器或容器到主机之间的数据共享。
-v命令添加数据卷
容器内添加数据卷有两种办法。
第一种直接命令添加。
第二种是用DockerFile添加。
命令添加
1.添加
命令:docker run -it -v /宿主机的路径:/容器内的路径 镜像名
例:
docker run -it -v /home/ceshi:/home centos /bin/bash 将容器里面的home目录,挂载到linux的home/ceshi目录
2.查看数据卷是否挂成功
运行 docker inspect 容器id 命令 检查json串里有没有以下内容,如果有则证明卷挂载成功。
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi", 主机的地址
"Destination": "/home", 容器内的地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
3.设置容器内数据卷只读、只写
命令:docker run -it -v /主机路径:/容器内路径:ro 镜像名
例子:docker run -it -v /hostDataValueme:/containerDataValueme:ro centos #只读,只能通过宿主机来操作,容器内是无法操作的!
docker run -it -v /hostDataValueme:/containerDataValueme:rw centos #只写
4.查看配置文件
"Mounts": [
{
"Type": "bind",
"Source": "/hostDataValueme",
"Destination": "/containerDataValueme",
"Mode": "ro", #只读
"RW": false,
"Propagation": "rprivate"
}
],
完整测试:
[root@VM-0-11-centos ~]# docker run -it -v /home/ceshi:/home centos /bin/bash 将容器里面的home目录,挂载到linux的home/ceshi目录
[root@VM-0-11-centos ~]# docker inspect f88768ef 复制个窗口,在容器外面执行,查看有没有挂载成功
容器与主机是可以共享资源的。容器关闭之后,再开启容器之后也可以读取并加载主机的卷中数据!
实战:mysql同步数据
问题:mysql持久化的问题! mysql下有个data目录,所有的数据都放在data目录下面。
[root@VM-0-11-centos ~]# docker pull mysql:5.7 获取镜像
# 运行容器,需要做数据挂载!
# 安装启动mysql的时候,需要配置密码的
#
-d 后台运行
-p 端口映射
-v 数据卷挂载 这里挂载了俩个目录
-e 环境配置
--name 给容器起别名
[root@VM-0-11-centos home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name myslq01 mysql:5.7
# 启动成功后,zaibendi使用navicat连接测试!
# navicat连接到服务器的3310,3310和容器3306映射,这时就可以连接上了!
当我们把容器删除,挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!
具名挂载和匿名股挂载
# 匿名挂载
-v 容器内路径
[root@VM-0-11-centos home]# docker run -d -P --name nginx01 -v /ect/nginx nginx
5553fc0ddba8b71d38c08ba2496ffe5bb03a2c4092767ee47af6172e04d3a915
[root@VM-0-11-centos home]# docker volume ls 查看所有的volume 的情况
DRIVER VOLUME NAME
local 4c78507dd476688b41791470be4daeb25a88a62a6e08b3b9e37758248741b14f 每一个路径。都是真实存在的目录
local 09a462c8b5582512609b88840f2016eccfba3b1729925a7c0aed921c8ebb067c
[root@VM-0-11-centos home]#
这就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!
# 具名挂载 这里-v 的不是一个目录,而是一个名字,
[root@VM-0-11-centos home]# docker run -d -P --name nginx02 -v juming_nginx:/etc/nginx nginx
2349a1bb9c643ae22410d3cf5356ab62b64f7a2e4356fb566fcfa5527733fa4b
[root@VM-0-11-centos home]# docker volume ls
DRIVER VOLUME NAME
local 4c78507dd476688b41791470be4daeb25a88a62a6e08b3b9e37758248741b14f
local 09a462c8b5582512609b88840f2016eccfba3b1729925a7c0aed921c8ebb067c
local juming_nginx 这里就是具名
通过 -v 卷名 :容器内路径
查看一下这个卷
[root@VM-0-11-centos home]# docker volume inspect juming_nginx 查看卷的具体位置
[
{
"CreatedAt": "2020-11-14T11:15:42+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/xxx/_data
通过具名挂载可以方便的找到我们的卷,通常使用具名挂载
如何确定是具名挂载和匿名挂载,还是指定路径挂载?
-v 容器内的路径 #匿名挂载
-v 卷名:容器内路径 #具明挂载
-v /宿主机路径:容器内路径 #指定路径下载
DockerFile添加数据卷
Dockerfile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本。
通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
[root@VM-0-11-centos home]# mkdir docker-test-volume
[root@VM-0-11-centos home]# cd docker-test-volume/
[root@VM-0-11-centos docker-test-volume]# pwd
/home/docker-test-volume
[root@VM-0-11-centos docker-test-volume]# vim dockerfile1 创建并编辑douckerfile1文件
然后编写文件中的内容 指令(大写)和参数
FROM centos 当前镜像是基于哪个镜像的
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
[root@VM-0-11-centos docker-test-volume]# docker build -f dockerfile1 -t zhangsan/centos:1.0 . 生成镜像
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 0d120b6ccaa8
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in 9360ba58b4f6
Removing intermediate container 9360ba58b4f6
---> 1f7c9b7edb16
Step 3/4 : CMD echo "---end---"
---> Running in 177c6e8d1819
Removing intermediate container 177c6e8d1819
---> d627236d5571
Step 4/4 : CMD /bin/bash
---> Running in 4d504a580f5f
Removing intermediate container 4d504a580f5f
---> 59d7cce14aa4
Successfully built 59d7cce14aa4
Successfully tagged zhangsan/centos:1.0
[root@VM-0-11-centos docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zhangsan/centos 1.0 59d7cce14aa4 About a minute ago 215MB 自己生成的镜像
tomcat1 1.0 c68cf1b31ea6 13 hours ago 653MB
<none> <none> 502b4ac77c81 13 hours ago 653MB
tomcat latest 2703bbe9e9d4 2 days ago 648MB
nginx latest c39a868aad02 8 days ago 133MB
redis latest 62f1d3402b78 2 weeks ago 104MB
mysql 5.7 1b12f2e9257b 3 weeks ago 448MB
centos latest 0d120b6ccaa8 3 months ago 215MB
portainer/portainer latest 62771b0b9b09 3 months ago 79.1MB
elasticsearch 7.6.2 f29a1ee41030 7 months ago 791MB
hello-world latest bf756fb1ae65 10 months ago 13.3kB
[root@VM-0-11-centos docker-test-volume]# docker run -it 59d7cce14aa4 /bin/bash 启动自己的镜像
[root@c2f90987509a /]#
这个卷和外部一定有一个同步的目录!
[root@c2f90987509a /]# cd volume01
[root@c2f90987509a volume01]# touch container.txt 在容器内部创建一个文件
[root@VM-0-11-centos home]# docker ps 复制一个窗口到容器外
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c2f90987509a 59d7cce14aa4 "/bin/bash" 11 minutes ago Up 11 minutes nervous_mclean
2349a1bb9c64 nginx "/docker-entrypoint.…" 55 minutes ago Up 55 minutes 0.0.0.0:32769->80/tcp nginx02
5553fc0ddba8 nginx "/docker-entrypoint.…" About an hour ago Up About an hour 0.0.0.0:32768->80/tcp nginx01
[root@VM-0-11-centos home]# docker inspect c2f90987509a 查看这个容器信息
查看一下挂载的路径
查看下是否同步了!这种方式用的很多,因为我们通常会构建自己的镜像!
假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径
[root@VM-0-11-centos home]# cd /var/lib/docker/volumes/08e6c893482dd872b8dc82889f4b2365599df6d32dc7e255cb62d84fc7671ee2/_data
[root@VM-0-11-centos _data]# ls
container.txt
[root@VM-0-11-centos _data]#
数据卷容器
# 启动3个容器,通过我们刚才自己写的镜像启动
[root@VM-0-11-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zhangsan/centos 1.0 59d7cce14aa4 3 hours ago 215MB
[root@VM-0-11-centos ~]# docker run -it --name docker01 zhangsan/centos:1.0 启动docker01
[root@47ecb4c885b9 /]# ls volume01和volume02为容器数据卷
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@47ecb4c885b9 /]#
crtl+p+q
[root@VM-0-11-centos ~]# docker run -it --name docker02 --volumes-from docker01 zhangsan/centos:1.0 通过--volumes-from绑定docker
[root@6993484338a7 /]# ls -l 这里也有volume01和volume02
复制会话 进入docker01容器
[root@VM-0-11-centos ~]# docker attach 47ecb4c885b9
[root@47ecb4c885b9 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@47ecb4c885b9 /]# cd volume01/
[root@47ecb4c885b9 volume01]# ls
[root@47ecb4c885b9 volume01]# touch docker01
[root@47ecb4c885b9 volume01]# ls
docker01
在docker02下查看:
[root@6993484338a7 /]#cd volume01
[root@6993484338a7 volume01]# ls
docker01 docker01的数据同步到docker02
[root@6993484338a7 volume01]#
在启动一个
[root@VM-0-11-centos ~]# docker run -it --name docker03 --volumes-from docker01 zhangsan/centos:1.0
[root@6208a03ca236 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@6208a03ca236 /]# cd volume01
[root@6208a03ca236 volume01]# ls
docker01
可以做到容器之间数据的同步
删除docker01后,docker02和docker03依旧可以访问这个文件
[root@47ecb4c885b9 volume01]# exit
exit
[root@VM-0-11-centos ~]# docker ps -a
[root@VM-0-11-centos ~]# docker rm -f 47ecb4c885b9
47ecb4c885b9
inspect发现他们用的都是宿主机下的同一个卷
多个mysql同步数据!
[root@VM-0-11-centos home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name myslq01 mysql:5.7
[root@VM-0-11-centos home]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
这个时候,可以实现两个容器数据同步
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止!
但是一旦你持久化到本地,这个时候,本地的数据是不会删除的!
DockerFile
DockerFile构建
Dockerfile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本。简单来说就是一个镜像的描述文件。
构建步骤
1.编写Dockerfile文件
2.docker build 创建镜像
3.docker run 运行容器
4.docer push 发布镜像(DockerHub、阿里云镜像仓库!)
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像,比如自己的镜像中有tomcat,jdk,mysql,redis等等
DockerFile构建过程
Dockerfile内容基础知识
1.每条保留字指令都必须为大写,且后面都要跟至少一个参数。
2.指令按照从上到下,顺序执行。
3.#表示注释。
4.每条指令都会创建一个新的镜像层,并对镜像进行提交。
docker是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
DockerFile:构建文件,定义了一切的步骤,好比源代码!
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务的
Dockerfile中的保留字指令
保留字 | 作用 |
---|---|
FROM | 当前镜像是基于哪个镜像的 (基础镜像) |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 容器构建时需要运行的指令 |
EXPOSE | 当前容器对外暴露出的端口号 |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包 |
COPY | 类似于ADD,拷贝文件和目录到镜像中 将从构建上下文目录中<原路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换 |
ENTRYPOINT | 指定一个容器启动时要运行的命令 ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及其参数,但ENTRYPOINT可以追加命令 |
ONBUILD | 当构建一个被继承的Dockerfile时运行命令,父镜像在被继承后父镜像的onbuild被触发 |
Dockerfile构建过程解析
1.Docker从基础镜像运行一个容器
2.执行一条命令并对容器进行修改
3.执行类似docker commit的操作提交一个新的镜像层
4.docker再基于刚提交的镜像运行一个新容器
5.执行dockerfile中的下一条指令直到所有指令都执行完毕
实战:构建自己的centos
DockerHub上的centos镜像默认落脚点是/,默认不支持vim。那么现在我们想自定义一个centos,改变其默认落脚点,让其支持vim。
[root@VM-0-11-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 0d120b6ccaa8 3 months ago 215MB
[root@VM-0-11-centos ~]# docker run -it centos
[root@3c349fee4362 /]# vim
bash: vim: command not found
[root@3c349fee4362 /]# ifconfig
bash: ifconfig: command not found
[root@VM-0-11-centos home]# mkdir dockerfile 创建dockerfile文件目录
[root@VM-0-11-centos home]# cd dockerfile/ cd doukerfile
[root@VM-0-11-centos dockerfile]# vim mydockerfile-centos
编写Dockerfile
FROM centos
MAINTAINER zhangsan<wyn3163@163.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 "build-------success"
CMD /bin/bash
构建镜像
-f dockerfile的文件路径
-t 镜像名:版本号
[root@VM-0-11-centos dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 .
运行容器
[root@VM-0-11-centos dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0 05bf9352a3e8 4 minutes ago 295MB
[root@VM-0-11-centos dockerfile]# docker run -it mycentos:1.0
[root@d51f1bba9774 local]# pwd 直接到了刚才设置的工作目录
/usr/local
[root@d51f1bba9774 local]# ifconfig 命令也是可以用的!
可以通过 docker history 镜像名/镜像id 命令 查看构建过程!
CMD和ENTRYPOINT的区别
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
EMTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
[root@VM-0-11-centos dockerfile]# vim dockerfile-cmd-test
编写dockerfile文件,保存
FROM centos
CMD ["ls","-a"]
[root@VM-0-11-centos dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest . 构建镜像
[root@VM-0-11-centos dockerfile]# docker run cdca1da2ef80 1、当执行run的时候会执行cmd的 ls -a命令(只有最后一个会生效)
[root@VM-0-11-centos dockerfile]# docker run cdca1da2ef80 ls -al 2、当执行这句话的时候 ls -al 会替换掉 ls -a
测试ENTRYPOINT
[root@VM-0-11-centos dockerfile]# vim dockerfile-entrypoint-test
编写dockerfile文件,保存
FROM centos
ENTRYPOINT ["ls","-a"]
[root@VM-0-11-centos dockerfile]# docker build -f dockerfile-entrypoint-test -t intrypointtest . 构建镜像
[root@VM-0-11-centos dockerfile]# docker run ab18395ce14a 1、当执行run的时候会执行entrypoint的 ls -a命令
[root@VM-0-11-centos dockerfile]# docker run ab18395ce14a -l 2、-l会追加到ls -a上去了,也就变成了ls -al了,而不会替换到ls -a 这就是与cmd的区别所在
实战:构建tomcat镜像
**1. 先创建/home/docekrfile/tomcat这个目录 **
将tomcat和jdk8的tar包放进此目录下
2. 编写Dockerfile,使用官方命令Dockerfile,build时会自动寻找这个文件,就不需要 -f 制定了
[root@VM-0-11-centos tomcat]# touch readme.txt
[root@VM-0-11-centos tomcat]# vim Dockerfile
FROM centos
MAINTAINER wyn<wyn3163@163.com>
#把宿主机当前上下文的read.txt拷贝进容器的/usr/local/路径下
COPY readme.txt /usr/local/readme.txt
#把tomcat和jdk的tar包拷贝到容器中
ADD ./apache-tomcat-9.0.22.tar.gz /usr/local/
ADD ./jdk-8u171-linux-x64.tar.gz /usr/local/
#安装vim编辑器
Run yum -y install vim
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java和tomcat的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh"]
# CMD ["/usr/local/apache-tomcat-9.0.22/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
3. 构建镜像
$ docker build -t mytomcat .
这里没写-f是因为如果在当前目录下并且file文件名为正统的Dockerfile 那么-f可以省略不写。
4. 运行容器
[root@VM-0-11-centos tomcat]# docker run -d -p 8888:8080 --name mytomcat01 -v /home/dockerfile/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/dockerfile/tomcat/logs:/usr/local/apache-tomcat-9.0.22/logs --privileged=true mytomcat
ca960643b19fd0982ded355597870e404c3265b5028a7632308efa2d7dbbd417
[root@VM-0-11-centos tomcat]# ls
apache-tomcat-9.0.22.tar.gz jdk-8u171-linux-x64.tar.gz readme.txt
Dockerfile logs test
[root@VM-0-11-centos tomcat]# docker exec -it ca960643b19 /bin/bash
[root@ca960643b19f local]# pwd
/usr/local
[root@ca960643b19f local]# ls
apache-tomcat-9.0.22 etc include lib libexec sbin src
bin games jdk1.8.0_171 lib64 readme.txt share
[root@ca960643b19f local]# cd apache-tomcat-9.0.22/
[root@ca960643b19f apache-tomcat-9.0.22]# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs webapps
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib temp work
[root@ca960643b19f apache-tomcat-9.0.22]#
进入容器外面 测试8888
[root@VM-0-11-centos tomcat]# curl localhost:8888 这时返回了首页
我们也用外网访问一下
4.发布项目(由于做了卷挂载,我们直接在本地编写项目就行)
这里只是创建在test下穿件一个WEB-INF/web.xml和index.jsp来当做一个项目
[root@VM-0-11-centos test]# mkdir WEB-INF
[root@VM-0-11-centos test]# cd WEB-INF/
[root@VM-0-11-centos WEB-INF]# vim web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
</web-app>
[root@VM-0-11-centos test]# cd ..
[root@VM-0-11-centos test]# vim index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello</title>
</head>
<body>
Hello World!<br/>
<%
out.println("你的 IP 地址 " + request.getRemoteAddr());
%>
</body>
</html>
发布镜像
发布镜像到DockerHub
1、在DockerHub上注册账号,登录
https://registry.hub.docker.com/
2、登录
先要登录自己的DockerHub
root@VM-0-11-centos tomcat]# docker login -u codeapes #1.登录用户名
Password: #2.输入自己的密码
Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
[root@VM-0-11-centos tomcat]# docker login -u codeapes
Password:
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 #3.登录成功
3、在服务器上提交自己的镜像
[root@VM-0-11-centos tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest f89c9387675a 11 hours ago 675MB
[root@VM-0-11-centos tomcat]# docker tag f89c9387675a codeapes/tomcat:1.0 修改镜像名和版本号
[root@VM-0-11-centos tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
codeapes/tomcat 1.0 f89c9387675a 11 hours ago 675MB
mytomcat latest f89c9387675a 11 hours ago 675MB
[root@VM-0-11-centos tomcat]# docker push codeapes/tomcat:1.0 提交到dockerhub,也是按镜像的层级来提交的
发布镜像到阿里云
1、登录阿里云,找到容器镜像服务,创建命名空间和镜像库
2、点击镜像名,会很清晰的告诉你操作指南,根据操作指南一步一步来
[root@VM-0-11-centos ~]# docker logout 先退出之前的
登录的时候注意,这个密码不是阿里云的登录密码,可以访问凭证中设置密码
[root@VM-0-11-centos tomcat]# docker login --username=3163223987@qq.com registry.cn-beijing.aliyuncs.com
Password: 输入密码
Error response from daemon: Get https://registry.cn-beijing.aliyuncs.com/v2/: unauthorized: authentication required
[root@VM-0-11-centos tomcat]# docker login --username=3163223987@qq.com registry.cn-beijing.aliyuncs.com
Password:
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 1.登录成功
2.这步给镜像生成一个版本号
[root@VM-0-11-centos tomcat]# docker tag f89c9387675a registry.cn-beijing.aliyuncs.com/codeapes/codeapes-test:1.0
3.push到阿里云
[root@VM-0-11-centos tomcat]# docker push registry.cn-beijing.aliyuncs.com/codeapes/codeapes-test:1.0
上传后,镜像版本中会出现版本信息,点击层信息,就可以看到每一层,来源于我们的Dockerfile
总结
Docker网络
清空所有环境,这是为了更好学习docker网路
[root@VM-0-11-centos tomcat]# docker rm -f $(docker ps -aq)
[root@VM-0-11-centos tomcat]# docker rm -f $(docker images -aq)
[root@VM-0-11-centos tomcat]# docker run -d -P --name tomcat01 tomcat
# 查看容器内部网路地址 ip addr
[root@VM-0-11-centos tomcat]# docker exec -it tomcat01 ip addr
liunx可以ping通容器内部
[root@VM-0-11-centos tomcat]# ping 172.17.0.2
原理
1、我们每安装一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,是桥接模式,使用的技术是veth-pair技术
2、这时在启动一个tomcat,ip addr 发现又会多出一对网卡!
[root@VM-0-11-centos tomcat]# docker run -d -P --name tomcat02 tomcat
[root@VM-0-11-centos tomcat]# ip addr
我们发现这个容器带来的网卡都是一对一对的
veth-pair 就是一对的续集设备接口,他们嗾使成对出现的,一端连接协议,一端彼此相连
正因为这个特性,veth-pair 充当了一个桥梁,连接各种虚拟网络设备的
3、测试下tomcat01和tomcat02是否可以ping通
启动tomcat02 ping tomcat01 ,是可以ping通的
[root@VM-0-11-centos tomcat]# docker exec -it tomcat02 ping 172.17.0.2
结论:tomcat01和tomcat02是公用的一个路由器,docker0.
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip,
小结
Docker使用的是liunx的桥接,宿主机中是一个Docker容器的网桥,也就是docker0
Docker中所有的网路接口都是虚拟的。虚拟的转效率高!
只要容器删除,对应网桥的一对就没有了!
容器互联 - -link(了解)
真实开发不建议使用- -lingk,- - 可以作为一个了解!后面会使用自定义网络,不使用dcoekr0!
docker0的问题:不支持容器名连接访问
当我们使用tomcat02 ping tomcat01,通过服务名ping是不通的
[root@VM-0-11-centos tomcat]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
通过--link联通 03和02的网络就联通了
[root@VM-0-11-centos tomcat]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
这时 03ping02 就通了
[root@VM-0-11-centos tomcat]# docker exec -it tomcat03 ping tomcat02
但是反向连接是ping不同的
[root@VM-0-11-centos tomcat]# docker exec -it tomcat02 ping tomcat03
[root@VM-0-11-centos tomcat]# docker network ls
NETWORK ID NAME DRIVER SCOPE
cc492e1930e6 bridge bridge local
943b4d6805ac host host local
22c0292e6932 none null local
[root@VM-0-11-centos tomcat]# docker network inspect cc492e1930e6 查看这个网卡里的内容
其实就是tomcat03在本地配置tomcat02!
查看 03 hosts 配置 ,它把tomcat02写进去了!
–link 就是我们在host 配置中 增加了一个17172.17.0.3 tomcat02 5686365551ec,就是tomcat02的映射,
[root@VM-0-11-centos tomcat]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 tomcat02 5686365551ec #
172.17.0.4 48e2417553fd
[root@VM-0-11-centos tomcat]#
自定义网络
查看所有的docker网络
几种网络模式:
bridge:桥接 ,docker(默认),我们自定义网络也是用bridge模式
none :不配置网络
host:和宿主机共享网络
conrainer:容器网络连通(用的少,了解一下)
我们直接启动的命令 默认是会有 --net bridge 这个操作,而这个就是docker0 ,不加–net bridge会默认有
docker run -d -P --name tomcat01 --net bridge tomcatdocker0特点:1、是默认的 2、域名不能访问,- -link可以打通,但是麻烦,不建议用
下面我们自定义一个网络
[root@VM-0-11-centos ~]# docker rm -f $(docker ps -aq)
-- driver bridge 桥接
--subnet 192.168.0.0/16 子网地址
--gateway 192.168.0.1 网关
[root@VM-0-11-centos ~]# docker network create --driver bridge --subnet 192
.168.0.0/16 --gateway 192.168.0.1 mynet
我们自己的网络就创建好了
[root@VM-0-11-centos ~]# docker run -d -P --name tomcat-net-01 --network mynet tomcat
[root@VM-0-11-centos ~]# docker run -d -P --name tomcat-net-02 --network mynet tomcat
现在不使用- -link也可以ping名字了!
我们自定义的网络docker已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
[root@VM-0-11-centos ~]# docker exec -it tomcat-net-01 ping 192.168.0.4 01ping02ip是没问题的
[root@VM-0-11-centos ~]# docker exec -it tomcat-net-01 ping tomcat-net-02 直接通过名字去ping也可以ping通
好处:不同集群使用不同的网络,保证了集群是安全和健康的!
网络连通
我们启动两个tomcat,这时没有指定网络,默认走到docker0上面的
[root@VM-0-11-centos ~]# docker run -d -P --name tomcat01 tomcat
[root@VM-0-11-centos ~]# docker run -d -P --name tomcat02 tomcat
[root@VM-0-11-centos ~]# docker exec -it tomcat01 ping tomcat-net-01 这是ping不通的,
Error: No such container: tomcat
此时要将tomcat01和mynet网卡打通
要使用connect命令
打通 tomcat01 跟 mynet
[root@VM-0-11-centos ~]# docker network connect mynet tomcat01
docker network inspect mynet 查看mynet网络信息,你会看到将tomcat01放到可mynet下
此时就可以ping通了
[root@VM-0-11-centos ~]# docker exec -it tomcat01 ping tomcat-net-01
这就是容器和网络如何连通的!
实战:部署redis集群
建一个redis的网卡,现将容器移出,避免卡
[root@VM-0-11-centos ~]# docker rm -f $(docker ps -aq)
[root@VM-0-11-centos ~]# docker network create redis --subnet 172.38.0.0/16 创建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 六个节点
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
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
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
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
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
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
创建集群
[root@VM-0-11-centos /]# docker exec -it redis-1 /bin/sh
创建集群
/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:6379 172.38.0.16:6379 --cluster-replicas 1
输入yes
此时已经创建完成
/data # redis-cli -c 连接集群
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
复制窗口,把 redis-3 主节点停掉
[root@VM-0-11-centos ~]# docker stop redis-3
redis-3
连接集群,get a 依旧可以从 redis-3的丛机获得到
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
SpringBoot微服务打包Docker镜像
1、构建spingboot项目
创建一个controller,启动测试访问下
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "Hello CodeApes";
}
}
2、打包应用
成功
3、编写dockerfile
下载一个docker插件
创建一个Dockerfile
编写Dockerfile
4、构建镜像
[root@VM-0-11-centos home]# cd /home/
[root@VM-0-11-centos home]# mkdir idea
[root@VM-0-11-centos home]# cd idea/
将Dockerfile和jar包传到idea目录中
构建镜像
[root@VM-0-11-centos idea]# docker build -t codeapes .
[root@VM-0-11-centos idea]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
codeapes latest e4ffcac52002 40 seconds ago 660MB
启动
[root@VM-0-11-centos idea]# docker run -d -P --name codeapes-springboot-web codeapes
[root@VM-0-11-centos idea]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0db485eb4697 codeapes "java -jar /app.jar …" 40 seconds ago Up 39 seconds 0.0.0.0:32783->8080/tcp codeapes-springboot-web