docker 认知
使用docker可以快速的搭建环境,解决运维很多重复性的工作,那么docker是什么? docker对于开发人员来说意味这什么?
docker在表观上,有点像虚拟机,可以在宿主主机进入docker容器,在
docker里面可以执行各种命令行,以及文件,活脱脱的一个类似于VMware的虚拟机的感觉。
虽然感觉上像是一个虚拟机,但是docker和虚拟机WMware有着本质的不同,而且实现的原理也不一样,如果(假如)我们按照虚拟机的思路使用docker,那么我们会创建一个docker容器,然后在这个docker'容器里面安装php,mongodb,mysql,nginx等等,然后运行,这样来实现开发环境的快速部署
通过这里可以更详细的参看docker 和虚拟机的不同:https://yeasy.gitbooks.io/docker_practice/content/introduction/what.html
但是实际上,docker不是这样使用的,docker的表征就是服务,譬如我安装一个wordpress,需要安装nginx,php,mysql,那么我开启三个docker容器,一个nginx容器,一个php容器,一个mysql容器,三个容器相互隔离完全独立(注意,127.0.0.1只代表容器本身,譬如php访问mysql容器,不能通过127.0.0.1连接,因为他们是独立的,属于局域网远程访问),同时三个容器是可以通信的,可以通过hosts访问,譬如php容器可以访问mysql容器进行通信
步骤:我们将nginx容器的端口80,映射到宿主主机的80
端口,然后宿主主机的80端口的访问,就会访问到nginx容器,然后nginx容器访问php容器获取数据,php容器访问mysql容器获取数据库数据,然后逐层返回数据,最后返回给用户
上面的步骤,感觉像是一个独立的服务,但是还是有问题
1.数据安全的问题:容器销毁后,里面的数据也会消失,这样就造成我们的系统数据丢失,因此,在容器中的数据,必须是宿主主机通过映射的方式挂载进去,类似于linux局域网的NFS(将一个局域网远程的磁盘挂载到本地的某个文件夹,访问起来就和自己的磁盘一样的感觉),因为容器里面的系统文件是挂载的宿主主机的文件夹,我们可以在宿主主机里面修改文件。
容器销毁后,数据也不会丢失。
2.容器内部的某些操作,譬如cron
对于php容器,我们会跑一些cron脚本,如果我们进入搭配php容器,然后设置cron。这种方式是不正确的
对于docker容器,里面的linux异常的干净,对于cron这些服务,如果你在制作docker镜像的时候没有安装,是没有这些服务的
我们在宿主主机中设置cron,然后通过命令行进入都php docker容器,执行相应的命名。
docker运行cron参看: http://www.fecshop.com/topic/1296
docker部署https: http://www.fecshop.com/topic/1249
最后,我们可以发现docker容器看起来像虚拟机,但不能把docker理解成虚拟机,docker最恰当的理解是服务,
docker容器里面需要执行的命令,我们都可以在宿主主机通过命令行操作docker容器里面的命令,docker里面的文件(我们需要的系统文件,而非linux内核等文件)可以通过映射的方式挂载出来,docker就是一个活脱脱的服务,有点像我们在宿主主机安装的一个php服务。
docker的方便之处,解决的问题
通过上面我们了解了docker是什么,怎么理解docker,结果是服务
,以及docker如何实现服务
的概念, 下面
说一下我们用docker解决什么问题
docker解决的是快速部署环境
1.新员工,内部员工在各个项目调动,都需要搭建相应的开发环境,过程比较繁琐,加上一些
员工自己的操作系统的配置参数不同,会造成一些差异,使用docker可以快速的部署环境,
这个一般用docker compose
,开发人员了解这个足够
2.线上系统,使用docker快速的水平扩展,由于docker的快速部署,可以快速的为应用水平扩展,当然这是k8s
方面的,一般都是专业运维掌握的,开发人员我认为没有必要过多了解这个(能了解肯定是更好)
引用文字:
1)提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
(2)提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。
(3)组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。
docker的原理
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
使用docker
1.通过Dockerfile,做docker镜像
Dockerfile的例子:
https://github.com/fecshop/yii2_fecshop_docker/blob/master/services/php/docker/Dockerfile
参考上面的,我们写一个Dockerfile文件,我们可以在里面添加各种命令行,譬如上面的这个dockerfile,我们可以根据需要添加各种php的扩展,以及安装composer等等。
然后就可以通过这个配置文件生成一个镜像文件。
docker中心,有大量的各个程序员上传的docker镜像,如果有合适的,可以使用docker hub下载的docker镜像直接使用,也可以将自己制作的镜像上传上去,由于docker hub是在美国,伟大长城的存在经常存在网络问题,也可以将自己的镜像上传到阿里云,关于这个可以参看文章:http://www.fecshop.com/topic/643
很多公司做自己的内部docker仓库,将制作好的各种镜像上传上去,由于docker镜像文件比较大,使用内部docker仓库
下载会更快
2.通过docker镜像,生成docker容器
docker镜像是文件,就像我们的window镜像盘,需要安装后启动才能跑起来
我们可以通过docker镜像生成docker容器,docker容器是生成启动后,运行docker服务,譬如docker php容器,
就可以处理请求了
上面说的是docker的大致的一个认知穿线,更详细的docker知识,以及相应的语法操作,可以参看文档:https://yeasy.gitbooks.io/docker_practice/content/
docker compose
作为开发人员,我的机器上面有很多的docker容器,如果每一个单独启动关闭,这种管理方式很麻烦,我们可以通过compose统一管理docker
docker compose是单机版的docker管理,分布式的多机docker需要用k8s,这一块一般是专业运维研究的,下面说一下docker compose
这里有一个docker compose的例子:
https://github.com/fecshop/yii2_fecshop_docker
详细讲解:
1.通过上面的README部分,安装docker 和docker compose
2.参考:https://github.com/fecshop/yii2_fecshop_docker/blob/master/docker-compose.yml
,在根目录创建一个docker-compose.yml文件,然后在里面写配置
services
: 这是服务名,每一个服务名对应一个docker容器,可以看到 web
, php
, mysql
都是一个容器,
3.下面看一下 nginx这个容器的配置,容器的名字是web
:
web:
image: nginx:latest
ports:
- "80:80"
restart: always
volumes:
- ./app:/www/web
- ./services/web/nginx/conf:/etc/nginx
- ./services/web/nginx/logs:/www/web_logs
networks:
- code-network
depends_on:
- php
image
: 指的是web容器生成对应的镜像,nginx:latest
代表的是从docker hub中心下载nginx镜像,下载的是最后的一个版本。(这种方式容器出bug,之前写过mysql容器的版本是latest,今年5月份左右,mysql从mysql5直接跳到了mysql8版本,连接方式都改变了,导致系统无法连接mysql,排查后发现是mysql8的问题)
ports
: 和宿主主机的端口映射,这里表示nginx容器的80
端口映射到宿主主机的80端口,如果你的宿主主机的80
端口被占用,则会启动失败
restart
: always
代表启动失败后,一直重新启动,直到启动成功位置
volumes
: 这个就是磁盘挂载,将宿主主机的磁盘挂载到docker容器中,一行代表一个磁盘文件挂载,譬如
- ./app:/www/web
代表的是将当前文件夹下的./app
文件夹,挂载到nginx容器的/www/web
networks
: 网络部分,对应78行的配置:https://github.com/fecshop/yii2_fecshop_docker/blob/master/docker-compose.yml#L78
depends_on
: 代表容器启动优先级,也就是php容器启动成功后,才会启动nginx容器
4.对于和宿主主机的通信,需要做ports映射,譬如nginx的80端口,但是
对于容器内部的相互访问,不需要做ports映射,譬如php容器访问,mysql和mongodb的端口,就不需要,因为容器之间访问端口是通畅的
5.其他参数
mysql容器部分environment
:是创建mysql容器的时候,初始化mysql的数据库和用户名
6.着重说一下php容器
php:
build:
context: ./services/php/docker/
restart: always
build
:代表php容器,不是通过docker hub下载的镜像,而是通过dockerfile文件生成的镜像,然后通过
镜像生成容器。
context: ./services/php/docker/
: 代表dockerfile的文件路径,我们打开这个文件:https://github.com/fecshop/yii2_fecshop_docker/blob/master/services/php/docker/Dockerfile
,可以看到dockerfile的配置,里面都是命令行,具体的语法参看基础知识
7.上面都是docker hub的下载地址,下载慢还经常被长城墙到,因此,我们可以吧这些镜像下载下来上传到阿里云
,这里是我做的一份:https://github.com/fecshop/yii2_fecshop_docker/blob/master/docker-compose.yml.aliyun
,下载速度会更快,如果使用阿里云的服务器,下载速度更是火箭一般。
8.启动
进入相对根目录,可以通过
docker-compose up -d
docker-compose stop
可以启动和关闭docker compose
9.设置开机启动
我们想要机器开机的时候,直接运行这些docker容器
9.1centos7下启动docker
systemctl enable docker
9.2.开机启动docker-compose
vim /etc/rc.d/rc.local
, 新行,添加下面的命令行
/usr/local/bin/docker-compose -f /www/web/yii2_fecshop_docker/docker-compose.yml up -d
注意,要将/www/web/yii2_fecshop_docker
替换成您自己的地址。
10.远程访问docker容器
有一些时候,我们需要远程直接通过ssh访问docker容器,而不是通过宿主主机,那么我们可以加一个ssh容器
ssh1:
build:
context: ./services/ssh/docker/
networks:
- code-network
ports:
- "2222:22"
dockerfile:https://github.com/fecshop/yii2_fecshop_docker/blob/master/services/ssh/docker/Dockerfile
附:
docker基础知识: https://yeasy.gitbooks.io/docker_practice/content/introduction/what.html
本文由 Fecshop 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。
可自由转载、引用,但需署名作者且注明文章出处。