Docker 学习笔记一

一、什么是docker

Docker 是一个基于轻量级虚拟化技术的容器,整个项目基于Go语言开发;Docker是一个C/S架构,后端众多模块各司其职,docker的daemon是运行在主机上通过client可以进行通信。

docker 由三部分组成:镜像(Image)、容器 (container)、仓库 (repository)。

  • 镜像:是一种轻量级、可执行的软件包,包含了软件的运行环境并打包好的一种运行环境;镜像是一个只读的模板;一个镜像可以生成多个同时运行的容器实例,镜像之间相互隔离,保证安全性。
  • 容器:是一个运行时的环境,容器实例只有通过镜像才能生成,容器之间相互独立。镜像类似Java的类模板,docker容器实例类似 Java 中 new出来的实例对象。
  • 仓库:集中存放镜像文件的地方,分为公开仓库和私有仓库。

docker 和 虚拟机的对比

  • docker 比虚拟机运行速度更快,有着比虚拟机更少的抽象层。
  • docker 利用的是宿主机的内核,不需要加载OS操作系统,所以整体更小巧。

UnionFS(联合文件系统):是一种分层、轻量级并且高性能的文件系统,将对文件操作的修改作为一次提交,多个提交层层叠加;联合文件系统,是docker镜像基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像)的拓展。

在docker镜像的最底层是引导文件系统 bootfs;镜像分层的优点是资源共享,例如多个镜像都是由base镜像拓展得到,那么只需要存一份base镜像即可,无需重复加载,做到镜像的每一层都能被共享。当容器启动时,一个新的可写层被加载到镜像的顶部,这一层被叫做容器层,容器层之下的都叫镜像层。

二、安装配置docker并配置加速地址

  • 安装 docker 步骤

配置docker的安装环境

bash 复制代码
yum -y install gcc
yum -y install gcc-c++ 
yum install -y yum-utils

设置stable仓库

bash 复制代码
# 这里的地址需要换成国内的  外网的用不了
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新yum索引

bash 复制代码
yum makecache fast

安装 docker

bash 复制代码
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

启动 docker 并打印hello-world

bash 复制代码
sudo systemctl start docker    
sudo docker run hello-world  

卸载docker 命令

bash 复制代码
sudo systemctl stop docker    
yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
  • 通过阿里云设置镜像加速地址(仅学习用),在阿里云的容器镜像服务中获得镜像加速地址。

通过以下命令设置镜像加速地址

bash 复制代码
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://4a9cjnr5.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload  
sudo systemctl restart docker

三、docker常用命令

启动类命令

bash 复制代码
------------------docker 服务相关-----------------------
systemctl start docker    #  启动docker 
systemctl stop docker     #  关闭docker 
systemctl restart docker  #  重启docker 
systemctl status docker   #  查看docker状态 
systemctl enable docker   #  开机启动docker 
docker info               #  查看docker 相关信息
docker stats              #  实时统计当前宿主机容器状态

------------------容器 服务相关-------------------------
docker start  container_id/container_name     # 启动容器  
docker restart  container_id/container_name   # 重启容器 
docker stop  container_id/container_name      # 停止容器 
docker kill  container_id/container_name      # 强制停止 
docker rm -f container_id/container_name      # 删除已停止的容器 

常用命令

bash 复制代码
docker images [opt] # 列出本机上所有镜像,一个仓库可以有多个版本不同但同名的镜像
    -a 列出本地所有镜像,包含历史镜像层级
    -q 只显示镜像ID

docker create name  # 创建一个新镜像,和run的区别就是不会运行

docker search name  # 查询某个镜像
	--limit 10      # 指定搜索结果数量

docker pull name[:tag]  # 拉取某个镜像,不加tag参数默认最新

docker ps [opt]   # 列出所有容器
	-a   列出当前运行 + 历史运行过的容器
	-l   显示最近创建的容器
	-n   显示最近n个创建的容器
	-q   静默模式 只显示容器编号

