1.03 docker的镜像和容器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010986776/article/details/84809988

1.docker的底层技术实现架构

  • docker提供了一个开发、打包、运行app的平台
  • 把app和底层infrastructure(基础设施)隔离开
    在这里插入图片描述

2.docker engine

  • docker engine是核心,里面有后台进程,叫dockerd,提供了REST API接口,还提供了CLI接口,可以看出,docker就是一种C/S的架构

3.整体架构

  • Client是客户端,命令行用的命令
  • 中间docker_host是安装docker的机器,可以与Client在同一台机器,这里面重要的概念是镜像(Images)和容器(Containers)
  • Registry是存储镜像公共的服务器,类似于Github,可以存储和获取Registry

4.底层技术支持

  • Namespaces:做隔离pid、net、ipc、mnt、uts,隔离后,可以启多个容器
  • Control groups:做资源限制,可以让一个容器只用200M内存,另一个用300M等
  • Union file systems:Container和image的分层

5.docker image概述

  • 文件和meta data的集合(root filesystem)
  • 分层的,并且每一层都可以添加、改变、删除文件,成为一个新的image
  • 不同的image可以共享相同的layer(层)
  • image本身是read-only的
  • linux有系统空间和用户空间,在系统空间之上,创建不同发行版本的image,在baseImage之上可以进行添加和删除文件,例如安装mysql,就会产生新的一层,成为一个新的image
  • 查看本地存在的image
    在这里插入图片描述
  • 写一个Dockerfile
#选择了一个baseImage
FROM ubuntu
#在image之上运行了update和install
RUN apt-get update && apt-get install -y stress
#要暴露的端口
EXPOSE 6379
#程序入口
ENTRYPOINT ["/usr/bin/redis-server"]
  • 也可以从Registry拉取image,类似于github
  • 例如拉取一个image
    在这里插入图片描述
  • 查看本地image
    在这里插入图片描述
  • 点击Explore,可以查看官方提供的一些image
    在这里插入图片描述
  • 点进某个image,下载时,参照右边的命令就可以,也可以点击左边Tag,根据版本号获取
    在这里插入图片描述
    在这里插入图片描述

6.制作baseImage

  • baseImage:基于系统的基础镜像
  • 创建文件
    在这里插入图片描述
#include<stdio.h>
int main(){
  printf("hello docker\n");
}
  • 安装依赖包
    在这里插入图片描述
  • 编译.c文件
    在这里插入图片描述
  • 可以简单执行一下
    在这里插入图片描述
  • 在当前目录创建文件Dockerfile
    在这里插入图片描述
#从头开始
FROM scratch
#加到根目录
ADD hello /
#运行command,就是根目录下的hello
CMD ["/hello"]
  • 制作baseImage
    在这里插入图片描述
  • 查看制作的image
    在这里插入图片描述
  • 查看image分层
    在这里插入图片描述
  • 运行docker
    在这里插入图片描述

7.container概念和使用

  • 列举当前本地正在运行的container容器
    在这里插入图片描述
  • 列举出所有容器,包括正在运行的和退出的
    在这里插入图片描述
  • 运行一个不存在的image,查看container运行并释放
    在这里插入图片描述
  • 交互式运行容器
    在这里插入图片描述
  • 克隆一个会话,查看当前正在运行的container
    在这里插入图片描述
  • 可以在里面进行centOS相关操作,退出后
    在这里插入图片描述
  • 查看所有docker命令,分为Management Commands和Commands
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 删除container
    在这里插入图片描述
  • 简写:删除一个container
    在这里插入图片描述
  • 简写:删除一个image
    在这里插入图片描述
  • 列举出所有的containerID
    在这里插入图片描述
  • 批量清理运行释放后的container
    在这里插入图片描述
  • container有正在运行的,还有未运行的情况下,先列出status=exited的container,然后最后只删除已经运行结束的container
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

8.创建Image的两种方式

  • 第一种
    在这里插入图片描述
  • 运行centos
    在这里插入图片描述
  • 安装上传下载工具
    在这里插入图片描述
  • 退出container
    在这里插入图片描述
  • 根据安装了lrzsz的image,创建新的image
    在这里插入图片描述
  • 查看新创建的image,与原本centos大小不一样
    在这里插入图片描述
    在这里插入图片描述
  • 第二种
    在这里插入图片描述
  • 创建目录
    在这里插入图片描述
  • 创建Dockerfile文件
FROM centos
RUN yum -y install lrzsz
  • 创建image
    在这里插入图片描述
  • 在一个临时的container中安装lrzsz
    在这里插入图片描述
  • 查看创建的image
    在这里插入图片描述
  • 建议采用第二种方式创建image,分享时,可以将Dockerfile分享给别人,不涉及共享层

9.Dockerfile详解

  • FROM
  • 为了安全,尽量使用官方的image作为base image
