嵌入式——Linux 学习之路(二):Docker

嵌入式 —— Linux 学习之路(二):Docker

一、Ubuntu1604 安装 Docker

1、使用官方安装脚本自动安装

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

错误1:
  可能会提示未安装 curl,
解决1:
  按照提示安装即可,sudo apt install curl
  
错误2:

  在这里插入图片描述

解释2:
  弃用警告
  这个Linux发行版(ubuntu xenia)已经到了生命的尽头,不再受此脚本的支持。
解决2:
  使用其他更高版本的ubuntu,或进行手动安装

2、使用国内 daocloud 一键安装命令

curl -sSL https://get.daocloud.io/docker | sh

3、手动安装

a)卸载旧版本

sudo apt-get remove docker docker-engine docker.io containerd runc
  1. Docker 的旧版本被称为 docker,docker.io 或 docker-engine 。
    如果已安装,请卸载它们。
  2. 当前称为 Docker Engine-Community 软件包 docker-ce。

b)更新 apt 包索引

sudo apt-get update

c)安装 apt 依赖包,用于通过HTTPS来获取仓库

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

d)添加 Docker 的官方 GPG 密钥

curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

e)写入软件源信息,设置稳定版仓库

sudo add-apt-repository \
  "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu \
  $(lsb_release -cs) \
  stable"

f)更新并安装 最新版本的 Docker Engine-Community 和 containerd

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

g)测试 Docker 是否安装成功

sudo docker run hello-world

打印出以下信息则安装成功:
  在这里插入图片描述

h)查找仓库中 Docker-CE 的版本

apt-cache madison docker-ce

查找即如果如下:
  在这里插入图片描述

i)安装指定版本的方式(与步骤 f 的区别)

sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

备注:
<VERSION_STRING> - 使用第二列中的版本字符串安装特定版本
例如 5:20.10.7 ~ 3-0~ubuntu-xenial

4、查看 Docker 版本信息

docker version

查看结果如下:
  
在这里插入图片描述

5、启动与停止 Docker 服务

1. 启动
sudo service docker start
2. 停止
sudo service docker stop
3. 重启
sudo service docker restart

6、卸载 Docker

根据自己电脑安装情况进行卸载
  在这里插入图片描述

1. 查看相关插件
dpkg -l | grep docker 
2. 删除安装包(以下两种选择其中一个)
sudo apt-get purge docker-ce
或
sudo apt-get autoremove docker docker-ce docker-engine  docker.io  containerd runc
3. 删除镜像、容器、配置文件等内容
sudo rm -rf /var/lib/docker
4. sudo rm -rf /etc/systemd/system/docker.service.d(如果存在改文件)

二、Win7 安装 Docker

1、官方网站:https://docs.docker.com/
  Docker现在主推Win10下的操作,Win7使用toolbax。(官方途径下载很慢,不推荐)
2、

三、为什么要学习 Docker

1、Linux 的部署形式

  1. 很久很久以前是如何部署服务器应用的:
      
    在这里插入图片描述
  • 部署非常慢
  • 成本非常高
  • 资源浪费
  • 难于迁移和扩展
  • 可能会被限定硬件厂商
      
  1. 由于物理机的诸多问题,后来出现了虚拟机,常见的形式如下:
      宿主机(例如:windows笔记本) + vmware 虚拟机 + ubuntu(ISO镜像) = 得到一个可以使用的 Linux 系统
      在安装好的 Linux 系统上部署软件在这里插入图片描述
  • 一台物理机可以通过 vmware 虚拟化安装多个操作系统
  • 每个操作系统可以运行单独的App
  • 虚拟化也是有局限性的,每一个虚拟机都是一个完整的操作系统,要分配系统资源
  • 虚拟机多到一定程度,宿主机本身的的资源也就消耗殆尽,需要进行扩容

2、虚拟化技术

懂了!VMware/KVM/Docker原来是这么回事儿

3、虚拟出一个隔离的程序运行环境

  1. 虚拟机中的程序说:我只是想要一个单独的执行执行环境,不需要你费那么大劲去虚拟出一个完整的计算机来。
  2. 一台物理机可能同时虚拟出10台虚拟机就已经开始感到乏力了,但同时虚拟出100个虚拟的执行环境却还是能够从容应对,这对于资源的充分利用可是有巨大的好处。
  3. 容器技术可以高效地利用硬件资源实现云服务

