Docker学习笔记

Docker背景介绍

1. 什么是Docker?

Docker是一种开源的应用容器引擎,允许开发者将应用及其依赖打包成一个可移植的容器,从而能够在任何流行的Linux机器上运行。Docker以其轻量级、快速启动和隔离性质著称,可以实现虚拟化,但与传统虚拟机相比,它几乎没有性能开销。

Docker使用沙盒机制,确保不同容器之间相互独立,避免了系统间的干扰,这使得应用的部署和管理更加高效。此外,Docker不依赖于特定的编程语言、框架或包装系统,增强了其通用性。

小知识:沙盒(Sandbox)

沙盒是一种虚拟化技术,常用于计算机安全领域。它可以让程序在受限环境中运行,如果程序表现出恶意行为,则可以阻止其进一步执行,从而保护系统的安全。

Docker最初由dotCloud公司开发,是基于LXC(Linux Container)构建的高级容器引擎。它的源码托管在GitHub上,采用Go语言编写,并遵循Apache 2.0协议开源。

小知识:LXC

LXC代表Linux Container,是一种内核虚拟化技术,提供轻量级的虚拟化解决方案,以便隔离进程和资源。LXC通过Linux内核的命名空间(namespace)实现用户实例之间的隔离,通过控制组(cgroup)管理资源分配和调度。

2. Docker容器技术与虚拟机的区别

相同点

  • 虚拟化技术:Docker和虚拟机(VM)都是虚拟化技术,用于隔离应用程序和服务,确保它们能够在独立的环境中运行。

不同点

虚拟机技术
  • 架构:虚拟机依赖于Hypervisor(虚拟机监控程序),它负责管理物理硬件资源并将其分配给多个虚拟机。每个虚拟机都有自己的操作系统,创建了多个抽象层。
  • 资源消耗:由于每个虚拟机都需要完整的操作系统,因此会消耗更多的内存和存储资源。
  • 启动时间:虚拟机的启动时间通常较长,可能需要几分钟,取决于操作系统的加载时间。
容器技术
  • 架构:Docker容器直接运行在宿主操作系统上,共享内核,而不需要额外的操作系统层。这样减少了抽象层,提高了性能。
  • 资源消耗:容器通常更轻巧,仅包含应用及其依赖,资源占用小。
  • 启动时间:Docker容器的启动时间仅需几秒钟,极大提高了开发和部署的效率。

Docker相较于虚拟机的优点

  1. 轻量级与快速:Docker的容器比虚拟机小得多,启动速度快,使得云部署和分发更加高效。
  2. 开放平台:Docker提供一个开放的平台,方便构建、发布和运行分布式应用程序。
  3. 操作系统无关性:开发人员无需关注底层使用的具体Linux操作系统。
  4. 广泛支持:多家知名科技公司(如Google、微软、亚马逊等)均支持Docker。
  5. 跨平台支持:Docker不仅支持Unix/Linux操作系统,还支持Windows和Mac。

Docker的局限性

  • 数据管理:Docker主要用于计算,不直接管理数据存储。日志、数据库等通常保存在容器外部,可以通过外部挂载的方式(如NFS、iSCSI等)进行管理。
  • 镜像大小:虽然容器镜像较小,但不适合存储大量数据,推荐将数据存储放在外部解决方案中。

总结

Docker是一个非常高效的虚拟化解决方案,适用于快速开发和部署应用程序,但在数据管理上需要依赖其他工具和技术。

Docker架构图与工作流程

在深入了解Docker之前,参考下面的架构图有助于理解Docker的基本概念和结构。希望大家在学习完Docker后能再次查看这张图,以加深理解。

  • **镜像(Image):**Docker 镜像,就相当于一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统

  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等

  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像

Docker工作流程

  1. 启动Docker:首先需要启动Docker守护进程,使其能够管理容器和镜像。
  2. 下载镜像到本地:从Docker Hub等镜像仓库下载所需的镜像。
  3. 启动Docker容器实例:基于下载的镜像创建并启动容器实例。

提示:建议大家注册一个Docker Hub账户,这对后续的学习非常重要,没有账号将无法充分利用Docker的功能。

Docker核心技术

  1. Namespace:实现容器的进程、网络、消息、文件系统和主机名的隔离,使每个容器都能独立运行。
  2. Cgroup:用于资源的配额和调度,可以限制每个容器使用的CPU、内存等资源。

