docker学习笔记

容器化 | 使用 Alpine 构建 Redis 镜像 上一期我们介绍了几种常见的构建镜像方式,并给出了功能对比、决策树等作为选型参考。本期我们将演示如何使用 Alpine 构建一个 Redis 镜像。 Alpine 系统使用 apk 包管理工具,文中相关 apk 使用技巧不再赘述。 我们将构建镜像 Dockerfile 中的几个部分单独讲解,最后提供一个完整的 Demo。重点在如何使用 Alpine,Redis 镜像构建步骤此文不详细介绍。 文章大纲: 更换镜像源 构建镜像所需软件 启动服务 调整时区 包含 1- 4 的完整镜像构建 Demo 更换镜 阅读详情

1. Docker简介

由go语言开发,基于Linux内核的cgroup、namespace等技术,对进程进行封装隔离。属于操作系统层面的虚拟化技术。

传统的虚拟机通过在宿主主机中运行 hypervisor 来模拟一整套完整的硬件环境,在其上运行一个完整操作系统,再在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

前者具有以下优点:

  • 更高效的系统资源利用率
  • 更快的启动时间
  • 通过Dockerfile快速进行镜像构建,更轻松的迁移和部署交付

在这里插入图片描述
在这里插入图片描述

2. 基本概念

2.1 Dokcer镜像

一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像利用Union FS技术,被设计为分层存储的架构,由多层文件系统组层,可以运行docker info查看当前Union FS 类型
在这里插入图片描述
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。分层存储的特征使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

2.2 容器

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为 容器存储层。任何保存于容器存储层的信息都会随容器删除而丢失。所有的文件写入操作,都应该使用 数据卷(Volume)、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

2.3 仓库

如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,这就是Docker Registry。与git类似,一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。最常使用的 Registry 公开服务是官方的 Docker Hub。还有一些功能丰富的开源的仓库,例如 harbor

2.4 Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction)表明如何构建镜像,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。每一层构建的最后一定要清理掉无关文件,避免制作出很臃肿的镜像。

