Docker使用笔记

docker日常使用

# 使用别人的镜像

# 获取镜像

  • 如果是拉在Docker Hub注册的镜像,比如python的镜像

    1
    2
    3
    4
    
    # 明确tag
    docker pull python:3.9.0
    # 不明确tag默认为latest
    docker pull python
    
  • 如果是拉非Docker hub注册的公开镜像,比如elastic公司的logstash镜像

    1
    2
    
    # 镜像名构成:地址/命名空间/镜像名[:镜像tag]
    docker pull docker.elastic.co/logstash/logstash:7.6.0
    
  • 如果是拉非公开镜像,比如自己仓库的镜像

    1
    2
    3
    4
    
    # 先登录
    docker login xxx.xxx
    # 再拉镜像
    docker pull xxx.xxx/some_project/some_img:0.1.0
    
  • 如果镜像仓库不是https

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    # 修改/etc/docker/daemon.json
    # 添加 "insecure-registries":["192.166.1.23:5001"]
    
    # 重启docker
    systemctl restart docker
    
    # 登录
    docker login 192.166.1.23:5001
    
    # 再拉镜像
    docker pull 192.166.1.23:5001/some_project/some_img:0.1.0
    
  • 如果要运行的环境甚至不能联网

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 保存镜像
    docker save nginx -o nginx.tar
    
    # 拷贝到不能联网到机器
    # scp / u盘 / ...
    
    # 加载
    docker load -i nginx.tar
    
  • 总结

    是否docker hub注册镜像 是否公开镜像 镜像仓库是否为https 是否有网 使用方法
    ✔️ ✔️ ✔️ ✔️ docker pull python:3.9.0
    ✖️ ✔️ ✔️ ✔️ docker pull docker.elastic.co/logstash/logstash:7.6.0
    ✖️ ✖️ ✔️ ✔️ docker login + docker pull
    ✖️ - ✖️ ✔️ 修改daemon后操作
    - - - ✖️ docker save + docker load

# 自己构建镜像

# 构建镜像流程

  1. 写Dockerfile: 见下文
  2. docker build
    1
    2
    3
    4
    5
    6
    7
    8
    
    # 用名为Dockerfile的dockerfile
    docker build .
    
    # 指定dockerfile
    docker build . -f Dockerfile_test
    
    # build并打tag
    docker build . -t test:0.1.0
    
  3. docker tag
  4. docker push

# 编写Dockerfile

  • Dockerfile格式
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    # 基本格式:命令 参数
    
    ########################
    ###     拉基础镜像    ###
    ########################
    FROM golang:alpine
    #FROM ubuntu
    
    ########################
    ###      一番操作     ###
    ###  (以下为常见命令) ###
    ########################
    ## 设置镜像根目录
    WORKDIR /app
    ## 设置镜像内的环境变量
    ENV COMPANY=wudun
    ENV USER twomental
    ## 设置build阶段的参数
    ARG APP_NAME
    ARG APP_VERSION=0.1.0
    ## 运行命令
    RUN /bin/sh -c "echo $COMPANY"
    RUN ["/bin/sh", "-c", "echo $USER"]
    RUN echo $APP_NAME,$APP_VERSION
    ## 从目录里拷贝文件进镜像
    COPY entrypoint.sh .
    ## .dockerignore
    
    
    ########################
    ###  指定容器启动命令  ###
    ########################
    ## ENTRYPOINT(多个的话只运行最后一个)
    ENTRYPOINT /app/entrypoint.sh hello
    ENTRYPOINT ["/app/entrypoint.sh", "hello"]
    
    ## CMD(多个的话只运行最后一个)
    CMD ["echo", "$COMPANY"]
    CMD echo $USER
    
    ## ENTRYPOINT + CMD
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]
    
  • 例子
    • 解释型语言,以python项目为例
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      
      FROM python:3.7.2-alpine
      
      ENV LC_ALL="C.UTF-8" LANG="C.UTF-8"
      
      WORKDIR /app
      RUN set -ex && pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple
      RUN set -ex && pip3 install pipenv -i https://mirrors.aliyun.com/pypi/simple
      RUN apk update && apk add py3-zmq && apk add curl
      
      COPY Pipfile Pipfile.lock ./
      
      ONBUILD RUN set -ex && pipenv install --deploy --system
      # Install dependenciese, build and clean up. But keep c++ libs.
      RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
      RUN set -ex\
          && apk add --no-cache --virtual .build-deps \
          ca-certificates \
          gcc \
          linux-headers \
          musl-dev \
          libffi-dev \
          jpeg-dev \
          zlib-dev \
          && pipenv install --system --deploy --ignore-pipfile \
          && find /usr/local \
          \( -type d -a -name test -o -name tests \) \
          -o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) \
          -exec rm -rf '{}' + \
          && runDeps="$( \
          scanelf --needed --nobanner --recursive /usr/local \
          | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
          | sort -u \
          | xargs -r apk info --installed \
          | sort -u \
          )" \
          && apk add --virtual .rundeps $runDeps \
          && apk del .build-deps
      COPY . ./
      
      ENTRYPOINT [ "/app/entrypoint.sh" ]
      STOPSIGNAL SIGTERM
      
    • 编译型语言,以go项目为例
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      
      # 阶段一:用于编译
      FROM golang:alpine AS base
      
      WORKDIR /app
      COPY . .
      RUN go build -o server .
      
      # 阶段二:用于运行
      FROM alpine:latest
      
      WORKDIR /app
      COPY --from=base /app/server ./
      
      ENTRYPOINT ./server
      
  • 善用多阶段构建
    1
    2
    
    docker_test stage_1 5f953dcafb9c   About a minute ago   822MB
    docker_test stage_2 3c168da33a5a   About a minute ago   61.1MB
    

