鹤啸九天 自律更自由,平凡不平庸 Less is More

Docker学习笔记

2020-08-06
鹤啸九天
         
阅读量

Notes(温馨提示):

  1. ★ 首次阅读建议浏览:导航指南, 或划到本页末尾, 或直接点击跳转, 查看全站导航图
  2. 右上角工具条搜索文章,右下角二维码关注微信公众号(鹤啸九天),底栏分享、赞赏、评论
  3. ★ 转载请注明文章来源,知识点积累起来不容易,水滴石穿,绳锯木断,谢谢理解
  4. ★ 如有疑问,邮件讨论,欢迎贡献优质资料


总结

【2024-4-16】docker是什么?和kubernetes(k8s)是什么关系?

  • docker是什么?
  • docker架构原理?
  • docker的命令基础
  • docker容器和虚拟机有什么区别?
  • docker compose是什么?
  • docker swarm是什么?
  • docker compose和docker swarm的区别是什么?
  • docker和kubernetes(k8s)的关系是什么?
  • docker swarm和kubernetes(k8s)的差异是什么?

k8s

【2021-12-1】从零开始入门 K8s:详解 K8s 核心概念

从零开始入门 K8s:详解 K8s 核心概念

一、什么是 Kubernetes

Kubernetes,从官方网站上可以看到,它是一个工业级的容器编排平台。Kubernetes 这个单词是希腊语,它的中文翻译是“舵手”或者“飞行员”。在一些常见的资料中也会看到“ks”这个词,也就是“K8s”,它是通过将 8 个字母“ubernete ”替换为“8”而导致的一个缩写

Kubernetes 为什么要用“舵手”来命名呢?大家可以看一下这张图:

这是一艘载着一堆集装箱的轮船,轮船在大海上运着集装箱奔波,把集装箱送到它们该去的地方。我们之前其实介绍过一个概念叫做 container,container 这个英文单词也有另外的一个意思就是“集装箱”。Kubernetes 也就借着这个寓意,希望成为运送集装箱的一个轮船,来帮助我们管理这些集装箱,也就是管理这些容器。

这个就是为什么会选用 Kubernetes 这个词来代表这个项目的原因。更具体一点地来说:Kubernetes 是一个自动化的容器编排平台,它负责应用的部署、应用的弹性以及应用的管理,这些都是基于容器的。

二、Kubernetes 有如下几个核心的功能:

  • 服务的发现与负载的均衡;
  • 容器的自动装箱,我们也会把它叫做 scheduling,就是“调度”,把一个容器放到一个集群的某一个机器上,Kubernetes 会帮助我们去做存储的编排,让存储的声明周期与容器的生命周期能有一个连接;
  • Kubernetes 会帮助我们去做自动化的容器的恢复。在一个集群中,经常会出现宿主机的问题或者说是 OS 的问题,导致容器本身的不可用,Kubernetes 会自动地对这些不可用的容器进行恢复;
  • Kubernetes 会帮助我们去做应用的自动发布与应用的回滚,以及与应用相关的配置密文的管理;
  • 对于 job 类型任务,Kubernetes 可以去做批量的执行;
  • 为了让这个集群、这个应用更富有弹性,Kubernetes 也支持水平的伸缩。

下面,我们希望以三个例子跟大家更切实地介绍一下 Kubernetes 的能力。

1、调度

Kubernetes 可以把用户提交的容器放到 Kubernetes 管理的集群的某一台节点上去。Kubernetes 的调度器是执行这项能力的组件,它会观察正在被调度的这个容器的大小、规格。

比如说它所需要的 CPU 以及它所需要的 memory,然后在集群中找一台相对比较空闲的机器来进行一次 placement,也就是一次放置的操作。在这个例子中,它可能会把红颜色的这个容器放置到第二个空闲的机器上,来完成一次调度的工作。

2、自动修复

Kubernetes 有一个节点健康检查的功能,它会监测这个集群中所有的宿主机,当宿主机本身出现故障,或者软件出现故障的时候,这个节点健康检查会自动对它进行发现。

下面 Kubernetes 会把运行在这些失败节点上的容器进行自动迁移,迁移到一个正在健康运行的宿主机上,来完成集群内容器的一个自动恢复。

3、水平伸缩

Kubernetes 有业务负载检查的能力,它会监测业务上所承担的负载,如果这个业务本身的 CPU 利用率过高,或者响应时间过长,它可以对这个业务进行一次扩容。

比如说在下面的例子中,黄颜色的过度忙碌,Kubernetes 就可以把黄颜色负载从一份变为三份。接下来,它就可以通过负载均衡把原来打到第一个黄颜色上的负载平均分到三个黄颜色的负载上去,以此来提高响应的时间。

以上就是 Kubernetes 三个核心能力的简单介绍。

三、Kubernetes 的架构

Kubernetes 架构是一个比较典型的二层架构和 server-client 架构。Master 作为中央的管控节点,会去与 Node 进行一个连接。

所有 UI 的、clients、这些 user 侧的组件,只会和 Master 进行连接,把希望的状态或者想执行的命令下发给 Master,Master 会把这些命令或者状态下发给相应的节点,进行最终的执行。

