部署Linux代理服务器

在DevOps自动初始化服务器时,需要自动安装Linux软件包、Pip依赖包等。但对于一些安全策略,从服务器直接访问外网时不被允许的。

所以,一般企业采用两种方式:

1. 下载依赖包,上传到服务器上后手动安装。 该方法非常冗余,而且依赖包可能会形成好几层依赖。依赖包的抓取和更新都是一件很耗时和无趣的事情;

2. 做一个软件库镜像。这种方式通过Docker的方式,比以前要容易的多了,软件上试行很简单,硬件上,准备百G左右的硬盘就好了。 还有,镜像更新需要你的网络足够好。

我偏好的方式,是建立一个代理。在一个有外网网络访问权限的机器上,安装代理服务器,其他不可访问外网的设备,通过代理服务器进行访问。可访问资源的策略通过代理服务器进行控制即可, 比如仅能访问yum源、pip源等。这种方式属于按需访问,简单轻便。

代理服务器比较知名的,是Squid,配置强大。另一个我最爱的小型简约的代理服务器是tinyproxy。

  1. 在可访问公网的机器上安装tinyproxy:
yum install tinyproxy

如果yum repo里面没有tinyproxy,可以去rpmfind寻找,并安装远程文件:

yum install https://rpmfind.net/linux/epel/7/x86_64/Packages/t/tinyproxy-1.8.3-2.el7.x86_64.rpm

2. 配置

vi /etc/tinyproxy/tinyproxy.conf
#Add below line, according your server ip configuration
Allow 172.16.0.0/12
Allow 192.168.0.0/12

3. 启动

service tinyproxy restart

4. 在其他机器上验证代理

ssh a-internal-server
export http_proxy=192.168.6.200:8888
curl http://www.luochunhui.com/

完成,就这么简单。

接下来在后文,我将通过配置,把这个Proxy,用到DevOps的自动化软件安装中去,解决yum、pip的安装问题。

项目的环境配置化

发布包往往依赖于一些环境配置,比如项目的数据库连接地址等, 在现在的云方案中,有etcd/condf,Apollo等方案,以相对独立的方式对配置进行管理。但对于传统项目,配置文件经常与Jar、War等文件,或与源代码在同一目录下进行管理。

传统项目的配置文件通常有以下三种。

  1. 编译参数选择,通过编译时指定不同的参数,将源代码中不同的配置文件打包至二进制文件。
  2. 线上文件目录指定。二进制文件固定读取某一指定目录下的配置文件。
  3. 二进制文件替换配置。由于Java工程下的Jar、War实际结构是zip包,而且其配置文件是明文文本文件。所以,对于此类伪二进制目标文件,可以先采用解压包,替换二进制文件,再封装包的方式进行配置更新。该方式即可达到配置文件更新的目的,又可以保证测试环境和生产环境的二进制包的一致性。

建立配置模板文件、配置文件

在config库中,根据项目名称samples,建立 以下文件:

---
# file: projects/samples/vars/main.yml
# configure_files选项,其指定配置文件列表。系统将从main,prod,uat等文件中所获得变量文件,对src模板文件进行替换,生成实际的配置文件,最后替换jar包中的dest文件。

hellowar:
tomcat:
service_name: "tomcat-hellowar"
port: 8080
configurations_files:
- { src: "{{ project_dir }}/hellowar/config.properties.j2", dest: "WEB-INF/classes/config.properties" }
# file: projects/samples/hellowar/config.properties.j2
# 一个测试的配置

config.site.name={{ config.site.name }}
---
# file: projects/samples/vars/prod.yml
# 生产环境的变量值

config:
site:
name: "I am a production site"
---
# file: projects/samples/vars/uat.yml
# UAT环境的变量值

config:
site:
name: "I am a test site"

Ansible文件

---
# 用Ansible文件将上述配置连接起来。注意增加: role: app.config; configurations_files: "{{ hellowar.configurations_files }}" 即可。

