Docker!Docker!Docker!学习笔记

环境 : 阿里云服务器 centos7

推荐看狂神说的视频 本笔记只整理了一些视频内容

https://www.aliyun.com/minisite/goods?userCode=xri9is4k

在这里插入图片描述
阿里云服务器购买地址

Dcoker概述

Docker为什么会出现?

一款产品:开发–上线 两套环境 ->应用环境,应用配置.

开发 ---- 运维 问题:我在我的电脑上可以运行! 版本更新导致服务不可用,对于运维来说考验十分大

开发即运维!

环境配置十分麻烦,每个机器都要部署环境(集群Redis,ES,Hadoop…) 费时费力

发布一个项目 (jar + (Redis MySQL jdk ES)) ,项目能不能带上环境安装打包?

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

Windows开发,发布到Linux上.

传统:开发打包成jar ,运维来做环境部署.

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

比如一个安卓应用 java – apk – 发布 (应用商店) --张三使用apk – 安装即可用

java – jar (环境) – 打包项目带上环境 (镜像) --(Docker仓库:商店) — 下载我们发布的镜像 – 直接运行即可
image-20200519093951171

Docker的思想来自于集装箱

JRE – 多个应用 (端口冲突) – 原来都是交叉的

隔离:Docker核心思想–>打包装箱. 每个箱子是互相隔离的

Docker给以上的问题,提出了解决方案.

image-20200519094046607

虚拟机技术缺点:

1, 资源占用十分多

2, 冗余步骤多

3, 启动很慢

容器化技术

容器化技术并不是模拟一个完整的操作系统

image-20200519094232528

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

  • 传统虚拟机,虚拟出一条硬件,运行一个 完整的操作系统,然后在这个系统上安装和运行软件-

  • 容器内的应用直接运行在宿主机的内容, 容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了

  • 每个容器间是相互隔离的,每个容器内部都有一个属于自己的文件系统,互不影响

应用更快速的交付和部署

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

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

更便捷的升级和扩缩容

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

项目打包为一个镜像,水平扩展服务器A,服务器B

更简单的系统运维系统

在容器化之后,我们的开发,测试环境都是高度一致的.

更高效的计算资源利用

1核2g的服务器 可以同时运行几十个tomcat?!!!

Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例

服务器的性能可以被压榨到极致!

Docker安装 请参考视频

狂神说

1 Docker的常用命令

1.1帮助命令


# docker   看docker版本
docker version 
#docker    信息
docker info
#docker    万能命令
docker 命令  --help

帮助文档地址

1.2镜像命令


1.2.1 查看镜像
# 查看本机所有本地镜像
docker images
#解释
REPOSITORY  镜像的仓库源
TAG 		镜像的标签
IMAGE ID 	镜像的ID
CREATED		镜像的创建时间
SIZE		镜像的大小
# 命令的可选项
  -a, --all            列出所有镜像
  -q, --quiet          只显示镜像的ID

image-20200516202537614

1.2.2搜索镜像
# 搜索镜像
docker search  镜像
#可选项 通过收藏来过滤s
--filter=STARS=3000 # 搜索的镜像就STARS大于3000以上的

image-20200516202139615

image-20200516203251174

1.2.3下载镜像
#下载镜像  docker pull 镜像名[:tag] 
[root@weifeng demo]# docker pull mysql
Using default tag: latest         #如果没指定版本会下载最新的
latest: Pulling from library/mysql# 
afb6ec6fdc1c: Pull complete  	  #分层下载 docker image的核心联合文件系统
0bdc5971ba40: Pull complete      
97ae94a2c729: Pull complete 
f777521d340e: Pull complete 
1393ff7fc871: Pull complete 
a499b89994d9: Pull complete 
7ebe8eefbafe: Pull complete 
597069368ef1: Pull complete 
ce39a5501878: Pull complete 
7d545bca14bf: Pull complete 
0f5f78cccacb: Pull complete 
623a5dae2b42: Pull complete 
Digest: sha256:beba993cc5720da07129078d13441745c02560a2a0181071143e599ad9c497fa
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 下面两个命令是一个意思
docker pull mysql 
docker pull docker.io/library/mysql:latest

#指定版本下载
[root@weifeng demo]# docker pull mysql:5.7

image-20200516203032925

image-20200516204044043

1.2.4删除镜像
#通过id删除 docker rmi -f 镜像id
[root@weifeng demo]# docker rmi -f b84d68d0a7db