Kubernetes 的 Master 包含四个主要的组件:API Server、Controller、Scheduler 以及 etcd。如下图所示:

  • API Server:顾名思义是用来处理 API 操作的,Kubernetes 中所有的组件都会和 API Server 进行连接,组件与组件之间一般不进行独立的连接,都依赖于 API Server 进行消息的传送;
  • Controller:是控制器,它用来完成对集群状态的一些管理。比如刚刚我们提到的两个例子之中,第一个自动对容器进行修复、第二个自动进行水平扩张,都是由 Kubernetes 中的 Controller 来进行完成的;
  • Scheduler:是调度器,“调度器”顾名思义就是完成调度的操作,就是我们刚才介绍的第一个例子中,把一个用户提交的 Container,依据它对 CPU、对 memory 请求大小,找一台合适的节点,进行放置;
  • etcd:是一个分布式的一个存储系统,API Server 中所需要的这些原信息都被放置在 etcd 中,etcd 本身是一个高可用系统,通过 etcd 保证整个 Kubernetes 的 Master 组件的高可用性。

我们刚刚提到的 API Server,它本身在部署结构上是一个可以水平扩展的一个部署组件;Controller 是一个可以进行热备的一个部署组件,它只有一个 active,它的调度器也是相应的,虽然只有一个 active,但是可以进行热备。

Kubernetes 的架构:Node

Kubernetes 的 Node 是真正运行业务负载的,每个业务负载会以 Pod 的形式运行。等一下我会介绍一下 Pod 的概念。一个 Pod 中运行的一个或者多个容器,真正去运行这些 Pod 的组件的是叫做 kubelet,也就是 Node 上最为关键的组件,它通过 API Server 接收到所需要 Pod 运行的状态,然后提交到我们下面画的这个 Container Runtime 组件中。

在 OS 上去创建容器所需要运行的环境,最终把容器或者 Pod 运行起来,也需要对存储跟网络进行管理。Kubernetes 并不会直接进行网络存储的操作,他们会靠 Storage Plugin 或者是网络的 Plugin 来进行操作。用户自己或者云厂商都会去写相应的 Storage Plugin 或者 Network Plugin,去完成存储操作或网络操作。

在 Kubernetes 自己的环境中,也会有 Kubernetes 的 Network,它是为了提供 Service network 来进行搭网组网的。(等一下我们也会去介绍“service”这个概念。)真正完成 service 组网的组件的是 Kube-proxy,它是利用了 iptable 的能力来进行组建 Kubernetes 的 Network,就是 cluster network,以上就是 Node 上面的四个组件。

Kubernetes 的 Node 并不会直接和 user 进行 interaction,它的 interaction 只会通过 Master。而 User 是通过 Master 向节点下发这些信息的。Kubernetes 每个 Node 上,都会运行我们刚才提到的这几个组件。

下面我们以一个例子再去看一下 Kubernetes 架构中的这些组件,是如何互相进行 interaction 的。

用户可以通过 UI 或者 CLI 提交一个 Pod 给 Kubernetes 进行部署,这个 Pod 请求首先会通过 CLI 或者 UI 提交给 Kubernetes API Server,下一步 API Server 会把这个信息写入到它的存储系统 etcd,之后 Scheduler 会通过 API Server 的 watch 或者叫做 notification 机制得到这个信息:有一个 Pod 需要被调度。

这个时候 Scheduler 会根据它的内存状态进行一次调度决策,在完成这次调度之后,它会向 API Server report 说:“OK!这个 Pod 需要被调度到某一个节点上。”

这个时候 API Server 接收到这次操作之后,会把这次的结果再次写到 etcd 中,然后 API Server 会通知相应的节点进行这次 Pod 真正的执行启动。相应节点的 kubelet 会得到这个通知,kubelet 就会去调 Container runtime 来真正去启动配置这个容器和这个容器的运行环境,去调度 Storage Plugin 来去配置存储,network Plugin 去配置网络。

这个例子我们可以看到:这些组件之间是如何相互沟通相互通信,协调来完成一次 Pod 的调度执行操作的。

四、Kubernetes 的核心概念与它的 API

核心概念

第一个概念:Pod

Pod 是 Kubernetes 的一个最小调度以及资源单元。用户可以通过 Kubernetes 的 Pod API 生产一个 Pod,让 Kubernetes 对这个 Pod 进行调度,也就是把它放在某一个 Kubernetes 管理的节点上运行起来。一个 Pod 简单来说是对一组容器的抽象,它里面会包含一个或多个容器。

比如像下面的这幅图里面,它包含了两个容器,每个容器可以指定它所需要资源大小。比如说,一个核一个 G,或者说 0.5 个核,0.5 个 G。

当然在这个 Pod 中也可以包含一些其他所需要的资源:比如说我们所看到的 Volume 卷这个存储资源;比如说我们需要 100 个 GB 的存储或者 20GB 的另外一个存储。

在 Pod 里面,我们也可以去定义容器所需要运行的方式。比如说运行容器的 Command,以及运行容器的环境变量等等。Pod 这个抽象也给这些容器提供了一个共享的运行环境,它们会共享同一个网络环境,这些容器可以用 localhost 来进行直接的连接。而 Pod 与 Pod 之间,是互相有 isolation 隔离的。

第二个概念:Volume

