Docker容器使用记录

Posted by     "zengchengjie" on Thursday, February 17, 2022

概念

将部署的安全包、配置文件等一次打包放到docker(集装箱)中,方便一次打包,且迁移应用的时候不会因为系统差异而产生问题

部署

参考文档:

docker官方文档

微软提供的docker文档

官方文档:centos下的docker安装

docker安装(阿里云源)

  • yum install -y yum-utils device-mapper-persistent-data lvm2

    执行结果:

    ...
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
      正在安装    : libaio-0.3.109-13.el7.x86_64                                                                                                             1/10
      正在更新    : 7:device-mapper-libs-1.02.170-6.el7_9.5.x86_64                                                                                           2/10
      正在更新    : 7:device-mapper-1.02.170-6.el7_9.5.x86_64                                                                                                3/10
      正在安装    : 7:device-mapper-event-libs-1.02.170-6.el7_9.5.x86_64                                                                                     4/10
      正在安装    : 7:device-mapper-event-1.02.170-6.el7_9.5.x86_64                                                                                          5/10
      正在安装    : 7:lvm2-libs-2.02.187-6.el7_9.5.x86_64                                                                                                    6/10
      正在安装    : device-mapper-persistent-data-0.8.5-3.el7_9.2.x86_64                                                                                     7/10
      正在安装    : 7:lvm2-2.02.187-6.el7_9.5.x86_64                                                                                                         8/10
      清理        : 7:device-mapper-libs-1.02.170-6.el7.x86_64                                                                                               9/10
      清理        : 7:device-mapper-1.02.170-6.el7.x86_64                                                                                                   10/10
      验证中      : 7:device-mapper-event-1.02.170-6.el7_9.5.x86_64                                                                                          1/10
      验证中      : 7:lvm2-libs-2.02.187-6.el7_9.5.x86_64                                                                                                    2/10
      验证中      : device-mapper-persistent-data-0.8.5-3.el7_9.2.x86_64                                                                                     3/10
      验证中      : 7:device-mapper-1.02.170-6.el7_9.5.x86_64                                                                                                4/10
      验证中      : libaio-0.3.109-13.el7.x86_64                                                                                                             5/10
      验证中      : 7:lvm2-2.02.187-6.el7_9.5.x86_64                                                                                                         6/10
      验证中      : 7:device-mapper-libs-1.02.170-6.el7_9.5.x86_64                                                                                           7/10
      验证中      : 7:device-mapper-event-libs-1.02.170-6.el7_9.5.x86_64                                                                                     8/10
      验证中      : 7:device-mapper-libs-1.02.170-6.el7.x86_64                                                                                               9/10
      验证中      : 7:device-mapper-1.02.170-6.el7.x86_64                                                                                                   10/10
    
    已安装:
      device-mapper-persistent-data.x86_64 0:0.8.5-3.el7_9.2                                   lvm2.x86_64 7:2.02.187-6.el7_9.5
    
    作为依赖被安装:
      device-mapper-event.x86_64 7:1.02.170-6.el7_9.5         device-mapper-event-libs.x86_64 7:1.02.170-6.el7_9.5         libaio.x86_64 0:0.3.109-13.el7
      lvm2-libs.x86_64 7:2.02.187-6.el7_9.5
    
    作为依赖被升级:
      device-mapper.x86_64 7:1.02.170-6.el7_9.5                                   device-mapper-libs.x86_64 7:1.02.170-6.el7_9.5
    
    完毕!
    
  • yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

    需要执行这一步,使用阿里云镜像源,否则会出现‘没有可用软件包’错误

    已加载插件:fastestmirror
    Loading mirror speeds from cached hostfile
     * base: mirrors.aliyun.com
     * centos-sclo-rh: mirrors.bupt.edu.cn
     * epel: mirrors.njupt.edu.cn
     * extras: mirrors.aliyun.com
     * updates: mirrors.aliyun.com
    没有可用软件包 docker-ce。
    没有可用软件包 docker-ce-cli。
    没有可用软件包 containerd.io。
    错误:无须任何处理
    
  • yum install docker-ce docker-ce-cli containerd.io

    碰到此处,选择y继续安装

    安装  3 软件包 (+6 依赖软件包)
    
    总下载量:93 M
    安装大小:381 M
    Is this ok [y/d/N]: y
    Downloading packages:
    

    这里我也是选择y

    从 https://mirrors.aliyun.com/docker-ce/linux/centos/gpg 检索密钥
    导入 GPG key 0x621E9F35:
     用户ID     : "Docker Release (CE rpm) <docker@docker.com>"
     指纹       : 060a 61c5 1b55 8a7f 742b 77aa c52f eb6b 621e 9f35
     来自       : https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
    是否继续?[y/N]:y
    Running transaction check
    Running transaction test
    Transaction test succeeded
    Running transaction
    
  • systemctl start docker

  • systemctl enable docker

    执行结果:

    systemctl enable  docker
    Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
    
  • docker version

    执行结果:

    docker version
    Client: Docker Engine - Community
     Version:           20.10.12
     API version:       1.41
     Go version:        go1.16.12
     Git commit:        e91ed57
     Built:             Mon Dec 13 11:45:41 2021
     OS/Arch:           linux/amd64
     Context:           default
     Experimental:      true
    
    Server: Docker Engine - Community
     Engine:
      Version:          20.10.12
      API version:      1.41 (minimum version 1.12)
      Go version:       go1.16.12
      Git commit:       459d0df
      Built:            Mon Dec 13 11:44:05 2021
      OS/Arch:          linux/amd64
      Experimental:     false
     containerd:
      Version:          1.4.12
      GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
     runc:
      Version:          1.0.2
      GitCommit:        v1.0.2-0-g52b36a2
     docker-init:
      Version:          0.19.0
      GitCommit:        de40ad0
    
  • docker run hello-world

