firewalld 用法小结

简介

firewalld 提供了支持网络 / 防火墙区域 (zone) 定义网络链接以及接口安全等级的动态防火墙管理工具。它支持 IPv4, IPv6 防火墙设置以及以太网桥接,并且拥有运行时配置和永久配置选项。它也支持允许服务或者应用程序直接添加防火墙规则的接口。以前的 iptables 防火墙是静态的,每次修改都要求防火墙完全重启。这个过程包括内核 netfilter 防火墙模块的卸载和新配置所需模块的装载等。而模块的卸载将会破坏状态防火墙和确立的连接。现在 firewalld 可以动态管理防火墙,firewalld 把 Netfilter 的过滤功能于一身.

以上引自《使用 firewalld 构建 Linux 动态防火墙 - IBM》

运行、停止、禁用、状态

systemctl start  firewalld.service
systemctl disable firewalld.service
systemctl stop firewalld.service
systemctl restart firewalld.service

systemctl status firewalld.service
firewall-cmd --state

zone

还没有做任何配置,default zone和active zone都应该是public

firewall-cmd --get-default-zone
firewall-cmd --get-active-zones

查看规则

查看已打开的端口和服务

firewall-cmd --zone=public --list-ports
firewall-cmd --list-services

还有哪些服务可以打开

firewall-cmd --get-services

添加规则