# 跨CPU架构build

# buildx

  • 适用场景:在x86的机器上build的镜像,希望能在arm的机器上跑起来
  • 步骤
    1. qemu: 开启arm平台支持
      1
      
      docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
      
    2. 安装buildx(以Ubuntu为例)
      a. 下载机器对应的二进制安装包: buildx-release
      b. 将其拷贝至$HOME/.docker/cli-plugins
      c. 确认安装成功: docker buildx version
    3. 初始化builder
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      # 新建一个builder instance, 
      #   名字叫arm(--name), 
      #   指定支持的平台(--platform), 
      #   指定driver(--driver), 
      #   使用(--use)
      docker buildx create \
          --name arm \
          --platform linux/arm64,linux/arm,linux/amd64 \
          --driver docker-container --use
      # boot并查看
      docker buildx inspect arm --bootstrap
      
      其中:
      • docker buildx create 用于新建builder
        • --name: 指定名称
        • --platform: 支持架构, 包括arm64、arm、amd64等(详见github
        • --use: 使用这个builder
      • docker buildx inspect 用于查看builder
    4. buildx
      1
      
      docker buildx build --platform linux/arm64 . -t $(IMG_NAME):$(TAG) -f Dockerfile --load
      
      其中:
      • docker buildx build用于build
        • --platform: 为哪些架构build
        • -t: tag
        • -f: dockerfile文件名
        • --load: 将build完的镜像加载到docker(不然只在缓存里,docker images找不到这个镜像)

# manifest

  • 适用场景:同一个tag的镜像,希望能在不同架构的设备上都能跑
  • 步骤
    1. build image
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      
      # build amd64
      docker buildx build . --load \
          -t ${IMG_NAME}:${IMG_VERSION}_amd64 \
          -f Dockerfile_amd64 \
          --platform linux/amd64
      # build arm64
      docker buildx build . --load \
          -t ${IMG_NAME}:${IMG_VERSION}_arm64 \
          -f Dockerfile_arm64 \
          --platform linux/arm64
      
    2. push image
      1
      2
      3
      4
      
      # push amd64
      docker push ${IMG_NAME}:${IMG_VERSION}_amd64
      # push arm64
      docker push ${IMG_NAME}:${IMG_VERSION}_arm64
      
    3. create manifest
      1
      2
      3
      
      docker manifest create ${IMG_NAME}:${IMG_VERSION} --amend \
          ${IMG_NAME}:${IMG_VERSION}_amd64 \
          ${IMG_NAME}:${IMG_VERSION}_arm64
      
    4. annotate manifest
      1
      2
      3
      4
      5
      6
      7
      8
      
      # anotate amd64
      docker manifest annotate ${IMG_NAME}:${IMG_VERSION} \
          ${IMG_NAME}:${IMG_VERSION}_amd64 \
          --os linux --arch amd64
      # anotate arm64
      docker manifest annotate ${IMG_NAME}:${IMG_VERSION} \
          ${IMG_NAME}:${IMG_VERSION}_arm64 \
          --os linux --arch arm64 --variant v8
      
    5. push manifest
      1
      
      docker manifest push ${IMG_NAME}:${IMG_VERSION}
      

# 运行容器

# 容器启动/停止

  • 启动容器:docker run
    • 用法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    • 常用options
      • —name:指定容器名称
      • —publish, -p: 绑定容器端口到主机特定端口
      • —volume, -v: 数据挂载
      • —env, -e: 设置容器内环境变量
      • —env-file: 用文件设置容器内环境变量
      • —restart: 容器重启规则
  • 同时启动多个容器:docker-compose
    • 小工具:composerize,翻译docker命令行为docker-compose
  • 容器停止:docker stop xxx
  • 容器重启:docker restart xxx / docker start xxx

# 容器查看

  • 查看运行中的容器:docker ps
  • 查看所有容器(包括运行的、停止的):docker ps -a
  • 查看容器日志:docker logs -f —tail 100 xxx
  • 查看容器/镜像信息:docker inspect xxx
  • 在容器里执行命令:docker exec
    • 用法:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    • 常用options
      • —-interactive, -i:进入交互

# 容器删除

  • 删除容器(容器已停止):docker rm xxx
  • 删除容器(容器未停止):docker rm -f xxx
  • 删除镜像(镜像未被使用):docker rmi xxx
  • 删除镜像(镜像正在被使用):docker rmi -f xxx
Built with Hugo
Theme Stack designed by Jimmy