Docker学习笔记-快速上手笔记(保姆级)

文章目录

  • Docker简介
  • Docker安装
    • 阿里云加速服务
    • 运行流程图(run)
  • Docker常用命令
    • 基础命令
    • 镜像命令
      • docker images
      • docker search
      • docker pull
      • docker rmi
    • 容器命令
      • **新建容器并启动**
      • **容器退出命令**
      • 查看运行的容器
      • 删除容器
      • 启动和停止容器的操作
  • 其他命令
      • 后台启动容器
      • 查看日志
      • 实时查看CPU、内存等信息
      • 查看容器中的进程信息
      • 查看容器的元数据
      • 进入正在运行的容器
      • 从容器内复制文件到主机
  • Docker配置Nginx容器例子
  • Docker配置Tomcat容器例子
  • Docker可视化面板
  • Docker镜像讲解
    • 镜像是什么
    • 镜像分层理解
    • commit镜像
  • 容器数据卷
    • 容器数据卷的使用
      • **方法一**
      • 方法一实战:mysql+容器数据卷
      • 方法二:具名和匿名挂载
      • 知识拓展
    • 配合DockerFile使用
    • 数据卷容器
    • 数据卷volume命令
      • 查看本地数据卷
      • 查看卷详细信息(元数据)
      • 删除一个卷
      • 删除容器时同时删除卷
      • 删除所有卷
  • DockerFile
    • 介绍
    • 热知识
    • DockerFile命令
    • Centos镜像解析
    • 创建自己的镜像
      • 脚本文件
      • 构建镜像
    • CMD和ENTRYPOINT区别
      • CMD
      • ENTRYPOINT
    • 制作Tomcat镜像实战
    • 发布镜像
      • 发布到DockerHub
        • 登录命令login
        • 发布命令push
      • 发布到阿里云镜像服务
        • 官方使用方式
        • 使用过程(推送镜像)
        • 使用例子
  • Docker 小结
    • 所有命令
  • Docker网络
    • Docker0
    • 通信原理
    • --link容器互联
    • 自定义网络
      • 查看所有docker网络
      • 创建网络
      • 查看网络信息
      • 使用网络
      • 指定IP启动
      • 跨网段通信
  • Docker实战:Springboot打包docker镜像
    • springboot项目
    • 打包应用
    • 编写dockerfile
    • 构建镜像
    • 发布运行
  • 未完待续!!!
    • 编写dockerfile
    • 构建镜像
    • 发布运行
  • 未完待续!!!

Docker简介

Docker是一个应用打包、分发、部署的工具
可以理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要。
而普通虚拟机则是一个完整庞大的系统。

打包、分发、部署
打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
分发:你可以吧你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不论是在Windows/Mac/Linux

镜像、容器
镜像:可以理解为软件的安装包,可以方便的进行传播和安装
容器:软件安装后的状态,每个软件运行环境是独立的、隔离的、称之为容器

Docker安装

  1. 安装需要的软件包,yum-util提供yum-config-manager功能,另外两个是devecemapper驱动依赖的

    yum install -y yum-utils device-mapper-persistent-data lvm2
    
  2. 设置yum源(阿里源)

    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    
  3. 更新源

    yum update
    
  4. 安装docker (docker-ce社区 ee企业版)

    yum install docker-ce docker-ce-cli containerd.io
    
  5. 使用命令docker version查看版本判断是否安装成功

  6. 运行官方测试例子HelloWorld

    1. 启动Docker

    2. 运行hello world例子
      docker run hello-world

    3. 图片说明

      远端是指DockerHub
      Docker学习笔记-快速上手笔记(保姆级)_第1张图片

    4. 查看本地镜像
      docker images
      在这里插入图片描述

    5. docker安装的目录(默认)
      /var/lib/docker

阿里云加速服务

用于加速个人仓库

开启步骤:

  1. 阿里云控制台
  2. 容器镜像服务
  3. 没有开通就先开通
    Docker学习笔记-快速上手笔记(保姆级)_第2张图片

4.镜像工具-镜像加速器
Docker学习笔记-快速上手笔记(保姆级)_第3张图片

运行流程图(run)

docker run hello-world时发生了什么?

Docker学习笔记-快速上手笔记(保姆级)_第4张图片

Docker常用命令

官方文档:https://docs.docker.com/

基础命令

#启动docker服务
systemctl start docker
#查看版本
docer version
#查看更详细的信息,包括镜像和容器数量
docker info
#帮助
命令 --help

镜像命令

docker images

查看本地所有的镜像

[root@hecs-79730 docker]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    feb5d9fea6a5   8 months ago   13.3kB

#解释
REPOSITORY	镜像的仓库源
TAG			镜像的标签
IMAGE ID	镜像的id
CREATED		镜像创建时间
SIZE		镜像大小

可选参数:
  -a, --all             #列出所有镜像
  -q, --quiet           #只显示镜像的ID

docker search

所有镜像(从DockerHub中搜索一样)

[root@hecs-79730 docker]# docker search mysql
NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                          MySQL is a widely used, open-source relation…   12708     [OK]       
mariadb                        MariaDB Server is a high performing open sou…   4878      [OK]       

#可选项
--filter=stars=3000 	#搜索出来的镜像就是stars大于3000的

docker pull

拉取镜像(下载镜像)

#下载镜像 docker pull 镜像名[:版本tag]
[root@hecs-79730 docker]# docker pull mysql
Using default tag: latest			#如果不写tag,默认就是最新版
latest: Pulling from library/mysql
72a69066d2fe: Pull complete 		#分层下载,docker iamge的核心 联合文件
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
688ba7d5c01a: Pull complete 
00e060b6d11d: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709	#签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest		#镜像真实地址

#两个命令是一致的,第二条使用真实地址来拉取镜像
#docker pull mysql
#docker pull docker.io/library/mysql:latest

#指定版本下载
[root@hecs-79730 docker]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists 	#共用相同的文件
93619dbc5b36: Already exists 
99da31dd6142: Already exists 
626033c43d70: Already exists 
37d5d7efb64e: Already exists 
ac563158d721: Already exists 
d2ba16033dad: Already exists 
0ceb82207cd7: Pull complete 
37f2405cae96: Pull complete 
e2482e017e53: Pull complete 
70deed891d42: Pull complete 
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi

删除镜像命令,rmi意思就是remove image