4、容器技术

  1. Docker 最初是 DotCloud 公司在法国期间发起的一个公司内部项目,后来以 Apache2.0 授权协议开源,代码在 Github 上维护。
  2. Docker 是基于 Google 公司推出的 Golang 语言开发而来,基于 Linux 内核的 Cgroups、NameSpace,以及 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
  3. 由于隔离的进程独立于宿主机和其他隔离的进程,也称之为容器。
  4. 最初的 Docker 是基于 LXC 的,后来去除 LXC 转而使用自行开发的 Libcontainer。
  5. Docker 被定义为开源的容器引擎,可以方便地对容器进行管理,例如:对镜像打包封装,引入 Docker Registry 对镜像统一管理。
  6. 利用 Docker 可以实现开发,测试,生产环境的部署一致性,极大地减少运维成本。
  7. 容器内的应用程序直接运行在宿主机的内核上,容器内没有自己的内核,也没有对硬件进行虚拟,因此容器比起虚拟机更为轻便。

5、为什么要选择 Docker

  1. Docker 更高效地利用系统资源
  • 容器不需要进行硬件虚拟化以及运行一个完整操作系统的额外开销,无论是应用执行,文件存储,还是在内存消耗等方面,都比传统虚拟机更高效。
  1. 更快的启动时间
  • Docker 容器直接运行在宿主机的内核上,无需启动一个完整的操作系统,可以达到秒级启动。
  1. 一致性的环境
  • 在企业里,程序从开发环境,到测试服务器,到生产环境,难以保证机器环境的一致性,极大可能出现系统依赖冲突,导致难以部署等BUG。
  • 利用 Docker 的容器-镜像技术,提供了除了内核以外完整的运行时环境,确保了应用环境的一致性。
  1. 持续交付和部署
  • 利用 Docker 可以制定镜像,以达到持续集成,持续交付和部署。
  • 通过 Dockerfile 来进行镜像构建,实现系统集成测试,运维进行生产环境的部署。
  • 且 Dockerfile 可以使镜像构建透明化,方便技术团队能够快速理解运行环境部署流程。
  1. 更轻松的迁移
  • Docker 可以在很多平台运行,无论是物理机,虚拟机,云端服务器等环境,运行结果都是一致的。
  1. Docker 能做什么
  • 可以把应用程序代码及运行依赖环境打包成镜像,最为交付介质,在各个环境部署。
  • 可以将镜像(image)启动成为容器(container),并且提供多容器的生命周期进行管理(启、停、删)。
  • container 容器之间相互隔离,且每个容器可以设置资源限额。
  • 提供轻量级虚拟化功能,容器就是在宿主机中的一个个的虚拟的空间,彼此相互隔离,完全独立。

四、Docker 安装部署

1、Docker 引擎

在这里插入图片描述

2、Docker Daemon

安装使用 Docker,得先运行 Docker daemon 进程,用于管理 Docker,如:

  • 镜像 images
  • 容器 containers
  • 网络 network
  • 数据卷 Data Volumes

3、Rest 接口

  • 提供和 Daemon交互的API接口

4、Docker Client

  • 客户端使用 RESET API 和 Docker Daemon 进行访问

5、Docker 平台组成

在这里插入图片描述

  1. Images
  • 镜像是一个只读模板,用于创建容器,也可以通过 Dockerfile 文本描述镜像的内容。
  • 镜像的概念类似于编程开发里面对象的类,从一个基类开始(基础镜像 Base Image)构建容器的过程,就是运行镜像,生成容器实例。
  • Docker 镜像的描述文件是 Dockerfile,包含了如下指令:
    – FROM    ,定义基础镜像
    – MAINTAINER,作者
    – RUN    ,运行 Linux 命令
    – ADD    ,添加文件/目录
    – ENV    ,环境变量
    – CMD    ,运行进程
      
  1. Container
  • 容器是一个镜像的运行实例,镜像 > 容器
  • 创建容器的过程:
    a)获取镜像,如:docker pull centos,从镜像仓库拉取
    b)使用镜像创建容器
    c)分配文件系统,挂载一个读写层,在读写层加载镜像
    d)分配网络/网桥接口,创建一个网络接口,让容器和宿主机通讯
    e)容器获取 IP 地址
    f)执行容器命令,如:/bin/bash
    g)反馈容器启动结果
      
  1. Registry
  • Docker 镜像需要进行管理,docker 提供 Registry 仓库,其实它也是一个容器。
  • 可以基于该容器运行私有仓库。
  • 也可以使用 Docker Hub 互联网公有镜像仓库。