- hosts: "&samples:hellowar"
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
tags: "always"
vars:
project_name: "samples"
roles:
- role: app.config
- role: app.war
vars:
type: "tomcat"
vars:
project_name: "samples"
service_name: "{{ hellowar.tomcat.service_name }}"
workspace: "{{ app_root }}/war/{{ service_name }}"
container:
type: "tomcat"
service_name: "{{ service_name }}"
jdk_home: "{{ jdk8_home }}"
warfile: "hello.war"
TARGET_FILE: "hello-0.0.1-SNAPSHOT.war" #this file path will be replace by jenkins
war_unachive: false
target_type: "war"
configurations_files: "{{ hellowar.configurations_files }}"
service:
name: "{{ service_name }}"
port: "{{ hellowar.tomcat.port }}"

详细工作原理可以阅读 app.war 中的源代码。

加密配置管理

基于安全考虑,生产服务器中的数据库密钥、付费业务的Key/Value对,通常应该进行保密处理,不应该将明文暴露在Config代码库中。Ansible的变量文件可以通过Vaults工具进行加密管理。

另一个好的建议是对公用资源的管理,如数据库、缓存等。 运维应按照业务需要、资源配置需求,对公用资源进行分组管理。开发人员无需了解实际的资源连接IP、密码等细节,只需要了解组名、以及该类型资源下存在的键即可。

以MySQL配置为例,说明配置组和加密配置使用:

---
# file: configs/vaults/test.yml

mysql:
group_sample:
host: 192.158.31.100
port: 3306
user: root
password: "password"

文件定义了 mysql 的sample组。 其键包括 host、port,password等。

在应用的配置模板文件中,按照应用的格式要求,填写资源.组.键即可:

server:
sql:
# 开发环境
host: {{ mysql.group_jkt.host }} # 192.158.31.100
port: {{ mysql.group_jkt.port }}
username: {{ mysql.group_jkt.user }}
password: {{ mysql.group_jkt.password }}

建立加密的prod配置文件

$ cd configs/vaults
$ ansible-vault create prod.yml
New Vault password:
Confirm New Vault password:

输入密钥文件,回车之后,会进入vi编辑页面。 填入与test.yml文件相同的结构和正确的密码,保存。 特别注意,在配置文件更新时,要保证prod和test环境的同步,prod环境缺少配置键而到时上线失败。

查看prod.yml应形如如下内容:

$ cat prod.yml
$ANSIBLE_VAULT;1.1;AES256
6466356161366165386166393136336233
3762383566393964366661313962636264

该文件仅能通过ansible-vault edit prod.yml ,并输入密码后再次进行编辑。无密码之人是无法对文件进行查看和修改的。所以,放心的将prod.yml加入到git版本库进行管理。

还有一个步骤,你需要将这个密钥告诉Ansbile发布机。登录到发布机后,修改ansbile.cfg文件,增加行:

vault_password_file = ~/.ansbile/vault_password_file

创建~/.ansbile/vault_password_file文件,并将密钥明文写入到文件中。

DevOps下的角色及工作流

角色说明

角色职能
admin
管理员
对自动化部署系统进行系统管理、插件管理、编译节点建设、用户及权限管理。 对Jenkins使用的密钥进行管理。
sa
发布配置工程师
建立Jenkins编译任务(Build job)、发布任务(Publish Job)
scm
运维配置工程师
建立配置文件模板、配置文件参数,编写自动运维剧本
dev
开发工程师
编写代码、提交至SCM。
test
测试工程师
按顺序进行测试、准生产、生产各环境的发布、测试、审核审批
master
DevOps架构师
设计并实现DevOps的架构、流程、角色、规范,选择并应用各DevOps工具,指导全员融入DevOps体系

角色权限表 – Jenkins

RoleOverallCredentialsManage ownershipAgentJobPipelineRunViewSCM
adminAllAllAllAllAllAllAllAllAll
devNoneNoneNoneBuild, CancelDeploy to test (Automatically)NoneNoneNone
qaNoneNoneNoneBuild, CancelTestPassDeploy to uat&prodNoneNoneNone
scmCreate, Update, ViewALLNoneConfigureand All for test usageAll for test usageAllNoneNone
saCreate, Update, ViewNoneALLNoneNoneNoneNoneNone

启用角色管理插件

