【读书笔记】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 时不会生效,只会创建对应的空目录


相关内容

热门资讯

德乌将联合生产航程达1500公... 新华社基辅5月11日电 (记者李东旭)正在乌克兰首都基辅访问的德国国防部长鲍里斯·皮斯托里乌斯11日...
特朗普:与伊朗停火协议已“岌岌... 美国总统特朗普11日表示,目前与伊朗的停火协议正处于“岌岌可危”的状态。特朗普还称,将对伊朗取得“彻...
老人喝农药后医护误判死亡?官方... 近日,网传“我县一老人喝农药后医护人员未检查即认为老人已死亡”。对此,我县高度重视,立即成立由卫生健...
张凌赫、刘宇宁或被邀请赴台交流 5月11日,据中国新闻网报道,台北演艺经纪文化交流协会创会理事长王祥基表示,今年将力邀张凌赫、刘宇宁...
台湾演员赴陆偶遇“如花”高喊“... 据台媒TVBS,曾演出《破事精英第二季》的台湾演员萧子一,日前在中国大陆横店影视城巧遇景区知名NPC...
东盟“不选边”走到尽头? 第48届东盟峰会落幕,中东冲突外溢、美国关税施压、内部矛盾凸显,东盟陷入“经济要救生、安全走钢丝”的...
17岁高中生写作业至凌晨,外出... 5月11日,据青海大通县融媒体中心消息:大通县公安局表示,5月8日6时15分,大通县公安局桥头派出所...
天猫“国货严选”纯棉一次性内裤... 淘宝天猫国货严选旗舰店内一次性内裤宣称“纯棉”,“假一赔十”,实际收到商品为“100%聚酯纤维”。近...
字节砍掉30%的AI项目?背后... 来源:市场资讯 (来源:钛媒体APP) 5月9日,一则关于字节跳动AI战略的消息,在社交媒体上迅速发...
戴尔电脑频繁出现蓝屏死机、重启... IT之家 5 月 11 日消息,Windows 11 更新时常出故障并引发各类问题,其中最让用户恼火...