image-20200516205103306

#批量删除
docker rmi -f $(docker images -aq)

image-20200516222709710

1.3 容器命令


说明: 有了镜像才可以创建容器,使用linux镜像来学习

1.3.1 运行容器
#下载centos镜像
docker pull centos

image-20200516205607709

# 运行镜像
docker run  [可选参数] images
# 参数说明
--name="Name"  	容器名字  tomcat1 tomcat2 用了区分容器
-d  			后台方式运行
-it				使用交互方式运行,进入容器查看内容
#注意 p(小写)  P(大写)
-p				指定容器的端口   -p  8080:8080
		-p		ip:主机端口:容器端口
		-p  	主机端口: 容器端口(常用)
		-p  	容器端口
-P				指定随机端口	

#测试 启动并进入容器
[root@weifeng demo]# docker run -it centos /bin/bash
[root@211e4bb80345 /]# ls  # 查看内部容器的centos
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

image-20200517081501113

1.3.2退出容器
# 退出 后容器停止
[root@211e4bb80345 /]# exit
# 容器不停止退出
Ctrl+P+Q    

image-20200517082048104

1.3.3列出运行的容器
#docker ps 命令
	# 当前正在运行的容器
-a  #列出当前正在运行的容器+带出历史运行过的容器	
-n=?#列出最近创建的容器	
-p  #只显示容器的编号
#列出运行的容器
[root@weifeng demo]# docker ps
#列出
[root@weifeng demo]# docker ps -a
#列出最近创建的容器 n后面数字可选
[root@weifeng demo]# docker ps -a -n=1
#只显示容器的编号
[root@weifeng demo]# docker ps -aq

image-20200516211552967

image-20200516212019240

1.3.4 删除容器
#删除指定容器 运行中的不能删 如果强制删除 需要加 -f 参数(docker rm -f 容器id)
docker rm 容器ID 
#删除所有容器
docker rm -f $(docker ps -aq)

image-20200516212245171

image-20200516213054612

1.3.5 启动和停止容器的操作
# 启动容器
docker start 容器ID

image-20200516214229497

#停止正在运行容器
docker stop 容器ID

image-20200516213405704

docker restart  容器ID     #重启容器
docker kill     容器ID     #强制停止当前容器

1.4常用的其他命令

1.4.1 后台启动容器
# 命令  docker run -d 镜像名
[root@weifeng demo]# docker run -d centos
c29b4906c418eb979e3dd111015508eca9e520cb08e6df51d5b41c5af2ab73c0
[root@weifeng demo]# docker ps
# 问题docker ps 发现 centos 停止了
# 常见的坑,docker 容器使用后台运行 必须要有一个前台进程,否则docker就会自动停止

image-20200516222104870

1.4.2 查看日志
docker logs 

-f 			:跟踪日志输出
--since 	:显示某个开始时间的所有日志
-t 			:显示时间戳
--tail 		:仅列出最新N条容器日志
#例子 运行容器 循环打印hello
[root@weifeng demo]# docker run -d centos /bin/bash -c "while true;do echo hello;sleep 1;done"

#显示日志 docker logs -tf --tail 10 容器ID
[root@weifeng demo]# docker logs -tf --tail 10 40123a87d3a1

image-20200516214350489

image-20200516214800095

1.4.3查看容器中进程ID
# docker top 容器ID
docker top 40123a87d3a1


1.4.4查看镜像|容器元数据
#查看容器元数据
docker inspect 容器ID
[root@weifeng ~]# docker ps -aq
aa6357c78b8f
40123a87d3a1
763aa3e14833
b9d4012f2b72
37c3a8b11187
c29b4906c418
bbdd3d3fe2ff
[root@weifeng ~]# docker inspect aa6357c78b8f
[
    {
        "Id": "aa6357c78b8f51a724642f82c6fb329c4548dc8d4cae8644698f62bbd7573c09",
        "Created": "2020-05-17T00:14:35.849665997Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-05-17T00:14:36.695023294Z",
            "FinishedAt": "2020-05-17T00:18:06.576675345Z"
        },
	.....略
]

image-20200517083115608

image-20200517084334731

1.4.5进入当前运行的容器
#我们通常都是使用后台的方式运行容器,有时需要进入容器,修改一些配置
# 命令 方式一
 docker exec -it 容器id   bashShell 