进入Jenkins管理页面,配置全局安全配置, 选择 Role-Based Strategy,保存。在保存前,先备份Jenkins Home下面的config.xml文件,当权限配置出错时,会导致管理员登录不进去。此时还原config.xml文件即可解决。

配置全局角色、项目角色

然后开始按上述权限表进行配置,进入Jenkins系统管理 -> Manage and Assign Roles -> Manage Roles, 通过新增,勾选,得到如下图所示的全局角色表、项目角色表。

建立用户,并授权角色

使用OpenLdap,添加用户。

Jenkins开启Role-Based Strategy组件之后,不接受OpenLdap的角色属性,因此,Jenkins内部权限应迁移到Manage and Assign Roles中进行配置。

进入系统管理 -> Manage and Assign Roles -> Global roles -> User/group to add -> 添加用户邮箱 -> 然后勾选对应角色

进入系统管理 -> Manage and Assign Roles -> Item roles -> User/group to add -> 添加用户邮箱 -> 然后勾选对应的项目组

其他与职能角色相关的任务

SA / SCM:

  1. 管理playbooks部署代码,负责项目及工程配置
  2. 管理 configs/prod 的配置代码修订
  3. 在Jenkins中发布playbooks库
  4. 在Jenkins中发布configs生产库
  5. 维护Jenkins的项目、工程文件。[SA/Dev]

Admin:

  1. 管理角色、用户、角色赋权
  2. 管理整体Jenkins配置

Dev:

  1. 维护业务代码
  2. 维护业务Config。由于生产配置库使用加密存储,Configs/Prod的配置,特别是涉及到密码的配置,由SA管理。
  3. 发起Pipeline编译过程,完成从编译、测试环境发布、测试过程,进入UAT发布准备阶段。

Test:

  1. 承接Dev的测试环境,共同完成测试验证工作。
  2. 确认发布UAT环境
  3. 验收UAT环境
  4. 发布PROD环境
  5. 验收PROD环境

新建项目和工程

为了管理方便,在DevOps中将系统分级为两层,项目、工程。 在演示用例中,我们建立一个项目,samples, 里面包含若干工程,hellowar, hellojar, hellohtml等。

以hellowar为例,建立Tomcat项目的自动化部署。

关于hellowar

hellowar是一个简单的tomcat项目,源代码可以在gikoluo/java-tomcat-example-app找到。部署成功后,访问项目首页,会得到一个WEB页面: hello world。

Jenkins项目框架

 HOME  #根
|-- samples #项目名
| |-----builds #这里放置编译任务
| |---- hellowar
| |---- hellojar
| |---- hellowar #这是一个带有pipeline的发布任务
| |---- hellojar
|-- sa #SA项目,用于管理DevOps环境及设备
|---- playbooks 这是一个发布+ant编译的项目。

对于工程,我们把编译和发布分离,一个pipeline中仅关联一次编译,这样有助于减少编译次数,并保证各环境下的部署内容一致。

Playbook项目框架

ROOT
|-- samples #项目名
|-- 22-tomcat8.yml #基础包。用数字作为前缀,表明依赖的先后顺序。
|-- hellowar.yml #工程包。以工程为名。

配置文件结构

ROOT
|-- projects
| |-- samples
| | |-- vars
| | | |-- main.yml #通用配置
| | | |-- uat.yml #环境特殊配置,比如环境IP,数据库IP等
| | |-- hellowar #应用配置模板文件,可以使用vars中的变量
| | | #在发布时进行变量替换。
| | | |-- application.xml

Tomcat基础包部署文件

---
# filename: 22-tomcat8.yml

- hosts: "&samples:hellowar"
become: True
become_user: root
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
vars:
project_name: "samples"
roles:
- app.tomcat
vars:
project_name: "hellowar"
service_name: "{{ hellowar.tomcat.service_name }}"
jdk_home: "{{ jdk8_home }}"
tomcat_version: '8.5.38'
tomcat_env_catalina_home: "{{ opt_root }}/{{ service_name }}/"
tomcat_redis_filename: "apache-tomcat-{{ tomcat_version }}.tar.gz"
tomcat_default_override_uri_encoding: UTF-8
tomcat_service_allow_restart: true
system_type: "systemd"
tomcat_instances:
- name: "{{ service_name }}"
service_name: "{{ service_name }}"
service_file: "{{ service_name }}"
port_ajp: 8009
port_connector: "{{ hellowar.tomcat.port }}"
port_redirect: 8443
port_shutdown: -1
path: "{{ opt_root }}/{{ service_name }}"
tomcat_service_allow_restart: true
tomcat_default_override_uri_encoding: UTF-8

