docker学习笔记

1. docker安装

可以从以下地址下载并安装docker,Linux,Windows,MacOS均支持:

  • 官网:https://docs.docker.com/engine/install/
  • 阿里云镜像安装:https://developer.aliyun.com/mirror/docker-ce

Docker 安装完成后,可以直接打开终端执行:

docker run hello-world

输出如下信息:

Hello from Docker!
This message shows that your installation appears to be working correctly.
 
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
 
To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash
 
Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/
 
For more examples and ideas, visit:
 https://docs.docker.com/get-started/

通过上述 hello-world 镜像运行起来的容器,输出了一个容器的运行步骤:

  • Docker 客户端与 Docker 服务端建立连接,告知服务端需要使用 hello-world 镜像运行一个容器
  • Docker 服务端从 Hub 仓库拉取与当前宿主机相同架构的镜像 hello-world
  • Docker 服务端运行一个 hello-world 容器,执行容器中的 hello-world 程序
  • Docker 服务端将 hello-world 程序输出的内容打印到控制台

2. docker架构

Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个文件存储中心,用来保存镜像。

镜像 与 容器 的关系?

镜像(image)是一个压缩包,镜像通过 Docker Daemon 进程解压拉起(run)得到容器(container).
在这里插入图片描述

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
在这里插入图片描述

3. 容器和虚拟机的区别

虚拟化技术是由Hypervisor真正的创建了一个虚拟机,有以下特点:

  • 要运行真实的操作系统后才能执行应用进程,Guest OS本身就会带来资源的消耗
  • 应用进程对CPU、网络、磁盘IO的系统调用都要经过虚拟软件的拦截和处理;

容器化技术的特点:

  • 容器中的应用进程本身就是宿主机上的一个普通进程,系统调用不会带来额外的资源消耗,也不需要运行额外的Guest OS;

所以容器化技术相对于虚拟化技术的优势是敏捷和高性能。但有利就有弊,弊端在于隔离不彻底,主要表现为:

  1. 容器化的进程是共享宿主机内核,所以跨操作系统是不被支持的,例如CentoOS、Ubuntu、Windows不共融;
  2. 有些资源和对象是不能被namespace的,例如:时间,所以容器化部署的应用需要清楚哪些能做,哪些不能做。

4. 容器化技术理解

容器就是一种沙盒技术,一种把应用进程装进集装箱的技术,应用与应用之间因为有了边界而不会相互干扰,同时应用被装起来后也方便搬运和迁移 。
容器技术的核心功能,就是做到两点:

  1. 约束进程的资源边界,使用linux中的Cgroups技术;
  2. 修改进程的动态视图,使用linux中的Namespaces技术;

容器文件系统:rootfs

  • 一个操作系统的所有文件和目录,不包括内核
  • 容器化时挂载在容器根目录上,用于为进程提供隔离执行环境的文件系统。
  • chroot命令可以改变进程的根目录到指定的位置

docker与k8s的区别:

  • Docker:是一个容器运行时,拉取镜像、运行容器
  • K8s:重心在容器编排,它的观点是运行在大规模容器中的各种任务之间是有关系的,所以它从更宏观的角度,以统一的方式来定义任务之间的各种关系,而像Docker这样的容器运行时只是作为一个底层设施。

5. Namespaces

作用:从视图中隔离应用进程的可视范围,包括网络、文件、CPU、进程、用户等。

隔离进程空间要达到的效果:

  • 在宿主机中启动一个进程时,操作系统会分配一个进程编号PID(例如100),这个PID是进程的唯一标识;
  • 在Docker容器中,启动的进程只能看到当前应用一个进程,并且PID是重新计算过的,一般编号为1。

为了做到这点,就需要为应用设置一个隔离的进程空间,而namespaces就恰好能做到这点,它的原理如下:

  • 在clone函数创建进程的系统调用中添加一个参数CLONE_NEWPID,这样新创建的这个进程将会看到一个全新的进程空间,在这个进程空间中当前进程的PID=1。
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 