Volume 就是卷的概念,它是用来管理 Kubernetes 存储的,是用来声明在 Pod 中的容器可以访问文件目录的,一个卷可以被挂载在 Pod 中一个或者多个容器的指定路径下面。

而 Volume 本身是一个抽象的概念,一个 Volume 可以去支持多种的后端的存储。比如说 Kubernetes 的 Volume 就支持了很多存储插件,它可以支持本地的存储,可以支持分布式的存储,比如说像 ceph,GlusterFS ;它也可以支持云存储,比如说阿里云上的云盘、AWS 上的云盘、Google 上的云盘等等。

第三个概念:Deployment

Deployment 是在 Pod 这个抽象上更为上层的一个抽象,它可以定义一组 Pod 的副本数目、以及这个 Pod 的版本。一般大家用 Deployment 这个抽象来做应用的真正的管理,而 Pod 是组成 Deployment 最小的单元。

Kubernetes 是通过 Controller,也就是我们刚才提到的控制器去维护 Deployment 中 Pod 的数目,它也会去帮助 Deployment 自动恢复失败的 Pod。

比如说我可以定义一个 Deployment,这个 Deployment 里面需要两个 Pod,当一个 Pod 失败的时候,控制器就会监测到,它重新把 Deployment 中的 Pod 数目从一个恢复到两个,通过再去新生成一个 Pod。通过控制器,我们也会帮助完成发布的策略。比如说进行滚动升级,进行重新生成的升级,或者进行版本的回滚。

第四个概念:Service

Service 提供了一个或者多个 Pod 实例的稳定访问地址。

比如在上面的例子中,我们看到:一个 Deployment 可能有两个甚至更多个完全相同的 Pod。对于一个外部的用户来讲,访问哪个 Pod 其实都是一样的,所以它希望做一次负载均衡,在做负载均衡的同时,我只想访问某一个固定的 VIP,也就是 Virtual IP 地址,而不希望得知每一个具体的 Pod 的 IP 地址。

我们刚才提到,这个 pod 本身可能 terminal go(终止),如果一个 Pod 失败了,可能会换成另外一个新的。

对一个外部用户来讲,提供了多个具体的 Pod 地址,这个用户要不停地去更新 Pod 地址,当这个 Pod 再失败重启之后,我们希望有一个抽象,把所有 Pod 的访问能力抽象成一个第三方的一个 IP 地址,实现这个的 Kubernetes 的抽象就叫 Service。

实现 Service 有多种方式,Kubernetes 支持 Cluster IP,上面我们讲过的 kuber-proxy 的组网,它也支持 nodePort、 LoadBalancer 等其他的一些访问的能力。

第五个概念:Namespace

Namespace 是用来做一个集群内部的逻辑隔离的,它包括鉴权、资源管理等。Kubernetes 的每个资源,比如刚才讲的 Pod、Deployment、Service 都属于一个 Namespace,同一个 Namespace 中的资源需要命名的唯一性,不同的 Namespace 中的资源可以重名。

Namespace 一个用例,比如像在阿里巴巴,我们内部会有很多个 business units,在每一个 business units 之间,希望有一个视图上的隔离,并且在鉴权上也不一样,在 cuda 上面也不一样,我们就会用 Namespace 来去给每一个 BU 提供一个他所看到的这么一个看到的隔离的机制。

Kubernetes 的 API

下面我们介绍一下 Kubernetes 的 API 的基础知识。从 high-level 上看,Kubernetes API 是由 **HTTP+JSON **组成的:用户访问的方式是 HTTP,访问的 API 中 content 的内容是 JSON 格式的。

Kubernetes 的 kubectl 也就是 command tool,Kubernetes UI,或者有时候用 curl,直接与 Kubernetes 进行沟通,都是使用 HTTP + JSON 这种形式。

下面有个例子:比如说,对于这个 Pod 类型的资源,它的 HTTP 访问的路径,就是 API,然后是 apiVesion: V1, 之后是相应的 Namespaces,以及 Pods 资源,最终是 Podname,也就是 Pod 的名字。

如果我们去提交一个 Pod,或者 get 一个 Pod 的时候,它的 content 内容都是用 JSON 或者是 YAML 表达的。上图中有个 yaml 的例子,在这个 yaml file 中,对 Pod 资源的描述也分为几个部分。

第一个部分,一般来讲会是 API 的 version。比如在这个例子中是 V1,它也会描述我在操作哪个资源;比如说我的 kind 如果是 pod,在 Metadata 中,就写上这个 Pod 的名字;比如说 nginx,我们也会给它打一些 label,我们等下会讲到 label 的概念。在 Metadata 中,有时候也会去写 annotation,也就是对资源的额外的一些用户层次的描述。

比较重要的一个部分叫做 Spec,Spec 也就是我们希望 Pod 达到的一个预期的状态。比如说它内部需要有哪些 container 被运行;比如说这里面有一个 nginx 的 container,它的 image 是什么?它暴露的 port 是什么?

当我们从 Kubernetes API 中去获取这个资源的时候,一般来讲在 Spec 下面会有一个项目叫 status,它表达了这个资源当前的状态;比如说一个 Pod 的状态可能是正在被调度、或者是已经 running、或者是已经被 terminates,就是被执行完毕了。