项目部署文件

---
# filename: hellowar.yml

- hosts: &samples:hellowar
pre_tasks:
- name: include Globals
include: "{{ playbook_dir }}/../includes/global_vars.yml"
tags: "always"
roles:
- role: app.config
- role: app.war
vars:
type: "tomcat"
vars:
project_name: "samples"
service_name: "{{ hellowar.tomcat.service_name }}"
workspace: "{{ app_root }}/war/{{ service_name }}"
container:
type: "tomcat"
service_name: "{{ service_name }}"
jdk_home: "{{ jdk8_home }}"
warfile: "hello.war"
TARGET_FILE: "hello-0.0.1-SNAPSHOT.war" #this file path will be replace by jenkins
war_unachive: false
target_type: "war"
configurations_files: "{{ hellowar.configurations_files }}"
service:
name: "{{ service_name }}"
port: "{{ hellowar.tomcat.port }}"

服务器设备配置

#filename: uat/samples

[jdk8]
192.168.10.50 default_link=1

[hellowar]
192.168.10.50

[samples:children]
hellowar

配置文件

---
#repo: configs
#filename: configs/projects/vars/main.yml

hellowar:
tomcat:
service_name: "tomcat-hellowar"
port: 8080
configurations_files: []
log:
home: "{{ log_root }}/tomcat-hellowar"
level: INFO

提交并在Jenkins中发布Playbooks,configs代码

进入发布机,将项目的设备资源及环境进行初始化

ansible-playbook jkt/22-tomcat7.yml -i $INVERNTORY
ansible-playbook jkt/crm.yml -i $INVERNTORY --tags=setup
ansible-playbook jkt/appserver.yml -i $INVERNTORY --tags=setup

配置Jenkins

在Jenkins WEB页面中,如上框所示的目录架构,新建文件夹任务,samples; 再建立文件夹任务builds。

建立hellowar工程,类型为maven项目,配置如下:

源代码: https://github.com/gikoluo/java-tomcat-example-app.git
Build:
ROOT POM: pom.xml
Goals and options: compile war:war
归档成品: target/hellowar.war

保存,编译,等待hellowar.war编译完成

在samples内,建立任务hellowar,类型为 流水线。配置如下:

Prepare an environment for the run: True
Properties Content内填入以下内容:

PROJECT_NAME=samples
SERVICE_NAME=hellowar
BUILD_JOB=${PROJECT_NAME}/builds/hellowar
TARGET_FILE=target/hellowar.war
AUTO_BUILD=true

流水线: Pipeline srcipt from SCM
GIT, Repositories: https://github.com/gikoluo/devops-utils.git
脚本路径: src/jenkinsfile/common/Jenkinsfile.groovy

  • Prepare an environment for the run: 为EnvInject提供的功能,将Properties Content的语法为Key/Value变量,申明内容将注入到全局变量,供Jenkins脚本使用。注意,内容中,不允许有注释。
    • PROJECT_NAME/SERVICE_NAME: 填项目、工程名称。
    • BUILD_JOB: 填上文建立的Maven项目名。形如${PROJECT_NAME}/builds/hellowar。
    • TARGET_FILE: 填BUILD_JOB中编译归档的文件名,注意带上路径。
    • PLAYBOOK: 填写Playbook名称,如不存在则将使用 ${PROJECT_NAME}/${SERVICE_NAME}。
    • AUTO_BUILD: true/false 。 #是否每次发布时都自动执行编译。默认True。
  • 流水线: gikoluo/devops-utils 提供了一些标准通用的流水线文件,可以直接使用,可以获得源代码滞后,将文件内容直接复制到流水线定义里。

