Docker Compose

docker-compose

docker-compose是Docker官方编排工具,用来管理和运行Docker容器,负责实现对Docker容器集群的快速编排。使用一个 Dockerfile 模板文件,可以很方便的定义一个单独的应用容器,而Compose则可以方便的实现需要多个容器相互配合来完成某项任务的情况。
Docker Compose将所管理的容器分为三层,工程(project),服务(service)以及容器(contaienr)。Docker Compose运行的目录下的所有文件(docker-compose.yml、extends文件或环境变量文件等)组成一个工程,默认名称为当前目录名。一个工程当中可包含多个服务,一个服务当中可包括多个容器实例。Docker Compose并没有解决负载均衡的问题,需要借助其他工具实现服务发现及负载均衡。
Compose 通过一个单独的 docker-compose.yml 模板文件(YAML格式)来定义一组相关联的应用容器为一个项目 (project)。
Compose 中有两个重要的概念:
服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器 实例。
项目(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。

Docker Compose是一个部署多个容器的简单必要的工具,使用一条简单的命令部署多个容器,简化了多容器的部署过程,使多容器移植变得简单可控。从其Roadmap可以看出,Docker Compose的目标是做一个生产环境可用的工具,包括服务回滚,多环境支持(dev/test/staging/prod),支持在线服务部署升级,防止服务中断并且监控服务使其始终运行在正确的状态。Roadmap中的另一个目标是更好的与Docker Swarm集成,目前版本存在的主要问题是无法保证处于多个主机的容器间正常通信因为目前不支持跨主机间容器通信。另一个问题是在Docker Compose中定义构建的镜像只存在在一台Docker Swarm主机上,无法做到多主机共享,因此目前需要手动构建镜像并上传到一个镜像仓库使多个Docker Swarm主机可以访问并下载镜像。相信随着Docker Compose的完善,其必将取代docker run成为开发者启动docker容器的首选。

安装 Docker Compose
https://docs.docker.com/compose/install/

Docker服务器端用Nginx作为反向代理并添加SSL证书(阿里云免费DV证书)
https://www.cnblogs.com/wushangjue/p/7810339.html
http://www.mamicode.com/info-detail-1703824.html
http://blog.51cto.com/11962757/2086760
http://www.lixiangfeng.com/blog/article/content/8595503
https://www.jianshu.com/p/2217cfed29d7
可能冒号后需要加个空格,不然在执行 docker-compose up -d后报错ERROR: yaml.scanner.ScannerError: mapping values are not allowed here。
创建 docker-compose.yml 文件,然后在当前目录下执行命令 docker-compose up -d 来启动各个服务。

version: "2"
services:
  php-fpm1:
    image: bitnami/php-fpm
    container_name: php-fpm1
    restart: always
    links:
      - mysql1:mysql-alias
    volumes:
      - /alidata/docker_work/www:/host/www
  nginx1:
    image: nginx
    container_name: nginx1
    restart: always
    ports:
      - 81:80
      - 444:443
    volumes:
      - /alidata/docker_work/nginx/conf:/etc/nginx/conf.d
      - /alidata/docker_work:/host
    links:
      - php-fpm1:php-fpm-alias

注意在此环境下的Php连接mysql,需要使用mysqli_connect。

docker-machine

VirtualBox和Docker的区别

VirtualBox和Docker的区别,一句话总结就是VirtualBox虚拟化硬件,Docker虚拟化操作系统。
VirtualBox,是创建硬件虚拟化的软件。通常情况下,一个操作系统运行在硬件上,其中硬件和操作系统之间的通信是通过移动数据到内存地址,然后发出指令来通知可使用该数据的硬件(或者是数据在被读取时)。 在VirtualBox(或其它虚拟机)设置的环境中,那些内存地址实际上是虚拟机软件自身的内存区域,并且那些指令是由虚拟机而不是直接由底层的CPU解释的。实际结果是,你在VirtualBox中运行一个操作系统,对于这个操作系统来说,VirtualBox程序看起来像一台完整计算机,硬件以及所有配件都有。实际上它不知道自己是在另一个程序中运行的。

Docker,则是不进行硬件的虚拟化。相反,它的作用是创建一个文件系统,使其看起来像一个普通的Linux文件系统,并且运行应用程序在一个所有文件和资源都在文件系统内的锁定环境中。事实上,该应用程序的容器并不模仿任何硬件,应用程序仍然在硬件上运行,它只是隔离了应用程序并允许您可以运行该应用程序跟特定的并且完全不是主机操作系统的软件和第三方库合作。这意味着,在启动或停止Docker应用程序时几乎没有开销,因为它们不需要预先分配的内存和磁盘空间等等。因此Docker容器很容易设置或者拆除。此外,容器在假装需要系统中各种硬件组件上运行软件的时候并不浪费任何开销 – 它是直接使用硬件的。

yum安装VirtualBox
配置yum源:
vim /etc/yum.repos.d/virtualbox.repo
输入

[virtualbox]
name=Oracle Linux / RHEL / CentOS-$releasever / $basearch - VirtualBox
baseurl=http://download.virtualbox.org/virtualbox/rpm/el/$releasever/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.virtualbox.org/download/oracle_vbox.asc

然后用yum直接安装:
yum install VirtualBox-5.2

CentOS7下minikube start后VirtualBox执行报错
https://blog.csdn.net/jiekou0376/article/details/80454808

[root@openshift ~]# docker-machine create –driver virtualbox virtualbox1
Running pre-create checks…
Error with pre-create check: “This computer doesn’t have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory”

Docker Swarm

Docker Swarm 和 Docker Compose 都是 Docker 官方容器编排项目,不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署 Docker Swarm 更加适合。

【Docker】 Swarm简单介绍
https://www.cnblogs.com/franknihao/p/8490416.html

Swarm就是一组运行docker的机器,并联合成为一个集群。当启动Swarm集群之后,docker命令会通过Swarm manager执行在整个集群之上。Swarm集群的机器可以是物理机,也可以是虚拟机,当加入Swarm集群之后,被称为nodes。
Swarm managers有两种不同的方式运行container:第一种emptiest node,尽量使用少的机器部署容器;第二种global,确保每一台机器上都会运行一个容器的实例。可以在docker-compose.yml中指定运行的模式。
Swarm managers是集群的核心控制节点,它负责执行命令,授权新机器加入集群。Worker节点只负责提供资源。
docker可以很方便的切换为 swarm mode,切换的命令是docker swarm init,一旦切换为 swarm mode后,当前的机器角色就变为Swarm managers。

Docker

docker

Docker官方文档
https://docs.docker.com/reference/
DOCKER入门
https://ppt.fujiabin.com/tutorial/docker/
Mac上用Docker搭建lamp环境
http://www.56cto.com/1089
Docker for Mac 初体验
https://segmentfault.com/a/1190000005106237
在MAC上运行Docker和Oracle 12.2数据库环境
http://database.51cto.com/art/201705/540105.htm
Spring Cloud 微服务(四) Docker化
http://www.jianshu.com/p/1ce2bc8ce674
将spring cloud打包docker镜像
http://www.cnblogs.com/waterlufei/p/6627280.html
Docker 教程 及 Docker 命令大全
http://www.runoob.com/docker/docker-tutorial.html
http://www.runoob.com/docker/docker-command-manual.html
Docker —— 从入门到实践
https://yeasy.gitbooks.io/docker_practice/content/
https://www.gitbook.com/book/yeasy/docker_practice/details
Docker使用阿里云docker镜像加速
https://www.cnblogs.com/zhxshseu/p/5970a5a763c8fe2b01cd2eb63a8622b2.html
https://dev.aliyun.com/search.html
2017年,使用docker开发应用程序
https://zhuanlan.zhihu.com/p/25092632
下载Docker for Mac
https://download.docker.com/mac/stable/Docker.dmg

容器存储层

镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,这个存储层为容器运行时读写而准备,我们称它为容器存储层。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的持久化操作,都应该使用 数据卷(Volume),或者绑定宿主目录。在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
https://yeasy.gitbooks.io/docker_practice/content/basic_concept/container.html

运行时参数

    • –name 为容器指定一个名称。
    • -t 让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
    • -i interactive,让容器的标准输入保持打开
    • -d detached 以后台进程方式运行容器,并返回容器ID。还可以使用Ctrl+p+q将容器放在后台运行。此时容器不会把输出的结果(STDOUT)打印到宿主机上面(输出结果可以用docker logs 查看)。
    • -p 创建特定端口绑定规则。一个-p指定一个端口映射,可使用多个-p指令多个映射。
    • –rm 容器退出后随之将其删除
    • –restart=always 设置容器的重启策略,以决定在容器退出时Docker守护进程是否重启刚刚退出的容器。–restart选项通常只用于detached模式的容器,i不能与–rm选项同时使用
    • -v 目录或文件映射挂载,宿主中的路径:Docker容器中的路径,主机和容器中某个目录同步。-v 参数可以多次使用,每次映射一个目录。
    • -w 表示将-v映射的/webapp目录设置为work directory,也就是运行node命令的目录。这个设置将覆盖Dockfiie中的设置:/Data。
    • –privileged=true 大约在0.6版,privileged被引入docker。使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限。

更多参数解释 http://blog.csdn.net/alen_xiaoxin/article/details/54694051

运行时端口映射

-p参数内容有几种不同的格式:
ip:hostPort:containerPort| ip::containerPort | hostPort:containerPort | containerPort
其中,ip或者hostPort可以忽略。默认为tcp,如果需要udp,需要在最后指定,比如-p 1234:1234/udp。在多个容器都暴露端口时,须注意避免端口冲突。
所有发布(-p或者-P)的端口都暴露了,但并不是所有暴露(EXPOSE或–expose)的端口都会发布。

link用来解决关联的容器IP变化的问题,而expose只是用来标记一下开放的端口,没有任何实际的效果,官方文档上说给link用其实是种误导。因为在没有link和expose情况下,通过IP+端口也能从一个容器访问另一个容器的服务。

快速参考:

创建一个新的容器并运行一个命令

命令跟在镜像名之后,命令运行后容器终止。当Docker容器中指定的应用终结时,容器也自动终止。

docker run ubuntu /bin/echo "Hello world"
docker run ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

运行交互式的容器

docker run --name name1 -i -t ubuntu /bin/bash

通过exit命令或使用CTRL+D退出并停止容器。使用组合键 ctrl(Mac上是control) + p + q 退出容器后容器不会停止。

交互式连接容器

如果容器运行的时候加了 -d 参数,就可以通过 attach 或 exec 进入容器进行操作:

docker attach -i -t CONTAINER_NAME /bin/bash
docker exec -it CONTAINER_ID bash
docker exec -it CONTAINER_ID /bin/sh

运行mysql

docker run -p 3306:3306 --name mysql1 -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6

使用Docker快速搭建Mysql,并进行数据卷分离
https://www.jianshu.com/p/57420240e877
docker安装mysql,可能mysql8要对用户进行授权,否则用navicat连接不上。
https://blog.csdn.net/wyl9527/article/details/79111467

运行nginx

nginx相关路径有 /etc/nginx/、/etc/nginx/conf.d、/usr/share/nginx/html

docker run --name nginx1 -p 8887:80 -v /主机html目录:/usr/share/nginx/html nginx
docker run -p 81:80 --name szsmart-www -v /opt/szsmart/angular:/usr/share/nginx/html -d nginx
docker run -p 82:80 --name hksmart-www -v /opt/hksmart/angular:/usr/share/nginx/html -d nginx

运行mongo

docker run -p 14000:27017 --name mongo_db -v /opt/mongo_db:/data/db -d mongo

运行tomcat

docker run -d –restart always -v /alidata/webapps/ReadAdmin.war:/usr/local/tomcat/webapps/ReadAdmin.war -p 8080:8080 –name tomcat1 tomcat
Docker实践 – 安装Docker并在容器里运行tomcat
https://blog.csdn.net/massivestars/article/details/54352484

数据卷Volume映射

-v 后面可以跟多个映射,本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动创建它。
Docker 挂载数据卷的默认权限是读写,可以在容器路径后加上 :ro 指定为只读。

-v /some/nginx.conf:/etc/nginx/nginx.conf:ro

还可以对正在运行的容器追加映射:

docker run -v /path/to/hostdir:/mnt $container

生成镜像

1.从基础镜像生成镜像
编辑Dockerfile文件,例如输入内容:

FROM docker.io/tomcat    #基础镜像
MAINTAINER XXX@qq.com    #作者
COPY docker.war /usr/local/tomcat/webapps  #拷贝war包到tomcat的webapps目录

根据当前目录下的Dockerfile文件配置生成镜像

docker build -t nginx-demo:v1 .

2.保存容器成镜像
将容器的存储层保存下来成为镜像,在旧的镜像上添加了新的一层,形成新的镜像。
脱离容器保持运行,使用ctl+p+q快捷键,然后可以看到刚启动的容器继续在运行。

docker commit -m "descriptiont" -a "author" container_id new_name
docker commit \
--author "作者" \
--message "修改了默认网页" \
webserver \
nginx:v2

导出镜像为文件

docker save container_ID > /home/nginx-demotest.tar

查看容器相对镜像的改动
docker diff CONTAINER_ID
查看镜像内的历史记录
docker history 镜像名

其它命令

#启动docker服务
service docker start

镜像操作:

#查找镜像
docker search ubuntu
#获取镜像
docker pull nginx:latest
#查看本地镜像
docker images | grep abc
docker images IMAGE_NAME
#删除镜像
docker rmi IMAGE_ID

容器操作:

#查看运行的容器
docker ps
#查看运行和终止状态的容器
docker ps -a
#删除容器
docker rm  CONTAINER_ID  要删除一个运行中的容器,可以添加 -f 参数,Docker 会发送 SIGKILL 信号给容器。
docker rm $(docker ps -a -q) 清理所有处于终止状态的容器。
docker stop $(docker ps -q) 停用全部运行中的容器
docker rm $(docker ps -aq) 删除全部容器
docker stop $(docker ps -q) & docker rm $(docker ps -aq) 一条命令实现停用并删除容器

#查看容器内的标准输出。-f 查看实时日志
docker logs -f CONTAINER_ID
#停止容器运行,对于只启动了一个终端的容器,通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。
docker stop CONTAINER_ID
#将一个终止状态的容器启动运行
docker start CONTAINER_ID
#重启容器
docker restart CONTAINER_ID
#容器内运行nginx服务
docker exec CONTAINER_ID nginx  
#查看容器运行时端口绑定信息
docker port CONTAINER_ID
#查看容器详细的网络信息
docker inspect CONTAINER_ID
#查看容器的IP
docker inspect CONTAINER_ID | grep '"IPAddress"',或者 进入容器内部后 cat /etc/hosts
#主机和容器之间拷贝文件
docker cp ...

Detached vs foreground

启动一个container时,首先需要确定这个container是运行在前台模式还是运行在后台模式。
Detached (-d)
如果在docker run 后面追加-d=true或者-d,则containter将会运行在后台模式(Detached mode)。此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为container不再监听你执行docker run的这个终端命令行窗口。但你可以通过执行docker attach 来重新挂载这个container里面。需要注意的时,如果你选择执行-d使container进入后台模式,那么将无法配合”–rm”参数。
Foregroud
如果在docker run后面没有追加-d参数,则container将默认进入前台模式(Foregroud mode)。Docker会启动这个container,同时将当前的命令行窗口挂载到container的标准输入,标准输出和标准错误中。也就是container中所有的输出,你都可以再当前窗口中查看到。
容器是否会长久运行,和docker run指定的命令有关,和 -d 参数无关。

查找镜像
sudo docker search nginx
而具体版本号到https://hub.docker.com/explore/中查找。

How to run NGINX as a Docker container
https://www.techrepublic.com/article/how-to-run-nginx-as-a-docker-container/

Linux f2b4dd41f60e 4.9.49-moby #1 SMP Wed Sep 27 23:17:17 UTC 2017 x86_64 GNU/Linux

查看docker容器的系统信息

wangweikedeMacBook:~ admin$ docker run --name nginx1029 -t -i nginx bash
root@b519367267ca:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@b519367267ca:/# uname -r
4.9.36-moby
root@b519367267ca:/# uname -a
Linux b519367267ca 4.9.36-moby #1 SMP Wed Jul 12 15:29:07 UTC 2017 x86_64 GNU/Linux

公司测试服务器

#mongodb
docker run -p 14000:27017 –name mongo_db -v /opt/mongo_db:/data/db -d mongo
docker run -p 81:80 –name szsmart-www -v /opt/szsmart/angular:/usr/share/nginx/html -d nginx
docker run -p 82:80 –name hksmart-www -v /opt/hksmart/angular:/usr/share/nginx/html -d nginx

在Centos中安装与卸载docker

yum install docker-io
service docker start

https://docs.docker.com/install/linux/docker-ce/centos/#install-docker-ce-1
https://rancher.com/docs/rancher/v1.6/zh/hosts/#docker%E7%89%88%E6%9C%AC%E9%80%82%E7%94%A8%E5%AF%B9%E6%AF%94

docker容器运行后退出的问题

Docker容器后台运行,就必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。这个是docker的机制问题。

docker run -d -it --net=host --name cnmp4 wwk/cnmp /bin/sh

http://blog.51cto.com/gentle/1826820

使用 Dockerfile脚本 定制镜像

把每一层修改、安装、构建、操作的命令都写入Dockerfile,用这个脚本来构建、定制镜像,解决了之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题。
使用Dockerfile构建Docker镜像为一个规范的方式,根据Dockerfile可以了解镜像中安装的组件的详细内容。
Dockerfile一般由四部分组成:
第一,构建的基础镜像;
第二,镜像构建者的信息;
第三,构建镜像过程中镜像层添加指令;
第四,由该镜像启动容器时执行的程序。

link

设定的别名要和容器环境中使用的变量名字一致。

Docker在连接容器的时候,会根据–link提供的参数自动的在接收者容器中创建一些环境变量,包括源容器的Dockerfile中使用ENV命令设置的环境变量和源容器启动时(docker run),使用-e或者–env, –env-file参数指定的环境变量。
除了环境变量之外,Docker也在接收容器的/etc/hosts文件中更新了hosts信息。与环境变量不同的是,如果源容器重启了,接收容器中/etc/hosts中的信息会自动更新。
https://www.cnblogs.com/jytx/p/5438747.html

基于Docker搭建LNMP环境,独立安装mysql、php-fpm、nginx,然后各容器用link参数建立起联系。
https://blog.csdn.net/xy752068432/article/details/75975065

https://blog.csdn.net/zhangyifei216/article/details/50921215
https://www.jianshu.com/p/13752117ff97

docker加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF' #相当于在daemon.json中输入以下内容
{
  "registry-mirrors": ["https://4qqg0972.mirror.aliyuncs.com"]
}
EOF
#重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker

wordpress

docker run --name wp1 --link mysql1:mysql -p 80:80 -v /home/apache2/apache2.conf:/etc/apache2/apache2.conf -v /home/www/brogrammer:/var/www/html -e WORDPRESS_DB_NAME=wwk_wordpress -d wordpress

Centos 7.5 中 docker 启动web服务,但外部无法访问。

解决办法:
# vi /etc/sysctl.conf
或者
# vi /usr/lib/sysctl.d/00-system.conf
添加如下代码:
net.ipv4.ip_forward=1

重启network服务,或者重启服务器。
# systemctl restart network

docker容器中安装缺失命令

先要执行apt-get update同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。
apt-get install vim
​apt-get install telnet
apt-get install net-tools
apt install iputils-ping

设置docker开机自启动
systemctl enable docker
成功后打印 Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.