# 方式二
[root@weifeng ~]# docker attach 容器ID
#两种区别
docker exec 	#进入容器后开启一个新的终端,可以在里面操作(常用)
docker attach   #进入容器正在执行的终端,不会启动新的进程

方式一

image-20200517084823536

方式二

image-20200517085123029

1.4.6从容器内拷贝文件到主机上
docker cp 容器id:容器内文件路径   目的主机路径
#查看运行的容器
[root@weifeng ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
c7c90ac66437        centos              "/bin/bash"         18 minutes ago      Up 39 seconds                           angry_cohen
#进入容器
[root@weifeng ~]# docker attach c7c90ac66437
[root@c7c90ac66437 home]# ls
my.java
[root@c7c90ac66437 home]# read escape sequence
#拷贝到/home文件下
[root@weifeng ~]# docker cp c7c90ac66437:/home/my.java /home
[root@weifeng ~]# ls
auto_disk.sh  bt-uninstall.sh  demo  install.sh  softwore
[root@weifeng ~]# cd /home/
[root@weifeng home]# ls
cao  my.java  redis  www
#拷贝式一个手动过程,之后可以通过 -v 卷的技术,可以实现文件自动同步

image-20200517090747714

小结

image-20200517091953964

image-20200517092923812

image-20200517092953977

docker 的命令是非常多的 ,上面只是最常用的命令

2 Docker 的练习

Docker安装nginx

2.1 安装nginx

  1. 搜索镜像 search 建议去dockerhub搜索 可以看到详细信息

    dockerHub地址:docker仓库地址

    image-20200517094141117

  2. docker pull nginx

image-20200517095240897

  1. 步骤

    [root@weifeng ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    nginx               latest              9beeba249f3e        29 hours ago        127MB
    centos              latest              470671670cac        4 months ago        237MB
    #后台启动nginx 起名 nginx01 暴露端口号为20884(注意此端口需要你的服务器开放了此端口)
    # -d 后台运行
    # --name 给容器命名
    # -p 宿主机端口:容器内部端口
    [root@weifeng ~]# docker run -d --name nginx01 -p:20884:80 nginx
    6abddc1ce2eed5ecf4a1ae52026191c2d1a27c24c743b63e8c66379c450ba831
    [root@weifeng ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
    6abddc1ce2ee        nginx               "nginx -g 'daemon of…"   7 seconds ago       Up 6 seconds        0.0.0.0:20884->80/tcp   nginx01
    c7c90ac66437        centos              "/bin/bash"              56 minutes ago      Up 38 minutes                               angry_cohen
    #测试
    [root@weifeng ~]# curl localhost:20884
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    #进入容器
    [root@weifeng ~]# docker exec -it nginx01 /bin/bash
    root@6abddc1ce2ee:/# whereis nginx
    nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
    root@6abddc1ce2ee:/# cd /etc/nginx/ 
    root@6abddc1ce2ee:/etc/nginx# ll
    bash: ll: command not found
    root@6abddc1ce2ee:/etc/nginx# ls
    conf.d		koi-utf  mime.types  nginx.conf   uwsgi_params
    fastcgi_params	koi-win  modules     scgi_params  win-utf
    root@6abddc1ce2ee:/etc/nginx# 
    
    

    端口暴露的概念

    image-20200517101822590

2.2安装tomcat

#官方的命令 容器用完就删 做测试可以用
docker run -it --rm tomcat:9.0

#下载在启动
[root@weifeng ~]# docker pull tomcat:9.0
9.0: Pulling from library/tomcat
Digest: sha256:ce753be7b61d86f877fe5065eb20c23491f783f283f25f6914ba769fee57886b
Status: Image is up to date for tomcat:9.0
docker.io/library/tomcat:9.0

#启动
[root@weifeng ~]# docker run -d -p 20885:8080 --name tomcat01 tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
Digest: sha256:ce753be7b61d86f877fe5065eb20c23491f783f283f25f6914ba769fee57886b
Status: Downloaded newer image for tomcat:latest
17aefd39887d6a5adbd1cd272957da8bc0344c2a12912ba92179c4906c3c19b0
#进入容器
[root@weifeng ~]# docker exec -it tomcat01 /bin/bash
root@17aefd39887d:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work
#问题 1.linux命令少了 2.没有webapps  
#原因 阿里云镜像默认是最小的镜像,所以不必要的都剔除了 保证最小可运行的环境
root@17aefd39887d:/usr/local/tomcat# cd webapps
root@17aefd39887d:/usr/local/tomcat/webapps# ls
root@17aefd39887d:/usr/local/tomcat/webapps# 
# 注意 因为webapps里面没有文件 所以外部访问404
#解决
root@17aefd39887d:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work
#进入到webapps.dist目录
root@17aefd39887d:/usr/local/tomcat# cd webapps.dist/
root@17aefd39887d:/usr/local/tomcat/webapps.dist# ls
ROOT  docs  examples  host-manager  manager
root@17aefd39887d:/usr/local/tomcat/webapps.dist# cd ../
# 将webapps.dist目录下的文件拷贝到webapps目录下
root@17aefd39887d:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@17aefd39887d:/usr/local/tomcat# cd webapps
root@17aefd39887d:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
root@17aefd39887d:/usr/local/tomcat/webapps# 

image-20200517094220484

解决

image-20200517101119304

2.3 安装Elasticsearch和Kibana

#es暴露的端口很多
#es十分的耗内存
#es的数据一般要放置到安全目录!挂载
# --net somentwork ?网络配置
#启动 
docker run -d --name elasticsearch  -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
#启动了 liunx就卡住了 不建议这样用 服务器配置高的随意 我的直接卡住了
docker stats 查看

image-20200517112227788

#es是十分耗内存的 启动可以增加内存的限制,修改配置文件 -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
#再次查看(注意 这个命令的容器和之前的容器名相同了 把之前的删掉就行了)
#启动后就运行的快了

image-20200517112725309

#查看
[root@weifeng ~]# curl localhost:9200

image-20200517112951781

2.4 Docker可视化

  • portainer (先用这个)
  • Rancher(CI/CD再用)

protainer

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

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

image-20200517114400004

访问8088 第一次加载会很慢 等待即可

image-20200517114542057

自己设置密码即可 密码长度大于八位

image-20200517114847613

3 Docker镜像讲解

3.1镜像是什么


推荐看视频理解

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

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

如何得到镜像:

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

3.2 Docker镜像加载原理

UnionFS(联合文件系统)

UnionFS联合文件系统是一种分层的,轻量级并且高性能的文件系统,它最大的特点就是可以支持对文件的修改作为一次提交来一层层放叠加,同时可以将不同的目录挂载到同一个虚拟文件系统下(unite several directiories into a single virtual filesystem。UnionFS联合文件系统是Docker镜像的基础,镜像可以通过分层来继承,基于基础镜像可以制作成各种应用镜像。

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

image-20200517122110497

虚拟机式分钟级别,容器是秒级!

image-20200517123848049

image-20200517123912388

image-20200517124717173

image-20200517124848144

image-20200517125134360

3.3 commit镜像

docker commit 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

测试

#启动默认的tomcat
docker run -it -p 8080:8080 tomcat /bin/bash
#发现这个默认的tomcat是没有webapps应用 ,镜像的原因 官方的镜像默认webapps 是没有文件的
#手动拷贝进去
#将修改后的容器 通过commit 提交为一个镜像! 以后就可以使用修改后的镜像了
[root@weifeng ~]# docker commit -a="卫风" -m="add webapps" 482f029ecab1 tomcat02:1.0

自己创建镜像

image-20200517131314251

如果你想要保存当前容器的状态,就可以通过commit来提交,来获得一个镜像
类似于虚拟机的快照 

4 容器数据卷

4.1什么是数据卷

docker的理念回顾

将应用和环境打包成一个镜像!
数据?如果都在容器中,那么我们容器删除,数据就会丢失! 需求: 数据可以持久化

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

容器之间可以有一个数据共享的技术! Docker容器中产生的数据,同步到本地!

这就是卷技术! 目录的挂载,将我们的容器内的目录挂载到Liunx上面

image-20200517150018789

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

4.2使用数据卷


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

docker run -it -v 主机目录:容器内目录
#测试
[root@weifeng test]# docker run -it -v /home/test/:/home centos /bin/bash

image-20200517164859601

查看容器元数据
docker inspect 容器id
[root@weifeng test]# docker inspect 5c1c442d3e5a
#找到mounts可以看到挂载

image-20200517165806157

#测试
在容器内部的操作会自动同步到容器外挂载的目录 类似vue双向绑定

image-20200517170226227

  1. 停止容器
  2. 在宿主机上修改文件
  3. 启动容器
  4. 容器内的数据依旧是同步的

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

4.3 安装MySql

MySQL的数据库持久化的问题

#下载mysql
[root@weifeng test]# docker pull mysql:5.7

image-20200517191940298

#运行容器 ,需要做数据挂载 配置mysql的账户密码
#官方   docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#实际运行的命令 根据情况自己修改即可
# -d    后台运行
# -p    端口映射
# -v    卷映射 可以配置多个
# -e    环境配置
# -name 容器名字  
[root@weifeng ~]# docker run -d -p 28885: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

image-20200517194600589

通过外部访问成功

image-20200517195006784

用sqlyog创建数据库 会同步到宿主机挂载的目录下

image-20200517202230902

此时就算把容器删除,挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!

4.4 具名和匿名挂载

#匿名挂载
-v容器 容器内路径!
docker run -d -p --name nginx01 -v /etc/nainx nginx
#查看所有的volume的情况
[root@weifeng test]# docker volume ls
DRIVER              VOLUME NAME
local             45a74152a07762e29e08569ada14eddeda23afc717be8d6a18d7326960926ad4
#这里发现,这就是匿名挂载,我们在 -v 里只写了容器内的路径,没有写容器外的路径

#具名挂载
[root@weifeng test]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
3aab8c7c6c12f7e8a86956e347fa38a38b6c13c3b632298b9324a4a3df6b3bba
[root@weifeng test]# docker volume ls
DRIVER              VOLUME NAME
local               juming-nginx
# 通过 -v 卷名:容器内路径
# 查看这个卷

image-20200517214405786

所有的docker容器内的卷,没有指定目录的情况下 都是在 /var/lib/docker/volume/***(卷名)/data

我们通过具名挂载可以方便的找到我们的一个卷 推荐使用具名挂载

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

#扩展 通过 -v 容器内路径:ro或者rw 改变读写权限
#ro    readonly   只读
#rw	   readwrite  可读可写
# 一旦这个设置了容器权限,容器对我们挂载出来的内容就有限定了!
[root@weifeng _data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
###或者
[root@weifeng _data]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
# ro   只有看到ro就说明这个路劲只能通过宿主机来操作,容器内部是无法操作!

方式二

一 创建一个dockerfie文件 ,名字可以随机 建议 Dockerfile
#通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层
FROM centos
VOLUME   ["volume01","volume02"]

CMD echo "------end-------"

CMD /bin/bash           
[root@weifeng docker-test-volume]# docker build -f  dockerfile1 -t my/centos:1.0  .
#这里的每个命令就是镜像的一层

image-20200517220927641

image-20200517221018688

#启动自己生成的镜像

image-20200517221721086

image-20200517222111054

查看一些卷挂载的路劲

image-20200517222027977

测试一下刚才的文件是否同步出去了!

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

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

4.5数据卷容器


多个mysql同步数据!

image-20200517222858750

#启三个容器
[root@weifeng ~]# docker run -it --name docker1 f76d77329573

[root@weifeng ~]# docker run -it --name docker02 --volumes-from docker1 f76d77329573

[root@weifeng ~]# docker run -it --name docker03 --volumes-from docker1 f76d77329573

image-20200517223254740

进去docker01目录下创建文件

image-20200517225023111

不停止退出进去docker02 和docker03 分别查看

image-20200517225216735

image-20200517225253117

此时发现另两个容器也有docker01文件

docker01文件同步到docker02和docker03容器

只要有一个容器存在数据依旧可以访问

image-20200517225901121

多个mysql实现数据共享

[root@weifeng ~]# docker run -d -p 28885:3306 -v /etc/mysql/conf.d -v /var/lib/mysql  -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

[root@weifeng ~]# docker run -d -p 28885:3306 -v /etc/mysql/conf.d -v /var/lib/mysql  -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 volumes-form mysql01 mysql:5.7

#这个时候可以实现两个容器数据同步!

结论:

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

但是一旦你持久化到了本地,这个时候,本地的数据库是不会删除的!

5 初始Dockerfile

5.1自定义镜像

Dockerfile就是用来构建docker 镜像的构建文件! 就是命令脚本

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub,阿里云镜像仓库!)

查看官方怎么做的?

image-20200518080207913

点击版本信息 以centos7 为例

image-20200518080412344

很多官方的镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!

官方既然可以制作镜像,那我们也可以!

5.2DockerFile构建过程

基础知识

  1. 每个保留关键字(指令)都是必须是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建一个新的镜像层,并提交!

image-20200518081202603

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

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

  • DockerFile : 构建文件,定义了一个一切的步骤,源代码
  • DocekrImages : 通过DockerFile构建生成的镜像,最终发布运行的产品
  • Docker容器 : 容器就是镜像运行起来提供服务器

5.3 学习dockerFile的指令

image-20200518081112404

FROM			# 基础镜像,一起从这里开始构建

MAINTAINER 		# 镜像是谁写的,姓名+邮箱

RUN				# 镜像构建的时候需要运行的命令

ADD				# 编译镜像时复制文件到镜像中,比如添加个tomcat镜像

WORKDIR			# 镜像的工作目录

VOLUME			# 挂载的目录

EXPOSE			# 暴露端口配置

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

ENTRYPOINT		# 指定这个容器启动的时候要运行的命令,可以追加命令

ONBUILD			# 当构建一个被继承的 DockerFile 这个时候就会运行ONBUILD 的指令,触发指令

COPY			# 类似ADD, 将我们的文件拷贝到镜像中

ENY				# 构建的时候设置环境变量

5.4 实战测试


Docker Hub中 99%

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

image-20200518083835353

创建一个自己的CentOS镜像

编写dockerFile文件

vim mydockerfile

FROM centos

MAINTAINER weifeng<1783246945@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     

通过这个镜像构建镜像

#命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]

[root@weifeng dockerfile]# docker build -f mydockerfile -t mycentos:0.1 .

#最后成功标识
Successfully built d97c9630e08e
Successfully tagged mycentos:0.1

# 进行测试

对比 : 之前的工作目录默认是根目录,没有ifconfig 和 vim

image-20200518090743960

自己创建的镜像

image-20200518090833741

我们可以列出本地镜像的变更历史

# 命令 docker history 镜像id
[root@weifeng dockerfile]# docker history d97c9630e08e

image-20200518092657224

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

CMD 和 ENTRYPOINT 的区别

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

ENTRYPOINT		# 指定这个容器启动的时候要运行的命令,可以追加命令

测试CMD

#建dockerfile文件
vim cmd-test
#内容
FROM centos
CMD ["ls","-a"]
#执行构建
[root@weifeng dockerfile]# docker build -f cmdtest -t cmdtest .
#成功之后直接执行构建后的镜像
[root@weifeng dockerfile]# docker run c63eb140ebc4
#发现ls-a 生效了
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
# 测试追加个命令 
[root@weifeng dockerfile]# docker run c63eb140ebc4 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
[root@weifeng dockerfile]# 
# 因为cmd 的情况下 -l 替换了 CMD["ls","a"]命令, -l 不是命令所以报错!

测试 ENTRYPOINT

#创建dockerfile文件
vim vim dockerfile-cmd-entrypoint
#编写内容
FROM centos
ENTRYPOINT ["ls","-a"]
#保存后退出 进行构建 注意 后面的  . 不要忘了
[root@weifeng dockerfile]# docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .
# 构建完运行此镜像
[root@weifeng dockerfile]# docker run bd8100b2acff
# 输出结果
.
..
.dockerenv
bin
dev
etc
home
# 现在后面加 -l 进行测试
[root@weifeng dockerfile]# docker run bd8100b2acff -l
# 结果 我们的追加命令 是直接ENTRYPOINT 命令下的
total 56
drwxr-xr-x   1 root root 4096 May 18 02:02 .
drwxr-xr-x   1 root root 4096 May 18 02:02 ..
-rwxr-xr-x   1 root root    0 May 18 02:02 .dockerenv
lrwxrwxrwx   1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x   5 root root  340 May 18 02:02 dev
drwxr-xr-x   1 root root 4096 May 18 02:02 etc
drwxr-xr-x   2 root root 4096 May 11  2019 home
lrwxrwxrwx   1 root root    7 May 11  2019 lib -> usr/lib

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

5.5 实战: Tomcat镜像

  1. 准备镜像文件tomcat压缩包,jdk的压缩包!

image-20200518102907702

  1. 编写dockerfile文件,官方命名 Dockerfile ,build 就会自动寻找这个文件,就不需要-f 指定docker file 文件路径

    FROM centos                                                                                                                      
    MAINTAINER weifeng<1783246945@qq.com>
    
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u241-linux-x64.tar.gz /usr/local/
    
    ADD apache-tomcat-9.0.35.tar.gz /usr/local/
    
    RUN yum -y install vim 
    
    ENV MYPATH /usr/local
    
    WORKDIR $MYPATH
    
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_241
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALTNA_HOME /usr/local/apache-tomcat-9.0.35
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALTNA_HOME/bin
    
    EXPOSE 8080
    CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/bin/logs/catalina.out
    
    
  2. 执行构建

    [root@weifeng tomcat]# docker build -t diytomcat .
    

    image-20200518105902315

    image-20200518105939336

  3. 运行

    [root@weifeng tomcat]# docker run -d -p 9090:8080 --name mytomcat -v /home/cao/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/cao/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs diytomcat
    
    

image-20200518110438999

  1. 进入运行中的容器 访问测试

    [root@weifeng tomcat]# docker exec -it 5605928525ea /bin/bash
    

    image-20200518110741705

  2. 发布项目

因为之前挂载了 所以此时只要把文件 放到 挂载目录 就可以实时 发布了

容器外

image-20200518112750265

容器内

image-20200518112813676

访问后 发现可以访问

我们以后开发的步骤:需要掌握DockerFile的编写! 我们之后的一切都是使用docker镜像来发布运行!

5.6发布自己的镜像

5.6.1 发布到DOckerHub
  1. 地址 https://hub.docker.com/

    (需要自己注册个账号)

  2. 确定这个账号可以登陆

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

  4. 通过命令行登陆

    image-20200518150444105

    docker login -u (用户名)   
    #回车后输入密码
    
    

    image-20200518151129890

  5. 提交镜像

    # docker push <作者>/<镜像名>:版本号
    [root@weifeng ~]# docker push weifeng/diytomcat:1.0
    #出现问题
    The push refers to repository [docker.io/weifeng/diytomcat]
    An image does not exist locally with the tag: weifeng/diytomcat
    # 原因及解决 当前镜像没有版本 
    # docker tag 镜像id <作者用户名>/<镜像>:版本号
    [root@weifeng ~]# docker push 用户名/tomcat:1.0
    

    image-20200518153748485

    提交的时候也是按照镜像的层级进行提交

5.6.2发布阿里云镜像
  1. 登陆阿里云

  2. 找到容器镜像服务

  3. 创建命名空间 点击创建就可以了(注意一个账户只能创建三个命名空间)

    image-20200518155534388

  4. 创建镜像仓库 点击创建镜像仓库 一步一步创建即可

    image-20200518155800689

    填写完信息记得选本地仓库

image-20200518155928224

这就是创建成功

image-20200518160026789
示例

image-20200518160333767

根据步骤一步一步来即可

主要参考官方文档

小结

6. Docker网络

6.1 理解网络Docker0网络

清空所有环境

测试

image-20200518165250457

三个网络

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

image-20200518165427193

[root@weifeng ~]# docker run -d -P --name tomcat01 tomcat
# 启动容器 查看容器内部的网络地址 ip addr
[root@weifeng ~]# docker exec -it tomcat01 ip addr
# 发现容器启动的时候得到一个 eth0@if55 地址 ,docker分配的
[root@weifeng ~]# ping 172.17.0.2
# 发现可以ping 通docker容器内部

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7NyMb6g-1589852930362)(upload%5Cimage-20200518170303001.png)]

image-20200518170521670

原理

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

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

再次测试ip addr 发现多了一个网卡

image-20200518171207937

  1. 在启动一个tomcat02 发现有多了一对网卡

image-20200518171643398

# 我们发现这个容器带来的网卡 都是一对一对的
# evth-pair 就是一对的虚拟设备接口,他们都是成对成对出现的,一端连接协议,一端彼此连接
# 正因为有这个特性, evth-pair 充当一个桥梁,连接各种虚拟网络设备
# OpenStac Docker 容器之间的连接,OVS 的连接 都是使用evth-pair 技术
  1. 我们测试下 tomcat01 和 tomcat02 可不可以ping通

    image-20200518180136961

    结论 : 容器和容器之间是可以ping通的

    image-20200518181906765

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

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

    docker使用的是Linux的桥接,宿主机中是一个docker的网桥 docker0 (最多可以分配65535个)

    image-20200518182721586

    Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高!

    (比如: 内网传递)

    只有容器删除,对应的一对网桥就没了!

    image-20200518215053533

6.2 --link

思考一个场景,我们编写了一个微服务,database url=ip , 项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以名字来访问容器?

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

#如何可以解决呢?
#docker run -d -P --name tomcat03 --link tomcat02 tomcat
#docker exec -it tomcat03 ping tomcat02
64 bytes from tomcat02 (172.17.0.3): icmp_seq=53 ttl=64 time=0.091 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=54 ttl=64 time=0.091 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=55 ttl=64 time=0.095 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=56 ttl=64 time=0.086 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=57 ttl=64 time=0.091 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=58 ttl=64 time=0.085 ms
#反向可以ping通吗?
[root@weifeng ~]# docker exec -it tomcat2 ping tomcat03
Error: No such container: tomcat2
[root@weifeng ~]# 
# 

探究

 # 列出docker网络ip
 docker network ls 
 # 查看name是brige的元数据  docker network inspect networkID
 docker network inspect 08f69d91fc03

image-20200518214454748

其实这个tomcat03就是在本地配置了tomcat02的配置

image-20200518215622256
本质探究: --link 就是我们hosts配置中增加了一个 172.17.0.4 tomcat02 的映射

我们现在玩Docker 已经不建议使用docker0!

docker0问题 : 它不支持容器名连接访问!

6.3 自定义网络

查看所有的docker网络

[root@weifeng ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
08f69d91fc03        bridge              bridge              local
f1d04511057a        host                host                local
99e79746af60        none                null                local

网络模式

bridge : 桥接 docker

none : 不配置网络

host : 和宿主机共享网络

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

测试

# 把之前的容器都删掉 净化网络环境
[root@weifeng ~]# docker rm -f $(docker ps -aq)
# 查看网络
[root@weifeng ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
08f69d91fc03        bridge              bridge              local
f1d04511057a        host                host                local
99e79746af60        none                null                local

#我们之间启动的命令 默认有 --net bridge  这个就是我们的docker0
[root@weifeng ~]# docker run -d -P --name tomcat01 - tomcat
[root@weifeng ~]# docker run -d -P --name tomcat01 --net bridge tomcat

#docker 特点 , 默认 ,域名不能访问 --link 可以打通容器

#我们可以自定义一个网卡  自定义一个网络
# --driver  bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
[root@weifeng ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
1c058a8b2e667f10b51a61a2639e15da2904073240e10538eb206ac6b7501d68
[root@weifeng ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
08f69d91fc03        bridge              bridge              local
f1d04511057a        host                host                local
1c058a8b2e66        mynet               bridge              local
99e79746af60        none                null                local
# 查看自己创建的网络元数据
docker network inspect mynet

image-20200518222030659

# 用自己创建的网络运行tomcat容器
[root@weifeng ~]# docker run -d -P --name tomcat01 --net mynet tomcat

[root@weifeng ~]# docker run -d -P --name tomcat02 --net mynet tomcat

image-20200518222212425

#再次测试 现在不使用--link 也可以ping名字了
[root@weifeng ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.099 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.085 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.092 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=5 ttl=64 time=0.093 ms

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

好处:

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

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

6.4 网络联通

image-20200518223528284

image-20200518223629036

#测试打通 tomcat01 和 1
[root@weifeng ~]# docker network connect mynet tomcat1
#查看元数据
[root@weifeng ~]# docker network inspect mynet
#连通后就是将tomcat01 放到了mynet网络下

image-20200518224305678

image-20200518224605478

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

6.5 部署Redis集群

image-20200518224936079

#shell脚本
#创建网卡
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-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
# 启动
[root@weifeng ~]#
# 一次性启动
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.comf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf: \

# 一个一个启动
# 开启1
docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf -v /mydata/redis/node-1/data:/data -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 开启2
 docker run -p 6372:6379 -p 16372:16379 --name redis-2 -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf -v /mydata/redis/node-2/data:/data -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 开启3 这个只要把外面的端口改下就好 比如 6372:6379 改为 6373:6379 把涉及的改掉即可
 docker run -p 6373:6379 -p 16373:16379 --name redis-3 -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf -v /mydata/redis/node-3/data:/data -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
 # 后面的依次类推即可
 
 #进入rdis-1 创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.3
8.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

docker搭建redis集群完成!

image-20200519084740551

使用docker之后,所有的技术都会变得简单

6.6 spirng boot 微服务打包成Docker镜像

  1. 构建spring boot项目
  2. 打包应用
  3. 编写dockerfile
  4. 构建镜像
  5. 发布运行

以后我们使用了Docker之后,给别人交付的就是一个镜像即可!

7 Docker Compost

8 Docker Swarm

9 CI/CD 之Jenkins

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caoweifeng12

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值