Docker
Docker 学习
- docker 安装
- docker命令
- Docker镜像
- 容器数据卷
- DockerFile
- Docker网络原理
- IDEA 整合Docker
- Dcoker Compose
- Docker Swarm
- CI\CD jenkins
docker 概述
docker为什么出现
一款产品:开发–上线 两套环境!应用环境,应用配置!
开发 ---- 运维。 问题:
传统:开发jar包,运维来做
现在:开发打包部署上线,一套流程做完!
java – apk --发布(应用商店)----张三使用apk —安装即可用!
jav – jar(环境) – 打包项目带上环境(镜像) – ( Docker仓库:商店 )----下载我们发布的镜像—直接运行即可!
Docker给以上的问题,提出了解决方案!
Docker 的思想就来自于集装箱!
JRE – 多个应用(端口冲突) — 原来都是交叉的!
隔离:Docker核心思想 !打包装箱! 箱子之间相互隔离
Docker 通过隔离机制 ,可以将服务器利用到极致!
本质:所有的技术都是因为出现了一些问题
Docker 的历史
2010, 几个搞IT的年轻人,在美国成立一家公司dotCloud
做一些 pass 的云计算服务! LXC有关的容器技术!
他们将自己的技术(容器化技术)命名 就是Docker
Docker 刚刚诞生的时候,没有引起行业的注意!dotCloud,就活不下去
开放源代码
Docker 越来越多的人发现了docker的优点!docker 每个月都会更新一个版本
Docker为什么这么火!十分的轻巧
在容器技术出来之前,我们都是使用的虚拟机技术!
虚拟机:在window中安装一个Vmware ,同过这个软件我们可以虚拟出来一台或多台电脑!笨重
虚拟机也是属于虚拟化技术,Docker 容器技术 ,也是一种 虚拟化技术
vm: linux centos 原生镜像(一个电脑!) 隔离,需要开启多个虚拟机! 几个G 几分钟
docker: 隔离 ,镜像(核心的环境 4m+JDK +mysql) 十分的小巧 ,运行镜像就可以
docker 是基于 Go语言开发的!开源项目
·Docker 能干嘛
普通电脑运行机制
容器化技术不是墨迹的一个完整的操作系统
比较 Docker 和虚拟机技术的不同
-
传统虚拟机 ,虚拟出一条硬件,运行一个完整的操作系统 ,然后再这个系统上安装和运行软件 -
容器内的应用直接运行在宿主机上的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了 -
每个容器间是相互隔离,每个容器内都有一个属于自己的文件系统,互不影响
devOps (开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像测试,一键运行
更便捷的升级或扩缩容
使用了Docker之后,我们部署应用就和搭积木·一样
项目打包未一个镜像,扩展 服务器A! 服务器B
更简单的系统运维
在容器化之后,我们的开发,测试环境是高度一致的
更高效的计算资源利用
docker 是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致
Docker的基本组成
镜像(image):
docker镜像就像一个模板,可以通过这个模板来创建容器服务,tomcat镜像===》run ==》tomcat01 容器
通过这个镜像可以创建多个容器 (最终服务运行或者)
容器(contanier):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
启动,停止,删除,基本命令
仓库(repository):
仓库就是存放镜像的地方
仓库分为公有仓库和私有仓库!
Docker Hub(默认是国内的)
阿里云…都有容器服务器(配置镜像加速!)
安装docker
环境准备:
用xshell 理解上服务器(记得设置安全组打开22端口)
安装
帮助文档:
yum remove docker \
docker-client \
docker-client-lastest \
docker-common \
docker-latest \
docker-latest-logrotate \
docekr-engine
yum install -y yum-utils
yum-config-manager \
--add-repo \
https://download.docker.com/lunix/centos/docker-ce.repo
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
docker -version
docker run hello-world
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
配置阿里镜像加速器
1.访问阿里云服务
2.找到镜像加速地址
3、配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://l1m9m3zg.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
底层原理
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 info
docker 命令 --help
帮助的文档地址
镜像命令
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
-a,--all
-q,--quiet
docker search 搜索镜像
[root@iz2ze4axajsdleozcknrk7z ~]
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10281 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3801 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 749 [OK]
percona Percona Server is a fork of the MySQL relati… 515 [OK]
--filter=starts=3000
docker pull 拉取镜像
[root@iz2ze4axajsdleozcknrk7z ~]
Using default tag: latest
latest: Pulling from library/mysql
6ec7b7d162b2: Pull complete
fedd960d3481: Pull complete
7ab947313861: Pull complete
64f92f19e638: Pull complete
3e80b17bff96: Pull complete
014e976799f9: Pull complete
59ae84fee1b3: Pull complete
ffe10de703ea: Pull complete
657af6d90c83: Pull complete
98bfb480322c: Pull complete
9f2c4202ac29: Pull complete
a369b92bfc99: Pull complete
Digest: sha256:365e891b22abd3336d65baefc475b4a9a1e29a01a7b6b5be04367fcc9f373bb7
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
docker pull docker.io/library/mysql:latest
[root@iz2ze4axajsdleozcknrk7z ~]
5.7: Pulling from library/mysql
6ec7b7d162b2: Already exists
fedd960d3481: Already exists
7ab947313861: Already exists
64f92f19e638: Already exists
3e80b17bff96: Already exists
014e976799f9: Already exists
59ae84fee1b3: Already exists
7d1da2a18e2e: Pull complete
301a28b700b9: Pull complete
979b389fc71f: Pull complete
403f729b1bad: Pull complete
Digest: sha256:d4ca82cee68dce98aa72a1c48b5ef5ce9f1538265831132187871b78e768aed1
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
[root@iz2ze4axajsdleozcknrk7z ~]
[root@iz2ze4axajsdleozcknrk7z ~]
[root@iz2ze4axajsdleozcknrk7z ~]
容器命令
我们有了镜像才可以创建容器,lunix,下载一个centos镜像来测试学习
docker pull centos
新建容器并启动
列出所有的运行命令
退出容器
exit
删除容器
docker rm 容器id
启动和停止容器
docker start 容器id
常用的其他命令
后台启动容器
查看日志
docker logs -f -t --tail 容器,没有日志
查看容器中的进程信息ps
查看镜像的元数据
进入当前正在运行的容器
docker exec -it 容器id bashShell
docker attach 容器id
正在执行当前的代码。。。。
从容器内拷贝文件到主机上
docker cp
[root@iz2ze4axajsdleozcknrk7z home]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5450d9097ba7 centos "/bin/bash" 2 minutes ago Up About a minute interesting_wing
[root@iz2ze4axajsdleozcknrk7z home]
[root@5450d9097ba7 /]
[root@5450d9097ba7 home]
[root@5450d9097ba7 home]
[root@5450d9097ba7 home]
exit
[root@iz2ze4axajsdleozcknrk7z home]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5450d9097ba7 centos "/bin/bash" 3 minutes ago Exited (0) 7 seconds ago interesting_wing
[root@iz2ze4axajsdleozcknrk7z home]
[root@iz2ze4axajsdleozcknrk7z home]
admin lxx.java test.java
可视化工具
什么是portainer
Docker 图形化界面管理工具!提供一个后台面板供我们操作
docker run -d -p 8088:9000 \--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
访问测试: 外网:8080
进入后的面板
可视化面板一般不会使用
docker 镜像讲解
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量和配置文件
所有的应用,直接打包docker 镜像,就可以跑起来
如何得到镜像
分层理解
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect命令!
"RootFS": { "Type": "layers", "Layers": [ "sha256:7e718b9c0c8c2e6420fe9c4d1d551088e314fe923dce4b2caf75891d82fb227d", "sha256:89ce1a07a7e4574d724ea605b4877f8a73542cf6abd3c8cbbd2668d911fa5353", "sha256:9eef6e3cc2937e452b2325b227ca28120a70481be25404ed9aad27fa81219fd0", "sha256:c6e23529840f1d7025d61f4e41781d16fff2c0a2639484e9c0a2e516ed98c23a", "sha256:0c895bca4020c183c3f093cf920d29460ac5a25b7e48210d9f0655b1e115b7af", "sha256:fa723b6cb1b660d6c745a09892783a552657b9dba07f52974cb88365281feb19" ] }
理解
所有的Docker(镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示 (这只是一个用于演示的很简单的例子) 。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。 下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统.
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及 ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1].下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
commit 镜像
docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker run -d --name=typecho-blog --restart always -e PHP_TZ=Asia/Shanghai -e PHP_MAX_EXECUTION_TIME=600 -p 80:80 -v 80x86/typecho:latest
容器数据卷
docker容器数据卷是什么?
当我们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在我们关闭docker容器时是会消失的,但是其中产生的部分内容我们是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,我们希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。
通俗地来说,docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
特点:
-
数据卷可以在容器之间共享或重用数据 -
数据卷中的更改可以直接生效 -
数据卷中的更改不会包含在镜像的更新中 -
数据卷的生命周期一直持续到没有容器使用它为止
总结:容器的持久化和同步操作!容器间也是可以数据共享的
添加数据卷
添加数据卷的方式有两种,第一种是直接通过命令行挂载,第二种是通过dockerFile添加
第一种 命令行挂载
docker run -it -v 宿主机绝对路径目录:容器内目录 镜像名
这个命令会在宿主机和容器内分别建立两个目录,两个目录是对接的,里面的数据可以共享。如果我们不知道数据卷是否挂载成功时,我们可以通过以下方式来检查数据卷的挂载结果。
docker inspect 容器id
我们再挂载的时候还可以给数据卷加上权限,假如我们要宿主机只能读取容器的数据卷内容不能修改,我们可以添加只读权限
docker run -it -v /宿主机绝对路径目录:/容器内目录 :ro 镜像名
第二种 利用dockerFile的形式添加
dockerFile对于docker镜像而言就如同java中某个类的.class文件对应上该类的.java文件。
首先在linux服务器根目录上新建docker文件夹并建立DockerFile文件,使用volume命令(出于可移植可分享的的考虑,用以上 -v /宿主机绝对路径目录 : /容器内目录 的这种方式不能够直接在dockerFile中直接实现,因为宿主机目录是依赖于特定的宿主机的,并不能保证所有的宿主机都存在这样特定的目录)
FROM 镜像名VOLUME ["/生成的目录路径"] -- privileged=trueCMD echo "success build"CMD /bin/bash
相当于命令行: docker run -it -v /宿主机目录路径 : /生成的目录路径
然后我们通过命令行docker build执行我们写好的dockerFile文件(docker build和docker commit两个命令都可以建立docker镜像,docker commit 需要在容器内进行,docker build 不需要)
docker build -f /docker/DockerFile -t 命名空间/镜像名 .参数: -f 指定dockerfile 文件,默认情况下在执行命令的目录下寻找 Dockerfile 文件 -t 指定镜像名称 . 在当前目录下生成镜像
docker build -f /root/Dockerfile -t image/test .
运行我们自己构建的镜像,并进入镜像,查看我们自己生成镜像时创建的文件夹
在宿主机中查看我们在容器卷中创建的文件,和写入的文件内容。
注: 可以使用 ctrl + q + P 退出容器,让容器进入后台运行。退回宿主机中
使用 inspct 命令查看容器信息找到宿主机中相应的容器卷
docker inspect 8c05c7c1eec4
可以看到test.txt已经同步到宿主机对应的挂载目录中
Docker 镜像原理
Docker 镜像加载原理
commit镜像
docker commit 提交容器成为一个新的副本
容器数据卷
什么是容器数据卷
docker理念回顾
将应用和环境打包成一个镜像
如果将数据存在容器中,容器删除,数据就会丢失
容器之间可以有一个数据共享的技术!Docker 容器产生的数据同步到本地
目录的挂载,将我们容器内的目录,挂在到linnux上
容器的持久化和同步操作 容器间也是可以共享数据的!
使用数据卷
方式一:直接使用命令挂在 -v
docker run -it -v 主机目录:容器内目录
修改本地,容器会自动同步
实战 :安装Mysql
将容器删除 挂载在本地的数据卷依旧没有丢失,这就实现了容器数据化功能
具名挂载 和 匿名挂载
结果为这样 这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径
所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载
拓展:
Dockerfile
初识Dockerfile
dockerfile 就是用来构建docker镜像的构建文件,
通过这个脚本可以生成镜像,镜像是一层一层的,每个命令都是一层
这个卷和外部一定有一个同步的目录!
查看一下卷挂载的路径
测试一下刚才的文件是否同步出去了!
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器
多个mysql同步数据
docker 01 上的数据同步到了docker02 上
多个mysql数据共享
结论:
容器之间配置信息的传递,容器数据卷的生命周期一直持续到没有容器使用为止
DockerFile介绍
dockerfile 是用来构建docker镜像的文件!命令参数脚本
构建步骤
1、编写一个dockerfile 文件
2、docker bulid 构建成为一个镜像
3、 docker run 运行镜像
4、docker push 发布镜像
查看官方是怎么做的
很多官方镜像都是基础包,很多功能都没有,我们通常会自己搭建自己的镜像
Dockerfile构建过程
基础知识:
1、每个保留关键字(指令)必须是大写字母
2、 从上到下的顺讯执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,作镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准吗,必须掌握
步骤:开发、部署、运维。。缺一不可
Dockerfile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
Dockerfile的指令
FROM
实战测试
Docker Hub 中99% 镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建
创建一个自己的centos
FROM centos
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
docker build -f docker文件路径 -t 镜像名:[tag]
我们可以列出本地进行的变更历史
CMD 和 ENTRYPOINT 的区别
vim dockerfile-cmd-test
FROM centos
CMD ["1s ","-a"]
docker build -f dockerfile-cmd-test -t cmdtest .
docker run dd8e4401d72f
..
.docker
env
bin
devet
chome
lib
lib64
[root dockerfile]
docker: Error response from daemon: 0CI runtime create failed: container_linux.go:349: startingcontainer process caused "exec: \"-l\ ": executable file not found in SPATH": unknown.
# cmd的清理下-l 替换了CMD ["1s " , "-a"]命令,-1 不是命令所以报错!
实战:Tomcat镜像
- 准备镜像文件 tomcat压缩包,jdk的压缩包
- 编写Dockerfile文件
FROM centos
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/ADDapache-tomcat-9.0.22.tar.gz /usr/local/
RUNyum-y install vim
ENV MYPATH/usr/localWORKDIR $MYPATH
ENV JAVA HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME/usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CND /usr/local/apache-tomcat-9.0.22/bin/startup.sh & tail -F /url/local/apache-tomcat-9.0.22/bin/logs/catalina.out
- 构建镜像
docker build -t tomcat
发布自己的镜像
- dockerhub 注册自己的账号
- 确认这个账号可以登录
- 在我们服务器上提交自己的镜像
docker login -u 账号名
- 登录完毕后就可以提交自己的镜像
阿里云镜像服务上
1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建容器镜像
Docker 网络
三个网络
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
va7id_lft forever preferred_lft forever
261: eth0@if262:<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 7ink-netnsid o
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@kuangshen /]
PING 172.18.0.2 (172.18.0.2)56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 tt1=64 time=0.067 ms64 bytes from 172.18.0.2: icmp_seq=2 tt1=64 time=0.055 ms
原理
1、我们每启动一个docker容器。docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术
再次测试 ip addr
2、 再启动一个容器,发现多了一对网卡!
3、我们来测试两个容器之间是否能ping通
结论:tomcat01 和 tomcat02 是公用的一个路由器 ,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我的容器分配一个默认的可用IP
Docker中的所有的网络接口都是虚拟的。虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应网桥一对就没了!
–link
思考一个场景,我们编写了一个微服务,database url =ip,项目不重启,数据ip换掉了,我们希望可以处理在这个问题,可以通过名字来访问网络、
[root@kuangshen/]
[root@kuangshen/]
[root@kuangshen /]
[root@kuangshen /]
PING tomcat02 (172.18.0.3)56(84) bytes of data.
64 bytes from tomcat02 (172.18.0.3): icmp_seq=1 tt1=64 time=0.100 ms64 bytes from tomcat02 (172.18.0.3): icmp_seq=2 tt1=64 time=0.066 ms64 bytes from tomcat02 (172.18.0.3): icmp_seq=3 tt1=64 time=0.067 ms
I
--- tomcat02 ping statistics ---
3 packets transmitted,3 received,0% packet loss, time 1000msrtt min/avg/max/mdev = 0.066/0.077/0.100/0.018 ms
link的原理
其实这个tomcat03 就是在本地配置了tomcat02 的配置
[root@kuangshen /]
127.0.0.1 localhost
::1 locaThost ip6-1ocalhost ip6-loopback
fe00::0 ip6-loca1net
ff00::0 ip6-mcastprefix
ff02::1 ip6-a71nodes
ff02::2 ip6-a11routers
172.18.0.3tomcat02 312857784cd4
172.18.0.4 5ca72d80ebb0
本质探究:–link就是我们在hosts配置中增加了一个172.18.0.3 tomcat02 312857784cd4
这种方式不建议使用
自定义网络
查看所有的docker网络
网络模式
bridge:桥接
none: 不配置网络
host:和宿主机共享网络
container:容器网络连通!(用的少!局限性很大)
测试
docker run -d -p --name tomcat01 tomcat
docker run -d -p --name tomcat01 --net bridge tomcat
[root@kuangshen /]
eb21272b3a35ceaba11b4aa5bbff131c3fb09c4790f0852ed4540707438db052
[root@kuangshen /]
NE TWORK ID NAME DRIVER SCOPE
5a008c015cac bridge bridge local
db44649a9bff composetest_default bridge local
ae2b6209c2ab host host local
eb21272b3a35 mynet bridge local
[root@kuangshen /]
PING192.168.0.3 (192.168.0.3)56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 tt7=64 time=0.085 ms
64 bytes from 192.168.0.3: icmp_seq=2 tt1=64 time=0.070 ms
--- 192.168.0.3 ping statistics ---
2 packets transmitted,2 received,0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.070/0.077/0.085/0.011 ms
[root@kuangshen /]
PING tomcat-net-02 (192.168.0.3)56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.063 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 tt1=64 time=0.070 ms
好处: redis-不同的集群使用不同的网络,保证集群是安全和健康的
mysql -不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
此时可以发现容器成功的加入了mynet网络
[root@kuangshen /]
PING tomcat-net-o1 (192.168.0.2)56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.070 ms
[root@kuangshen /]
结论:假设需要跨网络操作别的容器,就需要使用docker network connect 连通。。。
实战:部署Redis集群
docker network create redis --subnet 172.38.0.0/16
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-bus-port 16379
appendonly yes
EOF
done
for port in $(seq 1 6);\
do \
docker rm -f redis-${port};
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 redis-server /etc/redis/redis.conf;
done
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
>>> 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: 12ccc413ed4e351aceed1d738f4b3abf415be47c 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: dc3f1a2b9da08d94256d3beef69d9f64711815d8 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 2615c949c02207e54664c5f11bd615388f66b043 172.38.0.14:6379
replicates dc3f1a2b9da08d94256d3beef69d9f64711815d8
S: 0d39e27b5f5fdc1353094107df06ccf127f39d5e 172.38.0.15:6379
replicates 12ccc413ed4e351aceed1d738f4b3abf415be47c
S: 64dd8e732978a6cbf68c753ac9dfcaff66599450 172.38.0.16:6379
replicates 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d
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: 12ccc413ed4e351aceed1d738f4b3abf415be47c 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 2615c949c02207e54664c5f11bd615388f66b043 172.38.0.14:6379
slots: (0 slots) slave
replicates dc3f1a2b9da08d94256d3beef69d9f64711815d8
S: 64dd8e732978a6cbf68c753ac9dfcaff66599450 172.38.0.16:6379
slots: (0 slots) slave
replicates 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d
S: 0d39e27b5f5fdc1353094107df06ccf127f39d5e 172.38.0.15:6379
slots: (0 slots) slave
replicates 12ccc413ed4e351aceed1d738f4b3abf415be47c
M: dc3f1a2b9da08d94256d3beef69d9f64711815d8 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
docker 搭建redis集群完成
Docker
Docker 学习
- docker 安装
- docker命令
- Docker镜像
- 容器数据卷
- DockerFile
- Docker网络原理
- IDEA 整合Docker
- Dcoker Compose
- Docker Swarm
- CI\CD jenkins
docker 概述
docker为什么出现
一款产品:开发–上线 两套环境!应用环境,应用配置!
开发 ---- 运维。 问题:
传统:开发jar包,运维来做
现在:开发打包部署上线,一套流程做完!
java – apk --发布(应用商店)----张三使用apk —安装即可用!
jav – jar(环境) – 打包项目带上环境(镜像) – ( Docker仓库:商店 )----下载我们发布的镜像—直接运行即可!
Docker给以上的问题,提出了解决方案!
Docker 的思想就来自于集装箱!
JRE – 多个应用(端口冲突) — 原来都是交叉的!
隔离:Docker核心思想 !打包装箱! 箱子之间相互隔离
Docker 通过隔离机制 ,可以将服务器利用到极致!
本质:所有的技术都是因为出现了一些问题
Docker 的历史
2010, 几个搞IT的年轻人,在美国成立一家公司dotCloud
做一些 pass 的云计算服务! LXC有关的容器技术!
他们将自己的技术(容器化技术)命名 就是Docker
Docker 刚刚诞生的时候,没有引起行业的注意!dotCloud,就活不下去
开放源代码
Docker 越来越多的人发现了docker的优点!docker 每个月都会更新一个版本
Docker为什么这么火!十分的轻巧
在容器技术出来之前,我们都是使用的虚拟机技术!
虚拟机:在window中安装一个Vmware ,同过这个软件我们可以虚拟出来一台或多台电脑!笨重
虚拟机也是属于虚拟化技术,Docker 容器技术 ,也是一种 虚拟化技术
vm: linux centos 原生镜像(一个电脑!) 隔离,需要开启多个虚拟机! 几个G 几分钟
docker: 隔离 ,镜像(核心的环境 4m+JDK +mysql) 十分的小巧 ,运行镜像就可以
docker 是基于 Go语言开发的!开源项目
·Docker 能干嘛
普通电脑运行机制
容器化技术不是墨迹的一个完整的操作系统
比较 Docker 和虚拟机技术的不同
-
传统虚拟机 ,虚拟出一条硬件,运行一个完整的操作系统 ,然后再这个系统上安装和运行软件 -
容器内的应用直接运行在宿主机上的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了 -
每个容器间是相互隔离,每个容器内都有一个属于自己的文件系统,互不影响
devOps (开发、运维)
应用更快速的交付和部署
传统:一堆帮助文档,安装程序
Docker:打包镜像测试,一键运行
更便捷的升级或扩缩容
使用了Docker之后,我们部署应用就和搭积木·一样
项目打包未一个镜像,扩展 服务器A! 服务器B
更简单的系统运维
在容器化之后,我们的开发,测试环境是高度一致的
更高效的计算资源利用
docker 是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致
Docker的基本组成
镜像(image):
docker镜像就像一个模板,可以通过这个模板来创建容器服务,tomcat镜像===》run ==》tomcat01 容器
通过这个镜像可以创建多个容器 (最终服务运行或者)
容器(contanier):
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
启动,停止,删除,基本命令
仓库(repository):
仓库就是存放镜像的地方
仓库分为公有仓库和私有仓库!
Docker Hub(默认是国内的)
阿里云…都有容器服务器(配置镜像加速!)
安装docker
环境准备:
用xshell 理解上服务器(记得设置安全组打开22端口)
安装
帮助文档:
yum remove docker \
docker-client \
docker-client-lastest \
docker-common \
docker-latest \
docker-latest-logrotate \
docekr-engine
yum install -y yum-utils
yum-config-manager \
--add-repo \
https://download.docker.com/lunix/centos/docker-ce.repo
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
docker -version
docker run hello-world
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
配置阿里镜像加速器
1.访问阿里云服务
2.找到镜像加速地址
3、配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://l1m9m3zg.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
底层原理
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 info
docker 命令 --help
帮助的文档地址
镜像命令
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
-a,--all
-q,--quiet
docker search 搜索镜像
[root@iz2ze4axajsdleozcknrk7z ~]
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10281 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3801 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 749 [OK]
percona Percona Server is a fork of the MySQL relati… 515 [OK]
--filter=starts=3000
docker pull 拉取镜像
[root@iz2ze4axajsdleozcknrk7z ~]
Using default tag: latest
latest: Pulling from library/mysql
6ec7b7d162b2: Pull complete
fedd960d3481: Pull complete
7ab947313861: Pull complete
64f92f19e638: Pull complete
3e80b17bff96: Pull complete
014e976799f9: Pull complete
59ae84fee1b3: Pull complete
ffe10de703ea: Pull complete
657af6d90c83: Pull complete
98bfb480322c: Pull complete
9f2c4202ac29: Pull complete
a369b92bfc99: Pull complete
Digest: sha256:365e891b22abd3336d65baefc475b4a9a1e29a01a7b6b5be04367fcc9f373bb7
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
docker pull docker.io/library/mysql:latest
[root@iz2ze4axajsdleozcknrk7z ~]
5.7: Pulling from library/mysql
6ec7b7d162b2: Already exists
fedd960d3481: Already exists
7ab947313861: Already exists
64f92f19e638: Already exists
3e80b17bff96: Already exists
014e976799f9: Already exists
59ae84fee1b3: Already exists
7d1da2a18e2e: Pull complete
301a28b700b9: Pull complete
979b389fc71f: Pull complete
403f729b1bad: Pull complete
Digest: sha256:d4ca82cee68dce98aa72a1c48b5ef5ce9f1538265831132187871b78e768aed1
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
[root@iz2ze4axajsdleozcknrk7z ~]
[root@iz2ze4axajsdleozcknrk7z ~]
[root@iz2ze4axajsdleozcknrk7z ~]
容器命令
我们有了镜像才可以创建容器,lunix,下载一个centos镜像来测试学习
docker pull centos
新建容器并启动
列出所有的运行命令
退出容器
exit
删除容器
docker rm 容器id
启动和停止容器
docker start 容器id
常用的其他命令
后台启动容器
查看日志
docker logs -f -t --tail 容器,没有日志
查看容器中的进程信息ps
查看镜像的元数据
进入当前正在运行的容器
docker exec -it 容器id bashShell
docker attach 容器id
正在执行当前的代码。。。。
从容器内拷贝文件到主机上
docker cp
[root@iz2ze4axajsdleozcknrk7z home]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5450d9097ba7 centos "/bin/bash" 2 minutes ago Up About a minute interesting_wing
[root@iz2ze4axajsdleozcknrk7z home]
[root@5450d9097ba7 /]
[root@5450d9097ba7 home]
[root@5450d9097ba7 home]
[root@5450d9097ba7 home]
exit
[root@iz2ze4axajsdleozcknrk7z home]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5450d9097ba7 centos "/bin/bash" 3 minutes ago Exited (0) 7 seconds ago interesting_wing
[root@iz2ze4axajsdleozcknrk7z home]
[root@iz2ze4axajsdleozcknrk7z home]
admin lxx.java test.java
可视化工具
什么是portainer
Docker 图形化界面管理工具!提供一个后台面板供我们操作
docker run -d -p 8088:9000 \--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
访问测试: 外网:8080
进入后的面板
可视化面板一般不会使用
docker 镜像讲解
镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量和配置文件
所有的应用,直接打包docker 镜像,就可以跑起来
如何得到镜像
分层理解
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect命令!
"RootFS": { "Type": "layers", "Layers": [ "sha256:7e718b9c0c8c2e6420fe9c4d1d551088e314fe923dce4b2caf75891d82fb227d", "sha256:89ce1a07a7e4574d724ea605b4877f8a73542cf6abd3c8cbbd2668d911fa5353", "sha256:9eef6e3cc2937e452b2325b227ca28120a70481be25404ed9aad27fa81219fd0", "sha256:c6e23529840f1d7025d61f4e41781d16fff2c0a2639484e9c0a2e516ed98c23a", "sha256:0c895bca4020c183c3f093cf920d29460ac5a25b7e48210d9f0655b1e115b7af", "sha256:fa723b6cb1b660d6c745a09892783a552657b9dba07f52974cb88365281feb19" ] }
理解
所有的Docker(镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
该镜像当前已经包含3个镜像层,如下图所示 (这只是一个用于演示的很简单的例子) 。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。 下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统.
Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及 ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1].下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
commit 镜像
docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker run -d --name=typecho-blog --restart always -e PHP_TZ=Asia/Shanghai -e PHP_MAX_EXECUTION_TIME=600 -p 80:80 -v 80x86/typecho:latest
容器数据卷
docker容器数据卷是什么?
当我们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在我们关闭docker容器时是会消失的,但是其中产生的部分内容我们是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,我们希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。
通俗地来说,docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
特点:
-
数据卷可以在容器之间共享或重用数据 -
数据卷中的更改可以直接生效 -
数据卷中的更改不会包含在镜像的更新中 -
数据卷的生命周期一直持续到没有容器使用它为止
总结:容器的持久化和同步操作!容器间也是可以数据共享的
添加数据卷
添加数据卷的方式有两种,第一种是直接通过命令行挂载,第二种是通过dockerFile添加
第一种 命令行挂载
docker run -it -v 宿主机绝对路径目录:容器内目录 镜像名
这个命令会在宿主机和容器内分别建立两个目录,两个目录是对接的,里面的数据可以共享。如果我们不知道数据卷是否挂载成功时,我们可以通过以下方式来检查数据卷的挂载结果。
docker inspect 容器id
我们再挂载的时候还可以给数据卷加上权限,假如我们要宿主机只能读取容器的数据卷内容不能修改,我们可以添加只读权限
docker run -it -v /宿主机绝对路径目录:/容器内目录 :ro 镜像名
第二种 利用dockerFile的形式添加
dockerFile对于docker镜像而言就如同java中某个类的.class文件对应上该类的.java文件。
首先在linux服务器根目录上新建docker文件夹并建立DockerFile文件,使用volume命令(出于可移植可分享的的考虑,用以上 -v /宿主机绝对路径目录 : /容器内目录 的这种方式不能够直接在dockerFile中直接实现,因为宿主机目录是依赖于特定的宿主机的,并不能保证所有的宿主机都存在这样特定的目录)
FROM 镜像名VOLUME ["/生成的目录路径"] -- privileged=trueCMD echo "success build"CMD /bin/bash
相当于命令行: docker run -it -v /宿主机目录路径 : /生成的目录路径
然后我们通过命令行docker build执行我们写好的dockerFile文件(docker build和docker commit两个命令都可以建立docker镜像,docker commit 需要在容器内进行,docker build 不需要)
docker build -f /docker/DockerFile -t 命名空间/镜像名 .参数: -f 指定dockerfile 文件,默认情况下在执行命令的目录下寻找 Dockerfile 文件 -t 指定镜像名称 . 在当前目录下生成镜像
docker build -f /root/Dockerfile -t image/test .
运行我们自己构建的镜像,并进入镜像,查看我们自己生成镜像时创建的文件夹
在宿主机中查看我们在容器卷中创建的文件,和写入的文件内容。
注: 可以使用 ctrl + q + P 退出容器,让容器进入后台运行。退回宿主机中
使用 inspct 命令查看容器信息找到宿主机中相应的容器卷
docker inspect 8c05c7c1eec4
可以看到test.txt已经同步到宿主机对应的挂载目录中
Docker 镜像原理
Docker 镜像加载原理
commit镜像
docker commit 提交容器成为一个新的副本
容器数据卷
什么是容器数据卷
docker理念回顾
将应用和环境打包成一个镜像
如果将数据存在容器中,容器删除,数据就会丢失
容器之间可以有一个数据共享的技术!Docker 容器产生的数据同步到本地
目录的挂载,将我们容器内的目录,挂在到linnux上
容器的持久化和同步操作 容器间也是可以共享数据的!
使用数据卷
方式一:直接使用命令挂在 -v
docker run -it -v 主机目录:容器内目录
修改本地,容器会自动同步
实战 :安装Mysql
将容器删除 挂载在本地的数据卷依旧没有丢失,这就实现了容器数据化功能
具名挂载 和 匿名挂载
结果为这样 这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径
所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载
拓展:
Dockerfile
初识Dockerfile
dockerfile 就是用来构建docker镜像的构建文件,
通过这个脚本可以生成镜像,镜像是一层一层的,每个命令都是一层
这个卷和外部一定有一个同步的目录!
查看一下卷挂载的路径
测试一下刚才的文件是否同步出去了!
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器
多个mysql同步数据
docker 01 上的数据同步到了docker02 上
多个mysql数据共享
结论:
容器之间配置信息的传递,容器数据卷的生命周期一直持续到没有容器使用为止
DockerFile介绍
dockerfile 是用来构建docker镜像的文件!命令参数脚本
构建步骤
1、编写一个dockerfile 文件
2、docker bulid 构建成为一个镜像
3、 docker run 运行镜像
4、docker push 发布镜像
查看官方是怎么做的
很多官方镜像都是基础包,很多功能都没有,我们通常会自己搭建自己的镜像
Dockerfile构建过程
基础知识:
1、每个保留关键字(指令)必须是大写字母
2、 从上到下的顺讯执行
3、#表示注释
4、每一个指令都会创建提交一个新的镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,作镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准吗,必须掌握
步骤:开发、部署、运维。。缺一不可
Dockerfile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
Dockerfile的指令
FROM
实战测试
Docker Hub 中99% 镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行的构建
创建一个自己的centos
FROM centos
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
docker build -f docker文件路径 -t 镜像名:[tag]
我们可以列出本地进行的变更历史
CMD 和 ENTRYPOINT 的区别
vim dockerfile-cmd-test
FROM centos
CMD ["1s ","-a"]
docker build -f dockerfile-cmd-test -t cmdtest .
docker run dd8e4401d72f
..
.docker
env
bin
devet
chome
lib
lib64
[root dockerfile]
docker: Error response from daemon: 0CI runtime create failed: container_linux.go:349: startingcontainer process caused "exec: \"-l\ ": executable file not found in SPATH": unknown.
# cmd的清理下-l 替换了CMD ["1s " , "-a"]命令,-1 不是命令所以报错!
实战:Tomcat镜像
- 准备镜像文件 tomcat压缩包,jdk的压缩包
- 编写Dockerfile文件
FROM centos
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/ADDapache-tomcat-9.0.22.tar.gz /usr/local/
RUNyum-y install vim
ENV MYPATH/usr/localWORKDIR $MYPATH
ENV JAVA HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME/usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CND /usr/local/apache-tomcat-9.0.22/bin/startup.sh & tail -F /url/local/apache-tomcat-9.0.22/bin/logs/catalina.out
- 构建镜像
docker build -t tomcat
发布自己的镜像
- dockerhub 注册自己的账号
- 确认这个账号可以登录
- 在我们服务器上提交自己的镜像
docker login -u 账号名
- 登录完毕后就可以提交自己的镜像
阿里云镜像服务上
1、登录阿里云
2、找到容器镜像服务
3、创建命名空间
4、创建容器镜像
Docker 网络
三个网络
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
va7id_lft forever preferred_lft forever
261: eth0@if262:<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 7ink-netnsid o
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@kuangshen /]
PING 172.18.0.2 (172.18.0.2)56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 tt1=64 time=0.067 ms64 bytes from 172.18.0.2: icmp_seq=2 tt1=64 time=0.055 ms
原理
1、我们每启动一个docker容器。docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术
再次测试 ip addr
2、 再启动一个容器,发现多了一对网卡!
3、我们来测试两个容器之间是否能ping通
结论:tomcat01 和 tomcat02 是公用的一个路由器 ,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我的容器分配一个默认的可用IP
Docker中的所有的网络接口都是虚拟的。虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应网桥一对就没了!
–link
思考一个场景,我们编写了一个微服务,database url =ip,项目不重启,数据ip换掉了,我们希望可以处理在这个问题,可以通过名字来访问网络、
[root@kuangshen/]
[root@kuangshen/]
[root@kuangshen /]
[root@kuangshen /]
PING tomcat02 (172.18.0.3)56(84) bytes of data.
64 bytes from tomcat02 (172.18.0.3): icmp_seq=1 tt1=64 time=0.100 ms64 bytes from tomcat02 (172.18.0.3): icmp_seq=2 tt1=64 time=0.066 ms64 bytes from tomcat02 (172.18.0.3): icmp_seq=3 tt1=64 time=0.067 ms
I
--- tomcat02 ping statistics ---
3 packets transmitted,3 received,0% packet loss, time 1000msrtt min/avg/max/mdev = 0.066/0.077/0.100/0.018 ms
link的原理
其实这个tomcat03 就是在本地配置了tomcat02 的配置
[root@kuangshen /]
127.0.0.1 localhost
::1 locaThost ip6-1ocalhost ip6-loopback
fe00::0 ip6-loca1net
ff00::0 ip6-mcastprefix
ff02::1 ip6-a71nodes
ff02::2 ip6-a11routers
172.18.0.3tomcat02 312857784cd4
172.18.0.4 5ca72d80ebb0
本质探究:–link就是我们在hosts配置中增加了一个172.18.0.3 tomcat02 312857784cd4
这种方式不建议使用
自定义网络
查看所有的docker网络
网络模式
bridge:桥接
none: 不配置网络
host:和宿主机共享网络
container:容器网络连通!(用的少!局限性很大)
测试
docker run -d -p --name tomcat01 tomcat
docker run -d -p --name tomcat01 --net bridge tomcat
[root@kuangshen /]
eb21272b3a35ceaba11b4aa5bbff131c3fb09c4790f0852ed4540707438db052
[root@kuangshen /]
NE TWORK ID NAME DRIVER SCOPE
5a008c015cac bridge bridge local
db44649a9bff composetest_default bridge local
ae2b6209c2ab host host local
eb21272b3a35 mynet bridge local
[root@kuangshen /]
PING192.168.0.3 (192.168.0.3)56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 tt7=64 time=0.085 ms
64 bytes from 192.168.0.3: icmp_seq=2 tt1=64 time=0.070 ms
--- 192.168.0.3 ping statistics ---
2 packets transmitted,2 received,0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.070/0.077/0.085/0.011 ms
[root@kuangshen /]
PING tomcat-net-02 (192.168.0.3)56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.063 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 tt1=64 time=0.070 ms
好处: redis-不同的集群使用不同的网络,保证集群是安全和健康的
mysql -不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
此时可以发现容器成功的加入了mynet网络
[root@kuangshen /]
PING tomcat-net-o1 (192.168.0.2)56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.070 ms
[root@kuangshen /]
结论:假设需要跨网络操作别的容器,就需要使用docker network connect 连通。。。
实战:部署Redis集群
docker network create redis --subnet 172.38.0.0/16
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-bus-port 16379
appendonly yes
EOF
done
for port in $(seq 1 6);\
do \
docker rm -f redis-${port};
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 redis-server /etc/redis/redis.conf;
done
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
>>> 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: 12ccc413ed4e351aceed1d738f4b3abf415be47c 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: dc3f1a2b9da08d94256d3beef69d9f64711815d8 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 2615c949c02207e54664c5f11bd615388f66b043 172.38.0.14:6379
replicates dc3f1a2b9da08d94256d3beef69d9f64711815d8
S: 0d39e27b5f5fdc1353094107df06ccf127f39d5e 172.38.0.15:6379
replicates 12ccc413ed4e351aceed1d738f4b3abf415be47c
S: 64dd8e732978a6cbf68c753ac9dfcaff66599450 172.38.0.16:6379
replicates 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d
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: 12ccc413ed4e351aceed1d738f4b3abf415be47c 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 2615c949c02207e54664c5f11bd615388f66b043 172.38.0.14:6379
slots: (0 slots) slave
replicates dc3f1a2b9da08d94256d3beef69d9f64711815d8
S: 64dd8e732978a6cbf68c753ac9dfcaff66599450 172.38.0.16:6379
slots: (0 slots) slave
replicates 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d
S: 0d39e27b5f5fdc1353094107df06ccf127f39d5e 172.38.0.15:6379
slots: (0 slots) slave
replicates 12ccc413ed4e351aceed1d738f4b3abf415be47c
M: dc3f1a2b9da08d94256d3beef69d9f64711815d8 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 98b58f8d0e29f6fe4317a745d79f3ec11a3fda3d 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
docker 搭建redis集群完成
|