欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

深入浅出Docker1-6章学习笔记

时间:2023-07-21
docker深入浅出 docker概览

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 引擎

这章不影响使用,只讲原理,可以跳过

简介

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

一个镜像可以有多个不同的标签

过滤docker image ls内容

通过–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删除全部镜像

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。