资讯详情

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 在这里插入图片描述

    4. 查看本地镜像 docker imags

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

阿里云加速服务

用于加速个人仓库

  1. 阿里云控制台
  2. 容器镜像服务
  3. 没有开通就先开通

4.镜像工具-镜像加速器

运行流程图(run)

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

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容器来测试学习

[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 以命令行交互方式打开

#直接退出并停止容器
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,里面包含了许多信息,其中网络配置比较重要

进入正在运行的容器

#当容器后台启动后,或者按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

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

#查看正在运行的容器
[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目录
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可视化面板

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

后续会讲,主要用于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 便可访问 并且首次访问要设置管理密码

选择Local,然后Connect连接上。因为docker在本地,所以用不上远程

进到的页面就是这样的

Docker镜像讲解

镜像是什么

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

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

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

镜像分层理解

当我们在下载一个镜像时,会发现该镜像存在很多的layer层级

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

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

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层级信息

原先版本的centos层级信息

容器数据卷

卷技术就是: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) 可以看到挂载信息,如果没有信息表明挂载失败

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

方法一实战: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查看容器元数据 可以看到已近挂载了两个目录

方法二:具名和匿名挂载

匿名挂载

# 匿名挂载,就是在-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的<src>只能是本地文件,其他用法一致
ONBUILD		#这个命令只对当前镜像的子镜像生效。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。

Centos镜像解析

#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<czr2001@outlook.com>
# 配置环境变量,变量名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。

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

    # 以centos7作为第一层
    FROM centos:7
    # 作者信息
    MAINTAINER xzlyf<czr2001@outlook.com>
    # 复制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 
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
       <h1>hhhhhhh</h1> 
    </body>
    </html>
    
    # 宿主机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

发布到阿里云镜像服务

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

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

官方使用方式

使用过程(推送镜像)

  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 --username=czr2001@outlook.com 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 小结

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

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

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

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

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

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

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

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

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

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

# 用法:$ load -i 路径

所有命令

Docker网络

Docker0

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

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

# 启动一个容器
[root@localhost home]# docker run -it centos-net /bin/bash
# 执行容器内 ip addr命令
[root@localhost home]# docker exec -it 17bcb991db3f 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
6: eth0@if7: <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
# 通过 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,可以发现多了个网卡,这个网卡就是连接容器的介质

同理,我们再启动一个容器,让容器相互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是以工作的,这里涉及到一个

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

然后我们进入容器内部查看ipaddr,网络名是6:eth0@if7

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

容器之间相互ping,容器会在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来实现容器访问

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

还有一点,通过 docker inspect centos03可以看到,这里多了个Links

综上所述,这种连接方式一般很少用。一般通过自定义网络来实现,就是不再使用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

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

标签: 智能温度变送器ad180fd连接器ca3106e22fce连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台