刚刚在 API 之中,我们讲了一个比较有意思的 metadata 叫做“label”,这个 label 可以是一组 KeyValuePair。

比如下图的第一个 pod 中,label 就可能是一个 color 等于 red,即它的颜色是红颜色。当然你也可以加其他 label,比如说 size: big 就是大小,定义为大的,它可以是一组 label。

这些 label 是可以被 selector,也就是选择器所查询的。这个能力实际上跟我们的 sql 类型的 select 语句是非常相似的,比如下图中的三个 Pod 资源中,我们就可以进行 select。name color 等于 red,就是它的颜色是红色的,我们也可以看到,只有两个被选中了,因为只有他们的 label 是红色的,另外一个 label 中写的 color 等于 yellow,也就是它的颜色是黄色,是不会被选中的。

通过 label,kubernetes 的 API 层就可以对这些资源进行一个筛选,那这些筛选也是 kubernetes 对资源的集合所表达默认的一种方式。

例如说,我们刚刚介绍的 Deployment,它可能是代表一组的 Pod,它是一组 Pod 的抽象,一组 Pod 就是通过 label selector 来表达的。当然我们刚才讲到说 service 对应的一组 Pod,就是一个 service 要对应一个或者多个的 Pod,来对它们进行统一的访问,这个描述也是通过 label selector 来进行 select 选取的一组 Pod。

所以可以看到 label 是一个非常核心的 kubernetes API 的概念,我们在接下来的课程中也会着重地去讲解和介绍 label 这个概念,以及如何更好地去使用它。

k8s 集群

k8s GPU

【2024-4-15】k8s CPU/GPU 集群操作

mlx worker 可用方法

NAME:
   mlx worker - Workspace远程GPU
USAGE:
   mlx worker command [command options] [arguments...]

COMMANDS:
   launch   launch gpu任务
   list     展示GPU Worker
   login    ssh登陆gpu worker
   kill     终止GPU Worker
   quota    展示GPU Worker当前剩余quota
   help, h  Shows a list of commands or help for one command

命令

mlx worker list
# id          cpu    memory    gpu    gpuType        podIP       createdAt             webshell                                                    
# 2106896     6      30        1      A100-SXM-80GB              2024-04-15T08:19:44   https://workspace.**.org/api/v1/workers/2106896/webshell/

mlx worker list # 来查看gpu worker的pod ip
mlx worker login 10.23.19.98 # 登录机器

GPU 资源显示

# 查看额度:
mlx worker quota
# 简洁模式: 
mlx worker quota | grep Gpu

launch 用法

launch [flags] -- COMMAND [args...]

flags:
    cpu: CPU core 数量(默认10)
    memory: 内存大小(默认40GB)    
    gpu: GPU 卡数(默认1)
    type: GPU 类型,如 v100-32g(默认),v100-32g-half(半卡),v100-16g

Launch 示例

launch -- bash 
launch -- python3 benchmark.py
launch --gpu 0 --cpu 50 --memory 200 -- bash script.sh
# 申请特定型号gpu
launch --type A100-SXM-80GB  -- bash # 错误写法
launch --type a10  -- bash # 正确
launch --type a100-80g  -- bash # 正确

mlx

# 再notebook右上角的“新建Remote GPU Kernel”设置worker配置
mlx worker list # 查看当前可用worker
mlx worker launch -- kernel # 拉起远端GPU kernal
mlx worker launch -- bash # 启动 GPU
mlx worker launch -- nvidia-smi # 查看GPU状态
mlx worker launch -- watch -n 1 nvidia-smi # 动态显示GPU状态
mlx worker launch jupyter lab --cpu 2 --gpu 2 --memory 50
nohup mlx worker launch jupyter lab --cpu 2 --gpu 2 --memory 50 &>log_jupyter_lab.txt &
mlx worker launch --type v100-sxm2-32g -- python3 time_v2_diff_sampler.py
  • 启动jupyter lab进程,带GPU——执行第3条命令
mlx worker launch -- jupyter lab # 默认方式,6cpu
mlx worker launch jupyter lab --cpu 2 --gpu 2 --memory 50
nohup mlx worker launch jupyter lab --cpu 2 --gpu 2 --memory 50 &>log_jupyter_lab.txt &
# 多卡训练:
launch --gpu 2 --memory 40 -- horovodrun -np 2 python3 hvd_benchmark.py --batch-size 128

Docker

docker 背景

为什么用 docker ?

问题:平时部署开源项目,总会因系统和软件版本差异引起各种问题

docker 基本解决了各种版本差异问题,真正做到了一键部署使用。

docker 概念

Docker的三大核心概念:镜像、容器、仓库

  • 镜像:类似虚拟机的镜像、用俗话说就是安装文件。
  • 容器:类似一个轻量级的沙箱,容器是从镜像创建应用运行实例,可以将其启动、开始、停止、删除、而这些容器都是相互隔离、互不可见的。
  • 仓库:类似代码仓库,是Docker集中存放镜像文件的场所。

docker 分为镜像容器

  • 镜像是一个静态的文件,用于分发部署。
  • 容器镜像运行起来后的运行时对象,可以在容器里安装软件、添加文件等
    • 修改后可用 docker commit 将容器打成一个新的镜像。
    • 通俗理解:镜像就是一份安装光盘,容器是安装在主机上的操作系统环境。

