docker(1)

容器时代Docker

1.1   Docker容器

1.1.4  组成

两个进程:

Docker 使用客户端-服务器 (C/S) 架构模式。Docker 客户端会与 Docker 守护进程进行通信。Docker 守护进程会处理复杂繁重的任务,例如建立、运行、发布你的 Docker 容器。Docker 客户端和守护进程可以运行在同一个系统上,当然你也可以使用 Docker 客户端去连接一个远程的 Docker 守护进程。Docker 客户端和守护进程之间通过 socket 或者 RESTful API 进行通信。

1.1.5  Docker核心概念

VM虚拟机的出现可以让服务器资源可以充分利用,一台服务器上可以安装多个VM,而每个VM又形成资源隔离,使不同的VM可以使用同一台服务器,却互相不干扰。Docker同理,它也是将硬件资源抽象。

Docker两个最重要的概念是镜像和容器。镜像类似虚拟机的快照,但更轻量,非常非常轻量。举例来说,VM相当于绿皮火车,Docker就相当于劳斯莱斯小汽车。VM的快照通常2~3G,而Docker只有100~300M。

1.1.5.1 镜像image

简单说,镜像就是一个只读模板。

创建Docker镜像有几种方式,多数是在一个现有镜像基础上创建新镜像,因为几乎你需要的任何东西都有了公共镜像,包括所有主流Linux发行版,你应该不会找不到你需要的镜像。不过就算你想从头构建一个镜像也有好几种方式。

实现的方式有两种:在一个文件Dockerfile中指定一个基础镜像及需要完成的修改;或通过“运行”一个镜像,对其进行修改并提交。不同方式各有优点,不过一般会使用文件Dockerfile来指定所做的变化。

镜像拥有唯一ID,以及一个供人阅读的名字和标签对。镜像可以命名为类似ubuntu:latest、ubuntu:precise、django:1.6、django:1.7等等。

1.1.5.2 容器container

每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

可以从镜像中创建容器,这等同于从快照中创建虚拟机,不过更轻量。应用是由容器运行的。容器与虚拟机一样,是隔离的。它们也拥有一个唯一ID和唯一的供人阅读的名字。容器有必要对外暴露服务,因此Docker允许暴露容器的特定端口。

容器启动时,将被分配一个随机的私有IP,其它容器可以使用这个IP地址与其进行通讯。这点非常重要,原因有二:一是它提供了容器间相互通信的渠道,二是容器将共享一个本地网络。

要开启容器间通讯,Docker允许你在创建一个新容器时引用其它现存容器,在你刚创建的容器里被引用的容器将获得一个(你指定的)别名。我们就说,这两个容器链接在了一起。

因此,如果DB容器已经在运行,我可以创建web服务器容器,并在创建时引用这个DB容器,给它一个别名,比如dbapp。在这个新建的web服务器容器里,我可以在任何时候使用主机名dbapp与DB容器进行通讯。

1.1.5.3 数据卷volume

Docker是只读的,那就产生一个问题,例如mysql,用户有自己的数据,那这部分数据怎么保存呢?Docker提供了数据卷就用来保存持久的数据。

卷是针对容器的,你可以使用同一个镜像创建多个容器并定义不同的卷。卷保存在运行Docker的宿主文件系统上,你可以指定卷存放的目录,或让Docker保存在默认位置。

注意:定义了数据卷,Docker迁移就可能失败,可能新的机器没有对应目录。另外,如果数据量非常大,Tb级别的,docker镜像才几百兆。所以并不推荐使用数据卷方式,最好就是只读的,运行时只产生临时数据,不产生业务数据,退出、删除无需额外处理。

1.1.5.4 仓库repository

Docker有一个类似版本管理仓库(Repositry)的东西,有docker.io提供的官方仓库(index.docker.io,相当于github),也可以自建(叫docker-registry,相当于自己搭建一个小型github)。

 

Git

Docker

GitHub

DockerHub

用户 User Account

用户 User Account

仓库 Repository

仓库 Repository

分支 Branch

镜像 Image

标签 Tag

标签 Tag

Push 推送,上传

Push 推送,上传

Pull/Clone 拉取/克隆

Pull 拉取

Commit 提交

Commit 提交

Merge 合并

N/A

 

1.1.6  包洋葱

简单来说docker是利用AUFS文件系统的支持,反复包裹形成无数的镜像,公用相同的部分(Image),又可以形成自己独有的内容(Container)。镜像支持使之可以站在巨人的肩膀上(已经实现的内容),又变化无穷(独有的内容)。

Container和Image 在Docker的世界里,Image是指一个只读的层(Layer),这里的层是AUFS里的概念,最直观的方式就是看一下docker官方给出的图:

AUFS的文件系统可以让你一层一层地叠加修改你的文件,最底下的文件系统是只读的,如果需要修改文件,AUFS会增加一个可写的层(Layer),这样有很多好处。例如,不同的Container可以共享底层的只读文件系统(同一个Kernel),使得你可以跑N多个Container而不至于你的硬盘被挤爆了,复用了相同的内容(本地镜像库中的镜像),大大减小了存储空间。

1.1.7  那Image和Container的区别是什么?

很简单,它们的区别仅仅是一个是只读的层,一个是可写的层。你可以使用docker commit 命令,将你的Container变成一个Image,也就是提交你所运行的Container的修改内容,变成一个新的只读的Image,这非常类似于git commit命令。

