Docker容器学习笔记1
Docker容器
概述
1、之前项目的部署方式的缺点
通过物理机方式部署,如图所示
- 部署非常慢
- 成本非常高
- 资源浪费
- 难于迁移和扩展
- 可能会被限定硬件厂商
2、虚拟化技术的出现
通过虚拟化的技术,我们可以使用一台物理机部署多个app,每个app独立运行在一个VM里
虚拟化技术的优点:
- 资源池 ———— 一个物理机的资源分配到了不同的虚拟机里
- 很容易扩展 ———— 加物理机器or加虚拟机
- 很容易云化 ———— 亚马逊AWS,阿里等
虚拟化的局限性
- 每一个虚拟机都是一个完整的操作系统,要给其分配资源,当虚拟机数量增多时,操作系统本身消耗的资源势必增多
3、容器技术的出现
容器解决了什么问题?
- 解决了开发和运维之间的矛盾
- 在开发和运维之间搭建了一个桥梁,是实现devops最佳解决方案
什么是容器?
- 对软件和其依赖的标准化打包
- 应用之间相互隔离
- 共享同一个OS Kernel
- 可以运行在很多主流操作系统上
注:容器和虚拟机的区别在于容器是APP层面的隔离,而虚拟化是物理资源层面的隔离
Docker的架构和底层技术
Docker Platform
- Docker提供了一个开发,打包,运行app的平台
- 把app和底层infrastructure隔离开来
其三层模型如图:
Docker Engine
- 后台进行(dockerd)
- REST API Server
- CLI接口(docker)
底层技术支持
其主要利用Linux的底层技术
- Namespaces:做隔离pid,net,ipc,mnt,uts
- Control groups:做资源限制
- Union file systems:Container和image的分层
Docker Image概述
什么是Image
- 文件和meta data的集合(root filesystem)
- 分层的,并且每一层都可以添加改变删除文件,成为一个新的image
- 不同的image可以共享相同的layer
- Image本身是read-only的
Image的获取
- 方式1:Build from Dockerfile
- 方式2:Pull from Registry
例如:输入命令 sudo docker pull ubuntu:14.04,则会从Registry中拉出Image,Registry类似于github的作用,默认都是从docker hub上面拉取,上面会有官方和第三方的版本
输入命令 sudo docker image ls则可以显示所拉去的Image
如何做一个自己的Base Image
1.首先创建一个可以执行的程序,下面用一个C语言的hello程序做例子
2.通过dockerfile把这个可执行文件打成一个Image
我们在hellow文件当前目录下创建一个Dockerfile文件,如下:
3.执行命令:docker build -t yunduan/hello-world . (-t表示指示表情,"."表示在当前路径下寻找dockerfile),执行以后,出现如下界面表示执行成功。
4.查看image,则可以看到成功build了一个image,执行命令docker history +[IMAGE ID]则可以查看镜像的层级
,执行命令docker run + [镜像标签名]则可以生成一个container运行程序。
Docker Container概述
什么是Container
- 通过Image创建(copy)
- 在Image layer之上建立一个container layer(可读写)
- 类比面向对象:类和实例
- Image负责app的存储和分发,Container负责运行app
Container相关命令
- 查询container状态 docker container ls -a
- 创建容器 docker run centos
- 创建容器 docker run -it centos
- 移除容器 docker container rm + [container ID]
- 移除镜像 docker image rm + [image ID]
- 显示所有containerID docker container ls -aq
- 移除所有的container docker rm $(docker container ls -aq)
构建自己的Docker镜像
- 命令一:docker container commit(Create a new image from a container's changes)
这个命令表示当你在容器中做出了改变之后,可以重新构建Image
通过这个例子可以看出,其就在centos镜像上重新构建了一层
- 命令二:docker image build(Build an image from a Dockerfile)
Dockerfile语法梳理
- FROM
原则:尽量使用官方的image作为base image!
FROM scratch #制作base image FROM centos #使用base image FROM ubuntu:14.04
- LABEL
原则:Metadata不可少!相当于代码的注释
LABEL maintainer="[email protected]" LABEL version="1.0" LABEL description="This is description"
- RUN
作用:执行命令并创建新的Image Layer
原则:为了美观,复杂的RUN请用反斜线换行!避免无用分层,合并多条命令成一行!
RUN yum update && yum install -y vim \ python-dev #反斜线换行
RUN apt-get update && apt-get install -y perl \ pwgen --no-install-recommends && rm -rf \ /var/lib/apt/lists/* #注意清理cache
RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
- WORKDIR
作用:设定当前目录,类似于cd
原则:用WORKDIR,不要用RUN cd!尽量使用绝对目录
WORKDIR /root
WORKDIR /test #如果没有会自动创建test目录 WORKDIR demo RUN pwd #输出结果应该是 /test/demo
- ADD and COPY
作用:把本地文件添加到Docker image里面
原则:大部分情况,COPY优先于ADD!ADD除了COPY还有额外功能(解压)!添加远程文件/目录请使用curl或者wget!
ADD hello /
ADD test.tar.gz / #添加到根目录并解压
WORKDIR /root ADD hello test/ # /root/test/hello
WORKDIR /root COPY hello test/
- ENV
作用:设置一个环境变量,引用常量
原则:尽量使用ENV增加可维护性!
ENV MYSQL_VERSION 5.6 # 设置常量 RUN apt-get install -y mysql-server= "${MYSQL_VERSION}" \ && rm -rf /var/lib/apt/lists/* # 引用常量
- VOLUME and EXPOSE (存储和网络)
- CMD and ENTRYPOINT
CMD:设置容器启动后默认执行的命令和参数
注释:1.容器启动时默认执行的命令 2.如果docker run指定了其他命令,CMD命令被忽略 3.如果定义了多个CMD,只有最后一个会执行
ENTRYPOINT:设置容器启动时运行的命令
注释:1.让容器以应用程序或者服务的形式运行 2.不会被忽略,一定会执行 3.最佳实践:写一个shell脚本作为entrypoint
1.Shell格式
RUN apt-get install -y vim CMD echo "hello docker" ENTRYPOINT echo "hello docker"
2.Exec格式
RUN ["apt-get","install","-y","vim"] CMD [" /bin/echo" , "hello docker" ] ENTRYPOINT ["/bin/echo" , "hello docker"]
3.Shell和Exec格式
- Dockerfile1 A
FROM centos ENV name Docker ENTRYPOINT echo "hello $name"
- Dockerfile2
FROM centos ENV name Dokcer ENTRYPOINT ["/bin/bash", "-c","echo hello $name" ]
镜像发布
- docker login
- docker push