6、安装 Docker

a)开启 Linux 内核的流量转发(暂未使用)

cat <<EOF > /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.ip_forward = 1
EOF

b)加载修改内核的参数,配置文件(暂未使用)

modprobe br_netfilter #(如果直接下面的命令有错,则先执行该命令)
sysctl -p /etc/sysctl.d/docker.conf

c)安装 Docker 参考第一章节

d)镜像加速器

  • 使用 Docker 首要操作就是获取镜像文件,默认下载是从 Docker Hub 下载,网速较慢
  • 国内很多云服务商都提供了加速服务,阿里云加速器,Daocloud 加速器,灵雀云加速器

e)修改 Docker 配置文件

sudo vi /etc/docker/daemon.json

写入内容如下:(七牛云加速器)
{
	"registry-mirrors" : [
		"https://reg-mirror.qiniu.com"
	]
}

建议添加多个
 {
      "registry-mirrors" : [
          "https://reg-mirror.qiniu.com",
          "https://docker.mirrors.ustc.edu.cn/",
          "https://8xpk5wnt.mirror.aliyuncs.com"
     ]
}

f)重新启动服务

sudo systemctl daemon-reload
sudo systemctl enable docker #(设置开启自启,看自己需求设置)
sudo systemctl restart docker

g)查看 Docker 进程

ps -ef | grep docker

查看结果如下:
  在这里插入图片描述

h)查看 Docker 是否正确启动

sudo docker version

查看结果如下:
  在这里插入图片描述

五、启动第一个 Docker 容器

1、获取镜像

  • 获取镜像是从你配置好的 Docker 镜像站中,去拉取镜像
  1. 先搜索镜像
sudo docker search nginx

在这里插入图片描述

  1. 拉取镜像
sudo pull nginx

在这里插入图片描述

  1. 查看本地的 Docker 镜像有哪些
sudo docker image ls

在这里插入图片描述

2、运行镜像,生成容器

  1. 运行该 nginx 镜像,运行出具体的容器,然后这个容器就跑着一个 nginx 服务了
#docker run 参数 镜像的名字/id
# -d 后台运行容器
#-p 80:80 端口映射,宿主机端口:容器内端口,你访问宿主机的这个端口,也就访问到了容器内的端口
#docker run 命令会返回一个容器的id
sudo docker run -d -p 80:80 nginx

在这里插入图片描述

  1. 查看容器是否在运行
sudo docker ps

在这里插入图片描述

  1. 此时可以访问宿主机的80端口,查看到容器内的80端口的应用是什么了
    在这里插入图片描述
    在这里插入图片描述

  2. 停止具体容器的进程

#docker stop 容器id
sudo docker stop 10b91fb6f107

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

  1. 启动容器
sudo docker start 10b91fb6f107
  1. 删除镜像 hello-world
sudo docker rmi feb5d9fea6a5

六、Docker 的生命周期

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

七、Docker 镜像的原理

1、 快速实践,使用 Docker,来切换不同的发行版,内核使用的都是宿主机的内核

#运行最新的ubuntu版本
#运行容器,且进入容器内
# -i 交互式命令操作
# -t 开启一个终端
# ba6acccedd2 镜像的id
# bash 进入容器后,执行的命令
sudo docker run -it ba6acccedd29 bash

# 退出容器
exit

在这里插入图片描述

在这里插入图片描述