整体流程

  • docker pull(基础镜像) → docker run(生成容器) → 安装软件、添加文件 → docker commit(打包新镜像) → docker push(发布新镜像)

docker 安装

【2024-4-5】 Docker — 从入门到实践

MacOS

Docker Desktop for Mac 系统最低为 macOS 必须是 10.15 或更高版本

  • Catalina、Big Sur 或者 Monterey,建议升级到最新版本的 macOS。

Homebrew 安装

  • Homebrew 的 Cask 已经支持 Docker Desktop for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装:
brew install --cask docker
docker --version
# Docker version 20.10.0, build 7287ab3
docker info
# 测试 NGINX 服务
docker run -d -p 80:80 --name webserver nginx
docker stop webserver
docker rm webserver

手动安装

Linux

资料

centos下安装docker,前置条件:

  • 64-bit 系统
  • kernel 3.10+
  • 【2024-4-24】docker
# -------- 方法① ----------
curl -sSL https://get.daocloud.io/docker | sh # 一键安装 
# [2024-4-24] 以上方法失效, 改成下面
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

# 手动安装
yum install -y docker-ce docker-ce-cli containerd.io


docker ps # 检测状态
systemctl start docker.service # 启动服务
#systemctl restart docker.service # 重启服务
sudo systemctl enable docker # 开机自启
# -------- 方法② ----------
# 检查内核
uname -r
# 更新yum
yum update
# 添加yum仓库
tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
# 安装docker
yum install -y docker-engine
# 查看是否安装成功
docker version

# 启动docker
systemctl start docker.service
service docker start
# [2024-4-24] docker 启动失败, /etc/init.d/docker: 62: ulimit: error setting limit (Invalid argument)


# 开机启动
sudo systemctl enable docker
# -------- 方法③ ---------- 阿里云镜像 ------
# 安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 
# 设置阿里云镜像源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
# 安装 Docker-CE
sudo yum install docker-ce
# 开机自启
sudo systemctl enable docker 
# 启动docker服务  
sudo systemctl start docker
# 添加docker用户组(可选)
# 1. 建立 Docker 用户组
sudo groupadd docker
# 2.添加当前用户到 docker 组
sudo usermod -aG docker $USER
# 镜像加速配置
# 加速器地址 :
# 阿里云控制台搜索容器镜像服务
# 进入容器镜像服务, 左侧最下方容器镜像服务中复制加速器地址
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["你的加速器地址"]
}
EOF
# 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker

dockerhub镜像

# 下载镜像:docker pull <镜像名:tag>    如:下载centos镜像
sudo docker pull bitnami/tensorflow-serving # 安装TensorFlow serving
docker pull centos
docker pull sameersbn/redmine:latest
# 查看已下载镜像
docker images
# 删除容器
docker rm <容器名 or ID>
# 查看容器日志
docker logs -f <容器名 or ID>
# 查看正在运行的容器
docker ps
# 查看所有的容器,包括已经停止的。
docker ps -a 
# 删除所有容器
docker rm $(docker ps -a -q)
# 停止、启动、杀死指定容器
docker start <容器名 or ID> # 启动容器
docker stop <容器名 or ID> # 启动容器
docker kill <容器名 or ID> # 杀死容器
# 后台运行 docker run -d <Other Parameters>
docker run -d -p 127.0.0.1:33301:22 centos6-ssh
# 暴露端口: 一共有三种形式进行端口映射
docker -p ip:hostPort:containerPort # 映射指定地址的主机端口到容器端口
# 例如:docker -p 127.0.0.1:3306:3306 映射本机3306端口到容器的3306端口
docker -p ip::containerPort # 映射指定地址的任意可用端口到容器端口
# 例如:docker -p 127.0.0.1::3306 映射本机的随机可用端口到容器3306端口
docer -p hostPort:containerPort # 映射本机的指定端口到容器的指定端口
# 例如:docker -p 3306:3306 # 映射本机的3306端口到容器的3306端口
# 映射数据卷
docker -v /home/data:/opt/data # 这里/home/data 指的是宿主机的目录地址,后者则是容器的目录地址

构建docker镜像

构建Docker镜像有以下两种方法:

  • 1:使用docker commit命令。
  • 2:使用docker build命令和 Dockerfile 文件。 一般情况下并不推荐使用“docker commit”来构建镜像,而应该使用更灵活、更强大的Dockerfile来构建Docker镜像,这里就来说一下使用Dockerfile创建镜像,创建容器并运行的方法。

  • 注意:源码文件和Dockerfile文件放到同一个目录下
    • Dockerfile
    • jdk-8u162-linux-x64.tar.gz

docker GUI 管理

推荐使用 Portainer 作为容器的 GUI 管理方案。官方地址

# 安装
docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

IP:9000 即可进入容器管理页面

Docker命令

常用命令

docker常用命令精华

# 构建镜像(当前目录dockerfile)
#   -t 镜像名称及标签(name:tag),tag一般表示版本号,一次构建中可以设置多个tag
#   . 待构建的上下文环境目录
docker build -t myubuntu:v1 .
# 构建镜像:指定源dockerfile
docker build . -f ./build/fpm/Dockerfile  -t php:latest