1.1.8  Docker的特征

序号

特征

说明

1.    

更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

2.    

更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

3.    

一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现“这段代码在我机器上没问题啊”这类问题。

4.    

持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

 

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署。

 

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

5.    

更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

6.    

更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

7.    

敏捷开发

有了Docker的支持,部署速度快捷,三大环境的统一(开发、测试、生产环境),支持敏捷开发。

1.1.9  面试:Docker与VM虚拟机的不同点

1.  虚拟化技术依赖物理CPU和内存,是硬件级别的;而docker构建在操作系统上,利用操作系统的containerization容器技术,所以docker甚至可以在虚拟机上运行。

2.  启动速度快,比VM快太多了,启动、停止、开始、重启都是秒级甚至毫秒级。

3.  轻量级虚拟化,在一台服务器上可以部署100~1000个Container容器。而VM一台服务器能部署10到20就很不错了。

4.  *Docker是单线程,Docker设计者极力推崇“一个容器一个进程的方式”。无法很好地模拟一个完整的环境(详细参加LXC)。

5.  *当停止一个虚拟机时,可能除了一些临时文件,没有文件会被删除(业务产生的文件);但当停止一个Docker容器,对初始状态(创建容器所用的镜像的状态)做的所有变化都会丢失。这是使用Docker时必须做出的最大思维变化之一:容器是短暂和一次性的。所以有种说法,例如mysql这样的数据库还是不要用Docker的好,因为数据库在使用过程中会有很多业务数据。

6.  Docker的安全性目前比VM要差。VM做到资源完全隔离,而Docker会共享资源,这就带来了安全的风险。

1.2    Centos7下安装Docker

1.2.1  配置虚拟机

docker官方文档要求必须运行在Linux kernel 3.8以上,所以需要安装在Centos7或者Ubantu系统上。

yum install lrzsz        #安装上传下载组件

uname –a                 #检查当前Linux内核版本

查询结果:

Linux tdocker 3.10.0-327.el7.x86_64 #1 SMP Thu Nov19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

1.2.2  VM配置NAT模式网络上网

修改配置文件

cd /etc/sysconfig/network-scripts  #进入网络配置目录

dir ifcfg*                         #找到网卡配置文件

ifcfg-eno16777736 ifcfg-lo

vi ifcfg-eno16777736

配置文件内容

TYPE=Ethernet

BOOTPROTO=static                              #改成static,针对NAT

NAME=eno16777736

UUID=4cc9c89b-cf9e-4847-b9ea-ac713baf4cc8

DEVICE=eno16777736

ONBOOT=yes               #开机启动此网卡

IPADDR=192.168.163.30       #固定IP地址

NETMASK=255.255.255.0       #子网掩码

GATEWAY=192.168.163.2       #网关和NAT自动配置的相同,不同则无法登录

DNS1=192.168.163.2          #和网关相同

测试

centos7   命令发生巨大变化

ip addr                     #查看IP地址 ip add

service network restart  #重启网络

systemctl restart network.service  #重启网络centos7

vi /etc/hosts            #127.0.0.1 dredis

hostname dreids          #注意必须修改机器名hostname

ping www.baidu.com          #如果出现baidu的ip地址则表示网络连通

1.2.3  安装Docker

1.2.3.1          第一步:安装工具包

$ sudo yum install -y yum-utils        #安装工具包,缺少这些依赖将无法完成

执行结果:

Loaded plugins: fastestmirror, langpacks

base                                                                                          |3.6 kB  00:00:00

epel                                                                                         | 4.3 kB  00:00:00

extras                                                                                       | 3.4kB  00:00:00

update                                                                                       | 3.4 kB  00:00:00

(1/3): epel/7/x86_64/updateinfo                                                              | 797 kB  00:00:00

(2/3): epel/7/x86_64/primary_db                                                              | 4.7 MB  00:00:00

(3/3): update/7/x86_64/primary_db                                                            | 4.8 MB  00:00:00

Loading mirror speeds from cached hostfile

Package yum-utils-1.1.31-40.el7.noarch alreadyinstalled and latest version

Nothing to do

1.2.3.2          第二步:设置远程仓库

$sudo yum-config-manager --add-repohttps://download.docker.com/linux/centos/docker-ce.repo

执行结果:

Loaded plugins: fastestmirror, langpacks

adding repo from:https://download.docker.com/linux/centos/docker-ce.repo

grabbing filehttps://download.docker.com/linux/centos/docker-ce.repo to/etc/yum.repos.d/docker-ce.repo

repo saved to /etc/yum.repos.d/docker-ce.repo

1.2.3.3          第三步:安装

$ sudo yum install docker-ce

执行结果:

1.2.3.4          第四步:启动

$ sudo systemctl start docker

或者

$ sudo service docker start

service docker start        #启动docker

chkconfig docker on         #加入开机启动

1.2.3.5          第五步:查看版本

$ sudo docker version

执行结果:

Client:

 Version:      17.03.1-ce

 APIversion:  1.27

 Goversion:   go1.7.5

 Gitcommit:   c6d412e

 Built:        Mon Mar 27 17:05:44 2017

 OS/Arch:      linux/amd64

1.2.3.6          第六步:校验

$ sudo docker run hello-world

执行结果:

Unable to find image 'hello-world:latest' locally

latest: Pulling from library/hello-world

78445dd45222: Pull complete

Digest:sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7

Status: Downloaded newer image for hello-world:latest

 