实际上,namespaces只是对被隔离应用的进程空间做了手脚,使得这些进程只能看到重新计算过的进程编号1,而实际上在宿主机操作系统里,进程编号还是100,相当于一个碍眼法。

namespaces有很多种,除了上面提到的pid namespace外,还有下面几种:

  • Mount Namespace:用于让被隔离进程只看到当前namespace里的挂载点信息;
  • Network namespace: 用于让被隔离进程只看到当前namespace里的网络设备和配置;
  • UTS namespace: 提供主机名隔离能力;
  • IPC namespace: 提供进程间通信的隔离能力;
  • User namespace: 提供用户隔离能力。

6. Cgroups

namespaces只能隔离应用进程的可视范围,却并不能真正限制进程所能使用的资源。例如:

一个namespace中只能看到1G的内存,但它真实运行时却能占用整个宿主机的内存。

所以需要一个机制来限制进程能使用的资源上限,它就是Cgroups(全称是Linux Control Group),能限制的资源包括CPU、磁盘、内存、网络带宽等。
Cgroups 给用户暴露出来的操作接口是文件系统,位于/sys/fs/cgroup目录下,用以下命令可以展示内容:mount -t cgroup
在这里插入图片描述

上面截图中列出的这些子系统就是cgroup支持限制的资源种类。

下面拿CPU举例来说明如何使用(目录位于/sys/fs/cgroup/cpu):

  1. 在子系统中创建一个控制组:root@ubuntu:/sys/fs/cgroup/cpu$ mkdir user.slice, 操作系统会在新目录中自动生成对应的配置文件;
    在这里插入图片描述
  2. 对于CPU来说主要由两个关键参数来控制:cfs_periodcfs_quota,用来限制进程在cfs_period长的时间内,最多能被分到cfs_quota的CPU时间;
  3. 在user.slice下面的tasks文件中写入进程的PID,这样container控制组的限制就只对指定的进程生效。

除CPU外,还有以下子系统分别对进程作不同的限制 :

  • blkio: 为块设备设定IO限制
  • memory: 为进程设定内存使用的限制
  • cpuset: 为进程分配单独的CPU核和内存节点

7. 镜像构建

7.1 Dockerfile

镜像一般通过Dockerfile进行构建,它是一个用来声明镜像构建过程的文件。下面是一个示例:

FROM ubuntu:20.04               # 指定基础镜像文件                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
COPY uc/sbin/ /uc/sbin/         # 拷贝应用程序文件
USER root   EXPOSE 8051 18051   # 指定用户、暴露应用进程端口
ENTRYPOINT ["./docker_start.sh"]# 指定镜像中的应用启动入口

Dockfile常用的指令有:

指令描述
FROM指定基础镜像,例如 FROM ubuntu:20.04
LABEL给新镜像打标签,便于过滤,方便理解,起到备注注释的作用
RUN在新镜像中做一些指令操作,可以理解为执行一些 shell 命令,如 mkdir, apt-get, cp 等
CMD类似 RUN ,定义容器启动时执行的指令,或者作为参数提供给 ENTRYPOINT 指令。如果定义多个CMD,则仅最后一个有效。CMD指令可以被 docker run image param1 param2 后面的参数覆盖
ENTRYPOINT定义容器启动指令,类似于 CMD 指令,但其不会被 docker run 的命令行参数所覆盖。可以使用 docker run image --entrypoint 选项来覆盖 ENTRYPOINT 指令指定的程序
EXPOSE声明容器启动会使用的端口,仅仅供人查看而已。作用:帮助镜像使用者理解这个镜像使用的端口,以方便配置映射。在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
ENV定义环境变量,在后续的指令中,就可以使用这个环境变量(包括启动容器后)
ARG类似ENV,但作用域不同,仅在构建镜像时有用,容器运行时不存在,可以放置在FROM前,可以被 --build-arg key=value 覆盖
COPY复制指令,从上下文目录中复制文件或者目录到容器里指定路径,例如:COPY sayHi /uc/bin/sayHello
ADD同COPY,比COPY多了:支持拷贝 远程url地址文件 至镜像中;压缩包会被自动解压缩。同等需求下,建议采用COPY
VOLUME声明容器要使用的挂载点,便于使用者理解镜像的关键数据存储位置。如果没有指定则会自动挂载到匿名卷,这个匿名卷难以查找。
WORKDIR指定工作目录,以后各层的当前目录就被改为指定的目录,可以将WORKDIR理解为 cd 命令。
USER用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

