Simpleblog博客系统(一)---DaoCloud持续集成

DaoCloud持续集成

DaoCloud提供了非常棒的CI系统,配合github完美持续集成应用部署.

操作步骤

  • 创建项目
    01创建项目
  • 02创建项目
    02创建项目
  • 03初始界面
    03初始界面
  • 04流程
    04流程
  • 05安全构建
    05安全构建
  • 06构建准备
    06构建准备
  • 安全构建
    安全构建
  • 08手动触发
    08手动触发
  • 09master分支触发
    09master分支触发
  • 10查看日志
    10查看日志
  • 11执行成功
    11执行成功
  • 12应用-创建应用
    12应用-创建应用
  • 13部署最新版本
    13部署最新版本
  • 14基本信息
    14基本信息
  • 15应用设置
    15应用设置
  • 16启动应用
    16启动应用

欢迎大家关注😁

Docker教程(八)---构建Kafka镜像

Kafka

该容器的前提依赖是使用我的JDK的镜像的依赖,后面我会把镜像同步到线上.

构建镜像

下载好Dockerfile文件执行

docker build -t="lujiahao/kafkatest" .

启动容器

docker run --name test_kafka -it -p 2181:2181 -p 9092:9092 lujiahao/kafkatest /bin/bash

额外配置

容器中使用kafka还需要将容器的内部IP配置到config/server.properties

docker inspcet test_kafka查看容器的内部IP

然后更改config目录中的server.properties中的三个配置

#容器的ip地址
host.name=172.17.0.1
#容器的ip地址
listeners=PLAINTEXT://172.17.0.1:9092
#宿主机的IP地址,用于外部Producer和Consumer使用(公司服务器你懂得)
advertised.listeners=PLAINTEXT://xx.xx.xx.xx:9092

启动Kafka

./kafkastart.sh

错误总结

1.无法分配内存

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c0000000, 1073741824, 0) failed;
error='Cannot allocate memory' (errno=12)

解决方案

vi zookeeper-server-start.sh 
    将 export KAFKA_HEAP_OPTS="-Xmx512M -Xms512M"
    改成 export KAFKA_HEAP_OPTS="-Xmx512M -Xms128M"
vi kafka-server-start.sh 
    将 export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
    改成 export KAFKA_HEAP_OPTS="-Xmx512M -Xms128M"
把这两个值改成相同的就行了

参考资料

2.无法发送消息

Error when sending message to topic TESTTOPIC with key: null, value: 9 bytes with error: 
Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)

解决方案

在 server.properties 中添加 advertised.listeners=PLAINTEXT://xx.xx.xx.xx:9092 ,对应的IP为宿主机的IP

参考资料

Kafka的基本操作

  1. 创建topic

    kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
  2. 查看topic

    kafka-topics.sh --list --zookeeper localhost:2181
  3. 生产者

    kafka-console-producer.sh --broker-list localhost:9092 --topic test
  4. 消费者

    kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning

Docker教程(七)---构建Tomcat镜像

这次镜像构建是基于上篇的JDK镜像构建的.

Dockerfile

FROM lujiahao/jdk1.7
MAINTAINER lujiahao
ADD apache-tomcat-7.0.75.tar.gz /usr/local/
RUN mv /usr/local/apache-tomcat-7.0.75 /usr/local/tomcat7
WORKDIR /usr/local/tomcat7/bin
EXPOSE 8080

构建命令

docker build -t="lujiahao/tomcat7" .

启动容器测试

docker run --name tomcat7 -p 8080:8080 -d lujiahao/tomcat7 ./catalina.sh run

注意:在运行装有tomcat的容器的时候使用catalina.sh run (调试模式,在前台运行)来启动,如果使用startup.sh 的话会在后台运行,容器会认为进程down掉,容器也会自动停止。

然后在浏览器中查看能否访问tomcat主页

Docker教程(六)---构建JDK镜像

1.创建文件夹jdk

因为会把当前构建目录中的内容添加到镜像里面  所以要单独创建一个文件夹

2.编写Dockerfile文件