Hello from Docker!

This message shows that your installation appears tobe working correctly.

 

To generate this message, Docker took the followingsteps:

 1. The Dockerclient contacted the Docker daemon.

 2. The Dockerdaemon pulled the "hello-world" image from the Docker Hub.

 3. The Dockerdaemon created a new container from that image which runs the

    executablethat produces the output you are currently reading.

 4. The Dockerdaemon streamed that output to the Docker client, which sent it

    to yourterminal.

 

To try something more ambitious, you can run anUbuntu container with:

 $ docker run-it ubuntu bash

 

Share images, automate workflows, and more with afree Docker ID:

 https://cloud.docker.com/

 

For more examples and ideas, visit:

 https://docs.docker.com/engine/userguide/

1.2.4  查看Docker版本

docker --help                                     #帮助

docker –v                                                     #简单查看版本

docker version                                            #查看版本

Client version: 1.7.1

Client API version: 1.19

Go version (client): go1.4.2

Git commit (client): 786b29d/1.7.1

OS/Arch (client): linux/amd64

Server version: 1.7.1

Server API version: 1.19

Go version (server): go1.4.2

Git commit (server): 786b29d/1.7.1

OS/Arch (server): linux/amd64

docker info                                         #查看信息

Containers: 0

Images: 2

Storage Driver: devicemapper

 Pool Name:docker-253:0-34097258-pool

 PoolBlocksize: 65.54 kB

 BackingFilesystem: xfs

 Data file:/dev/loop0

 Metadatafile: /dev/loop1

 Data SpaceUsed: 308.3 MB

 Data SpaceTotal: 107.4 GB

 Data SpaceAvailable: 16.08 GB

 MetadataSpace Used: 782.3 kB

 MetadataSpace Total: 2.147 GB

 MetadataSpace Available: 2.147 GB

 Udev SyncSupported: true

 DeferredRemoval Enabled: false

 Data loopfile: /var/lib/docker/devicemapper/devicemapper/data

 Metadataloop file: /var/lib/docker/devicemapper/devicemapper/metadata

 LibraryVersion: 1.02.107-RHEL7 (2015-10-14)

Execution Driver: native-0.2

Logging Driver: json-file

Kernel Version: 3.10.0-327.el7.x86_64

Operating System: CentOS Linux 7 (Core)

CPUs: 4

Total Memory: 985.6 MiB

Name: localhost.localdomain

ID:B5ZW:FJXF:FNUD:OLH7:FCNI:56DJ:XEQY:I6J4:PPHQ:OKRW:CIJK:Y26P

1.2.5  安装其它产品的两种方式

docker安装其它产品有两种方式

方式一:通过拉取事先做好的镜像,例如下面redis的安装方式

方式二:通过Dockerfile来构建新的镜像,例如下面tomcat的安装方式

1.2.6  组成结构

docker会自动给docker容器配置一个vip虚拟ip地址

bash-4.1#提示符就代表进入docker容器内部

1.3    Redis

1.3.1  拉取Redis镜像

docker search redis      #镜像库提供的多个镜像

docker pull redis        #拉取最后版本的docker-redis镜像

docker pull redis:3.2.8  #拉取指定版本的redis镜像

注意:拉取速度会很慢,因为docker中央仓库在国外,中国虽然有镜像仓库,如阿里、网易蜂巢等,但速度也不理想。好在,docker文件可以反复拉取,拉取失败,重新拉取即可。

拉取完成提示:

Digest:sha256:f4751caa521d05db548a3190fb87f92cd7cc2f1612b7ef8b84218864d2c45577

Status: Downloaded newer image for redis:latest

1.3.2  查看镜像

dockerimages            #查看已经拉取的镜像

执行结果:

REPOSITORYTAG       IMAGE ID     CREATED          VIRTUAL SIZE

redis       latest8f41ae49db402 weeks ago      183.6 MB

1.3.3  启动第一个Redis实例

启动redis实例,映射程序访问端口为7000,实例名称为redis7000

docker run -d --name redis7000 -p 7000:6379 redis

参数说明:

-d,则containter将会运行在后台模式(Detachedmode)

--name 实例名称

-p 对外程序访问端口7000,宿主机映射的redis端口6379

最后的redis为镜像的名称

1.3.4  单个节点测试

    @Test  //完成单实例链接

    publicvoid jedis(){

       Jedisjedis = new Jedis("192.168.163.30", 7000);

       //jedis.auth("123456");

       jedis.set("name","tony");  //调用redis命令set

       Strings = jedis.get("name");

       System.out.println(s);

       jedis.close();

    }

1.3.5  启动Redis实例

docker run -d --name redis7001 -p 7001:6379 redis

docker run -d --name redis7002 -p 7002:6379 redis

1.3.6  查看docker的实例

docker ps                          #查看当前运行的dockerid

docker ps -a                       #查看已有的可能状态是停止

docker start b193fbe1e400              #开启实例,如重启可能实例被关闭

docker stop b193fbe1e400           #停止实例

docker rm –f 0cfc4932b9a0              #删除运行的docker,-f强制删除

docker rmi xcfc4932b9a0             #删除镜像

查看结果:

CONTAINER ID       IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES

6567870ec0ae       redis              "docker-entrypoint.s   17minutes ago      Up 16 minutes       0.0.0.0:7002->6379/tcp   redis7002          