保存,构建。顺利的话,你将得到一个如图所示的Pipeline:

确认发布UAT之后,将进入验收阶段。 在浏览器中键入: http://192.168.10.50:8080/hello/ , 得到Hello World。确认UAT验证完成。

接下来继续通过Pipeline,确认Production发布、Production验收阶段,完成上线的全部流程。

新增目标服务器

在完成服务器的上架工作后,对服务器进行初始化配置。

在Ansible发布机配置的章节,已经进行过类似的操作了。 这里作为运维新机器上架的操作,再列一次。

在机器建立之初,首先得通过项目属性,了解机器的用途。获得以下属性:

  • 项目组: samples。 项目组为服务组,或者一个工作组。可以共享部署配置。
  • 服务名:hellowar。 服务名为一个可独立部署的服务。
  • 环境:UAT。
  • 设备IP:192.168.10.50
  • 服务环境: Tomcat8
  • JAVA环境:JDK8
  • 服务类型:放置在Tomcat下的War服务包

建立机器配置

$ cd playbooks
$ vi uat/samples
[jdk8]
192.168.33.100 default_link=1

[hellowar]
192.168.33.100

[samples:children]
hellowar

提交代码到GIT,然后在Jenkins WEB界面中执行SA/playbooks发布操作,将更新推送到发布机。

进入到发布机中进行目标的Ansible推送操作。

ssh ANSIBLE-UAT

export IP=192.168.33.100
export INVERNTORY=uat
export KEY_PATH=~/.ssh/agent/id_rsa
#注入公钥
ansible-playbook setups/10-installkey.yml -i $INVERNTORY -l "$IP" --private-key=$KEY_PATH
#建立统一的初始化环境
ansible-playbook setups/00-setup.yml -i $INVERNTORY -l "$IP"
#安装JDK8
ansible-playbook setups/01-oracle-jdk8.yml -i $INVERNTORY -l "$IP"
#安装Tomcat
ansible-playbook samples/22-tomcat8.yml -i $INVERNTORY
#初始化项目框架
ansible-playbook samples/23-hellowar.yml -i $INVERNTORY --tags=setup