docker events [opt]  # 从服务器获取实时事件
    -f:根据条件过滤事件
    --since:从指定的时间戳后显示所有事件
    --until:流水时间显示到指定的时间为止

docker history [opt] name  
    -H :以可读的格式打印镜像大小和日期,默认为true
    --no-trunc :显示完整的提交记录
    -q :仅列出提交记录ID

docker system df  # 查看镜像 数据卷所占空间

docker rmi name   # 根据名称移除镜像,多个镜像空格分隔
    -f  强制删除

docker logs 'container_id'      # 查看容器日志

docker port 'container_id'      # 查看容器的端口映射

docker tag 'container_id'       # 给容器打标签,相当于clone了一个

docker top  'container_id'      # 查看容器内运行的进程

docker inspect  'container_id'  # 查看容器的配置信息 返回json串格式

docker cp 'container_id': 容器路径 主机路径  # 将容器的文件复制到主机

docker diff 'container_id'      # 列出不同版本提交的文件状态变化(A - Add, D - Delete, C - Change)列表清单。

docker pause 'container_id'     # 暂停容器
docker unpause 'container_id'   # 取消暂停容器

※:支持参数续传(内层查询的结果作为外层命令的参数),可以通过此删除全部镜像

bash 复制代码
docker rmi -f $(docker images -qa)

docker run命令:包含了拉取 + 运行 两个步骤;首先在本地进行查找,如果有直接运行,没有就去docker hub 查找;远程仓库如果没有直接报错,如果有先拉取到本地镜像库,然后再运行。部分软件不支持后台运行模式,最佳的解决方案是将其以前台进程的形式运行。

bash 复制代码
docker run [opt] image [cmd] [arg]
  opt:
	--name  指定容器名字
    --restart
        -: always docker重启以后当前容器也重启
	-d      启动守护式容器(后台运行) 并返回容器id
    -P      随机指定端口
	-p      指定端口  5000:80 将本机的5000端口映射到docker的80端口 
    -i      以交互式运行容器
    -t      为容器重新分配一个伪终端

# 在docker中启动交互式镜像,进入交互式控制台 名称会变成 root + 容器ID
docker  run  -it  ubuntu  /bin/bash

※:退出容器两种方式以及对比

输入 exit 退出容器,容器会停止;ctrl + p +q 退出容器,容器不停止。

重新进入运行容器交互模式

bash 复制代码
docker exec -it '' /bin/bash  # 在容器中打开新cmd   启动新进程  用exit退出 不会导致容器的停止
docker attach 'container_id'  # 直接进入容器cmd     不启动新的进程 用exit退出 会导致容器的停止

容器的导入导出

export 命令:导出容器中的内容,作为一个tar归档文件。

bash 复制代码
docker export container_id > 'tar文件名称'

import 命令:从tar包中创建一个新的文件系统再导入为镜像。

bash 复制代码
cat xx.tar| docker import - 用户名/镜像名称:版本号

例:cat xx.tar| docker import - images/new_image:base

提交镜像

bash 复制代码
docker commit -m='commit_msg' -a='author_name' 'container_id' 路径/镜像名称:版本号

例: docker commit -m='msg' -a='name' 07e1506aca97 images/new_image:1.1

四、将镜像推送到公库

首先在个人实例 → 命名空间新建一个命名空间,并在该空间下新建一个本地仓库。

此时可以通过阿里云命令就可以进行推送

bash 复制代码
# 推送镜像
docker login --username=aliyun6711407430 registry.cn-hangzhou.aliyuncs.com  # 需要验证阿里云账号密码
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/zhuo98/my_study:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/zhuo98/my_study:[镜像版本号]

# 拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/zhuo98/my_study:[镜像版本号]

五、将镜像推送到私库

bash 复制代码
# 1. 先拉取registry
docker pull registry

# 2. 以守护进程方式启动registry,设置端口映射和数据卷的映射关系
docker run -d -p 5000:5000 -v /store/test/:/temp/registry --privileged=true registry
    - 将主机5000端口映射docker5000端口
    - 将主机/store/test/ 映射 docker的 /temp/registry 路径