# 查看生成的镜像
docker images
# 创建容器(命名为myubuntu_test)并运行命令(/bin/bash), 映射到本地主机 127.0.0.1 的 8111 端口上
docker run -it -p 127.0.0.1:8111:80 --name myubuntu_test myubuntu:v8 /bin/bash
# 后台模式启动容器
docker run -p 127.0.0.1:8111:80 -d --name myubuntu_test myubuntu:v8
# 登录到容器中
docker run -it myubuntu_test /bin/bash
# 查看运行中的容器:
docker ps
# 查看所有容器:
docker ps -a

docker help
# 搜索仓库镜像:
docker search 镜像名
# 拉取镜像:
docker pull 镜像名
# 查看正在运行的容器:
docker ps
# 查看所有容器:
docker ps -a
# 删除容器:
docker rm container_id
# 查看镜像:
docker images
# 删除镜像:
docker rmi image_id
# 启动(停止的)容器:
docker start 容器ID
# 停止容器:
docker stop 容器ID
# 重启容器:
docker restart 容器ID
# 启动(新)容器:
docker run -it ubuntu /bin/bash
# 进入容器:推荐使用后者
docker attach 容器ID
docker exec -it 容器ID /bin/bash

容器生命周期管理命令

  • run:创建一个新的容器。
  • start/stop/restart
    • docker start # 启动一个或多个已经被停止的容器。
    • docker stop # 停止一个运行中的容器。
    • docker restart # 重启容器。
  • kill:杀掉一个运行中的容器。可选参数:
    • -s : 发送什么信号到容器,默认 KILL
  • rm:删除一个或多个容器。
  • create:创建一个新的容器但不启动它。
  • exec:在运行的容器中执行命令。可选参数:
    • -d : 分离模式: 在后台运行
    • -i : 即使没有附加也保持STDIN 打开
    • -t : 分配一个伪终端
  • pause/unpause
    • docker pause :暂停容器中所有的进程。
    • docker unpause :恢复容器中所有的进程。
# 使用docker镜像nginx:latest以后台模式启动一个容器, 并将容器命名为mynginx。  
docker run --name mynginx -d nginx:latest  
# 使用镜像 nginx:latest,以后台模式启动一个容器, 将容器的 80 端口映射到主机的 80 端口, 主机的目录 /data 映射到容器的 /data。  
docker run -p 80:80 -v /data:/data -d nginx:latest  
# 使用镜像nginx:latest以交互模式启动一个容器, 在容器内执行/bin/bash命令。  
docker run -it nginx:latest /bin/bash  
# 启动已被停止的容器mynginx  
docker start mynginx  
# 停止运行中的容器mynginx  
docker stop mynginx  
# 重启容器mynginx  
docker restart mynginx  

# 根据容器名字杀掉容器  
docker kill tomcat7  
# 根据容器ID杀掉容器  
docker kill 65d4a94f7a39  

# 强制删除容器 db01、db02:  
docker rm -f db01 db02  
# 删除容器 nginx01, 并删除容器挂载的数据卷:  
docker rm -v nginx01  
# 删除所有已经停止的容器:  
docker rm $(docker ps -a -q) 

# 使用docker镜像nginx:latest创建一个容器,并将容器命名为mynginx  
docker create --name mynginx nginx:latest     

# 在容器 mynginx 中以交互模式执行容器内 /root/nginx.sh 脚本  
docker exec -it mynginx /bin/sh /root/nginx.sh  
# 在容器 mynginx 中开启一个交互模式的终端  
docker exec -i -t  mynginx /bin/bash  
# 也可以通过 docker ps -a 命令查看已经在运行的容器,然后使用容器 ID 进入容器。  
docker ps -a   
docker exec -it 9df70f9a0714 /bin/bash  

# 暂停数据库容器db01提供服务。  
docker pause db01  
# 恢复数据库容器 db01 提供服务  
docker unpause db0  

容器操作命令

  • ps:列出容器。可选参数:
    • -a : 显示所有的容器,包括未运行的。
    • -f : 根据条件过滤显示的内容。
    • –format : 指定返回值的模板文件。
    • -l : 显示最近创建的容器。
    • -n : 列出最近创建的n个容器。
    • –no-trunc : 不截断输出。
    • -q : 静默模式,只显示容器编号。
    • -s : 显示总的文件大小。
  • 补充说明:
    • 容器的7种状态:created(已创建)、restarting(重启中)、running(运行中)、removing(迁移中)、paused(暂停)、exited(停止)、dead(死亡)。
  • inspect:获取容器/镜像的元数据。可选参数:
    • -f : 指定返回值的模板文件。
    • -s : 显示总的文件大小。
    • –type : 为指定类型返回JSON。
  • top:查看容器中运行的进程信息,支持 ps 命令参数。
  • events:获取实时事件。参数说明:
    • -f : 根据条件过滤事件;
    • –since : 从指定的时间戳后显示所有事件;
    • –until : 流水时间显示到指定的时间为止;
  • logs:获取容器的日志。参数说明:
    • -f : 跟踪日志输出
    • –since : 显示某个开始时间的所有日志
    • -t : 显示时间戳
    • –tail : 仅列出最新N条容器日志
  • export:将文件系统作为一个tar归档文件导出到STDOUT。参数说明:
    • -o : 将输入内容写到文件。
  • port:列出指定的容器的端口映射。