主要命令包括(https://docs.docker.com/engine/reference/builder/#from):

  • FROM 就是指定 基础镜像。若不存在基础镜像,则使用FROM scratch。 RUN 指令是用来执行命令行命令的。

  • COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

  • ADD与COPY类似,支持自动解压缩等功能,不支持缓存

  • CMD 指令就是用于指定默认的容器主进程的启动命令的,只能指定一个,否则后面的会覆盖前面的

    CMD <命令>
    # 或
    CMD ["可执行文件", "参数1", "参数2"...]
    
  • ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令

    CMD ["参数1", "参数2"...]
    ENTRYPOINT <命令>
    
  • ENV设置环境变量

    ENV <key> <value>
    ENV <key1>=<value1> <key2>=<value2>...代码片
    
  • ARG也是设置环境变量,但相比ENV,其设置的构建环境的环境变量,在将来容器运行时不存在。

  • VOLUME设置数据卷

    VOLUME ["<路径1>", "<路径2>"...]
    VOLUME <路径>
    
    VOLUME /data
    docker run -d -v mydata:/data xxxx
    
  • EXPOSE 暴露端口,其只是声明,并不会自动进行端口暴露,需要在运行时使用 -p <宿主端口>:<容器端口>

    EXPOSE <端口1> [<端口2>...]
    
  • WORKDIR 指定工作目录(或者称为当前目录)。每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。因此不同层间需要改变目录则需要使用该命令

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    
    RUN pwd  # /a/b/c
    
  • USER 指令和 WORKDIR 用法相似,用于指定用户。

    USER <用户名>[:<用户组>]
    
  • ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

    FROM node:slim
    RUN mkdir /app
    WORKDIR /app
    ONBUILD COPY ./package.json /app
    ONBUILD RUN [ "npm", "install" ]
    ONBUILD COPY . /app/
    CMD [ "npm", "start" ]
    
  • LABEL 指令用来给镜像以键值对的形式添加一些元数据

    LABEL <key>=<value> <key>=<value> <key>=<value> ...
    

多阶段构建镜像

FROM golang:1.9-alpine as builder   # as命令为某阶段命名

RUN apk --no-cache add git

WORKDIR /go/src/github.com/go/helloworld/

RUN go get -d -v github.com/go-sql-driver/mysql

COPY app.go .

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest as prod

RUN apk --no-cache add ca-certificates

WORKDIR /root/

COPY --from=0 /go/src/github.com/go/helloworld/app .  # 从第一个镜像中复制文件

CMD ["./app"]

单独运行某阶段

$ docker build --target builder -t username/imagename:tag .

2.5 容器网络

当 Docker 启动时,会自动在主机上创建一个 docker0 虚拟网桥( 参考1,参考2),实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0 接口。比如典型的 172.17.42.1,掩码为 255.255.0.0。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。
当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
在这里插入图片描述

3. 常用命令

3.1 镜像相关

从仓库拉取镜像

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

列出镜像

docker image ls [仓库名[:标签]] [选项]

查看镜像、容器、数据卷占用的使用空间

docker system df

查看并消除虚悬镜像(dangling image)

docker image ls -f dangling=true
docker image prune

删除本地镜像
删除行为分为两类,一类是 Untagged,另一类是 Deleted。镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。当删除指定标签镜像时,若还有别的标签指向这个镜像,则为 Untagged,此时并不会真正删除镜像。

docker image rm [选项] <镜像1> [<镜像2> ...]

在这里插入图片描述

将容器保存为镜像

docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

$ docker commit \
    --author "zjw" \
    --message "修改了默认网页" \
    webserver \
    nginx:v2

查看当前镜像内历史记录

docker history <镜像>

构建镜像
Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具(例如命令行),客户端调用远程服务进行各种操作。当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。

docker build [选项] <上下文路径/URL/->

$ docker build -t nginx:v3 .

#基于git构建
$ docker build -t hello-world https://github.com/docker-library/hello-world.git#master:amd64/hello-world

#基于压缩包构建
$ docker build http://server/context.tar.gz

3.2 容器相关

新建容器并启动
检查本地是否存在指定的镜像,不存在就从公有仓库下载

1.利用镜像创建并启动一个容器
2.分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
3.从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
4.从地址池配置一个 ip 地址给容器
5.执行用户指定的应用程序
6.执行完毕后容器被终止

docker run -it ubuntu:18.04 /bin/bash  #获取用户交互
docker run -d ubuntu:18.04  #后台运行,输出结果使用 docker container logs查看

启动已终止的容器

docker start <name>

进入容器

docker exec -it <name> bash

查看容器列表

docker ps

终止容器

docker stop <name>

删除容器

docker rm <name> # -f 为强制停止容器并删除

查看容器详细信息

docker inspect <name>

3.3 存储相关

创建数据卷

docker volume create my-vol

查看数据卷列表

docker volume ls

查看数据卷详细信息,包括挂载点、驱动等

docker volume inspect my-vol

删除数据卷

docker volume rm my-vol

挂载数据卷

docker run -d -P \
    --mount source=my-vol,target=/usr/share/nginx/html \
    nginx:alpine

挂载主机目录

$ docker run -d -P \
    --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html,readonly \
    nginx:alpine

3.4 网络相关

随机映射一个端口到内部容器开放的网络端口

docker run -d -P nginx:alpine

指定映射端口,本地 : 容器

docker run -d -p 80:80 nginx:alpine

docker run -d \
    -p 80:80 \
    -p 443:443 \
    nginx:alpine

创建docker网络

docker network create -d bridge my-net

连接容器网络

docker run -it --rm --name busybox1 --network my-net busybox sh
docker run -it --rm --name busybox2 --network my-net busybox sh

4. 底层原理

Docker 底层的核心技术包括 Linux 上的命名空间(Namespaces)、控制组(Control groups)、Union文件系统(Union file systems)和容器格式(Container format)
Docker 采用了 C/S架构,包括客户端和服务端。Docker 守护进程 (Daemon)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。
客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。

docker通过命名空间隔离文件目录、进程、网络、user等,通过控制组隔离共享底层的资源,比如cpu、内存、磁盘IO、网络带宽等。通过Union文件系统实现镜像分层。参考

dockerfile运行apk命令卡住的问题解决——更换镜像 在练习docker官方文档关于docker compose初体验(https://docs.docker.com/compose/gettingstarted/)过程中,执行dockerfile命令RUN apk add --no-cache gcc musl-dev linux-headers时,出现卡住的情况,等了几千秒都不行。网上查了一下,阿里提供了一个镜像:http://mirrors.aliyun.com/alpine/v3.19/main/显示Installing gcc。 阅读详情

相关推荐

docker命令

dockerfile文件:解决图形验证码空指针异常 #FROM java:8 FROM openjdk:8-jdk-alpine RUN set -xe \ && apk --no-cache add ttf-dejavu fontconfig ARG JAR_FILE COPY ${JAR_FILE} app.jar EXPOSE xxxx端口号 ENTRYPOINT ["java","-jar","/app.jar"] dockerfile文件编写步骤: 1. 设置基础环境

AI炼丹师的专栏 1069

Alpine

Alpine介绍和相应apk指令

m0_72898391的博客 1170

【Docker 学习笔记】Docker 命令大全

【Docker 学习笔记】Docker 命令大全。本文总结了Docker使用过程中常用命令,以及各命令常用参数的解释说明。

小青龍 的博客 3万+

玩转Docker实战篇!使用Docker搭建Nginx静态网站,附加介绍Docker容器数据卷

一、文本目的 前面学完了Docker的一些常用语法,现在来开始将Docker用于构建和测试 将Docker作为本地Web开发环境是Docker的一个最简单的应用场景。这样的环境可以完全复制生产环境,并确保用户开发的东西在生产环境中也能运行。下面从将Nginx Web服务器安装到容器来架构一个简单的网站开始,这个网站的名字暂时命名为sample 二、创建Nginx配置文件 创建一个nginx目录,用来存放nginx的配置文件,然后创建两个配置文件,分别名为global.conf和nginx.conf

董哥的黑板报 2075

软件工程导论实践:从需求到架构的机票预订系统全流程解析

本文深入解析机票预订系统从需求分析到架构设计的全流程实践,涵盖业务流程、功能建模、模块化设计、性能优化等关键环节。通过实际项目经验,分享软件工程导论在复杂系统开发中的应用技巧,包括数据流图绘制、E-R图设计、微服务架构及高并发处理等实战策略,助力开发者构建高效可靠的机票预订系统。

weixin_29202213的博客 414

HTML入门(详细教程),前端入门从这里开始

HTML基础教程,网页框架搭建,表单制作,了解HTML标签的基本用法,每个标签具备哪些属性。

wandertp的博客 1284

【docker】docker学习笔记

docker学习笔记

weixin_43308380的博客 1361

昆仑通态屏幕制作(连载1)---接触篇

写在开始 背景:最近出了做QT、LORA和4G,还做了一个屏幕。以前做了一个迪文的串口屏幕,发现网上的教程很多,所以连载就不更新了,并且迪文屏幕的设置什么的比较简单,应该从网上都能找到对应的教程。而现在用的昆仑通态的屏幕属于嵌入式屏幕,至于为啥叫嵌入式,也不是很明白,反正就是需要用这个屏幕,嵌入式不嵌入式不重要了。重要的是能用,并且能实现串口屏幕不能实现的功能。所以选定昆仑通态的一款屏幕。 文章语言:我比较习惯用比较糙的语言介绍做的东西,有时候不太准备,但是为了方便理解,还请大家谅解。用...

weixin_45426095的博客 6736

Docker学习笔记

一般情况下,ENTRYPOINT 和 CMD 标签都是互相配合使用的,即:ENTRYPOINT 填写固定的命令,CMD 填写该固定命令对应的参数,CMD 将这个参数传递给 ENTRYPOINT命令。可以理解为 CMD 参数为 ENTRYPOINT 的默认值,如果项目中使用的不是 CMD 的默认值,就可以在启动 docker 容器时添加上真实的参数值,用来覆盖 CMD 的默认值。这个 FROM 指令是 dockerfile 的第一个指令,然后指定了基础镜像,后面的所有指令都是运行在该基础镜像环境上的。

Wu 小杰的博客 2091

VisionPro开发实战:CogRecordDisplay控件显示与保存图片的完整流程(附C#代码示例)

本文详细解析了VisionPro开发中CogRecordDisplay控件的图像处理全流程,包括图像加载、显示优化、动态清屏及结果保存等关键操作。通过C#代码示例,展示了如何高效使用该控件进行工业视觉应用开发,特别适合自动化检测系统的开发者参考。

weixin_42523792的博客 276

别再卡在Google验证了!用Header Editor插件5分钟搞定TryHackMe注册(附最新.json规则)

本文提供了使用Header Editor插件快速解决TryHackMe注册时Google验证失败问题的详细指南。通过导入特定的JSON规则文件,用户可以轻松绕过网络限制,5分钟内完成账号注册,无需复杂设置。文章包含完整的配置步骤、常见问题解决方案以及安全使用建议。

weixin_30736301的博客 463

Docker的学习笔记

网上关于docker的介绍很多,要不就是讲的很底层,要不就是不连贯,能把知识穿起来的我没找到,所以最后还是自己写个笔记,方便以后回顾。对于笔记的学习,还是看不太进去,准备找一些视频介绍进行学习。

qq_55728814的博客 1686

uniapp - HBuilder提示adb: failed to install X Failure [INSTALL_ARSE_FAILED_NOT_APK:X(安装HBuilder调试基座失败)

安装HBuilderX调试基座失败,uniapp APP运行到手机adb: failed to install,Uniapp提示adb,uniapp ios 真机调试报错 uniapp安卓调试,Uniapp安装不了基座,手动安装基座,正在安装手机端HBuilder调试基座,点击运行到手机报错信息:基座无法正常安装,Uniapp-安装HBuilder调试基座失败解决方案,解决 HBuilderX 安卓基座安装失败的问题,显示adb报错,UniApp苹果真机运行调试(自定义基座,版本更新后/没有基座打开失败)如

🏆 前端领域优质创作者 8061

Docker学习笔记索引

Docker学习笔记 ->环境与背景篇->1、容器技术 Docker学习笔记 ->环境与背景篇->2、docker简介 Docker学习笔记 ->环境与背景篇->3、安装docker(ubuntu ) Docker学习笔记 ->环境与背景篇->3、安装docker(CentOS7 ) Docker学习笔记 ->环境与背景篇->3、安装d...

外环西路 591

prometheus普罗米修斯集监控外部k8s

prometheus普罗米修斯集监控外部k8s

你是我一生的追求 2249

29.Labview界面设计 --- (下篇)自定义控件库、界面布局与外观设计

1.自定义控件外观(自定义控件)1.1 自定义外观库1.2 手动自定义控件外观2. 前面板控件布局方式(控件排布)2.1 模块化控制布局方式2.2 数据采集布局方式3. 前面板外观优化项(背景设计)3.1 前面板背景设计3.2 前面板窗口整理本节第一部分教大家安装一种可以直接用的自定义控件库,第二部分教大家如何自己设计控件并保存调用。

关注我,更多技术问题欢迎私聊~ 4782

Docker学习笔记这一篇就够

​ Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”。​ Linux容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用打成镜像,通过镜像成为运行在Docker容器上面的实例,而 Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。

weixin_45501045的博客 1061

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

狂神Docker学习笔记下载

狂神Docker学习笔记下载 去发现同类优质开源项目:https://gitcode.com/ 本仓库提供了一个名为“狂神Docker学习笔记.pdf”的资源文件下载。该文件是学习Docker时整理的学习笔记,内容详实,适合初学者和进阶学习者参考。 资源文件描述 文件名: 狂神Docker学习笔记.pdf 文件类型: PDF 文件大小: [文件大小] 内容概述: 该PDF文件包含了Docker的...

gitblog_06644的博客 424

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Docker 完整学习笔记

记录docker的学习过程

dandingchongci的博客 1281

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

上一篇: 100道最常见的校招前端面试题(更新中)
下一篇: Linux命令学习笔记
PAT-python-zjw
博客等级 码龄10年 381粉丝 408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值