概述:
参考资料
官方文档:https://docs.docker.com/docker-for-windows/
【官方文档超级详细】
仓库地址:https://hub.docker.com/
【发布到仓库,git pull push】
b站教程:https://www.bilibili.com/video/BV1og4y1q7M4?
【这个教程非常简洁!且深入!基于企业应用场景!推荐!以下笔记都基于该课程】
Docker为什么会出现
一款产品,开发和上线两套环境,应用环境配置费时费力,而且容易出问题
尤其对于机器学习和深度学习的库更是如此,很可能存在版本问题、底层依赖冲突问题
所以发布项目时,不只是一套代码过去,而是代码+环境整体打包过去
所谓开发即运维,保证系统稳定性,提高部署效率
使用Docker后的流程:
开发:建立模型--环境--打包带上环境,即镜像--放到Docker仓库
部署:下载Docker中的镜像,直接运行即可
Docker的思想来自于集装箱,集装箱,对环境进行隔离
Docker通过隔离机制,可以将服务器利用到极致。
Docker的历史
2010年,几个搞IT的人,在美国成立一家公司dotCloud
做一些pass的云计算服务.他们将自己的容器化技术命名为Docker
Docker基于Go语言开发,Docker刚刚诞生的时候,没有引起行业的注意,dotCloud活不下去然后他们决定开源
2013年,创始人将Docker开源,不开则以,一开惊人,刚开源的时候,每个月都会更新一个版本
2014年4月9日,Docker 1.0发布
容器vs虚拟机
在容器技术出来之前,用的是虚拟机技术
虚拟机原理示意图
缺点:
- 资源占用多
- 冗余步骤多
- 启动很慢
容器化技术示意图
不是模拟的完整的操作系统
二者对比
比较虚拟机和Docker的不同
传统虚拟机 | Docker | |
---|---|---|
虚拟内容 | 硬件+完整的操作系统+软件 | APP+LIB |
大小 | 笨重,通常几个G | 轻便几个M或KB |
启动速度 | 慢,分钟级 | 快,秒级 |
Docker安装
Docker的基本组成
明确几个概念:
-
镜像(image):docker镜像好比一个模板,可以通过这个模板来创建容器(container),一个镜像可以创建多个容器,类似Python中的Class
-
容器(container):类似Python中通过Class创建的实例,Object;容器可以理解为一个简易的系统
-
仓库(repository):存放镜像的地方,
分为共有仓库和私有仓库
-
Docker Hub:国外的
-
阿里云:配置镜像加速
-
环境准备
我们要有一台服务器,并且可以操作它
- Linux命令基础,购买linux阿里云的服务器
- CentOS 7
- 使用Xshell链接远程服务器
安装xshell
下载CentOS7 https://www.jianshu.com/p/a63f47e096e8
[root@192 ~]# cd / [root@192 /]# pwd / [root@192 /]# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var [root@192 /]# uname -r 3.10.0-1127.el7.x86_64
Centos安装Docker
官网参考地址:https://docs.docker.com/engine/install/centos/
- 首先先卸载先前的版本:
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
- 1、安装所需的软件包
# sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 2. 设置阿里云镜像仓库地址
# sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 3.安装docker
#注意这里会有几个个y/n的判断,选择y即可
# sudo yum install docker-ce
- 4.设置docker开机启动
# sudo systemctl enable docker
Docker的启动与卸载:
启动: systemctl start docker
查看版本: docker version
查看下载的docker镜像: docker images
卸载docker:
# 卸载依赖 yum remove docker-ce docker-ce-cli containerd.io # 删除资源 rm -rf /var/lib/docker # docker 的默认工作路径
# docker run helloworld
run的运行流程图
设置docker镜像加速(去阿里云申请自己的加速地址填在下面)
阿里云地址:https://cr.console.aliyun.com/cn-hangzhou/new
直接复制阿里云提供的命令即可:
Docker底层原理
Docker是真么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程在主机上。通过Socket从客户端访问!
DockerServer接受到Docker-Client的指令,
Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层
- docker主要用的是宿主机的内核,vm需要Guest OS
所以说新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导
Docker命令
帮助命令:
官方文档地址:
https://docs.docker.com/reference/
docker version # 显示docker的基本信息 docker info # 系统信息,镜像和容器的数量 docker 命令 --help # 全部信息
镜像命令:
docker images(查看镜像)
查看服务器上面所有的镜像:docker images
显示所有的镜像:docker images -a
显示所有的镜像id:docker images -qa
# 解释 REPOSITORY # 镜像仓库源 TAG # 镜像的标签 IMAGE ID # 镜像的ID CREATED # 镜像的创建时间 SIZE # 镜像的大小
docker -search(搜索)
搜索仓库中的镜像,相当于GitHub中的搜索
地址:https://hub.docker.com/
或者通过命令行进行搜索:
docker search 镜像名
docker pull(拉取镜像)
docker pull mysql # 下载mysql镜像,default tag,默认最新版latest
[root@192 ~]# docker pull mysql Using default tag: latest # 不写tag默认最新版 latest: Pulling from library/mysql 8559a31e96f4: Pull complete # layer 分层下载,docker image的核心 联合文件系统 d51ce1c2e575: Pull complete c2344adc4858: Pull complete fcf3ceff18fc: Pull complete 16da0c38dc5b: Pull complete b905d1797e97: Pull complete 4b50d1c6b05c: Pull complete c75914a65ca2: Pull complete 1ae8042bdd09: Pull complete 453ac13c00a3: Pull complete 9e680cd72f08: Pull complete a6b5dc864b6c: Pull complete Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6#签名 Status: Downloaded newer image for mysql:latest docker.io/library/mysql:latest # 真实地址 # 即 docker pull mysql # 等价于 docker pull docker.io/library/mysql:latest
docker pull mysql:5.7 # 下载指定版本的镜像,版本来要来自于官网的镜像库,否则会找不到
docker rmi(删除镜像)
# 查看所有镜像 docker images # 删除一个 可以通过名称 也可以指定id -f表示删除所有 docker rmi -f 9cfcce23593a # 删除多个 用空格分隔id docker rmi -f id id id # 删除所有,images -aq就是查所有镜像id,从而递归删除 docker rmi -f $(docker images -aq)
容器命令
说明:有了镜像才能创建容器,linux,下载一个centos镜像来测试学习
docker pull centos:下载centos镜像
新建容器并启动
docker run [可选参数] image # 参数说明 --name=“Name” # 容器名字,用于区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器的端口 如-p 8080::8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 -p 随机指定端口
后面的/bin/bash的作用是表示载入容器后运行bash ,docker中必须要保持一个进程的运行,要不然整个容器启动后就会马上kill itself,这个/bin/bash就表示启动容器后启动bash。
exit 退出容器:
查看运行中的容器
# 查看正在运行的容器 docker ps # 查看曾经运行的容器 docker ps -a # 显示最近创建的容器,设置显示个数 docker ps -a - n=? # 只显示容器的编号 docker ps -aq
退出容器,与重新进入容器
# 容器停止退出 exit # 容器不停止退出 注意必须在英文输入法下,中文输入法不行 Ctrl + P + Q
删除容器
# 删除指定容器 不能删除正在运行的容器,如果强制删除 rm -f docker rm 容器id # 删除所有容器(可以将正在运行的容器删除) docker rm -f $(docker ps -aq) # 删除所有容器(可以将正在运行的容器也删除) docker ps -a -q|xargs docker rm
容器的启动和停止
docker start docker restart docker stop docker kill
其他常用命令
后台启动docker
# 注意:。。。。。
docker run -d 镜像名 # 用docker ps 查看的时候 发现停止了 # 后台运行,docker发现前台没有,容器启动后,发现自己没有提供服务,会立刻停止
查看日志
[root@192 ~]# docker logs --help Usage: docker logs [OPTIONS] CONTAINER Fetch the logs of a container Options: --details Show extra details provided to logs -f, --follow Follow log output --since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes) --tail string Number of lines to show from the end of the logs (default "all") -t, --timestamps Show timestamps # 时间戳 --until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
docker logs docker logs -f -t --tail n 【id】
使用脚本运行并查看日志:
docker run -d centos /bin/sh -c "while true;do echo shenzai;sleep 1;done"
查看正在运行的容器信息:docker inspect 容器id
进入当前正在运行的容器
方式一:docker exec run -it 容器id /bin/bash
方式二:docker attach 容器id
# 区别
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用) # docker attach 进入容器正在执行的终端,不会启动新的进程
将容器内的文件拷贝到主机上面
docker cp 容器id/容器文件 /主机目录
小结:
作业练习(部署程序)
一、Docker部署Nginx
- 1、搜索nginx镜像
2、docker安装nginx容器
- 3、运行测试
# -d 后台运行,--name 命名 -p Linux端口:nginx容器端口 开启的容器名
就是将容器外部的8023端口给容器内部的80端口用(80是nginx默认端口)
- 4、本地服务器访问测试
- 5、外网访问测试
需要注意的是,要把阿里云的安全组 8023 端口开放、
访问流程图:
[root@192 home]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38dbf7bdcaef nginx "/docker-entrypoint.…" 21 minutes ago Up 21 minutes 0.0.0.0:3344->80/tcp nginx01 # 进入容器 [root@192 home]# docker exec -it nginx01 /bin/bash # 查一下nginx在哪 root@38dbf7bdcaef:/# whereis nginx nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx # 到这个目录 root@38dbf7bdcaef:/# cd /etc/nginx root@38dbf7bdcaef:/etc/nginx# ls conf.d koi-utf mime.types nginx.conf uwsgi_params fastcgi_params koi-win modules scgi_params win-utf # 退出 root@38dbf7bdcaef:/etc/nginx# exit exit # 停止 [root@192 home]# docker stop 38dbf7bdcaef 38dbf7bdcaef
再次刷新网页,服务关闭
思考问题:每次改动nginx配置文件,都需要进入容器内部,十分麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?-v 数据卷技术!
二、Docker部署Tomcat
- 1、下载指定版本的tomcat
- 2.运行tomcat:将外部的8024端口给容器内部的8080端口用
- 3、开放端口
在阿里云跟宝塔面板中放行8024端口
- 4、访问
网址访问:182.92.209.212:8024
发现的是404,找不到tomcat的页面,
这是阿里云镜像的原因:默认使用最小镜像,所有不必要的都剔除了,保证最小可运行环境
- 5、解决访问不到tomcat主页
- 6、测试访问
三、Docker部署ElasticSearch+Kibana
查看内存使用情况命令:docker stats
- 1、官网命令:下载并运行ES(先别执行,往下看)
docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
- 2、可以看到ES启动的时候耗费的内存是非常大的,这对我1核心2G的服务器着实有很大压力o(╥﹏╥)o
这里就不截图了,直接卡的不行不行的,赶紧关掉ES
- 3、使用配置ES的方式启动
docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
- 4、测试访问
开启阿里云跟宝塔的9200端口
思考:
如何让ES跟Kibana之间通信
可视化操作(Protainer)
- portainer(先用这个)
- Rancher(CI/CD时用)
1、搜索镜像
docker search portainer
2、下载镜像
我们下载上图中标出来的
docker pull portainer/portainer
下载完成之后,我们查看一下是否已经有此镜像
docker images
3、运行Portainer镜像:单机
1.创建数据卷:
docker volume create portainer_data
2.运行容器:
docker run -d -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data --name prtainer-test portainer/portainer
参数说明:
-d:容器在后台运行; -p 8088:9000 :宿主机9000端口映射容器中的9000端口 –restart 标志会检查容器的退出代码,并据此来决定是否要重启容器,默认是不会重启。 --restart的参数说明 always:无论容器的退出代码是什么,Docker都会自动重启该容器。 on-failure:只有当容器的退出代码为非0值的时候才会自动重启。另外,该参数还接受一个可选的重启次数参数,`--restart=on-fialur
–restart=always:自动重启该容器
-v /var/run/docker.sock:/var/run/docker.sock :把宿主机的Docker守护进程(Docker daemon)默认监听的Unix域套接字挂载到容器中
-v portainer_data:/data :把宿主机portainer_data数据卷挂载到容器/data目录
–name prtainer-test : 给容器起名为portainer-test4、
4、测试外网访问
开启8088端口访问:IP/8088,第一次访问需要输入账号密码
给用户admin设置好密码之后,主页一开始进来是Remote ,单机版本我们选择 Local
,点击Connect
即可连接到本地docker
,如下图:
注意:从上图可以看出,有提示需要挂载本地 /var/run/docker.socker与容器内的/var/run/docker.socker连接。因此,在启动时必须指定该挂载文件。
点击进入
进入后可以对容器、镜像、网络、数据卷等进行管理,如下图:
Docker镜像
原理
UnionFS 联合文件系统
bootfs:boot file system
rootfs:root file system
Docker镜像都是只读的,当容器启动时,一个新的可写层被加到镜像的顶部,这一层就是我们通常说的容器层,容器层之下的都叫镜像层
commit提交镜像
docker commit # 提交容器成为一个新的副本 docker commit -m="提交的描述信息" -a="作者" 容器id 起的镜像名:版本信息
开始实践吧:
- 1、开启tomcat,外网能够访问到tomcat页面
-开启tomcat:docker run -d --name tomcat-test -p 8023:8080 tomcat
-查看开启的tomcat容器id:docker ps
-进入到容器内部:docker exec -it 1124bd4d7e53 /bin/bash
-拷贝文件到webapp目录下:cp -r webapps.dist/* webapps
-外网访问:www.zhangzhixi.top:8023
-退出tomcat容器:Ctrl+P+Q
- 2、提交镜像
docker commit -m="提交的说明" -a="用户名" 镜像id 起的镜像名:自定义版本号
- 3、使用镜像
docker run -d -p 8023:8080 956610f6c2d2
- 4、测试访问:自行测试访问即可!
容器数据卷
什么是容器卷
docker是要将应用和环境打包成一个镜像
这样,数据就不应该在容器中,否则容器删除,数据就会丢失,这就是删库跑路
故容器之间要有一个数据共享技术
在Docker容器中产生的数据,同步到本地,这就是卷技术
本质上是一个目录挂载,将容器内的目录挂载到虚拟机上
目的:容器的持久化和同步操作
容器间可以数据共享
使用数据卷
方式一:直接使用命令来挂载
docker run -it -v /home/ceshi:/home/ centos
docker run -it -v -p # -it 交互式进入 # -v volume卷技术 # -p 主机端口
测试:
查看容器详细信息:
【实战】安装mysql
docker search mysql # 拉取 docker pull mysql:5.7 # 挂载 docker run -d -p 8024:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=zhixi158 --name mysql01 mysql:5.7 -d 后台运行 -p 端口映射 -v 卷挂载 -e 环境配置 安装启动mysql需要配置密码 --name 容器名字
测试本地连接:注意要开启自己暴露的端口
测试添加数据:在本地mysql创建文件,服务器上面的数据会不会增加
具名和匿名挂载
初识Dockerfile
dockerfile就是来构建docker镜像的文件
第二种:DockerFile来构建docker镜像的文件
- 1、新建dockerfile1文件,建议使用dockerfile
# 镜像是一层一层的,脚本是一行一行的 # 指令都是大写的 # 这里的每个命令可以理解为镜像的一层 FROM centos VOLUME ["volume01","volume02"] # 再创建镜像的时候就挂载出来 CMD echo "---end---" CMD /bin/bash
- 2、通过脚本构建镜像
build 构建镜像的命令 -f 表示构建镜像脚本文件的地址 -t 表示生成的镜像名 . 表示生成在当前目录下
docker build -f dockerfile1 -t centos/zhixi:1.0.1 . # 红色的表示可以自定义生成的版本号
- 3、运行我们自己构建的镜像脚本
# docker ps
# docker run -it bc9025700d0c /bin/bash
这个卷一定与外部有一个文件是对应的:
- 4、查看容器内的数据卷对应的Linux中位置
查看一下数据卷挂载的路径:
- 5、测试容器内数据卷中的文件是否同步出去
容器间的数据共享
1、启动我们上个例子构建的容器,命名为docker1:
run -it --name docker1 centos/zhixi /bin/bash
2、新建一个docker2容器,-volumes-from 表示继承
docker run -it --name docker1 --volumes-from docker2 centos/zhixi
看到docker2继承了docker1,也同时继承了数据卷
3、测试docker1跟docker2的连通性
4、测试容器1的数据丢了容器2的数据会不会丢失
可以得出docker之间的容器共享是一种备份的概念!
DockerFile
是用来构建docker镜像的文件,可以理解为命令参数脚本
构建步骤:
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像仓库 私有/共有)
这个写一个项目时一样的
DockerFile基础知识
- 每个指令都必须是大写字母
- 按照从上到下顺序执行
- #表示注释
- 每一个指令都会创建体检一个新的镜像层,并提交
docker是面向开发的,我们以后要发布项目,做镜像,就要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业的交付标准,必须掌握!
DockerFile命令
FROM # 基础镜像 比如centos MAINTAINER # 镜像是谁写的 姓名+邮箱 RUN # 镜像构建时需要运行的命令 ADD # 添加,比如添加一个tomcat压缩包 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 指定暴露端口,跟-p一个道理 RUN # 最终要运行的 CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,而且可被替代 ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD # 当构建一个被继承Dockerfile 这个时候运行ONBUILD指定,触发指令 COPY # 将文件拷贝到镜像中 ENV # 构建的时候设置环境变量
【实践】构建自己的centos镜像,并添加其他功能
在我们之前制作的centos以及其他镜像信息,很多都是被阉割过的,很多的东西都没有了,只保留了最基础的功能。
我们自己来DIY一个镜像,增加其功能:
1.编写镜像配置
# 下面给官方centos加上自定义的内容 FROM centos MAINTAINER padaxing<010301200@hai.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
2.运行配置文件
3.测试:运行来查看我们自己DIY的centos镜像中有没有这些命令
拓展:查看镜像的构建历史信息
# docker images
# docker history 镜像id
CMD与ENTRYPOINT
测试CMD:能够被覆盖
脚本文件:
FROM centos CMD ["ls","-a"]
[root@zhixi dockerfile]# vim docker-cmd-test # 1.编写镜像脚本文件 [root@zhixi dockerfile]# docker build -f docker-cmd-test -t mycentos-cmd:1.0.1 . # 2、运行脚本文件 Sending build context to Docker daemon 3.072kB Step 1/2 : FROM centos ---> 300e315adb2f Step 2/2 : CMD ["ls","-a"] ---> Running in b7f321764f54 Removing intermediate container b7f321764f54 ---> e6c219530671 Successfully built e6c219530671 Successfully tagged mycentos-cmd:1.0.1 [root@zhixi dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos-cmd 1.0.1 e6c219530671 16 seconds ago 209MB mycentos 1.0.1 cddf7011bd95 39 minutes ago 291MB centos/zhixi latest bc9025700d0c 5 hours ago 209MB tomcat-zhixi 1.0.1 956610f6c2d2 10 hours ago 654MB mysql 5.7 a70d36bc331a 7 weeks ago 449MB tomcat 9.0 040bdb29ab37 7 weeks ago 649MB tomcat latest 040bdb29ab37 7 weeks ago 649MB nginx latest f6d0b4767a6c 8 weeks ago 133MB centos latest 300e315adb2f 3 months ago 209MB portainer/portainer latest 62771b0b9b09 7 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 11 months ago 791MB hello-world latest bf756fb1ae65 14 months ago 13.3kB elasticsearch latest 5acf0e8da90b 2 years ago 486MB [root@zhixi dockerfile]# docker run e6c219530671 # 3、执行镜像 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@zhixi dockerfile]# docker run e6c219530671 -l # 4、想追加一个命令:ls -la docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
测试ENTRYPOINT:能够被追加
脚本文件:
FROM centos ENTRYPOINT ["ls","-a"]
[root@zhixi dockerfile]# vim docker-entrypoint-test [root@zhixi dockerfile]# docker build -f docker-entrypoint-test -t mycentos-entrypoint:1.0.1 . Sending build context to Docker daemon 4.096kB Step 1/2 : FROM centos ---> 300e315adb2f Step 2/2 : ENTRYPOINT ["ls","-a"] ---> Running in fd76b617ae62 Removing intermediate container fd76b617ae62 ---> 750558da3e80 Successfully built 750558da3e80 Successfully tagged mycentos-entrypoint:1.0.1 [root@zhixi dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos-entrypoint 1.0.1 750558da3e80 14 seconds ago 209MB mycentos-cmd 1.0.1 e6c219530671 15 minutes ago 209MB mycentos 1.0.1 cddf7011bd95 55 minutes ago 291MB centos/zhixi latest bc9025700d0c 5 hours ago 209MB tomcat-zhixi 1.0.1 956610f6c2d2 10 hours ago 654MB mysql 5.7 a70d36bc331a 7 weeks ago 449MB tomcat 9.0 040bdb29ab37 7 weeks ago 649MB tomcat latest 040bdb29ab37 7 weeks ago 649MB nginx latest f6d0b4767a6c 8 weeks ago 133MB centos latest 300e315adb2f 3 months ago 209MB portainer/portainer latest 62771b0b9b09 7 months ago 79.1MB elasticsearch 7.6.2 f29a1ee41030 11 months ago 791MB hello-world latest bf756fb1ae65 14 months ago 13.3kB elasticsearch latest 5acf0e8da90b 2 years ago 486MB [root@zhixi dockerfile]# docker run 750558da3e80 . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@zhixi dockerfile]# docker run 750558da3e80 -l # 执行追加成功 total 56 drwxr-xr-x 1 root root 4096 Mar 9 13:31 . drwxr-xr-x 1 root root 4096 Mar 9 13:31 .. -rwxr-xr-x 1 root root 0 Mar 9 13:31 .dockerenv lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin drwxr-xr-x 5 root root 340 Mar 9 13:31 dev drwxr-xr-x 1 root root 4096 Mar 9 13:31 etc drwxr-xr-x 2 root root 4096 Nov 3 15:22 home lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64 drwx------ 2 root root 4096 Dec 4 17:37 lost+found drwxr-xr-x 2 root root 4096 Nov 3 15:22 media drwxr-xr-x 2 root root 4096 Nov 3 15:22 mnt drwxr-xr-x 2 root root 4096 Nov 3 15:22 opt dr-xr-xr-x 114 root root 0 Mar 9 13:31 proc dr-xr-x--- 2 root root 4096 Dec 4 17:37 root drwxr-xr-x 11 root root 4096 Dec 4 17:37 run lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Nov 3 15:22 srv dr-xr-xr-x 13 root root 0 Mar 9 08:32 sys drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
【实战】制作Tomcat镜像
1、准备镜像文件
2、编写Dockerfile配置文件信息
FROM centos MAINTAINER zhixi<1820712542@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u144-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.43.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_144 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.43 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.43 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.43/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.43/logs/catalina.out
3、构建镜像
因为Dockerfile是官方名称,所以在这里可以忽略-f参数:
docker build -t mytomcat:1.0.1 .
看到我们自定义的镜像已经构建成功了!
4、运行镜像
-d:后台运行
-p:暴露端口
--name:别名
-v:绑定路径
解释:/home/package/tomcat/test:/usr/local/apache-tomcat-9.0.43/webapps/test
就是说在本机的Linux下的/home/package/tomcat/test文件夹中放入项目,会自动同步到容器内的/webapps/test文件夹中!
不需要再进入,然后进入到webaps目录下放入我们要发布的项目了!
docker run -d -p 8023:8080 --name tomcat01 -v /home/package/tomcat/test:/usr/local/apache-tomcat-9.0.43/webapps/test -v /home/package/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.43/logs mytomcat:1.0.1
5、访问测试
使用浏览器访问:ip:自定义暴露的端口
6、测试发布项目
(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)
发现:项目部署成功,可以直接访问!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0" metadata-complete="true"> <display-name>Welcome to Tomcat</display-name> <description> Welcome to Tomcat </description> </web-app>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.util.Arrays" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>这是我的第一个jsp页面</title> </head> <body> <h1>你好!!</h1> </body> </html>
发布自己的镜像
发布到Docker Hub
1、先在DockerHub注册自己的账号
https://hub.docker.com/
2、在服务器上登录自己的DockerHUb
docker login -u 用户名
docker login -p 密码
3、提交(push)镜像
1、首先创建一个tag image
docker tag imageid username/dockername:tagname
imageid:镜像id
username账号名称或者组织名称
dockername:应用名称
tagname:版本信息
2、push镜像
docker push username/dockername:tagname
发布到阿里云
1、进入阿里云镜像服务
https://cr.console.aliyun.com/cn-zhangjiakou/instances/namespaces
2、创建自己的命名空间
3、创建自己的镜像仓库
4、阿里云上传
先退出我们自己的DockerHub账号 ,登录阿里云的
https://cr.console.aliyun.com/repository/cn-zhangjiakou/zhangzhixi-docker/zhangzhixi-repo/details
$ sudo docker login --username=搬砖的java小白 registry.cn-zhangjiakou.aliyuncs.com $ sudo docker tag [ImageId] registry.cn-zhangjiakou.aliyuncs.com/zhangzhixi-docker/zhangzhixi-repo:[镜像版本号] $ sudo docker push registry.cn-zhangjiakou.aliyuncs.com/zhangzhixi-docker/zhangzhixi-repo:[镜像版本号]
成功push
Docker 网络
理解Docker 0
学习之前清空下前面的docker 镜像、容器测试,方便观察网卡信息
# 删除全部容器 $ docker rm -f $(docker ps -aq) # 删除全部镜像 $ docker rmi -f $(docker images -aq)
问题: docker 是如果处理容器网络访问的?
# 测试 运行一个tomcat $ docker run -d -P --name tomcat01 tomcat # 查看容器内部网络地址 $ docker exec -it 容器id ip addr # 发现容器启动的时候会得到一个 eth0@if91 ip地址,docker分配! $ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 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 261: eth0@if91: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever # 思考? linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以! $ ping 172.18.0.2 PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data. 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.074 ms
原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术!
再次测试 ip addr
2 、再启动一个容器测试,发现又多了一对网络
# 我们发现这个容器带来网卡,都是一对对的 # veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连 # 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的 # OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
3、我们来测试下tomcat01和tomcat02是否可以ping通
# 获取tomcat01的ip 172.17.0.2 $ docker-tomcat docker exec -it tomcat01 ip addr 550: eth0@if551: <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 # 让tomcat02 ping tomcat01 $ docker-tomcat docker exec -it tomcat02 ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.098 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms # 结论:容器和容器之间是可以互相ping通
网络模型图
结论:tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
小结
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥一对就没了!
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
--link
$ docker exec -it tomcat02 ping tomca01 # ping不通 ping: tomca01: Name or service not known # 运行一个tomcat03 --link tomcat02 $ docker run -d -P --name tomcat03 --link tomcat02 tomcat 5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef # 3连接2 # 用tomcat03 ping tomcat02 可以ping通 $ docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms # 2连接3 # 用tomcat02 ping tomcat03 ping不通 12345678910111213141516
探究:
docker network inspect 网络id 网段相同
docker inspect tomcat03
查看tomcat03里面的/etc/hosts发现有tomcat02的配置
–link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
自定义Docker网络
查看所有的docker网络信息:docker network ls
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
测试:启动tomcat使用的网络解释
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
创建自定义网络
# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
查看网络信息:# docker network inspect mynet
使用我们自己定义的网络,启动两个tomcat查看情况:
docker run -d -P --name tomcat-net-01 --net mynet tomcat:9.0
查看自定义网络信息:docker network inspect mynet
可以看到在这个我们自定义的网络中多出来了两个容器信息,说明成功!
测试容器连通情况
# docker exec -it tomcat-net-02 ping tomcat-net-01
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
不能够将Docker0直接跟我们自己定义的网络进行连接:
我们先来测试一下,在上面已经了解过Docker1的两个容器都不能够直接使用名称进行ping通对方,更不要说在Docker0网络下的tomcat01网络能ping通mynet网络下的容器了!
我们网络连通要来实现的就是第四点
查看docker网络命令,查看如何将Docker0网络下的tomcat01容器连接到mynet网络下的tomcat-net-01网络
测试打通:tomcat01 --》 mynet网络
#docker network connect mynet tomcat01
#docker network inspect mynet
实战:部署Redis集群
1、创建自己的网卡
docker network create redis --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
3、开启六个容器(运行redis)
docker run -p 6371:6379 -p 16271: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 16272: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 16273: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 16274: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 16275: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 16276: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
4、开启集群
- 1.先进入到一个redis容器中
docker exec -it redis-1 /bin/sh
- 2.开启redis集群
5、连接redis集群进行测试
- 1.连接集群:-c 表示集群
redis-cli -c
- 2.在主机中设置一个值,然后关闭这个容器,看下这个值还能不能get到
- 3.开启一个窗口,关闭3号容器,看能不能获取到a的值?
可以看到数据是在6314容器中获取到的,因为14是13的从机
查看容器状态:
【实战】Dockerfile打包发布SpringBoot项目
1、新建SpringBoot项目,保证能够跑的起来、
这里我就跟着简单创建了个controller进行跳转
可以运行就将项目打成jar包
2、编写Dockerfile脚本文件
FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
3、将Dockerfile跟我们刚刚打包的jar放到服务器上面
4、运行脚本,构建镜像
docker build -f Dockerfile -t docker-springboot-test:1.0.1 .
-f 表示脚本文件 -t表示生成的镜像名称以及版本信息 . 在当前目录运行
5、运行镜像
-d 表示后台运行
-P 表示生成随机端口
--name 表示生成的容器名称(随便取)
如果要通过外网访问,需要开启阿里云安全组规则~!