7.2 上下文

Dockerfile 所在的当前目录就是容器构建的上下文,它的作用体现在:

  • COPY 指令只能拷贝构建上下文中的文件或目录;
  • 上下文中的数据默认都会复制一份传输给 docker-daemon,所以上下文所在目录要尽可能小,以加速构建;
  • .dockerignore 可用于声明要忽略的文件,这里声明的文件不需要传输,类似于.gitignore
.git
src
*.war
*.jar

7.3 镜像分层

Docker镜像是分层构建的,Dockerfile 中每条指令可能都会新建一层。例如以下 Dockerfile:

FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
  • 以上四条指令会创建四层,分别对应基础镜像、复制文件、编译文件以及入口文件;
  • 每层只记录本层所做的更改,而这些层都是只读层;
  • 当你启动一个容器,Docker 会在最顶部添加读写层;
  • 你在容器内做的所有更改,如写日志、修改、删除文件等,都保存到了读写层内,一般称该层为容器层。

如下图所示:

说明:也不是每一行指令都产生新层,只有那些修改了文件系统的命令才会产生新的镜像层,例如RUN、COPY之类。

7.4 镜像构建

# 当前目录结构 tree
/tmp/test-v1
- Dockerfile
- Dockerfile2
- a.log
 
# 切换到目录
$ cd /tmp/test-v1
 
# 在当前目录下构建 test:v1 镜像
$ docker build -t test:v1 .
 
# 使用 Dockerfile2 构建镜像
$ docker build -t test:v2 -f Dockerfile2 .
 
# 添加完整的镜像路径(用于私有或第三方仓库)
$ docker build -t hub-ali.quanshi.com/repotest/test:v3 .

8. 镜像仓库

镜像仓库分为如下几类:

  1. 中央仓库:https://hub.docker.com/, 仓库上的镜像来源有

    • 官方镜像, Docker公司提供的镜像
    • 经过验证的发布者,大厂或机构
    • 开源社区,开源软件组织
    • 其他小厂或个人
  2. 第三方仓库,其他公司或者机构提供的免费或付费的仓库

    • 阿里云ACR:https://help.aliyun.com/zh/acr/
    • 腾讯云TCR:https://cloud.tencent.com/document/product/1141/39278
    • 其他
  3. 私有仓库,个人或公司自己搭建的供公司内部使用的仓库

    • registry, 官方提供的私有仓库软件
    • harbor, 基于 registry 包装的更加好用的私有仓库软件
    • 其他
  4. 本地仓库,在机器本地镜像存放的仓库

中央仓库和私有仓库在使用时有些许区别:

  • 中央仓库在拉取镜像时是不需要添加域名的,可以直接
docker pull busybox
  • 私有仓库和第三方仓库拉取镜像需要使用域名(默认只支持 https ,不需要带协议字段)
docker pull hub-ali.quanshi.com/infra/busybox

如果需要 http 或直接 ip 方式访问,需要给 docker 配置免安全校验,见下:

# 编辑 /etc/docker/daemon.json, 加入 insecure-registries 字段
{
  "insecure-registries" : ["test.hub.com", "192.168.11.11"]
}

配置镜像加速

# 编辑 /etc/docker/daemon.json, 加入registry-mirrors 字段

{
  "registry-mirrors": ["https://fv743jei.mirror.aliyuncs.com"],
}
# 更多可用镜像加速方案参照:https://gist.github.com/y0ngb1n/7e8f16af3242c7815e7ca2f0833d3ea6

9. 常用命令

