Docker快速入门

Docker已经火了很长一段时间,最近打算在阿里云上好好熟悉一下Docker的相关应用,为从此的工做作准备,但愿以下图同样,Docker技术一飞冲天。
javascript

基本概念

Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初发起者是dotCloud公司,其目标是“Build, Ship and Run Any App, Anywhere”,主要概念包括镜像、容器、仓库。Docker引擎的技术是Linux容器(Linux Containers, LXC)技术。容器有效地将由单个操做系统的资源划分到孤立的组中,以便更好地在孤立的组之间平衡有冲突的资源使用需求。
java

  • 镜像Image:相似于虚拟机镜像,能够理解为面向Docker引擎的只读模板,包括文件系统。
    获取镜像:docker pull NAME[:TAG]
    查看镜像信息: 查看全部镜像docker images;查看某个镜像具体信息docker inspect
    添加标签: docker tag xxx ubuntu:first
    搜寻镜像: docker search xxx-s=0指定星级
    删除镜像: docker rmi xxx,通常状况下会删除镜像的标签,而不是文件,当删除最后一个TAG时则会删除文件,须要注意。
    使用镜像ID删除镜像: -f删除能够强制删除镜像,推荐作法为先删除依赖该镜像的全部容器,以后删除镜像,Qdocker rm e81
    建立镜像: 建立镜像包括3种方式,基于已有镜像的容器建立,首先启动一个镜像docker run -ti ubuntu:14.04 /bin/bash,任意建立一个test文件,以后建立镜像docker commit -m "add file" -a "xionger" a9fdsfxx test;基于本地模板建立,推荐使用OpenVZ提供的模板来建立;基于Dockerfile建立。
    存出镜像和载入镜像(导出、导入): 导出到本地文件sudo docker save -o ubuntu_14.04.tar ubuntu:14.04,导入镜像docker load --input ubuntu_14.04.tar
    上传镜像: docker push NAME[:TAG],默认上传镜像到DockerHub官方仓库,须要登陆。
  • 容器Container:相似一个轻量级的沙箱,能够利用容器来运行和隔离应用,容器从镜像启动时会在镜像的最上层建立一个可写层,镜像自己保持不变
    建立容器:docker create -it ubuntu:lastest,经过docker ps -a查看容器,经过docker start启动容器
    新建并启动容器:docker run ubuntu /bin/bash,-d参数守护态运行,经过Ctrl+d或者exit退出容器
    终止容器:docker stop xxx,首先会发送SIGTERM信号,一段时候后发送SIGKILL,能够经过docker kill强行停止,docker restart能够关闭并重启容器,docker ps -a -q能够查看处于终止态的容器信息。
    进入容器:docker attach xxx会被阻塞不推荐使用;docker exec -ti xxx /bin/bash能够直接在容器中运行命令;nsenter工具。
    删除容器:docker rm xxx,须要注意区分,rmi是删除镜像,rm是删除容器
    导入和导出容器:docker export xxx导出一个已经建立的容器到文件,不论是否在运行;docker import,须要理解的是export的是快照,信息少,而save的是镜像,信息多,包含元数据和历史信息。
    node

  • 仓库Repository:相似于代码仓库,是Docker存放镜像的场所,而Registry注册服务器是存放仓库的地方,其上放着不少仓库,每一个仓库集中存放某一类镜像的多个文件,能够经过tag标签来区分。目前最大的公有仓库是Docker Hub,而国内是Docker Pool。
    Docker Pub:本地用户目录.dockercfg中存储登陆信息,在仓库中存在centos这类由Docker公司建立、验证、支持的根镜像,也有相似xionger/centos这类由我的提供的镜像,能够经过-s N来查看高星镜像。此外,Docker Hub还能够经过设置追踪相似GitHub的网站,而后根据其更行,自动执行建立。
    建立和使用私有仓库:能够经过官方提供的registry镜像来简单搭建一套本地私有仓库环境。python

    docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry docker images docker tag ubuntu:14.04 139.196.96.27:5000/test docker push 139.196.xx.xx:5000/test curl http://139.196.xx.xx:5000/v1/search docker pull 139.196.xx.xx:5000/test

Tip:
CURL(CommandLine Uniform Resource Locator):curl是利用URL语法在命令行方式下工做的开源文件传输工具。
安装Docker(Ubuntu16.04),默认安装在/var/lib/dockermysql

sudo apt-get install apt-transport-https sudo apt-get update sudo apt-get install -y docker.io

Tip:
在用putty链接阿里云时,常常会断开,如何解决?
解决方法:在Connection里面有个Seconds between keepaliaves。这里就是每间隔指定的秒数,就给服务器发送一个空的数据包,来保持链接。以避免登陆的主机那边在长时间没接到数据后,会自动断开SSH的链接,设置为10。
阿里云购买ECS, 操做系统版本Ubuntu 16.04(LTS)nginx

进阶概念