#根据镜像id删除
docker rmi -f 3218b38490ce
#删除多个镜像
docker rmi -f id1 id2 id3 id4 ...
#删除全部容器
docker rmi -f $(docker images -aq) #$()先执行里面的命令,里面的命令意思是列出所有镜像id,执行完里面后再执行外层的rmi -f,根据所有的镜像id进行批量删除

容器命令

有了镜像才可创建容器

下面例子是在docker里面跑一个centos容器来测试学习

拉取centos镜像

[root@hecs-79730 docker]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete 
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest

新建容器并启动

docker run [可选参数] image

#参数说明
--name="Name"		#容器名字,用来区分容器
-d					#后台运行方式
-it					#使用交互方式运行,进入容器查看内容
-rm					#容器退出后将会自动删除容器,也就是docker ps -a 也没有记录
-p					#指定容器端口
	-p 				#ip:主机端口:容器端口	(映射,访问宿主机的端口会映射给容器)
	-p				#主机端口:容器端口(常用)
	-p				#容器端口
-P					#随机指定端口

docker run -it centos /bin/bash
-it 交互方式打开
centos 镜像名
/bin/bash 以命令行交互方式打开

Docker学习笔记-快速上手笔记(保姆级)_第5张图片

容器退出命令

#直接退出并停止容器
exit
#容器不停止退出(快捷键)
ctrl + P + Q

查看运行的容器

#查看正在运行的容器
docker ps
#查看所有的容器
docker ps -a
#查看最近创建的容器
docker ps -a -n=1		#最近1个
#以容器ID显示所有容器
docker ps -aq

删除容器

#根据容器id指定删除,不能删除正在运行的容器,强势删除可以 rm -f
docker rm 容器id
#删除所有容器,正在运行的容器删除不了
docker rm -f $(docker ps -aq)
#删除所有容器2
docker ps -a -q | xargs docker rm

启动和停止容器的操作

#启动容器
docker start 容器id
#重启容器
docker restart 容器id
#停止当前正在运行的容器
docker stop 容器id
#强制停止当前容器
docker kill 容器id

其他命令

后台启动容器

#docker run -d centos
#问题docker ps,发现centos停止了
#常见的坑:容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
#nginx,启动容器后,发现自己没有提供服务,就会立即停止,就是没有程序了

查看日志

docker logs -f -t --tail 容器id
# -tf 显示日志
# --tail number 显示日志的条数
示例:
docker logs -tf --tail 10 容器id

实时查看CPU、内存等信息

docker stats

查看容器中的进程信息

#根据容器id查看容器中的进程信息
[root@hecs-79730 docker]# docker top be1086a105df
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12987               12968               0                   17:29               pts/0               00:00:00            /bin/bash

查看容器的元数据

#根据容器id查询
docker inspect 容器id
#根据镜像id查询
docker iamge inspect 镜像id

这个其实才是完整的容器id,里面包含了许多信息,其中网络配置比较重要
Docker学习笔记-快速上手笔记(保姆级)_第6张图片

进入正在运行的容器

第一种方式

#当容器后台启动后,或者按ctrl+P+Q退出容器,使用此命令重新进入
docker exec -it 容器id bashShell
#解释
-it		以交互方式进入
bashShell	前台交互方式
#例子
docker exec -it be1086a105df /bin/bash
#解释
/bin/bash 以命令行方式进入

在这里插入图片描述

第二种方式