2、理解什么是 Docker 镜像

  1. 一个完整的 Docker 镜像可以创建出 Docker 容器的运行,
  • 例如一个 centos:7.8.2003 镜像文件,我们获取的是 centos7 这个发行版本
  • 这个镜像文件是不包含 linux 内核的
  • Docker的架构,镜像就是一个【发行版】的作用,你需要准备好一个 linux 内核
  • 然后上层使用不同的【发行版】就好了,这样就可以自由使用各种发行版本系统,兼容多种环境
    在这里插入图片描述在这里插入图片描述
  1. Docker 镜像的层级概念
  • 如果我们想要定义一个 mysql5.6 镜像,我们会这么做
  • 获取基础镜像,选择一个发行版平台
  • 在 ubuntu 镜像中安装 mysql5.6 软件
  • 导出镜像,可以命名为 mysql:5.6 镜像文件
  • 从这个过程中,我们可以感觉出这是一层层地添加的,Docker 镜像的层级概念就出来了
    底层是 ubuntu 镜像,上层是 mysql 镜像,ubuntu 镜像层属于父镜像
    在这里插入图片描述
  1. 进入到正在运行的容器内
sudo docker exec -it  bash

在这里插入图片描述

4、Docker 为什么分层镜像

  • 镜像分层一大好处就是共享资源
  • 例如有多个镜像都来自于同一个 base 镜像,那么在 docker host 只需要存储一份 base 镜像
  • 内存里也只需要加载一份 host,即可为多个容器服务
  • 即使多个容器共享一个 base 镜像,某个容器修改了 base 镜像的内容,例如修改 /etc/下配置文件,其他容器的 /etc/ 下的内容是不会被修改的
  • 修改动作只限制在单个容器内,这就是容器的写入时复制特性

5、可写的容器层

  • 当容器启动后,一个新的可写层被加载到镜像的顶部
  • 这一层通常被称为容器层
  • 容器层下的都称为镜像层
    在这里插入图片描述
    在这里插入图片描述

6、Docker 镜像的内容

  • Docker 镜像层级管理的方式大大便捷了 Docker 镜像的分发和存储
  • Docker Hub 是为全世界的镜像仓库
  • Docker 镜像代表一个容器的文件系统内容
  • 镜像层级技术属于联合文件系统
  • 容器是一个动态的环境,每一层镜像里的文件都属于静态内容
  • Dockerfile 里的 ENV、CMD等内容都会落实到容器环境里
    在这里插入图片描述

八、获取镜像

1、镜像托管仓库

  • 默认的 Docker 仓库是 dockerhub,有大量的优质镜像,以及用户自己上传的镜像

2、搜索镜像

# docker search <镜像名>:<tag>
# <tag> 为具体的标签版本
sudo docker ubuntu

3、查看本地的镜像文件有哪些

sudo docker images
sudo docker image ls

4、下载 Docker 镜像

# 默认的是 centos:lastest
sudo docker pull centos
# 指定版本 centos:lastest:tag
sudo docker pill centos:7.8.2003

5、查看 Docker 镜像的存储路径

# 查看 Docker 的信息
sudo docker info

# 查找路径
sudo docker | grep Root

# 路径为 : /var/lib/docker/image/overlay2/imagedb/content/sha256
# 该路径下的文件为 json 数据类型
# 该文件的作用是 : 记录镜像和容器的配置关系

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

6、使用不同的镜像,生成容器

# -it - 开启一个交互式的终端
# --rm - 容器退出时删除该容器
# bash - 进入容器后执行的内容
sudo docker run -it --rm ubuntu bash

7、如何查看 centos 的标签信息

https://hub.docker.com/_/centos

九、查看镜像

1、查看本地镜像

sudo docker images

# 查看具体的镜像
sudo docker images ubuntu

# 指定具体的 tag
sudo docker images centos:7.8.2003

# 只列出镜像的 id
# -q
# --quiet
sudo dcker images -q
sudo dcker images -quiet

# 按格式显示
# 这是 docker 的模板语言,--format
sudo docker images --format "{{.ID}}--{{.Repository}}"

# 以表格形式显示
sudo docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"

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

十、删除镜像

1、下载一个 hello-world 镜像

sudo docker hello-world

2、运行 hello-world 生成容器

sudo docker run hello-world

3、删除 hello-world

# 根据镜像的 id,名字,摘要等方式进行删除
sudo docker rmi hello-world

# 指定 id 的前三位即可
sudo docker rmi feb

删除结果如下:删除失败,hello-world正在被容器6959e376594a 使用

  • 被删除的镜像,不得有依赖的容器记录在这里插入图片描述
    在这里插入图片描述