Docker特性

  • 文件系统隔离:每个容器都有独立的根文件系统,互不影响。
  • 资源隔离:通过Cgroup实现系统资源的分配,确保不同容器之间的资源隔离。
  • 网络隔离:每个容器运行在自己的网络空间中,拥有虚拟接口和IP地址。
  • 日志记录:Docker记录每个容器的标准流(stdout/stderr/stdin),方便实时或批量检索。
  • 变更管理:容器文件系统的变更可以提交为新的镜像,便于重复使用与部署。
  • 交互式Shell:Docker允许分配虚拟终端,方便与容器进行交互。

SSH客户端

WindTerm 是一款 Github 上开源的 SSH 终端工具,到目前为止它已经收获了 16.9K 颗星,它是完全可以比肩 MobaXterm工具的。其支持的系统及功能如下:

1. 系统支持:

  • Linux
  • macOS
  • Windows

2. 功能支持:

  • SSH
  • Telnet
  • Shell
  • TCP
  • Serial
  • SFTP
  • Cmd
  • PowerShell
  • Git

WindTerm 安装使用教程【图解】

docker安装

参考文章:

10分钟学会Docker的安装和使用_docker安装-CSDN博客

安装 Docker | Docker 从入门到实践

配置阿里云

注册一个阿里云的账号,在阿里云官网的控制台申请个人容器镜服务、并完成基础配置。

点击镜像加速器

根据官网提示的命令进行操作

操作完成后 再次输入 docker run hello-world。如果能正常运行跳出hello,world 说明配置正确。至此个人账号下的阿里云镜像配置完成,从此下载速度可以变快。(没有加速会导致后续有些操作莫名其妙报错、超时、会很头疼)

Docker学习社区

Docker官方文档教程

学习任何技术,官方文档都是最好的资料教程。

Docker中文社区

Docker入门到实践开源教程(推荐)

Docker常见命令

类别 命令 说明
进程相关 systemctl start docker 启动 Docker 服务
systemctl stop docker 停止 Docker 服务
systemctl restart docker 重启 Docker 服务
systemctl status docker 查看 Docker 服务状态
systemctl enable docker 设置开机启动 Docker 服务
镜像相关 docker images 查看本地所有的镜像
docker images -q 查看所有镜像的 ID
docker search 镜像名称 从网络中查找需要的镜像
docker pull 镜像名称 从 Docker 仓库下载镜像到本地
docker rmi 镜像ID 删除指定本地镜像
docker rmi $(docker images -q) 删除所有本地镜像
容器相关 docker ps 查看正在运行的容器
docker ps -a 查看所有容器
docker run 参数 --name=容器名称 镜像名称 创建并启动容器
docker exec -it 容器名称 /bin/bash 进入容器
docker stop 容器名称 停止容器
docker start 容器名称 启动容器
docker rm 容器名称 删除容器
docker inspect 容器名称 查看容器信息

Docker容器数据卷

容器数据卷介绍

Docker容器在产生数据时,如果不使用docker commit生成新的镜像,数据会随着容器的删除而消失。为了解决这一问题,Docker引入了数据卷的概念。

数据卷:数据卷是宿主机中的一个目录或文件,当容器目录和数据卷目录绑定后,对方的修改会立即同步

  • 一个数据卷可以被多个容器同时挂载

  • 一个容器也可以被挂载多个数据卷

数据卷的作用:

  • 容器数据持久化

  • 外部机器和容器间接通信

  • 容器之间数据交换

配置数据卷

创建启动容器时,使用-v参数设置数据卷

XML 复制代码
docker run ... --v 宿主机目录(文件):容器内目录(文件) ... 
docker run -it --name=c1 -v /root(or~)/data:/root/data_container centos:7

注意事项:

  • 目录必须是绝对路径
  • 如果目录不存在,会自动创建
  • 可以挂载多个数据卷

多容器进行数据交换:

  • 多个容器挂载同一个数据卷

  • 数据卷容器

创建启动c3数据卷容器,使用 --v 参数设置数据卷

XML 复制代码
docker run --it --name=c3 --v /volume centos:7 /bin/bash 

创建启动 c1 c2 容器,使用 ---volumes-from 参数设置数据卷

XML 复制代码
docker run --it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run --it --name=c2 --volumes-from c3 centos:7 /bin/bash  

应用部署

MySQL

在Docker容器中部署MySQL,通过外部mysql客户端操作MySQL Server