FROM scratch			#从头制作base image
FROM centos			#使用已有的base image
FROM ubuntu:14.04	#指定使用的base image的版本
  • LABEL
  • 定义了一些说明信息
  • LABEL Metadata不可少,就像代码的注释
LABEL maintainer="[email protected]"
LABEL version="1.0"
LABEL description="This is description"
  • RUN
  • 每执行一条RUN,就会多一层
  • 为了美观,尽量避免无用的分层
  • 用&&合并语句,用反斜杠合并多条命令为一行
#反斜线换行
RUN yum -y update && yum -y install lrzsz \
	net-tools
RUN apt-get -y update && apt-get -y install lrzsz \
	net-tools
#/bin/bash是shell的一种
RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
  • WORKDIR
  • 进入或创建目录
  • 使用WORKDIR,不要使用RUN cd
  • 尽量使用绝对目录
WORKDIR /root		#进入/root目录
WORKDIR /test		#如果没有会自动创建/test目录
WORKDIR demo
RUN pwd			#输出结果应该是/test/demo
  • ADD and COPY
  • 将本地的文件,添加到Docker image里
  • ADD还可以解压缩到指定目录
  • 大部分情况下,优先使用COPY
ADD hello /
ADD test.tar.gz /	#添加到根目录并解压
WORKDIR /root
COPY hello test/  #最终hello会在目录 /root/test/hello 中
  • ENV
  • 可以增加Dockerfile的可维护性,尽量使用
