Docker知识汇总

Docker的概述

Docker为什么出现?

一款产品:开发—上线 两套环境!应用环境,应用配置!

开发 -------运维。问题:在我这可以运行,但是在你的电脑就不能运行了。或者版本更新就不能使用了。

开发即运维!!

环境配置十分麻烦,每一个机器都要部署环境(集群redis、ES、Hadoop)。费时费力的。

发布一个项目jar(Redis+mysql+jdk+ES),那么你发送一个jar过去,别人还需要去配置运行这个jar包所需要的环境,而且版本一旦稍有不同就可能会出错。

所以希望项目能够带上环境进行打包发布,而不是单纯的一个jar文件。===>Docker

之前在服务器配置一个应用环境Redis、Mysql、jdk、ES、Hadoop,配置超麻烦,不能跨平台。

Windows开发,发布到Linux。

传统:开发jar,运维来部署

现在:开发打包部署上线,一套流程做完。

比如现在开发了一个Android的应用上线了给别人用:

Java->apk->发布(应用商店)->张三使用apk->到商店下载安装即可

回到我们的开发项目流程

Java->jar(环境)->打包项目带上环境(镜像)->上传到docker仓库(类似上面的商店)->运维下载我们发布的镜像->直接运行即可!

Docker的思想来自于集装箱

同一个JRE->多个应用(可能会出现端口冲突)–>原来的项目是交叉的

隔离:Docker的核心思想,打包装箱,每个箱子都是互相隔离的,每个箱子有自己的环境,即使端口一样也不会冲突。

Docker通过隔离可以使得服务器利用到极致。只要有一点空间,docker就可以利用。

Docker能干嘛

Docker知识汇总_第1张图片

传统的虚拟机技术缺点:

  1. 资源占用十分多

  2. 冗余步骤多

  3. 启动慢

容器技术

容器化技术不是虚拟的一个完整的系统,只要一个核心。

Docker知识汇总_第2张图片

容器内部有自己的运行环境,每个 容器是隔离的,容器是建立在我们的虚拟机之上的,可以充分的使用我们的虚拟机资源。

比较docker和虚拟机的不同

  • 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后再这个操作系统上安装和运行软件
  • 容器内的应用直接运行在宿主机的内容上,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
  • 每个容器间是互相隔离的,每个容器内都有自己的文件系统,互不影响。

DevOps(开发、运维)

应用更快的交付和部署

传统的:一堆帮助文档,安装程序

Docker:打包镜像发布测试,一键运行。

更便捷的升级和扩缩容

使用了Docker之后,部署应用就和搭积木一样

项目打包为一个镜像,扩展为服务器A,直接把镜像下载到服务器B运行就可以使服务器A的工作量减少,到达负载均衡的目的。

更简单的系统运维

在容器化之后,我们的开发测试环境都是高度一致的。(底层的系统kernel是一样的)

更高效的计算资源利用

1核2G可以运行十几个tomcat

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

Docker的基本组成

Docker知识汇总_第3张图片

镜像(image)

docker镜像就好比一个模板,可以通过这个模板来创建容器服务,Tomcat镜像===>run---->tomcat1容器(提供服务器),通过这个镜像创建多个容器(最终服务运行或者项目运行就是在容器里面的)。镜像run起来就是容器了。

容器(container):

docker利用容器口域独立运行一个或者一组应用,通过镜像来创建

启动,停止,创建,删除,基本命令

目前可以理解为一个容器就是一个简易的Linux系统,就是有些基本的内容。

仓库(repository):

仓库就是存镜像的地方。

有公有仓库和私有仓库!(这个概念和git的相似)

Docker Hub(默认是国外的)

阿里云。。。。都有容器服务器(配置镜像加速!这里类似于maven)

所以应该docker的启动流程应该是这样的:client去启动一个镜像,而这个镜像要去仓库里面去获取,然后运行这个镜像来创建得到容器,我们实际上就是在跑这个容器。

安装docker

环境准备

  1. 需要会Linux基础
  2. centos8
  3. 使用远程终端软件来操作服务器(Xshell)

查看官方文档

网址:https://docs.docker.com/get-docker/

Docker知识汇总_第4张图片

我们这里是需要安装在Linux上的。

Docker知识汇总_第5张图片

# 1、卸载旧的版本
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 2、安装的需要的安装包
sudo yum install -y yum-utils

# 3、设置镜像仓库
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo   #这个仓库地址默认是国外的,非常慢,我们不要这样设置,可以去找国内的加速镜像
   
sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo  #使用阿里云的镜像来安装

#更新yum软件包索引
yum makecache
    
#4、安装docker相关的包
#安装最新版本的docker引擎 docker-ce 社区版 ee是企业版
sudo yum install docker-ce docker-ce-cli containerd.io

#我这里安装的时候出现这个问题:
Error: 
 Problem: package docker-ce-3:20.10.2-3.el7.x86_64 requires containerd.io >= 1.4.1, but none of the providers can be installed
  - cannot install the best candidate for the job
  - package containerd.io-1.4.3-3.1.el7.x86_64 is filtered out by modular filtering
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)