a071867d6233       redis              "docker-entrypoint.s   18minutes ago      Up 18 minutes       0.0.0.0:7001->6379/tcp   redis7001          

c3ce36dc147c       redis              "docker-entrypoint.s   19minutes ago      Up 19 minutes       0.0.0.0:7000->6379/tcp   redis7000

1.3.7  端口的映射关系

1.3.8  关闭防火墙

systemctl stop firewalld.service       #关闭防火墙服务

disable firewalld.service              #禁止防火墙开启启动

systemctl restart iptables.service #重启防火墙使配置生效

systemctl enable iptables.service #设置防火墙开机启动

systemctl restart docker           #重启docker服务

1.3.9  进入docker内部

docker exec -it 0cfc4932b9a0 bash  #进入docker内部,-it输入输出,展示信息在控制台

root@a071867d6233:/data# ps -ef |grep redis

redis       1     0  1 08:45 ?        00:00:08 redis-server *:6379

root       26    20  0 08:58 ?        00:00:00 grep redis

redis-cli                          #根据最后映射的端口执行redis命令

exit                               #退出docker中的redis环境

1.3.10 Shard分片测试类

package jedis;

 

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import org.junit.Test;

 

import redis.clients.jedis.HostAndPort;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.JedisSentinelPool;

import redis.clients.jedis.JedisShardInfo;

import redis.clients.jedis.ShardedJedis;

import redis.clients.jedis.ShardedJedisPool;

 

public class TestJedis {

    @Test  //分片

    publicvoid shard(){

      

      

       //构造各个节点链接信息,host和port

       List<JedisShardInfo>infoList = new ArrayList<JedisShardInfo>();

       JedisShardInfoinfo1 = new JedisShardInfo("192.168.163.200",6379);

       //info1.setPassword("123456");

       infoList.add(info1);

       JedisShardInfoinfo2 = new JedisShardInfo("192.168.163.200",6380);

       infoList.add(info2);

       JedisShardInfoinfo3 = new JedisShardInfo("192.168.163.200",6381);

       infoList.add(info3);

      

       //分片jedis

       JedisPoolConfigconfig = new JedisPoolConfig();

       config.setMaxTotal(500); //最大链接数

      

       ShardedJedisPoolpool = new ShardedJedisPool(config, infoList);

       //ShardedJedisjedis = new ShardedJedis(infoList);

       ShardedJedisjedis = pool.getResource();  //从pool中获取

       for(inti=0;i<10;i++){

           jedis.set("n"+i,"t"+i);

       }

       System.out.println(jedis.get("n9"));

       jedis.close();

    }

}

1.4    Dockerfile

Dockerfile通过逐层layer叠加,使资源得到重复利用,同时变化无穷。

注意:FROM指定的镜像,本地如果有直接使用,无需网上下载。

1.4.1  关键字及含义

序号

关键字

说明

1.    

FROM

指定基础镜像的来源

2.    

MAINTAINER

作者

3.    

ADD

复制文件,会自动解压

4.    

WORKDIR

设置当前工作目录 cd

5.    

VOLUME

设置数据卷,挂载主机目录

6.    

EXPOSE

指定对外暴漏的端口

7.    

RUN

执行命令 sh

8.    

CMD

执行命令 exec,一个Dockerfile只能一个

9.    

COPY

复制文件

10.  

ENTRYPOINT

docker run时参数可以覆盖,指定参数值

1.5    基础镜像centos

1.5.1  centos

mkdir /usr/local/src/docker            #创建目录

1.5.2  配置Dockerfile

FROM index.alauda.cn/tutum/centos:6.5

FROM registry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

1.5.3  创建镜像build

docker build -t jt-centos6:0.0.1 .

参数-t标识TAG名称,注意最后有一个.代表当前路径

执行结果:

Sending build context to Docker daemon

Step 0 : FROMregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

0.0.1: Pulling fromregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos

3690474eb5b4: Pull complete

0a444b299d5a: Pull complete

a04895de1996: Pull complete

d4350798c2ee: Already exists

Digest:sha256:6573e33c14607402068620507e450b65f637023f43fd1223269447c9532da292

Status: Downloaded newer image forregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

 --->d4350798c2ee

Successfully built d4350798c2ee

1.5.4  重命名镜像

小技巧:只写FROM相当于对现有镜像重命名

docker build -t jt-centos6:0.0.1 .

1.5.5  查看镜像images

docker images

执行结果:

REPOSITORY                                          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

registry.cn-hangzhou.aliyuncs.com/repos_zyl/centos   0.0.1               d4350798c2ee        5 months ago        191.8 MB

jt-centos6                                          0.0.1               d4350798c2ee        5 months ago        191.8 MB

1.5.6  删除镜像rmi

docker rmiregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

1.5.7  导出镜像save

docker save -o jt-centos6.tar jt-centos6:0.0.1       #按镜像名称导出

docker save 9610cfc68e8d > jt-centos6.tar        #按镜像id导出,但导入时没名称

1.5.8  导入镜像load

docker load -i jt-centos6.tar

1.6    JDK

1.6.1  jdk

mkdir /usr/local/src/docker            #创建目录

jdk-7u51-linux-x64.tar.gz                 #上传jdk文件

1.6.2  配置Dockerfile

FROM index.alauda.cn/tutum/centos:6.5

或者

FROM registry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

 

# install jdk1.7

ADD jdk-7u51-linux-x64.tar.gz /usr/local/src