ENV MYSQL_VERSION 5.6					#设置常量
RUN apt-get -y install mysql-server="${MYSQL_VERSION}" \
	&& rm -rf /var/lib/apt/lists/*	#引用常量

10.Dockerfile——CMD vs ENTRYPOINT

  • 先介绍Shell和Exec格式
#Shell格式
RUN apt-get -y install lrzsz
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
#Exec格式,需要特定的格式
RUN ["apt-get","-y","install","lrzsz"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]
  • ENTRYPOINT(比CMD使用的多)
  • 设置容器启动时运行的命令
  • 让容器以应用程序或者服务的形式运行
  • 不会被忽略,一定会执行
  • 演示如下两个Dockerfile构建出的image,运行有什么不同,shell和exec的区别
#Dockerfile1,shell格式
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
#Dockerfile2,exec格式
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo","hello $name"]
  • 先使用Dockerfile1创建文件,然后构建如下
    在这里插入图片描述

  • 运行构建出来的image
    在这里插入图片描述

  • 用Dockerfile2创建文件,然后构建如下
    在这里插入图片描述

  • 运行构建出来的image
    在这里插入图片描述

  • linux能够识别shell,替换成ENV并执行

  • 修改Dockerfile如下,使之能够识别Exec格式的命令

  • 重新构建和运行image看效果

FROM centos
ENV name Docker
#-c指明参数,-c后的命令要作为一个命令,在一个引号里
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
  • CMD
  • 设置容器启动后默认执行的命令和参数
  • 如果docker指定了其他命令,CMD命令被忽略
  • 如果定义了多个CMD,只有最后一个会执行(可以演示)
  • 如下Dockerfile,与上面ENTRYPOINT的效果一样
FROM centos
ENV name Docker
CMD echo "hello $name"
  • 实践:再创建另一个ENTRYPOINT的image,运行对比
#CMD
FROM centos
ENV name Docker
CMD echo "hello $name"
#ENTRYPOINT
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
  • 构建image
    在这里插入图片描述
    在这里插入图片描述
  • 运行image,创建container,CMD的执行打印命令,被/bin/bash覆盖了
    在这里插入图片描述
    在这里插入图片描述

11.分享docker image

  • image名字一定要以自己docker hub的用户名开头
  • 查看所有image
    在这里插入图片描述
  • 登录,输入用户名和密码
    在这里插入图片描述
  • 上传自己的image
    在这里插入图片描述
  • 删除本地的image
    在这里插入图片描述
  • 从docker hub下载自己上传的image
    在这里插入图片描述

12.分享Dockerfile

  • 直接分享image不安全
  • 分享docker image不如分享Dockerfile
  • 点击如下
    在这里插入图片描述
  • 与gitHub账户关联
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

13.搭建私有docker registry

  • github是公开的,也可以创建自己的仓库
  • 官方提供了搭建私有仓库的方法
  • docker hub搜索registry如下
    在这里插入图片描述
  • 打开后,可以查看快速搭建本地私有仓库的方法,运行如下命令即可
    在这里插入图片描述
  • 开启另一台安装并启动了docker的虚拟机,关机,复制当前机器就可以
    在这里插入图片描述
  • 查看启动了的registry
    在这里插入图片描述
  • 在之前的机器上安装telnet,查看端口是否可以访问
    在这里插入图片描述
    在这里插入图片描述
  • 在之前机器上重新构建image,IP是仓库机器的IP
    在这里插入图片描述
  • 将image放到本地私有的registry,但此时会报错,不可信任
    在这里插入图片描述
  • 本机创建如下文件
    在这里插入图片描述
  • 加入如下内容,IP是仓库机器的IP
{"insecure-registries":["192.168.174.142:5000"]}

在这里插入图片描述

  • 修改docker的启动文件
    在这里插入图片描述
  • 加入如下内容
EnvironmentFile=-/etc/docker/daemon.json

在这里插入图片描述

  • 重启docker服务
    在这里插入图片描述
  • 查看第二台机器的registry中有什么 http://192.168.174.142:5000/v2/_catalog
    在这里插入图片描述
  • 第一台机器将image放到本地私有的registry,IP是仓库机器的
    在这里插入图片描述
  • 浏览器再次查看如下
    在这里插入图片描述
  • 删掉第一台机器的image
    在这里插入图片描述
  • 从第二台机器的私有仓库中下载image
    在这里插入图片描述

14.Dockerfile案例

  • 创建python文件
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
    return "hello docker"
if __name__ == '__main__':
    app.run()
  • 运行app.py
    在这里插入图片描述
  • 安装flask
    在这里插入图片描述
  • 安装pip
    在这里插入图片描述
  • 安装flask
    在这里插入图片描述
  • 再次运行app.py
    在这里插入图片描述
  • 浏览器访问如下,这就创建好了一个最简单的web应用
    在这里插入图片描述
  • 将这个web应用打包成docker image,将image运行
  • 创建目录
    在这里插入图片描述
  • 将app.py移到该目录下
    在这里插入图片描述
  • 创建Dockerfile
    在这里插入图片描述
FROM python:2.7
LABEL maintainer="Sun [email protected]"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD ["python","app.py"]
  • 构建image
    在这里插入图片描述
  • 运行image
    在这里插入图片描述
  • 后台运行image
    在这里插入图片描述
  • 查看进程
    在这里插入图片描述

15.运行中对container操作

  • 后台运行image
    在这里插入图片描述
  • 查看所有container
    在这里插入图片描述
  • 交互式执行
  • 进入运行中的容器执行/bin/bash
    在这里插入图片描述
  • 查看进程
    在这里插入图片描述
  • 退出
    在这里插入图片描述
  • 进入container的python shell
    在这里插入图片描述
    在这里插入图片描述
  • 查看运行中容器的ip
    在这里插入图片描述
  • 停止container
    在这里插入图片描述
  • 删除所有退出状态的container
    在这里插入图片描述
  • 为container指定名称并启动
    在这里插入图片描述
    在这里插入图片描述
  • 名字也是唯一的,可以用名字停止
    在这里插入图片描述
  • 用名字启动
    在这里插入图片描述
  • 显示容器的详细信息
    在这里插入图片描述
  • 查看container的运行日志
    在这里插入图片描述
  • 修改container的名称
    在这里插入图片描述

16.Dockerfile案例2

  • 方式一:
    在这里插入图片描述
  • 安装stress
    在这里插入图片描述
  • 查看stress位置
    在这里插入图片描述
  • 查看帮助文档
    在这里插入图片描述
  • 启动一个worker,占用256M内存
    在这里插入图片描述
  • 指定内存超出了容器内存
    在这里插入图片描述
  • 方式二:
    在这里插入图片描述
  • 创建Dockerfile
    在这里插入图片描述
	FROM ubuntu
	RUN apt-get update && apt-get -y install stress
	#运行容器,执行stress
	ENTRYPOINT ["/usr/bin/stress"]
	#定义参数,[]是空,等待接收参数
	CMD []
  • 构建image
    在这里插入图片描述
  • 直接交互运行,类似于查看帮助文档
    在这里插入图片描述
  • 后面直接加参数运行容器
    在这里插入图片描述

17.对容器资源限制

  • 虚拟机可以对资源进行限制,容器也一样可以
  • 查看帮助文档
    在这里插入图片描述
  • 运行stress,200+200,用了400M内存
    在这里插入图片描述
  • 退出时如果卡死,打开另一个会话,查看docker进程并关闭
    在这里插入图片描述
  • 运行一个500M内存的程序,显示内存不够,证明内存限制生效
    在这里插入图片描述
  • 对CPU的限制
  • 限制CPU的使用,这里是限制相对权重,例如一个容器权重10,另一个5,第一个是第二个的二倍
  • 开三个窗口,前两个窗口运行指令CPU,第三个窗口top查看内存使用
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 先运行第一窗口,然后查看top
    在这里插入图片描述
  • 再运行第二窗口,查看top,两个容器占用的CPU是有权重的
    在这里插入图片描述
  • 可以给重要的容器设置多一点,就等于设置了优先级
  • 底层技术支持:
    • Namespaces:做隔离pid、net、ipc、mnt、uts
    • Control groups:做资源限制
    • Union file systems:container和image的分层

猜你喜欢

转载自blog.csdn.net/u010986776/article/details/84809988