Semaphore简介

2023/03/07

Semaphore是一个ansible GUI系统,它可以提供一个可视化的界面,用于执行playbook,查看任务执行状态,并且提供简单的认证授权功能。除了GUI功能之外,它还提供一套API,可以通过API来控制任务执行,方便我们开发扩展的应用或者和已有的管控平台对接。

安装配置

Semaphore提供了Ubuntu下的snap安装功能,还有deb,rpm等预置的安装包,也可以通过docker启动,甚至可以直接通过二进制部署。本文以docker部署方式为例,提供一个安装demo:

docker run  -d  --name=semaphore -p 3000:3000 -e SEMAPHORE_DB_DIALECT=bolt -e SEMAPHORE_ADMIN_PASSWORD=fortest -e SEMAPHORE_ADMIN_NAME=admin -e  SEMAPHORE_ADMIN_EMAIL=admin@localhost -e SEMAPHORE_ADMIN=admin -v /root/containers/semaphore/volumes/etc:/etc/semaphore -v /root/containers/semaphore/volumes/lib:/var/lib/semaphore semaphoreui/semaphore:latest 

这里我们用boltdb作为SEMAPHORE_DB_DIALECT的参数,用于数据持久化。除了bolt之外,Sempaphore还支持mysql和postgreSQL作为后端数据库,生产环境可以考虑用mysql或postgreSQL的高可用集群作为后端。

Semaphore支持对接LDAP,并可以通过邮件,telegram,slack等方式触发告警。

Semaphore有个concurrency_mode参数,默认情况下不允许并发执行任务,这个参数可以设置成project或者node。当参数设置成project时,如果task之间是属于不同的project_id时,它们是可以并发执行的,不会校验节点之间是否有相互影响。如果参数设置成node,则仅当这些节点间互不影响时才能并发执行。

入门指南

门户界面

打开系统登录界面:

登录之后,可以直接创建一个项目:

主界面如下所示:

Dashboard页面展示的是任务的执行历史。

Task Templates页面用于配置task,build,和deploy等任务。

Inventory页面用于配置playbook的Inventory信息。

Environment页面用于环境变量的相关配置。

Key Store页面用于配置密码或者密钥信息,这些信息可以用于Inventory里,也可以用在Repositories里。

Repositories页面用于配置ansible playbook存放的位置。

Team页面主要是维护哪些用户可以使用本项目。

除了这些主页面,界面还有一个Dark Mode单选框,选中后可以切换到Dark模式。

点击最底下的用户名

可以进行用户相关的管理:

可以新增用户,修改用户,删除用户:

入门任务

我们从一个全新的环境开始配置练手任务。

免密配置

在配置Inventory之前,我们先做下Semaphore到各个被控节点的公钥免密登录。首先,我们在Semaphore容器上生成一对密钥。

$ docker exec -ti semaphore sh
~ $ cd /var/lib/semaphore/
/var/lib/semaphore $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/semaphore/.ssh/id_rsa): /var/lib/semaphore/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/lib/semaphore/id_rsa
Your public key has been saved in /var/lib/semaphore/id_rsa.pub
The key fingerprint is:
SHA256:8SgiC85Put7vbE5rLCaSsrmv/E5L9YgBpM0Rlg6zwiI semaphore@dc8b31b39871
The key's randomart image is:
+---[RSA 3072]----+
| .+o             |
|=+..             |
|o*o     .        |
|E.o      +       |
|= ..... S .      |
|o. o+.o.         |
| +.=.o .         |
|=oBo++.          |
|OXB*B*           |
+----[SHA256]-----+
/var/lib/semaphore $ ls -ltr
total 56
-rw-r--r--    1 semaphor root         65536 Mar  7 11:56 database.boltdb
-rw-r--r--    1 semaphor root           576 Mar  7 12:10 id_rsa.pub
-rw-------    1 semaphor root          2610 Mar  7 12:10 id_rsa

再把id_rsa.pub的内容加到各个被控节点的.ssh/authorized_keys文件中。

vi $HOME/.ssh/authorized_keys

从Semaphore容器里尝试登录到被控节点: ssh -i /var/lib/semaphore/id_rsa [email protected] ,一方面可以验证下免密登录是否生效,另一方面可以避免后续ansible到各个客户端执行命令时碰到指纹验证问题。

Key Store

完成所有节点的免密登录后,我们可以回到Semaphore界面的配置上。