ENV JAVA_HOME=/usr/local/src/jdk1.7.0_51

ENV PATH=$JAVA_HOME/bin:$PATH

ENVCLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

1.6.3  制作镜像

docker build --no-cache -t jt-jdk:0.0.1 .   #-t添加tag .代表当前路径

创建日志

[root@localhost docker]# docker build -tjt-jdk:0.0.2 .

Sending build context to Docker daemon 138.2 MB

Sending build context to Docker daemon

Step 0 : FROMregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

0.0.1: Pulling fromregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos

3690474eb5b4: Pull complete

0a444b299d5a: Pull complete

a04895de1996: Pull complete

d4350798c2ee: Already exists

Digest:sha256:6573e33c14607402068620507e450b65f637023f43fd1223269447c9532da292

Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

 --->d4350798c2ee

Step 1 : ADD jdk-7u51-linux-x64.tar.gz/usr/local/src

 --->f7e506cbd4b5

Removing intermediate container c25330765fe5

Step 2 : ENV JAVA_HOME /usr/local/src/jdk1.7.0_51

 --->Running in e1c9a1a018fb

 --->312f6aeadb84

Removing intermediate container e1c9a1a018fb

Step 3 : ENV PATH $JAVA_HOME/bin:$PATH

 --->Running in 194844ddd65d

 --->2e6b9a3557a7

Removing intermediate container 194844ddd65d

Step 4 : ENV CLASSPATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

 --->Running in 4979a414305a

 --->e0dade7b259b

Removing intermediate container 4979a414305a

Successfully built e0dade7b259b

[root@localhost docker]#

1.6.4  运行镜像

docker run -d jt-jdk:0.0.1

1.6.5  进入容器,检查jdk是否安装成功

[root@localhost ~]# docker exec -i -t 8fd3e511b3a4bash

bash-4.1# java -version                                                                                                       

java version "1.7.0_51"

Java(TM) SE Runtime Environment (build1.7.0_51-b13)

Java HotSpot(TM) 64-Bit Server VM (build24.51-b03, mixed mode)

bash-4.1#

1.6.6  退出容器,但是容器不关闭

[root@docker jdk]# docker exec -i -t 0905440611ccbash

bash-4.1# java -version                                                                                                                                             

java version "1.7.0_51"

Java(TM) SE Runtime Environment (build1.7.0_51-b13)

Java HotSpot(TM) 64-Bit Server VM (build24.51-b03, mixed mode)

bash-4.1# exit                           #退出容器,但是容器不关闭

1.7    Tomcat

1.7.1  准备文件

mkdir /usr/local/src/docker            #创建目录

jdk-7u51-linux-x64.tar.gz                 #上传jdk文件

apache-tomcat-7.0.55.tar.gz            #上传tomcat文件

1.7.2  配置Dockerfile

FROMregistry.cn-hangzhou.aliyuncs.com/repos_zyl/centos:0.0.1

 

# install jdk1.7

ADD jdk-7u51-linux-x64.tar.gz /usr/local/src  #ADD复制文件并解压

ENV JAVA_HOME=/usr/local/src/jdk1.7.0_51         #ENV配置环境

ENV PATH=$JAVA_HOME/bin:$PATH

ENVCLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

 

# install tomcat7

ADD apache-tomcat-7.0.55.tar.gz /usr/local/src

ENV CATALINA_HOME/usr/local/src/apache-tomcat-7.0.55

ENV PATH=$PATH:$CATALINA_HOME/bin

 

EXPOSE 8080                                   #对外访问的端口

                                              #执行命令

CMD["/usr/local/src/apache-tomcat-7.0.55/bin/catalina.sh","run"]

1.7.3  制作镜像

docker build -t jt-tomcat:0.0.1 .

docker images

1.7.4  运行

docker run -d -p 8001:8080 --name jt-tomcatjt-tomcat:0.0.1

cc6c7460029232f787d195df5648e85dec0e7b2e7bbf6bb86ccc53898fc47764

[root@localhost docker]# docker ps

CONTAINER ID       IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES

cc6c74600292       jt-tomcat:0.0.1    "/usr/local/src/apac   12seconds ago      Up 9 seconds        0.0.0.0:8001->8080/tcp   jt-tomcat          

[root@localhost docker]#

1.7.5  打开端口

iptables -A INPUT -p tcp --dport 8001 -j ACCEPT

1.7.6  测试

http://192.168.163.8:8001/

展示tomcat页面就表示成功了

1.8    MySQL============

1.9    部署war包

1.9.1  准备文件

上传war,修改好jdbc.properties文件

1.9.2  配置Dockerfile

FROM jt-centos6:0.0.1

 

#install jdk1.7

ADD jdk-7u51-linux-x64.tar.gz /usr/local/src

ENV JAVA_HOME=/usr/local/src/jdk1.7.0_51

ENV PATH=$JAVA_HOME/bin:$PATH

ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

 

#install tomcat7

ADD apache-tomcat-7.0.55.tar.gz /usr/local/src

ENV CATALINA_HOME/usr/local/src/apache-tomcat-7.0.55

ENV PATH=$PATH:$CATALINA_HOME/bin