FROM centos
MAINTAINER lujiahao
ADD jdk-7u80-linux-x64.tar.gz /usr/local
RUN mv /usr/local/jdk1.7.0_80 /usr/local/jdk1.7
ENV JAVA_HOME /usr/local/jdk1.7
ENV JRE_HOME /usr/local/jdk1.7/jre
ENV CLASSPATH .:$JAVA_HOME/jre/lib/rt.jar  :$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $JAVA_HOME/bin:$PATH

3.构建镜像

docker build -t="lujiahao/jdk1.7" .

4.构建完成之后启动一个临时性容器来测试

docker run --rm -it lujiahao/jdk1.7 /bin/bash

在运行java和javac看看,java -version看版本

相关资源

可以到 DockerfileCollection 中寻找对应的 Dockerfile 文件

Docker教程(五)---Azure虚拟安装Docker

老大把Azure的权限给我了,哈哈,可惜我已经准备离职了,但是工作还是要继续的.

一切进行的非常顺利,登录Azure云平台,创建虚机,然后切换root权限安装docker,退出root用户,准备docker pull centos…
无法运行,卧槽!

运行docker命令弹出如下提示:

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

docker出于安全的考虑才会这样做(http://dockone.io/article/589).

解决方案

  1. 切换root权限

    visudo -f /etc/sudoers
  2. /etc/sudoers 中添加如下内容

    azureuser  ALL=(ALL)       NOPASSWD: /usr/bin/docker
  3. 退出root用户

  4. 执行 vim ~/.bashrc 添加

    alias docker='sudo /usr/bin/docker'
  5. 保存后执行

    source ~/.bashrc

此时就可以自由的使用docker命令了.

Docker教程(四)---Dockerfile命令详解

深入docker镜像

拉取镜像文件到本地

docker pull centos

查看本地镜像:

docker images 

查找镜像

docker search [镜像名称]

构建镜像

1. 使用docker commit 命令      用户名:lujiahao
    docker commit 容器名称/ID lujiahao/centos-tomcat
    docker commit -m="describe" --author="lujiahao" 容器名称/ID  lujiahao/centos-tomcat:test
    docker inspect lujiahao/centos-tomcat:test
2. 使用docker build命令和Dockerfile文件(推荐)
    docker build  -t=“用户名/镜像名称" .
    docker build  -t="crxy/centos" .
    点表示会在当前目录中找Dockerfile文件
    建议创建镜像的时候单独一个目录,然后在写Dockerfile,这个目录叫构建目录.如果目录下面有其他文件,会把目录下所有文件发送给docker的守护进程

查看构建的步骤和层级

docker history 用户ID/镜像名

执行流程

  • dockerfile中的指令会按照从上到下执行
  • docker首先从基础镜像运行一个容器
  • 执行一条指令,对容器进行修改
  • 执行类似docker commit的操作,提交一个新的镜像层
  • docker再基于刚提交的镜像运行一个新容器
  • 然后执行dockerfile中的下一条指令,直到所有指令都执行完毕

Dockerfile指令详解

  • 所有指令都必须为大写字母
  • 以#开头的都认为是注释

FROM

第一条指令必须是`FROM`(指定使用的基础镜像)

MAINTAINER

指定镜像的作者信息

RUN

指定镜像被构建时要运行的命令,默认会使用/bin/bash -c 执行RUN 后面指定的命令
也可以使用RUN  ["mkdir","a.txt"]

EXPOSE

告诉docker该容器需要对外开放的端口

CMD

指定一个容器运行时要执行的命令 
docker run -i -t lujiahao/cenos-tomcat /bin/bash
等于在Dockerfile中添加 CMD ["/bin/ps"]
注意:使用 docker run 命令可以覆盖CMD指令

ENTRYPOINT

与CMD类似,但是ENTRYPOINT指定的命令不会被docker run指定的命令覆盖,
它会把docker run命令行中指定的参数传递给ENTRYPOINT指令中指定的命令当作参数。
ENTRYPOINT ["/bin/ps"]
docker run -t -i lujiahao/centos  -l
ENTRYPOINT 还可以和CMD组合一块来用,可以实现,当用户不指定参数的时候使用默认的参数执行,如果用户指定的话就使用用户提供的参数.
ENTRYPOINT ["/bin/ps"]
CMD ["-h"]
注意:如果确实要覆盖默认的参数的话,可以在docker run中指定--entrypoint进行覆盖

WORKDIR

WORKDIR /etc
RUN touch a.txt
WORKDIR /usr/local
RUN touch b.txt
注意:可以在docker run命令中使用-w覆盖工作目录,但是不会影响之前在工作目录中执行的命令

ENV

设置环境变量,在这设置的环境变量可以在后面的指令中使用,使用$引用
并且这个环境变量也会被持久保存到从我们的镜像创建的任何容器中。可以使用env命令查看
也可以使用docker run 命令行的-e参数来传递环境变量,这些变量只在运行时有效 -e JAVA_HOME=/usr/local

USER(了解)

可以指定以什么用户去运行这个容器
USER ftp(用户信息:查看/etc/group)
还可以使用其他组合方式
USER 用户名/UID:组/GID(用户名/UID和组/GID可以单独指定或者组合)
不指定的话默认就是root用户

ADD

ADD指令用来将构建目录下的指定文件复制到镜像中(注意只能是构建目录下面的文件)
ADD a.txt /etc/a.txt
ADD 在添加压缩文件的时候会把压缩文件自动解压。(gzip bzip2 xz),如果目的位置已经存在了和压缩文件同名的文件或者目录,那么这些文件将会被覆盖。

COPY

COPY和ADD类似,但是COPY命令不会对压缩文件进行解压,只负责复制。
如果目的位置不存在,docker会自动创建所有需要的目录,就像使用make -p一样
注意:使用COPY和ADD的命令的时候,复制的源文件必须在当前构建环境之内,也就是和Dockerfile同一目录,否则会找不到。

ONBUILD

这个指令能为镜像添加触发器,当一个镜像被用作其他镜像的基础镜像时,
该镜像中的触发器将会执行。这个触发器所指定的命令会在FROM指令之后执行。
ONBUILD ADD . /usr/local
先在一个镜像中添加这个触发器,再使用这个镜像作为基础镜像创建一个镜像,
会发现在FROM指令之后就开始执行基础镜像中设置的触发器中的指令了。启动一个容器可以查看效果。
注意:触发器只能被继承一次。
有一些命令是不能在ONBUILD中指定的。包括FROM,MAINTAINER,ONBUILD,这样是为了防止在构建过程中产生递归调用的问题。

.dockerignore

在执行build的时候忽略掉不需要的文件。
在Dockerfile同目录下创建.dockerignore,将要忽略的文件填到里面即可.

VOLUME

可以理解为设置(共享目录,磁盘挂载),添加到容器中,并没有真正提交到镜像文件中
这个指令用来向基于镜像创建的容器添加卷,一个卷可以存在于一个或者多个容器内的特定的目录。
卷的特点
    1:卷可以在容器间共享和重用
    2:对卷的修改是立刻生效的
    3:对卷的修改不会对更新镜像产生影响
    4:卷会一直存在直到没有任何容器再使用它。
卷功能可以让我们将一些数据添加到镜像中而不是将将这个内容提交到镜像中。并且允许我们在多个容器间共享这些内容。
    格式:VOLUME  ["/usr/projrct"]
    还可以一次指定多个VOLUME ["/usr/project","/data"]
创建数据卷
    VOLUME  ["/usr/projrct"]
    或者在启动容器的时候创建docker run -it -v /webapp centos /bin/bash
    注意:默认情况下,如果只是声明数据卷而没有映射到宿主机上的具体目录,docker会在/var/lib/docker/vfs/dir/
        目录下分配一个具有唯一名字的目录给该数据卷。通过docker inspect 命令可以查看具体路径
指定宿主主机目录作为数据卷
                        宿主机目录:容器目录
    docker run -it -v /usr/local/webapp:/webapp centos /bin/bash
    注意:如果容器内部已经存在webapp目录,那么目录中的文件将会被覆盖。
默认情况下,数据卷是具有读写权限,rw权限,可以改为只读权限,ro
    docker run -it -v /usr/local/webapp:/webapp:ro centos /bin/bash
使用场景:
    容器里面的tomcat/webapps/目录和本地宿主机的目录对应上,本地修改代码后,
    直接重启容器即可(如果是html连重启都不用了),相当于一个动态部署.

镜像操作

docker的构建缓存

由于每一步的构建过程都会将结果提交为镜像,所以docker的构建镜像过程就显得非常聪明,它会将之前的镜像层看作缓存。再进行重新构建时会从第一条发生了变化的指令开始,前面的都使用缓存

不使用构建缓存的两种方式:

  • 可以使用 --no-cache 参数来指定不使用缓存功能
  • 一般会在dockerfile中使用ENV指令设置一个时间(ENV CREATE_TIME 2015-01-01),写在FROM下面,这样只要一改了这个就不会使用构建缓存了

容器端口映射

默认情况下docker不会自动打开这些端口,必须在运行容器的时候指定-P(大写)参数,这样就可以打开expose指定的所有端口。 会随机映射到宿主机的一个端口上

EXPOSE指令可以同时指定一个或多个需要对外开放的端口

expose 80 8080 6379

对外开放端口的两种方式

-P(大写) 这样的话会将dockerfile文件中EXPOSE 指令指定的所有端口一并公开
-p(小写)可以手工指定需要对外公开的端口

如果没有使用expose指定需要对外开放的端口,还可以在启动容器的时候动态指定,使用-p(小写)参数

-p 80(docker会在宿主机上随机选择一个位于49000~49900内未被使用的端口来映射到容器中的80端口上)
-p 8080:8080(把宿主机上的8080端口映射到容器的8080端口) 前面的表示宿主机
-p 80:80 -p 8080:8080 同时指定多个

使用docker ps 可以查看容器的端口分配情况 或者使用docker port 容器ID/名称查看

推送镜像到Docker Hub(需要先登录:docker login)

docker push 用户ID/镜像名(docker 1.6以下版本这样使用)
docker1.6需要使用下面命令才能推送
docker tag image_id docker.io/login_name/image_name
docker push docker.io/login_name/image_name
推送可能会报错,cdn-registry-1.docker.io: no such host 是因为网络问题、重试几次。

删除镜像

docker rmi 用户ID/镜像名
或者docker rmi `docker images -a -q`
删除所有未打标签的镜像
 docker rmi -f $(docker images --filter 'dangling=true')

Docker教程(三)---容器命令

Docker 容器命令

交互式操作流程

运行一个容器(交互式)

docker run -i -t centos /bin/bash
-i 表示stdin标准输入
-t表示tty终端

第一次执行docker run命令会先从远程仓库中拉取centos的镜像
内部流程如下图

run命令内部流程.jpg

退出容器

exit

重命名容器

docker rename 旧名称 新名称
另一种方法,启动时重命名
docker run --name crxy -t -i centos /bin/bash
合法的容器名称正则[a-zA-Z0-9_.-]

查看容器列表

docker ps [-a]  [-l]  [-n num]

重新启动已经停止的容器

docker start 容器名称/容器ID

附着到一个容器上

docker attach 容器名称/容器ID
    使用`exit`退出容器后,重新由`docker start`命令启动了容器
    此时可以使用这个命令重新进入到容器里面
    可以理解为从外部进入到这个容器内部
    仅仅适用于使用-it启动的容器,像下面的后台启动的是无法使用这个命令的

后台长期运行

创建长期运行的容器

docker run --name lujiahao -d centos /bin/bash -c "while true;do echo hello world;sleep 1;done"

会返回该容器的长id : 55ba56913bb5666ecb352a031503b5191cc8f186558e2f22380c2adadecc7c14

我们通过docker ps获得的是这个长id的前十二位

docker run后面追加-d=true或者-d,那么容器将会运行在后台模式.

获取容器日志

docker logs [--tail num] [-t] [-f]  容器名称/容器ID
    旧版本的日志位置/var/lib/docker/containers/ID/ID-json.log
    但是新版本的实验并没有发现这个log存在位置
    -t 是来添加时间戳的
    -f 持续输出

查看容器内的进程

docker top 容器名称/容器ID

操作一个正在运行的容器

在容器内部运行进程(docker1.3之后才支持)   
docker exec -d lujiahao touch /etc/lujiahao.txt
在后台运行的容器里面创建一个文件
docker exec -it lujiahao /bin/bash
连到一个在后台运行的容器,此时执行exit退出,后台容器还在运行

停止容器

docker stop 容器名称/容器ID  
    向容器发送停止指令,容器自己停止,建议使用
docker kill 容器名称/容器ID   
    直接停掉,不建议使用

获取容器详细信息

docker inspect  [--format | -f] 容器名称/容器ID
    例子:docker inspect --format='{{.State.Running}}' lujiahao
    容器存储位置:/var/lib/docker/containers

删除容器

docker rm 容器名称/容器ID

正在运行中的容器是无法删除的,会出现下面的提示

Error response from daemon: You cannot remove a running container 55ba56913bb5666ecb352a031503b5191cc8f186558e2f22380c2adadecc7c14. 
Stop the container before attempting removal or use -f

可以先停止容器,或者使用 -f 参数

批量删除正在运行中的容器

docker rm `docker ps -a -q`
    docker ps -a -q : 这个命令用来获取所有容器的id

容器的导入和导出

导出:docker export 容器ID/名称 > my_container.tar
导入:cat mycontainer.tar | docker import - 镜像名称:标签

镜像的保存和加载(暂时还没讲到)

保存:docker save 镜像ID > my_image.tar 
加载:docker load< my_image.tar

Docker教程(二)---安装Docker

Docker 核心组件

镜像(Image)

镜像是构建docker世界的基石,也是docker生命周期中的构建阶段.

仓库(Registry)

存储用户构建的镜像以及官方的镜像,分为公有和私有.
Docker公司运营的公有仓库叫做 Docker Hub

容器(Container)

容器是基于镜像启动的,容器中可以运行一个或多个进程。
容器是docker生命周期中的启动或执行阶段。

仓库里面存储着镜像,基于镜像可以启动容器

container = image + docker run

Docker工作流

dockerworkflow.jpg

安装Docker

宿主机Centos7 64位,因为 Docker 是基于64位系统构建的.

  1. 验证linux内核版本uname -a,官方建议使用3.8版本以上

  2. 检查Device Mapper(Docker的存储驱动)

    grep device-mapper /proc/devices
    如果不存在则安装yum install -y device-mapper
    加载dm_mod内核模块 modprobe dm_mod
  3. 安装

    yum -y install docker(默认安装最新版)
  4. 安装指定版本 Docker

    查看可安装的版本
        yum makecache fast(相当于更新本地缓存)
        yum list docker --showduplicates
    安装指定版本
        yum install 2:1.12.5-14.el7.centos
  5. 验证

    启动docker
        systemctl start docker(centos7)
    添加开机启动项
        systemctl enable docker(centos7)
    验证docker是否正常
        systemctl status  docker
        docker info

    出现下面图片表示安装成功了
    dockerinfo.jpg

总结

至此,Docker已经顺利安装了,下面进入到基础命令学习阶段吧!


欢迎大家关注 : LF工作室

简书 : https://www.jianshu.com/u/e61935d18b09

掘金 : https://juejin.im/user/59239002570c350069c5f0bb

微信公众号 :

头条号 :

Docker教程(一)---Docker简介

虚拟化技术

传统虚拟化方式是虚拟机虚拟出一套硬件后,在上面运行一个完整的操作系统;而容器技术是直接使用宿主机的资源,是一种轻量级的虚拟技术.

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

VMvsDocker.jpg

这幅图比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。

虚拟机和容器的区别

相同点:

  • 均可在不同主机之间进行迁移
  • 权限级别操作相同

不同点:

  • 虚拟机是硬件虚拟化,容器是系统层面虚拟化
  • 虚拟机臃肿性能有限,迁移难度较大;容器轻量占用空间小,迁移方便,性能接近原生系统
  • 一台服务器支持虚拟机数量有限,容器却可以达到上千个

容器和虚拟机各有各的优缺点,容器也并不是虚拟机的替代品,只是二者在适应不同的需求下各有特点

Docker思想及理念

  • docker 封装思想和 Java 的跨平台思想非常相似
  • 建议一个容器只部署一个应用(当然也可以部署多个)

Docker应用场景

  • 大量部署相同相似环境服务器(例如微信公众号环境)
  • 为开发、测试提供一个轻量级的独立沙盒环境,让应用程序在不同的环境中,得到相同的运行结果
  • 应用的自动化测试/持续集成/自动化打包/发布
  • 高性能、超大规模的宿主机部署

欢迎大家关注 : LF工作室

简书 : https://www.jianshu.com/u/e61935d18b09

掘金 : https://juejin.im/user/59239002570c350069c5f0bb

微信公众号 :

头条号 :