数据管理:在使用docker过程当中,会涉及查看容器内应用产生的数据,或者数据在多个容器间共享,此时须要管理数据的两种方式包括数据卷Data Volumes和数据卷容器Data Volume Containers.
数据卷:是一个可供容器使用的特殊目录,绕过文件系统,具备的特性包括数据卷能够在容器之间共享和重用、对数据卷的修改会立刻生效、对数据卷的更新不会影响镜像、卷会一致存在,知道没有容器使用,相似Linux下对目录或文件进行mount操做。
在容器内建立一个数据卷:使用training/webapp镜像建立一个web容器,并建立一个数据卷挂在到容器的/webapp目录,docker run -d -P --name web -v /webapp python app.py
挂载一个主机目录做为数据卷:加载主机的/src/webapp目录到容器的/opt/webapp目录,docker run -d -P --name web - v /src/webapp:/opt/webapp training/webapp python app.py
Tip:编辑工具包括vi或者sed --in-place,推荐挂载目录而不是文件,由于inode变化会形成docker容器启动失败。
数据卷容器:其实就是一个普通的容器,其中会挂载数据卷用户共享,建立数据库容器dbdata,以后其余容器将挂载能够挂载该数据卷容器中的数据卷。git

docker run -it -v /dbdata --name dbdata ubuntu ls docker run -it --volumes-from dbdata --name db1 ubuntu

利用数据卷容器迁移数据:能够经过数据卷容器对其中的数据卷进行备份、回复,以实现数据的迁移。接下来的示例利用ubuntu镜像建立一个容器worker,使用--volumes-from dbdata参数挂载dbdata容器的数据卷,
使用-v ${pwd}:/backup参数来挂载本地的当前目录到worker容器的/backup目录,
容器启动后,使用tar cvf /backup/backup.tar /dbdata来说/dbdata下内容备份为容器内的/backup/backup.tarweb

docker run --volumes-from dbdata -v ${pwd}:/backup --name worker ubuntu tar cvf /backup/backup.tar /dbdata //恢复,首先建立一个带有数据卷的容器dbdata2,以后 建立另外一个新的容器,挂载dbdata2容器,并使用untar解压备份文件到所挂载的容器卷中便可 docker run -v /dbdata --name dbdata2 ubuntu /bin/bash docker run --volumes-from dbdata2 -v ${pwd}:/backup busybox tar xvf /backup/backup.tar

在生产环境,推荐使用分布式文件系统Ceph、GPFS、HDFS按期对主机的本地数据进行备份。
网络基础配置:
端口映射实现访问容器:在启动容器时,若是不指定对应参数,在容器外部是没法经过网络来访问容器内的网络应用和服务的。可使用-p ip:hostPort:containerPort映射端口,docker logs查看应用的信息,docker port查看端口配置。redis

docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py

容器互联实现容器间通讯:容器见的链接系统是除了端口映射外另外一种能够与容器中应用进行交互的方式,它会在源和接受容器间建立一个隧道,接受容器能够看到源容器制定的信息,好比--link链接应用容器和数据库容器,这样能够保证db的接口不暴露到公网。sql

docker run -d -P --name web training/webapp python app.py docker ps -l docker inspect -f xxx //容器互联 docker run -d --name db training/postgres docker rm -f web docker run -d -P --name web --link db:db training/webapp python app.py docker ps

Docker经过两种方式为容器公开链接信息,包括环境变量env和/etc/hosts文件,经过apt-get install -yqq inetutils-ping安装ping。
扩展知识:Docker已有的实现PaaS的项目有Deis、Flynn等,持续集成方面有Drone,管理工具备Citadel, Shipyard, DockerUI等。

使用Dockerfile建立镜像

基本结构:dockerfile由命令语句组成,支持#开头的注释,分为4个部分,包括基础镜像信息、维护者信息、镜像操做指令和容器启动执行指令,在docker hub上有不少dockerfile的demo,须要时能够直接使用。

#基础镜像 FROM ubuntu #维护者信息 MAINTAINER xionger xiongere@email.com #镜像的操做指令 RUN apt-get update && apt-get install -y nginx RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf #容器启动时执行指令 CMD /usr/sbin/nginx

指令:通常格式为INSTRUCTION arguments,具体以下所示。
FROM <image>:<tag>默认的第一条指令
MAINTAINER <name>维护者信息
RUN <command>或者RUN ["executable", "param1", "param2"],前者将在shell终端中运行命令,即/bin/sh -c,后者则使用exec执行。
CMD ["executable", "param1", "param2"]使用exec执行,推荐方式。
EXPOSE <port> [<port>..]告诉Docker服务器容器暴露的端口号,供互联网系统使用。
ENV <key> <value>指定一个环境变量,会被后续的RUN指令使用
ADD <src> <dest>该命令将复制指定到容器中的
COPY <src> <dest>复制本地主机<src>到容器中<dest>,推荐使用
ENTRYPOINT ["executable", "param1", "param2"]配置容器启动后执行的命令,不能被docker run提供的参数覆盖
VOLUME ["/data"]建立一个能够从本地主机或其余容器挂载的挂载点,通常用来存放数据库和须要保持的数据。
USER daemon指定运行容器时的UID,后续的RUN也会使用指定用户,如RUN group add -r postgres && useradd -r -g postgres postgres,要获取管理员权限时可使用gosu而不是sudo
WORKDIR path/to/workdir为后续的指令配置工做目录
ONBUILD [INSTRUCTION]配置当所建立的镜像做为其余新建立镜像的基础镜像时,所执行的操做指令。

