【读书笔记】08 | 白话容器基础(四):重新认识Docker容器
admin
2023-04-04 00:02:21
0次

《深入剖析Kubernetes - 08 | 白话容器基础(四):重新认识Docker容器》


1、Dockerfile 制作

制作rootfs 常用的方式:Dockerfile

# 使用官方提供的 Python 开发镜像作为基础镜像
FROM python:2.7-slim

# 将工作目录切换为 /app
WORKDIR /app

# 将当前目录下的所有内容复制到 /app 下
ADD . /app

# 使用 pip 命令安装这个应用所需要的依赖
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 允许外界访问容器的 80 端口
EXPOSE 80

# 设置环境变量
ENV NAME World

# 设置容器进程为:python app.py,即:这个 Python 应用的启动命令
CMD ["python", "app.py"]


注意事项:

1、ENTRYPOINT 和 CMD 为容器启动必需参数,docker会提供一个默认的ENTRYPOINT : /bin/sh -c ,故在不指定ENTRYPOINT 时,直接指定CMD,实际上执行的命令是/bin/sh -c CMD

2、ADD 和 COPY 的区别:ADD 可以如果添加的是一个压缩包,会自动解压,COPY不会

3、每个指令都会生成对应的镜像层,所以在写RUN的时候可以通过连接符写多个命令,避免产生过多的镜像层,例如:

RUN ln -s /data/services/nginx /usr/local/nginx && \
    mkdir -p /data/weblog/nginx && \
    /etc/init.d/nginx start

创建完dockerfile 通过以下命令构建镜像(在Dockerfile所在目录下)

# docker build -t test-images .

然后通过docker push 上传到镜像仓库

# docker tag test-images test/nginx:1.14.2 
# docker push test/nginx:1.14.2


也可以通过commit的方式创建容器镜像,具体做法如下;

docker exec -it 4ddf4638572d /bin/sh
# 在容器内部新建了一个文件
root@4ddf4638572d:/app# touch test.txt
root@4ddf4638572d:/app# exit

# 将这个新建的文件提交到镜像中保存
$ docker commit 4ddf4638572d geektime/helloworld:v2


docker commit 其实就是在容器起来后,加上最上层的读写层,还有原先镜像中的只读层构成镜像。其中只读层在宿主机上是共享的,不会占用额外空间。

根据联合文件系统,在镜像rootfs上做的任何更改都会在最上层先复制一层,再此基础上进行修改,也就是所谓的写时复制(copy on write)


2、docker exec 实现原理

宿主机上可以看到容器执行的进程,通过PS 看到进程pid后(假设为25686),在/proc/25686/ns 这个目录下,可以看到全部ns对应的文件

ls -l  /proc/25686/ns
total 0
lrwxrwxrwx 1 root root 0 Aug 13 14:05 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 ipc -> ipc:[4026532278]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 mnt -> mnt:[4026532276]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 net -> net:[4026532281]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 pid -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 pid_for_children -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 uts -> uts:[4026532277]


然后通过setns() 的系统调用,即可将进程加入到对应的ns中。

setns() 需要2个参数,第一个参数是要加入的namespace文件路径,如/proc/25686/ns/net;第二个参数是要执行的程序,如/bin/bash

当docker启动时指定--net=host,则容器启动时不会为进程启动network namespace,容器跟宿主机共享一个网络栈。


3、voluem实现机制

主要解决宿主机和容器之间文件互通的问题,例如:

(1) 宿主机上如何访问到容器产生的文件

(2) 容器怎么访问到宿主机上的文件

在docker上,可以通过以下两种方式实现

$ docker run -v /test ...
$ docker run -v /home:/test ...

第一种方式相当于在宿主机本地创建一个temp目录,再挂载到容器的/test目录

第二种方式则是将宿主机上的/home目录挂载到容器的/test目录


本质上是使用了linux的bind mount机制,其主要作用是允许将一个目录或文件而不是这块设备挂载到指定目录上。其原理是一个inode替换的过程,在linux中,inode存放的文件内容的对象,而dentry则存放的是指向这个对象的指针。故这个挂载的过程,实际上就是修改指针,指向另外一个inode,执行umount 时则将指针指向回原来的inode。

【读书笔记】08 | 白话容器基础(四):重新认识Docker容器


注意:

1、在挂载目录上做的操作并不会影响源目录

2、对于挂载目录的修改,执行docker commit 时不会生效,只会创建对应的空目录


相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...