# 3. 发送请求获取私服库的内容 
curl -XGET http://IP:PORT/v2/_catalog    

# 4. 通过tag命令修改镜像,符合docker私服命名规则:IP:PORT/镜像名:版本
docker tag hello-world:latest IP:PORT/hello-world:latest

# 5. 由于docker不允许http方式push镜像 需要修改配置文件,添加配置 并重启docker
vim /etc/docker/daemon.json
追加内容 insecure-registries": ["IP:PORT"]

# 6. 推送私服镜像
docker push IP:PORT/hello-world:latest

# 7. 拉取私服镜像
docker pull IP:PORT/hello-world:latest  

六、数据卷

容器中的数据在删除后会丢失,数据卷的出现就是对容器数据持久化;换句话说就是数据的备份,使主机和docker互通;数据卷完全独立于docker,删除docker不会删除其挂载的数据卷。

bash 复制代码
# 通过-v 参数添加数据卷,也可以添加多组数据卷
# 默认情况下仓库被创建在容器的/var/lib/registry目录下
docker run -v /temp/data:/test/data  xxx

※:数据卷可以在容器之间共享和重用数据;数据卷中的更改可以实时生效;数据卷的生命周期一直持续到没有容器使用它;数据卷中的更改不会包含在镜像中。

在默认情况下默认数据卷是可读写的,也可以将数据卷的权限设置成只读的。注意:限制的是容器并不是宿主机的权限。

bash 复制代码
docker run -v /tmp/a:/user/b:rw  xx # 默认是rw的
docker run -v /tmp/a:/user/b:ro  xx # 设置为只读  

数据卷之间也是可以继承的,如果继承的父类容器挂了,并不会影响子类的容器卷使用。

bash 复制代码
docker run --volumes-from 父类容器名称 xx 
    --volumes-from 指定父类

七、net work

Docker使用Linux桥接,在宿主机默认创建一个docker容器网桥(docker0),在内核层连通了其他虚拟或物理网卡,docker默认指定了docker0接口的IP地址和子网掩码,启动容器时会根据docker网桥的网段分配给容器IP(Container-IP),同时docker网桥是每个容器的默认网关,因为在统一宿主机的容器都接入同一个网桥,这样容器之间就能通过容器的Container-IP直接通信。

网桥在创建一对对等的虚拟设备接口一个叫veth,另一个叫eth0成对匹配;每个容器有个实例网卡 接口叫eth0,此时 docker0上面的每个veth匹配每个容器的 eth0 两两匹配。

一共有三种 网桥(bridge) 主机(host) 无(none) 容器(container) 四种模式。docekr inspect 容器名

  • bridge: 虚拟网桥模式,为每一个容器分配、设置IP,并将容器连接到docker0,默认为该模式。

    发现网卡之间互相对应。


  • host:容器不会虚拟自己的网卡和IP等,而是使用宿主机的IP和端口与外界通信,不需要额外的NAT转换。这里都是空代表和主机公用。

  • none:容器有自己独立的Network namespace,但是并没任何的网络配置(简称没有网络)。

  • container:容器不会创建自己的网卡配置自己的IP,而是和一个指定的容器共享IP和端口。

    bash 复制代码
    # 启动主容器
    docker run -d -it --name alpine1 alpine /bin/sh
    
    # 启动从容器
    docker run -d -it --name alpine2 --network '网络名称':'主容器名' alpine /bin/sh

    ※:两个容器共用铜一个网卡,当共享主机被干掉了,另一台主机也没有网络了。

bash 复制代码
# 查看一共有哪些网关
docker network ls

# 添加网络  默认是bridge模式
docker network create 'netWork_name'

# 查看网络
docker network inspect 'netWork_name'

# 删除网络
docker network rm 'netWork_name'网络

※:使用host模式启动容器时并指定端口映射,会抛出警告!!此时设置 -p 参数并不会生效,而是会以主机端口号为主,重复时则递增。

八、DockerFile

DockerFile是用来构建docker镜像的文件,由一条条构建镜像所需的命令和参数组成的脚本。DockerFile包含了执行的代码和文件、以及运行时的环境、依赖包等等。