指令描述
docker-compose up创建并启动容器,通过-f参数来指定yaml容器配置,例如:docker-compose -f /meetconf.yml up uniformserver -d
docker commit通过容器创建镜像
docker cp容器与本地目录相互拷贝文件
docker exec在容器中执行命令,例如进入容器:docker exec -it 容器id /bin/bash
docker logs查看容器控制台日志输出,例如:docker logs -f sqlproxy
docker ps获取正在运行的容器,-a 获取所有容器(包含已停止的)
docker rm [容器ID]删除已停止的容器,加上-f表示删除正在运行的容器
docker stop [容器ID]停止正在运行的容器
docker build通过 Dockerfile 构建镜像
docker history查看镜像构建历史,如docker history nginx:v1
docker images列出镜像
docker inspect [容器ID]显示镜像或容器的详细信息
docker load加载镜像到本地仓库
docker pull从镜像仓库拉取镜像
docker push推送镜像到镜像仓库
docker rmi移除镜像
docker save保存镜像到一个tar文件
docker tag镜像更改标签名称

参考阅读

  • Docker官网:https://docs.docker.com/get-started/overview/
  • Docker的镜像分层:https://zhuanlan.zhihu.com/p/70424048
  • Dockerfile常用指令介绍:https://www.runoob.com/docker/docker-dockerfile.html
  • Docker命令大全:https://www.runoob.com/docker/docker-command-manual.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/115875.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3.Docker的客户端指令学习与实战

1.Docker的命令 1.1 启动Docker(systemctl start docker) systemctl start docker1.2 查看docker的版本信息(docker version) docker version1.3 显示docker系统范围的信息(docker info) docker info1.4…

3.21每日一题(区间在现求定积分)

当发现一个定积分,原函数根本找不出来时,可以用变量代换:区间再现!!!

【JVM】双亲委派机制、打破双亲委派机制

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 JVM 一、双亲委派机制1.1 双亲委派的作用1.…

AST注入-从原型链污染到RCE

文章目录 概念漏洞Handlebarspug 例题 [湖湘杯 2021 final]vote 概念 什么是AST注入 在NodeJS中,AST经常被在JS中使用,作为template engines(引擎模版)和typescript等。对于引擎模版,结构如下图所示。 如果在JS应用中存在原型污染漏洞&…

【蓝桥杯选拔赛真题10】C++求奇数和 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++求奇数和 一、题目要求 1、编程实现 2、输入输出 二、算法分析 <

sqlsugar查询数据库下的所有表,批量修改表名字

