Docker 基础知识点和命令

发布于 2024-08-01 18:29:49 字数 18146 浏览 22 评论 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技术交流群

发布评论

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

关于作者

顾冷

暂无简介

文章
评论
28 人气
更多

推荐作者

alipaysp_snBf0MSZIv

文章 0 评论 0

梦断已成空

文章 0 评论 0

瞎闹

文章 0 评论 0

寄意

文章 0 评论 0

似梦非梦

文章 0 评论 0

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