建立镜像:编写好dockerfile后,能够经过docker build命令来建立镜像,该命令将读取指定路径下(包括子目录)的dockerfile,并将该路径下全部内容发送给docker服务端,由服务端来建立镜像,此外能够经过.dockerignore文件来忽略目录或文件,还能够经过-t指定镜像的标签信息。示例docker build -t build_repo/first_image /tmp/docker_builder/

实践之道

操做系统:CentOS和Ubuntu均可以,我的喜爱ubuntu(还能够选用debian:jessie, alpine),属于最基础的镜像。
tip: 当试图安装软件出现没有相关包信息时,须要apt-get update或编辑/etc/apt/sources.list文件(deb, deb-src,须要时在查询,好比163的镜像,阿里云的话无需设置),能够经过netstat -tunlp查看当前网络状况。
支持SSH:当须要直接进入容器进行管理时安装,没必要须。
Web服务器与应用(Nginx,可使用淘宝优化的Tengine代替Nginx,Tomcat):在/usr/docker下建立tomcat,nginx目录应用存放Dockerfile文件,最终仍是选择经过pull拉去镜像的方式安装应用,dockerfile比较复杂。

docker pull nginx:1.12 docker ps -a //-p 80:80:将容器的80端口映射到主机的80端口 //-name mynginx:将容器命名为mynginx //-v $PWD/www:/www:将主机中当前目录下的www挂载到容器的/www //-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:将主机中当前目录下的nginx.conf挂载到容器的/etc/nginx/nginx.conf //-v $PWD/logs:/wwwlogs:将主机中当前目录下的logs挂载到容器的/wwwlogs docker run --name nginx01 -p 80:80 -v $PWD/www:/www -v $PWD/conf:/etc/nginx -v $PWD/logs:/wwwlogs -d nginx:1.12 docker pull tomcat:8.0 docker run --name tomcat01 -p 8080:8080 -v $PWD/test:/usr/local/tomcat/webapps/test -d tomcat:8.0

tip:
有时可能须要重启docker服务, service docker restart,能够选择tomcat7.0:jdk1.8
nginx配置详解
nginx官方文档
数据库应用MySQL(5.6), MongoDB(3.2), Redis(3.2)

docker pull mysql
docker run -p 3306:3306 --name mysql01 -v $PWD/conf:/etc/mysql -v $PWD/logs:/logs -v $PWD/data:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -d mysql //主从模式 docker run -p 3306:3306 --name mysql01 -v $PWD/conf01:/etc/mysql -v $PWD/logs01:/logs -v $PWD/data01:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -e REPLICATION_MASTER=true -d mysql docker run -p 3307:3306 --name mysql02 -v $PWD/conf02:/etc/mysql -v $PWD/logs02:/logs -v $PWD/data02:/mysql_data -e MYSQL_ROOT_PASSWORD=123456 -e REPLICATION_SLAVE=true --link mysql01:mysql01 -d mysql //mongodb,暂时单机,其默认提供集群的配置 docker pull mongo:3.2 docker run -p 27017:27017 -p 28017:28017 --name mongodb01 -v $PWD/db01:/data/db -e MONGODN_PASS="123456" -d mongo:3.2 //redis docker pull redis:3.2 docker run -p 6379:6379 --name redis01 -v $PWD/data01:/data -d redis:3.2 redis-server --appendonly yes

tip:能够进入db的容器进行操做docker exec -ti mysql /bin/bash
其余应用:maven, gitlab, jenkins, dubbo, cat,具体内容将在以后的文章中陆续介绍。

docker pull jenkins:2.60.1 docker run --name jenkins01 -p 9090:8080 -p 9091:50000 -v $PWD/jenkins01:/var/jenkins_home -d jenkins:2.60.1

构建Docker容器集群:核心问题就是让不一样主机中的Docker容器相互访问,简单的方式包括两种。使用自定义网桥链接跨主机容器,Docker默认的网桥是docker0,能够经过brctl show查看。使用Ambassador容器:当2个docker容器再赞成主机时,能够经过--link相互访问,若是须要跨主机实现,则须要知道其余物理主机的IP地址。
Docker CI集成方案:在以后的Jenkins一文中将重点分析。

Tip:目前百度BAE已经在生产环境使用Docker,Airbnb,ebay已使用mesos集成docker部署应用,此外可使用apparmor对容器的能力进行限制。我的目前实践计划私有Docker仓库暂时不创建,先使用DockerHub;Git相似,先使用Github;Maven须要使用Nexus创建一个私有库;jenkins之间搭建就好。

相关文章
相关标签/搜索