firewall-cmd --permanent --add-service=IPSec // 换成想要开放的service
firewall-cmd --zone=public --add-port=8080/tcp --permanent    (

# --permanent永久生效,没有此参数重启后失效

然后更新规则

删除

firewall-cmd --zone= public --remove-port=80/tcp --permanent

更新规则

firewall-cmd --reload

或者直接重启 firewall

systemctl restart firewalld

开机自启动

systemctl enable firewalld.service
systemctl disable firewalld.service
systemctl is-enabled firewalld.service

概念验证(POC)自动化测试实现指南 | 转

接触到了一些POC测试的东西。这篇文章翻译的真不错。转载过来看一下~~

译者是:海燕

如何实现在自动化测试中的概念验证(POC) ?

每个团队都有不同的测试过程和步骤,手工测试是重要的、不可代替的,然而,自动化测试正加快它的发展脚步。

向一个团队介绍自动化测试是一个挑战,以下的要点将决定他们是否需要自动化测试:

  • 项目持续时间

    短期项目还是长期项目–长期项目更适合自动化测试

  • 每轮测试要进行多少次的回归验证?

    对具有重复性和冗长回归测试的项目进行自动化测试,降低了整体的测试时间,同时确保了完全覆盖。

  • 应用程序的稳定性

    应考虑对不受频繁变动的应用程序进行自动化测试。不稳定的产品,其图形用户界面/功能、页面元素或者XPath在不断变化 ,不应该实行自动化,不应在稳定之前对其进行自动化测试。

  • 项目数据是否安全,测试是否需要一些复杂的过程?

    在这种情况下,最好是做手工测试

  • 团队有自动化测试的预算吗?

    自动化测试将给团队增加额外的支出,例如:自动化工具成本、资源成本以及用于框架开发和编写/维护自动化测试脚本所需的时间成本 。

对于自动化测试来说,漏测、认为测试结果是理所当然的情况将永远不会发生。它100%保证每个给定的模块的覆盖率并且每一次的测试都是相同的。同时,它也将有助于在多个浏览器和多个平台上,多次执行相同的测试。

以下的图片,将帮助你了解自动化测试的过程

从技术测试的角度来看,QA团队需要从以下几个方面了解他们的自动化工具:

  1. 平台和操作系统矩阵测试
  2. 数据驱动能力
  3. 报告能力以及报告可移植性
  4. 易于调试和日志记录
  5. 支持版本控制
  6. 可扩展&可定制(能够与其他工具集成,如Ant,TestNG)
  7. 连续整合
  8. 电子邮件通知(当测试成功/失败/任何网络故障时, 可以收到相应自定义邮件)
  9. 如果需要跨浏览器测试和多个平台的测试,是否支持分布式测试环境

选择正确自动化测试工具:

1. 被测的应用程序是一个网络应用程序还是桌面应用程序
2. 选择一个开源工具还是付费工具
3. 工具应满足应用程序的测试要求
4. 使用该工具—根据团队的专业知识以及适合级别来使用和学习工具
5.是否支持报告?如果不支持,没有其他的报告可供选择(开源或付费),如果支持的话,它是如果从介绍和内容的角度来传递正确的数据 **另外:工具评估包括:**    

在选择自动化工具时,有一点是非常重要的,那就是要考虑它是否支持应用程序图形用户界面 GUI 的实现。

1、GUI的实现,是使用传统的HTML或Ajax或其他Web开发工具

2、GUI是否包括视频,图像或大量的文本?

3、它是交互性的还是静态信息

4、浏览器测试

通过上面几点来评估测试工具,用来了解该工具是否真的符合项目的测试要求是很重要的。

实施 **自动化测试(POC) **是至关重要的,最常用的是向一个团队介绍一个工具的一种方法。一旦决定做自动化测试,选定了工具,就是时候为POC创建原型,然后提交给管理层来展示它的实时使用情况以及效益。

要做到这一点:

1、决定在POC中我们将用到的测试用例

2、选择客户最感兴趣的领域可以帮助更好的展示

3、通过一种方式来计划显示手工测试VS自动化测试,证明选择自动化测试在质量上没有退化

4、添加一个运行失败并继而找到缺陷的测试用例–这有助于进一步证实该工具确实可以找到缺陷

5、在任何需要的地方使用断言和验证点

6、明确哪些可以和不能自动化测试的地方。通常,以下几个方面不能自动化测试:

  • 视频流
  • FLASH内容(非静态内容)
  • 非静态图象

7、高亮显示,如果该工具满足以下要求:

  • 它可以自动完成应用程序的所有的关键功能
  • 是否在项目中要求的同一浏览器中进行自动化测试
  • 自动化测试会在每一次应用程序里调用而变化?(就比如:对自动化测试而言最重要的在于每一个元素标识符是唯一的、不会因为在网页中被调用而改变)

POC的结果 -通常是下列之一:

1、工具符合项目要求–进一步的细节,例如,实施成本-谈判价格是必要的,最后确定的许可费、培训以及支持成本,咨询和实施支出等。在开源工具的情况下,确定工具的成熟度和学习曲线,以及是否可以获取学习资源和后续支持,不论是授权的工具还是开源工具,都需要考虑维护成本。需要牢记的是,这些好处在很长一段时间内才是巨大的。

2、工具不符合要求且有其局限性,则不再考虑该工具。

3、工具部分符合要求–重新审视和检查假如有一个能更好的满足要求,或完全与自动化无关。

一旦我们向管理层提出我们的概念证明,并得到了他们的批准。下一步就是在试点项目上尝试该工具。

POC模板:

没有一个完美的POC模板。它的模板一般包括:

1、POC要求

2、POC备选项(所有的自动化工具)

3、项目要求

4、基于项目需求的每一种工具的优缺点

5、POC的结果

这里有几个参考自动化POC模板:

= > POC模板1

= > POC模板2

实施试点项目:

我们应该确定我们的试点项目:

  • 量化商业案例,这将决定我们是否应该使用这个工具。
  • 定义命名规则和应用工具的各种指南。
  • 工具的好处,包括财政及其他各方面的好处。什么可以做,什么不能做,以及可能的解决方法。

第1步# 选择测试案例

  • 从客户端角度的重要的模块或功能
  • 容易证明的功能
  • 测试用例难以手动测试,但自动化将简化那些测试
  • 破碎的功能,用来演示自动化如何帮助识别失败的测试案例

第2步# 自动化框架开发

测试自动化框架是一组概念、过程、程序、实践和环境的集合。这只不过是一个集成的系统,由规则组成,来自动化测试任何给定的产品。该系统包括一系列的功能库、API、测试数据、对象库以及各种其他模块。用于测试自动化的框架和方法脚本,对它本身的成本有影响。

以下的脚本技术可以使用:

  • 线性
  • 混合
  • 数据驱动
  • 关键字驱动
  • 结构化

使用上述任何技术,都可以设计一个测试框架,以帮助实现一个特定的格式来推动测试,简化测试执行和报告。

确定模板、对象的命名规则、测试用例、测试套件、数据仓库等。

第3步# 脚本开发与执行

第4步# 报告

该工具是否具有内置的报表功能?内置的报告能够准确地传送所有需要的信息吗?我们需要另一个工具,如水晶报表,reportNG等来达到报告的目的吗?

第5步# 维护自动化脚本

向利益相关者说明:

正如概念证明和实施试点项目十分重要一样,将其以正确的方式呈现也同样重要。以下几点将有助于用一种积极的方式呈现:

1、通过描述在每个测试周期中,手动测试有多么耗费精力,手动测试中面临的挑战以及如何通过自动化测试来解决问题来开始说明。

2、解释基于概念证明如何选择工具

3、自动化工具的突出特点及其如何满足测试要求

4、同时通过自动化运行,说明自动化工具如何不仅更快的测试执行,同时还有它执行验证和错误识别的能力。

5、演示报告如何显示测试用例的执行状态

6、突出报告功能,如通过彩色的图例来显示不同的测试状态,不同的测试情况下,失败的测试案例的快照,并报告可移植性

7、最后展示每一个测试周期减少的测试时间

8、解释如何实现你已经开发的整个自动化框架,以及它在使用和维护方面的好处。

做好回答一个简单的、关键的功能将需要多少时间来自动化的问题的准备 。除此之外,如果应用程序发生一个小的变更,将需要多少脚本变更以及需要多少时间来修改。

我们希望本指南能帮助你开始写一个自动化测试POC文件

【英文原文:http://www.softwaretestinghelp.com/implement-proof-of-concept-poc-in-automation-testing/】

参考资料


postgresql报错 —— column “rolcatupdate” does not exist

最近又要安装新系统,然后按照惯例地搭建工作环境。却在 postgresql 这一块出了问题,使用 Navicat Premium 访问数据库时弹出了这样的错误:

column “rolcatupdate” does not exist

出现这个问题的根源在于 Postgres 9.5 以后 “rolcatupdate” 便不再支持了。这个问题是客户端的问题。23333333333

所以用官方自带的 pgAdmin 4 访问数据库,则完全不会出现这个问题呢。

其实要解决 Navicat Premium 的这个报错也很简单,你只需要用官方自带的客户端添加好相应的数据库db 和角色role,这个报错就不会再出现了~

参考资料


分布式系统中的必备良药 —— 服务治理

服务治理,从中文字面意思不好理解,如果你知道他的英文,很容易就能理解了:service manage —— 管理服务。以下转载自: 分布式系统中的必备良药 —— 服务治理 ,写的很好,可以辅助学习和理解。

一、前言

  首先本文仅作为笔者在做一些调研之后的总结,仅提供思路,不提供源码,所以如果是想直接冲着源码来的,可以跳过此文。如果后续有机会将项目开源出来,会第一时间写新文章讲解实线细节。

  在分布式系统的构建之中,服务治理是类似血液一样的存在,一个好的服务治理平台可以大大降低协作开发的成本和整体的版本迭代效率。在服务治理之前,简单粗暴的RPC调用使用的点对点方式,完全通过人为进行配置操作决定,运维成本高(每次布置1套新的环境需要改一堆配置文件的IP),还容易出错,且整个系统运行期间的服务稳定性也无法很好的感知。

  关于服务治理网上相关的信息也是非常多,但是如何基于每个公司的当下情况去选择最合适的方案落地,是我们每个架构师或者Leader需要考虑的问题。所谓工欲善其事必先利其器,做好了服务治理,那么SOA化的推进会事半功倍,已经从技术层面天然支持了程序的水平扩展。.Neter社区下成熟的服务治理平台缺乏,我想这也是每个基于.Net技术栈公司面临的问题。2016年微软正式推出了Service Fabric,并于17年开源(https://github.com/Azure/service-fabric),但是相对Java社区常见的解决方案,这个还未得到大规模验证,所以还需谨慎对待。所以本文就通过对不同的成熟解决方案来分析,提炼出一些核心的通用准则,来分析自建一个服务治理框架需要做些什么。欢迎大家拍砖。

二、成熟的解决方案

  查阅的一些资料,目前的业界一些比较成熟的解决方案如下:

名称 所属公司 是否开源 资料文档 备注
Dubbo 阿里巴巴  
HSF 阿里巴巴 目前已作为阿里云产品EDAS其中的套件开放使用
Tars 腾讯 已作为腾讯云应用框架对外提供使用
JSF 京东  
Linkerd CNCF 原型是Twitter所构建的一个基于scala的可扩展RPC系统Finagle
Motan 新浪微博  
istio 谷歌、IBM、Lyft  

  相关资料文档较为丰富的只有一个Dubbo。下面先罗列一下这些解决方案的架构设计(点击图片可跳转到图片出处)。


Docker Compose工具快速入门 | 转

Docker Compose

译者注:原文地址,本译文仅供学习参考,如有侵权请立即联系我,我会立即删除。

Compose是一个用于在Docker上定义并运行复杂应用的工具。通过Compose,你可以很容易地使用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。

在开发环境、临时服务器、CI中使用Compose是非常合适的。但是,我们目前不建议你在生产环境中使用。

使用Compose需要三个基本步骤。

首先,你需要使用一个Dockerfile来定义你的应用的运行环境,这样你就可以在任何地方轻松地重建这个环境。

FROM python:2.7
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code
CMD python app.py

然后,你需要在docker-compose.yml中确定你的应用所使用的服务,这样它们就可以在一个隔离环境中一起运行。

web:
 build: .
 links:
 - db
 ports:
 - "8000:8000"
db:
 image: postgres

最后,执行docker-compose up命令,然后Compose就会启动并运行你的整个应用。

Compose有一整套命令来对你的应用的整个生命周期进行管理。

  • 启动、终止、重建服务。
  • 查看运行中服务的状态。
  • 将运行服务的日志输出整理成数据流。
  • 对一个服务运行一次性指令(原文:Run a one-off command on a service)(译者注:这个没看懂)。

Compose文档

快速开始

让我们完整地进行一套Compose的使用流程——在Compose上运行一个简单的Python的web应用。在这里我们假定你已有一点关于Python的知识,但是即使你不懂也没关系,下文中会出现的概念都很浅显易懂。

安装并搭建Compose环境

首先,安装Docker和Compose

然后,创建项目目录。

$ mkdir composetest
$ cd composetest

在目录中,创建app.py,这是一个使用Flask框架、用于递增Redis中的数据的简单应用。

from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
 redis.incr('hits')
 return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
 app.run(host="0.0.0.0", debug=True)

接下来,在requirements.txt中确定Python依赖:

flask
redis

创建一个Docker镜像

现在,创建一个包含了你的应用所有依赖的Docker镜像。你需要在Dockerfile中确定你创建镜像的Docker命令:

FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt

这些命令会创建一个包含Python、你的代码、Python依赖的Docker镜像。想了解更多关于如何编写Dockerfile的信息,请看Docker用户指南Dockerfile参考文档

确定服务

接下来,在docker-compose.yml中定义你使用的服务的集合:

web:
 build: .
 command: python app.py
 ports:
 - "5000:5000"
 volumes:
 - .:/code
 links:
 - redis
redis:
 image: redis

上文确定了两个服务:

  • web, 这个服务按照Dockerfile安装在当前目录。另外它在镜像中运行了python app.py命令。在镜像中,容器使用开放的5000端口连接宿主机的5000端口,同时访问Redis服务,并且将当前目录挂载到容器中,这样我们在代码上工作改进时就不需要重建镜像了。
  • redis,这个服务使用了公共镜像redis,这个进镜像可以从Docker中心注册镜像库(Docker Hub registry)上拉下来。

使用Compose构建并运行你的应用

现在,当我们执行docker-compose up命令时,Compose就会自动拉下Redis镜像,按你的需求建立镜像,然后将环境和依赖部署好,并运行相关服务:

$ docker-compose up
Pulling image redis...
Building web...
Starting composetest_redis_1...
Starting composetest_web_1...
redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
web_1   |  * Running on http://0.0.0.0:5000/

这个web应用现在应该正在Docker守护进程上监听5000端口(如果你使用了Boot2docker工具,执行boot2docker ip可以显示它的地址)。

如果你希望后台运行这些服务,就在执行docker-compose up时传入-d 标志,执行 docker-compose ps 就可以看到现在正在运行的服务:

$ docker-compose up -d
Starting composetest_redis_1...
Starting composetest_web_1...
$ docker-compose ps
 Name                 Command            State       Ports
-------------------------------------------------------------------
composetest_redis_1   /usr/local/bin/run         Up
composetest_web_1     /bin/sh -c python app.py   Up      5000->5000/tcp

docker-compose run命令能够让你对服务执行一次性指令。比如,如果你想查看web服务的所有可用环境变量:

$ docker-compose run web env

通过查看docker-compose run web env的回显能够查看其他可用命令。

如果你使用docker-compose up -d命令启动Compose,你可能需要这条指令来在运行应用结束后终止你需要的服务: $ docker-compose stop

看完以上内容,你已经了解了使用Compose的基本过程。

参考资料


gitlab 入门(四)—— 创建自己的镜像

这一篇主要来看如何创建自己的镜像.

安装Go

访问下载地址,32位系统下载go1.8.3.linux-386.tar.gz,64位系统下载go1.8.3.linux-amd64.tar.gz,以我这一次下载为例:

wget https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz

# 添加到系统路径
ln -s /usr/local/go/bin/go /usr/local/bin/go

build示例

sameersbn/docker-gitlab 作为示例项目进行创建。

git clone https://github.com/sameersbn/docker-gitlab.git
cd docker-gitlab
docker build --tag="$USER/gitlab" .

build 很慢,耐心等等~

dockerfile 详解

结合 gitlab 的项目

https://github.com/sameersbn/docker-gitlab/commit/711e4115b123f0dfc0c0c2e39879be51fc6f80b2 作为学习版本。

镜像基本配置

基于父镜像构建其他docker镜像,父镜像:可以通过docker pull 命令获得,也可以自己制作

FROM sameersbn/ubuntu:14.04.20171024

Dockerfile维护者

MAINTAINER sameer@damagehead.com

gitlab依赖的版本配置,包括

  • gitlab
  • ruby
  • go
  • gitlab shell
  • gitlab workhorse
  • gitlab page
  • gitlab server

同时还有一些基础配置:

  • git用户与家目录
  • gitlab日志目录
  • gitlab缓存目录
  • redis和节点配置为生产环境。

      ENV GITLAB_VERSION=10.1.1 \
          RUBY_VERSION=2.3 \
          GOLANG_VERSION=1.8.3 \
          GITLAB_SHELL_VERSION=5.9.3 \
          GITLAB_WORKHORSE_VERSION=3.2.0 \
          GITLAB_PAGES_VERSION=0.6.0 \
          GITALY_SERVER_VERSION=0.43.1 \
          GITLAB_USER="git" \
          GITLAB_HOME="/home/git" \
          GITLAB_LOG_DIR="/var/log/gitlab" \
          GITLAB_CACHE_DIR="/etc/docker-gitlab" \
          RAILS_ENV=production \
          NODE_ENV=production
    

gitlab 的其他安装目录配置,包括:

  • gitlab
  • gitlab-shell
  • gitlab-workhorse
  • gitlab-pages
  • gitaly
  • gitlab数据目录
  • gitlab build目录
  • gitlab 运行时目录

      ENV GITLAB_INSTALL_DIR="${GITLAB_HOME}/gitlab" \
          GITLAB_SHELL_INSTALL_DIR="${GITLAB_HOME}/gitlab-shell" \
          GITLAB_WORKHORSE_INSTALL_DIR="${GITLAB_HOME}/gitlab-workhorse" \
          GITLAB_PAGES_INSTALL_DIR="${GITLAB_HOME}/gitlab-pages" \
          GITLAB_GITALY_INSTALL_DIR="${GITLAB_HOME}/gitaly" \
          GITLAB_DATA_DIR="${GITLAB_HOME}/data" \
          GITLAB_BUILD_DIR="${GITLAB_CACHE_DIR}/build" \
          GITLAB_RUNTIME_DIR="${GITLAB_CACHE_DIR}/runtime"
    

镜像初始化

设置好基本信息后,解下来是镜像的必要软件的安装。

  • 添加 git-core 源

    RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E1DD270288B4E6030699E45FA1715D88E1DF1F24 \
     && echo "deb http://ppa.launchpad.net/git-core/ppa/ubuntu trusty main" >> /etc/apt/sources.list \
    
  • 添加 Brightbox 维护的 Ruby PPA 源

       && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 80F70E11F0F0D5F10CB20E62F5DA5F09C3173AA6 \
       && echo "deb http://ppa.launchpad.net/brightbox/ruby-ng/ubuntu trusty main" >> /etc/apt/sources.list \
    
  • 添加 nginx 源

       && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8B3981E7A6852F782CC4951600A6F0A3C300EE8C \
       && echo "deb http://ppa.launchpad.net/nginx/stable/ubuntu trusty main" >> /etc/apt/sources.list \
    
  • 添加 postgresql 源

       && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
       && echo 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' > /etc/apt/sources.list.d/pgdg.list \
    
  • 添加 nodejs 源

       && wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \
       && echo 'deb https://deb.nodesource.com/node_8.x trusty main' > /etc/apt/sources.list.d/nodesource.list \
    
  • 添加 js 包管理器 yarn 的源, yarn 是 Facebook 开源的

       && wget --quiet -O - https://dl.yarnpkg.com/debian/pubkey.gpg  | apt-key add - \
       && echo 'deb https://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list \
    
  • 安装依赖包

    debian_frontend=noninteractive 使用非交互式安装。

       && apt-get update \
       && DEBIAN_FRONTEND=noninteractive apt-get install -y supervisor logrotate locales curl \
            nginx openssh-server mysql-client postgresql-client redis-tools \
            git-core ruby${RUBY_VERSION} python2.7 python-docutils nodejs yarn gettext-base \
            libmysqlclient18 libpq5 zlib1g libyaml-0-2 libssl1.0.0 \
            libgdbm3 libreadline6 libncurses5 libffi6 \
            libxml2 libxslt1.1 libcurl3 libicu52 \
    
  • 设置字符集

    LC_MESSAGES 提示信息的语言, “C”是系统默认的locale,”POSIX”是”C”的别名。所以当我们新安装完一个系统时,默认的locale就是C或POSIX。

       && update-locale LANG=C.UTF-8 LC_MESSAGES=POSIX \
       && locale-gen en_US.UTF-8 \
       && DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales \
    
  • 安装 ruby 的包管理器 bundler

       && gem install --no-document bundler \
    
  • 清除 apt-get 的list

       && rm -rf /var/lib/apt/lists/*
    
  • 拷贝一些文件到 docker 容器,开始安装 gitlab

      COPY assets/build/ ${GITLAB_BUILD_DIR}/
      RUN bash ${GITLAB_BUILD_DIR}/install.sh
    	
      COPY assets/runtime/ ${GITLAB_RUNTIME_DIR}/
      COPY entrypoint.sh /sbin/entrypoint.sh
      RUN chmod 755 /sbin/entrypoint.sh
    
  • 端口映射 EXPOSE :

    EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。主要用处是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。

    在使用 docker run 时,可以使用 docker run -p <host_port>:<container_port> 来固化端口

      EXPOSE 22/tcp 80/tcp 443/tcp
    
  • 匿名卷

    容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,后面的章节我们会进一步介绍 Docker 卷的概念。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。

      VOLUME ["${GITLAB_DATA_DIR}", "${GITLAB_LOG_DIR}"]
    
  • 指定工作目录

    使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。

    在dockerfile中,每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN cd /app 的执行仅仅是当前进程的工作目录变更,一个内存上的变化而已,其结果不会造成任何文件变更。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。

      WORKDIR ${GITLAB_INSTALL_DIR}
    
  • 容器启动时执行的命令

    一个Dockerfile中只有最后一条ENTRYPOINT生效,并且每次启动docker容器,都会执行ENTRYPOINT。 ps: 这一个区别于 CMD,CMD 命令在启动时不一定会执行,ENTRYPOINT 一定会执行。

      ENTRYPOINT ["/sbin/entrypoint.sh"]
    
  • 指定容器的默认执行的命令

      CMD ["app:start"]
    

    此命令会在容器启动且 docker run 没有指定其他命令时运行。

    1. 如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。
    2. 如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。

RUN , CMD 和 ENTRYPOINT 的区别

可以参考这篇答案,讲得非常详细:https://segmentfault.com/q/1010000000417103,以下是转载:

运行时机不太一样。

RUN是在Build时运行的,先于CMD和ENTRYPOINT。Build完成了,RUN也运行完成后,再运行CMD或者ENTRYPOINT。

ENTRYPOINT和CMD的不同点在于执行docker run时参数传递方式,CMD指定的命令可以被docker run传递的命令覆盖,例如,如果用CMD指定:

...
CMD ["echo"]

然后运行

docker run CONTAINER_NAME echo foo

那么CMD里指定的echo会被新指定的echo覆盖,所以最终相当于运行echo foo,所以最终打印出的结果就是:

foo

而ENTRYPOINT会把容器名后面的所有内容都当成参数传递给其指定的命令(不会对命令覆盖),比如:

...
ENTRYPOINT ["echo"]

然后运行

docker run CONTAINER_NAME echo foo

则CONTAINER_NAME后面的echo foo都作为参数传递给ENTRYPOING里指定的echo命令了,所以相当于执行了

echo "echo foo"

最终打印出的结果就是:

echo foo

另外,在Dockerfile中,ENTRYPOINT指定的参数比运行docker run时指定的参数更靠前,比如:

...
ENTRYPOINT ["echo", "foo"]

执行

docker run CONTAINER_NAME bar

相当于执行了:

echo foo bar

打印出的结果就是:

foo bar

Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

执行docker run命令时,也可以添加-entrypoint参数,会把指定的参数继续传递给ENTRYPOINT,例如:

...
ENTRYPOINT ["echo","foo"]

然后执行:

docker run CONTAINER_NAME bar #注意没有echo

那么,就相当于执行了echo foo bar,最终结果就是

foo bar

我在dockboard.org上翻译了一篇《15 Docker Tips in 15 Minutes》,其中有讲到RUN、CMD和ENTRYPOINT的不同,你可以参考一下。

另外有一个Docker Quicktips系列,里面有一篇也是讲ENTRYPIONT的,你可以看一下,连接在这里: http://www.tech-d.net/2014/01/27/docker-quicktip-1-entrypoint/

这个系列的文章翻译我们马上也会添加到dockboard.org的,敬请关注一下哈。

另外这里有官方文档中对entrypoint的说明:http://docs.docker.io/en/latest/reference/builder/#entrypoint

转载结束。

于是本篇对创建镜像的介绍就到此为止了。

参考资料


gitlab 入门(三)—— gitlab与postgresl redis

参照前几篇文章,对gitlab也有了个大致的了解。这一篇将 gitlab 相关的服务全部 docker 化——gitlab postgresql 和 redis 。具体过程可以参考 sameersbn/docker-gitlab, 涉及到的容器有:

docker-compose

创建一个容器,我们可以通过 Dockerfile 模板文件对镜像进行创建并按照配置要求启动。

然而,一般项目往往需要多个容器相互配合才能完成某项任务,比如说在一个web项目中,除了web服务容器,往往还需要后端的数据库服务容器,甚至还需要负载均衡容器等。

使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

docker-compose 安装

有很多种方式可以安装。这里介绍 pip(python) 方式。

yum -y install epel-release 
yum -y install python-pip

确认版本

pip --version
pip 7.1.0 from /usr/lib/python2.7/site-packages (python 2.7)

安装

pip install docker-compose
docker-compose version

	docker-compose version 1.16.1, build 6d1ac219
	docker-py version: 2.5.1
	CPython version: 2.7.5
	OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013

修改内核参数

允许系统给进程的内存大小超过实际可用的内存,对内存申请来者不拒。

vm.overcommit_memory = 1
sysctl -p

这个设置主要是为了 redis 使用。防止后台运行时内存不足。

快速开始

wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml

修改docker-compose.yml文件的一些配置:

# 修改时区。修改参数可以参照 <http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html>

- TZ=Asia/Shanghai
- GITLAB_TIMEZONE=Asia/Shanghai

# 设置一些 key, 64位长度

- GITLAB_SECRETS_DB_KEY_BASE=BRW6rHLKLnw5W3X8qFDHjbVdk4v3tb6RhTbq9MHvGDzZ7jpP2vlxZ9VPMVJLM3cK
- GITLAB_SECRETS_SECRET_KEY_BASE=H3rpHVjwGcK5SVXHVFlnnNFDvVDkPhcgsxGZGlbjcVXTBb2tFqPR5GG6dNgmnSKc
- GITLAB_SECRETS_OTP_KEY_BASE=zSjwt8lz4sG89Mp2zCWJ7MLSSR3kMctqKLjc5xCVZXCb9XTfRpHL6CbvBFqrqcgl

可以使用 pwgen -Bsv1 64 命令生成随机64位密钥。

如果你的服务器开启了SELinux,那么你需要进行下面的操作:

mkdir -p /srv/docker/gitlab/gitlab
sudo chcon -Rt svirt_sandbox_file_t /srv/docker/gitlab/gitlab
mkdir -p /srv/docker/gitlab/postgresql
sudo chcon -Rt svirt_sandbox_file_t /srv/docker/gitlab/postgresql

接下来只需要再 yaml 文件同目录下运行

docker-compose up

就可以看到系统启动起来啦。此时访问服务器上地10080端口,即可看到 gitlab 的页面了。

问题定位

在我设置的时候,中间一度出现Configuring gitlab : database ..........................................的错误,参照文末的参考资料,这是 gitlab 无法连接 postgresql 的原因导致。解决的办法很多。因为操作了很多次,我索性删除docker images 配置重新跑一遍流程,即可:

systemctl stop docker.server
rm -rf /var/lib/docker
docker-compose up

后续学习

目前已经可以将所有应用容器化了。接下来我会往这几个方向深入:

  • docker build创建自己的镜像
  • 容器的高可用策略
  • 与Rancher搭配使用

参考资料