略
docker安装 启动Hyper-V和容器特性 开始菜单-设置-搜索并选择“启用或关闭windows功能”-勾选Hyper-V和容器没有的话参考这个blog去官网下载安装,结束以后重启如果提示WSL2有问题,去这里下载更新输入docker verison,如果有类似消息
Client: Cloud integration: v1.0.22 Version: 20.10.12 API version: 1.41 Go version: go1.16.12 Git commit: e91ed57 Built: Mon Dec 13 11:44:07 2021 OS/Arch: windows/amd64 Context: default Experimental: trueServer: Docker Engine - Community Engine: Version: 20.10.12 API version: 1.41 (minimum version 1.12) Go version: go1.16.12 Git commit: 459d0df Built: Mon Dec 13 11:43:56 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.12 GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d runc: Version: 1.0.2 GitCommit: v1.0.2-0-g52b36a2 docker-init: Version: 0.19.0 GitCommit: de40ad0
开始玩吧
ubuntu安装sudo apt install docker.io
存储驱动可以通过docker system info查看
... Storage Driver: overlay2...
每个docker主机只能选择一种存储驱动linux下修改/etc/docker/daemon.json,重启生效,不能在运行时修改,否则可能会找不到原有镜像和容器(改回原有驱动可恢复)如果想要切换存储引擎后继续使用原有镜像和容器,可将镜像保存在docker格式,上传到仓库后,修改本地docker引擎并重启,然后拉取到本地默认情况下device mapper使用loopback mounted sparse file作为底层实现,如果想提升docker在生产环境中的性能,需要修改为direct-lvm。该模式使用基于裸块设备(row block device)的LVM精简池来提升性能,具体太高深了,我不看 纵观docker 运维视角
docker有两个组件,客户端和docker daemon(服务端或引擎)
默认安装时client和daemon通过本地socket进行通信/var/run/docker.sock,windows则通过npipe:./pipe/docker_engine的管道进行通信
可以通过docker version查看client和server,运行docker version,显示如下:
Client: Version: 20.10.7 API version: 1.41 Go version: go1.13.8 Git commit: 20.10.7-0ubuntu5~20.04.2 Built: Mon Nov 1 00:34:17 2021 OS/Arch: linux/amd64 Context: default Experimental: trueServer: Engine: Version: 20.10.7 API version: 1.41 (minimum version 1.12) Go version: go1.13.8 Git commit: 20.10.7-0ubuntu5~20.04.2 Built: Fri Oct 22 00:45:53 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.5.5-0ubuntu3~20.04.1 GitCommit: runc: Version: 1.0.1-0ubuntu2~20.04.1 GitCommit: docker-init: Version: 0.19.0 GitCommit:
如果提示缺少server权限,执行sudo chmod 666 /var/run/docker.sock,后重新查看
建议把docker加入sudo用户组,参考这个
可以理解为包含OS文件系统和应用的对象,指未运行的容器,可以理解为代码中的class,使用docker image ls查看镜像。每个镜像有自己的唯一ID
参考demo拉取镜像并运行
启动容器docker container run -it alpine /bin/sh
使用Ctrl+PQ挂起容器
使用docker container ls查看运行状态容器
使用docker container exec -选项 容器名/ID shell名连接到容器
挂起容器时,可以使用docker container stop和docker container rm来停止并杀死容器
这两个指令的区别在于,stop发SIGTERM信号给容器并等待容器关闭,rm发送SIGKILL强制关闭 开发视角
实例参考配套资源
查看dockerfile cat Dockerfile
# Test web-app to use with Pluralsight courses and Docker Deep Dive book# Linux x64FROM alpineLABEL maintainer="nigelpoulton@hotmail.com"# Install Node and NPMRUN apk add --update nodejs nodejs-npm# Copy app to /srcCOPY 、/srcWORKDIR /src# Install dependenciesRUN npm installEXPOSE 8080ENTRYPOINT ["node", "./app.js"]
其中每一行都是构建镜像的命令,使用docker build -t test:latest .根据dockerfile构建镜像,必须在包含应用代码和Dockerfile的目录下执行这条命令,结果:
Sending build context to Docker daemon 10.24kBStep 1/8 : FROM alpine ---> c059bfaa849cStep 2/8 : LABEL maintainer="nigelpoulton@hotmail.com" ---> Running in 7a3f72be141cRemoving intermediate container 7a3f72be141c ---> 829496dc94f4Step 3/8 : RUN apk add --update nodejs nodejs-npm ---> Running in 0fcb5c6173d8fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gzfetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gzERROR: unable to select packages: nodejs-npm (no such package): required by: world[nodejs-npm]The command '/bin/sh -c apk add --update nodejs nodejs-npm' returned a non-zero code: 1
却少包,这个问题在ubuntu上不好搞,把dockerfile里nodejs-npm改成npm,有警告但是可以编过。启动镜像
docker run -d --name web1 --publish 8080:8080 test:latest`
ifconfig查看docker IP,浏览器输入IP:8080看到Hello Pluralsighters!!!
这就是应用构建到容器的过程
这章不影响使用,只讲原理,可以跳过
简介docker引擎主要有client、守护进程daemon、containerd以及runc
详解整体架构:
client:docker命令daemon:API和其他特性containerd:容器supervisor,开启,停止等生命周期管理,不能push和pullshim:启动无守护进程容器runc:容易运行时,OCI规范的参考实现,轻量的对libcontainer进行封装的命令行交互工具运行容器
K8s通过cri-containerd使用containerd
容器启动过程:输入命令docker run --name ctr1 -it alpine:latest shclient将命令转换为合适的API格式,发送给正确的API端点daemon实现API,接受指令后指示containerd启动新容器,通过gPRC与containerd进行通信containerd将docker镜像转换为OCI bundle(镜像),指示runc创建容器runc与操作系统内核通信,基于必要工具创建容器,容器进程作为runc子进程启动,启动后runc退出,但是关联的containerd-shim进程会成为容器父进程,其职责为:
保持STDIN和STDOUT流开启,从而当daemon重启的时候,容器不会因为pipe关闭终止
将容器退出状态反馈给daemon
daemon的功能:镜像管理、镜像构建、REST API、身份验证、安全、核心网络与编排
docker 镜像 简介可以理解为class,常见仓库为docker hub,镜像由多个层组成,每层叠加形成一个独立的对象。镜像内部是一个精简的操作系统,同时包含应用运行必须的文件和依赖包。
详解 镜像是一种build-time结构,容器是一种run-time结构
通常用docker container run和docker service create从镜像启动一个或多个容器
容器启动后,而这就变成相互依赖的关系,在镜像上启动的容器全部停止前,镜像是无法删除的
通常docker镜像只有一个精简的shell甚至没有shell,镜像不包含内核
容器可以共享宿主机内核
linux本地镜像位于/var/lib/docker/overlay2,使用docker image pull 仓库:tag拉取镜像
镜像仓库 类似于git,默认为docker hub,不指定tag时默认拉取latest,latest不一定是最新的
从非官方账户拉取时docker image pull 账户/仓库:tag
从第三方镜像服务仓库拉取docker pull URL/账户/仓库:tag
一个镜像可以有多个不同的标签
通过–filter参数来过滤,例如悬需镜像docker image ls --filter dangling=true
没有标签的镜像被称为悬虚镜像,当为新镜像打一个旧镜像已经使用过的标签时,标签会生效到新镜像,旧镜像成为悬虚镜像
可以通过docker image prune移除所有悬虚镜像,添加-a移除没有被容器使用的镜像
docker支持的过滤器:
dangling:true or false,仅返回悬虚或者非悬虚镜像before:镜像名或ID,返回之前的所有镜像since:同上,返回之后label:根据label过滤,ls默认不现实label
其他的过滤方式可以使用reference
通过CLI方式搜索Docker Hub docker search命令允许通过CLI的方式搜索Docker Hub,可以通过NAME进行匹配,例如docker search nigelpoulto
结果有点长我就不放了,可以使用--filter "is-official=true"过滤官方镜像。可以使用--limit指定行数,默认结果只有25行
docker镜像由一些松耦合的只读镜像层组成,执行docker image pull ubuntu:latest的输出:
latest: Pulling from library/ubuntu08c01a0ec47e: Pull complete Digest: sha256:669e010b58baf5beb2836b253c1fd5768333f0d1dbcb834f7c07a4dc93f474beStatus: Downloaded newer image for ubuntu:latestdocker.io/library/ubuntu:latest
Pull complate那行在结束前显示的为pull fs layer,还可以通过docker image inspect ubuntu:latest查看镜像分层
... "RootFS": { "Type": "layers", "Layers": [ "sha256:36ffdceb4c77bf34325fb695e64ea447f688797f2f1e3af224c29593310578d2" ] },...
所有docker镜像都起始于一个基础镜像层,例如基于Ubuntu16.04创建一个镜像,就是第一层,然后给镜像添加Python包,就是第二层,继续添加一个安全补丁,就会创建第三层。更新底层添加的文件也需要创建新的层。
共享镜像层如果存在本地文件,在拉取镜像时有的layer会提示Alread exists,docker通过这种方式实现共享镜像层
根据摘要拉取镜像 由于标签可变,还可能多个镜像打同一个标签,可以通过镜像摘要(Image Digest)区分。
每个镜像都有一个基于内容的散列值,这里用摘要代指这个值,通过docker image ls --digests alpine查看
目前只支持拉取到本地后查看摘要,然后执行docker image pull apline@sha256:散列值拉取制定镜像
镜像是一系列松耦合的独立层的集合,镜像的唯一标识是一个加密ID,每个镜像层也有一个加密ID区分。由于拉取过程中需要压缩,会改变内容和散列值,相应地docker hub会提供一个分发散列值,这是一个压缩版镜像的散列值,用于校验
多架构的镜像 即一个镜像标签之下可以支持多个平台和架构。为了实现这个特性,镜像仓库API支持两种重要的结构:Manifest列表和Manifest
Manifest列表指某个镜像标签支持的架构列表,支持的每种架构都有自己的Mainfest定义
假设要在Raspberry Pi(基于ARM架构的Linux)上运行Docker,拉取镜像时,Docker client会调用Docker Hub镜像仓库的API完成拉取,如果镜像有Manifest列表,并且存有Linux on ARM这一项,则Dcoker Client就会找到ARM架构对应的Manifest并解析出组成该镜像的镜像层加密ID,然后从Docker Hub二进制存储中拉取每个镜像层
所有官方镜像都支持Manifest列表
docker image rm ID,只能删除没有运行状态容器的镜像
docker image rm $(docker image ls -q) -f删除全部镜像