4、查看正在运行或运行过的容器

# 查看正在运行的容器
sudo docker ps
# 查看运行过的容器
sudo docker ps -a

在这里插入图片描述

5、删除容器记录

sudo docker rm ac2abc057f9b

在这里插入图片描述

十一、镜像管理

1、批量删除镜像的用法(危险)

# 列出所有镜像
sudo docker images -a
# 列出所有镜像 id
sudo docker images -aq

#删除所有镜像
sudo rmi `docker images -aq`

在这里插入图片描述

2、批量删除容器

sudo docker rm `docker ps -aq`

3、导出镜像

sudo docker run -it ubuntu bash

# 运行默认的 ubuntu 镜像不提供 vim
# 可以运行该容器后,在容器内安装 vim
# 然后提交该镜像,再导出该镜像为压缩文件,可以给其他人用
# 提交镜像暂时不在这里讲解
sudo docker image save ubuntu > /home/ubuntu/myubuntu.tgz

若出现如下结果,容器内无法安装 vim,则先进行 apt-get update

  • 使用容器内默认的源下载速度很慢,可以使用 sed 指令替换源
# 修改 /etc/apt/sources.list 文件,
# 将 http://.*security.ubuntu.com替换成http://repo.huaweicloud.com 或者阿里云源(http://mirreors.aliyun.com)
sed -i "s@http://.*archive.ubuntu.com/@http://repo.huaweicloud.com/@g" /etc/apt/sources.list
sed -i "s@http://.*security.ubuntu.com/@http://repo.huaweicloud.com/@g" /etc/apt/sources.list

在这里插入图片描述

在这里插入图片描述

4、导入镜像

sudo docker image load -i /home/ubuntu/myubuntu.tgz

注意:myubuntu 与 ubuntu 是一致的,直接导入只显示一个,需要先删除 ubuntu
  
在这里插入图片描述

5、查看镜像详细信息

# 查看 docker 服务的信息
sudo docker info

# 列出镜像的json信息
sudo docker image inspect <镜像id>

十一、容器管理

1、创建 + 启动

# 如果镜像不存在本地,则会在线去下载该镜像
docker run <镜像名>
  • docker run 等于创建 + 启动
  • 注意:
  1. 容器内的进程必须处于前台运行状态,否则容器就会直接退出(自己部署一个容器运行,命令不得后台运行,前台运行即可)
  2. 如果容器内,什么事也没做,容器也会挂掉(容器内必须有一个进程在前台运行)

2、运行一个挂掉的容器

# 这个写法会产生容器记录,且容器内没有程序在跑,因此挂了
sudo docker run ubuntu

#运行容器,且进入容器内,且在容器内执行某个命令
sudo docker run -it ubuntu bash

# 开启一个容器,并执行某个程序(属于前台运行,会卡住一个终端)
sudo docker run ubuntu ping www.baidu.com

# 运行一个活着的容器(docker ps 可以看到的容器)
# -d - 让容器在后台跑着(针对宿主机而言)
# 返回容器 id
sudo docker run -d ubuntu ping www.baidu.com

# --rm - 容器挂掉后不产生容器记录(docker ps -a 无法看到这个容器运行过的记录)
sudo docker run -d --rm ubuntu ping www.baidu.com

# --name - 给容器起个名字叫 pingbaidu
sudo docker run -d --rm --name pingbaidu ubuntu ping www.baidu.com

3、查看容器日志的方法

# 打印至今为止的日志
sudo docker logs <容器id>

# 实时刷新日志
sudo docker logs -f <容器id>

# 查看最新的5条日志
sudo docker logs <容器id> | tail 5

4、进入容器空间内

# 进入正在运行的容器
sudo docker exec -it <容器id> bash

5、查看容器的详细信息

sudo docker container inspect <容器id>

6、容器的端口映射

# 后台运行 nginx 容器,且起个名字,且端口映射宿主机85端口,访问到容器内的80端口
sudo docker run -d --name my_ngix -p 85:80 nginx

# 查看容器的端口转发情况
sudo docker port <容器id>

# 随机端口映射
# 随机访问一个宿主机的空闲端口,映射到容器内打开的端口
sudo docker run -d --name my_ngix_1 -P nginx

