docker 实战
编辑本段什么是Docker
Docker是一种容器技术,通过Docker你可以做到:
- 更快速的交付和部署
- 更高效的虚拟化
- 更轻松的迁移和扩展
- 更简单的管理(类似git)
下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
编辑本段Docker的3个重要的概念
Docker 包括三个基本概念
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
镜像是分层存储的:
类似Git,一个文件对此修改,之后的修改是对上次修改的补丁,一层层的覆盖。
镜像也一样,它不像ISO那样的打包文件,由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
容器:
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
注意:容器中的数据非持久的,容器的生命周期结束了, 容器中的文件也就没有了,所以容器运行时,不应当往容器本身的存储层(文件系统)中写数据,而是应当用数据卷(Volume)。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失。
仓库:
用于集中的存储、分发镜像。
公开服务:Docker官方的镜像存储服务器,一般比较慢,但可以使用国内的加速器。
私有的服务:Docker Registry可以自己搭建, Docker 官方也提供了搭建Docker Registry的官方镜像
下图是Docker 的总结图
编辑本段Docker的安装
Mac下安装Docker:
https://download.docker.com/mac/stable/Docker.dmg
或者https://download.docker.com/mac/stable/Docker.dmg
或者https://docs.docker.com/docker-for-mac/
和一般的应用安装应用一样,安装完后如下:
设置加速:
https://ftheyftp.mirror.aliyuncs.com
在Centos6.5中。只需要修改 /etc/sysconfig/docker文件,加上下面这句
other_args=--registry-mirror=https://0yrztjfu.mirror.aliyuncs.com
并重启docker就好了
编辑本段Docker的基本操作
对镜像
镜像的搜索:
docker search Name
镜像的获取:
docker pull Name:Tag
镜像的查看:
docker images
镜像的标签:
一个镜像可以定义多个标签
docker tag REPOSITORY:TAG MY_REPOSITORY:TAG
镜像的删除:
删除可以是 REPOSITORY:TAG, 也可以是镜像的ID
按tag删除时,一个镜像还有其他标签是,这个镜像不会完全删除,直到这个是最后的标签。
docker rmi CONTAINERID docker rmi NAME:TAG
Docker 的导出:
docker save -o ~/Documents/99temp/onlyoffice_doc_server.tar onlyoffice:0.1
Docker的载入:
docker load < onlyoffice_doc_server.tar
Docker保存镜像:
docker commit -m 'add chinese fonts' -a 'jiangbingren' 629c927b43b3 onlyoffice:0.1
对容器
查看容器:
docker ps docker create # 创建容器,但不运行 docker run #创建容器,并且运行
典型的命名:
docker run -i -t -d -p 8080:80 -h onlyofficeweb --name onlyoffice --restart=always onlyoffice/documentserver #-it 参数保存标准输入打开,并分配一个伪终端 #--restart=always 异常情况下总是重新启,包括:不可知的错误(内存溢出等)、docker服务启动时
进入容器:
docker attach ContainerID/ContainerName docker exec -it ContainerID bash #-it 是必选的
容器的启动、停止:
docker start CONTAINER docker stop CONTAINER
删除容器:
docker rm CONTAINER
重命名
docker rename CONTAINER NEWNAME
输出容器的特定信息
docker inspect -f "{{ .Mounts }}” web1 docker inspect -f '{{ (index .Mounts 0).Source }}' containerid
数据卷
创建并启动一个nginx, 新建数据卷 /web
docker run -it -d -P --name web -h kmcweb1 -v /web nginx
bind 绑定一个本地目录为容器的数据卷:
docker run -it -d -P --name -h kmcweb1 web -v /Users/jiangbingren/Documents/workspace/docker/volumes/web1:/web nginx
数据共享: #web2 会共享web1中所用的数据卷
docker run -it -d -P -h kmcweb2 --name web2 --volumes-from web1 nginx
端口
-P 随机分配端口映射(49000 ~ 49900)
-p 8000:80 本机的8000端口映射到容器的80端口
docker run -it -d -P --name web -h kmcweb1 -v /web nginx docker run -it -d -p8000:80 --name web -h kmcweb1 -v /web nginx
容器互联
docker run -it -d -P -h kmcweb1 --name web --link db:db nginx
db为一个实际存在的容器,其中发生了两件事:
- 修改环境变量(就可以在其他的shell地方,直接用改环境变量了,如 echo $MYSQLDB_NAME)
- 添加host(可以不记db的IP,而用他的别名)
在 web上,运行 env命令:
[email protected]:/# env APPLICATION_USER=application MYSQLDB_PORT_3306_TCP=tcp://172.17.0.3:3306 REDIS_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.2.9.tar.gz REDIS_PORT_6379_TCP_PROTO=tcp WEB_DOCUMENT_INDEX=index.php HOSTNAME=820c5f1a0852 WEB_DOCUMENT_ROOT=/app MYSQLDB_NAME=/php7/mysqldb TERM=xterm PHP_INI_DIR=/usr/local/etc/php PHP_ASC_URL=https://secure.php.net/get/php-7.1.6.tar.xz.asc/from/this/mirror APPLICATION_PATH=/app REDIS_NAME=/php7/redis MYSQLDB_PORT=tcp://172.17.0.3:3306 # [email protected]:/# echo $REDIS_PORT_6379_TCP tcp://172.17.0.2:6379
在web上运行,cat /etc/hosts命令:
[email protected]:/# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 mysqldb 3660072cbfb5 172.17.0.2 redis b660da2976cb 172.17.0.5 820c5f1a0852
编辑本段镜像的制作与导出
生成镜像的两种方式:
- 通过容器 commit
- 通过Docker file 创建
docker commit -m 'add chinese fonts' -a 'jiangbingren' 629c927b43b3 onlyoffice:0.1
通过Docker file 创建是一般官方提倡的方式,当然这也是个技术活。
深入学习可参考:
https://www.qcloud.com/community/article/723556
镜像的导出、导入:
Docker 的导出:
docker save -o ~/Documents/99temp/onlyoffice_doc_server.tar onlyoffice:0.1
Docker的载入:
docker load < onlyoffice_doc_server.tar
编辑本段坑
- docker 容器一运行就停止了,如 webdevops/php-apache:centos-7-php56
问题是,没有 加 -P 的参数:
有问题的命令: docker run -it -d --name web webdevops/php-apache:centos-7-php56
修改为: docker run -it -d --name web -P webdevops/php-apache:centos-7-php56 - exec 要加上 -it 的参数,定义标准的输出
- 运行run 的时候,最好加上 -h 来定义 hostname
- mysql 的 镜像,需要加上密码的参数,才能启动, 如果不能启动容器,可以通过docker logs 来查看容器的日志
- docker 在挂载数据卷的时候,提示 docker: Error response from daemon: Mounts denied:
解决: 设置docker 的 File Sharing - 修改docker 的时间,时区
echo "Asia/Shanghai" > /etc/timezone dpkg-reconfigure tzdata date 或者直接: ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
编辑本段我们可以用Docker做什么
- 更快、更标准的产品部署 支持的操作系统
- 新产品的快速体验安装,可以用Docker实现(如果需要)
- 新技术的快速验证,而不需要费劲的去安装环境
- 如上次的OnlyOffice,就没有花时间去安装环境,直接有个Docker就能跑了
- PHP7?
- Elastic Search、Solr 这些都有Docker 的image 镜像
- 新技术的应用是,不用没个开发人员都去部署环境。 如果新产品需要PHP7? PHP7还要加PCache ? KMC 还要用PHP5.6 ? 这些Docker 都能解决,不然还麻烦了
Docker还是值得一试!
编辑本段相关参考链接
编辑本段PHP7本地环境安装
需求:
PHP7.1
Mysql
Redis
安装:
1.获取最新的官方镜像:
docker pull mysql:5.6 docker pull webdevops/php-apache:centos-7-php7 docker pull redis:latest
2.运行 mysql 容器
docker run -it -d -p8066:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql -v ~/Documents/code/mysqldata:/var/lib/mysql mysql:5.6
3.运行 redis容器
docker run -it -d -p6379:6379 --name redis redis:latest
4.运行 Apache PHP7.1 容器
docker run -it -d -p8000:80 -p8001:443 --name php7 \ --link mysql:mysql --link redis:redis \ -v ~/Documents/code:/app \ webdevops/php-apache:centos-7-php7
编辑本段PHP5本地环境的安装
练习:
再运行一套本地PHP5环境,用一个新的数据库mysql,并将mysql存储地址放到指定目录下
本地代码目录: ~/Documents/code
本地数据库目录:~/Documents/mysqldata
docker pull webdevops/php-apache:centos-7-php56 docker pull mysql:5.6 docker pull redis:latest //运行mysql(若运行不了mysql,则执行su -c "setenforce 0" ,然后运行) docker run -it -d -p8806:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql -v ~/Documents/mysqldata:/var/lib/mysql mysql:5.6 //运行redis docker run -it -d -p6379:6379 --name redis redis:latest //运行php5 ,注意 ~/Documents/code改成你本地的代码目录 docker run -it -d -p8010:80 -p8011:443 --name php56 \ --link mysql:mysql --link redis:redis \ -v ~/Documents/code:/app \ webdevops/php-apache:centos-7-php56 //编译redis扩展 //先进入docker容器 docker exec -it php56 bash cd /opt //安装phpdevel 及GCC yum install php56w-devel gcc //下载安装redis扩展 wget https://github.com/phpredis/phpredis/archive/3.1.2.tar.gz tar -xzvf 3.1.2.tar.gz cd phpredis-3.1.2 phpize ./configure make && make install cp /app/cosola/kmc.so /usr/lib64/php/modules #代码目录是/app/cosola //修改 /etc/php.ini vi /etc/php.ini //追加redis配置及kmc扩展 (kmc.so 见git目录下的kmc.so) extension=redis.so extension=kmc.so //或者在 /etc/php.d/下面新建 kmc.ini redis.ini 文件,分别添加如下两句 extension=redis.so extension=kmc.so //重启apache2 或者重启php56的docker容器 service apache2 restart //最后重启 php56这个容器 docker stop php56 docker start php56
其他说明:使用了link关联容器后,就可以在php代码中使用对应的host代替服务主机名
比如 mysql_host='127.0.0.1' 可以替换成 mysql_host='mysql'
本地时间的处理
docker run -it -d -p8030:80 -p8031:443 --name php \
--link mysql:mysql --link redis:redis --link memcached:memcached \
-v ~/Documents/code:/app \
-v ~/Documents/code/localtime:/etc/localtime:ro \
webdevops/php-apache:centos-7-php56
demo环境安装docker的php运行环境
docker run -it -d -p 8806:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysqldb -v /data/docker_mysql:/var/lib/mysql mysql:5.6
docker run -it -d -p 8879:6379 --name redis redis:latest
docker run -it -d -p 8000:80 -p 8001:443 -p 8002:8080 --name php7 --link mysqldb:mysqldb --link redis:redis -v /web/tiki:/app webdevops/php-apache:7.1
坑说明:
1.在Centos6.5等部分操作系统上,-p等命令后面需要加空格,如“-p 8806:3306 ”,否则会报错
2.由于demo宿主php是5.6.30版本,所以需要进入到php容器中运行yii框架
3.demo的防火墙需要把 8000 - 8880 之间的端口开放
编辑本段容器的服务升级
如上面的本地环境要升级 PHP,如需要如下的做:
1.制作 Apache PHP7.2的镜像
2.停止之前的容器
docker stop php7
3.新建容器,并使用 --volumes-from 继承之前的数据卷,link 也要重新建立连接
docker run -it -d -p 8000:80 \ -h php7.2 --name php7.2 \ --volumes-from php7 \ --link mysqldb:mysqldb --link redis:redis \ webdevops/php-apache:7.1
4.验证新的服务是否可用
5.删除就的容器(可选)
docker rm php7