k8s(二)理解Docker原理

297 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

Build,Ship and Run Any App,Anywhere

docker使用

  1. 通常在项目工程里使用Makefile文件,指定一系列的操作步骤;
  2. 通过docker build构建成一个可运行镜像;
  3. 使用docker push推送到指定的镜像仓库;
  4. 在任何可以连接镜像仓库的地方,拉取镜像并且运行:docker pull docker run

docker原理

基于Linux内核的Cgroup(资源限制),Namespace(隔离),以及UnionFS(文件系统)等技术,对进程进行封装隔离

  1. Namespace:对进程进行隔离,解决了进程之间的可见性问题。

    • 系统可以为进程分配不同的 Namespace,使进程能够拥有独立的运行环境,并且能够拥有网络与宿主机器进行通信。而container本质上是宿主机器上的一个进程;
    • 一个进程的Namespace信息以一个文件的形式存在于宿主机器上。
  2. Cgroup:对进程组资源进行限制及监控。(全称为control Group)

    • 保证不同的进程组资源独立分配、进程组彼此隔离,即不同的进程组下的进程互不干扰 。这些资源包括:主机名、用户权限、文件系统、网络、进程号、进程间通信。

    • 对进程的资源控制通常存在于/sys/fs/cgroup,每一个进程都会在这里存在一个单独的文件夹,文件夹下会存在各种资源的使用限制,可以修改里面的值进行相应的资源控制。

      [root@master cpu]# cd /sys/fs/cgroup
      # 创建文件夹
      [root@master cpu]# mkdir lomtom
      # 进入文件夹
      [root@master cpu]# cd lomtom
      [root@master lomtom]# ls
      cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
      cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks
      ...
      
      # 另起一个窗口,运行一个消耗cpu的程序(用写几个for循环即可)
      [root@master root]# cat > main.go << EOF
      package main
      
      func main() {
      	go func() {
      		for  {
      			
      		}
      	}()
      	go func() {
      		for  {
      			
      		}
      	}()
      	for  {
      		
      	}
      }
      EOF
      [root@master root]# go build ./main.go
      [root@master root]#./main
      
      
      # 查询该进程的进程号
      [root@master lomtom]# ps -ef|grep main|grep -v grep|awk '{print $2}'
      # 将进程号写入该文件夹下的cgroup.procs 
      [root@master lomtom]# echo 26630 > cgroup.procs 
      [root@master lomtom]# cat cgroup.procs 
      26630
      
      # 限制cpu使用率上限(10%)
      [root@master lomtom]# echo 10000 > cpu.cfs_quota_us 
      [root@master lomtom]# cat cpu.cfs_quota_us 
      10000
      

      限制前cpu占有率

    image-20220419100021909.png

    限制后cpu占有率

    image-20220419100236239.png

  3. 除此之外,还会对进程(也就是容器)切换根目录。并且docker镜像是以一层一层的结构构成,rootfs在原有的基础镜像(例如centos)增加自己所要执行的操作即在可读写层添加相应的层。

    并且,下一步操作如果与之前的操作冲突,将会覆盖之前的。例如我先创建一个文件config,然后我又重新写入config文件,那么最终保存的就是最后一次执行的config文件。

    echo 你好 > config
    echo 你快乐吗 > config
    

    最终在config中只有“你快乐吗”,这在日常的使用中也是这样的,所以这很好理解。

    对于docker镜像来说,Dockerfile的每一步操作都会生成一层可读写层,并且后来的操作也就是上层会覆盖下层,可以通过docker history [images ID],来查看镜像的层级结构。

    [root@master ~]# docker images
    REPOSITORY                                                        TAG                 IMAGE ID            CREATED             SIZE
    rancher/mirrored-flannelcni-flannel                               v0.17.0             9247abf08677        7 weeks ago         59.8MB
    
    [root@master ~]# docker history 9247abf08677
    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    9247abf08677        7 weeks ago         ENTRYPOINT ["/opt/bin/flanneld"]                0B                  buildkit.dockerfile.v0
    <missing>           7 weeks ago         RUN /bin/sh -c /iptables-wrapper-installer.s…   1.93kB              buildkit.dockerfile.v0
    <missing>           7 weeks ago         COPY dist/iptables-wrapper-installer.sh / # …   7.66kB              buildkit.dockerfile.v0
    <missing>           7 weeks ago         COPY dist/mk-docker-opts.sh /opt/bin/ # buil…   2.14kB              buildkit.dockerfile.v0
    <missing>           7 weeks ago         COPY dist/flanneld-amd64 /opt/bin/flanneld #…   39.8MB              buildkit.dockerfile.v0
    <missing>           7 weeks ago         RUN /bin/sh -c apk add wireguard-tools --no-…   2.63MB              buildkit.dockerfile.v0
    <missing>           7 weeks ago         RUN /bin/sh -c apk add --no-cache iproute2 n…   11.8MB              buildkit.dockerfile.v0
    <missing>           7 weeks ago         ENV FLANNEL_ARCH=amd64                          0B                  buildkit.dockerfile.v0
    <missing>           5 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
    <missing>           5 months ago        /bin/sh -c #(nop) ADD file:5a707b9d6cb5fff53…   5.62MB
    

    这样的一个好处是,当我在进行容器的分发时,发现底层层级没有发生改变时,那么每次发布只会发布改变的部分。