# 列出所有在运行的容器信息。  
docker ps  
# 列出最近创建的5个容器信息。  
docker ps -n 5  
# 列出所有创建的容器ID。  
docker ps -a -q  
# 获取镜像mysql:5.7的元信息。  
docker inspect mysql:5.7  
# 获取正在运行的容器mymysql的 IP。  
docker inspect --format='\{\{range .NetworkSettings.Networks\}\}\{\{.IPAddress\}\}\{\{end\}\}' mymysql  

# 查看容器mymysql的进程信息。  
docker top mymysql  

# 查看所有运行容器的进程信息。  
for i in  `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done  

# 显示docker 2016年7月1日后的所有事件。  
docker events  --since="1467302400"  

# 显示docker 镜像为mysql:5.6 2016年7月1日后的相关事件。  
docker events -f "image"="mysql:5.6" --since="1467302400"   
# 说明:如果指定的时间是到秒级的,需要将时间转成时间戳。如果时间为日期的话,可以直接使用,如–since=“2016-07-01”。

# 跟踪查看容器mynginx的日志输出。  
docker logs -f mynginx  
# 查看容器mynginx从2016年7月1日后的最新10条日志。  
docker logs --since="2016-07-01" --tail=10 mynginx  

# 将id为a404c6c174a2的容器按日期保存为tar文件。  
docker export -o mysql-`date +%Y%m%d`.tar a404c6c174a2  

ls mysql-`date +%Y%m%d`.tar  

# 查看容器mynginx的端口映射情况。  
docker port mymysql  

容器rootfs命令

  • commit: 从容器创建一个新镜像。参数说明:
    • -a : 提交的镜像作者;
    • -c : 使用Dockerfile指令来创建镜像;
    • -m : 提交时的说明文字;
    • -p : 在commit时,将容器暂停。
  • cp: 用于容器与主机之间的数据拷贝。参数说明:
    • -L : 保持源目标中的链接
  • diff: 检查容器里文件结构的更改。
# 将容器a404c6c174a2 保存为新的镜像,
# 并添加提交人信息和说明信息。  
docker commit -a "guodong" -m "my db" a404c6c174a2  mymysql:v1   

# 将主机/www/runoob目录拷贝到容器96f7f14e99ab的/www目录下。  
docker cp /www/runoob 96f7f14e99ab:/www/  
# 将主机/www/runoob目录拷贝到容器96f7f14e99ab中,目录重命名为www。  
docker cp /www/runoob 96f7f14e99ab:/www  
# 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中。  
docker cp  96f7f14e99ab:/www /tmp/  

# 查看容器mymysql的文件结构更改。  
docker diff mymysql  

镜像仓库命令

仓库命令

  • login/logoutdocker
  • login : 登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hubdocker
  • logout :登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub参数说明:
  • 登陆到Docker Hub
    • docker login -u 用户名 -p 密码
    • -u : 登陆的用户名
    • -p : 登陆的密码
  • pull:从镜像仓库中拉取/更新指定镜像到本地。参数说明:
    • -a : 拉取所有 tagged 镜像
    • –disable-content-trust : 忽略镜像的校验,默认开启
    • docker pull ***
  • push:将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。参数说明:
    • –disable-content-trust : 忽略镜像的校验,默认开启
  • search:从Docker Hub查找镜像。参数说明:
    • –automated : 只列出 automated build类型的镜像;
    • –no-trunc : 显示完整的镜像描述;
    • -f <过滤条件>: 列出指定条件的镜像。
# 登出Docker Hub  
docker logout  

# 从Docker Hub下载java最新版镜像。  
docker pull java  

# 从Docker Hub下载REPOSITORY为java的所有镜像。  
docker pull -a java  

# 上传本地镜像myapache:v1到镜像仓库中。  
docker push myapache:v1  

# 从 Docker Hub 查找所有镜像名包含 java,并且收藏数大于 10 的镜像  
docker search -f stars=10 java  
#NAME                  DESCRIPTION                           STARS   OFFICIAL   AUTOMATED  
#java                  Java is a concurrent, class-based...   1037    [OK]         
#anapsix/alpine-java   Oracle Java 8 (and 7) with GLIBC ...   115                [OK]  
#develar/java                                                 46                 [OK]  

# 每列参数说明:
# NAME: 镜像仓库源的名称
# DESCRIPTION: 镜像的描述
# OFFICIAL: 是否 docker 官方发布
# stars: 类似 Github 里面的 star,表示点赞、喜欢的意思
# AUTOMATED: 自动构建

运行镜像

# 运行镜像生成一个容器
# -it 表示启动时进入一个交互命令行,后面可以在这个命令行安装软件等各种操作;
# --gpus all 表示容器需要用到宿主机的显卡,如果不需要用显卡不要加这个。
docker run -it --gpus all <image_id>

本地镜像管理命令

  • images:列出本地镜像。参数说明:
    • -a : 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
    • –digests : 显示镜像的摘要信息;
    • -f : 显示满足条件的镜像;
    • –format : 指定返回值的模板文件;
    • –no-trunc : 显示完整的镜像信息;
    • -q : 只显示镜像ID。
  • rmi:删除本地一个或多个镜像。参数说明:
    • -f : 强制删除;
    • –no-prune : 不移除该镜像的过程镜像,默认移除;
  • tag: 标记本地镜像,将其归入某一仓库。
  • build: 用于使用 Dockerfile 创建镜像。参数说明:
    • –build-arg=[] : 设置镜像创建时的变量;
    • –cpu-shares : 设置 cpu 使用权重;
    • –cpu-period : 限制 CPU CFS周期;
    • –cpu-quota : 限制 CPU CFS配额;
    • –cpuset-cpus : 指定使用的CPU id;
    • –cpuset-mems : 指定使用的内存 id;
    • –disable-content-trust : 忽略校验,默认开启;
    • -f : 指定要使用的Dockerfile路径;
    • –force-rm : 设置镜像过程中删除中间容器;
    • –isolation : 使用容器隔离技术;
    • –label=[] : 设置镜像使用的元数据;
    • -m : 设置内存最大值;
    • –memory-swap : 设置Swap的最大值为内存+swap,”-1”表示不限swap;
    • –no-cache : 创建镜像的过程不使用缓存;
    • –pull : 尝试去更新镜像的新版本;
    • –quiet, -q : 安静模式,成功后只输出镜像 ID;
    • –rm : 设置镜像成功后删除中间容器;
    • –shm-size : 设置/dev/shm的大小,默认值是64M;
    • –ulimit : Ulimit配置。
    • –squash : 将 Dockerfile 中所有的操作压缩为一层。
    • –tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
    • –network: 默认 default。在构建期间设置RUN指令的网络模式
  • history: 查看指定镜像的创建历史。参数说明:
    • -H : 以可读的格式打印镜像大小和日期,默认为true;
    • –no-trunc : 显示完整的提交记录;
    • -q : 仅列出提交记录ID。
  • save: 将指定镜像保存成 tar 归档文件。参数说明:
    • -o : 输出到的文件。
  • load: 导入使用 docker save 命令导出的镜像。参数说明:
    • –input , -i : 指定导入的文件,代替 STDIN。
    • –quiet , -q : 精简输出信息。
  • import: 从归档文件中创建镜像。参数说明:
    • -c : 应用docker 指令创建镜像;
    • -m : 提交时的说明文字;
# 查看本地镜像列表。  
docker images  
# 列出本地镜像中REPOSITORY为ubuntu的镜像列表。  
docker images  ubuntu  

# 强制删除本地镜像 guodong/ubuntu:v4。  
docker rmi -f guodong/ubuntu:v4  

# 将镜像ubuntu:15.10标记为 runoob/ubuntu:v3 镜像。  
docker tag ubuntu:15.10 runoob/ubuntu:v3  

# 使用当前目录的 Dockerfile 创建镜像,标签为 runoob/ubuntu:v1  
docker build -t runoob/ubuntu:v1 .   

# 使用URL github.com/creack/docker-firefox 的 Dockerfile 创建镜像  
docker build github.com/creack/docker-firefox  

# 通过 -f Dockerfile文件的位置 创建镜像  
docker build -f /path/to/a/Dockerfile .  

# 查看本地镜像 guodong/ubuntu:v3 的创建历史。  
docker history guodong/ubuntu:v3  

# 将镜像 runoob/ubuntu:v3 生成 my_ubuntu_v3.tar 文档  
docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3  

# 导入镜像  
docker load --input fedora.tar  

# 从镜像归档文件my_ubuntu_v3.tar创建镜像,命名为runoob/ubuntu:v4  
docker import  my_ubuntu_v3.tar runoob/ubuntu:v4    

基础版本信息命令

  • info: 显示 Docker 系统信息,包括镜像和容器数。
  • version: 显示 Docker 版本信息。
# 查看docker系统信息。  
docker info  
# 版本信息
docker version  

Dockerfile

Dockerfile文件

FROM ubuntu:18.10

# 注视单独成行
#Ingrediten:
#       jdk-8u162-linux-x64.tar.gz

RUN buildDeps='gcc libc6 make ssh net-tools iputils-ping git curl telnet vim yum' \
        && apt-get update       \
        && apt-get install -y $buildDeps        \
        && mkdir -p /opt/java/

COPY ./jdk-8u162-linux-x64.tar.gz  /opt/java/

RUN cd /opt/java/       \
        && tar -zxvf jdk-8u162-linux-x64.tar.gz

ENV JAVA_HOME=/opt/java/jdk1.8.0_162
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/bin/dt.jar:$JAVA_HOME/lib/tools.jar

结束


支付宝打赏 微信打赏

~ 海内存知已,天涯若比邻 ~

Share

Related Posts

标题:机器学习模型评估方法-The-Evaluation-of-Machine Learning

摘要:机器学习项目开始前的核心问题:如何设置指标,评价模型效果?

标题:Web前端服务知识-Web-Serving

摘要:Web开发相关技术知识点

站内可视化导航

文章可视化导读:鼠标划过图形块时,如果出现蓝色光环, 点击即可跳转到对应主题

Comments

--disqus--

    Content
    My Moment ( 微信公众号 )
    欢迎关注鹤啸九天