docker容器极简教程

一,小王对于容器的困惑

小王刚开始学习Docker的时候,找资料在网上看到最多的是Docker的好处。比如:

1、Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多

2、Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。

3、更快速的交付和部署、更轻松的迁移和扩展

等等……

因为小王是做java开发的,他们现有的模式是在一个服务器上安装统一一个jdk,运行多个tomcat,每个tomcat里面一个java应用,大家也知道tomcat不用安装,当他们项目要迁徙的时候也只需要把整个tomcat打包然后在另一台服务器上解压就ok了,也很简单。。。当时小王就不懂Docker有什么好处,一度以为对他们现有的模式没用。知道昨天跟其他人交流小王才弄明白一个问题,那就是应用隔离与资源独立!!

这是小王刚画的一个图,现在他们的模式是A1,所有的应用共享服务器的CPU、内存等资源,这时如果一个应用出现问题,比如CPU爆满等等,另一个应用也就玩完了。所以要这时就要做到资源独立,一个应用一份资源,现在要做到这样只有做成A2那样,一个服务器上装几个虚拟机,一个虚拟机一个应用。这时如果你要重启虚拟机,你想想你重启电脑要多久。而且你想迁移应用的话,你就又要装虚拟机,配环境等等,麻烦不?我是觉得麻烦。如果有了Docker,就是A3 的模式,容器是什么概念我就不说了,这时一个服务器上运行多个容器,一个容器拥有独立的CPU、内存等资源,完全满足了应用隔离的需求。而且容器重启,1秒搞定!应用迁移的时候,这个大家应该也知道,所有装了Docker的服务器,只需把镜像pull或者load进去,run,一切OK,就是这么任性!

二,docker教程

基本概念

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

  • 镜像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的是镜像,信息多,包含元数据和历史信息。

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

    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/searchdocker pull 139.196.xx.xx:5000/test
  • Tip:
    CURL(CommandLine Uniform Resource Locator):curl是利用URL语法在命令行方式下工作的开源文件传输工具。
    安装Docker(Ubuntu16.04),默认安装在/var/lib/docker

        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)

    进阶概念

    数据管理:在使用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,之后其他容器将挂载可以挂载该数据卷容器中的数据卷。

        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.tar

        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查看端口配置。

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

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

        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    
      
        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

    数据库应用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.2docker run -p 27017:27017 -p 28017:28017 --name mongodb01 -v $PWD/db01:/data/db -e MONGODN_PASS="123456" -d mongo:3.2//redisdocker pull  redis:3.2docker 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优点

    ​  1、快速分发应用

    Docker可以帮助你把控开发各个周期。Docker允许你在本地的开发环境中进行代码开发,然后将开发好的应用整合到团队的开发流程中。

    比如:你可以再本地编写代码,当编写完成后。你将代码开发堆栈信息共享给团队成员。当他们也编写完成后,同样共享开发堆栈信息。然后再测试环境中,使用团队共享的开发堆栈就可以进行所需要的测试了。当完成测试后,团队就可以将测试通过的docker镜像(images)发布到产品环境中。

    2、方便部署和易于管理

    Docker基于容器的机制可以很容易进行部署。Docker容器可以在本地主机上面执行,也可以在虚拟机中执行,不论这些虚拟机是在本地或者云中。

    Docker快速部署和轻量级的特性也使得管理负载变得很容易。你可以快速启动或者销毁容器。这种时间几乎是实时的。

    3、可以执行大量的工作负载

    因为Docker具有便于部署和快速启停的方式,同时docker也提供了可行的,符合效益-成本的虚拟机管理机制。使得docker很适合负载要求高的环境。比如:将你的云平台作为PAAS用途时,或者你要求你的环境具有高资源使用率时。

    参考连接:http://www.batxue.com/html/jsgh/20171010/2074.html

    最后编辑于
    ©著作权归作者所有,转载或内容合作请联系作者
    • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
      沈念sama阅读 206,839评论 6 482
    • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
      沈念sama阅读 88,543评论 2 382
    • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
      开封第一讲书人阅读 153,116评论 0 344
    • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
      开封第一讲书人阅读 55,371评论 1 279
    • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
      茶点故事阅读 64,384评论 5 374
    • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
      开封第一讲书人阅读 49,111评论 1 285
    • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
      沈念sama阅读 38,416评论 3 400
    • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
      开封第一讲书人阅读 37,053评论 0 259
    • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
      沈念sama阅读 43,558评论 1 300
    • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
      茶点故事阅读 36,007评论 2 325
    • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
      茶点故事阅读 38,117评论 1 334
    • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
      沈念sama阅读 33,756评论 4 324
    • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
      茶点故事阅读 39,324评论 3 307
    • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
      开封第一讲书人阅读 30,315评论 0 19
    • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
      开封第一讲书人阅读 31,539评论 1 262
    • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
      沈念sama阅读 45,578评论 2 355
    • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
      茶点故事阅读 42,877评论 2 345

    推荐阅读更多精彩内容

    • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
      ahohoho阅读 15,508评论 15 147
    • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
      极客圈阅读 10,473评论 0 120
    • 五、Docker 端口映射 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的。此外,除了...
      R_X阅读 1,738评论 0 7
    • 0x01 核心概念 Docker镜像类似于虚拟机镜像,可以理解为一个面向Docker引擎的只读模板,包含了文件系统...
      闲云逸心阅读 4,695评论 0 9
    • 转眼间毕业五年,时间就在指尖悄悄的溜在,经历过迷茫无助,可现在想想,更加迷茫,更加无助,我得到了什么,又失...
      每天都是路过阅读 254评论 0 0