自动化基础随心记二-docker

一、配置docker源

官网
菜鸟教程docker

1.1 安装

# 安装相关依赖
yum install -y yum-utils
# 下载官方的docker yum源文件
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 替换源地址
sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# 安装docker-ce
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

systemctl enable --now docker
docker version

1.2 配置镜像加速

tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.1ms.run"]
}
EOF

重新加载

systemctl daemon-reload
systemctl restart docker

二、第一个docker容器实例

C/S架构
docker服务端:dockerd
docker客户端:下载镜像、运行容器…

镜像Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。它也相当于是一个root文件系统。比如官方镜像 centos:7 就包含了完整的一套 centos:7 最小系统的 root 文件系统。
容器Docker 利用容器(Container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序
仓库仓库(Repository)是集中存放镜像文件的场所,仓库分为公开仓库(Public)和私有仓库(Private)两种形式
# -d 后台运行 -p 端口映射 --name 容器名字 nginx 镜像名字
docker run -d -p 80:80 --name "first_nginx" nginx

三、镜像管理

Docker镜像加载原理:
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统叫UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

docker 家目录/var/lib/docker
docker search搜索镜像
docker pull拉取镜像
docker push推送镜像
docker load导入镜像
docker load -i docker_centos7.tar.gz
docker save导出镜像
docker save centos:7 -o docker_centos7.tar.gz
docker images查看镜像
docker image inspect nginx查看镜像的详细信息,输出为json
docker rmi删除镜像
docker tag给镜像打标签
docker tag a830707172e8 nginx:1.0
docker build结合Dockerfile自定义镜像
docker inspect查看镜像信息

四、容器管理

docker ps查看容器列表
-a 查看所有容器 -q 只显示容器id
docker run创建并运行容器
-i 进入交互模式 -t 分配一个终端 -d 后台运行 -v 挂载容器卷
--rm 容器退出的时候,自动删除
–restart=always 自动重启 unless-stopped 只在容器关闭、停止的时候重启 on-failure 只在失败的时候重启 默认不重启
docker volume create创建数据卷空间,只关注容器中的数据不丢,创建后的数据卷空间存放在/var/lib/docker/volumes/下
docker logsnginx容器的日志默认是输出到docker标准输出和标准错误输出,而不是存放在文件中,可以通过docker logs xxx查看日志
docker export
docker import
导出容器信息为tar包
从tar包将容器导入成镜像
docker create创建容器
docker start启动容器
docker stop停止容器
docker restart重启容器
docker kill强制停止容器
docker rm删除容器
docker exec进入正在运行的容器(分配一个新终端)
docker exec -it 容器id/容器名字 /bin/bash
docker attach进入正在运行的容器(共用相同的终端)
docker cp宿主机与docker容器之间传输数据
上传:docker cp 宿主机路径 容器名字:容器路径
下载:docker cp 容器名字:容器路径 宿主机路径
docker stats
docker top
docker inspect
查看容器状态、信息
docker commit将容器提交成新镜像
docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

五、dockerfile

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。

  1. 编写Dockerfile文件
  2. docker build -t “镜像名” . 构建镜像
  3. docker run 镜像运行容器实例

5.1 Docker执行Dockerfile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

5.2 常用保留字指令

FROM基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FROM尽量指定具体版本
LABEL以键值对的形式用于指定容器的属性信息,作者,个人联系方式,邮件等等
ENV用来在构建镜像过程中设置环境变量ENV <key> <value>
RUN容器构建时需要运行的命令,是在 docker build时运行Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大
RUN yum -y install wget \
&& tar -xvf redis.tar.gz
ADD将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包拷贝压缩包
COPY将文件或目录复制到镜像中,不会解压压缩包COPY [–chown=<user>:<group>] <源路径1>… <目标路径>
用于拷贝文件或目录,同样需求下,官方推荐使用 COPY
WORKDIR指定在创建容器后,终端默认登陆进来的工作目录一般用于配合ADD,COPY需要书写容器中路径指令,Dockerfile中使用相对路径操作容器
VOLUMN挂载数据卷在docker run的时候用-v即可
结尾部分书写的内容
EXPOSE当前容器对外暴露出的端口暴露出的端口可以被-P识别,-P 宿主机的随机端口映射到容器的指定端口
CMD在docker run 时运行,指定一个容器启动时要运行的命令。Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换大部分时候使用CMD
CMD [“命令”,“参数01”,“参数02”]
CMD [“nginx”,“-g”,“daemon off;”]
CMD [“catalina.sh”,“run”]
ENTRYPOINT也是用来指定一个容器启动时要运行的命令,类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序,如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令

5.3 多阶段提交

一个Dockerfile有多个FROM
应用场景:压缩镜像的大小,镜像分层次架构,适用于编译安装/构建场合,先通过中间镜像进行编译,编程结果存放到新的镜像中。
FROM ubuntu:20.04 AS base

FROM ubuntu:20.04
COPY --from=base /app/ /app/

5.4 示例

# 阶段 1: 构建阶段
# 定义构建参数(可设置默认值)
ARG MAVEN_VERSION=3.9
ARG JDK_VERSION=17
FROM maven:${MAVEN_VERSION}-eclipse-temurin-${JDK_VERSION}-alpine AS builder

# 声明构建期可访问的环境变量
ARG BUILD_NUMBER=0
ARG SKIP_TEST=true
ENV BUILD_NUMBER=${BUILD_NUMBER}

WORKDIR /app
COPY pom.xml .
# 利用缓存提前下载依赖
RUN mvn dependency:go-offline -B

COPY src ./src
# 带参数构建
RUN mvn package -DskipTests=${SKIP_TEST}

# 阶段 2: 运行时阶段 - 使用最小化 JRE 镜像
# 阶段 2: 运行时阶段
# 覆盖基础镜像版本变量
ARG JDK_VERSION=17
FROM eclipse-temurin:${JDK_VERSION}-jre-alpine

# 声明运行时环境变量
ARG APP_VERSION=1.0.0
ENV APP_VERSION=${APP_VERSION} \
    TZ=Asia/Shanghai

# 非 root 用户配置
ARG APP_USER=appuser
ARG APP_UID=1001
RUN addgroup -g ${APP_UID} ${APP_USER} && \
    adduser -u ${APP_UID} -G ${APP_USER} -D ${APP_USER}

WORKDIR /app
COPY --from=builder --chown=${APP_USER}:${APP_USER} /app/target/*.jar ./app.jar

# 优化 JVM 参数(根据需求调整)
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"


# 健康检查(Spring Boot Actuator 端点)
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

USER ${APP_USER}
# 暴露端口(根据实际应用端口修改)
EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

六、docker网络

6.1 概述

docker启动后,会产生一个名为docker0的虚拟网桥,默认创建三大网络模式,用于容器间互联和通信以及端口映射,容器IP变动时可以通过服务名直接网络通信而不受影响
在这里插入图片描述

6.2 常用基本命令

查看网络 docker network ls
查看网络源数据 docker network inspact 网络名称
删除网络 docker network rm 网络名称

6.3 网络模式

bridge模式使用–network bridge指定,默认使用docker0Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信
宿主机会有个veth对应容器的eth0
host模式使用–network host指定直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换
none模式使用–network none指定在none模式下,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo。需要我们自己为Docker容器添加网卡、配置IP等
container模式使用–network container:NAME或者容器ID指定新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
自定义网络模式使用–network 网络名 指定自定义网络本身就维护好了主机名和ip的对应关系,也就是ip和服务名都能通信

6.4 同一台宿主机的容器间通信

参考文章

通信方式实现方法优点缺点
默认 Bridge 网络容器通过 IP 或名称通信简单易用默认不支持容器名称通信
自定义网络创建自定义网络,容器通过名称通信支持容器名称通信,网络隔离性好需要手动创建网络
–link(不推荐)使用 --link 连接容器早期支持容器名称通信功能有限,已弃用
Host 网络容器共享宿主机网络栈直接使用宿主机网络安全性低,可能导致端口冲突
Docker Compose自动创建网络,容器通过服务名通信简化多容器管理,支持服务名称通信需要编写 docker-compose.yml 文件
共享数据卷容器通过共享文件系统通信适合共享数据场景仅适用于文件系统通信

七、docker-compose

7.1 docker-compose与docker compose

原文链接:https://blog.csdn.net/u010066597/article/details/137753590
Docker Compose 有两种使用方式,分别是 docker-compose 和 docker compose。这两种方式之间存在一些差异:
集成程度:
docker-compose 是一个独立的工具,需要单独安装和配置。
docker compose 是 Docker 命令行工具的一部分,更加紧密地集成在 Docker 生态中。
兼容性:
docker-compose 可以在任何支持 Docker 的系统上使用,不受 Docker 版本的限制。
docker compose 需要 Docker 19.03 及以上版本才能使用。
总的来说,docker compose 是 Docker 官方推荐的新用法,它提供了更好的集成和用户体验。但如果你需要在较旧的 Docker 版本上使用 Docker Compose,或者需要更多的灵活性,那么使用 docker-compose 命令可能更合适。

7.2 概述

dockerfile是对镜像进行管理
docker compose是对容器进行管理
单机容器编排工具:docker compose
容器集群管理:
ansible+dockerfile+docker compose
docker swarm
k8s

7.3 常用基本命令

docker-compose这个命令包含了docker container和docker image 命令
-h查看帮助
up -d启动所有docker-compose服务并后台运行
down停止并删除容器、网络、卷、镜像
exec yml里面的服务id进入容器示例内部
ps展示当前docker-compose编排过的所有运行的容器
top展示当前docker-compose编排过的容器进程
logs yml里面的服务id查看容器日志
config -q检查配置 有问题才输出
restart|start|stop重启服务|启动服务|停止服务
run运行容器
images查看镜像

7.4 示例

version: '3.8'

# 定义共享网络(实现服务隔离)
networks:
  app_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16

# 集中管理环境变量
x-environment: &common_env
  TZ: Asia/Shanghai
  LANG: C.UTF-8

# 共享配置扩展点
x-logging: &default_logging
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"

services:
  # 后端服务(Spring Boot 示例)
  backend:
    image: your-registry/backend:${TAG:-latest}
    build:
      context: ./backend
      dockerfile: Dockerfile
      args:
        - BUILD_NUMBER=${BUILD_NUMBER:-0}
    environment:
      <<: *common_env
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/app_db
      SPRING_REDIS_HOST: redis
      SPRING_PROFILES_ACTIVE: prod
    networks:
      - app_network
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8080/actuator/health || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
    logging: *default_logging

  # 数据库服务(PostgreSQL)
  db:
    image: postgres:15-alpine
    networks:
      - app_network
    environment:
      <<: *common_env
      POSTGRES_USER: app_user
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app_user"]
      interval: 10s
      timeout: 5s
      retries: 5
    logging: *default_logging

  # Redis 缓存服务
  redis:
    image: redis:7-alpine
    networks:
      - app_network
    command: redis-server --save 60 1 --loglevel warning
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
    logging: *default_logging

  # 前端服务(Nginx + React 示例)
  frontend:
    image: your-registry/frontend:${TAG:-latest}
    build:
      context: ./frontend
      dockerfile: Dockerfile
    networks:
      - app_network
    depends_on:
      backend:
        condition: service_healthy
    environment:
      <<: *common_env
      API_BASE_URL: http://backend:8080/api
    ports:
      - "80:80"
    logging: *default_logging

# 敏感数据管理
secrets:
  db_password:
    file: ./secrets/db_password.txt

# 持久化存储定义
volumes:
  pg_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./data/pg_data
  redis_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./data/redis_data
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值