docker入门(1):初识docker与基本使用
1. 容器是什么? 容器是一种轻量级操作系统层面的虚拟化,它为应用软件及其依赖组件提供了一个资源独立的运行环境。应用软件所依赖的组件会被打包成一个可重用的镜像,镜像运行环境并不会与主操作系统共享内存、CPU和硬盘空间,由此也保证了容器内部的进程与容器外部进程的独立关系。 而虚拟机的每个实例自带操作系统,因而是一种硬件级的虚拟化隔离。Docker是当前流行的开源容器虚拟化平台;2. dock...
1. 容器是什么?
容器是一种轻量级操作系统层面的虚拟化,它为应用软件及其依赖组件提供了一个资源独立的运行环境。应用软件所依赖的组件会被打包成一个可重用的镜像,镜像运行环境并不会与主操作系统共享内存、CPU和硬盘空间,由此也保证了容器内部的进程与容器外部进程的独立关系。
而虚拟机的每个实例自带操作系统,因而是一种硬件级的虚拟化隔离。
Docker是当前流行的开源容器虚拟化平台;
2. docker原理与架构
Docker实现原理2个重要概念:namespace,cgroup,
其中,namespace(命名空间)用来做容器与宿主机的隔离,cgroup用来做内存、存储等资源的限制;
Docker三大组件:镜像、仓库、容器
Docker 镜像:镜像 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。
Docker 仓库:仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker 仓库分为公有仓库和私有仓库,公有仓库就是Docker官方的仓库:Docker Hub,私有仓库可以自己进行搭建;
Docker 容器:一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。
3. 安装
本次实验使用系统为红帽企业7.3,安装Docker18.06.1社区版,以下的所安装的docker级所需要的依赖性的RPM包:
开启docker:
注意:docker开启后在宿主机会出现一块虚拟网卡docker,docker运行起来后,所有运行的容器都使用内网地址,默认情况下docker与宿主机的网络使用桥接网络:
4. 使用:
- 第一个docker容器:
准备镜像(此镜像是已经压制好的镜像,后面会学习如何压制自己的镜像):导入镜像:
运行容器:
查看正在运行的容器:
由于我们在启动容器时进行了端口映射,所以此时宿主机上的8080端口已经开启:
访问宿主机的8080端口,则可以看到2048小游戏的界面(可以在此界面上正常玩游戏):
2. Dcoker常用命令:
docker
run ##创建并启动容器
-it ##交互式终端
--rm ##退出容器时自动删除容器
--name ##指定容器名称
-d ##容器后台运行
ps ##查看当前的容器
-a ##所有容器
rm ##删除容器
-f ##强制删除
rmi ##删除镜像
-f ##强制删除
attach ##进入容器
commit ##提交
contanier ##容器的命令
cp ##将指定的文件cp到容器内指定的位置
prune ##删除所有停止的容器
exec CMD ##容器内执行CMD命令
export ##将一个容器打包成tar包
diff ##查看容器的变更
logs ##查看容器的日志
insepc ##查看容器的详细状态
history ##看到此容器的历史
附一张高大上的docker命令图:
3.Docker使用之镜像:
从上面的实验可以看出,docker的镜像是docker的基石,而若要满足个性化的需求,就需要我们自己来压制所需要的镜像,docker的镜像压制有自己的一套规则,Dockerfile文件中存储定制镜像的一系列命令,编写Dockerfile的规则如下:
# FROM:设置要制作的镜像基于哪个镜像
# 第一条指令必须为 FROM 指令
# usage:FROM <image>
# FROM <image>:<tag>
FROM rhel7
# MAINTAINER 维护者信息
# usage: MAINTAINER <name>
MAINTAINER wx
# ADD 将源文件复制到目的容器指定目录下,如果源是一个URL,那该URL的内容将被下载并复制到容器中
# ADD 把包添加到容器指定目录,如果是tar包会自动解压
# ADD 后跟的源码包必须与Dockerfile置于同一目录下
# usage: ADD <src or URL> <dest>
ADD nginx-1.15.7.tar.gz /usr/local/
# COPY 将本地的源系统复制到目标容器指定目录下
# usage:COPY <src> <dest>
# COPY yum.repo /etc/yum.repos.d/yum.repo
# RUN 在容器中运行命令
# usage: RUN <command> 在shell中运行命令,即"/bin/bash -c"
# RUN ["executable","param1", "param2"] 指定exec来执行命令
# 指定使用其它终端可以通过第二种方式实现,例如 RUN [“/bin/bash”, “-c”,”echo hello”]
#RUN yum clean all && yum repolist && yum install gcc pcre*
make openssl-devel zlib-devel -y && yum clean all
# WORKDIR 指定容器的一个目录,容器启动时执行的命令会在该目录下执行,相当于设置了容器的工作目录
# 此命令类似cd
# 为后续的 RUN,CMD,ENTRYPOINT 指令配置工作目录.可以使用多个WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径
# WORKDIR 可以用来做目录的切换
# usage:WORKDIR /path/to/workdir
# WORKDIR /usr/local/nginx-1.15.7
# RUN 在容器中运行命令并进行编译安装
ADD yum.repo /etc/yum.repos.d/rhel7.repo
RUN rpmdb --rebuilddb && yum
clean all && yum swap fakesystemd systemd -y \
&& yum install gcc pcre* make
openssl-devel zlib-devel -y && yum clean all \
&& useradd -s /sbin/nologin -M
nginx \
&& cd /usr/local/nginx-1.15.7/ \
&& ./configure --prefix=/usr/local/nginx && make && make install \
&& ln -s
/usr/local/nginx/sbin/nginx /usr/local/sbin \
&& chmod +x
/usr/local/sbin/nginx
# ENV指令用于设置环境变量,在Dockerfile中这些设置的环境变量也会影响到RUN指令,当运行生成的镜像时这些环境变量依然有效
# ENV 将nginx启动命令添加到系统环境变量里
# usage:ENV <key> <value>
# ENV <key>=<value>
# ENV PATH /usr/local/nginx/sbin/:$PATH
# EXPOSE指令用来告诉Docker这个容器在运行时会监听哪些端口
# EXPOSE 暴露80端口
# usage:EXPOSE <port>
EXPOSE 80
# CMD 指定启动容器时执行的命令
# 当有多个CMD命令时,只有最后一个CMD命令会被执行
# usage:CMD ["executable","param1","param2"]
# CMD command param1 param2 在 /bin/bash 中执行
# CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数
# 启动容器时开启nginx
# WORKDIR /usr/local/nginx/sbin
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off"]
实例:基础镜像:rhel7.3;目标:压制http镜像:
1.新建docker目录:
##不要在/ 底下编译,否则会将/ 下的所有文件都编译一遍,所以应该新建一个空目录来编译
2.编写Dockerfile如下:
3.导入基础镜像rhel7(若本地不存在此镜像,默认会从官方的镜像仓库拉取):
4.将所需的copy文件与Dockerfile放置在同一目录下:
5.压制镜像:
查看:
6.启动容器:
注意:ps选项只会显示出当前正在运行的容器,不会显示出停止的容器,若想显示所有的容器,需要添加-a/-all选项:
8.测试:
启动容器apache:
查看容器详细信息:
可以看到容器的地址:
写一个自己的index.html,内容如下:
将此文件放入容器中apache默认发布目录下,访问容器,返回我们的index文件内容,这说明容器正常运行,镜像压制无误:
3.ENV & CMD & ENTYRYPOINT:
1.ENV:定义全局变量
“测试:”
#1.Dockerfile如下:
FROM busybox
ENV name world
CMD echo "hello $name"
输出:
[root@server1 test1]# docker run --rm test:v1
hello world
#2.Dockerfile如下:
FROM busybox
ENV name world
CMD ["/bin/echo","hello $name"]
输出:
[root@server1 test1]# docker run --rm test:v2
hello $name ##若要解析,需指定-e参数
#3.Dockerfile如下:
FROM busybox
ENV name world
CMD ["/bin/sh","-c","echo hello,$name"]
##/bin/sh 是 /bin/bash的软链接,使用man bash可以查看bash命令的具体使用方法;
输出:
[root@server1 test1]# docker run --rm test:v3
hello,world
#4.Dockerfile如下:
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
输出:
[root@server1 test1]# docker run --rm test:v4
hello world
[root@server1 test1]# docker run --rm test:v4 westos
hello westos
结论:
##两者的相同之处:都是在运行容器时被执行
##不同之处:CMD可以被覆盖,但是ENTRYPOINT不会被覆盖
##同时:如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数
4.镜像的缩减:
#1.减少RUN命令:将RUN命令尽量写在一起,使用 \ 换行或者 && 进行级联执行
#2.可以将需要编译的软件在外面编译好,将安装包cp进容器即可
#3.镜像多阶段构建:
首先看不经过多阶段构建是镜像的大小:
Dockerfile如下:
将nginx源码包和yum源配置与Dockerfile放在同一目录下构建镜像:
可以正常运行:
可以看到源码编译安装后镜像体积相比基础镜像大了90M,这会使得镜像臃肿从而失去了docker轻量级的优势,但是很多软件是需要我们进行源码编译的,此时我们就可以先编译好在直接拿来用:
Dcokerfile如下:
构建镜像:
此时镜像大小:
此时镜像只比基础镜像多了1M,但它的功能仍是完美无缺的:
注意:在镜像构建过程中,实际上是分层构建的,因此首先应减少Dockerfile的层数,同时由于构建过程中会产生cache,所以对于多次构建的镜像(以前构建失败的镜像在使用images命令列出时也会出现),只会在第一次构建某一层时真正进行操作(若没有删除构建失败的镜像时),同时在仓库拉取或上传镜像时,若检测到有哪一层仓库中已经存在了,就不再进行拉取或者上传,这使得镜像实现了复用的功能。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)