7、容器的提交

# 运行基础的ubuntu,在容器内安装vim,然后提交新镜像
# 新镜像再运行出的容器,默认就携带vim了
sudo docker commit <容器id> <新的镜像名>

十二、Dockerfile 创建镜像

1、创建镜像的两个方法

  1. 手动修改容器的内容,然后 docker commit 提交容器为新的镜像
  2. 通过在 dockerfile 中定义一系列的命令和参数构成的脚本,然后这些命令应用于基础镜像,依次添加层,最终生成一个新的镜像。极大地简化了部署工作。

2、官方提供的 Dockerfile 实例

https://github.com/CentOS/CentOS-Dockerfiles

3、dockerfile 主要组成部分

  1. 基础镜像信息 FROM centos:6.8
  2. 制作镜像操作指令 RUN yum install openssh-server -y
  3. 容器启动时执行指令 CMD [“/bin/bash”]

4、Dockerfile 指令

  1. FROM - 指定基础镜像(这个镜像的妈妈是谁?)
  2. MAINTAINER - 指定维护者信息(可以没有,告诉别人,谁负责养它?)
  3. RUN - 在命令前加上RUN即可(你想让他干啥)
  4. ADD - 添加宿主机的文件到容器内,会自动解压(给它点创业资金)
  5. WORKDIR - 设置当前工作目录(我是xiaoming,今天刚化了妆)
  6. VOLUME - 设置卷,挂载主机的目录(给它一个存放行李的地方)
  7. EXPOSE - 指定对外端口(它要打开的门是啥)
  8. CMD - 指定容器启动后要干的事(奔跑吧,兄弟)
  9. COPY - 和ADD的作用是一样的,复制宿主机的文件到容器内,但不会解压
  10. ENV 环境变量
  11. ENTRYPOINT - 容器启动会后执行的命令

十三、快速入门 Dockerfile

1、通过 Dockerfile,构建 nginx 镜像,且运行容器后,生成的页面是"超哥带你学习docker"

# 1. 创建 Dockerfile,注意文件名,必须是这个
FROM nginx
RUN echo '<meta charset=utf8>超哥带你用docker运行nginx服务.' > /usr/share/nginx/html/index.html

# 2. 构建 Dockerfile
sudo docker build .

# 3. 修改镜像名
sudo docker tag <镜像id> my_nginx

# 4. 运行该镜像
sudo docker run -d -p 80:80 my_nginx bash

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

2、COPY 指令用法

copy chaoge.py /home

# 支持多个文件,以及通配符形式复制,语法要满足Golang的filepath.Match
copy chaoge* /tmp/cc?.txt /home/

# COPY指令能够保留源文件的元数据,如权限,访问时间等等

3、ADD 指令用法

# 特性和COPY基本一致,不过多了一些功能
# 1. 源文件是一个URL,此时docker引擎会下载该链接,放入目标路径,且权限自动设置为600,若这不是期望结果,还得增加一层RUN指令进行调整
# 2. 源文件是一个URL,且是一个压缩包,不会自动解压,也得单独用RUN指令解压
# 3. 源文件是一个压缩文件,且是gzip,bzip2,xz,tar情况,ADD指令会自动解压该文件到目标路径

ADD xxx.tar /home/

# Dockerfile官方更推荐使用COPY,ADD包含了更多复杂的功能,且ADD会使构建缓存失效,导致镜像构建缓慢

3、CMD 指令用法

# 用法,注意是双引号
CMD ["参数1","参数2"]
# 在指定了entrypoint指令后,用CMD指定具体参数

# docker不是虚拟机,容器就是一个进程,既然是进程,那么程序在启动的时候需要指定一些运行参数,这就是CMD指令的作用

# 例如centos镜像默认的CMD是/bin/bash,直接docker run -it centos会直接进入bash解释器
# 也可以启动容器时候,指定参数. docker run -it centos cat /etc/os-release

# CMD运行shell命令,也会被转化为shell形式
# 例如
CMD echo $PATH
# 会被转化为
CMD ["sh","-c","echo $PATH"]

4、容器内运行的程序

# 这里要注意的是,docker不是虚拟机的概念,虚拟机里的程序运行,基本都是在后台运行,利用systemctl运行,但容器内没有后台进程的概念,必须在前台运行