关于如何写sample/*.yml, 在下一篇文章中会介绍。

Ansible发布机

上接Jenkins部署,现在分别在三个环境下,构建三台Ansible发布机器,机器将作为Jenkins的部署节点。
现在将Jenkins机器作为临时的Ansible节点,分别推送三个环境的Ansible部署机器的安装工作。
以UAT环境为例,操作如下

建立Playbook发布项目

进入Jenkins:
新建任务,添加文件夹,任务名: SA;
进入SA目录,新建任务,添加自由风格的软件项目,任务名: playbook,配置如下:

项目类型: 自由风格的软件项目
描述: 将Absible Playbooks 发布到 发布机
源码管理: git, Repository URL: https://github.com/gikoluo/playbooks2.git
构建:Invoke Ant
Ant version: ant or default
Target: build
构建后操作:
Send build artifacts over SSH
SSH Server: 192.168.10.45
Transfers Set:
Source file: dist/playbooks.tar.gz
Remote directory: playbooks/
Exec command: cd /data/playbooks && tar zxvf playbooks.tar.gz && rm playbooks.tar.gz
Flatten files: TRUE

SSH Server: 192.168.33.10
Transfers Set:
THE SAME AS BELOW.

SSH Server: 10.0.1.12
Transfers Set:
THE SAME AS BELOW.

归档成品:
用于存档的文件: dist/playbooks.tar.gz

保存,然后发布, 检查日志输出、目标文件夹代码是否正常。

安装Ansible

#进入Jenkins机器
$ ssh jenkins
#安装pip & ansbile。 通过pip安装可以保证ansible的版本较新。
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py
$ pip install ansible
#克隆ansible剧本
$ cd /data
$ git clone https://github.com/gikoluo/playbooks2.git playbook
$ git clone https://github.com/gikoluo/ansible-config.git configs
#配置IP
$ cd playbooks
$ vi uat/sa

[ansible]
192.168.10.45
[jdk8]
192.168.10.45 default_link=1

#将Jenkins登录公钥注入部署机器
$ export IP=192.168.10.45
$ export INVERNTORY=uat
$ export KEY_PATH=~/.ssh/agent/id_rsa
$ ansible-playbook setups/10-installkey.yml -i $INVERNTORY -l "$IP" --private-key=$KEY_PATH #如果使用证书登录,使用本行
$ ansible-playbook setups/10-installkey.yml -i $INVERNTORY -l "$IP" -kK #如果使用密码登录,可以使用本行,输入密码和SUDO密码
$ ssh $IP ip a #测试是否可直接登录成功,如果返回正常,则说明安装密钥正常。
#将Jenkins登录公约注入部署机器
$ ansible-playbook setups/00-setup.yml -i $INVERNTORY -l "$IP" #初始化机器环境
$ ansible-playbook provo/01-ansible.yml -i $INVERNTORY -l "$IP" #安装Ansible
$ ansible-playbook setups/01-oracle-jdk8.yml -i $INVERNTORY -l "$IP" #安装JDK环境,将Ansible机器作为Jenkins节点时需要
$ ansible-playbook setups/01-open-jdk8.yml -i $INVERNTORY -l "$IP" #或安装openJDK环境,将Ansible机器作为Jenkins节点时需要

将发布机器配置为Jenkins节点

进入Jenkins -> 系统管理 -> 节点管理 -> 新建节点 -> 填写下方配置后保存。

节点名称:ansible-uat
节点类型:固定节点
远程工作目录: /data/playbooks
主机: 192.168.10.45
Credentials: 自行配置私钥

保存后,Jenkins会自动启动节点服务。如启动失败,可根据日志检查问题。

部署其他节点

与上方操作相同,完成三台发布机初始化工作,在JENKINS节点中分别命名为ANSIBLE-TEST,ANSIBLE-UAT,ANSIBLE-PROD。

Jenkins部署

使用Docker部署

$ git clone https://github.com/gikoluo/devops-jenkins.git
$ cd devops-jenkins
$ docker-compose up

使用K8S部署

$ git clone https://github.com/gikoluo/devops-jenkins.git
$ cd devops-jenkins
$ kubectl apply -f jenkins-home-pvc.yaml
$ kubectl apply -f jenkins-deployment.yaml
$ kubectl apply -f jenkins-service.yaml

传统部署

$ yum install jenkins

安装组件

微服务部署时,组件已经完成部署。传统部署模式下,需要手动运行以下脚本安装组件。

 
$ export JENKINS_USER_ID=luochunhui
$ export JENKINS_API_TOKEN=123456
$ export JENKINS_SERVER=http://192.168.30.200:8080/
$ cd devops-jenkins
$ wget "${JENKINS_SERVER}jnlpJars/jenkins-cli.jar"
$ xargs java -jar jenkins-cli.jar -s $JENKINS_SERVER install-plugin $i < plugins.txt

OpenLdap管理

一、服务器部署

使用DockerComposer部署

$ git clone https://github.com/gikoluo/openldap
$ cd openldap
$ docker-compose up

使用K8S部署

$ git clone https://github.com/gikoluo/openldap
$ cd openldap
$ kubectl apply -f openldap-etc-pvc.yaml
$ kubectl apply -f openldap-lib-pvc.yaml
$ kubectl apply -f openldap-deployment.yaml
$ kubectl apply -f openldap-service.yaml

# Check services
$ kubectl get deployments openldap
$ kubectl get services openldap
$ kubectl describe services openldap
$ kubectl get pods

# Open a temporary port to manage
$ kubectl port-forward openldap-XXXXXX-XXXX 8389:389

使用Helm部署

helm install --name openldap -f helm.yaml stable/openldap

使用传统Yum部署

详细流程参见页面: https://linuxtechlab.com/openldap-complete-guide-install-configure

$ yum install openldap-server

二、管理使用

验证:

$ ldapsearch -x -W -D 'cn=Manager,dc=greenlandfinancial,dc=com' -b "" -s base
Enter LDAP Password:
# extended LDIF
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: ALL
#

#
dn:
objectClass: top
objectClass: OpenLDAProotDSE

# search result
search: 2
result: 0 Success
numResponses: 2
numEntries: 1

使用ApacheDirectoryStudio进行管理

从 https://directory.apache.org/studio/ 下载并安装ADS。 适用于MAC,Windows,Linux。

新建LDAP连接,使用以下配置:

Hostname: 127.0.0.1
Port: 389
Encryption method: No encryption
Provider: Apache Directory LDAP Client API
BindDN or user: cn=Manager,dc=greenlandfinancial,dc=com
Bind password: password set in deploy

建立组织和用户结构

建立组织结构,结果按图示:

ou=inner         #内部产品
- ou=jenkins #某产品,也用来管理用户和产品之间权限管理
ou=people #用户列表
- cn=luochunhui@greenlandfinancial.com #用户

管理用户和组关系

在需要的授权的组中,增加member属性,其值为用户的DN地址。示例如下图:

DevOps最佳实践(开篇)

十年工作以来,我一直工作在IT工作领域,从事的工作包括工程师,高级工程师,技术总监,产品总监,也包括有事业部总经理,集团副总裁等管理职能。每次职能提升,我更多的看到是跨部门协作和沟通的重要性和难度。如何处理部门间的工作分配、协同、甚至是整合,成了我日常工作的重要内容。

开发部的利益诉求,是保障产品功能得以快速上线,功能正常运行;运维团队的利益诉求是系统安全、功能稳定,系统高效。在运维的最佳实践中,大都会指明:『为了更好的保证数据安全和运维稳定,应该禁止开发人员直接访问和修改生产环境』。该实践说明运维原则的Why和What,但少有公司能解决How。在缺乏工具的时代,常常是开发人员完成工作后,将开发结果交给运维人员,运维人员再通过FTP等工具上传至生产服务器,完成部署和重启工作。而这个过程中,运维人员对上线的的服务不了解,承担不了上线过程的审核工作,只是机械的重复的完成了FTP、代码搬运、服务重启的执行工作。而开发人员也在惆怅说没有生产环境权限,对于部署中或部署后的日志访问权限受限,降低了服务故障的识别效率。

DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。借助这一理论框架,可对公司的开发和运维方式建立一套解决方案。

我最早接触DevOps概念是2007年在『满星』任职时期。当时还不叫DevOps的概念,但开发、测试、运维的实际工作与DevOps的组织结构很相似。开发人员使用PHP进行开发,CVS用于代码管理,运维提供称之为『Code Ballinrobe Launcher』的WEB工具。 cheap NBA jerseys 在每次上线时,开发人员先声明需要增量发布的标记Tag,使用这个Tag对需要增量更新的代码进行标记;而后交付给开发团队进行代码走查,测试人员使用『Code cheap jerseys Lancher』将Tag文件签出,上线到测试环境进行回归测试。测试通过后,再将测试环境的代码rsync到生产环境完成整个上线过程。这套工具很好的释放了运维工程师,将上线工作交给了测试人员,因为测试人员有审核代码是否达到上线标准的权利。 wholesale NBA jerseys 2010年进入腾讯,广告平台部。我继承了满星的思路,使用Python开发了一个全新的发布系统,称之为『Code wholesale NBA jerseys Builder』,用来承载广告平台部门及其外包部门的代码管理和发布工作。然后DevOps的概念开始蔓延,capistrano、 Tasar?m Jenkins等各种辅助工具出现,并相互渗透整合,形成了DevOps的生态链。至此我也放弃了对CodeBuilder的继续维护,并切换到开源微服务阵营。

DevOps的技术理论和工具的不断完善,给自动化运维带来了福音。他不是一个新的产品活工具,而是提供了一个跨部门的管理框架。

之所以开篇写此系列,是希望能将我爬过山,填过的坑做一个整理,将过往的经验进行一次整理,形成一个DevOps的最佳实践。我尽量将『最佳实践』进行了抽象和整理,尽可能少的涉及到业务细节和开发语言细节,使其具有一定的适应性和简便性,但每一次实践都取决于特定时期和特定环境,实践是否能在读者的工作环境快速推进,需要读者根据当前的环境认真分析和决策。