#所以需要安装对应的io
sudo dnf install https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm 

#接着再重新执行安装命令
sudo yum install docker-ce docker-ce-cli containerd.io

#5、启动docker
systemctl start docker
#查看docker的版本,看看是否安装成功
docker version

Docker知识汇总_第6张图片

#7、运行docker helloworld
docker run hello-world

Docker知识汇总_第7张图片

因为我们没有这个hello-world镜像,所以它去仓库进行pull,拉取这个镜像

然后会返回一个签名,代表拉取完成了。

拉取完成之后就会运行起来了。

#8、查看这个下载的hello-world镜像
[root@iZwz96cj54lr4szndhzbezZ ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    bf756fb1ae65   12 months ago   13.3kB

卸载docker

#1、卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
#2、删除资源
sudo rm -rf /var/lib/docker

# docker的默认工作路径 /var/lib/docker

阿里云镜像加速

登录阿里云账号,进入控制台

Docker知识汇总_第8张图片

Docker知识汇总_第9张图片

配置使用

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://9eigil3c.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

回顾helloworld的执行流程

Docker知识汇总_第10张图片

底层原理

docker是怎么工作的

Docker是一个client-server结构的系统,Docker的守护进程运行再主机上,通过socket从客户端访问。

DockerServer接受到client的指令,就会执行这个命令。

Docker知识汇总_第11张图片

docker为什么比虚拟机要快

1、Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。

2、Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。

Docker知识汇总_第12张图片

Docker容器 虚拟机(VM)
操作系统 与宿主机共享OS 宿主机OS上运行宿主机OS
存储大小 镜像小,便于存储与传输 镜像庞大(vmdk等)
运行性能 几乎无额外性能损失 操作系统额外的cpu、内存消耗
移植性 轻便、灵活、适用于Linux 笨重、与虚拟化技术耦合度高
硬件亲和性 面向软件开发者 面向硬件运维者

关于Docker实现原理,简单总结如下

  • 使用Namespaces实现了系统环境的隔离,Namespaces允许一个进程以及它的子进程从共享的宿主机内核资源(网络栈、进程列表、挂载点等)里获得一个仅自己可见的隔离区域,让同一个Namespace下的所有进程感知彼此变化,对外界进程一无所知,仿佛运行在一个独占的操作系统中;
  • 使用CGroups限制这个环境的资源使用情况,比如一台16核32GB的机器上只让容器使用2核4GB。使用CGroups还可以为资源设置权重,计算使用量,操控任务(进程或线程)启停等;
  • 使用镜像管理功能,利用Docker的镜像分层、写时复制、内容寻址、联合挂载技术实现了一套完整的容器文件系统及运行环境,再结合镜像仓库,镜像可以快速下载和共享,方便在多环境部署。

Docker常用命令

帮助命令

docker version		#显示docker的版本信息
docker info			#显示docker的系统信息,包括镜像和容器数量
docker 命令 --help	#帮助命令

帮助文档地址:https://docs.docker.com/reference/

镜像命令

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

[root@iZwz96cj54lr4szndhzbezZ ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    bf756fb1ae65   12 months ago   13.3kB

#解释
REPOSITORY 镜像的仓库源,也就是这个镜像在仓库里面的命名
TAG			镜像的标签,版本
IMAGE ID	镜像的id
CREATED		镜像的创建时间
SIZE		镜像的大小

#可选项
  -a, --all             #列出所有的镜像
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           #只显示镜像的id

docker search搜素镜像

[root@iZwz96cj54lr4szndhzbezZ ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   10380     [OK]       
mariadb                           MariaDB is a community-developed fork of MyS…   3848      [OK]       

#可选项,通过收藏来过滤
--filter=stars=3000  搜素出来的镜像的stars就是大于3000的

[root@iZwz96cj54lr4szndhzbezZ ~]# docker search mysql --filter=stars=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10380     [OK]       
mariadb   MariaDB is a community-developed fork of MyS…   3848      [OK]  

docker pull下载镜像

[root@iZwz96cj54lr4szndhzbezZ ~]# docker pull mysql
Using default tag: latest    #如果不写tag,默认就是lates
latest: Pulling from library/mysql
a076a628af6f: Pull complete #分层下载,docker image的核心 联合文件系统
f6c208f3f991: Pull complete 
88a9455a9165: Pull complete 
406c9b8427c6: Pull complete 
7c88599c0b25: Pull complete 
25b5c6debdaf: Pull complete 
43a5816f1617: Pull complete 
1a8c919e89bf: Pull complete 
9f3cf4bd1a07: Pull complete 
80539cea118d: Pull complete 
201b3cad54ce: Pull complete 
944ba37e1c06: Pull complete 
Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c  #签名
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 rmi -f  #删除所有的镜像
docker rmi -f id #根据镜像的id来删除镜像
docker rmi -f id1 id2 id3 #根据镜像的多个id来删除镜像
docker rmi -f $(docker images -aq)  #删除所有的容器

容器命令

有了镜像才可以创建容器

下载一个centos的镜像

新建容器并启动

docker run [可选参数] image

#参数的说明

--name="name" #容器的名字 tomcat1 tomcat2 用来区分容器
-d            #后台方式运行
-it           #使用交互方式运行,进入容器查看内容
-p 			  #指定容器端口  -p 8080:8080
		-p ip:主机端口:容器端口
		-p 主机端口:容器端口(常用)
		-p 容器端口
-P 			  #随机指定端口

#启动并加入容器
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -it centos /bin/bash
[root@95ca66a1d3d2 /]# ls   #查看容器内部的centos
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#从容器退出到主机
exit

列出所有的运行的容器

#docker ps命令
	# 列出所有的正在运行的容器
-a	#列出当前正在运行的容器+历史运行过的容器
-n=?	#显示最近创建的容器
-q	#只显示容器的编号
#查看运行的容器
docker ps
#查看曾经运行的容器
docker ps -a

退出容器

exit #直接容器停止退出
Ctrl+P+Q #容器不停止退出

删除容器

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

启动和停止容器的操作

docker start 容器id	#开启容器
docker restart 容器id	#重启容器
docker stop 容器id	#停止容器
docker kill 容器id	#强制停止容器

常用的其他命令

后台启动容器

# 命令 docker run -d 镜像名
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d centos
#问题docker ps,发现centos停止了
# 常见的坑,docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
#nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

查看日志命令

docker logs -f -t --tail 容器  ,没有日志

#自己编写一段shell脚本,让容器一直执行这一段程序,循环输出hello
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d centos /bin/sh -c "while true;do echo hello;sleep 1;done"

[root@iZwz96cj54lr4szndhzbezZ ~]# docker logs -tf --tail 10 ee9e03dfc9b4

查看容器中的进程信息

top命令
docker top 容器id

查看容器元数据

#命令 docker inspect 容器id

进入当前正在运行的容器

#我们通常容器都是通过后台的方式运行的,需要进入容器来修改一下配置

#命令
docker exec -it 容器id bashShell

#测试
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it ee9e03dfc9b4 /bin/bash


#方式二
docker attach 容器id
正在执行当前的代码

#docker exec #进入容器后开启一个新的终端,可以在里面操作
#docker attach #进入容器正在执行的终端,不会启动新的进程

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

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

[root@iZwz96cj54lr4szndhzbezZ home]# docker cp 2b6ceeade7e6:/home/test.java /home
[root@iZwz96cj54lr4szndhzbezZ home]# ls
hello.java  test.java

#拷贝的时候即使容器没有运行也是可以拷贝的,因为数据还在
#拷贝是一个手动过程,未来使用-v 卷的技术可以实现自动同步 比如:容器的home 和 主机的home 联通

小结

Docker知识汇总_第13张图片

Docker知识汇总_第14张图片

Docker知识汇总_第15张图片

练习

docker 安装nginx

#1、搜索镜像
docker search nginx
#2、下载镜像
docker pull nginx
#3、运行测试
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d --name nginx01 -p 3344:80 nginx	#-p映射的端口

端口映射的问题

Docker知识汇总_第16张图片

思考问题:我们每次改动nginx配置文件,都需要进入容器内部,十分的麻烦,我们要是可以在容器外部提供一个映射路径,达到在容器外部修改文件,容器内部的 文件就可以自动的修改?-v 数据卷

docker安装tomcat

#官方的使用
docker run -it --rm tomcat:9.0

#我们之前的启动都是后台,停止容器之后,容器还是可以查到 docker run -it --rm一般用来测试,用完即删

#下载启动
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat

启动之后外网访问发现:

Docker知识汇总_第17张图片

1、linux命令少了

2、没有webapps

是因为阿里云镜像的原因,默认的是最小的镜像,所有不必要的都剔除掉,保证最小的可运行的环境

#进入tomcat
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat01 /bin/bash
#进入webapps目录发现里面的内容是空的
#但是有一个webapps.dist,里面的文件就是我们需要的,把文件拷贝到webapps就可以成功访问tomcat了
root@777b7949eaf3:/usr/local/tomcat# cp -r webapps.dist/* webapps

思考问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?我要是在容器外部提供一个映射路径,webapps,我们在外部部署项目,就可以自动同步到内就好了。

docker容器 tomcat+网站

docker部署es和kibana

#es 暴露的端口很多
#es 十分的耗内存
#es 的数据一般需要放置到安全目录!挂载

# --net somenetwork ?网络配置
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

#es是十分耗内存的
[root@iZwz96cj54lr4szndhzbezZ ~]# curl localhost:9200
{
  "name" : "6ada9b775535",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "fUhyrAXvSoS8_XC8lbY0-A",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

#可以查看docker的cpu的内存状态 docker stats

#关闭增加内存的限制,修改配置文件-e环境配置
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

可视化

  • portainer

docker的图形化界面管理工具!提供一个后台面板供我们操作

docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

测试访问:外网8088http://47.106.213.152:8088/

Docker知识汇总_第18张图片

选择本地的

Docker知识汇总_第19张图片

  • Rancher

docker镜像讲解

镜像是什么

我们下载镜像的时候是一层层的

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件

所有的应用直接打包成docker镜像部署,就可以直接跑起来

如何得到镜像:

  • 从远程仓库下载
  • 朋友拷贝给你
  • 自己制作一个镜像dockerfile

docker镜像加载原理

UnionFS 联合文件系统

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

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

docker镜像加载原理

  • docker镜像是由一层层的文件系统组成,这种层级的文件系统UnionFS
  • BootFS(boot file system)系统启动需要引导加载
    • 主要包含boot loader、kernel,bootlocker主要是引导加载kernel
    • linux启动时会加载bootfs文件系统,在docker镜像的最底层是bootfs,这点linux和unix是一样的,boot加载器和内核,当boot加载完成之后,整个内核都在内存中,此时内存的使用权已由bootfs转交给内核,此时系统会卸载bootfs
  • rootFS,在bootfs之上,包括的就是典型的linux系统中的/dev、/proc、/bin、/etc等标准文件和目录,rootfs就是不同操作系统发行版,比如ubuntu,centos等等

Docker知识汇总_第20张图片

  • 先是from来一个debian,然后run了一层emacs在原来的基础上多叠加了一层,之后的apache是跟emacs是共用底层的,不需重复下载
  • 因为是一个精简的os,rootfs很小,只保留了一些基本的命令,底层的kernel还是使用的主机的kernel,只需要提供rootfs就行,不同的linux版本呢bootfs是一致的,rootfs会有差别,因此发型版本可以公用bootfs

分层理解

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。分层时有文件更新直接替换,基础镜像一样时直接拿过来复用。

如redis下载时,第一层相同,直接复用,其他几层分层下载。

afb6ec6fdc1c: Already exists 
608641ee4c3f: Pull complete 
668ab9e1f4bc: Pull complete 
78a12698914e: Pull complete 
d056855f4300: Pull complete 
618fdf7d0dec: Pull complete 

举一个简单的例子,假如基于 Ubuntu16.04创建一个新的镜像,这就是新镜像的第一层。如果在该镜像中添加Python包,就会在基础镜像层之上创建第二个镜像层。如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。

Docker知识汇总_第21张图片

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合。一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

image-20210123175458193

下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。
上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

Docker知识汇总_第22张图片

所有镜像层堆并合井,对外提供统一的视图。

Docker知识汇总_第23张图片

Docker镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部。这一层就是我们通常说的容器层,容器之下的都叫镜像层。

Docker知识汇总_第24张图片

commit镜像

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

#命令和git相似
docker commit -a "作者" -m "提交的描述信息" 容器id 目的镜像名:[tag]

实战

#1、启动一个默认的tomcat
#2、发现这个tomcat是没有webapps应用的,镜像的原因,官方的镜像默认webapps下面是没有文件的。
#3、我自己拷贝进去了基本文件到webapps
#4、将我们操作过的容器通过commit提交为一个镜像,我们以后就使用修改过的镜像就可以,这就是我们自己的一个镜像

Docker知识汇总_第25张图片

Docker知识汇总_第26张图片

如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们之前学习的VM时候,快照!

容器数据卷

什么是容器数据卷

docker的理念

将应用和环境打包成一个镜像

数据都在容器中,那么容器一删除,数据就会丢失, --需求:数据可以持久化

mysql,容器删了,删库跑路—需求:MySQL 的数据可以存储在本地,

容器之间可以有一个数据共享的技术。docker容器中产生的数据同步到本地,容器删除了,数据还在本地就不会丢失===>目录的挂载,将我们的容器的目录挂载在linux上面

Docker知识汇总_第27张图片

同步机制

总结:容器的持久化和同步操作,容器间也是可以数据共享的。

使用数据卷

方式一:直接使用命令来挂载 -v

docker run -it -v 主机目录:容器目录

#测试
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -it -v /home/test:/home centos /bin/bash

#启动之后我们可以通过docker inspect 容器id 来查看挂载信息

Docker知识汇总_第28张图片

测试文件的同步的具体效果

image-20210123220921860

即使你停止了容器我们在主机上修改文件,容器内的文件也可以同步的,只要这个容器没有被删除

好处:我们以后只需要修改本地的文件即可,容器的文件可以自动同步!

实战测试:安装MySQL

mysql的数据持久化问题,data目录

#获取镜像
docker pull mysql:5.7

#运行容器,需要做数据挂载! #安装启动mysql的时候,需要配置密码的
# 官方的测试
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#启动我们的MySQL
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@iZwz96cj54lr4szndhzbezZ ~]# 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 mysql mysql:5.7

#可以使用navicat来进行连接数据库,连接到服务器的3310端口,在本地创建一个mysql数据库,查看路径是否映射成功

即使将容器删除,发现我们挂载到本地的数据卷依旧没有丢失,这实现了数据持久化功能。

具名和匿名挂载

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

#查看所有卷的情况
[root@iZwz96cj54lr4szndhzbezZ data]# docker volume ls

发现卷的名字是一串数字,这就是匿名挂载,我们在-v的时候只写了容器的路径

image-20210123225742354

#具名挂载
-v 卷名:容器内路径
#查看卷的路径
docker volume inspect 卷名
比如
docker volume inspect juming-nginx

Docker知识汇总_第29张图片

卷的路径

Docker知识汇总_第30张图片

所有的卷在没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data

我们通过具名挂载可以方便找我们的卷,这也是我们大多情况下使用的

#如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径  #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器路径 #指定路径挂载

扩展

# 通过 -v 容器内路径,ro rw 改变读写权限
ro readonly #只读
rw radewrite #可读可写

#一旦设定了容器的权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:rw nginx

#ro只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的,默认是rw

初始DockerFile

DockerFile就是用来构建docker镜像的构建文件!之前是commit,现在是dockerFile!命令脚本!

通过这个脚本可以生成镜像,镜像是一层一层的,脚本就是一个个的命令,每个命令都是一层

方式二

#创建一个dockerfile文件,命名随意,但是尽量是dockerfile
#文件内容,指令和参数,指令都是大写的
FROM centos

VOLUME ["volume01","volume02"]   #这是一个匿名挂载
CMD ecoh "---------end-------"
CMD /bin/bash

#这里的每一个命令就是镜像的一层


#build这个dockerFile的镜像
[root@iZwz96cj54lr4szndhzbezZ docker-test-volume]# docker build -f dockerfile1 -t zhuzi/centos .

Docker知识汇总_第31张图片

可以看到是一层层的构建的

#启动刚刚自己创建的镜像
[root@iZwz96cj54lr4szndhzbezZ docker-test-volume]# docker run -it zhuzi/centos /bin/bash
#查看文件

Docker知识汇总_第32张图片

这个卷和外部一定有一个同步的目录

查看卷挂载的路径

docker inspect 38f17bbf2c99

Docker知识汇总_第33张图片

可以去source路径去查看数据文件是否被同步成功

这种方式我们未来使用的十分的多,因为我们通常会构建自己的镜像!

假设构建镜像的时候没有挂载卷,要手动挂载卷 -v 卷名:容器路径

数据卷容器

两个MySQL同步数据。

Docker知识汇总_第34张图片

#启动3个容器
#第一个
docker run -it --name contos01 zhuzi/centos
#第二个
docker run -it --name centos02 --volumes-from contos01  zhuzi/centos
#第三个
docker run -it --name centos03 --volumes-from contos01  zhuzi/centos

#我们通过 --volumes-from 父容器id 就可以实现容器之间的数据同步

image-20210124105818479

Docker知识汇总_第35张图片

image-20210124110127206

数据共享即使父容器丢了,子容器里面的文件还是可以访问的,即数据没有丢失。

–volumes-from 的理解

实际上–volumes-from 是使得我们创建的子容器共享父容器的数据卷在主机本地的目录,也就是子容器和父容器的数据卷在本地上的位置是一样的,这样子就可以实现数据的同步,因为其中一个容器的文件一旦修改,本地的文件就会修改,本地文件一修改这样其他容器的文件也会修改,牵一而动百

这里需要注意的是,即使是继承了,数据之间是同步了,但是只要数据卷的内容是同步的,非数据卷的目录是不同步的。

所以对于多个MySQL的数据共享

docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

#第二个MySQL
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volume-from mysql01 mysql:5.7

结论

容器之间的配置信息的传递,数据卷容器的生命周期是一直持续到没有容器使用为止

但是一旦你持久化到了本地,本地的数据不会删除

数据卷挂载的权限问题

这个问题的发现是偶然的,一次在我安装code-server挂载code文件夹的时候,发现exec进去之后,容器里面不能创建文件,原因是code文件的用户权限是root权限的,而code-server登录的用户的权限是coder,所以没有权限创建文件

#运行容器,把容器的code挂载到/home/zhuzi/code,因为容器里面的code原来是没有的,所以在运行容器的时候是root的身份创建的
docker run -d -p 8081:8080 --name code-server2 -v /home/zhuzi/code:/home/code codercom/code-server
#我们exec进入容器查看这个文件的权限,所属的用户和用户组

Docker知识汇总_第36张图片

在这里我们可以发现,登录容器的用户是coder,而code文件夹是属root用户的,我们试试在code里面创建文件

image-20210126113247080

可以看到我们是没有权限创建文件的,决解的方法就是把容器的用户改位root,不用使用默认的coder用户了

#这里我们使用-u来指定容器的用户为root,这样子登录容器的用户就为root了,我们就有权限在code文件夹创建文件了
docker run -d -u root -p 8088:8080 --name code-server -v /home/zhuzi/code:/home/code codercom/code-server

Docker知识汇总_第37张图片

看到了吗,这样子创建文件是看到没问题了的,有人可能会说我们在exec进去的时候就使用root也可以啊,但是这样子在浏览器登录code-server的时候,还是以coder身份登录,依旧不能在code创建文件

DockerFile

dockerFile介绍

dockerfile是用来构建docker镜像的文件!命令参数脚本。

构建步骤:

1、 编写一个dockerfile文件

2、docker build构建为一个镜像

3、docker run镜像

4、docker push推送我们的镜像

Docker知识汇总_第38张图片

官方就是构建了dockerfile然后发布到github上面的

Docker知识汇总_第39张图片

很多官方镜像都是基础包,很多功能都没有,我们通常需要自己安装。

DockerFile的构建过程

基础知识

1、每个保留关键字(指令)都必须是大写字母

2、指令是从上到下顺序执行的

3、#表示注释

4、每个指令都会被创建一个新的镜像层,并提交

image-20210124122220466

dockerFile是面向开发的,我们以后开发项目,做镜像,就需要编写dockerFile文件,这个文件十分简单

Docker镜像逐渐成为了企业交付的标准,必须要掌握!

步骤:开发、部署、上线运维

dockerFile:构建文件,定义了一切的步骤,源代码

dockerImage:通过dockerFile构建生成的一个镜像,最终要发布和运行的产品,原来是jar运行,最后哪怕是一个jar都需要创建一个镜像来运行。

docker容器:镜像运行起来提供服务的

DockerFile的指令

FROM  #基础镜像   一切从这里开始构建
MAINTARNER #镜像是谁写的,姓名+邮箱
RUN #Docker镜像构建运行时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat压缩包,添加的内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口配置
RUN #

CMD #指定容器启动的时候运行的命令,只有最后一个会生效,可以被代替
ENTRYPOINT #指定容器启动的时候运行的命令,可追加
ONBUILD #当构建一个被继承的DockerFile中国时候就会运行ONBUILD指令,触发指令
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建的时候设置环境变量

Docker知识汇总_第40张图片

实战测试

Docker Hub中99%的镜像都是从这个基础的镜像过来的,FROM scratch,然后配置需要的软件和配置来进行构建

Docker知识汇总_第41张图片

创建一个自己的centos

#1、编写在自己的dockerFile文件
FROM centos
MAINTAINER zhuzi<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yun -y install vim
RUN yun -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "------end--------"
CMD /bin/bash

#2、通过这个文件构建镜像,不要忘记最后的.
docker build -f mydockerfile -t mycentos .

#3、测试运行

进来之后第一件事pwd发现我们当前的目录就是工作目录,也就是我们刚刚dockerfile写的WORKDIR的路径

image-20210124134151882

对比之前的centos:官方的。工作目录默认是根目录,

Docker知识汇总_第42张图片

我们增加之后的镜像

Docker知识汇总_第43张图片

我们可以列出本地进行变更的历史docker history 镜像id

Docker知识汇总_第44张图片

我们平时拿到一个镜像可以研究它是怎么做的

CMD和ENTRYPOINT区别

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

测试CMD命令

[root@iZwz96cj54lr4szndhzbezZ dockerfile]# vim dockeefile-cmd
FROM centos
CMD ["ls","-a"]

[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker build -f dockeefile-cmd -t cmd .

#run运行
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run 47ac151e85da
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var


#想追加一个命令 -l ls -al
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run 47ac151e85da -l
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.
ERRO[0000] error waiting for container: context canceled

#CMD的清理下 -l 替换了CMD["ls","-a"]命令,-l不是命令所有保存

测试ENTRYPOINT命令

#编写脚本
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# vim dockerfile-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]

[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker build -f dockerfile-entrypoint -t cmd .

[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run entrypoint
.
..
.dockerenv
bin
dev
etc
home
lib
lib64


#我们追加的命令,是直接拼接在我们的ENTRYPOINT命令后面!
[root@iZwz96cj54lr4szndhzbezZ dockerfile]# docker run entrypoint -l
total 0
drwxr-xr-x   1 root root   6 Jan 24 06:11 .
drwxr-xr-x   1 root root   6 Jan 24 06:11 ..
-rwxr-xr-x   1 root root   0 Jan 24 06:11 .dockerenv
lrwxrwxrwx   1 root root   7 Nov  3 15:22 bin -> usr/bin

dockerfile很多的命令都是十分相似的,我们需要了解它们的区别,我们最好的学习就是对比他们然后测试效果

实战:Tomcat镜像

1、准备镜像文件: tomcat压缩包,jdk压缩包

image-20210124171712186

#下载tomcat
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.41/bin/apache-tomcat-9.0.41.tar.gz
#下载jdk1.8
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz"

2、编写dockerfile文件,官方命名DockerFile,build会自动寻找这个文件,就不需要-f指定文件了

FROM centos
MAINTAINER zhuzi<[email protected]>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u141-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.41.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_141
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.41
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.41/bin/logs/catalina.out

3、构建我们的镜像

 docker build  -t diytomcat .

4、运行起来

docker run -d -p 9090:8080 --name zhutomcat -v /home/zhu/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v /home/zhu/tomcatlogs:/usr/local/apache-tomcat-9.0.41/logs diytomcat

5、访问测试

6、发布项目(由于做了卷挂载, 我们直接就可以在本地发布了)

cd /home/zhu/test
mkdir WEB-INF
cd WEB-INF
vim web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

web-app>
cd ..
vim index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
Hello World!<br/>
</body>
</html>

访问IP:9090/test

发布自己的镜像

发布到Docker Hub

1、地址,需要注册自己的账号

2、确定这个账号可以登录

3、在我们的服务器上提交自己的镜像

#先登录在提交
[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

docker login -u 用户名

4、登录完毕之后就可以提交镜像了

[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker push diytomcat
Using default tag: latest
The push refers to repository [docker.io/library/diytomcat]
260ffe8a6d50: Preparing 
3f712cddb48b: Preparing 
e11d641fac9d: Preparing 
3fcf3732082d: Preparing 
2653d992f4ef: Preparing 
denied: requested access to the resource is denied   #被拒绝了,因为提交的时候需要带上镜像的作者

[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker push zhuzi/diytomcat
Using default tag: latest
The push refers to repository [docker.io/zhuzi/diytomcat]
An image does not exist locally with the tag: zhuzi/diytomcat

#解决,增加一个tag
[root@iZwz96cj54lr4szndhzbezZ tomcatlogs]# docker tag 4506821fe9c9 csulfz/tomcat:1.0
# docker tag 镜像id 作者/镜像名称:版本号
#需要注意的是这里的作者名称一定要和docker hub上面的用户名一致

提交时候也是按照层级来进行发布的。

Docker知识汇总_第45张图片

发布镜像到阿里云

1、登录阿里云

2、找到容器镜像服务

3、创建命名空间,防止冲突,一般一个命名空间里面可以有很多个镜像

Docker知识汇总_第46张图片

4、创建容器镜像,点击创建镜像仓库,填好信息之后,选本地仓库

Docker知识汇总_第47张图片

5、查看仓库的详细信息

Docker知识汇总_第48张图片

里面会有具体的镜像push操作步骤

小结

Docker知识汇总_第49张图片

docker网络

理解网络docker0

测试

Docker知识汇总_第50张图片

有三个网络

#问题,docker是如何处理容器网络的访问的。

Docker知识汇总_第51张图片

[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat01 tomcat

#查看容器内部的网络地址 ip addr  发现容器启动的时候会得到一个eth0@if81 ip地址,docker分配的
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it 4be50fc1352a ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
80: eth0@if81: <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

#思考,Linux服务器能不能ping通容器内部
[root@iZwz96cj54lr4szndhzbezZ ~]# 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.094 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.075 ms

#Linux可以ping通docker容器内部

原理

1、我们每启动一个docker容器,我们的docker就会给容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0

桥接模式,使用的技术就是evth-pair技术!

Docker知识汇总_第52张图片

我们再创建一个tomcat容器,发现又多了一对网卡

Docker知识汇总_第53张图片

我们发现容器带来的网卡都是一对对出现的

evth-pair就是一对虚拟设备接口,他们都是一对出现的,一段连着协议,一段相互相连

正因为这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的

OpenStack Docker容器之间的连接,ovs的连接,都是使用evth-pair技术

3、我们测试一下tomcat01能不能ping通tomcat02

[root@iZwz96cj54lr4szndhzbezZ ~]# 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.145 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.113 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 62ms

发现是可以ping通的

结论:

容器和容器之间是可以互相ping通的

Docker知识汇总_第54张图片

结论:tomcat01和tomcat02是公用一个路由器的,docker01

所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip

小结

Docker使用的是Linux的桥接,宿主机中有一个Docker容器的桥接,docker0

Docker知识汇总_第55张图片

Docker中的所有网络接口都是虚拟的,虚拟的转发效率高,内网传递文件

只要容器删除,对应的网桥一对就会没了。

–link

思考

我们编写了一个微服务,database url=ip,项目不重启,数据库ip换掉了,我们下午可以处理这个问题,可以使用名字来访问这容器。==》高可用

[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

#解决方法 使用--link
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
62403ff463e52c0ee41724b69e65b7106ae37254015b384daeb81e475bf7d582
[root@iZwz96cj54lr4szndhzbezZ ~]# 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.175 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.083 ms

#但是反向就不能ping通
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

其实就是tomcat03再启动的时候在本地配置了tomcat02的网址,做了域名解析,可以查看tomcat03的/etc/hosts文件

–link就是在hosts文件中增加了域名和地址的映射

我们现在玩docker已经不建议使用–link了

现在一般都是使用自定义网络,不适用docker0

docker0的问题:它不支持容器名进行连接访问

自定义网络

容器互联

#相关的查看docker网络的指令
docker network --help

image-20210124230926231

网络模式

bridge:桥接模式(默认的,自己创建也使用桥接模式)

none:不配置网络

host:和宿主机共享网络

container:容器网络连通!(用的少,局限很大)

测试

#我们直接启动的命令 --net bridge 而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

#docker0特点,默认的,域名不能访问的,--link可以打通连接

#我们可以自定义一个网络
docker network create --help

#--driver bridge 桥接模式
#--subnet 192.168.0.0/16 子网掩码
#--gateway 192.168.0.1 网关,类似家里路由器的地址
[root@iZwz96cj54lr4szndhzbezZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

我们自己的网络就创建好了,我们

Docker知识汇总_第56张图片

#创建两个容器基于我们刚刚创建的网络上
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
3ca146219630fcb0dbdbd0abea5b3277bde5cd5af037898611afab2279df5c43
[root@iZwz96cj54lr4szndhzbezZ ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
3d0fb38a72ca140c0b6857175eb99fdd36ffc37f38c13df3c88d6b6d968f3678

#可以查看得到这个网络下有两个容器就是我们刚刚创建的
[root@iZwz96cj54lr4szndhzbezZ ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "0b7e18fe62ef35fadbe186e024a96e3c89725a0672f0729b4ce9e464153e3149",
        "Created": "2021-01-25T00:16:55.10800343+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "3ca146219630fcb0dbdbd0abea5b3277bde5cd5af037898611afab2279df5c43": {
                "Name": "tomcat-net-01",
                "EndpointID": "80e5272e6311049ca71160202b403ddeee0d765019942f9157687cae30d5b88c",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "3d0fb38a72ca140c0b6857175eb99fdd36ffc37f38c13df3c88d6b6d968f3678": {
                "Name": "tomcat-net-02",
                "EndpointID": "e36304257875e423faec18a967ea5e511b2fde30a845627e95ad57778adec4a8",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]


#再次测试ping连接
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.184 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.112 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.113 ms
^C
--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 58ms
rtt min/avg/max/mdev = 0.112/0.136/0.184/0.035 ms

#现在不适使用--link也可以ping名字了
[root@iZwz96cj54lr4szndhzbezZ ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
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.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.089 ms

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络

好处:

redis-保证不同的集群使用不同的网络,保证集群是安全的和健康的

mysql-保证不同的集群使用不同的网络,保证集群是安全的和健康的

Docker知识汇总_第57张图片

网络连通

Docker知识汇总_第58张图片

连接一个容器到一个网络

Docker知识汇总_第59张图片

#测试打通,tomcat01到mynet
#连通之后,直接把tomcat01放到了mynet网络下,一个容器两个ip(公网ip,私网ip)

Docker知识汇总_第60张图片

Docker知识汇总_第61张图片

结论:假设要跨网络去操作别人,就需要使用docker network connect 连通

实战:Redis集群部署

image-20210125110203471

#建立一个redis的网卡
docker network create redis --subnet 172.38.0.0/16 

#编写redis集群配置文件
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF  >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

#启动redis
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p1637${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

#进入第一个redis容器
docker exec -it redis-1 /bin/sh

#搭建集群
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

image-20210125113023298

redis集群部署完毕

我们使用了docke之后,所以的技术都会慢慢的变得简单起来

Springboot微服务打包Docker镜像

1、搭建一个springboot项目

2、打包应用

3、编写dockerfile

4、构建镜像

5、发布运行

首先在IDEA下载docker插件

#1、编写一个简单的controller
#2、然后打包成jar包
#3、编写Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]
#4、构建自己的镜像
#5、运行镜像
#6、测试

企业实战

如果有很多镜像 100个,分别启动,维护很麻烦

Docker Compose

简介
100个微服务,依赖关系

不能手动运行,通过Docker Compose来高效管理,定义运行多个容器

官方介绍

定义、运行多个容器

YAML file配置文件。

single command。命令有哪些?

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

所有环境都可以使用docker Compose

Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.

Using Compose is basically a three-step process:

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
    1. Dockerfile 保证项目在任何地方可以运行
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
    1. services是什么服务?
    2. docker-compose.yml这个文件怎么写?
  3. Run docker-compose up and Compose starts and runs your entire app.
    1. 启动项目

作用:批量容器编排,根据配置文件启动多个容器,解决他们的依赖关系

自己的理解

Compose是Docker官方的开源项目,需要安装!

Dockerfile让程序在任何地方运行

重要的两个概念:

项目:由一群容器组成的一套完整的业务

服务:又一个或者多个相同镜像运行起来的容器提高的service

compose

yarml配置文件

version: "3.8"
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

docker-compose up

Compose:重要的概念

  • 服务services,容器。应用。(web、redis、mysql…)

  • 项目project。一组关联的容器。博客:web、mysql、wp

安装

1.用app.py

2.DcokerFile应用打包镜像(单机)

记录每天学习生活的点点滴滴,感谢身边的每一位帮助过我的人,感谢狂神

你可能感兴趣的:(运维,docker)