端口映射:

  • 容器内的网络服务和外部机器不能直接通信,外部机器和宿主机可以直接通信,宿主机和容器可以直接通信

  • 当容器中的网络服务需要被外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上。外部机器访问宿主机的该端口,从而间接访问容器的服务。这种操作称为:端口映射

MySQL部署步骤:搜索mysql镜像,拉取mysql镜像,创建容器,操作容器中的mysql

1、搜索 MySQL 镜像

XML 复制代码
docker search mysql

2、拉取 MySQL 镜像

选择一个具体版本的 MySQL 镜像进行拉取,这里以 5.6 版本为例:

XML 复制代码
docker pull mysql:5.6

3、创建容器并设置端口和目录映射

在宿主机上创建一个目录来存储 MySQL 的数据。

XML 复制代码
mkdir ~/mysql
cd ~/mysql

然后运行以下命令来创建并启动 MySQL 容器:

XML 复制代码
docker run -id \
-p 3307:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6

参数说明:

  • -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
  • -v $PWD/conf:/etc/mysql/conf.d:将当前目录下的 conf 目录挂载到容器的 /etc/mysql/conf.d,用于配置文件。
  • -v $PWD/logs:/logs:将当前目录下的 logs 目录挂载到容器的 /logs,用于日志存储。
  • -v $PWD/data:/var/lib/mysql:将当前目录下的 data 目录挂载到容器的 /var/lib/mysql,用于数据库数据存储。
  • -e MYSQL_ROOT_PASSWORD=123456:设置 MySQL root 用户的密码。

4、进入容器并操作 MySQL

XML 复制代码
docker exec -it c_mysql /bin/bash

进入容器后,可以使用 MySQL 客户端进行数据库操作:

XML 复制代码
mysql -u root -p

输入上述命令后,系统会提示你输入密码,输入 123456 即可登录。

要退出 MySQL 客户端,可以使用以下命令:

sql 复制代码
exit;

Tomcat

搜索tomcat镜像

XML 复制代码
docker search tomcat

拉取tomcat镜像

XML 复制代码
docker pull tomcat

创建容器,设置端口映射、目录映射

在主机上创建一个目录用于存储 Tomcat 的数据信息:

XML 复制代码
mkdir ~/tomcat
cd ~/tomcat

使用以下命令创建并运行 Tomcat 容器:

XML 复制代码
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat

参数说明:

  • -id:以分离模式运行容器,并返回容器 ID。
  • --name=c_tomcat:给容器命名为 c_tomcat。
  • -p 8080:8080:将容器的 8080 端口映射到主机的 8080 端口,以便可以通过 http://localhost:8080 访问。
  • -v $PWD:/usr/local/tomcat/webapps:将当前主机目录挂载到容器的 /usr/local/tomcat/webapps,这样可以方便地在主机上管理 web 应用。

访问 Tomcat

在浏览器中输入 http://ip:8080,你应该可以看到 Tomcat 的默认欢迎页面。

Redis

以下是如何在 Docker 中使用 Redis 的详细步骤。

  1. 搜索 Redis 镜像

使用以下命令在 Docker Hub 上搜索 Redis 镜像:

XML 复制代码
docker search redis
  1. 拉取 Redis 镜像

将指定版本的 Redis 镜像拉取到本地:

XML 复制代码
docker pull redis:5.0
  1. 创建容器并设置端口映射

运行 Redis 容器,并将其端口映射到主机:

XML 复制代码
docker run -id --name=c_redis -p 6379:6379 redis:5.0
  1. 连接到 Redis

你可以通过 Docker 的 exec 命令进入已经运行的 Redis 容器,使用 Redis CLI 进行操作:

XML 复制代码
docker exec -it c_redis redis-cli

在 Redis CLI 中,你可以输入 Redis 命令,例如:

XML 复制代码
SET key "value"
GET key

管理容器

查看正在运行的容器:

XML 复制代码
docker ps

停止容器

XML 复制代码
docker stop 容器命名

启动容器

XML 复制代码
docker start 容器命名

删除容器

XML 复制代码
docker rm 容器命名

镜像原理

底层原理

Docker 镜像本质是什么? Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G? Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?

操作系统的组成部分:进程调度子系统、进程通信子系统、内存管理子系统、设备管理子系统、文件管理子系统、网络通信子系统、作业控制子系统

Linux文件系统由bootfs和rootfs两部分组成:

  • bootfs:包含bootloader(引导加载程序)和 kernel(内核)

  • rootfs: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件

  • 不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos

