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="sjc@126.com" 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 sjc_job@126.com" 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的分层
学院 Go 语言视频主页
https://edu.csdn.net/lecturer/1928以上所述就是小编给大家介绍的《1.03 docker的镜像和容器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C语言程序开发范例宝典
2010-1 / 59.00元
《C语言程序开发范例宝典》全面介绍了应用C语言进行开发的各种技术和技巧,全书共分12章,内容包括基础知识、指针、数据结构、算法、数学应用、文件操作、库函数应用、图形图像、系统调用、加解密与安全性、游戏、综合应用等。全书共提供300个实例,每个实例都突出了其实用性。 《C语言程序开发范例宝典》既可作为C程序的初学者学习用书,也可作为程序开发人员、相关培训机构老师和学生的参考用书。一起来看看 《C语言程序开发范例宝典》 这本书的介绍吧!