RUN rm -rf $CATALINA_HOME/webapps/*

 

#deploy the war

COPY ROOT.war $CATALINA_HOME/webapps/ROOT/ROOT.war

WORKDIR $CATALINA_HOME/webapps/ROOT

RUN jar xvf ROOT.war

RUN rm -rf ROOT.war

 

EXPOSE 8080

 

CMD["/usr/local/src/apache-tomcat-7.0.55/bin/catalina.sh","run"]

1.9.3  制作镜像

docker build -t jt-manage-war:0.0.1 .

docker images

执行日志:

Sending build context to Docker daemon

Step 0 : FROM jt-centos6:0.0.1

 --->d4350798c2ee

Step 1 : ADD jdk-7u51-linux-x64.tar.gz/usr/local/src

 --->Using cache

 --->9a792e3fab6f

Step 2 : ENV JAVA_HOME /usr/local/src/jdk1.7.0_51

 --->Using cache

 --->79571eb304c3

Step 3 : ENV PATH $JAVA_HOME/bin:$PATH

 --->Using cache

 --->35dff4e4df85

Step 4 : ENV CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

 --->Using cache

 --->f3e681348b2f

Step 5 : ADD apache-tomcat-7.0.55.tar.gz/usr/local/src

 --->Using cache

 --->262f103f08af

Step 6 : ENV CATALINA_HOME/usr/local/src/apache-tomcat-7.0.55

 --->Using cache

 --->aecd8888daff

Step 7 : ENV PATH $PATH:$CATALINA_HOME/bin

 --->Using cache

 --->eff7fa41fea2

Step 8 : RUN rm -rf $CATALINA_HOME/webapps/*

 --->Using cache

 --->22bc88155a21

Step 9 : COPY ROOT.war$CATALINA_HOME/webapps/ROOT/ROOT.war

 

 inflated:WEB-INF/views/login.jsp

 inflated:WEB-INF/web.xml

  created:META-INF/maven/

  created:META-INF/maven/com.jt/

  created:META-INF/maven/com.jt/jt-manage-web/

 inflated:META-INF/maven/com.jt/jt-manage-web/pom.xml

 inflated:META-INF/maven/com.jt/jt-manage-web/pom.properties

 --->7f09fcdeb256

Removing intermediate container 0037f2032ef2

Step 12 : RUN rm -rf ROOT.war

 --->Running in 333872bb469c

 --->40d0fcfc3717

Removing intermediate container 333872bb469c

Step 13 : EXPOSE 8080

 --->Running in c702f140c7bf

 --->c36982676589

Removing intermediate container c702f140c7bf

Step 14 : CMD /usr/local/src/apache-tomcat-7.0.55/bin/catalina.shrun

 --->Running in 8f2f5e3a9f2c

 --->bc2cc8c59ee0

Removing intermediate container 8f2f5e3a9f2c

Successfully built bc2cc8c59ee0

[root@localhost docker]#

1.9.4  运行

docker run -d -p 8001:8080 --name jt-tomcatjt-tomcat:0.0.1

cc6c7460029232f787d195df5648e85dec0e7b2e7bbf6bb86ccc53898fc47764

[root@localhost docker]# docker ps

CONTAINER ID       IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES

cc6c74600292       jt-tomcat:0.0.1     "/usr/local/src/apac   12 seconds ago      Up 9 seconds        0.0.0.0:8001->8080/tcp   jt-tomcat          

[root@localhost docker]#

1.9.5  打开端口

iptables -A INPUT -p tcp --dport 8001 -j ACCEPT      #打开8001端口

systemctl stop firewalld                         #关闭防火墙

1.9.6  测试

http://192.168.163.8:8001/

1.9.7  查看tomcat日志

docker logs -f -t --tail="10"892718f559d0

参数说明:

l  -f 跟踪容器日志的最近更新

l  -t 显示容器日志的时间戳

l  --tail="10" 仅列出最新10条容器日志

1.9.8  出错后重建

docker stop d58ab377493b    #运行中的实例不能直接删除,先停止运行的实例

docker rm d58ab377493b      #再删除实例

docker build -t jt-manage-war:0.0.2 .                   #制作镜像

docker run -d -p 8001:8080 --name jt8001jt-tomcat:0.0.2    #运行

1.10 docker-compose实现ZK集群

compose是用来在Docker中定义和运行复杂应用的小工具,比如在一个文件中定义多个容器,只用一行命令就可以让一切就绪并运行。fig是compose的前身。

1.10.1 YML文件

docker-compose批量执行的内容放在YML格式文件中配置。

YML文件格式是YAML (YAML AintMarkup Language)编写的文件格式,YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。

1.10.2 安装配置

上传文件docker-compose-Linux-x86_64到/usr/local/bin目录下

mv docker-compose-Linux-x86_64docker-compose  #修改名称

chmod +x /usr/local/bin/docker-compose        #设置文件访问权限

docker-compose -version                       #查看版本

docker-compose up -d                          #后台模式被启动

1.10.3 编写docker-compose.yml

配置zk的yml文件,默认找docker-compose.yml,分为两个版本1和2。 image:zookeeper为基础镜像,如果没有下载会自动下载。也可以单独的拉取。docker pull zookeeer。

version: '2'

services:

    dzk1:

       image: zookeeper

       restart: always

       container_name: dzk1

       ports:

           - "2181:2181"

       environment:

           ZOO_MY_ID: 1

           ZOO_SERVERS: server.1=dzk1:2888:3888 server.2=dzk2:2888:3888server.3=dzk3:2888:3888

 

    dzk2:

       image: zookeeper

       restart: always

       container_name: dzk2

       ports:

           - "2182:2181"

       environment:

           ZOO_MY_ID: 2

           ZOO_SERVERS: server.1=dzk1:2888:3888 server.2=dzk2:2888:3888server.3=dzk3:2888:3888

 

    dzk3:

       image: zookeeper

       restart: always

       container_name: dzk3

       ports:

           - "2183:2181"

       environment:

            ZOO_MY_ID: 3

           ZOO_SERVERS: server.1=dzk1:2888:3888 server.2=dzk2:2888:3888server.3=dzk3:2888:3888

1.10.4 启动

COMPOSE_PROJECT_NAME=myzk docker-compose up –d   #设置环境变量

执行结果:

Creating network "myzk_default" with the default driver

Creating dzk3 ...

Creating dzk2 ...

Creating dzk1 ...

Creating dzk3

Creating dzk2

Creating dzk1 ... done

注意:成功后会自动匹配一个网络连接myzk_default

1.10.5 查看

COMPOSE_PROJECT_NAME=myzk docker-compose ps          #查看版本

COMPOSE_PROJECT_NAME=myzk docker-compose stop    #先停止

COMPOSE_PROJECT_NAME=myzk docker-compose rm          #后删除

执行结果:

Name             Command               State                     Ports                   

------------------------------------------------------------------------------------------

dzk1  /docker-entrypoint.sh zkSe ...  Up      0.0.0.0:2181->2181/tcp,2888/tcp, 3888/tcp

dzk2  /docker-entrypoint.sh zkSe ...  Up      0.0.0.0:2182->2181/tcp,2888/tcp, 3888/tcp

dzk3  /docker-entrypoint.sh zkSe ...  Up      0.0.0.0:2183->2181/tcp,2888/tcp, 3888/tcp

1.10.6 运行

docker run -it --rm \

       --link z1:dzk1 \

       --link z2:dzk2 \

       --link z3:dzk3 \

       --net myzk_default \

       zookeeper zkCli.sh -server dzk1:2181,dzk2:2181,dzk3:2181

 

检查zk是否正常

上面就批处理实现了同时启动3个docker容器

docker ps                                     #查看容器

docker exec -it 30389ad3865f  bash            #进入容器

cd bin                                        #进入目录

ls                                            #看看内容

./zkServer.sh status                          #查看zk节点的状态

exit                                          #退出

cd bin

./zkCli.sh -server localhost:2181             #客户端连接

 

[zk: localhost:2181(CONNECTED) 0] ls /        #查看根目录

[zookeeper, myapp]

[zk: localhost:2181(CONNECTED) 1] create /jtjt-web  #创建节点

Created /jt

[zk: localhost:2181(CONNECTED) 2] ls /jt         #查看节点

[]

[zk: localhost:2181(CONNECTED) 3] ls /        #查看根目录

[jt, zookeeper, myapp]

 

[zk: localhost:2181(CONNECTED) 4] get /jt     #获取新节点内容

jt-web

cZxid = 0x200000002

ctime = Fri May 26 09:15:11 GMT 2017

mZxid = 0x200000002

mtime = Fri May 26 09:15:11 GMT 2017

pZxid = 0x200000002

cversion = 0

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 6

numChildren = 0

 

[zk: localhost:2181(CONNECTED) 5] set /jtjt-manage  #修改信息

cZxid = 0x200000002

ctime = Fri May 26 09:15:11 GMT 2017

mZxid = 0x200000003

mtime = Fri May 26 09:15:52 GMT 2017

pZxid = 0x200000002

cversion = 0

dataVersion = 1

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 9

numChildren = 0

 

[zk: localhost:2181(CONNECTED) 6] get /jt        #获取信息

jt-manage

cZxid = 0x200000002

ctime = Fri May 26 09:15:11 GMT 2017

mZxid = 0x200000003

mtime = Fri May 26 09:15:52 GMT 2017

pZxid = 0x200000002

cversion = 0

dataVersion = 1

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 9

numChildren = 0

 

[zk: localhost:2181(CONNECTED) 7] delete /jt     #删除节点

[zk: localhost:2181(CONNECTED) 8] ls /

[zookeeper, myapp]

 

Ctrl+C                                           #退出

1.10.7 测试

1.10.7.1     命令行

ls 查看指定节点中包含的子节点(如:ls / 或 ls/app1/server1)

create 创建节点并赋值

get 读取节点内容

set 改变节点内容

delete 删除节点

1.10.7.2     Maven依赖

       <dependency>

           <groupId>com.github.sgroschupf</groupId>

           <artifactId>zkclient</artifactId>

           <version>0.1</version>

       </dependency>

或者

       <dependency>

<groupId>com.101tec</groupId>

<artifactId>zkclient</artifactId>

<version>0.7</version>

</dependency>

1.10.7.3     测试类

package zk;

import java.util.List;

import java.util.concurrent.TimeUnit;

 

import org.I0Itec.zkclient.DataUpdater;

import org.I0Itec.zkclient.IZkChildListener;

import org.I0Itec.zkclient.IZkDataListener;

import org.I0Itec.zkclient.IZkStateListener;

import org.I0Itec.zkclient.ZkClient;

importorg.apache.zookeeper.Watcher.Event.KeeperState;

 

/**

 * ZkClient的使用测试

 */