指令按照从上到下顺序执行,每条保留字指令都必须大写且后面至少跟随一个参数,用#注释,每条指令都会创建一个新的镜像层并对镜像进行提交。

保留字解释

bash 复制代码
# 指定新镜像基于哪个镜像,DockerFile 第一条必须是from,build时候执行
FROM ubuntu:latest

# 镜像维护者的姓名和邮箱地址
MAINTAINER zhuo zhuo@163.com

# 设置环境变量, 可以在后续的任何RUN指令或其他指令中使用
ENV work_path /home

# 设置参数 用等号赋值
ARG BASE_VERSION=latest

# 指定登陆进来后默认的工作目录,使用环境变量需要加$
WORKDIR $work_path 

# USER <user>[:<group>],该镜像以什么样的用户去执行,如果不指定,默认是root
USER zhuo

# 定义数据卷,用于持久化工作  ?
VOLUME /home/zhuo:/test/temp

# 将宿主机下的目录拷贝到指定路径并解压 src源路径 dest目标路径
ADD src dest                       # 写法一
ADD ["<src>","<src>"... "<dest>"]  # 写法二  多个src解压到指定的dest下

# 将宿主机下的目录拷贝到指定路径 src源路径 dest目标路径
COPY src dest                      # 写法一
COPY ["<src>","<src>"... "<dest>"] # 写法二  多个src解压到指定的dest下

# 对外暴露的端口号
EXPOSE 8080

RUN 保留字

在执行build时会运行,每次构建时会优先查找本地缓存,若不想使用缓存可以通过 docker build --no-cache 解除。

shell格式,多个命令用 "&&" 连接,等同于在终端输入命令。

bash 复制代码
RUN cmd1 && cmd2

例:RUN echo 1 && echo 2

exec格式,被解析为JSON序列,这意味着必须使用双引号。

bash 复制代码
RUN ["executable","param1","param2"]

例:RUN ["/bin/bash","-c","echo hello world"]

CMD 保留字

在docker run运行时运行,运行结束后容器将终止,CMD可以被docker run后面的命令覆盖。一个Dockerfile只有顺序向下的最后一个CMD生效。

bash 复制代码
# shell格式
CMD ls -a

# exec格式
CMD ["ls", "-a"]

ENTRYPOINT 保留字

在docker run运行时运行,也是指定一个容器启动的命令类似CMD指令,但是不会被docker run所覆盖,而且这些指令会被当做参数送给 ENTRYPOINT 指令所指定的程序。多条ENTRYPOINT 只会执行最后一个。

bash 复制代码
# shell格式
ENTRYPOINT ls -a

# exec格式
ENTRYPOINT ["ls", "-a"]

※:CMD 和 ENTRYPOINT冲突情况

|----------------------------|----------------------------------------|----------------------------------------|
| | ENTRYPOINT exec格式("ls", "-l") | ENTRYPOINT cmd格式(ls -l) |
| CMD exec格式("ls", "-a") | CMD的命令作为参数放到ENTRYPOINT的后面。 ls -a ls -l | ENTRYPOINT 覆盖CMD的命令 /bin/sh -c 'ls -l' |
| CMD cmd格式(ls -a) | ls -l /bin/sh -c 'ls -a' | ENTRYPOINT 覆盖CMD的命令 /bin/sh -c 'ls -l' |

build文件

在路径下新建一个名称为 Dockerfile 的文件,也可以通过 -f 指定具体文件。

bash 复制代码
# 注意版本号后面有个空格 有个点
docker build -f 文件路径 -t 镜像名:版本号 .

虚悬镜像(dangling Image)

仓库名、标签名都是none的镜像被称为虚悬镜像,虚悬镜像没有价值,可以删除,一般不会有虚悬镜像存在。

bash 复制代码
# 创建一个虚悬镜像  直接不写名称和版本
docker build .

# 删除虚悬镜像
docker image prune

九、Docker-Compose

