Docker 基础知识点和命令

发布于 2024-08-01 18:29:49 字数 18146 浏览 14 评论 0

Docker 相关基础

配置

基础知识

  • docker-compose 中的 depends_on 会依据依赖顺序启动服务,被 depends_on 的容器会先启动,但是主动 depends_on 的容器不会等到被 depends_on ,例如下面的例子:db,redis 容器启动顺序要优先于 web 容器;当启动 web 容器时会自动创建 redis 和 db 容器.不过需要注意的是,depends_on 不会等到 db 和 redis 容器 ready 再启动,web 容器仅仅等到 redis 和 db 容器启动就开始启动.具体可参考 官网启动顺序 了解
version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

dockerignore

和 gitignore 一样,用于忽略掉部分不需要的文件,用于加快传输文件到 docker 上下文。写法有很多种:

  • 将部分 build 不需要的文件写入 dockerignore 文件:这个是按需排除不需要的文件
  • 仅将 build 需要的文件写入 dockerignore 文件:反向思考,参考例子是 apache-airflow 的 dockerignore
# Ignore everything
**

# Allow only these directories
!airflow
!common
!dags
!dev
!docs
!licenses
!scripts
!tests

基础命令

run

ps

  • docker ps : 查看正在运行的容器
  • docker ps -a : 查看全部容器包括已经退出的容器
  • docker ps -s : 查看正在运行的容器信息( 包括大小 )

cp

Copy files/folders between a container and the local filesystem.

  • docker cp src container:dest : 从宿主机复制文件/文件夹到 docker 容器
  • docker cp container:src dest : 从 docker 容器复制文件/文件夹到宿主机

network

  • 查看 network 下的 Containers 的具体内容 docker network inspect --format='{{range .Containers}}{{println .Name}}{{end}}'
  • 清除一个 network 中的所有 active endpoints: docker network inspect --format='{{range .Containers}}{{println .Name}}{{end}}' <network_name> | xargs -I % echo 'docker network disconnect <network_name> %' | sh

inspect

用于查看对象详细信息

  • --format : 详见 Format command and log output
    • join : concatenates a list of strings to create a single string
    • json : encodes an element as a json string
    • lower : transforms a string into its lowercase representation
    • split : slices a string into a list of strings separated by a separator
    • title : capitalizes the first character of a string
    • upper : transforms a string into its uppercase representation
    • println : prints each value on a new line

system

  • docker system prune : clean up all images, containers, networks, volumes not used, offical-system
  • docker system prune -a --volumes : clear all including volumes, 只要是没有 container 使用的 volumes 都会被清除,这可能会带来关键数据丢失的问题,使用前请注意

tag

基本命令

docker-basic-command

  • 进入 docker 容器 docker exec -it container_name bash
  • docker 删除虚悬镜像 docker rmi $(docker images -f dangling=true)
  • 删除所有停止/退出镜像 docker rm $(docker ps -aq -f status=exited) -f 是过滤参数
  • docker-compose 运行指定 yml 文件 docker-compose -f docker-compose-file.yml up -d
  • 用 docker-compose 部署的时候如果要先 build 一些东西的话,可以直接在 service 下面放一个 build 任务,部署的时候用 docker-compose up --build 如果没有 --build 的话就会引用已经存在的镜像,没有更新到
  • docker 格式化 ps 输出 docker ps -format 'table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}' 这是 docker ps 的原生输出,format 后面的 table 是格式化输出成表格
  • docker-compose 重启单个 workerHow to restart a single container with docker-compose : docker-compose restart worker 可以设置时间等待杀死容器 docker-compose restart -t 30 worker
  • docker-compose 停止其中一个容器: docker-compose stop service-name
  • docker-compose 通过 scale 来创建多个容器: docker-compose version 2 docker-compose scale service_a=3; docker-compose scale service_b=3 会生成 3 个 service_a 和 3 个 service_b, 如果 docker-compose version 3 的话要达到同样的效果要 docker-compose up -d --scale service_a=3 --scale service_b=3 --no-recreate 而不能单独的运行 docker-compose up -d --scale <service_name>=3 这个会只生成 3 个 service_name 容器
  • 将本机容器制作导出: docker save IMAGE | gzip > LOCAL_IMAGE.gz ,将导出的镜像导入: docker load -i LOCAL_IMAGE.gz

