• docker入门到精通一文搞定


    文章目录


    前言

    从docker安装到docker容器、docker镜像、docker网络、docker-compose、dockers-swarm、docker-stack等


    整理自:bilibili 狂神说

    一、Docker概述

    1.Docker为什么会出现?

    传统应用
    缺点1:
    一款产品:开发-上线 两套环境! 应用环境,应用配置很麻烦
    开发 – 运维。问题,我电脑上可以运行!版本的更新,导致服务不可用了!对于运维人员来说,考验就比较大。
    现在情况:开发即运维

    缺点2:
    环境配置十分麻烦,每一个机器都要部署环境(redis集群、Es集群、Hadoop集群…),费时又费力
    发布一个项目:jar+ 环境(redis + mysql + jdk + es等),项目不能带上环境进行打包,配置很麻烦,jar可以跨平台,环境是不能跨平台。如window跨到linux

    缺点3:
    传统:开发做好jar,剩下运维来做
    现在:开发打包部署上线,一套流程做完!
    java – apk – 发布(应用商店) — 张三使用apk – 安装即可用!
    java – jar (环境) – 打包带上环境 (镜像) – (docker仓库 :商店) – 下载我们发布的镜像 – 直接运行使用

    docker的出现:
    Dokcer给以上的问题,提出了解决方案。
    Docker思想:来源于多集装箱,每个箱子互相隔离
    jre – 多个应用(端口错误、配置错误) – 原来环境都是交叉的(用的同一套环境)

    2.Docker相比VM技术

    vm : linux centos 原生镜像(小型电脑) ,隔离,需要开启多个虚拟机;启动几分钟
    缺点:1.资源占用十分多 2.冗余步骤多 3.启动很慢
    
    docker : 隔离,镜像(最核心的环境(4M大小) + jdk + mysql)十分轻巧,运行镜像就可以。启动,秒级别
    
    • 1
    • 2
    • 3
    • 4

    3.Docker 能做什么?

    3.1 比较Docker和虚拟机技术的不同:

    • 传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,然后在这个系统上安装和运行文件
    • 容器内的应用直接运行在宿主机内核,容器没有自己的内核,也不会虚拟出自己的硬件,轻便
    • 每个容器之间是相互隔离,容器内都有一个属于自己的文件系统,互不影响

    3.2 DevOps (开发、运维):4个特点

    1、更快速的交付和部署

    传统:一堆帮助文档、安装程序
    Docker:打包镜像发布测试、一键运行

    2、更便捷的升级和扩容

    使用了Docker之后,我们部署应用就和搭积木一样 轻松
    项目打包为一个镜像,进行扩展。如A服务器出问题了,在B服务器一键运行镜像即可

    3、更简单的系统运维

    在容器化之后,我们的开发,测试环境都是高度一致的。不出出现本地可以用,线上环境不能用

    4、更高效的计算与资源利用(最好的地方)

    Docker是内核级别的虚拟化,可以在一个物理机上运行很多个容器实例。服务器性能可以被压榨到极致。

    二、Docker安装

    1.dokcer架构图:

    在这里插入图片描述

    2.Docker基本组成:3个大要素

    2.1 镜像(image)

    docker镜像就好比一个模板,通过这个模板来创建容器对象
    如tomcat镜像 ==>run ==> tomcat01容器(容器提供服务,最终服务运行就是在容器中);

    2.2容器(container)

    Docker利用容器技术,独立运行一个或一组应用,通过镜像来创建的。
    启动、停止、删除等基本命令
    目前就是可以把一个容器理解为一个建议的linux系统

    2.3仓库(repositry)

    仓库存放镜像的地方

    公有仓库:

    DockerHub (默认国外的)
    阿里云、华为…(配置镜像加速!)

    私有仓库:搭建自己的私有仓库

    3.安装 /卸载

    # 准备工作
    yum -y install gcc
    yum -y install gcc-c++
    
    # 1、卸载旧的docker文件
    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
                      
    # 2、需要的安装包
    yum install -y yum-utils
    
    # 3、设置中央仓库
    # 这里是国外的,非常慢
    yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    
    # 这里是国内的,比较快 - 阿⾥云
     yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    # 4、安装docker相关的内容,最新的:
    #更新yum软件包索引
    yum makecache fast
    
    # 5、docker-ce 社区版本(一般使用),docker-ee 企业版;如报错看下面解决方式
    yum install -y docker-ce docker-ce-cli containerd.io
    
    # 6、启动docker
    systemctl start docker # 第一步:启动docker服务端
    docker version	# 第二步:启动docker服务端后,查看docker版本。不然只能看到docker-client的版本
    
    # 7、运行hello-world
    docker run hello-world
    
    # 8、查看下载的hello-world镜像:(每个服务打包成镜像进行发布)
    docker images
    
    #了解:卸载docker
    yum remove docker-ce docker-ce-cli containerd.io # 卸载安装的docker软件
    rm -rf /var/lib/docker #删除docker在系统的数据文件,docker默认的工作路径
    
    # 9、开机启动
    sudo systemctl enable docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    备注:如低5步报错则修改下面:
    在这里插入图片描述

    4.阿里云镜像加速

    1.登录阿里云,找到【容器镜像服务】
    2.找到镜像加速地址(每个人地址不一样):
    在这里插入图片描述
    3.在系统中配置docker加速器,如上图代码

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://dk3u1mig.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.docker run的执行流程:

    在这里插入图片描述

    6.docker底层原理

    docker到底是怎么工作的?
    docker是一个client-server结构的系统,docker的守护进程运行在宿主机上。通过socket与客户端访问!
    docker server接受client指令,就会执行容器命令
    在这里插入图片描述

    7.docker为什么比VM快?

    1.docker有比VM更少的抽象层。
    2.docker利用的是宿主机的内核,VM需要GuestOS。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UaYQB6tR-1668762515097)(C:\Users\msi\AppData\Roaming\Typora\typora-user-images\image-20220621150946306.png)]
    所以:新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载的Guest OS,分钟级别的启动。而docker是利用宿主机的操作系统,省略了这个复杂过程,是秒级别启动!

    3.docker与vm对比
    在这里插入图片描述

    三、Docker常用命令(非常多)

    1.帮助命令

    docker version # 显示docker版本信息
    docker info #显示docker的系统信息,包括镜像和容器
    docker 命令 --help # 帮助命令;如docker images --help
    
    • 1
    • 2
    • 3

    帮助文档地址:docker官方帮助文档
    在这里插入图片描述

    2.镜像命令

    2.1 docker images

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

    docker images # 列出所有镜像
    # 可选项
    -a, --all 	# 列出所有镜像
    -q, --quiet # 只显示镜像的id
    
    • 1
    • 2
    • 3
    • 4

    2.2 docker search

    搜索远程镜像

    docker search mysql
    # 可选项
    -f 过滤 # --filter=STARS=3000
    例子:docker search mysql --filter=STARS=3000
    docker search mysql -f=STARS=3000
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.3 docker pull

    远程拉取镜像到本地

    docker pull mysql
    或
    docker pull mysql[:tag] # tag版本,一般都会加上版本 (通过分层下载,联合文件系统)
    
    # 两个命令等价
    docker pull mysql = docker pull mysql:5.7
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.4 docker rmi

    删除镜像

    docker rmi -f 镜像名/镜像ID	# -f 强制,多个删除用空格区分
    docker rmi -f $(docker images -qa)	# 删除所有本地镜像
    
    • 1
    • 2

    3.容器命令

    说明:有了镜像才能创建容器,以下载一个centos镜像来测试学习

    docker pull centos
    
    • 1

    3.1docker run

    新建容器并启动

    docker run [可选参数] image 
    
    #参数说明
    --name="name"  	容器名字,用来区分容器
    -d				后台方式运行
    -it				使用交互方式运行,进入容器查看内容
    -p				指定容器的端口 -p 8080:8080
    	-p ip:主机端口:容器端口 # ip是主机ip吗?
    	-p 主机端口:容器端口(常用)
    	-p 容器端口
    	容器端口
    -P 				随机指定端口
    
    # 测试:启动并进入容器
    [root@localhost ~]# docker run -it centos /bin/bash
    [root@1e973315dad7 /]# 	# 启动已经进入了容器,是一个最初版的centos
    [root@1e973315dad7 /]# exit; # 停止并退出容器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.2docker ps

    查看所有在运行的容器

    docker ps		# 正在运行的
    docker ps -a 	# 曾经运行的+正在运行的容器
    docker ps -n=? 	# 最近创建的容器,显示数量-n。
    docker ps -q 	# 只显示容器的id
    #eg: docker ps -a -n=2 # 显示最近的两个容器
    
    • 1
    • 2
    • 3
    • 4
    • 5

    进入容器后退出容器

    exit 		# 停止并退出容器
    ctrl+P+Q	# 容器不停止且退出
    
    • 1
    • 2

    3.3docker rm

    删除容器

    docker rm 容器id	# 移除单个,如果要强制删除需要加参数:-f
    docker rm -f $(docker ps -qa)	  # 删除所有容器
    docker ps -a -q | xargs docker rm # 删除所有的容器
    
    • 1
    • 2
    • 3

    3.4 容器启动、重启、关闭

    docker start 容器ID	#启动容器
    docker restart 容器ID #重启容器
    docker stop 容器ID 	#关闭容器
    docker kill 容器ID	#强制关闭容器
    
    • 1
    • 2
    • 3
    • 4

    4.其他常用命令

    4.1后台启动命令

    docker run

    # 命令 docker run -d 镜像名
    docker run -d centos
    	#存在问题:docker ps时发现centos停止了
    	#常见的坑:docker容器后台运行,必须要有一个前台进程,如果docker发现没有cli,那么后台应用就会自动停止
    	#启动nginx,容器启动后,发现自己没有提供服务,就会立即停止。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.2日志命令

    docker logs

    docker logs -f -t --tail n 容器ID # n日志条数,t 时间戳;f 规范显示format
    
    # 自己写一段shell脚本
    "while true;do echo biebiebie;sleep 1;done"
    docker run -d centos /bin/sh -c "while true;do echo biebie;sleep 1;done"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.3查看容器中进程信息

    docker top 容器ID

    4.3查看容器内部元数据

    docker inspect 容器ID

    4.4 进入正在运行的容器

    # 方式一:docker exec
    docker exec -it 容器ID /bin/bash # /bin/bash:通过哪个命令行进入容器,还有/bin/sh
    
    # 方式二:docker attach 
    docker attach 容器ID
    正在运行的代码.....
    
    #docker exec	#开启新的终端进入正在运行的容器,可以操作命令(常用)
    #docker attach  #进入容器正在执行的终端,不会启动新的终端
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.5 从容器内拷贝文件到主机上

    docker cp 容器ID:容器内路径 目的主机路径
    
    • 1

    4.6 从主机拷贝文件到容器

    挂在的方式

    5.docker各模块命令交互图

    在这里插入图片描述

    6.docker安装nginx(练习)

    #1.启动docker服务,并搜索镜像;建议先看hub.docker.com上进行搜索
    docker search nginx
    #2.远程下载镜像
    docker pull nginx:[版本号]
    #3.启动nginx
    docker run -d  --name nginx01 -p 3344:80 nginx
    #4.测试是否启动成功:成功
    curl localhost:3344
    	
    	#安装curl包
    	#1.下载
    	wget --no-check-certificate https://curl.haxx.se/download/curl-7.80.0.tar.gz
    	#2.解压
    	tar zxvf curl-7.80.0.tar.gz
    	#3.执行配置文件
    	cd curl-7.80.0
    	./configure
    	#4.make编译
    	make
    
    
    # 进入容器查看容器ip:cat /etc/hosts
    # 外部查看:docker inspect 容器ID/名称
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    7.docker端口暴露的概念:

    在这里插入图片描述
    思考:我们每次改动nginx配置文件,都需要进入容器内部,很麻烦,可以通过容器外部修改直接映射到内部文件吗? -v(数据卷技术)

    8.docker安装tomcat

    # 官网使用
    docker run -it --rm tomcat:9.0 # --rm:容器运行停止后即删除,一般用于测试
    
    # 下载启动
    docker  pull tomcat
    
    # 启动运行
    docker run -d -p 3355:8080 --name tomcat01 tomcat:[TAG]
    
    #测试,启动成功
    
    #进入容器
    docker exec -it tomcat01 /bin/bash
    # 发现问题:1.linux命令少了很多 2.在tomcat的webapps里面没内容
    # 原因:阿里云的镜像的原因:阿里云镜像默认是最小镜像,所有不必要的内容都会剔除
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    9.docker部署 es + kibana

    9.1es安装

    # es 暴露的端口很多
    # es 十分耗内存
    # es 的数据一般需要存放到安全目录! 即挂载
    
    # 1.下载镜像与启动:
    docker run -d --name elasticsearch  -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
    #其中:--net somenetwork是docker的网络配置
    
    # 2.启动完之后,linux卡死了
    docker stats # 查看docker CPU的状态
    
    # 3.测试es是否启动成功
    docker ps
    
    # 4. 赶紧关闭,增加内存的限制。修改es的配置文件 
    -e 环境修改
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    docker ps # 查看docker进程
    在这里插入图片描述

    9.2安装kibana连接es

    思考:网络如何联通?
    在这里插入图片描述

    10.可视化-管理镜像的工具

    10.1 portainer (不是最佳)

    什么是portainer?
    dokcer图像化界面管理工具。提供一个后台面板供我们操作

    # 1.拉取镜像安装并启动
    docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
    
    # 2.测试是否启动成功
    在宿主机上执行:curl localhost:8088
    
    # 3.通过浏览器访问:如下图
    宿主机ip:8088  -> 192.168.229.131:8088
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    # 4.一般连接选择本地,如下图
    
    • 1

    在这里插入图片描述

    # 5.进入之后的面板
    
    • 1

    在这里插入图片描述

    10.2 Rancher (CI/CD再用)

    四、Docker镜像(核心)

    学完镜像才算入门docker

    镜像是什么?

    镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。
    它包含运行某个软件所需要的所有内容:包括代码、运行时、库、环境变量和配置文件。
    所有的应用,直接打包成docker镜像,就可以直接跑运行了。方面扩展和部署

    如何得到镜像:

    - 从远程仓库下载
    - 朋友拷贝
    - 自己制作一个镜像,Dockerfile
    
    • 1
    • 2
    • 3

    1.Docker镜像加载原理

    UnionFS(联合文件系统) :

    UnionFS(联合文件系统):UnionFS文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同事可以将不同的目录挂在到同一个虚拟文件系统下。UnionFS是docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像)可以制作各种具体的应用镜像。
    特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
    联合文件系统类似于git的版本提交

    Docker镜像加载原理

    docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS
    bootfs(boot file system)引导文件系统。主要包含了bootloader和kernel,bootloader主要引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与典型的Linux/Unix系统是一样的,包含boot加载器和啮合。当boot加载器完成之后整个内核就在内存中了,此时内存的使用权有bootfs转交给内核,此时系统也会写在bootfs。
    rootfs(root file system)根文件系统,在bootfs智商。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。footfs就是各种不同的操作系统发行版,比如ubuntu,Centos等

    在这里插入图片描述

    思考:平常我们安装虚拟机centos都是好几个G,为什么Docker这里才200M?
    在这里插入图片描述

    对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了。因为底层直接用Host和kernel,自己只需要听过rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

    2.镜像分层理解

    分层的镜像

    在下载镜像时,观察下载时输出的日志,可以看到是一层一层的在下载!如图:
    在这里插入图片描述

    思考:为什么docker镜像要采用这种分层的结构呢?
    答:最大的好处就是资源共享了! 比如有多个降序都从相同的base镜像构建而来,那么宿主机啊只需要在磁盘上保留一份base镜像,同事内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像是每一次都可以被共享的。

    思考:为什么docker的继承只需要加载一次基础镜像而java中基础需要每次加载基类?
    答:java中的继承是有状态的,需要记录每个基类的数据。docker继承是无状态的,所以只加载存储一次即可

    查看镜像分层的方式可以通过docker image inspect命令
    理解:所有的dokcer镜像都起始于一个基础镜像,当进行修改或增加内容时,就会在当前镜像层之上,创建新的镜像层。

    例子:假如基于Ubuntu Linux 16.04创建一个新的镜像,这就新镜像的第一层;如果在该进行中添加Python包,就会在基础镜像层之上创建第二个镜像层;如继续添加一个安全补丁,那么就会创建第三个镜像层。

    如下图:
    在这里插入图片描述
    在添加额外的镜像层的同时,镜像始终保持当前所有镜像的并集组合。如下如每层镜像3个文件,打包镜像时会有6个文件,分别来自于不同的镜像层。

    如下图:
    在这里插入图片描述
    下图中展示了稍微复制的三层镜像,在外部看来整个镜像只有6个文件,这是因为文件7是文件5的更新版
    在这里插入图片描述

    这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件,这样就是的文件的更新版本作为一个镜像层添加到镜像中。
    Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
    Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都是基Linux中对应的文件系统或者快设备技术,并且每种存储引擎都有自己的特点。
    Docker在Windows上仅支持windowsFilter这一种存储引擎,并且该引擎基于NTFS文件系统之上实现了分层和CoW[1]。

    下图展示了与文件系统相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图
    在这里插入图片描述

    特点
    Docker现有pull的镜像都是只读的,当容器启动时,一个新的可写层被加载到docker现有镜像层的顶部,这一层就是容器层,容器之下的都是镜像层。
    我们对容器的所有操作都是正在新建一个自己的镜像层,容器commit提交就成为一个新的镜像。

    3.commit:容器提交为新的镜像

    命令:docker commit 
    解释:提交一个容器成为新的镜像副本
    
    # 命令和git命令类似
    docker commit -m="提交描述信息" -a="作者" 容器ID 目标镜像名:[TAG]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    以tomcat为例子提交新镜像

    # 1、启动一个默认的tomcat
    # 2、发现这个默认的tomcat是没有webapps应用,是因为镜像纯净的原因。官方的镜像默认webapps文件夹下是没有文件的
    # 3、自己拷贝进去了基本文件
    # 4、讲文明操作过的容器通过commit提交为一个镜像(提交的镜像会保存在docker本地,与git也类似),我们以后就使用这个新提交的镜像即可
    [root@localhost ~]# docker commit -a="bie" -m="add webapps app" 70b6e29900d3 tomcat02:1.1
    # 5、如下图
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    学习方式说明:理解概念,但是一定要实践,最后理论和实践相结合一次搞定这个知识。

    五、容器数据卷(核心)如何挂载

    docker精髓:容器数据卷、DockerFile、Docker网络原理三项

    什么是容器数据卷

    数据?如果数据都在容器中,那么我们删除容器,数据就会丢失! 需求:数据可用持久化
    mysql安装在docker容器中,容器删除 = 删库跑路! 需求:mysql数据可以存储在本地

    容器之间可以有一个数据共享的技术! 卷技术,容器挂载(容器内的目录,挂载到宿主机)
    总结:容器的持久化和同步操作!容器间也是可以数据共享的!

    使用数据卷:
    1.volumns挂载
    2.mounts挂载

    docker run -it -v 主机目录:容器目录
    
    # 1.执行命令进行挂载
    docker run -it -v /home/ceshi:/home centos /bin/bash
    
    # 2.测试,在容器home目录下创建test.txt
    结果:宿主机目录下 /home/cesh 有test.txt文件
    
    # 3.docker inspect 容器id/容器名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    1.安装mysql

    思考:mysql的持久化问题?data目录挂载

    会占用两倍存储空间

    # 1.远程下载mysql镜像
    docker pull mysql:5.7
    
    # 2.启动mysql
    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 mysql01 mysql:5.7
    
    # 注意:conf.d文件为空,正常,需要人为配置
    
    # 3.测试:启动成功后用sqlyog或navicat连接
    telnet 192.168.229.131 3310 # 允许登录
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.具名挂载和匿名挂载

    # 1.匿名挂载
    -v 容器内路径!
    -P 随机映射端口 -p指定映射端口
    
    docker run -d -P --name nginx01 -v /etc/nginx nginx
    
    #查看所有挂载映射
    docker volume ls 
    如下显示:
    DRIVER    VOLUME NAME
    local     8a5ae8e2f309a8619fdfb873ce561883498cc1a04572899f0e174548137f45fb	#匿名挂载,是真实存在的目录
    local     9ba4a4c682727d7584f9143788d66491d9bb267c23b659e002b8b9987379c487  #匿名挂载,是真实存在的目录
    
    
    # 2.具名挂载
    docker run -d -P -v juming-nginx:/etc/nginx --name nginx02 nginx
    docker volumn ls
    如下显示:
    DRIVER    VOLUME NAME
    local     8a5ae8e2f309a8619fdfb873ce561883498cc1a04572899f0e174548137f45fb
    local     9ba4a4c682727d7584f9143788d66491d9bb267c23b659e002b8b9987379c487
    local     juming-nginx	# 具名挂载
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    下图中:inspect时,Name就是挂载名
    在这里插入图片描述

    几种挂载语法

    # 3.几种挂载-v的写法:
    匿名写法:
    -v /宿主机路径:容器内路径 	# 带/绝对路径,没有名字,例子:-v /home/nginx:/etc/nginx
    -v 容器内路径 		# 例子:-v /etc/nginx
    
    具名写法:
    -v 卷名:容器内路径 	# 例子:-v juming-nginx:/etc/nginx 
    
    # 4.总结
    所有docker容器内的卷,没有指定目录的情况下都是在"/var/lib/docker/volumes/xxxxx(卷名)/_data"
    
    docker工作目录:"/var/lib/docke"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    # 5.拓展
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx # ro:只读,只能宿主机改变内容,容器内无法改变此目录及数据
    docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx # rw:可读写,默认情况
    
    • 1
    • 2
    • 3

    3.初始dockerfile:脚本生成镜像

    Dockerfile就是用来构建docker镜像的文件!实际上就是命令脚本,通过脚本生成镜像
    之前有commit构建docker镜像

    # 1.编写dokcerfile文件,脚本如下:
    FROM centos #基于centos镜像
    
    VOLUME ["volume1","volume2"] # 这里的写法就是匿名挂载,只写了容器内的目录
    
    CMD echo "---------------end----------------"
    
    CMD /bin/bash
    
    # 2.运行脚本
    docker build -f /home/docker-test-volume/dockerfile1 -t kuangshen-centos:1.0 .
    #-f 脚本路径; -t 打包版本 ;.标示存放位置
    
    # 3.查看镜像是否构建成功
    docker images;
    
    # 4.启动自己构建的镜像
    docker run -it kuangshen-centos /bin/bash
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    发现挂载目录如下图:
    在这里插入图片描述

    4.数据卷容器(是一个容器):多个dokcer容器共享一份数据(备份机制)

    被挂载的容器:就是数据卷容器
    在这里插入图片描述
    启动3个容器进行测试:

    #启动数据卷容器:
    docker run -it --name docker01 kuangshen-centos:1.1
    
    #启动第2个容器:
    docker run -it --name dokcer02 --volumes-from docker01 kuangshen-centos:1.1
    
    #启动第3个容器:
    docker run -it --name dokcer03 --volumes-from docker01 kuangshen-centos:1.1
    
    #启动第4个容器:挂载docker02上
    docker run -it --name dokcer04 --volumes-from docker02 kuangshen-centos:1.1
    
    命令:--volumes-from 类似于java的继承
    
    #测试,删除docker01之后,其他容器中的挂载目录还是有数据
    #总结:只要有一个容器还在运行,那么数据就不会丢失
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    使用docker进行mysql数据同步:

    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 mysql01 mysql:5.7
    
    docker run -d -p 3311:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumns-from mysql01 mysql:5.7
    
    • 1
    • 2
    • 3

    (测试时:数据挂载成功了。通过ssh链接时,哪台先开启,就可以连接上哪台。调换先后顺序后,发现创建的数据库test成功,没过3分钟,后启动的mysql自动挂了,很奇怪的现象)

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

    六、DockerFile

    1.DockerFile介绍

    dockerfile是用来构建docker镜像的文件,是一个命令参数的脚本!
    构建步骤:
    1、编写一个docker文件
    2、docker build构建成为新的镜像
    3、docker run运行镜像
    4、docker push发布镜像(DockerHub,阿里云镜像仓库)
    追问:有本地镜像仓库?

    2.Dockfile的构建过程

    DockerFile的基础知识

    1.每个保留关键字(指令)都必须是大写字母
    2.执行顺序从上到下
    3.#标示注释
    4.每一更的指令都会创建提交一个新的镜像层,并提交
    在这里插入图片描述
    dockerfile是面向开发的,我们以后要发布项目,做镜像就需要编写dockerfile文件,这个文件十分简单。
    docker镜像已经成为开发交付的一个趋势,逐步取代jar,war包

    步骤:开发,部署,运维,缺一不可
    Dockerfile:构建文件,定义了一切的步骤,原代码
    DockerImages:通过dockerfile构建生成的镜像,最终发布和运行的产品
    Docker容器:容器就是镜像运行起来提供服务器

    3.Dockfile的指令

    以前都是我们使用别人的,现在我们知道这些指令后,自己练习写一个镜像

    FROM		#基础镜像,一切从这里开始构建
    MAINTAINER 	#镜像作者,姓名+日期
    RUN			#镜像构建的时候需要运行的命令
    ADD			#添加文件,如步骤:tomcat镜像,添加tomcat的压缩包
    WORKDIR		#镜像的工作目录
    VOLUMES		#挂载的目录
    EXPOSE		#暴露端口
    CMD			#指定这个容器启动时需要运行的命令,只有最后一个会生效。有覆盖动作
    ENTRYPOINT 	#指定这个容器启动时需要运行的命令,是追加,无覆盖动作
    ONBUILD		#当构建一个被继承Dockfile这个时候就会运行ONBUILD命令
    COPY		#类似ADD,将我们文件拷贝到镜像中
    ENV			#构建的时候设置环境变量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    4.实战一:构建自己的centos

    DockerHub中99%的镜像都是从这个基础镜像构建而来的(FROM scratch)
    在这里插入图片描述

    在原有的centos上,添加vim包和ipconfig包

    # 1.编写自己的dockerfile文件
    FROM centos # FROM cenos1
    MAINTAINER biejiahao<729941382@qq.com>
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    RUN yum -y install vim 
    RUN yum -y install net-tools
    
    EXPOSE 80
    CMD echo $MYPATH
    CMD echo "------end-------------"
    CMD /bin/bash
    
    #2.通过这个文件构建镜像
    # 命令:docker build -f dockerfile文件路径 -t 镜像名:[TAG] .
    本地测试时,这里有问题:
    需要将原始centos upstream后发布新版的cenos1,然后再进行build操作
    地址:https://blog.csdn.net/weixin_43252521/article/details/124409151
    
    构建成功输出的信息:
    Successfully built bf40fedf541b
    Successfully tagged mycentos:0.1
    
    # 3.测试运行
    docker run -it mycentos:0.1 /bin/bash
    vim test.java # 成功
    ifconfig # 成功
    
    # 4.查看镜像构建历史
    docker history 镜像id
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    5.CMD 与ENTRYPOINT的区别

    CMD #指定这个容器启动时需要运行的命令,只有最后一个会生效。有覆盖动作
    ENTRYPOINT #指定这个容器启动时需要运行的命令,是追加,无覆盖动作

    6.CMD进行dockerfile测试

    #1 编写dockerfile-cmd的dockerfile文件
    FROM centos
    CMD ["ls","-a"]
    
    #2 build成为新镜像
    docker build -f dockerfile-cmd -t centos-cmd:1.0 .
    
    #3 测试启动centos-cmd:1.0镜像
    docker run centos-cmd:1.0 # 成功
    
    #4.测试加参数,本意想表达 ls -al命令
    docker run centos-cmd:1.0 -l # 控制台报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    7.ENTRYPOINT进行dockerfile测试

    #1 编写dockerfile-entrypoint的dockerfile文件
    FROM centos
    ENTRYPOINT ["ls","-a"]
    
    #2 build成为新镜像
    docker build -f dockerfile-entrypoint -t centos-entrypoint:1.0 .
    
    #3 测试启动centos-cmd:1.0镜像
    docker run centos-entrypoint:1.0 # 成功
    
    #4.测试加参数,本意想表达 ls -al命令
    docker run centos-entrypoint:1.0 -l # 成功
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    8.实战二:构建tomcat镜像

    1.准备镜像文件tomcat压缩包,jdk压缩包
    在这里插入图片描述
    2.编写dockerfile文件,官方命名Dockerfile,build时会自动寻找这个文件并执行,就不需要 -f 指定文件了。

    FROM cenos1
    MAINTAINER biejihao<729941382@qq.com>
    
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u301-linux-x64.tar.gz /usr/local
    ADD apache-tomcat-8.5.81.tar.gz /usr/local
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_301
    ENV CLASSPATH $JAVAHOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    
    ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.81
    ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.81
    
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-8.5.81/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.81/bin/logs/catalina.out
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.构建镜像

    #1.进入到dockerfile文件目录
    #2.执行构建命令
    docker build -t diytomcat:1.0 .
    
    • 1
    • 2
    • 3

    4.启动镜像

    docker run -d -p 9090:8080 --name kuangshentomcat -v /home/build/tomcat/test:/usr/local/apache-tomcat-8.5.81/webapps/test -v /home/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.5.81/logs diytomcat:1.0
    
    • 1

    5.访问测试

    curl localhost:9090
    # 如果访问不到,就是tomcat没有启动成功
    # 1.先排除启动命令是否有误 2.再排除dockerfile脚本是否有误(第一次多半是脚本问题)
    
    • 1
    • 2
    • 3

    6.发布项目(由于做了卷挂载,那么直接在宿主机进行发布项目即可)

    在宿主机挂载的test目录进行操作:
    mkdir WEB-INF
    cd WEB-INF
    vim web.xml
    
    • 1
    • 2
    • 3
    • 4

    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_3_1.xsd"
             version="3.1">
            
    </web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    将index.jsp文件存放到项目test目录下

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <body>
    <h2>Hello World!</h2>
     
     <%
     System.out.println("--------------test---------------------");
     %>
     
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    启动新的tomcat容器

    结果:通过浏览器可以访问成功,并且后台日志可以记录访问信息

    9.发布镜像到dockerhub

    1.需要注册账号:hub.docker.com
    2.确定这个账号可以登录即可
    docker login -u 账号 -p 密码
    3.在服务器上提交自己的镜像
    docker push 镜像名:[tag]

    10.发布到阿里云镜像服务

    1.登录阿里云
    2.找到容器镜像服务
    3.创建命名空间(是一个和大的项目组)
    在这里插入图片描述4.创建容器镜像(创建时,选择本地仓库)
    在这里插入图片描述
    5.浏览阿里云信息
    在这里插入图片描述
    6.退出dockerhub账号
    dokcer logout

    7.登录阿里云账号
    参考第五点做法

    小结

    在这里插入图片描述

    七、Docker网络原理

    1.理解dokcer0

    理解docker网络,就是理解dokcer0的网络:docker0=路由器 网络请求中转
    清空所有的镜像与容器,方便学习docker网络时的理解
    在这里插入图片描述

    # 启动一个tomcat
    docker run -d -P  --name tomcat01 tomcat
    # 查看容器的内部网络地址 ip addr,发现容器启动的时候会得到一个eth0@if262 ip地址是docker分配的
    docker exec -it tomcat01 ip addr
    
    # 异常请参考文章:https://blog.csdn.net/User_bie/article/details/125642454
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    # 思考:linux宿主机能不能ping通容器内部? 答案:可以
    > 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.077 ms
    64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.037 ms
    .....
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.网络原理

    1、每启动一个docker容器,docker就会给容器分配一个ip,完美只要安装了docker就会有一个dokcer0网卡
    利用的是桥接模式,使用的是evth-pair技术
    宿主机再次测试ip addr
    在这里插入图片描述
    2、再次启动一个新的容器,发现又多了一对网卡
    在这里插入图片描述

    # 我们发现这个容器带来网卡,都是一对一对
    # evth-pair就是一对虚拟设备接口,都是成对出现,一端连着协议,一端彼此相连
    # 正因为有了这个特性,一般用evth-pair充当一个桥梁,专门连接各种虚拟网络设备
    # Openstac,docker容器之间的连接,OVS的连接,都是使用的是evth-pair技术
    
    • 1
    • 2
    • 3
    • 4

    3、测试tomcat01是否可以ping同tomcat02 答:可以

    结论:tomcat01与tomcat02是公用一个路由器,dokcer0
    所有容器在不指定网络的情况下,都是通过docker0进行路由,docker0会给容器分配一个默认可用的IP。可用ip数为254个
    如:17.18.0.1/16 则可以分配 255*255 - 2(0.0.0.0 与255.255.255.255)个ip
    如:17.18.0.1/24 则可以分配 255-1(17.18.0.1)=254 个ip

    小结

    Docker使用的是linux的桥接:
    在这里插入图片描述
    dokcer中所有的网络接口都是虚拟的。虚拟的转发效率高!
    在这里插入图片描述

    3.- - link

    思考:

    场景,编写一个微服务,database url=ip,项目不重启,数据库ip换了,能否根据名称访问容器而不根据ip访问。因为docker容器每次启动ip都是会变化的
    在这里插入图片描述
    探究:docker network inspect
    在这里插入图片描述

    docker --link 本质:hosts配置

    –link后,会在/etc/hosts配置文件中添加一份映射
    在这里插入图片描述
    目前已经不推荐使用docker0,需要自定义网络:docker0不支持 容器名连接访问

    4.自定义网络:容器互联

    查看所有的docker网络
    在这里插入图片描述
    网络模式:
    bridge:桥接docker(默认)
    none:不配置网络,不建议
    host:和宿主机共享网络
    container:容器网络连通(用的少,局限性很大,不建议)

    测试:

    #1.直接启动的命令 --net bridge 这个参数是默认使用的,即代表dokcer0
    docker run -d -P --name tomcat01 --net bridge tomcat
    
    # docker0 特点: 默认网络,域名不能访问, --link可以打通进行连接
    
    #2.我们可以自己定义一个网络,以后启动的容器就在自己定义的网络内运行
    docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mybet
    
    --driver 网络连接方式
    --subnet 子网
    --gateway 子网网关
    #家用所有的路由器都是这个网络配置
    
    #3.查看当前docker网络
    docker networkd ls
    #成功
    
    f5aae4c0d555   bridge    bridge    local
    66ad3244c031   host      host      local
    c54074b0a393   mybet     bridge    local
    044d666dd3d7   none      null      local
    
    #4.使用自定义网络启动tomcat
    docker run -d -P --name tomcat-net-01 --net mybet tomcat
    docker run -d -P --name tomcat-net-02 --net mybet tomcat
    
    #5.再次两个容器进行ping
    docker exec -it tomcat-net-01 ping 192.168.0.3  #192.168.0.3为tomcat-net-02的ip
    #成功
    docker exec -it tomcat-net-01 ping tomcat-net-02 
    #成功
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    自定义的网络docker已经帮我们维护好了对应的网络关系,推荐平时使用自定义网络
    好处:
    mysql/redis:不同的集群使用不同的网络,保证集群是安全和健康的

    5.docker网络连通

    如mysql集群需要访问不同网段的redis集群
    在这里插入图片描述

    A网络容器需要与B网卡连通,才能访问B网段下的服务
    在这里插入图片描述

    # 测试tomcat01连通mybet网络
    docker network connect mybet tomcat01
    
    # 如下图:连通之后,直接会把这个容器加入到这个网络中
    # 这种情况再docker中称为一个容器两个ip,比如阿里云服务器,公网ip与私网ip
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    结论:假设要跨网络操作,需要使用docker network connect进行连通

    6.实战:部署redis集群

    redis cluster 多主从集群
    在这里插入图片描述

    # 1.创建redis集群网络
    docker network create redis --subnet 172.38.0.0/16
    
    # 2.通过脚本创建6个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
    
    docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
    -v /mydata/redis/node-${port}/data:/data \
    -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
    -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
    
    done
    
    #3.创建redis集群
    #3.1进入到某个redis # 以3-master为例
    docker exex -it 82a74538a215 /bin/sh
    
    #3.2执行创建集群
    redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
    
    #3.3中途执行yes
    
    # 注意redis-cli操作集群时,登录需要加参数-c,如:redis-cli -c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    小结:使用了docker之后,所有的技术使用的更简单

    7.springboot项目打包docker镜像

    1.架构springboot项目
    2.打包应用
    3.编写dockerfile

    FROM java:8
    
    COPY *.jar /app.jar
    
    CMD ["--server.port=8080"]
    
    EXPOSE 8080
    
    ENTRYPOINT ["java","-jar","/app.jar"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.构建镜像
    5.发布运行

    八、IDEA整合Docker

    docker单机版(一至八点)

    九、Docker Compose (编排管理,单机环境管理)

    简介

    Docker Compose轻松高效来管理容器,定义运行多个容器,一键上线。
    Compose是Docker官方的开源项目,需要安装。
    Dockerfile 文件能让程序再任何地方运行。web服务,redis,mysql,nginx…多个容器

    version: "3.9"  # optional since v1.27.0
    services:
      web:
        build: .
        ports:
          - "8000:5000"
        volumes:
          - .:/code
          - logvolume01:/var/log
        links:
          - redis
      redis:
        image: redis
    volumes:
      logvolume01: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Compose:2个重要概念
    服务services:容器-应用(web/redis/mysql…)
    项目project:一组关联容器。如博客,web项目,mysql等

    1.安装

    # 1.国外镜像,下载慢
    curl -SL https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
    
    # 国内镜像,下载很快
    sudo curl -L https://get.daocloud.io/docker/compose/releases/download/v2.6.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
    
    # 2.文件授权
    sudo chmod +x /usr/local/bin/docker-compose
    
    # 3.是否安装成功
    docker-compose --version
    
    
    卸载:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.测试与体验app.py

    官网:https://docs.docker.com/compose/gettingstarted/
    1.创建应用

    #1.创建一个文件夹
    cd /home && mkdir composetest && cd composetest
    
    #2.创建app.py运行脚本,注意空格缩进的问题
    import time
    
    import redis
    from flask import Flask
    
    app = Flask(__name__)
    cache = redis.Redis(host='redis', port=6379)
    
    def get_hit_count():
        retries = 5
        while True:
            try:
                return cache.incr('hits')
            except redis.exceptions.ConnectionError as exc:
                if retries == 0:
                    raise exc
                retries -= 1
                time.sleep(0.5)
    
    @app.route('/')
    def hello():
        count = get_hit_count()
        return 'Hello World! I have been seen {} times.\n'.format(count)
    
    
    #3.创建文件requirements.txt需要导入的包
    内容:
    flask
    redis
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    2.创建dockerfile

    # 创建Dockerfile文件,目录/home/composetest
    vim Dockerfile
    
    # syntax=docker/dockerfile:1
    FROM python:3.7-alpine
    WORKDIR /code
    ENV FLASK_APP=app.py
    ENV FLASK_RUN_HOST=0.0.0.0
    RUN apk add --no-cache gcc musl-dev linux-headers
    COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    EXPOSE 5000
    COPY . .
    CMD ["flask", "run"]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.创建docker-compose.yml文件(定义整个服务,需要的环境。web redis mysql 等),完成的上线服务

    # 创建docker-compose.yml文件,目录/home/composetest
    vim docker-compose.ym
    
    version: "3.9"
    services:
      web:
        build: .
        ports:
          - "8000:5000"
      redis:
        image: "redis:alpine"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.构建和运行compose

    #目录下执行:/home/composetest
    docker compose up
    
    • 1
    • 2

    5.停止compose

    cd /home/composetest && docker-compose stop 
    crl + c
    
    • 1
    • 2

    3.compse启动流程:docker-compose up

    1、创建compose网络
    2、执行docker-compose.yml
    3、启动服务:

    ⠿ Network composetest_default Created 0.3s
    ⠿ Container composetest-redis-1 Created 0.1s
    ⠿ Container composetest-web-1 Created 0.1s

    docker-compose up:执行后,会自动下载镜像并启动

    [root@localhost ~]# docker service ls;# 查看所有服务
    Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
    
    • 1
    • 2

    默认的服务名:文件名_服务名 _num
    注意:_num:副本数量

    4.docker-compose 网络规则

    #1.查看docker网络
    docker network ls;
    
    #2.查看docker-compose默认网络下的应用
    docker network inspect 240d9f259d39
    
    #3.如下图,通过compose启动的项目都在同一个网段下,可以通过域名直接访问调用,不用通过ip进行访问
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    在这里插入图片描述

    docker小结:

    1.docker镜像,run=>容器
    2.dockerfile构建镜像,服务打包
    3.docker-compse启动项目(编排,多个微服务/环境)
    4.精通docker网络

    6.yaml规则

    # 可以理解为核心3层
    version: '' 	# 版本
    
    services: 		#服务
      服务1: web
      	#dokcer容器配置
      	images
      	build
      	network
      
      服务2: redis
    
    #其他配置 网络/卷/全局规则等
    volumes:
    networks:
    configs:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    7.compose测试:一键启动博客

    #1.home目录下创建文件夹:
    cd /home && mkdir my_wordpress && cd my_wordpress/
    
    #2.编写docker-compose.yml文件
    services:
      db:
        # We use a mariadb image which supports both amd64 & arm64 architecture
        image: mariadb:10.6.4-focal
        # If you really want to use MySQL, uncomment the following line
        #image: mysql:8.0.27
        command: '--default-authentication-plugin=mysql_native_password'
        volumes:
          - db_data:/var/lib/mysql
        restart: always
        environment:
          - MYSQL_ROOT_PASSWORD=somewordpress
          - MYSQL_DATABASE=wordpress
          - MYSQL_USER=wordpress
          - MYSQL_PASSWORD=wordpress
        expose:
          - 3306
          - 33060
      wordpress:
        image: wordpress:latest
        ports:
          - 80:80
        restart: always
        environment:
          - WORDPRESS_DB_HOST=db
          - WORDPRESS_DB_USER=wordpress
          - WORDPRESS_DB_PASSWORD=wordpress
          - WORDPRESS_DB_NAME=wordpress
    volumes:
      db_data:
      
    # 3.启动
    docker-compose up -d
    docker-compose up
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    8.compse实战:计数器

    1.编写微服务项目
    2.编写Dockerfile文件,构建镜像

    FROM java:8
    
    COPY *.jar /app.jar
    
    CMD ["--server.port=8080"]
    
    EXPOSE 8099
    
    ENTRYPOINT ["java","-jar","/app.jar"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.编写docker-compose.yml文件,编排项目

    version: '3.8'
    services:
      kuangapp:
        build:
          dockerfile: Dockerfile
        image: kuangapp
        depends_on:
          - redis
        ports:
          - "8080:8080"
      redis:
        image: "redis:alpine" # 精简版本
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.丢到服务器

    1.创建kaungapp目录:在目录下操作
    2.启动
    docker-compose up -d
    
    • 1
    • 2
    • 3

    小结:未来项目只要有dokcer-compose文件。按照这个规则,启动编排容器

    假设项目要重新部署打包:

    docker-compose up --build # 重新构建镜像
    
    • 1

    9.总结:

    工程、服务、容器

    项目compose:三层

    • 工程project
    • 服务
    • 容器 运行实例 docker k8s等

    十、Docker Swarm (集群) - 简化版本的k8s

    集群方式的部署、需要购买4台阿里云服务器,2核心4G。swarm暂时买的1核2G

    k8s需要2核4G
    在这里插入图片描述

    1.swarm节点工作模式:

    在这里插入图片描述

    2.swarm服务工作模式:

    3.搭建集群

    #1.初始化一个swarm节点 docker-1机器上操作
    docker swarm init --advertise-addr 本机ip
    
    • 1
    • 2

    在这里插入图片描述

    #得到上图两个命令:
    # 添加一个工作节点:其他docker机器上操作
    docker swarm join --token SWMTKN-1-2lp87oe4q6ez6ehnqz3hs9887hjpe4prasxnafa8y0rsu13q8s-1idmuvh3lojmua824wxgw15ev 172.16.0.105:2377
    
     # 获取一个节点的token,manager的token与worker加入的节点token是不一样的
    docker swarm join-token manager
    # 添加一个管理节点
    docker swarm join --token SWMTKN-1-2lp87oe4q6ez6ehnqz3hs9887hjpe4prasxnafa8y0rsu13q8s-6lxrwnpfoazek2qzfjirda7qs 172.16.0.105:2377
    
    
    docker swarm join-token work
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    docker node ls;
    
    • 1

    在这里插入图片描述
    在这里插入图片描述1与4主节点。2与3从节点

    4.Raft一致性协议:

    目前是双主双从:假设一个节点挂了,其他节点是否可用
    raft协议:保证大多数节点存活才可以用。集群至少大于3台

    5.实验:

    将docker1停止(宕机),双主双从的情况下,docker4能否可用?答:不可用
    在这里插入图片描述
    重启dokcer1机器后,docker1不是leader了,docker4升级为leader

    docker swarm leave #如下
    
    • 1

    在这里插入图片描述
    目前1.3.4是主节点:

    集群中:至少要保证3个主节点。必须要保证2台主机存活这个集群才可用。

    raft协议:保证大多数节点存活,才可以使用,高可用

    6.swarm集群弹性创建服务(集群的扩缩容)

    在这里插入图片描述
    灰度发布:金丝雀发布
    docker service create -p 8888:80 --name my-nginx nginx
    在这里插入图片描述

    1.docker run 容器启动,不具备扩缩容器
    2.docker service 服务启动,具备扩容容器,滚动新
    
    • 1
    • 2
    dokcer service ls;
    
    • 1

    在这里插入图片描述

    docker service update --replicas 3  my-nginx 
    
    • 1

    在这里插入图片描述
    注意:外网访问不到,需要配置阿里云安全组,开放端口8888
    动态扩缩容

    服务,集群中任意的节点都可以访问。
    服务可以有多个副本动态扩缩容来实现服务高可用

    docker service scale my-nginx=5
    
    docker service scale my-nginx=1
    
    • 1
    • 2
    • 3

    7.概念总结

    在这里插入图片描述

    swarm
    集群的管理和编排,docker可以初始化一个swarm集群,其他节点可以加入。(管理或工作者)
    
    node:
    就是一个docker节点,docker节点就组成了一个集群网络
    
    service
    任务,可以再管理节点或工作节点来运行,核心!
    
    task:
    容器内的命令,细节任务
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    8.Docker Stack

    docker-compose 单机项目部署
    dockerstack 集群部署

    #单机
    docker-compose up -d wordpress.yml
    #集群
    docker stack deploy wordpress.yml
    
    • 1
    • 2
    • 3
    • 4

    9.Docker Secret

    安全!配置密码,证书!

    10.Docker Config

    配置,统一的配置

    十一、CI/CD Jenkins 持续集成与持续交付,持续部署

    CI/CD Jenkins 持续集成与持续交付,持续部署

    十二、docker相关组件原理

    http://t.zoukankan.com/goloving-p-14988269.html

    十三、docker安装es

    docker-compose安装es

  • 相关阅读:
    Java项目:ssm汽车租赁系统
    java 调用合约使用nonce 可能会出现的问题
    Springboot集成Swagger3详细操作步骤
    MySQL中特别实用的几种SQL语句
    线性回归(Linear Regression)(机器学习)
    source insight 使用过程中问题点总结
    关于支付宝授权用户信息
    到底怎么个DAO
    [Java安全]—Mybatis注入
    sql分析(查询截取分析做sql优化)
  • 原文地址:https://blog.csdn.net/User_bie/article/details/127925649