Docker-Compose 负责实现对容器集群的快速编排,需要定义一个yaml格式的配置文件 docker-compose.yml,配置好多个容器之间的调用关系,然后只需要一个命令就能同时启动/关闭这些容器。

Docker-Compose安装网址,执行官网命令即可安装。

bash 复制代码
https://docs.docker.com/compose/install/linux/#install-the-plugin-manually

工作流程:首先编写 docker-compose.yml``定义容器的编排规则,通过 docker-compose config -q检查yml文件是否编写语法正确,最后 docker-compose up一键启动容器编排。

bash 复制代码
version: "3"  # docker-compose文件版本号

# 配置各个容器服务
services:
  microService:
    image: springboot_docker:1.0  # 镜像名称
    container_name: ms01          # 容器名称,如果不指定,会生成一个服务名加上前缀的容器名
    ports:                        # 定义多个暴露端口
      - "6001:6001"
    volumes:                      # 定义多个容器卷
      - /app/microService:/data
    networks:                     # 使用网关
      - springboot_network
    depends_on:                   # 配置该容器服务所依赖的容器服务
      - redis
      - mysql

  redis:
    image: redis:6.0.8
    ports:
      - "6379:6379"
    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:data
    networks:
      - springboot_network
    command: redis-server /etc/redis/redis.conf   # 启动命令

  mysql:
    image: mysql:5.7
    environment:                           # 定义环境相关参数
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
      MYSQL_DATABASE: 'db_springboot'
      MYSQL_USER: 'springboot'
      MYSQL_PASSWORD: 'springboot'
    ports:
      - "3306:3306"
    volumes:
      - /app/mysql/db:/var/lib/mysql
      - /app/mysql/conf/my.cnf:/etc/my.cnf
      - /app/mysql/init:/docker-entrypoint-initdb.d
    networks:
      - springboot_network
    command: --default-authentication-plugin=mysql_native_password # 解决外部无法访问

networks:
  # 创建 springboot_network 网桥网络
  springboot_network:

常用命令

bash 复制代码
docker compose up      # 启动所有docker compose服务
docker compose up -d   # 后台启动所有docker compose服务
docker compose down    # 停止并删除容器、网络、卷、镜像
docker compose top     # 展示当前docker compose编排过的容器进程
docker compose ps      # 展示当前docker compose编排过的运行所有容器

docker compose exec yml里的服务id   #  进入容器
docker compose logs yml里的服务id   #  查看容器日志

docker compose config -q   # 检查配置,有问题才会有输出
docker compose restart     # 重启
docker compose start -q    # 启动
docker compose stop -q     # 停止

需要修改POM文件为XXX 才能防止闪退

相关推荐
Mikko78 分钟前
Linux 重启后日志没了?进程被 OOM 杀了去哪看?logrotate 之后日志还往旧文件写?三台真机实测日志与性能排查
linux·运维·centos
光依旧17 分钟前
发版就掉请求?Spring Boot优雅停机的四步
运维·spring boot·nginx·高可用·优雅停机·mcp server
yichengerp2 小时前
电子行业常用erp系统有哪些?推荐适合中小电子厂的易呈erp软件,操作简单,易落地
大数据·运维·人工智能·云计算·制造
天国梦2 小时前
国密门禁品牌怎么选?2026年最新3个避坑要点
运维·服务器·数据库·python
程序员老赵2 小时前
Docker 部署 Portainer CE:轻松搭建容器管理平台
docker·容器·开源
TTATTC3 小时前
Gmail、Drive、日历共用一套命令:gws 如何在运行时把 Discovery 文档编译成 CLI
docker·开源
信可维3 小时前
自动化操作多平台账号:登录态、双会话与 User Data 的 3 个坑
运维·自动化
龙仔7253 小时前
RustDesk 自建服务器 Key 强校验配置笔记
运维·服务器·笔记
大侠归来3 小时前
Docker 部署 Dolibarr:从零开始的完整指南
运维·docker·容器
KING-WU5123 小时前
Linux GDB 调试实战指南:从编译到断点调试
linux·运维·服务器