网络相关

Dockerfile

multi-stage build

Dockerfile 的 multi-stage build 属性允许你创建更小的镜像,更好的使用 cache,为每个特定的镜像编写更加小的 entrypoint,了解更多查看 这里

# 在 dockerfile 文件中指定镜像的版本 可以在构建镜像时使用 `--build-arg UBUNTU_VERSION=value` 修改镜像的版本
# 如果么有传对应的值 则会以默认的版本(18.6) 进行构建
ARG UBUNTU_VERSION=18.6

# 可以对当前的 stage 进行别名方便后面的 stage 调用
FROM ubuntu:${UBUNTU_VERSION} AS base
RUN apt-get update && apt-get install git

# 可以从之前的 stage 中来
FROM base AS src1
RUN git clone …

FROM alpine
# --from 可以直接从已有的镜像中拿对应的值
# 也可以使用之前已经完成的 stage,如 `--from=base`
COPY --from=linuxkit/ca-certificates / /

# 可以使用更加有意义的别名 如对 release 镜像衍生出 dev-env test 镜像分别用于开发和测试
FROM scratch AS release
FROM golang:alpine AS dev-env
COPY --from=release / /
ENTRYPOINT ["ash"]
FROM golang:alpine AS test
COPY --from=release / /
RUN go test …

先编译然后复制编译后的值

FROM nodejs as builder
WORKDIR /usr/src/app
COPY . .
RUN npm build

FROM nginx
COPY --from=builder /usr/src/app/build/ /nginx_home

docker-compose

docker-compose 汇总

  • docker-compose up -d --no-build : docker-compose 启动但是不重新 build 镜像

ulimits

指定容器的 ulimits 限制值。例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)

  ulimits:
    nproc: 65535
    nofile:
      soft: 20000
      hard: 40000

example

docker FAQ

  • Cannot install packages inside docker Ubuntu image : should apt-get -qq update first, because no package cache in the image
  • docker-mysql 用数据卷自定义配置之后 connect mysql 会变慢,可以在自定义配置文件 section mysqld 增加 skip-name-resolve 选项
  • docker-mysql 自定义文件编码 section mysql & client default-character-set=utf8 并且 section mysqld character-set-server=utf8
  • docker Hub Automated Build with specify tag
  • docker build 如果上一次运行成功,下次再运行会直接使用 cache, docker build --no-cache 可以指定不使用 cache, How to force docker for clean build of an image
  • docker 默认的 registry 地址 https://index.docker.io/v1/ ,可以通过 docker info | grep -i registry 得到 docker 中所有的信息.如果国内镜像仓库中部分镜像没有更新(例如自己编译的镜像没有及时更新), docker pull registry.hub.docker.com/library/busybox

不要以 root 用户运行容器

docker 的其中一个最佳实践就是不要已 root 用户运行容器,因为容器中的 root 和宿主机中的 root(uid 0) 是同一个,这意味着在容器用户可以对宿主机文件目录进行读写,这样会导致很多可能的问题.相见 这里

docker 模拟网址

play-with-docker : t’s an online playground where you can test all the latest Docker features without having to install anything locally

docker 中中文乱码

进入对应 image 生成的容器中,输入 locale 查看支持什么编码, C.UTF-8 以及 zh_CN.UTF-8 都可以,但是大部分 docker 镜像都只有 C.UTF-8 ,之后在 dockerfile 中增加一行 ENV LANG C.UTF-8 即可,如果还不行就增加

ENV LANGUAGE C.UTF-8
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV LC_CTYPE C.UTF-8
ENV LC_MESSAGES C.UTF-8

docker 开放远程 API 调用

  • 开启 docker 远程调用 API 端口
    • MAC: 根据 docker/for-mac:ISSUE-770 ,默认不开启远程调用端口,可以 fork 一个容器开启端口 docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 bobrik/socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock ,然后 export DOCKER_HOST=unix:///var/run/docker.sock
    • Linux:
    • Windows: 点击 docker 图标,在 设置->通用 选项勾选 Expose daemon on tcp://localhost:2375 without TLS
  • 在 docker-deamon 运行的机器中,检查端口是否开放 netstat -anp | grep 2375 或者 lsof -i:2375
  • 在 docker-deamon 运行的机器中,检查能否通过 tcp 访问 docker-deamon, docker -H tcp://localhost:2375 images
  • 在需要调用 remote-api 的机器检查 2375 端口是否开启, telnet <IP>:2375 ,如果上面都能成功倒是这步不成功,就是服务器防火墙没有开放 2375 端口,开放端口即可

