Docker 容器开发:虚拟化
Docker 容器开发:虚拟化
Docker 的核心价值在于虚拟化或者说环境隔离【通过虚拟化技术实现虚拟环境】,解决环境配置和部署的依赖问题实现解耦
我对虚拟化的理解源自《Operating Systems: Three Easy Pieces》,推荐阅读
容器技术相关历史推荐知乎上的这篇文章:容器技术的历史
Docker 基本概念
Docker 提供了在称为容器的松散隔离环境中打包和运行应用程序的能力
- 镜像(Image):镜像是一个只读的模板,用于创建 Docker 容器
- 容器(Container):容器是一个可运行的实例,是镜像的运行时实例
两者的关系类似于面向对象编程中的类和对象
Docker 生态系统
- Docker 注册表(Docker Registry):Docker 注册表是一个存储和分发 Docker 镜像的场所
- Docker 客户端(Docker Client):用于与 Docker 服务器交互的 CLI 工具
- Docker 服务器(Docker Server):Docker 服务器是一个守护进程,用于管理 Docker 对象,如镜像、容器、网络和卷
- Docker Hub:这是所有自定义镜像的存储库,类似于 GitHub
一种技术的发展离不开生态系统的支持,Docker 的生态系统也是 Docker 成功的重要原因之一,像 Git 与 GitHub、Node.js 与 npm、Python 与 PyPI 等技术都有类似的生态系统
关于 Docker 安装,这里不再赘述,可以参考官方文档:Get Docker
不过我比较好奇的是 Docker 是基于 Linux 的 Kernal 实现的,那么在 Windows 和 Mac 上如何运行呢?反正因为这个在 Windows 和 Mac 安装会相对麻烦一点。我只是练习使用是在虚拟机中使用 Debian 安装的
只不过需要说明一下,一般在安装 Docker 后,关于 Docker 相关内容需要使用 sudo 进行提权,如果想方便使用应该将你想使用的用户添加到 docker 组中,命令:
sudo usermod -aG docker $USER
Docker 使用容器
通过镜像创建容器
一般在创建容器的过程:
- Docker 守护进程首先尝试在本地仓库查找 Image
- 如果本地没有对应 Image 会继续远程拉取
- 在 Docker 守护进程成功获取 Image,后会通过 Image 创建 Container
示例:
# hello-world 镜像是用于测试的,通过下面命令可以创建对应容器并运行此容器
docker run hello-world
#### 下面是会显示的内容 #####
# 这是本地没有 hello-world 镜像
Unable to find image 'hello-world:latest' locally
# 下面是真的进行远程拉取,并创建容器
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9
Status: Downloaded newer image for hello-world:latest
# 下面是容器运行的内容,除了首行外我使用 ... 做了省略
Hello from Docker!
...
其中的拉取操作可以单独进行,使用
docker pull <images-name>[:<version>]其中
run的语法大致是docker run <images-name>[:<version>]使用
docker ps可以查看所有 正在运行的容器,通过添加-a选项可以查看所有可用dd简单说明,列表头的含义
- CONTAINER ID:显示每个容器的唯一 ID
- IMAGE:创建容器的图像
- COMMAND:启动时在容器中执行的命令
- CREATED:容器被创建的时间
- STATUS:容器的当前状态
- PORTS:如果任何容器端口映射情况
- NAMES:这是容器的名称,如果没有设置会随机生成一个并且是唯一的
说明一下
<>表示里面的内容是变换的[]表示里面的内容是可选的
接下来,需要简单说明一下镜像中的层,就是 hello-world 中 2db29710123e: Pull complete 做一下解释:
- 由于每个镜像都构建在 Linux 内核之上,因此它具有一些可以被其他镜像重用的共同依赖项
- Docker 将这些依赖项捆绑在一个堆栈中,这些堆栈称为层
- 只有指令 RUN、COPY、ADD 创建层,其他指令创建临时中间图像并且不会增加构建的大小
# 测试拉取 Nginx 这种相对 hello-world 大的镜像
docker pull nginx
#### 结果 ####
Using default tag: latest
latest: Pulling from library/nginx
# 被分五层
f1f26f570256: Pull complete
7f7f30930c6b: Pull complete
2836b727df80: Pull complete
e1eeb0f1c06b: Pull complete
86b2457cc2b0: Pull complete
9862f2ee2e8c: Pull complete
Digest: sha256:2ab30d6ac53580a6db8b657abf0f68d75360ff5cc1670a85acb5bd85ba1b19c0
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
- 分层不取决于镜像大小,它的决定性因素是设计者,在于共同依赖项的设计上,有时一个小镜像也会有大量分层
交互模式的容器,我们以 python:3.6 为例,先创建对应容器 docker run python:3.6
在使用
ps查看时会发现没有容器,那是因为容器并没有运行,所以需要使用-a选项CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8cc71dccbb99 python:3.6 "python3" 10 minutes ago Exited (0) 10 minutes ago cool_mendel
fba35ad4d200 hello-world "/hello" About an hour ago Exited (0) About an hour ago elastic_wing
们就一直在说 Docker 使用 Linux 内核作为容器,我们创建使用 bash 交互模式的容器
在运行容器时,使用
-it选项【实际是两个选项联用】,语法是:docker run -it <image-name> bash-t完整选项是--tty:作用是分配一个伪 tty-i完整选项是--interactive:作用是保持STDIN打开【即使未连接】,其实从 interactive 的中文意思就可以理解
# 创建使用 bash 交互式 tty 的 python:3.6 容器
docker run -it python:3.6 bash
#### 结果:目前处于虚拟 Linux 操作系统中 ####
root@84779de65a0b:/#
#### 交互操作过程 ####
# 使用 id 确认自己权限身份
root@84779de65a0b:/# id
uid=0(root) gid=0(root) groups=0(root)
# 退出 exit,提示如果退出容器它将停止,想要验证使用 docker ps 看有没有容器运行
root@84779de65a0b:/# exit
exit
learn@debian10:~$
- 现在我们能够创建可以访问 bash 的容器
如何再次使用停止的 Docker 容器
通过 docker ps -a 我们已经有三个容器,现在学习如何让停止的容器运行
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84779de65a0b python:3.6 "bash" 8 minutes ago Exited (0) 3 minutes ago romantic_meninsky
8cc71dccbb99 python:3.6 "python3" 37 minutes ago Exited (0) 37 minutes ago cool_mendel
fba35ad4d200 hello-world "/hello" 2 hours ago Exited (0) 11 minutes ago elastic_wing
语法是
docker start <container-id>,我们选择 romantic_meninsky【之前通过docker run -it python:3.6 bash创建的容器】,类比推理如果要停止运行容器docker stop <container-id>,重启使用docker restart <container-id>learn@debian10:~$ docker start 84779de65a0b
84779de65a0b
learn@debian10:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84779de65a0b python:3.6 "bash" 16 minutes ago Up 6 seconds romantic_meninsky
romantic_meninsky 容器再次运行了,通过
docker exec -it <container-id|container-name> bash可以重新登录容器的 bash,解释说明|是或的意思在其中表示使用容器 ID 或容器名称,比如:docker exec -it 84779de65a0b bash等价docker exec -it romantic_meninsky bash
docker exec -it 84779de65a0b bash
#### 结果:再次进入容器 romantic_meninsky ###
root@84779de65a0b:/#
#### 容器内操作 ####
# 我们将在容器中安装一些东西,以便我们可以在其中编写一些 python 脚本
# 修改 apt 源【国内镜像快一点】,命令 sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
root@84779de65a0b:/# sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 更新 apt 缓存,命令 apt update
root@84779de65a0b:/# apt update
# 安装一个编辑器,随意 vim, nano, ... 选你熟悉的
root@84779de65a0b:/# apt install vim
# 编辑器创建 hello-world.py
root@84779de65a0b:/# vim hello-world.py
#### vim 编辑器内容,进入编辑器按 i 键会进入编辑器模式 ####
print("Hello World")
#### vim End,按 Esc 键切换模式,再按 : 键输入 wq 即可保存退出 ####
# 运行 hello-world.py,当然这只是测试用,也可以写其他 Python 程序并运行
root@84779de65a0b:/# python hello-world.py
Hello World
# 退出
root@84779de65a0b:/# exit
exit
- 我们可以通过这样的方法对容器进行开发
- 在实际开发环境中还会与一些编辑器进行联合使用,比如 Visual Studio Code
通过容器创建镜像
在经过这些操作后,容器内部已经发生变动,现在我们将这个容器打包为镜像,语法 docker commit -m "<commit-message>" <container-id|name> <new-image-name>:<version>,这个有点像 Git 的提交操作,其中 -m 是添加注释信息的
docker commit -m "python36 Hello World Test" 84779de65a0b my-python36-hello-world:1.0
#### 结果:会输出一段 SHA256 作为生成镜像的哈希校验 ####
sha256:2f12c4d8f189633c4b0b58e6496f429f125a125cdd47e016991af721569a763e
# 通过 docker images 可以查看本地镜像仓库
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-python36-hello-world 1.0 2f12c4d8f189 2 minutes ago 958MB
nginx latest 080ed0ed8312 7 days ago 142MB
python 3.6 54260638d07c 15 months ago 902MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
通过下面操作可以将本地镜像推送到远程仓库 Docker Hub 中
- 你需要一个自己的 Docker Hub 帐户,并进行登录
docker login -u <username>,建议登录时使用 Access Tokens 方式进行【在 https://hub.docker.com/ 上设置】,登出docker logout - 设置 tag 标签,语法
docker tag <image-name>:<version> <username>/<image>:<version>对于 tag 标签作用有点类似虚拟机拍摄快照,相当于镜像的快照,实际应该以版本为单位使用 tag 标签记录
- 设置 tag 标签,语法
- 使用推送,语法
docker push <username>/<image>:<version>
# 设置 tag 标签 docker tag my-python36-hello-world:1.0 shadow7749/my-python36-hello-world:1.0
learn@debian10:~$ docker tag my-python36-hello-world:1.0 shadow7749/my-python36-hello-world:1.0
# 查看本地镜像仓库变化
learn@debian10:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-python36-hello-world 1.0 2f12c4d8f189 29 minutes ago 958MB
shadow7749/my-python36-hello-world 1.0 2f12c4d8f189 29 minutes ago 958MB
nginx latest 080ed0ed8312 7 days ago 142MB
python 3.6 54260638d07c 15 months ago 902MB
hello-world latest feb5d9fea6a5 18 months ago 13.3kB
# 推送,此操作必须确认你已经登录
learn@debian10:~$ docker push shadow7749/my-python36-hello-world:1.0
The push refers to repository [docker.io/shadow7749/my-python36-hello-world]
ff540de539ad: Pushed
aa4c808c19f6: Mounted from library/python
8ba9f690e8ba: Mounted from library/python
3e607d59ef9f: Mounted from library/python
1e18e7e1fcc2: Mounted from library/python
c3a0d593ed24: Mounted from library/python
26a504e63be4: Mounted from library/python
8bf42db0de72: Mounted from library/python
31892cc314cb: Mounted from library/python
11936051f93b: Mounted from library/python
1.0: digest: sha256:790bdc67737ed40e747fa9f1b7fb2831ac09031811036d2c9bda3a4b4eb56b94 size: 2430
- 完成后,你可以登录 https://hub.docker.com/ 确认是否推送到远程仓库中
/// 这便是一个简单的 Docker 容器开发流程:
拉取镜像 --> 创建容器 --> 开发容器 --> 生成镜像 --> tag 标签 --> 推送镜像
^ |
|------------- 继续开发 --------------|
补充说明:删除容器和镜像
- 删除容器,需要先停止容器,然后使用
docker rm <container-id> - 清理掉所有处于终止状态的容器的快捷方式
docker container prune - 删除镜像使用
docker rmi <image-id>,记忆上镜像的删除无非是多个i表示 image
后续内容:Docker 容器数据:持久化
Docker 容器开发:虚拟化的更多相关文章
- 八种Docker容器开发模式解析
原文链接:http://www.csdn.net/article/2014-10-27/2822294 Docker优点已经说过很多次,这里不做详述,Docker现在越来越受到开发人员的青睐,而且利用 ...
- 快速理解Docker - 容器级虚拟化解决方案
是什么 简单的说Docker是一个构建在LXC之上的,基于进程容器(Processcontainer)的轻量级VM解决方案 拿现实世界中货物的运输作类比, 为了解决各种型号规格尺寸的货物在各种运输工具 ...
- [Docker] 容器开发环境最佳实践理论
保持 image 小 选择合适的 base image. 使用 multi-stage 构建. https://docs.docker.com/develop/develo ...
- 1.Docker容器学习之新生入门必备基础知识
0x00 Docker 快速入门 1.基础介绍 描述:Docker [ˈdɑ:kə(r)] 是一个基于Go语言开发实现的遵循Apache 2.0协议开源项目,目标是实现轻量级的操作系统虚拟化解决方案: ...
- docker容器的学习笔记
目录 Docker入门学习笔记(一) 1. 什么是Docker? 2. Docke的目标 3. Docker通常应用场景 4. Docker的基本组成 补:Docker容器相关技术简介 安装Docke ...
- 【linxu】部署docker容器虚拟化平台
实验所涉内容 Docker 概述 部署 docker 容器虚拟化平台 docker 平台基本使用方法 创建docker镜像和发布镜像方法 Container 容器端口映射 一 Docker 概述 Do ...
- Linux高级运维 第八章 部署docker容器虚拟化平台
8.1 Docker概述 实验环境: CENTOS7.4-63 64位 Dcoker概述 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到 ...
- URLOS开发基础教程——docker容器的使用方法
URLOS本是基于docker容器运行,在入门URLOS开发之前,我们首先需要掌握docker的相关基础知识,本篇就以docker容器的基本使用方法为例,快速的让大家对docker有一个全面的印象. ...
- 开发自己的 chart - 每天5分钟玩转 Docker 容器技术(167)
Kubernetes 给我们提供了大量官方 chart,不过要部署微服务应用,还是需要开发自己的 chart,下面就来实践这个主题. 创建 chart 执行 helm create mychart 的 ...
- spring boot本地开发与docker容器化部署的差异
spring boot本地开发与docker容器化部署的差异: 1. 文件路径及文件名区别大小写: 本地开发环境为windows操作系统,是忽略大小写的,但容器中区分大小写 2. docker中的容器 ...
随机推荐
- 电脑临时文件清理2个方法?%temp% cleanmgr
按住电脑快捷键win+R,打开运行框 输入代码 %temp%,点击回车enter或者点击确定,打开temp文件夹[此处存放的都是系统无用的缓存垃圾] 按快捷键Ctrl + A ,点击delete,删除 ...
- k8s——kubctl命令基础
语法 kubevtl [command] [type] [name] [flags] command: 指定要对一个或多个资源执行的操作,例如,`create`,`get`,`describe`,`d ...
- kettle从入门到精通 第五十六课 ETL之kettle Microsoft Excel Output
1.9.4 版本的kettle中有两个Excel输出,Excel输出和Microsoft Excel输出.前者只支持xls格式,后者支持xls和xlsx两种格式,本节课主要讲解步骤Microsoft ...
- Vue第三方库与插件实战手册
title: Vue第三方库与插件实战手册 date: 2024/6/8 updated: 2024/6/8 excerpt: 这篇文章介绍了如何在Vue框架中实现数据的高效验证与处理,以及如何集成E ...
- 『手写Mybatis』实现映射器的注册和使用
前言 如何面对复杂系统的设计? 我们可以把 Spring.MyBatis.Dubbo 这样的大型框架或者一些公司内部的较核心的项目,都可以称为复杂的系统. 这样的工程也不在是初学编程手里的玩具项目,没 ...
- 交通规划四阶段法:基于 Python 的交通分布预测算法复现 - 附完整代码链接
目录 交通规划四阶段法:基于 Python 的交通分布预测算法复现 - 附完整代码链接 我只是想使用这些代码 下载代码文件 代码的使用方法 合作 部分代码内容的展示 交通规划四阶段法:基于 Pytho ...
- 详解Web应用安全系列(3)失效的身份认证
大多数身份和访问管理系统的设计和实现,普遍存在身份认证失效的问题.会话管理是身份验证和访问控制的基础,并且存在于所有有状态的应用程序中.攻击者可以使用指南手册来检测失效的身份认证,但通常会关注密码转储 ...
- FEDORA 显卡驱动安装
FEDORA 显卡驱动安装 在fedora中akmod-nvidia包可以自动的处理开源驱动屏蔽等各种问题, 强烈推荐用这个安显卡驱动. -1. 在 BIOS 中关闭安全启动 0. 切换桌面环境至 X ...
- 基于 SQLite 3 的 C 学习:1-开发流程 与 基本函数
背景 SQLite 是 一个 常用于 嵌入式平台的 轻量级的 关系型数据库. 我们已经介绍了 移植 SQLite 3 ,这一讲我们来介绍它的开发,这里仅仅涉及最基本的开发. 高级api:https:/ ...
- uboot 修改代码 增加 环境变量
--- title: uboot修改代码增加环境变量 date: 2019-12-27 21:26:39 categories: tags: - uboot --- 以"tftp下载kern ...