public class ZkClientTest {

 

    publicstatic void main(String[] args) {

       ZkClient zkClient = newZkClient("192.168.163.135:2181,192.168.163.135:2182,192.168.163.135:2183");

       String node = "/jt";

 

        // 订阅监听事件

       childChangesListener(zkClient, node);

       dataChangesListener(zkClient, node);

        stateChangesListener(zkClient);

 

        if(!zkClient.exists(node)) {

    //创建节点

           zkClient.createPersistent(node, "jt zk");

        }

       System.out.println(zkClient.readData(node));

 

       zkClient.updateDataSerialized(node, new DataUpdater<String>() {

    //修改信息

           public String update(String currentData) {

               return currentData + "-new";

           }

        });

       System.out.println(zkClient.readData(node));

 

        try{

           TimeUnit.SECONDS.sleep(3);

        }catch (InterruptedException e) {

           e.printStackTrace();

        }

    }

 

    /**

     * 订阅children变化

     */

    publicstatic void childChangesListener(ZkClient zkClient, final String path) {

       zkClient.subscribeChildChanges(path, new IZkChildListener() {

 

           public void handleChildChange(String parentPath, List<String>currentChilds) throws Exception {

               System.out.println("clildren of path " + parentPath +":" + currentChilds);

           }

 

        });

    }

 

