美文网首页
Docker基础

Docker基础

作者: Dakini_Wind | 来源:发表于2022-03-27 10:08 被阅读0次

有时候有些东西明明看过,面试还是想不起来,终归是纸上得来终觉浅。

Dockerfile

  • 结构

    • 基础镜像信息、维护者信息、镜像操作指令、容器启动时执行指令
  • 指令:

    FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD

    MAINTAINER:维护者信息

    RUN:在镜像基础上执行命令,提交为新的镜像

    CMD:容器启动时执行的命令,每个Dockerfile只能有一个,如果存在多个只执行最后一个

    EXPOSE:告诉服务器暴露的端口,供外部连接使用

    ENV:指定环境变量,后续可以被RUN使用,以及容器运行起来后使用

    ADD:拷贝来自远程URL或本地的文件、目录,支持通配符,自动解压压缩文件

    COPY:拷贝宿主机上的文件或目录

    ENTRYPOINT:用于配置容器启动后执行的命令,不能被docker run提供的参数覆盖,最后一个生效

    VOLUME:创建在本地主机或其他容易可以挂载的数据卷

    USER:指定容器运行的用户名或UID,在之前可以先用RUN创建需要的用户

    WORKDIR:为RUN CMD ENTRYPOINT指定工作目录,可以使用多个

    ONBUILD:命令出现的Dockerfile里不会执行指令,但被其他Dockerfile所引用的时候会执行

  • 镜像分层构建

    • Dockerfile中每个指令都会创建一个新的镜像层
    • 镜像层将会被缓存和复用
    • 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的缓存就会失效
    • 某一层的镜像缓存失效后,它之后的镜像层缓存就会都失效
    • 镜像层是不可变的,即便下一层删除某个文件,其镜像中仍然会包含该文件

原理

Namespce

主要用来做资源隔离。Linux内核共实现了以下几种Namespce:

  • UTS:表示不同的 namespace 可以配置不同的 hostname
  • User:表示不同的 namespace 可以配置不同的用户和组
  • Mount:表示不同的 namespace 的文件系统挂载点是隔离的
  • PID:表示不同的 namespace 有完全独立的 pid
  • Network:表示不同的 namespace 有独立的网络协议栈
  • IPC:表示不同的namespace有不同的IPC对象

查询Docker容器的Namespace信息如下:

# 获取容器ID
docker ps

# 获取容器对应的进程PID
docker inspect f604f0e34bc2

# 查询PID对应的ns信息
ls -l /proc/58212/ns 
lrwxrwxrwx 1 root root 0 Jul 16 19:19 ipc -> ipc:[4026532278]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 mnt -> mnt:[4026532276]
lrwxrwxrwx 1 root root 0 Jul 16 01:43 net -> net:[4026532281]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 pid -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jul 16 19:19 uts -> uts:[4026532277]

操作Namespace的方式如下:

# 进入指定的namespace
nsenter --target 58212 --mount --uts --ipc --net --pid -- env --ignore-environment -- /bin/bash

# 离开当前ns,并加入新的ns
unshare --mount --ipc --pid --net --mount-proc=/proc --fork /bin/bash

# 创建子进程,并将子进程放到新的ns中。父进程不变
# arg可选:CLONE_NEWUTS、CLONE_NEWUSER、CLONE_NEWNS、CLONE_NEWPID。CLONE_NEWNET
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);

# 将当前进程放到已有的ns中
# nstype 用来指定 namespace 的类型,可以设置为 CLONE_NEWUTS、CLONE_NEWUSER、CLONE_NEWNS、CLONE_NEWPID 和 CLONE_NEWNET
int setns(int fd, int nstype);

# 使当前进程退出当前的 namespace,并加入到新创建的namespace中
int unshare(int flags);

CGroups

全称Control Group,主要用来限制资源使用。CGroups定义了下面一系列子系统,每个子系统用于控制某一类资源:

  • cpu:限制进程的 cpu 使用率
  • cpuacct:统计 cgroups 中的进程的 cpu 使用报告
  • cpuset:为 cgroups 中的进程分配单独的 cpu 节点或者内存节点
  • memory:限制进程的 memory 使用量
  • blkio:限制进程的块设备 io
  • devices:控制进程能够访问某些设备
  • net_cls:标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。
  • freezer:可以挂起或者恢复 cgroups 中的进程

在 Linux 上,为了操作 Cgroup,有一个专门的 Cgroup 文件系统,位于/sys/fs/cgroup/目录下。目录结构如下所示:

drwxr-xr-x 5 root root  0 May 30 17:00 blkio
lrwxrwxrwx 1 root root 11 May 30 17:00 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 May 30 17:00 cpuacct -> cpu,cpuacct
drwxr-xr-x 5 root root  0 May 30 17:00 cpu,cpuacct
drwxr-xr-x 3 root root  0 May 30 17:00 cpuset
drwxr-xr-x 5 root root  0 May 30 17:00 devices
drwxr-xr-x 3 root root  0 May 30 17:00 freezer
drwxr-xr-x 3 root root  0 May 30 17:00 hugetlb
drwxr-xr-x 5 root root  0 May 30 17:00 memory
lrwxrwxrwx 1 root root 16 May 30 17:00 net_cls -> net_cls,net_prio
drwxr-xr-x 3 root root  0 May 30 17:00 net_cls,net_prio
lrwxrwxrwx 1 root root 16 May 30 17:00 net_prio -> net_cls,net_prio
drwxr-xr-x 3 root root  0 May 30 17:00 perf_event
drwxr-xr-x 5 root root  0 May 30 17:00 pids
drwxr-xr-x 5 root root  0 May 30 17:00 systemd

Docker操作CGroups的方式如下图所示:


操作cgroup

实践技巧

  • 如何借助宿主机上工具排查问题?考察命名空间

    kubectl debug、nsenter

参考:
构建Docker镜像的原理_人人都是酸菜鱼又酸又菜又多余的博客-CSDN博客_docker镜像构建原理
uufree/ubook: 读书笔记 (github.com)

相关文章

网友评论

      本文标题:Docker基础

      本文链接:https://www.haomeiwen.com/subject/vdnejrtx.html