镜像:文件系统、层:发行版(只读、whileout)、共享、unionfs(分层、修改为一层、增量rootfs、每一层都挂载在宿主机相应的目录下、层次覆盖、继承)、rootfs+app+config+lib、完整依赖,
容器:init层(ro、wh、host信息(host属于只读镜像但用户常修改此值,并不希望提交,commit只提交可读可写层))+readwrite(数据修改发生在此,增、改变(copy on write)、删除(wo文件、遮挡只读层文件)、commit保存可读可写层而只读层不变,将读写层+镜像层打包为镜像,其中镜像层共享不占用空间),写时复制、限制资源及试图的进程。
优势:bootfs,rootfs,无guest os,
Client-Server结构的系统,Docker的守护进程。通过Socket从客户端访问!Docker-Server接收到Docker-Client的指令,就会执行这个命令
docker exec 开启一个新的终端,新的进程属于容器对应的namespace和cgroups但是其父进程是docker daemon而不是pin=1,一个进程的 Namespace 信息在宿主机上以一个文件的方式存在,可以选择一个进程并加入他说在的namespace,
attach 进入正在执行的终端。
pin=1进程收到结束信号,直接给其子进程发送kill信号后容器结束。
1docker system prune -f # 删除停止容器和网络和镜像
2docker image prune -a # 删除未被使用镜像
3docker volume prune -f # 删除空闲volune
4docker container run --rm -it image_name args # 创建的容器在使用结束后自动删除容器
CMD
与ENTRYPOINT
联合使用,ENTRYPOINT
设置执行的命令,CMD
传递参数:
x1ENTRYPOINT ["echo"]
2CMD []
3
4docker container run -it -rm image_name hello # 输出hello
pin=1:one process per comntainer,只有pid=1可控,init进程、守护进程、祖先、第一个用户态进程、管理、生命周期、信号、docker stop和kill(默认)发送sigterm(正常终止信号缺省行为退出,自定义handler资源清理、等待、sigkill,传播给子进程、优雅),kill -9强制,忽略(sigstop,sigkill除外)+捕获(自定义、sigstop,sigkill除外)+缺省,处理孤儿和回收僵尸进程(dumb-init三方)。
Kill:sig_ignore(内部调用&默认handler&目标为pin=0)则忽略信号,kill -9 1再容器内部不工作。kill 1:如果pin=1实现了堆sigterm的自定义则响应否则不响应。
正常停止容器:pin=1收到sigtrem(缺省行为是释放资源后退出),其他进程收到pin=1发出的sigkill强制结束。自定义pin=1的singterm的hander,向其他进程转发sigterm而非sigkill,资源清理,graceful shutdown。
shell格式:命令行格式、先启动shell再执行服务程序,pin=1线程为shell,sigterm,handler,未提供、等待,sigkill强制退出。exec格式:字符串集合、pin=0线程为目标程序,docker run命令行cmd使用exec格式。
僵尸进程:zombie->exit,结束、资源已释放,占据PID,等待父进程(直接父类)回收(父进程收到子进程结束信号、僵尸不想赢kill信号、wait()、waitpid)、父进程获取子进程退出信息(nginx)、资源泄露(PID)。父进程结束:孤儿进程、收养、init进程。
默认情形下,docker提供一个隐含的entrypoint:“/bin/sh -c”,如果不指定entrypoint,cmd内容就是entrypoint的参数:/bin/sh -c python app.py。Docker 容器的启动进程为 ENTRYPOINT,而不是 CMD。
/src/
,如果只写/src
会将src
当作文件,将文件复制到镜像中并重命名为src
。dockerfile
中的`VOLUME ["app"]
设置项是将主机目录挂载到容器中的目录app上,本机会自动创建一个随机名字的volume,去存储我们在Dockerfile定义的volume,默认在/var/lib/docker/volumes
下;命令行通过-v
可以可以手动的指定本机目录,以及对应于容器内的路径,这个路径是可以任意的,不必需要在Dockerfile里通过VOLUME定义。容器访问外网:veth-pair虚拟设备接口,成对出现的,一端连接一个namespace(veth_container放入容器network namespace,veth-host放入host network namespace,实现host通信);容器数据在网桥处进行网络地址转换(bridge+NAT,将veth-host加入docker0,容器+docker0构成子网),借助本地主机地址访问外网(容器-(veth-pair)->docker0-(nat)->eth0)。NAT用于解决IP地址不足的问题,给一系列设备分配私有IP,当他们想要访问外网时,利用NAT将私有发送地址转换为共有地址,同样当受到外界发送回来的数据是将目的IP转换为私有IP,相当于一些列设备公用一个IP地址。
容器默认连接到名称为bridge的bridge桥接网络(veth),bridge网络还连接本地主机端(eth)。一个容器可以连接到多个bridge上,拥有多个私有IP地址。
自定义的bridge可以实现DNS的功能(iptable),可以直接使用与该bridge连接的容器名直接通信,而默认bridge(docker0)未实现该功能。
xxxxxxxxxx
21docker network connect bridge_name container_name #连接
2docker network dis connect bridge_name container_name #断开连接
Network namespace隔离,IP地址,路由表。
host网路使用和主机一样的网络,类似于容器、主机使用相同网络设备,免去转换,提升性能(注意多个容器监听相同端口导致冲突)。none网络下的容器无法实现使用网络(内部、外部网络都无法使用,常用于容器编排)。
EXPOSE
并不是真正的暴露的端口,只是为了告诉使用者该容器应该暴漏该端口,在启动容器时要使用-p
暴漏端口。docker-compose up
重新启动服务,会自动更新发生修改的容器,未经过修改的容器不会被重启。如果某个容器对应的镜像发生改变需要手指指定build
参数:docker-compose up -d --build
重新构建镜像并重启容器。如果是删除镜像需要添加参数以删除多余的容器:docker-compose up -d --remove orphans
。当需要重启时使用docker-compose restart
重启所有服务。docker-compose up -d --scale flask=3
将名为flask
的服务扩展为3份,当通过服务名(DNS)连接flask时会将连接请求均分到三个服务,实现简单的发在均衡。${arg_name}
替换,再在相同文件夹下创建.env
文件,写入arg_name=abc
,在启动compose时会自动替换,可以使用docker-compose config
检查替换后的compose文件。depends_on
指定该服务依赖另一个服务,需要在依赖服务启动后再启动该服务。但是服务启动不代表能正常提供服务,可以设置健康检查,HEALTHCHECK
配置项,更细化检查指标。一组联合挂载在 /var/lib/docker/aufs/mnt 上的 rootfs(容器镜像、静态视图、开发者关注重点)+ 一个由 Namespace+Cgroups 构成的隔离环境,(容器运行时,动态视图)。
Master(负责api服务、调度、编排;如何编排、管理、调度用户提交的作业)+Node结构;kubelet 通过CRI(Container Runtime Interface)的远程调用接口负责同容器运行时打交道,gri接口定义了容器运行时的各项核心操作(通用性,不局限于docker),通过 OCI 这个容器运行时规范同底层的Linux 操作系统进行交互;gRPC 协议同一个叫作 Device Plugin 的插件进行交互,是 Kubernetes 项目用来管理 GPU 等宿主机物理设备的主要组件;通过CNI(Container Networking Interface)和CSI(Container Storage Interface)实现对网络和存储的管理。