docker-compose安装

  • sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s-uname -m` -o /usr/local/bin/docker-compose

    执行结果:

      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   423  100   423    0     0    494      0 --:--:-- --:--:-- --:--:--   494
    100 16.2M  100 16.2M    0     0  11.4M      0  0:00:01  0:00:01 --:--:-- 52.2M
    
  • sudo chmod +x /usr/local/bin/docker-compose

  • docker-compose –version

    docker-compose version 1.25.1, build a82fef07
    

docker-compose.yml

修改容器时间和宿主机的一致,添加volumes变量 - /etc/localtime:/etc/localtime即可

  prometheus:
    container_name: prometheus
    image: prom/prometheus:latest
    volumes:
      - /etc/localtime:/etc/localtime

docker-compose中的depends_on

通过depends_on告诉docker-compose当前服务启动之前先要把depends_on指定的服务启动起来才行。例如:kafka依赖zookeeper,nginx依赖php-fpm等等。

services:

  kafka:
    image: tflinux_kafka
    depends_on:
      - zookeeper

  php-nginx:
    image: tflinux_php-nginx
    depends_on:
      - php-fpm

常用命令

常见问题

  • 问题1:WARNING: Found orphan containers ** command with the –remove-orphans flag to clean it up.

    原因:如果将docker-compose的镜像的配置放在同一个目录下时,docker运行时生成的镜像实例会有相同的前缀,就是当前的目录名,也就是说默认相同前缀的是同一组实例,当你在当前目录下还有别的镜像的配置文件,在运行时就会出现以下警告

    例如:我将docker-compose文件放在/test/下,启动的kafka名称就为test_kafka_1

    解决方案:

    1. 启动时制定docker容器名称

      docker-compose -p kafka -f /root/test/kafka-compose.yml up -d
      
    2. 或者将docker-compose文件放到单独的目录下启动

  • docker 镜像移除:把为none的移除,注意docker rmi前后空格)

    docker images | grep none | awk '{print " docker rmi "$3}' | bash
    
  • 问题2

    Mac m1芯片下的镜像有时候在Linux上不能使用,是CPU架构的原因。

    报错:

    WARNING: The requested image’s platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was requested 11e1b7fdbfcc7ead314864fae89ce2d2acdea21f93a4777c782c1e1d4e30a8e4

  • 执行脚本的时候dockerfile里 bash还是sh,取决于基础镜像的linux版本

    否则会报:

    docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: “/bin/bash”: stat /bin/bash: no such file or directory: unknown.

  • dockerfile里执行脚本的时候报 illegal option -问题

    脚本文件在windows下编辑过,换行符号是 \r\n而在linux上是\n,因此需要替换换行符

    解决办法:

    RUN sed -i -e ’s/\r//g' docker-entrypoint.sh ENTRYPOINT [“sh”, “docker-entrypoint.sh”]

    使用sed 命令替换即可

  • import可以导入save保存的镜像包和export保存的容器包。但是如果导入的是save保存的镜像包,导入时没有错。但是run运行时就会出错误。

    参考文章地址

  • import方式导包,可以重命名,而save的不可以

  • 如果需要bash的脚本,你的镜像里没有bash命令,其实在dockerfile里装一个就行了

    RUN apk update && apk add bash

  • 问题:java.net.NoRouteToHostException: Host is unreachable (Host unreachable)

    原因:firewalld 的没有信任 docker 的 ip 地址。

    解决方案:将所有 docker 的 ip 添加到信任区域

    firewall-cmd  --zone=trusted --add-source=172.23.0.1/16 --permanent
    firewall-cmd --reload
    

docker安装ping

直接安装ping:

apt-get update && apt-get install iputils-ping

报错:

E: List directory /var/lib/apt/lists/partial is missing. - Acquire (2: No such file or directory)

切换到root:

docker exec -it --user root <container id> /bin/bash

再次安装,成功。

执行ping

docker exec -it kafka ping zookeeper

成功

常用命令

docker stats <名称>

停止docker服务

  1. 停止所有正在运行的容器

    docker stop $(docker ps -aq)
    
  2. 清除所有已经停止的容器、网络、镜像和数据卷

$ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N] y
  1. 停止Docker的网络服务

    sudo launchctl unload /Library/LaunchDaemons/com.docker.vmnetd.plist
    
  2. 停止Docker的镜像服

    sudo launchctl unload /Library/LaunchDaemons/com.docker.hyperkit.plist
    
  3. 停止Docker的守护进程

    sudo launchctl unload /Library/LaunchDaemons/com.docker.docker.plist
    

    在执行第5条和第6条命令时,如果出现"no such file or directory"的错误,请使用如下命令代替:

    sudo launchctl stop com.docker.vmnetd
    sudo launchctl stop com.docker.hyperkit
    sudo launchctl stop com.docker.docker
    

    这样就可以停止Docker服务了。

部署应用实践

mac平台拉取Linux平台特定架构的镜像

docker pull --platform linux/amd64 docker.io/bitnami/kafka:3

以上命令即可拉取 linux/amd64 架构的docker镜像,否则不同架构的镜像,在使用过程中会出现不兼容现象

问题:给我一个dockerfile做为示例,告诉我如何兼容多个目标架构?

为了创建一个能够兼容多个目标架构的Dockerfile,你可以使用Docker的多阶段构建和BuildKit的功能。Docker BuildKit是Docker的一个新构建系统,它支持多种特性,包括构建多平台镜像。

以下是一个简单的Dockerfile示例,它使用了多阶段构建和BuildKit的--platform标志(虽然--platform标志通常在构建命令中指定,而不是在Dockerfile中)来创建一个能够同时支持Linux/amd64和Linux/arm64(比如Mac M1的Docker环境)的镜像。

然而,由于Dockerfile本身不直接支持条件语句来根据不同的架构选择不同的指令,我们通常会在构建过程中使用脚本或Docker的命令行参数来指定多个平台。

但我可以向你展示一个基本的Dockerfile,然后解释如何在构建时指定多个平台。

Dockerfile 示例

这个Dockerfile将简单地从一个基础镜像复制一个简单的Hello World脚本,并设置其为容器启动时执行的命令。

# 使用官方Python运行时作为基础镜像  
FROM python:3.8-slim AS build  
  
# 设置工作目录  
WORKDIR /app  
  
# 复制当前目录下的文件到容器的/app目录中  
COPY hello.py .  
  
# 设置容器启动时执行的命令  
CMD ["python", "./hello.py"]

构建多平台镜像

要在构建时指定多个平台,你需要在Docker构建命令中使用--platform参数,并且可能需要启用Docker BuildKit(如果你的Docker版本较旧,可能需要手动启用它)。以下是一个示例命令,展示了如何为Linux/amd64和Linux/arm64构建镜像:

# 确保Docker BuildKit已启用  
# 在Docker Desktop中,这通常是默认启用的  
# 或者,你可以通过设置环境变量来启用它:export DOCKER_BUILDKIT=1  
  
# 使用Docker BuildKit构建多平台镜像  
# 注意:下面的命令可能需要根据你的实际情况进行调整  
# --platform 参数可以多次使用以指定多个平台  
docker buildx build --platform linux/amd64,linux/arm64 -t yourusername/yourimage:latest .  
  
# 注意:docker buildx 是Docker BuildKit的一个扩展,提供了更强大的多平台构建功能  
# 如果你还没有安装或配置docker buildx,你可能需要先执行 'docker buildx install' 和 'docker buildx create --use'

在这个命令中,docker buildx build 是用来构建镜像的命令,--platform linux/amd64,linux/arm64 指定了要构建的目标平台,-t yourusername/yourimage:latest 指定了镜像的仓库、名称和标签。

请确保你的Docker环境已经配置好了Docker BuildKit和docker buildx,并且你的hello.py文件存在于Dockerfile所在的目录中。此外,如果你打算将镜像推送到Docker Hub或其他容器镜像仓库,请确保你已经登录并且有权推送镜像到指定的仓库。

error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. “docker buildx create –use”)

这个错误信息表明你正在尝试使用 Docker 的默认 docker 驱动来构建多平台镜像,但 docker 驱动本身不支持这一功能。为了构建多平台镜像,你需要切换到 docker buildx 驱动,这是一个更强大的构建工具,支持多平台构建。

以下是如何切换到 docker buildx 并使用它来构建多平台镜像的步骤:

  1. 安装 Docker Buildx(如果尚未安装): 通常,如果你使用的是 Docker Desktop(对于 Mac 或 Windows),Docker Buildx 应该已经包含在内。但是,如果你使用的是 Linux 或其他 Docker 安装方式,你可能需要手动安装或启用它。

    在 Docker 18.09 及更高版本中,Buildx 已经是 Docker CLI 的一部分,但你可能需要显式地创建并切换到它。

  2. 创建并切换到 Buildx 构建器: 打开你的命令行工具,并运行以下命令来创建一个新的 Buildx 构建器(如果还没有的话),并将其设置为默认构建器:

    bash复制代码
    
    docker buildx create --use
    

    这个命令会创建一个新的 Buildx 构建器实例(如果还没有的话),并将其设置为默认的构建器。

  3. 检查 Buildx 构建器: 你可以通过以下命令来检查当前配置的 Buildx 构建器:

    bash复制代码
    
    docker buildx inspect --bootstrap
    

    这个命令会显示当前构建器的详细信息,包括它支持的平台。

  4. 构建多平台镜像: 现在,你可以使用 Buildx 来构建多平台镜像了。使用与前面类似的命令,但这次是通过 Buildx:

    bash复制代码
    
    docker buildx build --platform linux/amd64,linux/arm64 -t yourusername/yourimage:latest .
    

    这个命令会构建两个版本的镜像,一个针对 linux/amd64 架构,另一个针对 linux/arm64 架构,并将它们标记为 yourusername/yourimage:latest

  5. 推送多平台镜像: 如果你打算将镜像推送到 Docker Hub 或其他容器镜像仓库,你可以使用相同的 docker push 命令,因为 Buildx 会处理多平台镜像的推送:

    bash复制代码
    
    docker push yourusername/yourimage:latest
    

    注意:确保你的仓库支持多平台镜像(如 Docker Hub)。

如果你遇到任何问题,确保你的 Docker 和 Docker Buildx 是最新版本,并且你的 Docker 守护进程正在运行。此外,检查你的 Dockerfile 是否正确无误,并且所有必要的文件都已包含在构建上下文中。

问题3

$ docker buildx build –platform linux/amd64,linux/arm64 -t wj-other-proj/cooperation-plan-api:1.0.47 . WARN[0000] No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use –push or to load image into docker use –load [+] Building 35.2s (11/11) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 436B 0.0s => [linux/amd64 internal] load metadata for docker.io/library/openjdk:8-jdk-al 1.7s => [linux/arm64 internal] load metadata for docker.io/library/openjdk:8-jdk-al 1.7s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build context 0.2s => => transferring context: 368.57kB 0.2s => [linux/arm64 1/3] FROM docker.io/library/openjdk:8-jdk-alpine@sha256:947928 0.0s => => resolve docker.io/library/openjdk:8-jdk-alpine@sha256:94792824df2df33402 0.0s => CACHED [linux/amd64 1/3] FROM docker.io/library/openjdk:8-jdk-alpine@sha256 0.0s => => resolve docker.io/library/openjdk:8-jdk-alpine@sha256:94792824df2df33402 0.0s => [linux/amd64 2/3] RUN apk –no-cache add tzdata ttf-dejavu && ln -sf / 31.9s => CACHED [linux/arm64 2/3] RUN apk –no-cache add tzdata ttf-dejavu && ln 0.0s => [linux/arm64 3/3] COPY app.war 1.4s => [linux/amd64 3/3] COPY app.war 1.5s 我想知道我这次打包的镜像成功没有?成功的话我去哪儿找到他并导出这个镜像?

根据你的构建输出信息,可以看出构建过程已经完成,但是有一个警告提示:

WARN[0000] No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load

这意味着构建结果只会保留在构建缓存中,不会自动加载到本地 Docker 镜像库中。因此,你需要手动加载或推送构建结果。 确认构建是否成功 从构建输出来看,构建过程已经完成,没有明显的错误。你可以通过以下步骤确认构建是否成功: 检查构建缓存: 运行以下命令查看构建缓存:

   docker buildx imagetools inspect wj-other-proj/cooperation-plan-api:1.0.47

如果构建成功,你应该能看到类似如下的输出:

   {
       "Name": "wj-other-proj/cooperation-plan-api:1.0.47",
       "Platforms": [
           "linux/amd64",
           "linux/arm64"
       ],
       "Images": [
           "sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
           "sha256:yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
       ]
   }

导出镜像 如果确认构建成功,你可以通过以下步骤导出镜像: 加载镜像到本地 Docker 镜像库: 使用 –load 参数重新运行构建命令,将构建结果加载到本地 Docker 镜像库中:

   docker buildx build --platform linux/amd64,linux/arm64 -t wj-other-proj/cooperation-plan-api:1.0.47 . --load

查看本地镜像: 运行以下命令查看本地镜像列表:

   docker images

应该能看到如下输出:

   REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
   wj-other-proj/cooperation-plan-api  1.0.47              sha256:xxxxxxxxxxxx  About an hour ago   123MB

导出镜像: 如果需要导出镜像,可以使用以下命令将其保存到文件中:

   docker save -o cooperation-plan-api-1.0.47.tar wj-other-proj/cooperation-plan-api:1.0.47

这会将镜像保存到一个名为 cooperation-plan-api-1.0.47.tar 的文件中。 总结 确认构建成功:通过 docker buildx imagetools inspect 命令检查构建缓存。 加载镜像到本地 Docker 镜像库:使用 –load 参数重新运行构建命令。 查看本地镜像:使用 docker images 命令查看本地镜像列表。 导出镜像:使用 docker save 命令将镜像保存到文件中。

问题3

$ docker buildx build --platform linux/amd64,linux/arm64 -t wj-other-proj/cooperation-plan-api:1.0.47 . --load
[+] Building 0.0s (0/0) error: docker exporter does not currently support exporting manifest lists

你遇到的问题是因为 docker buildx build 命令在使用 –load 选项时,不支持直接加载多架构的镜像列表(manifest list)。这通常会导致错误信息 error: docker exporter does not currently support exporting manifest lists。 为了解决这个问题,你可以采用以下步骤来分别加载每个架构的镜像,并创建一个多架构的镜像列表。 步骤 1: 分别构建和加载每个架构的镜像 构建和加载 AMD64 架构的镜像:

   docker buildx build --platform linux/amd64 -t wj-other-proj/cooperation-plan-api:1.0.47-amd64 . --load

构建和加载 ARM64 架构的镜像:

   docker buildx build --platform linux/arm64 -t wj-other-proj/cooperation-plan-api:1.0.47-arm64 . --load

步骤 2: 创建多架构的镜像列表 创建多架构的镜像列表:

   docker manifest create wj-other-proj/cooperation-plan-api:1.0.47 \
       wj-other-proj/cooperation-plan-api:1.0.47-amd64 \
       wj-other-proj/cooperation-plan-api:1.0.47-arm64

验证创建的镜像列表:

   docker manifest inspect wj-other-proj/cooperation-plan-api:1.0.47

推送多架构的镜像列表(可选):

   docker manifest push wj-other-proj/cooperation-plan-api:1.0.47

完整流程 构建和加载 AMD64 架构的镜像:

   docker buildx build --platform linux/amd64 -t wj-other-proj/cooperation-plan-api:1.0.47-amd64 . --load

构建和加载 ARM64 架构的镜像:

   docker buildx build --platform linux/arm64 -t wj-other-proj/cooperation-plan-api:1.0.47-arm64 . --load

创建多架构的镜像列表

   docker manifest create wj-other-proj/cooperation-plan-api:1.0.47 \
       wj-other-proj/cooperation-plan-api:1.0.47-amd64 \
       wj-other-proj/cooperation-plan-api:1.0.47-arm64

验证创建的镜像列表:

   docker manifest inspect wj-other-proj/cooperation-plan-api:1.0.47

推送多架构的镜像列表(可选):

   docker manifest push wj-other-proj/cooperation-plan-api:1.0.47

查看和导出镜像 查看本地镜像:

   docker images

应该能看到如下输出:

   REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
   wj-other-proj/cooperation-plan-api  1.0.47-amd64        sha256:xxxxxxxxxxxx  About an hour ago   123MB
   wj-other-proj/cooperation-plan-api  1.0.47-arm64        sha256:yyyyyyyyyyyy  About an hour ago   123MB
   

导出镜像: 如果需要导出单个架构的镜像,可以使用以下命令将其保存到文件中:

   docker save -o cooperation-plan-api-1.0.47-amd64.tar wj-other-proj/cooperation-plan-api:1.0.47-amd64
   docker save -o cooperation-plan-api-1.0.47-arm64.tar wj-other-proj/cooperation-plan-api:1.0.47-arm64

这样,你就可以成功构建并加载多架构的镜像,并创建一个多架构的镜像列表。