一.什么是Docker
Docker容器是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。
二 .Docker的用途
1)快速交付你的应用程序
Docker可以为你的开发过程提供完美的帮助。Docker允许开发者在本地包含了应用程序和服务的容器进行开发,之后可以集成到连续的一体化和部署工作流中。
举个例子,开发者们在本地编写代码并且使用Docker和同事分享其开发栈。当开发者们准备好了之后,他们可以将代码和开发栈推送到测试环境中,在该环境进行一切所需要的测试。从测试环境中,你可以将Docker镜像推送到服务器上进行部署。
2)开发和拓展更加简单
Docker的以容器为基础的平台允许高度可移植的工作。Docker容器可以在开发者机器上运行,也可以在实体或者虚拟机上运行,也可以在云平台上运行。
Docker的可移植、轻量特性同样让动态地管理负载更加简单。你可以用Docker快速地增加应用规模或者关闭应用程序和服务。Docker的快速意味着变动几乎是实时的。
3)达到高密度和更多负载
Docker轻巧快速,它提供了一个可行的、符合成本效益的替代基于虚拟机管理程序的虚拟机。这在高密度的环境下尤其有用。例如,构建你自己的云平台或者PaaS,在中小的部署环境下同样可以获取到更多的资源性能。
三.Docker的部署与安装
1.安装docker和相关依赖性:
yum install docker-engine-17.03.1.ce-1.el7.centos.x86_64.rpm
docker-engine-selinux-17.03.1.ce-1.el7.centos.noarch.rpm
2.打开docker服务
systemctl start docker
3.在安装好docker后,linux系统会为docker容器分配一个ip,利用ip addr中查看docker0的ip
4.查看docker的信息
docker info # docker宿主机的信息
docker version # docker的版本
三.现有镜像的导入和容器的使用
1.将game2048这个镜像加载
docker load -i game2048.tar
2.查看可用镜像中是否含有刚刚导入的game2048
docker images game2048
3.运行docker
docker run -d --name vm1 game2048
#-d打入后台
# --name表示为这个容器起的名字是vm1
4.查看vm1容器的ip
docker inspect vm1
5.在本机浏览器中输入该ip,访问该容器网址(需要注意的是:这个172.17.0.2是自己私有的ip地址,别人不能访问)
6.为了别人可以访问到,我们可以对ip地址进行映射,用nginx的镜像举例
对外:
对内:
四.在网络中拉取镜像的方法:
1.在www.aliyun.com(阿里云)注册帐号
2.编辑/etc/docker/daemon.json文件
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://cnbv6o5x.mirror.aliyuncs.com"] # 阿里云中镜像加速的属于你的ip
}
2.重启服务
systemctl daemon-reload
systemctl restart docker
3.拉取镜像
docker pull nginx
docker images nginx 查看是否拉取到
docker run -d --name vm5 nginx 运行nginx
拉取到nginx镜像之后,我们希望在物理主机向容器中的nginx服务传送html发布主页,我们该怎么做呢?
第一种传送首页的方法:在本地远程拷贝
vim index.html # 编辑nginx服务的首页
docker cp index.html vm5:/usr/share/nginx/html/ # 远程拷贝首页到镜像nginx的发布目录中
docker inspect vm5 # 查看nginx的ip,在浏览器访问
第二种传送首页的方法:在物理主机打开容器时-v挂载
mkdir /tmp/docker/web/
vim index.html
hello jay
docker rm -f vm5 # 删除上边已经命名的vm5
docker run -d --name vm5 -v /tmp/docker/web/:/usr/share/nginx/html/ nginx # 在本地导入nginx的默认发布目录
-v表示把宿主机的目录挂载到容器中
docker -v 容器中的目录下原来有部分文件的话,会加载到宿主机中的目录中,但不是全部都会加,会覆盖掉原本的文件(宿主机中的文件)
五.Dockerfile文件的编写
(一)我们利用功能最简化的rhel7镜像进行改造,封装出打开后直接带有httpd服务的v1版本镜像:
1.得到简单的rhel7镜像,我们希望可以得到一个打开后可以直接访问apach发布目录的镜像
2.我们在写Dockerfile文件的时候,可以打开一个rhel7的虚拟机,一边在这敲命令用来验证,一边在文件中编写
vim /tmp/docker/Dockerfile
FROM rhel7 # 源镜像是rhel7,最好将名为rhel7的镜像放在本地
ENV HOSTNAME server1 # 定义hostname为server1
MAINTAINER jay@2983088484.com # 定义邮箱
EXPOSE 80 # 定义端口为80
COPY dvd.repo /etc/yum.repos.d/dvd.repo # 配置yum源
RUN rpmdb --rebuilddb && yum install -y httpd && yum clean all
# 执行命令安装httpd并清除yum缓存
# rpmdb 命令用于初始化和重建rpm数据库
# --rebuilddb:从已安装的包头文件,反向重建RPM数据库
VOLUME ["/var/www/html"] # 数据卷所在的位置
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
# 打开apach服务
# -D 是全局文件/etc/sysconfig/httpd中的打开参数
3.将dvd.repo放在当前目录
4.开始封装
docker build -t rhel7:v1 . # rhel:v1是自己封装的镜像的名称和版本号
查看自己封装的rhel:
从封装过程来看,封装过程被分为了我们Dockerfile文件中的行数,一层一层往下执行,所以我们在编写Dockerfile文件的时候,应该尽量减少行数,加快封装速度…
(二).封装一个带有ssh服务,可以连接别的主机也可以被别人连接
1.编辑Dockerfile文件
vim Dockerfile
FROM rhel7
ENV HOSTNAME server2
MAINTAINER jay@2983088484.com
EXPOSE 22 # 对外端口是22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y openssh-server && yum install -y openssh-clients yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:redhat | chpasswd
CMD ["/usr/sbin/sshd","-D"]
2.开始封装:
3.封装之后的测试:
(三)利用supervisord一次封装多个服务
1.编辑Dockerfile文件(整合上边的httpd和ssh)
FROM rhel7
EXPOSE 80 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y httpd openssh-server openssh-clients supervisor && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:westos | chpasswd
# 安装supervisor
COPY supervisord.conf /etc/supervisord.conf
CMD ["/usr/bin/supervisord"]
# 在打开supervisor的时候,将多个服务同时开启(httpd和ssh)
2.在当前目录下编辑supervisord.conf文件
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D # 打开sshd服务
[program:httpd]
command=/usr/sbin/httpd # 打开httpd服务
3.配置yum源
[rhel7]
name=rhel7
baseurl=http://172.25.1.250/source7.3
gpgcheck=0
[docker]
name=docker
baseurl=http://172.25.254.250/pub/docker # supervisord包所在的位置
gpgcheck=0
4.在当前目录下开始封装
docker build -t rhel7:v3 .
5.利用刚封装的镜像创建容器
docker run -d --name vm1 -v /tmp/docker/web:/var/www/html rhel7:v3
6.测试同时具有httpd和sshd服务的容器
(四)Dockerfile文件中CMD和EMTRYPOINT的区别
ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与CMD 的 区 别 是 不 可 以 被 docker run 覆 盖 , 会 把 docker run 后 面 的 参 数 当 作 传 递 给ENTRYPOINT 指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,只 有 最 后 一 个 有 效 。 docker run 命 令 的 -entrypoint 参 数 可 以 把 指 定 的 参 数 继 续 传 递 给ENTRYPOINT。
1.
FROM rhel7
CMD echo "hello world"
2.
FROM rhel7
ENTRYPOINT echo "hello world"
3.
FROM rhel7
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
4.
FROM rhel7
ENV name jay
ENTRYPOINT echo "hello $name"
5.
FROM rhel7
ENV name jay
ENTRYPOINT ["/bin/sh","-c","echo $nmae"]