Docker镜像原理:

  • Docker镜像是一个分层文件系统,是由特殊的文件系统叠加而成,最底端是 bootfs,并复用宿主机的bootfs ,第二层是 root文件系统rootfs称为base image,然后再往上可以叠加其他的镜像文件

  • 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统

  • 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。

  • 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器

问题:

  • Docker 中一个Ubuntu镜像为什么只有200MB,而一个Ubuntu操作系统的iso文件要几个个G? Ubuntu的iso镜像文件包含bootfs和rootfs,而docker的Ubuntu镜像复用操作系统的bootfs,只有rootfs和其他镜像层

  • Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB? 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB

镜像制作

Dockerfile

基本概述

Dockerfile是一个文本文件,包含一条条的指令,每一条指令构建一层,基于基础镜像最终构建出新的镜像

  • 对于开发人员:可以为开发团队提供一个完全一致的开发环境

  • 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了

  • 对于运维人员:在部署时,可以实现应用的无缝移植

关键字 作用 备注
FROM 指定父镜像 指定dockerfile基于那个image构建
MAINTAINER 作者信息 用来标明这个dockerfile谁写的
LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"]
CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build的时候复制文件到image中
ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell
Centos

自定义centos7镜像:

  1. 默认登录路径为 /usr

  2. 可以使用vim

实现步骤:

  1. 定义父镜像:FROM centos:7

  2. 定义作者信息:MAINTAINER seazean < zhyzhyang@sina.com>

  3. 执行安装vim命令: RUN yum install -y vim

  4. 定义默认的工作目录:WORKDIR /usr

  5. 定义容器启动执行的命令:CMD /bin/bash

  6. 通过dockerfile构建镜像:docker bulid --f dockerfile文件路径 --t 镜像名称:版本

Boot

定义dockerfile,发布springboot项目:

实现步骤:

  1. 定义父镜像:FROM java:8

  2. 定义作者信息:MAINTAINER seazean < zhyzhyang@sina.com>

  3. 将jar包添加到容器: ADD springboot.jar app.jar

  4. 定义容器启动执行的命令:CMD java--jar app.jar

  5. 通过dockerfile构建镜像:docker bulid --f dockerfile文件路径 --t 镜像名称:版本

服务编排

基本介绍

微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。

  • 从Dockerfile build image 或者去dockerhub拉取image;

  • 创建多个container,管理这些container(启动停止删除)

服务编排:按照一定的业务规则批量管理容器

Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:

  1. 利用 Dockerfile 定义运行环境镜像

  2. 使用 docker-compose.yml 定义组成应用的各服务

  3. 运行 docker-compose up 启动应用

虚拟机

容器:

  • 容器是将软件打包成标准化单元,以用于开发、交付和部署

  • 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置

  • 容器化软件在任何环境中都能够始终如一地运行。

  • 容器赋予了软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突

容器和虚拟机对比:

  • 相同:容器和虚拟机具有相似的资源隔离和分配优势

  • 不同:

    • 容器虚拟化的是操作系统,虚拟机虚拟化的是硬件。

    • 传统虚拟机可以运行不同的操作系统,容器只能运行同一类型操作系统

    特性 容器 虚拟机
    启动 秒级 分钟
    硬盘使用 一般为MB 一般为GB
    性能 接近原生 弱于原生
    系统支持量 单机支持上千个容器 一般几十个
相关推荐
V_fanglue370516 分钟前
qmt量化交易策略小白学习笔记第67期【qmt编程之获取ETF申赎清单】
大数据·前端·数据库·笔记·python·学习·区块链
鸿_H16 分钟前
激光slam学习笔记4--slam_in_autonomous_driving编译碰到问题汇总
笔记
HC182580858321 小时前
生活英语口语柯桥学英语“再确认一下“ 说成 “double confirm“?这是错误的!
学习·职场和发展
软糖工程0011 小时前
正则表达式【详细解读】
大数据·前端·爬虫·python·学习·正则表达式·数据分析
月夕花晨3742 小时前
C++学习笔记(45)
c++·笔记·学习
这河里吗l2 小时前
Java每日面试题(JVM)(day15)
java·开发语言·jvm·笔记·后端
笑鸿的学习笔记2 小时前
git笔记之重置本地仓库所有分支和远程保持一致、工作区恢复干净,像刚clone下来一样
笔记·git·elasticsearch
apz_end3 小时前
Python Flask网页开发基本框架
开发语言·后端·python·学习·flask·编程学习
六个核桃Lu3 小时前
每天学习一个技术栈 ——【Django Channels】篇(2)
学习