查询数据库中的所有表 using SqlSugar;namespace 批量修改数据库表名 {internal class Program{static void Main(string[] args){SqlSugarClient sqlSugarClient new SqlSugarClient(new ConnectionConfig(){ConnectionString "Data Source(localdb)\\MSSQLLocalDB;In…

VS Code 开发 Spring Boot 类型的项目

在VS Code中开发Spring Boot的项目&#xff0c; 可以导入如下的扩展&#xff1a; Spring Boot ToolsSpring InitializrSpring Boot Dashboard 比较建议的方式是安装Spring Boot Extension Pack&#xff0c; 这里面就包含了上面的扩展。 安装方式就是在扩展查找 “Spring Boot…

故障诊断 | MATLAB实现GRNN广义回归神经网络故障诊断

故障诊断 | MATLAB实现GRNN广义回归神经网络故障诊断 目录 故障诊断 | MATLAB实现GRNN广义回归神经网络故障诊断故障诊断基本介绍模型描述预测过程程序设计参考资料故障诊断 基本介绍 MATLAB实现GRNN广义回归神经网络故障诊断 数据为多特征分类数据,输入12个特征,分3

SpringSecurity全家桶 (二) ——实现原理

1. SpringSecurity的强大之处 当我们并未设置登录页面时&#xff0c;我们只需要导入SpringSecurity的依赖就可以令我们的界面进入保护状态&#xff0c;由下面例子可以凸显出&#xff1a; 随便写个接口 RequestMapping("/hello")public String hello(){return "H…

【this详解】学习JavaScript的this的使用和原理这一篇就够了,超详细,建议收藏!!!

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;JavaScript进阶指南 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继…

虹科案例 | AR内窥镜手术应用为手术节约45分钟?

相信医疗从业者都知道&#xff0c;在手术室中有非常多的医疗器械屏幕&#xff0c;特别是内窥镜手术室中医生依赖这些内窥镜画面来帮助病患进行手术。但手术室空间有限&#xff0c;屏幕缩放位置相对固定&#xff0c;在特殊场景下医生观看内窥镜画面时无法关注到病患的状态。这存…

FFmpeg 硬件加速视频转码指南

基于 Windows 下演示&#xff0c;Linux 下也可以适用。 所使用 ffmpeg 版本为 BtbN 编译的 win64-gpl 版&#xff08;非 gpl-share&#xff09;&#xff0c;项目地址&#xff1a;BtbN / FFmpeg-Builds 也可以使用 gyan.dev 编译的 git-full 版&#xff0c;地址&#xff1a;gyan…

【Kafka】基本概念

文章目录 一、消息队列的流派1.1 有Broker1.1.1 重topic1.1.2 轻topic 1.2 无Broker 二、kafka安装三、kafka基本术语四、发送消息五、消费消息六、单播消息七、多播消息八、查看消费组的详细信息九、主题topic十、分区十一、kafka中消息⽇志⽂件中保存的内容 一、消息队列的流…

4 个最常见的自动化测试挑战及应对措施

有人说&#xff1a;“杂乱无章的自动化只会带来更快的混乱。”不仅更快&#xff0c;而且是更严重、更大的混乱。如果使用得当&#xff0c;自动化可以成为测试团队中令人惊叹的生产力助推器和系统的质量增强器。自动化测试的关键是要正确运用&#xff0c;这是初始最困难的部分。…

如何利用AppScan扫描H5页面,进行安全测试?

前期项目组接触的都是Web安全测试&#xff0c;今天做安全测试的时候&#xff0c;有一个项目刚好有H5页面&#xff0c;用以前那种AppScan内置浏览器的探索方式是不行的&#xff0c;研究了下&#xff0c;可以使用外部设备进行探索。 AppScan有两种手动探索方式&#xff0c;一种是…

面试算法53:二叉搜索树的下一个节点

题目 给定一棵二叉搜索树和它的一个节点p&#xff0c;请找出按中序遍历的顺序该节点p的下一个节点。假设二叉搜索树中节点的值都是唯一的。例如&#xff0c;在图8.9的二叉搜索树中&#xff0c;节点8的下一个节点是节点9&#xff0c;节点11的下一个节点是null。 分析&#xf…

memtest86 prosite v10.6

passmark官方的memtest86 v10开始支持颗粒级别的坏内存芯片定位了&#xff0c;对于特定的若干种CPU和芯片组的组合&#xff0c;支持这项功能。 当然支持颗粒定位的site版本售价4800美金&#xff0c;是比较贵的。所以网络上出现了破解版的&#xff0c;人才真是。但是鼓励大家支…

短视频矩阵营销系统工具如何助力商家企业获客?

1.批量剪辑技术研发 做的数学建模算法&#xff0c;数学阶乘的组合乘组形式&#xff0c;采用两套查重机制&#xff0c;一套针对素材进行查重抽帧素材&#xff0c;一套针对成片进行抽帧素材打分制度查重&#xff0c;自动滤重计入打分。 2.账号矩阵分发开发 多平台&#xff0c;…

【QT】QFileInfo文件信息读取

基于上节&#xff1a;【QT】文件读写-CSDN博客 //文件信息类QFileInfo info(filePath);qDebug() << "后缀名:" << info.suffix() << "大小:"<< info.size()<< "文件名:" << info.fileName() << "…

k8s:endpoint

在 Kubernetes 中&#xff0c;Endpoint 是一种 API 对象&#xff0c;它用于表示集群内某个 Service 的具体网络地址。换句话说&#xff0c;它连接到一组由 Service 选择的 Pod&#xff0c;从而使它们能够提供服务。每个 Endpoint 对象都与相应的 Service 对象具有相同的名称&am…
最新文章