pycharm 中使用 docker 中的解释器

参照 Configure a remote interpreter using Docker ,需要根据 docker 开放远程 API 调用 先启动远程调用端口,然后新增配置解释器配置.如果是离线的话需要 busybox:latest 以及 pycharm_helper:PY-<对应的版本号>

docker build 时 apt-get 的速度慢的解决办法

和本机 apt-get 慢是同一解决办法,使用国内的源,使用的方式参考 tenxcloud/docker-debian ,将国内源写入 sources.list 文件,使用时在 Dockerfile 中使用 COPY sources.list /path/to/docker_sources.list 替换原来的源,最后在 RUN 中运行 apt clean \ && apt update

docker build 中需要使用代理下载

docker 在本地 build 的时候可能需要下载需要翻墙的二进制包,可以参考 SO ,在 docker 的 configure 中配置 proxy 属性,然后重启 docker 就能使用了。如果是 mac 客户端的话,可以在 Prefrences -> Resources -> PROXIES 开启手动代理配置,然后重启 docker

docker build 时 COPY ADD 提示文件不存在

相关的[SO][]可能原因如下:

  • 文件路径写错:文件路径可能比较复杂,导致本地路径写错。此时修改成正确路径即可
  • 运行 docker build 的路径错了:本应该在指定路径运行 docker build 的,但却在别的路径下运行了。此时切换到正确的路径即可
  • dockerignore 文件错误:要 COPY/ADD 的文件在 dockerignore 文件中,或者 dockerignore 仅允许指定文件发送到 docker 上下文中。此时检查 dockerignore 的配置然后修改即可

docker-compose 运行时发现 COMPOSE_HTTP_TIMEOUT

更加可配置地方案是,编辑 .env 文件,加入 COMPOSE_HTTP_TIMEOUT=200 项目 SO

MAC 配置 2375 端口可以登录

docker 的 mac 默认不启动 2375 端口, 参考 ,方便的方式是直接写一个快捷方式到 zshrc

alias docker-api-start='docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:1234 --name docker-api bobrik/socat TCP-LISTEN:1234,fork UNIX-CONNECT:/var/run/docker.sock'
alias docker-api-stop='docker rm -f docker-api'

Tips

  • 当遇到部分 Dockerfile 没有办法没有正确写出来的时候,可以去 github 搜索一下 base images + pkg_to_install
  • 当遇到本地 docker build 过慢时,可以将 Dockerfile 放到 github 上,然后在 docker hub 上设置对应 automated-build 当提交到 github master 上后就会自动 build
  • 如果从国内镜像中 pull 镜像失败,可以直接去 dockerhub 官网拉取 docker pull registry.hub.docker.com/zhongjiajie/docker-airflow
  • centos7 安装 docker 之后可能出现不能打开端口的情况,根据 configure Centos7 firewallD to allow docker containers free access to the host's network ports
    • firewall-cmd --permanent --zone=trusted --change-interface=docker0
    • firewall-cmd --permanent --zone=trusted --add-port=4243/tcp
    • firewall-cmd --reload
    • systemctl restart docker.service

script

一些 docker 相关的 shell 脚本

  • 删除 dangling 镜像和停止的容器
    echo "remove dangling images"
    if [[ ! -z $(docker images -f dangling=true -aq) ]]; then
      docker rmi $(docker images -f dangling=true -aq)
    fi
    echo "remove extied container"
    if [[ ! -z $(docker ps -aq -f status=exited) ]]; then
      docker rm -f $(docker ps -aq -f status=exited)
    fi
    
  • 备份非 dangling 的容器
    echo "backup not dangling images"
    

Ref

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

顾冷

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

无远思近则忧

文章 0 评论 0

久伴你

文章 0 评论 0

萌无敌

文章 0 评论 0

新一帅帅

文章 0 评论 0

莫多说

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文