#查看正在运行的容器
[root@hecs-79730 docker]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
be1086a105df   centos    "/bin/bash"   13 minutes ago   Up 8 seconds             admiring_wilson
#使用docker attach进入到容器
[root@hecs-79730 docker]# docker attach be1086a105df
[root@be1086a105df /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

两种方式的区别

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

从容器内复制文件到主机

无论容器是否在运行都可以进项复制,前提是容器没有被删除

#docker cp	容器id:容器内路径	目的主机的路径
[root@hecs-79730 docker]# docker cp be1086a105df:/home/helloworld.java /data
[root@hecs-79730 docker]# ls /data
a.txt  helloworld.java

Docker配置Nginx容器例子

#1、搜索镜像,可以去dockerhub.com查找对应版本以及文档
docker search nginx
#2、拉取镜像至本地
docker pull nginx
#3、运行测试
#解释
# -d		后台运行
# --name	给容器命名
# -p		宿主机端口:容器端口(因为nginx默认是监听80端口的)
[root@localhost ~]# docker run -d --name nginx01 -p 3344:80 nginx
#4、查看正在运行容器
[root@localhost ~]# docker ps
#5、测试nginx是否启动成(返回nginx网页默认源码)
[root@localhost ~]# curl localhost:3344

其中端口映射的原理如下图所示
外网用户通过请求宿主机暴露的接口,便会映射给对应端口的容器。
主要要开入防火墙和安全组的入栈端口。

Docker学习笔记-快速上手笔记(保姆级)_第7张图片

进入正在运行nginx的容器

#查看正在运行的容器
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS              PORTS                                   NAMES
7e3f0b14cc3f   nginx     "/docker-entrypoint.…"   9 minutes ago   Up About a minute   0.0.0.0:3344->80/tcp, :::3344->80/tcp   nginx01
#通过exec命令,打开一个新终端进入
#nginx01是刚在启动nginx时命名的名字,可以直接通过名字操作,不需要容器id
[root@localhost ~]# docker exec -it nginx01 /bin/bash
root@7e3f0b14cc3f:/# ls
bin   dev		   docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
boot  docker-entrypoint.d  etc			 lib   media  opt  root  sbin  sys  usr

nginx

#查找nginx目录
root@7e3f0b14cc3f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@7e3f0b14cc3f:/# 
#/etc/nginx			nginx配置文件
#/usr/share/nginx	静态网页文件

Docker配置Tomcat容器例子

  1. 前往DockerHub查询Tomcat版本以及使用文档
    https://hub.docker.com/_/tomcat

  2. docker 拉取镜像,这里指定9.0版本
    docker pull tomcat:9.0

  3. 官方启动方式

    #官方启动方式
    docker run -it --rm tomcat:9.0
    #这种方式是用于临时测试的,
    #-rm 是用完即删,就是tomcat退出时会自动删除容器,也就是docker ps -a也没记录
    #而且这种方式是以前台方式启动,启动后直接打印tomcat日志
    
  4. 常用启动方式

    docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
    # -d		后台启动
    # -p		端口映射,宿主机3355,容器8080,因为tomcat默认端口为8080
    # --name	设定名字
    
  5. 发现问题1:外网无法通过http://ip:端口访问

    1. 开放宿主机防火墙和安全组:3355
  6. 发现问题2:Tomcat是访问到了,但是报404页面

    1. 这是正常的
    2. 我们可以通过进入tomcat容器看到,webapps是空的。这就可以解释到为什么404
    3. 是因为阿里云镜像的原因,默认是最小镜像,所有不必要的都剔除了,保证最小运行环境
    4. 可以通过复制webapps.dist文件夹里所有内容到webapps目录下,恢复tomcat默认页面显示cp -r webapps.dist/* webapps/

Docker可视化面板

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

Rancher
后续会讲,主要用于CI/CD操作

#下载镜像,并启动容器
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# -d 后台运行
# -p 端口映射
# -v 卷映射

然后通过http://ip:8088 便可访问
并且首次访问要设置管理密码
Docker学习笔记-快速上手笔记(保姆级)_第8张图片

选择Local,然后Connect连接上。因为docker在本地,所以用不上远程
Docker学习笔记-快速上手笔记(保姆级)_第9张图片

进到的页面就是这样的
Docker学习笔记-快速上手笔记(保姆级)_第10张图片

Docker镜像讲解

镜像是什么

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

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

如何得到镜像:

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

镜像分层理解

当我们在下载一个镜像时,会发现该镜像存在很多的layer层级
Docker学习笔记-快速上手笔记(保姆级)_第11张图片

而其中Already exists表示该层级已存在,是因为docker镜像会共用层级(sha256相同情况下)。在我们之前下载的镜像当中已经下载过该层级。所以可以直接拿过来用,大大节约空间。

其实docker镜像都是只读的,不可修改,当容器启动时,一个新的可写层被加载到镜像的内部,我们所作的所有操作、配置都在新的可写层。这一层就是我们通常说的容器层,容器层之下的都叫镜像层。

Docker学习笔记-快速上手笔记(保姆级)_第12张图片

我们对容器操作之后可以再次打包层镜像,给他人操作。也就时提交一个镜像commit

commit镜像

docker commit 提交容器成为一个新的镜像
通常用法是:保存当前的容器状态吗,相当于快照,随时可以回滚

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

例子:打包一个自己修改过的镜像

# 前台方式启动一个centos容器
[root@localhost ~]# docker run -it --name centos01 centos /bin/bash

# 原先容器的目录
[root@cee7a3b261a1 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 创建一个新的目录 xzlyf
[root@cee7a3b261a1 /]# mkdir xzlyf

# 验证
[root@cee7a3b261a1 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  xzlyf

# 查看当前正在运行的容器
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
cee7a3b261a1   centos    "/bin/bash"   2 minutes ago   Up 2 minutes             centos01

# commit提交镜像
# -m 描述信息
# -a 作者
# 容器id
# 新镜像名字:[版本]
[root@localhost ~]# docker commit -m="make private directory" -a="xzlyf" cee7a3b261a1 centos-test:0.1
sha256:2935bf71fe7c24f7f371a3782f8a801be3f6688546ec71f1c961b42647f858a9

# 制作成功,查看镜像
[root@localhost ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
centos-test           0.1       2935bf71fe7c   3 seconds ago   231MB
tomcat                9.0       ae6026892279   2 days ago      680MB
redis                 latest    dd8125f93b94   3 days ago      117MB
nginx                 latest    0e901e68141f   2 weeks ago     142MB
portainer/portainer   latest    12b0b8dced14   4 weeks ago     75.4MB
centos                latest    5d0da3dc9764   8 months ago    231MB

# 然后我们使用刚才提交的镜像运行容器测试下
[root@localhost ~]# docker run -it --name centos02 centos-test:0.1 /bin/bash

# 可以看到目录已存在
[root@3faec46c2918 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  xzlyf

通过查看元素据命令

# 查看自己打包的镜像元数据
docker image inspect centos-test:0.1
# 查看原先centos镜像的元数据
docker iamge inspect centos

可以看到我们自己打包镜像的层级时多了一层的
自己打包的centos层级信息

Docker学习笔记-快速上手笔记(保姆级)_第13张图片

原先版本的centos层级信息

Docker学习笔记-快速上手笔记(保姆级)_第14张图片

容器数据卷

数据都不应该放在容器里,容器删除后数据就会丢失!
卷技术就是:docker容器中产生的数据,同步到本地。
简单理解就是:目录的挂载,将容器内的目录,挂载到Linux上面。

还有一点:容器间数据可以共享的,也就是可以挂载同一个目录

容器数据卷的使用

方法一

指定容器内某个目录映射给宿主机目录

docker run -v 宿主机目录1:容器内目录1 -v 宿主机目录2:容器内目录2
# -v 目录映射
# 注意:一个 -v表示挂载一个目录,多个 -v可以挂载多个目录

例子

# 启动容器,并挂载容器/home目录到宿主机/home/centos-test目录下
[root@localhost ~]# docker run -it -v /home/centos-test:/home centos /bin/bash

# 进入容器/home目录下
[root@c536c8735c69 /]# cd /home/
# 创建一个文件测试下同步
[root@c536c8735c69 home]# vi hello.txt
# 退回宿主机,并进入宿主机/home目录
[root@localhost ~]# cd /home/
# ls查看发现多了centos-test的挂载目录,该目录是挂载会自动创建
[root@localhost home]# ls
centos-test
# 进入挂载目录,发现存在测试文件
[root@localhost home]# cd centos-test/
[root@localhost centos-test]# ls
hello.txt
[root@localhost centos-test]# cat hello.txt 
hello master
[root@localhost centos-test]# 

使用命令docker inspect 查看容器元数据
docker inspect c536c8735c69(容器id)
可以看到挂载信息,如果没有信息表明挂载失败
Docker学习笔记-快速上手笔记(保姆级)_第15张图片

解释:
Type 绑定
Source 宿主机目录
Destination 容器内目录

注意:其实就是容器内的/home目录内存地址指向的宿主机的/home/centos-test目录下,就是一份文件来的,不管容器是否在运行,该文件依旧可以操作。就算容器删除,宿主机的下挂载目录也不会受到影响

方法一实战:mysql+容器数据卷

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
# -d 后台运行
# -v 挂载容器内/etc/mysql/conf.d/目录到宿主机/home/mysql/conf目录
# -v 挂载容器内/var/lib/mysql目录到宿主机/home/mysql/data目录
# -e 环境配置,配置容器的MYSQL_ROOT_PASSWORD变量,这是mysql自定义的变量,是mysql的root初始密码,详情看Docker Hub的mysql文档
# --name 给容器命名

# 在宿主机内查看/home目录以及存在mysql的文件
[root@localhost home]# ls /home/mysql/conf/ /home/mysql/data/
/home/mysql/conf/:

/home/mysql/data/:
auto.cnf    ca.pem           client-key.pem  ibdata1      ib_logfile1  mysql               private_key.pem  server-cert.pem  sys
ca-key.pem  client-cert.pem  ib_buffer_pool  ib_logfile0  ibtmp1       performance_schema  public_key.pem   server-key.pem

通过命令docker inspect mysql01查看容器元数据
可以看到已近挂载了两个目录
Docker学习笔记-快速上手笔记(保姆级)_第16张图片

方法二:具名和匿名挂载

不指定宿主机目录,只指定容器的目录路径,以名字进行辨认。Docker默认会将所有容器的卷统一放在宿主机的一个目录下,以名字进行区分。该目录在宿主机的位置:/var/lib/docker/volumes/xxx/_data

注意:通过映射宿主机路径挂载的方式(方法一),数据卷并不会在该目录存在,只会在指定路径的目录下存在。

匿名挂载

# 匿名挂载,就是在-v时只写容器内部地址,没有写外部路径
# -v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

#使用docker volume 查看docker卷情况
[root@localhost home]# docker volume ls
DRIVER    VOLUME NAME
local     70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd
# 通过docker卷查看情况时,发现一个卷名是随机码
# 通过卷名随机码,获取在宿主机挂载的真实路径
# 命令:docker volume inspect 卷名
[root@localhost home]# docker volume inspect 70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd
[
    {
        "CreatedAt": "2022-06-13T09:02:16-04:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd/_data",
        "Name": "70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd",
        "Options": null,
        "Scope": "local"
    }
]
# 查看卷信息,可以发现该卷在宿主机挂载的真实地址

具名挂载(一般都使用这个)
指定挂载名字,解决随机码难以辨认

# 具名挂载
# 名字:容器内部路径 (注意:名字前没有/斜杆,有斜杠是映射宿主机地址)
docker run -d --name nginx01 -v nginx01-data:/etc/nginx nginx
# 通过docker volume查看卷
[root@localhost home]# docker volume ls
DRIVER    VOLUME NAME
local     nginx01-data
# 发现容器卷名字是自己定义的
# 查看卷真实地址
[root@localhost home]# docker volume inspect nginx01-data
[
    {
        "CreatedAt": "2022-06-13T09:13:04-04:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/nginx01-data/_data",
        "Name": "nginx01-data",
        "Options": null,
        "Scope": "local"
    }
]

知识拓展

给目录加权限用法

  • 不指定(默认)
    • 文件:
      • 宿主机 修改该文件后容器里面看不到变化
      • 容器 里面修改该文件,宿主机也看不到变化
    • 文件夹:不管是宿主机还是容器内 修改、新增、删除文件 都会相互同步
  • ro
    • 文件:容器内不能修改,会提示read-only
    • 文件夹:容器内不能修改、新增、删除文件夹中的文件,会提示read-only
  • rw
    • 文件:不管是宿主机还是容器内修改,都会相互同步;但容器内不允许删除,会提示Device or resource busy;宿主机删除文件,容器内的不会被同步
    • 文件夹:不管是宿主机还是容器内修改、新增、删除文件,都会相互同步

用法

docker run -d -P -v centos-data:/etc/nginx:ro ngxin
docker run -d -P -v centos-data:/etc/nginx:rw ngxin

配合DockerFile使用

Dockerfile初体验

Dockerfile就是用来构建docker镜像的构建文件,也就是命令脚本
通过这个脚本可以生成镜像,镜像是一层层的,每个命令都是一层

dockerfile文件:

# 建一个dockerfile文件,名字可以随机,但是推荐dockerfile
# 文件中的命令都必须是大写

# 以centos作为基础
FROM centos

# 载两个目录,两个都是匿名挂载方式,随机码文件夹名
# 挂载容器/volume01目录到宿主机/var/lib/docker/volumes/xxx/_data
# 挂载容器/volume02目录到宿主机/var/lib/docker/volumes/xxx/_data
VOLUME ["volume01","volume02"]

# 打印输出
CMD echo "----end----"

#进入方式是以控制台
CMD /bin/bash

开始构建

# docker build 构建命令
# -f 以dockerfile构建脚本进行构建(刚才创建的脚本)
# -t 镜像信息 镜像名:版本(注意镜像名前面不要加斜杠,中间可加)
# .  在当前目录下生成
[root@localhost centos-test]# docker build -f dockerfile -t xzlyf/centos:0.1 .
# 可以看到构建是以4步走的
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in f957993b695c
Removing intermediate container f957993b695c
 ---> 234224acf0e4
Step 3/4 : CMD echo "----end----"
 ---> Running in cd61faad4888
Removing intermediate container cd61faad4888
 ---> ec7fa7de0651
Step 4/4 : CMD /bin/bash
 ---> Running in 09eebb326e22
Removing intermediate container 09eebb326e22
 ---> 55f93c8af084
Successfully built 55f93c8af084
Successfully tagged xzlyf/centos:0.1
# 查看本地镜像
[root@localhost centos-test]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
xzlyf/centos          0.1       55f93c8af084   32 seconds ago   231MB

使用镜像

# 用刚才制作的镜像启动容器
[root@localhost centos-test]# docker run -it --name centos-xz 55f93c8af084 /bin/bash
# 容器内发现已近挂载上volume1、2的数据卷
# 我们在启动时并没有 -v 手动挂载数据卷
# 是应为我们在构建镜像时加载VALUME[]命令,设置了容器启动时自动挂载数据卷
[root@e19931d115a8 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var	   volume02
dev  home  lib64  media       opt  root  sbin  sys  usr  volume01

#我们退回宿主机,查看数据卷信息,发现是多了两个卷,并且是匿名创建的
[root@localhost centos-test]# docker volume ls
DRIVER    VOLUME NAME
local     3d1218071c2a9040367c60b5229f4170a371806ec6673facc47cb220efa8b6e0
local     e739f67e82c10654fee986565f3616f01ca1204ac93361e1427eb814fbc994f7

数据卷容器

两个或多个容器之间实现数据共享

# 命令: --volumes-from 父容器
# 示例: 
# 启动父容器,并挂载容器的/var/lib/mysql目录(匿名挂载方式)
docker run -d -P -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:7.5
# 启动子容器,不需要指定挂载目录,因为使用了--volumes-from 指定了父容器,它们的挂载目录是一致的
docker run -d -P -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:7.5

# 这时候就可以实现两个容器数据同步
# 启动父容器可以被多个子容器挂载
# 谁挂载谁,被挂载的那个就是父容器。子容器可以被挂载,相对于挂载那个容器,它就是父容器。

结论:不管父容器是否删除还是停止,子容器的同步过的文件是不会丢失的。他们是一种拷贝机制,不是文件的路径的指向。数据卷容器的生命周期一直持续到没有容器使用为止,类似病毒式传播。

数据卷volume命令

关于docker volume的常用命令

查看本地数据卷

[root@localhost home]# docker volume ls
DRIVER    VOLUME NAME
local     8c0f70022be0acea15671685df3c5c37f850f46db27ebc1441b3ae850a943263
local     70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd
local     a52de3ed1daad2b733772f

查看卷详细信息(元数据)

#命令:docker volume inspect 卷名字
[root@localhost home]# docker volume inspect nginx01-data
[
    {
        "CreatedAt": "2022-06-13T09:13:04-04:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/nginx01-data/_data",
        "Name": "nginx01-data",
        "Options": null,
        "Scope": "local"
    }
]

删除一个卷

docker volume rm 卷名字

删除容器时同时删除卷

默认删除容器卷并不会删除,会一直存在

docker rm -v 容器id

删除所有卷

删除不了容器正在使用的卷,其他无用卷全被删除

docker volume prune

DockerFile

介绍

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

构建步骤:

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

热知识

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

DockerFile命令

FROM		#基础镜像,一切从这里开始,centos ubuntu scratch
MAINTAINER	#镜像是谁写的,姓名 邮箱
RUN			#镜像构建的时候需要运行的命令,不如构建时要安装vim等命令或rm删除一些文件
ADD			#添加内容,比如tomcat、redis、mysql
WORKDIR		#镜像工作目录,就是指初次进入时的目录,比如mysql初始进入就在/etc/mysql目录下
VOLUMES		#挂载的目录,自动挂载到宿主机的目录,不用启动容器时 -v 手动挂载,但是只能匿名挂载
EXPOSE		#暴露端口,启动容器时-p进行端口映射。比如暴露3306端口,容器启动时-p 3300:3306就可映射
CMD			#CMD在Dockerfile中只能出现一次,有多个,只有最后一个会有效。其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令。没提供就会使用构建时的命令。
ENTRYPOINT	#这个命令和CMD命令一样,唯一的区别是不能被docker run命令的执行命令覆盖,如果要覆盖需要带上选项--entrypoint,如果有多个选项,只有最后一个会生效。
ENV			#设置容器的环境变量,可以让其后面的RUN命令使用,容器运行的时候这个变量也会保留。
COPY		#与ADD的区别,COPY的只能是本地文件,其他用法一致
ONBUILD		#这个命令只对当前镜像的子镜像生效。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

Centos镜像解析

Docker学习笔记-快速上手笔记(保姆级)_第17张图片

#Docker Hub 中99%的镜像都是从这个基础镜像开始的,然后配置需要的软件来进行构建
FROM scratch
# 添加了一个centos 7的压缩包,这个就是centos7超级精简版镜像,少了很多命令
ADD centos-7-x86_64-docker.tar.xz

创建自己的镜像

# 创建一个文件夹,存放镜像需要用到的所有资源
[root@localhost home]# mkdir DockerImage-xz
[root@localhost home]# cd DockerImage-xz/
# 创建dockerfile构建文件脚本
[root@localhost home]# vi dockerfile

脚本文件

# 从centos7镜像开始(注意centos8是在21年12月31日停止了源的服务,会出现无法yum下载)
FROM centos:7
# 作者信息 名字<邮箱> 这种格式
MAINTAINER xzlyf
# 配置环境变量,变量名MYPATH
ENV MYPATH /usr/local
# 默认工作目录,通过$取变量值
WORKDIR $MYPATH
# 构建时候安装vim和net-tools程序,原先centos精简过是不带这两个命令的
RUN yum -y install vim
RUN yum -y install net-tools
# 暴露80端口
EXPOSE 80
# 以命令行方式进入
CMD /bin/bash

构建镜像

# 构建命令:docker build
# -f 指定构建文件路径
# -t 镜像名字:版本标签
# . 在当前目录构建
docker build -f dockerfile -t centos-xz:0.1 .

...

Successfully built dd764fbcf302
Successfully tagged centos-xz:0.1
#出现Successfully表示构建成功

#运行测试镜像,这里要指定版本号,不然docker回去找最新版laster的
docker run -it centos-xz:0.1
#进入容器后发现,vim和ifconfig命令已经成功装上了

CMD和ENTRYPOINT区别

CMD			#CMD在Dockerfile中只能出现一次,有多个,只有最后一个会有效。其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令。没提供就会使用构建时的命令。
ENTRYPOINT	#这个命令和CMD命令一样,唯一的区别是不能被docker run命令的执行命令覆盖,如果要覆盖需要带上选项--entrypoint,如果有多个选项,只有最后一个会生效。

CMD

# dockerfile文件
FROM centos:7
CMD ["ls","-a"]

#运行生成的镜像,ccos为镜像名
dockert run ccos
.
..
.dockerenv
bin
dev
etc
home
lib
lib64

#可以看到启动容器时,会自动执行ls -a 命令

#加入命令启动
docker run ccos -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": unknow.
# 可以看到启动报错了,说找不到 -l 命令
# 确实,Centos没有-l
# CMD是否覆盖原有的”ls -a"命令,直接替换成“-l"命令
# 如果想追加变成”ls -al“命令,只能完整写出来,直接覆盖,这样是没问题的
# 例如: docker run ccos ls -al
# 如果想追加,只能使用ENTRYPOINT命令

ENTRYPOINT

# dockerfile文件
FROM centos:7
ENTRYPOINT ["ls","-a"]

#运行生成的镜像,ccos为镜像名
dockert run ccos
.
..
.dockerenv
bin
dev
etc
home
lib
lib64

#可以看到启动容器时,会自动执行ls -a 命令

#加入命令启动
docker run ccos -l
#此时发现命令是以 ls -a -l执行,可以追加命令

制作Tomcat镜像实战

  1. 准备需要用到的资源文件,tomcat依赖jdk,所以也要用上JDK。
    Docker学习笔记-快速上手笔记(保姆级)_第18张图片

  2. 编写Dockerfile文件,推荐使用官方命名Dockerfile,这样可以不用加-f指定了

    # 以centos7作为第一层
    FROM centos:7
    # 作者信息
    MAINTAINER xzlyf
    # 复制readme.md到容器内部目录
    COPY readme.md /usr/local/readme.md
    # 添加JDK包、Tomcat包,ADD命令会在构建镜像时自动解压,解压到目标路径/usr/local
    ADD jdk-8u333-linux0x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.64.tar.gz /usr/local/
    # 安装vim命令
    RUN yum -y install vim
    # 环境变量,默认工作目录
    ENV MYPATH /usr/local
    # 设定默认工作目录,用$调用环境变量
    WORKDIR $MYPATH
    # 配置JDK环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_333
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    # 配置tomcat环境变量
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.64
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.64
    # 配置path,这样启动命令不用进bin目录下了
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    # 暴露端口
    EXPOSE 8080
    # 容器启动时,自动启动tomcat,并监听tomcat日志,使用&& 可以拼接无数个命令
    CMD /usr/local/apache-tomcat-9.0.64/bin/startup.sh && tail -F /usr/localapache-tomcat-9.0.64/bin/logs/catalina.out
    
  3. 开始构建镜像

    # 因为使用了Dockerfile作为文件名,所以可以不用-f指定构建脚本,docker会在当前目录搜索Dockerfile文件
    docker build -t tomcatdiy .
    
  4. 测试镜像

    # 启动刚才生成的镜像,并映射端口
    # -v 挂载webapps目录到宿主机的目录下,以后部署项目只需要在宿主机目录下修改即可
    # -v 同时挂载tomcat的日志目录到宿主机下,方便查看
    [root@localhost DockerImage-tomcat]# docker run -d -p 9090:8080 \
     -v /home/DockerImage-tomcat/test:/usr/local/apache-tomcat-9.0.64/webapps/ROOT \
     -v /home/DockerImage-tomcat/tomcat-logs:/usr/local/apache-tomcat-9.0.64/logs \
     tomcatdiy
     
     # 进入容器看看
     [root@localhost DockerImage-tomcat]# docker exec -it 6b6618cbea00 /bin/bash
    [root@6b6618cbea00 local]# pwd
    /usr/local
    # 可以看到默认工作路径是我们自己指定的
    
    # 回到宿主机,进入/home/DockerImage-tomcat/test目录
    # 这里可以直接发布项目
    [root@localhost test]# ls
    index.html
    [root@localhost test]# cat index.html 
    
    
    
        
        
        
        Document
    
    
       

    hhhhhhh

    # 宿主机ip:9090/test 便可进入访问该项目

发布镜像

发布到DockerHub

hub.docker.com

登录命令login

[root@localhost home]# docker login --help
Usage:  docker login [OPTIONS] [SERVER]
Options:
  -p, --password string   密码
      --password-stdin    Take the password from stdin
  -u, --username string   用户名,邮箱不行
  
#示例
docker login -u aromz
password:*******

Login Succeeded

发布命令push

#命令:docker push 作者/镜像名:版本tag
docker push aromz/centos-xz:0.1

#如果报没有找到镜像文件,用docekr images查看镜像文件是否存在
[root@localhost home]# docker push aromz/centos-xz:0.1
The push refers to repository [docker.io/aromz/centos-xz]
An image does not exist locally with the tag: aromz/centos-xz

#已经制作好的镜像可以使用tag标签重新修改镜像信息
[root@localhost home]# docker tag dd764fbcf302 aromz/centos-xz:0.1
[root@localhost home]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED        SIZE
aromz/centos-xz       0.1       dd764fbcf302   2 days ago     601MB
centos-xz             0.1       dd764fbcf302   2 days ago     601MB
#然后就可以发现多了个镜像文件,原先的镜像也还在
#然后再次push就可以了
[root@localhost home]# docker push aromz/centos-xz:0.1
The push refers to repository [docker.io/aromz/centos-xz]
bc9a0af675d3: Pushed 
e8b9580b2039: Pushed 
174f56854903: Mounted from library/centos 
0.1: digest: sha256:d83ba3f879ad9f21714a13b478b7130e78cf2d628242bfb4a1d9054f15483357 size: 953

发布到阿里云镜像服务

Docker学习笔记-快速上手笔记(保姆级)_第19张图片

命名空间

​ 个人版只能拥有3个,可以把命名空间看作一个大项目,一个命名空间包含多个镜像,命名空间之间相互隔离。

镜像仓库

​ 个人版有300个镜像,每个镜像需要指定一个命名空间,通过命名空间隔离。每个镜像可以上传多个版本。

官方使用方式

Docker学习笔记-快速上手笔记(保姆级)_第20张图片

使用过程(推送镜像)

  1. docker 登录 阿里云容器镜像服务
    $ docker login --username=czr****@outlook.com registry.cn-guangzhou.aliyuncs.com
  2. 修改镜像名称和tag版本信息
    $ docker tag [ImageId] registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot:[镜像版本号]
  3. 推送修改信息后的镜像
    $ docker push registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot:[镜像版本号]

使用例子

# 先docker logout退出登录
[root@localhost home]# docker logout
Removing login credentials for https://index.docker.io/v1/
# 登录阿里云镜像中心
[root@localhost home]# docker login [email protected] registry.cn-guangzhou.aliyuncs.com
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 给镜像修改信息,修改成官方要求,可以看到修改后镜像id没有变,值修改了名字和版本
[root@localhost home]# docker tag dd764fbcf302 registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot:0.1
[root@localhost home]# docker images
REPOSITORY                         TAG       IMAGE ID       CREATED        SIZE
centos-xz                           0.1       dd764fbcf302   2 days ago     601MB
registry.xxxxxom/xzlyf/test_depot   0.1       dd764fbcf302   2 days ago     601MB

# 推送修改信息后的镜像
[root@localhost home]# docker push registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot:0.1
The push refers to repository [registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot]
bc9a0af675d3: Pushed 
e8b9580b2039: Pushed 
174f56854903: Pushed 
0.1: digest: sha256:d83ba3f879ad9f21714a13b478b7130e78cf2d628242bfb4a1d9054f15483357 size: 953

可以看到已经上传成功了

Docker学习笔记-快速上手笔记(保姆级)_第21张图片

Docker 小结

Docker学习笔记-快速上手笔记(保姆级)_第22张图片

push:
把镜像推送到容器中心(DockerHub、阿里容器镜像)

pull:
从容器中心拉取镜像下载

run:
运行一个镜像,运行后的环境称为容器

stop:
start:
restart:
控制容器的生命,启动运行和重启

commit:
把当前容器的状态保持,相当于一个快照。提交后会生成一个镜像。

tag:
镜像重新修改名称和tag版本信息,一般镜像是以“作者/镜像名:[版本tag]"命名

build:
制作一个镜像,通过dockerfile脚本文件生成

save:
打包镜像成tar压缩包,用于开发者直线相互共享或备份

# 用法:$ save -o 路径 镜像id

load:
加载打包后的tar压缩包镜像

# 用法:$ load -i 路径

所有命令

Docker学习笔记-快速上手笔记(保姆级)_第23张图片

Docker网络

Docker0

在纯净的docker环境中(没有启动任何容器),宿主机一般只有这三个网卡。

Docker学习笔记-快速上手笔记(保姆级)_第24张图片

网卡:

lo:本地回环地址
ens33:本地内网地址
docker0:docker0地址

当我们启动一个容器后(没有–net指定网络),docker会默认分配docker0的网络给容器(上图:172.17.0.0/16网段)

# 启动一个容器
[root@localhost home]# docker run -it centos-net /bin/bash
# 执行容器内 ip addr命令
[root@localhost home]# docker exec -it 17bcb991db3f ip addr
1: lo:  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
6: eth0@if7:  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
# 通过 ip addr 命令可以看到,
# 1:lo			容器回环地址
# 6:eth0@if7	docker0网络,符合172.17.0.0/16的网络,宿主机与容器通信是通过该ip

宿主机ping容器,可通

[root@localhost home]# 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.053 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.090 ms

容器ping宿主机,可通

[root@localhost home]# docker exec -it 17bcb991db3f ping 192.168.7.125
PING 192.168.7.125 (192.168.7.125) 56(84) bytes of data.
64 bytes from 192.168.7.125: icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from 192.168.7.125: icmp_seq=2 ttl=64 time=0.100 ms

回到宿主机ip addr,可以发现多了个网卡,这个网卡就是连接容器的介质
Docker学习笔记-快速上手笔记(保姆级)_第25张图片

同理,我们再启动一个容器,让容器相互ping,也是额可以通的。

[root@localhost home]# docker run -it centos-net /bin/bash
[root@44db2975dc87 /]# 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.084 ms

但是,它们是怎么工作的呢?详情看下面

通信原理

我们每启动一个docker容器,docker就会给容器分配一个ip。如果没有指定docker网络,docekr就会给容器分配docker0的网络。

而docker0是以桥接模式工作的,这里涉及到一个evth-pair技术

在宿主机ip addr可以看到,容器的网络名是 7:vethc7c394f@if6

Docker学习笔记-快速上手笔记(保姆级)_第26张图片

然后我们进入容器内部查看ipaddr,网络名是6:eth0@if7
Docker学习笔记-快速上手笔记(保姆级)_第27张图片

可以看到它们是成对出现的,这就是evth-pair技术,它们就是一对的虚拟设备接口。
evth-pair充当一个桥梁,连接各种虚拟网络设备。

Docker学习笔记-快速上手笔记(保姆级)_第28张图片

容器之间相互ping,容器会在docker0中找路由表,通过ip找到下一条的虚拟接口地址。虚拟接口之间有着它们的通信协议,从而完成通信。

注意:在删除容器时,docker会自动删除对应的网络接口和路由表,用户无需操作。
注意2:容器启动时,没有指定网络(–net)的情况下, 都会使用docker0网络随机分配一个可用ip。

–link容器互联

一般比较少用,用自定义网络可实现

在容器启动时,使用命令–link连接到另一个容器的网络

# 命令
# --link	容器名或容器id
[root@localhost home]# docker run -it --name centos03 --link centos02 fb46382c1acf
# 通过--link连接后可以直接通过centos02 ping通
[root@1c8dbf8b0f9d /]# ping centos02
PING centos02 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.125 ms
64 bytes from centos02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.093 ms

centos03可以直接通过容器名centos02 ping通。
但是,centos02 无法使用centos03 ping通。

其实,–link的原理很简单。就是通过修改hosts来实现容器访问
Docker学习笔记-快速上手笔记(保姆级)_第29张图片

centos03容器在启动时,修改了hosts,但是centos02并没有修改,所有centos02无法通过服务名来访问centos03。

还有一点,通过 docker inspect centos03可以看到,这里多了个Links
Docker学习笔记-快速上手笔记(保姆级)_第30张图片

综上所述,这种连接方式一般很少用。一般通过自定义网络来实现,就是不再使用docker0

自定义网络

查看所有docker网络

[root@localhost home]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e7cf25ea27a2   bridge    bridge    local
61b7289abf4d   host      host      local
8cd18ec10e2e   none      null      local

docker网络模式

bridge 桥接
none 不配置网络
host 和宿主机共享网络
container 容器网络连通(用得少)

创建网络

创建docker网络
命令:docker network create

# 命令
# --diver		网络模式	bridge
# --subnet		子网网段	192.168.1.0/24
# --gateway		网关		 192.168.1.1
# mynet			docker网络名字
[root@localhost home]# docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.1 mynet
3b205223b27709a6d102cd82ecdad281a7b394ba7ba074cbbafcc3fd2e3a56d7
# 通过查看网络可以看到已经创建成功
[root@localhost home]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
274d1929871b   bridge    bridge    local
61b7289abf4d   host      host      local
3b205223b277   mynet     bridge    local

注意:不要创建和自己物理网卡相同的网段。
比如物理网卡的内网地址是192.168.0.1/24,自定义网络的网段就不能使用这个了

查看网络信息

查看docker网络
命令:docker network inspect 网络id或网络名

[root@localhost home]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "3b205223b27709a6d102cd82ecdad281a7b394ba7ba074cbbafcc3fd2e3a56d7",
        "Created": "2022-06-18T08:06:49.861071541-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/24",
                    "Gateway": "192.168.1.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

使用网络

使用刚才创建的docker网络

[root@localhost home]# docker run -it --name centos01 --net mynet centos-net
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@1da090c5e3f7 /]# ip addr
1: lo:  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
8: eth0@if9:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever

自定义网络无需任何配置,可以直接通过容器名互ping通
而默认docker0是不支持的

这不是通过hosts实现,而是路由器(即自定义网络)实现的

Docker学习笔记-快速上手笔记(保姆级)_第31张图片

指定IP启动

注意docker0不支持指定ip启动

# 命令
# --net		指定网络
# --ip		指定ip,要求符合指定网络的网段
[root@localhost home]# docker run -it --name centos01 --net mynet --ip 192.168.1.125 centos-net
[root@aec043fce68f /]# ip addr
1: lo:  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
25: eth0@if26:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:01:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.125/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever

跨网段通信

命令:docker network connect 网络名或网络id 容器名或容器id
这个命令对应单个容器跨网段通信的!

比如使用docker0网络的一个容器,需要和mynet网段的容器通信。
Docker学习笔记-快速上手笔记(保姆级)_第32张图片

使用命令docker connect mynet 容器2
这个时候容器2便可以和mynet的任意一容器通信了。但是这条命令只是对于容器2生效,容器1并不可以与mynet网络通信。

而这个命令的原理很简单,就是把容器2加入mynet网络,我们通过命令docker network inspect mynet可以发现,容器2在网络中分配到一个可用ip。而此时容器2拥有两个网络,一个是docker0的,另一个是mynet的。

Docker学习笔记-快速上手笔记(保姆级)_第33张图片

常见用法:

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

Docker学习笔记-快速上手笔记(保姆级)_第34张图片

Docker实战:Springboot打包docker镜像

springboot项目

一个普通的springboot项目,写个测试接口
Docker学习笔记-快速上手笔记(保姆级)_第35张图片

打包应用

maven-项目-package
Docker学习笔记-快速上手笔记(保姆级)_第36张图片

在target目录得到xxx.jar包,如果打包jar包查看以前的笔记…
Docker学习笔记-快速上手笔记(保姆级)_第37张图片

编写dockerfile

# 项目用java8构建的,所有制作dock镜像可以直接用java8的镜像
FROM java:8

# 把当前目录下的所有jar包都拷贝到镜像里,并命名为app.jar,位置在/目录下
COPY *.jar /app.jar

# 修改springboot项目启动端口,后续启动容器时可以用此命令指定其他端口
CMD ["--server.port=8080"]

# 暴露8080端口,让宿主机自行觉得映射端口
EXPOSE 8080

# 启动容器是同时启动jar包(即项目)
ENTRYPOINT ["java","-jar","/app.jar"]

总共两个文件:项目jar包、Dockerfile文件
在这里插入图片描述

打包后,在开发本地使用命令java -jar docker-0.0.1-SNAPSHOT.jar 测试是否能正常运行业务

构建镜像

把上面两个文件(jar包、Dockerfile)文件上传到centos(docker环境)下打包成镜像
在这里插入图片描述

# docker build 构建命令
# -t 镜像信息:[TAG0.1]
# -f 没有指定是因为名字符合官方要求,docker将自动搜索到构建脚本Dockerfile
# . 当前目录(必备)
[root@localhost springboot]# docker build -t hello:0.1 .
Sending build context to Docker daemon  17.61MB
Step 1/5 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> e386fbf252eb
Step 3/5 : CMD ["--server.port=8080"]
 ---> Running in 0a21491b3b93
Removing intermediate container 0a21491b3b93
 ---> dc8823778613
Step 4/5 : EXPOSE 8080
 ---> Running in e1c6b8ea92ab
Removing intermediate container e1c6b8ea92ab
 ---> 52b3890a484e
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
 ---> Running in 598cfa442b38
Removing intermediate container 598cfa442b38
 ---> 17966c49a5d6
Successfully built 17966c49a5d6
Successfully tagged hello:0.1

# 构建成功,查看镜像
[root@localhost springboot]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
hello        0.1       17966c49a5d6   About a minute ago   661MB

发布运行

# 启动镜像测试
[root@localhost springboot]# docker run -d -p 8080:8080 --name hello01 hello:0.1
# 请求测试接口
[root@localhost springboot]# curl localhost:8080/hello
# 数据返回正常
{"msg":"success","code":1,"data":1655560180074}

此时docker 镜像已经制作完毕,并测试正常。

通过该镜像可以进项项目交付、上传到DockerHub和阿里云镜像服务中心等工作

未完待续!!!

编写dockerfile

# 项目用java8构建的,所有制作dock镜像可以直接用java8的镜像
FROM java:8

# 把当前目录下的所有jar包都拷贝到镜像里,并命名为app.jar,位置在/目录下
COPY *.jar /app.jar

# 修改springboot项目启动端口,后续启动容器时可以用此命令指定其他端口
CMD ["--server.port=8080"]

# 暴露8080端口,让宿主机自行觉得映射端口
EXPOSE 8080

# 启动容器是同时启动jar包(即项目)
ENTRYPOINT ["java","-jar","/app.jar"]

总共两个文件:项目jar包、Dockerfile文件
在这里插入图片描述

打包后,在开发本地使用命令java -jar docker-0.0.1-SNAPSHOT.jar 测试是否能正常运行业务

构建镜像

把上面两个文件(jar包、Dockerfile)文件上传到centos(docker环境)下打包成镜像
在这里插入图片描述

# docker build 构建命令
# -t 镜像信息:[TAG0.1]
# -f 没有指定是因为名字符合官方要求,docker将自动搜索到构建脚本Dockerfile
# . 当前目录(必备)
[root@localhost springboot]# docker build -t hello:0.1 .
Sending build context to Docker daemon  17.61MB
Step 1/5 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
 ---> e386fbf252eb
Step 3/5 : CMD ["--server.port=8080"]
 ---> Running in 0a21491b3b93
Removing intermediate container 0a21491b3b93
 ---> dc8823778613
Step 4/5 : EXPOSE 8080
 ---> Running in e1c6b8ea92ab
Removing intermediate container e1c6b8ea92ab
 ---> 52b3890a484e
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
 ---> Running in 598cfa442b38
Removing intermediate container 598cfa442b38
 ---> 17966c49a5d6
Successfully built 17966c49a5d6
Successfully tagged hello:0.1

# 构建成功,查看镜像
[root@localhost springboot]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
hello        0.1       17966c49a5d6   About a minute ago   661MB

发布运行

# 启动镜像测试
[root@localhost springboot]# docker run -d -p 8080:8080 --name hello01 hello:0.1
# 请求测试接口
[root@localhost springboot]# curl localhost:8080/hello
# 数据返回正常
{"msg":"success","code":1,"data":1655560180074}

此时docker 镜像已经制作完毕,并测试正常。

通过该镜像可以进项项目交付、上传到DockerHub和阿里云镜像服务中心等工作

未完待续!!!

你可能感兴趣的:(实用教程,docker,容器,linux,java)