在配置Inventory之前,我们先到Key Store里配置一个ssh的私钥,把我们上面创建的id_rsa托管在里面。

点击[New Key]创建一个SSH Key:

Inventory

然后进入Inventory页面:

点击Inventory界面上的[New Inventory]按钮:

这里可以选择Inventory的类型有Static, Static YAML和File。Static和Static YAML的用法类似,只是文件格式不同,具体可以查看下ansible官网文档: inventory_guide,File类型需要和Repositories搭配使用,指定本地存储或git上的文件做为inventory文件。

此处我们选择Static Yaml。

底下有示例,可以参照配置Inventory.

User Credentials选择我们前面创建的SSH key。

Environment

作为一个新手任务Environment我们不做过多配置,暂时都置空。

这里有个坑,界面上给出的样例里1245是个数值类型,这种写法不符合json要求,会导致后续task执行失败,需要写成字符串形式。

Repositories

我们创建一个本地存储类型的repository。所有的Repositories都需要配置AccessKey,对于本地存储,这个key就是一个空值。我们需要在Key Store中增加一个None类型的key来占位。

打开Repositories页面:

创建一个local类似的存储,key指定为None Key。

playbook 文件生成

我们可以让必应生成一个playbook样例

然后将这个样例放到容器目录里,由于我们的容器是以卷组方式挂到宿主机,因此可以直接在宿主机上操作。

xxxx@xxxxx[/home/xxxx/semaphore/volumes/lib]$ sudo mkdir repo
xxxx@xxxxx[/home/xxxx/semaphore/volumes/lib]$ cd repo/
xxxx@xxxxx[/home/xxxx/semaphore/volumes/lib/repo]$ sudo vi diskusage.yml
xxxx@xxxxx[/home/xxxx/semaphore/volumes/lib]$ sudo chown -R 1001 repo/

配置task

在Task Templates页面上点击[New Template]

Playbook Filename 里填写相对路径,其它选项用我们前面创建好的Inventory,repository和Env等:

点击[Run],触发测试:

成功执行:

进阶配置

git仓库

我们在入门配置中playbook是放在本地存储上的,这种方式对于配置的更新可能不是那么友好。Repositories除了本地存储之外,还支持git方式管理文件。 如果我们用的是私有的仓库,可以用ssh方式clone仓库,这就要求我们先在git系统上将ssh key配置好。

首先是ssh key的生成。Semaphore容器不支持通过rsa的key从仓库里拉playbook。 如果只能用rsa的key,需要在容器里的 ~/.ssh/config里增加如下内容:

Host git.zzzz.com
PubkeyAcceptedKeyTypes=+ssh-rsa

这里的git.zzzz.com就是指你的git系统域名。

建议用ed25519类型的key,安全性较好:

$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/cloud/.ssh/id_ed25519): 

将生成的key私钥录入到Semaphore的 Key Store里,此处就不一一赘述,然后将公钥关联到git账号上,一般是点击Git UI的右上角图标,选择Settings。

选择SSH/GPG keys,并在里面录入公钥:

Semaphore端Repositories的配置参考下图:

定时执行

Semaphore支持定时触发playbook的执行,可以配置下图中的Cron选项:

点击Cron右侧的文字,还支持通过git的提交配合Cron来触发任务的执行。

朴素的CICD

Semaphore 除了支持上面演示的简单task之外,还有build和deploy功能,可以用来搭建一个朴素的CICD流程。

如上图所示,build流程和task流程基本一致,只是多了一个Start Version参数,用于指定起始的版本号,这个版本号会随着build 任务的执行自增。Build流程里的task可以获取如下变量信息:

semaphore_vars:
    task_details:
        type: build
        username: user123
        message: New version of some feature
        target_version: 1.5.33

我们可以在制品中将上述变量引入到制品名称里,比如:semaphore_vars.task_details.target_version这个变量。

Deploy的流程配置界面如下:

Deloy流程需要关联一个Build流程,playbook里可以获取到如下变量:

semaphore_vars:
    task_details:
        type: deploy
        username: user123
        message: Deploy new feature to servers
        incoming_version: 1.5.33

Build流程编译出制品后,会把版本号传递到deploy的semaphore_vars.task_details.incoming_version。Deploy流程里还有一个Autorun复选框,选中后可以在对应的build流程执行完成后自动触发deploy。