    /**

     * 订阅节点数据变化

     */

    publicstatic void dataChangesListener(ZkClient zkClient, final String path){

       zkClient.subscribeDataChanges(path, new IZkDataListener(){

 

           public void handleDataChange(String dataPath, Object data) throwsException {

               System.out.println("Data of " + dataPath + " haschanged.");

           }

 

           public void handleDataDeleted(String dataPath) throws Exception {

               System.out.println("Data of " + dataPath + " haschanged.");

           }

 

        });

    }

 

    /**

     * 订阅状态变化

     */

    publicstatic void stateChangesListener(ZkClient zkClient){

       zkClient.subscribeStateChanges(new IZkStateListener() {

 

           public void handleStateChanged(KeeperState state) throws Exception {

               System.out.println("handleStateChanged");

           }

 

           public void handleSessionEstablishmentError(Throwable error) throwsException {

               System.out.println("handleSessionEstablishmentError");

           }

 

           public void handleNewSession() throws Exception {

               System.out.println("handleNewSession");

           }

        });

    }

}

1.11 x最简私服Registry

安装必要的软件

$ sudo apt-get install build-essential python-dev libevent-devpython-pip liblzma-dev

配置 docker-registry

sudo pip install docker-registry

或者使用 github clone 手动安装

 

$ git clone https://github.com/dotcloud/docker-registry.git

$ cd docker-registry/

$ cp config/config_sample.yml config/config.yml

$ mkdir /data/registry -p

$ pip install .

运行

docker-registry

高级启动方式 [不推荐]

使用gunicorn控制:

 

gunicorn -c contrib/gunicorn_config.py docker_registry.wsgi:application

或者对外监听开放

 

gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000-w 4 --max-requests 100 docker_registry.wsgi:application

10.3 提交指定容器到私有库

$ docker tag ubuntu:12.04 私有库IP:5000/ubuntu:12.04

$ docker push 私有库IP:5000/ubuntu

更多的配置选项推荐阅读官方文档:

 

Docker-Registry README

Docker-Registry advanced use

和Mavan的管理一样,Dockers不仅提供了一个中央仓库,同时也允许我们使用registry搭建本地私有仓库。使用私有仓库有许多优点:

l  节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;

l  提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。

1.11.1 拉取私服镜像

[root@localhost docker]# docker pull registry

执行结果:

latest: Pulling from registry

 

1486fe9a5f49: Already exists

afb46c69edc0: Already exists

31e1a4cc7f43: Already exists

4d027e0583ff: Already exists

b62848d85f39: Already exists

f187d1ddc533: Already exists

67439767c005: Already exists

155885d4df5f: Already exists

98959b7d32cc: Already exists

Digest:sha256:1fd7f060074f8279ad001d5b24b612167a89c5eab42998eac7490d7b4ab3418a

Status: Image is up to date for registry:latest

[root@localhost docker]# docker images

REPOSITORY         TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

registry           latest             bb682e0824bd        6 daysago          33.17 MB

[root@localhost docker]#

1.11.2 启动容器

docker run -d -p 5000:5000 -v/opt/data/registry:/var/lib/registry --restart=always registry

执行结果:

17d73ca512b738d48c75ca2a879354a4f11f00c701da81c3721cc373bb571223

[root@localhost docker]# docker ps

CONTAINER ID       IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES

17d73ca512b7       registry           "/entrypoint.sh /etc   12seconds ago      Up 10 seconds       0.0.0.0:5000->5000/tcp   loving_poitras

1.12 常见错误

1.12.1 docker Tag latest not found inrepository redis

docker Image for redis

docker pull redis

有时下载不完断掉,再次执行即可。如果仍然上面提示,让使用docker –d查看,直接reboot重启linux,然后重新执行。

1.12.2 Build a new image from thesource code at PATH

 [root@bogon docker]# docker build -tjt-jdk:0.0.1

docker: "build" requires 1argument.

See 'docker build --help'.

 

Usage: docker build [OPTIONS] PATH | URL |-

 

Build a new image from the source code atPATH

执行命令少了最后的路径,加个.代表当前路径

docker build -t jt-jdk:0.0.1 .

1.12.3 docker-compose: 权限不够

/usr/local/bin/docker-compose: 权限不够

[root@localhost bin]# chmod +x/usr/local/bin/docker-compose


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值