【Docker】学习笔记(一)三剑客之 docker engine仓库、镜像与容器的基本操作

docker engine安装

ubuntu20.04安装docker教程


docker核心架构

镜像(image
  • 一个镜像就代表一个软件服务(ubuntu镜像、mysql镜像、redis镜像、mq镜像)
  • 只读

远程中心仓库(repository
  • 中心仓库用来集中存储、管理所有软件服务(镜像文件) === >>>

    仓库web界面 docker hub

  • 镜像搜索docker search与拉取docker pull下载(拉取后自动存储到本地仓库)

# 除了docker hub搜索,命令行也可搜索
docker search tomcat
# 下载(tomcat:11.0.0 11.0.0为标签,不写默认为latest)

docker pull tomcat:11.0.0

docker pull tomcat:9.0.82-jdk8-corretto
  • docker pull 默认从官方镜像地址下载,很慢,切回国内备份镜像
  • 配置国内镜像源,加速下载
# 打开 Docker 配置文件
# Linux:/etc/docker/daemon.json(如果不存在,可以创建)
# 添加如下内容(登陆阿里云获取自己专属的镜像加速服务)
{
  "registry-mirrors": ["https://bx6t9g3c.mirror.aliyuncs.com"]
}
# 重新启动docker引擎
sudo systemctl daemon-reload
sudo systemctl restart docker
# 检测查看配置是否成功
docker info

# 输出如下(末尾):
 Registry Mirrors:
  https://bx6t9g3c.mirror.aliyuncs.com/
 Live Restore Enabled: false

参考:

自己的阿里云镜像加速器查找

  • 本地仓库:用来存储使用docker过程中的相关镜像(默认位置:/var/lib/docker
  • 创建自己的私有库

容器(container
  • 一个镜像运行一次就会产生一个容器,容器就是一个运行的软件服务,简言之:容器是镜像的实例
  • 可读可写
  • 基于镜像来运行docker run容器
docker run -it thicv:v1.0 bash

# --name 给容器命名 -v 挂载本地卷
docker run -it --name planning -v ./planningFigure:/thicvPilot/planningFigure thicv:v1.0 bash

镜像与容器的基本操作! ⭐️ ⭐️

docker运行第一个程序: hello-world
  • 安装docker时官方提供了一个默认镜像hello-world
  • 查看本地仓库所有镜像:docker images
docker images
# output (镜像名称、版本标签、唯一标识ID、创建时间(官方构建时间)、大小)
REPOSITORY    TAG                    IMAGE ID       CREATED        SIZE
tomcat        9.0.82-jdk8-corretto   bbaf8bb8e2c9   4 days ago     385MB
thicv         v1.0                   9d8d9f806797   5 days ago     2.27GB
hello-world   latest                 9c7a54a9a43c   6 months ago   13.3kB
  • 通过镜像创建并运行容器:docker run
docker run hello-world
# 注:必须要指定具体的镜像及其版本,如hello-world,容器名称是可选项
# 如:
docker run --name Hello hello-world

# output
Hello from Docker!
......
For more examples and ideas, visit:
 https://docs.docker.com/get-started/

注:docker run IMAGE 先会在本地仓库去找IMAGE,如若没找到会去中心仓库尝试下载拉取

  • 基础镜像 rootfs
  • 注意点
docker pull centos:latest
docker run -d --name test01 centos:latest
docker ps

# 后台没有运行的容器
# 原因是:镜像中没有可执行服务
# 可以理解为:系统启动后没有运行的可执行程序,然后自己又关机了

docker run -it --name test02 centos:latest

辅助命令
命令 功能
**docker -v **或者 docker --version 查询docker engine客户端版本
docker version 查看客户端与服务端部分信息
docker info 查看docker engine详细信息
docker --help 查看docker帮助文档
docker [命令] --hlep 获取docker命令帮助文档
docker login/logout 登入/退出docker hub

镜像管理基本操作
命令 功能
docker images 或者docker image ls 或者 docker images -a 查看本地仓库所有镜像
docker images [image] 只查看对应镜像的信息
docker search [image] 在中心仓库检索镜像(只能看是否存在,不能列出版本)
docker pull [image:TAG] 从中心仓库拉取镜像(若不指定版本tag,则默认latest)
docker rmi [image] 或者 docker image rm [image] 删除本地仓库中的镜像[image]可以是name/ID(正常删除,但无法删除已经通过其创建运行容器后的镜像)
docker rmi -f [image] 强制删除镜像(不管容器的死活,但并不会删除通过其实例化的容器)
docker push [image] 上传镜像
docker image inspect [image] 查看镜像的详细信息
docker image prune 删除所有未被使用的镜像层
docker system prune 删除docker engine中所有未被使用的镜像、容器、数据卷、网络等等,包括通过dockerfile创建镜像时的缓存

扩展:

  • docker images [image] -q 仅仅列出与image相关的镜像的ID
# 仅仅列出与tomcat相关的镜像的ID
docker images tomcat -q
# output
fb5657adc892
ef6a7c98d192
  • 组合操作 强制删除与tomcat相关的所有版本的镜像
# 先执行$里的命令,然后将结果作为参数给外层命令
docker rmi -f $(docker images tomcat -q)
  • 检查系统的防火墙状态
systemctl status firewalld.service

容器管理与运行

命令语法:docker 命令 [选项]

(docker 对容器操作可以不写container)

命令 功能
docker ps 或者 docker container ps 只列出正在运行的容器
docker ps -a 或者docker container ps -a 列出所有容器
docker run [image] 创建并且运行容器
docker run --help 查询选项、参数含义
docker rm [container] 删除已经停止的容器(可以是容器名称/ID;可以多个容器一起删除)
docker rm -f [container] 强制删除容器(即使在运行也能)
docker stop [container] 停止运行中的容器
docker start [container] 启动已经停止的容器
docker restart [container] 重启容器
docker pause [container] 暂停容器服务
docker kill [container] 杀死容器(杀死进程,stop会允许容器做正常服务的关闭操作,kill是直接杀掉进程)
docker port [container] 查看容器的映射端口
docker logs [container] 查看容器日志(-t 加入时间辍;-f 跟随最新的日志打印;–trail n 显示最后n行)
docker diff [container] 显示容器内的变化
docker stats 显示容器资源使用情况
docker cp containerID:文件路径 宿主机路径 从容器拷贝文件到宿主机
docker cp 宿主机文件路径 containerID:文件路径 拷贝宿主机本地文件到容器中

扩展:

  • 不论镜像还是容器在操作ID时可指定前几位能够区分即可(如四位)
# 查询所有容器
docker ps -a
# output (容器唯一ID,基于哪个镜像,容器命令,创建时间,当前状态,监听端口,容器名称(若不指定,默认分配独立名称))
CONTAINER ID   IMAGE         COMMAND    CREATED         STATUS                     PORTS     NAMES
5383edeba808   hello-world   "/hello"   8 seconds ago   Exited (0) 7 seconds ago             Hello
# 删除容器Hello
docker rm Hello
docker rm 5383
  • 简单运行一个容器 (这种方式直接运行容器,宿主机无法访问容器内服务,容器是操作系统层面的隔离)
docker run tomcat:8.0
  • 创建并运行tomcat容器,同时通过 -p 选项设置容器与宿主机的端口映射关系
    • 可以同时映射多个端口,如mq服务器 -p 15672:15672 -p 5672:5672
# --name test01 给容器命名test01,容器名称必须是唯一的
# -p 8080(宿主机):8080(docker容器服务内) 端口映射
docker run --name test01 -p 8080:8080 tomcat:8.0
# 然后网页地址栏目 登陆 宿主机ip:8080 即可显示web页面
http://192.168.0.105:8080/
  • 创建并运行tomcat容器,以test02命名该容器,开放端口映射, -d 以守护进程方式后台启动该服务
docker run --name test02 -p 8082:8080 -d tomcat:8.0
# output (返回容器ID)
530004aec6cd8804b93806f4a62d2201d733e0b782cb80d680760d4f52ede8fc
# 登陆web界面  	http://192.168.0.105:8082/

​ 注: 选项的顺序没有要求,但都是在镜像之前

命令 功能
docker attach [container] 以交互模式进入容器(只能是运行中的容器,退出后,容器也停止不运行)
docker exec -it [container] 以交互模式进入容器内部(只能是运行中的容器,退出后容器仍在后台运行)
  • 以交互式方式进入test02容器内部的bash
docker exec -it test02 bash
# bash 进入后打开面板
  • 容器与宿主机进行文件传输(记住:最后面的是目标路径)
# 拷贝宿主机本地文件到容器中
docker cp ./Dockerfile test01:/home

# 拷贝容器中文件到宿主机中
docker cp test01:/home/Dockerfile ./temp
  • 退出容器
# 在容器内部执行
exit
命令 功能
docker top [container] 查看容器内运行的进程
docker inspect [container] 查看容器的所有配置及详细信息

​ 一个进程代表着一个应用程序的实例。

  • 将容器打包成新的镜像
    • 容器可读可写, 对容器进行 自己的深度定制
命令 功能
docker commit [container] [image] 将容器打包成镜像
docker save [image] > FILE 或者 docker save [image] -o FILE 保存本地仓库中的镜像(部署到别的服务器上)
docker load -i FILE 还原恢复备份的镜像
docker commit -m "描述信息" -a "作者信息" 要打包的容器  镜像名称:标签
# 注意镜像名称要小写

# 创建一个容器tomcat01
docker run -d -p 8081:8080 --name tomcat01 tomcat:8.0

# 将自己定制修改的容器打包提交镜像到本地仓库
# sensiz/tomcat:v2.0 命名及其定义版本标签
docker commit -m "2023.11.10 Modify" -a "sensizlik" tomcat01 sensiz/tomcat:v2.0

docker images
# output
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
sensiz/tomcat   v2.0      3431a13ed69e   2 minutes ago   356MB

# 查看镜像的详细信息
docker image inspect sensiz/tomcat:v2.0
  • 镜像备份与还原机制

    保存本地镜像并将此镜像导入到别的服务器

# sensiz/tomcat:v2.0 本地镜像
# ./temp/myTomCat.tar 保存为tar包文件
docker save sensiz/tomcat:v2.0 -o ./temp/myTomCat.tar

# 在服务器上导入外部打包保存的镜像
docker load -i ./myTomCat.tar
# 查看是否导入成功
docker images

容器中的数据卷管理 volume
  • 作用(桥梁):实现容器中的数据(文件和目录)与宿主机中的数据映射(简言之:实现数据同步)

  • docker cp 命令过于繁琐频繁

  • 注意:数据卷使用必须在容器首次运行时设置

  • 数据卷可以设置多个

  • 使用绝对路径/相对路径设置数据卷

    这种方式会将容器路径的原始内容全部清空,始终以宿主机路径为主

docker run -v 宿主机绝对路径:容器路径 ...
# -d 以守护进程方式后台运行容器
# -p 端口映射
# -v /home/sensizlik/Docker:/home/docker 本地目录:容器目录	docker目录如果没有可以自动创建
docker run -d -p 8080:8080 -v /home/sensizlik/Docker:/home/docker --name tomcat01 tomcat:8.0

# 也可以将设置成 ro (readonly),代表容器中的文件是只读,且只能修饰容器
docker run -d -p 8080:8080 -v /home/sensizlik/Docker/webapps:/usr/local/tomcat/webapps:ro --name tomcat02 tomcat:8.0

# -it 以交互式方式创建,挂载相对路径且容器路径只读
docker run -it --name tomcat01 -p 8080:8080 -v ./webapps:/usr/local/tomcat/webapps:ro tomcat:8.0 bash
  • 使用别名方式设置数据卷

    • lemon 代表docker数据卷中的别名(如若别名存在,docker直接使用,不存在创建)
  • 使用别名方式会保留容器路径原始内容,前提是别名对应路径不能存在内容

    • 根据别名创建的数据卷默认在 /var/lib/docker/volumes/
    • 别名代表一个docker自身维护的数据卷
docker run -v lemon:/usr/local/tomcat/webapps:ro ...
docker run -d -p 8080:8080 --name tomcat01 -v lemon:/usr/local/tomcat/webapps tomcat:8.0 
# 在宿主机查找以下lemon
find / -name lemon
# output
/var/lib/docker/volumes/lemon

# 切回root用户,即可查看
sudo su
cd /var/lib/docker/volumes/lemon
ls
# output
_data

cd _data
ls
# output
docs  examples  host-manager  manager  ROOT

数据卷操作进阶
命令 功能
docker volume create [volume] 创建一个数据卷
docker volume ls 查看docker维护的本地所有数据卷
docker volume inspect [volume] 查看数据卷详细信息
docker volume rm [volume] 删除数据卷
docker volume prune 删除所有未使用的卷
镜像构成原理
  • 容器是独立的操作系统(精简linux操作系统+软件服务),是镜像运行的实例

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

  • 联合文件系统 unionFS

    • 基础镜像(操作系统核心库+运行环境)
    • 一层一层构建
    • 一次加载多个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录,在外面看起来,只能看到一个文件系统
    • 如:有多个镜像都是从相同的base镜像构建而来的,那么宿主机只需在磁盘中保存一份base镜像,同时内存中也只需加载一份镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称为容器层,容器层之下都叫做镜像层。

高级网络配置(容器间通信之网络使用) ⭐️ ⭐️

容器间通信

说明:容器之间通过网络进行相互通信

  • 当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
ifconfig
# output
...
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:3c:67:00:55  txqueuelen 0  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
...
  • 同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 协议中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1,掩码为 255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。

  • 当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

【Docker】学习笔记(一)三剑客之 docker engine仓库、镜像与容器的基本操作_第1张图片
docker pull tomcat:8.0

docker run --name tomcat01 -p 8081:8080 -d tomcat:8.0
docker run --name tomcat02 -p 8082:8080 -d tomcat:8.0

docker ps
docker inspect tomcat02

docker exec -it tomcat01 bash
root@52935a4d2eb3:/usr/local/tomcat#

# 注释:tomcat01容器内只是开放了8080
curl http://172.17.0.3:8080

总结:

  1. 默认docker在创建容器时将所有容器都连接到docker0网桥上,默认在docker0网桥的容器都可以使用容器内ip地址进行通信;
    • 但是容器重启时,ip 是动态分配的
  2. 也可以使用容器的名称作为容器的ip地址进行通信;
    • 注意:使用容器名称必须自定义网桥不能使用默认docker0
    • 为了解决一个默认网桥出现瓶颈、拥堵;为自己的项目搭桥
docker 网络管理基本操作
命令 功能
docker network ls 列出可用网络
docker network inspect [network] 查看网络详细信息
docker create [network] 创建一个新的网络
docker network connect [network] [container] 将容器连接到网络
docker network disconnect [network] [container] 将容器从网络断开
docker network rm [network] 删除网络
docker network prune 删除所有未用到的网络

自定义网桥实现网桥容器间通信
  • docker 中的网桥类型:bridgehostnone
docker network ls

# output
NETWORK ID     NAME                    DRIVER    SCOPE
731fabe34f98   bridge                  bridge    local
088206ae6f43   host                    host      local
6d1dc3ad4243   none                    null      local
  • 创建网络自定义桥
docker network create ems
# 上面等价于 docker network create -d bridge ems
# 不写,默认网桥类型为bridge
  • 在指定的同一个网络中运行多个容器

    • 启动容器时明确指定网络(前提是指定的网络已经存在);
    # --network ems 指定ems,前提是ems已经存在
    docker run -d --name tomcat01 -p 8081:8080 --network ems tomcat:8.0 
    docker run -d --name tomcat02 -p 8082:8080 --network ems tomcat:8.0
    
    # 查看网络中的容器有哪些(字段:"Containers)
    docker network inspect ems
    
    # 在容器tomcat02中用容器名访问tomcat01
    docker exec -it tomcat02 bash
    
    curl http://tomcat01:8080
    
    • 启动之后将容器加入到某个网络中
    # 创建tomcat03
    docker run -d --name tomcat03 -p 8083:8080 tomcat:8.0
    
    # 将tomcat03加入到ems网络中
    docker network connect ems tomcat03
    
    # 查看ems中有哪些容器
    docker network inspect ems
    

docker 使用实战

运行MySQL服务
  • docker hub
# 下载镜像
docker pull mysql:5.6
  • 创建容器,启动mysql 开放端口映射(3306)、指定root用户密码
# -e 参数,指定环境变量
docker run --name mysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6

# always=--restart docker引擎重启后自动重启容器
# -v 数据卷持续化数据到宿主机
docker run --name mysql02 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --restart=always  -v ./mydata:/var/lib/mysql -d mysql:5.6
  • 进入容器
dcoker exec -it mysql01 bash

mysql -u root -p
# input 123456

你可能感兴趣的:(学习笔记,docker,学习,笔记,c++,python,ubuntu,容器)