# 容器就是为了主进程而存在的,主进程如果退出了,容器也就失去意义,自动退出

# 例如有一个经典问题
CMD systemctl start nginx
# 这样的写法是错误的,容器会立即退出
# 因为systemctl start nginx是希望以守护进程形式驱动nginx,且CMD命令会转化为
CMD ["sh","-c","systemctl start nginx"]
# 这样的命令主进程是sh解释器,执行完毕后立即结束了,因此容器也就退出了。
# 因此正确的做法应该是
CMD ["nginx", "-g", "daemon off"]

5、ENTRYPOINT

和RUN指令一样,分为两种格式

  • exec
  • shell

作用和CMD一样,都是在指定容器启动程序以及参数
当指定了ENTRYPOINT之后,CMD指令的语义就有了变化,而是把CMD的内容当做参数传递给ENTRYPOINT指令

实际用法

  1. 准备好Dockerfile
FROM centos:7.8.2003
RUN rpm --rebuilddb && yum install epel-release -y
RUN rpm --rebuilddb && yum install curl -y
CMD ["curl","-s","http://ipinfo.io/ip"]
# 用法如下
docker run my_centos curl -s http://ipinfo.io/ip
#
docker run my_centos

# 2. 构建镜像
docker build .

# 3. 查看结果
Successfully built 92cd201c87bc

# 4.  运行镜像,生成容器记录,没有前台运行,因此立即挂了
docker run my_centos 

# 5. 上述运行正确,但我想再传入一个参数,该怎么办
# 发现是无法直接传入参数的,该形式是覆盖镜像中的cmd
docker run ny_centos -I

# 6. 想要正确地给容器传入一个 -I 参数该怎么办
# 希望容器内能正确完整执行这个命令
curl -s  http://ipinfo.io/ip -I

# 7. 解决办法1
# 给容器传入新的完整的命令

# 8. 正确的方法应该是使用 ENTRYPOINT
# 修改Dockerfile如下
FROM centos:7.8.2003
RUN rpm --rebuilddb && yum install epel-release -y
RUN rpm --rebuilddb && yum install curl -y
ENTRYPOINT ["curl","-s","http://ipinfo.io/ip"]

在这里插入图片描述

6、ARG 和 ENV

都是设置环境变量,区别在于ENV无论是在镜像构建时,还是在容器运行时,该变量都可以使用
  
ARG只用于构建镜像需要设置的变量,容器运行时消失了

ENV NAME="yuchao"
ENV AGE="18"
ENV MYSQL_VERSION=5.6
RUN yun install mysql-$NAME
# 后续所有操作,通过$NAME就可以直接获取变量值操作了,维护Dockerfile脚本时更加友好方便

7、VOLUME

容器在运行时,应该保证在存储层不写入任何数据,运行在容器内产生的数据,我们推荐是挂载,写到宿主机上进行维护

VOLUME /data # 将容器内的/data文件夹,在容器运行时,该目录自动挂载为匿名卷,任何向该目录中写入数据的操作,都不会被容器记录,保证容器存储层无状态理念

# Dockerfile
FROM centos
MAINTAINER chaoge
VOLUME ["/data1","/data2"]
# 该容器运行时,自动和宿主机的目录做好映射关系
docker build .
docker run <容器id>
docker inspect <容器id> # 查看映射情况

容器数据挂载的方式,

  1. 通过Dockerfile,指定VLUME目录
  2. 通过docker run -v参数,直接设置需要映射挂载的目录

8、EXPOSE

指定容器运行时对外提供的端口服务

  • 帮助使用该镜像的人,快速理解容器的一个端口业务
docker port 容器
docker run -p 宿主机端口:容器端口
docker run -P # 作用是随机宿主机端口:容器端口 

9、WORKDIR

用于在Dockerfile中,目录切换,更改工作目录

WORKDIR /opt

10、USER

用于改变环境,用于切换用户

USER root
USER chaoge

参考资料

1、菜鸟教程
https://www.runoob.com/docker/ubuntu-docker-install.html
2、阿里云开发者社区
Docker CE 镜像源站
懂了!VMware/KVM/Docker原来是这么回事儿

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值