- 博客/
使用 Helm 部署 Spinnaker 持续部署(CD)平台
Table of Contents
环境说明#
Kubernetes Version:
v1.17.9
操作系统:
CentOS 7.8.2003
Helm Version:
v3.2.1
Spinnaker Version:
1.26.3
spinnaker 组件说明#
Deck:前端web页面 端口9000
Gate:API网关,所有程序通过gate与spinnaker通信。 端口8084
Orca:编排引擎,定义管道或任务,并管理阶段和任务,协调其他Spinnaker服务。 端口8083
Clouddriver: 云厂商适配器,负责对云厂商的变更资源调用。 端口7002
Front50:用于保存应用程序、管道、项目和通知的元数据。 端口8080
Rosco:为各种运供应商生成不可变的VM镜像。 端口 8087
Igor: 持续集成系统集成,触发管道。端口 8088
Echo:消息通知,负责发送通知。端口 8089
Fiat: 认证授权服务。端口 7003
Kayenta:自动化的金丝雀分析。端口 8090
Halyard: Spinnaker生命周期配置管理工具。端口 8064
组件关联图 如下所示
使用 helm
安装部署#
注意
示例演示环境使用openwrt
进行扶墙处理;在使用 helm 部署前,首先需要确认你的梯子够不够稳,如果不稳的话建议使用的是手动部署。
helm 添加仓库
helm repo add stable https://charts.helm.sh/stable
helm repo update
helm search repo spinnaker
NAME CHART VERSION APP VERSION DESCRIPTION
stable/spinnaker 2.2.6 1.16.2 DEPRECATED - Open source, multi-cloud continuou...
创建 values.yaml
部署文件
示例部署使用了
Nfs storageClass
作为 pvc & pv 的管理。生产环境不太建议。原 helm
values.yaml
部署文件可以使用此 链接 查看,或 使用下面命令进行打印输出。helm show values stable/spinnaker
修改完成后的 prod-values.yaml 文件查看
cat > prod-values.yaml << EOF
halyard:
spinnakerVersion: 1.26.3
image:
repository: gcr.io/spinnaker-marketplace/halyard
tag: 1.32.0
persistence:
enabled: true
storageClass: nfs-retain
minio:
enabled: true
image:
tag: RELEASE.2020-01-03T19-12-21Z
service:
type: ClusterIP
accessKey: admin
secretKey: spinnaker
persistence:
enabled: true
storageClass: "nfs-retain"
redis:
enabled: true
password: spinnaker
master:
persistence:
storageClass: nfs-retain
cluster:
enabled: false
EOF
kubectl create ns spinnaker
helm upgrade --install spinnaker -f ./prod-values.yaml -n spinnaker stable/spinnaker
使用 traefik
暴露前端页面#
cat <<EOF | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: spin-deck
namespace: spinnaker
spec:
entryPoints:
- web
routes:
- match: Host(\`spinnaker.treesir.pub\`) && PathPrefix(\`/\`)
kind: Rule
services:
- name: spin-deck
port: 9000
EOF
cat <<EOF | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: spin-gate
namespace: spinnaker
spec:
entryPoints:
- web
routes:
- match: Host(\`spin-gate.treesir.pub\`) && PathPrefix(\`/\`)
kind: Rule
services:
- name: spin-gate
port: 8084
EOF
添加 host 记录
sudo vi /etc/hosts
192.168.8.30 spinnaker.treesir.pub # 解析至对应 ip
## 设置deck与gate的域名
kubectl exec -it spinnaker-spinnaker-halyard-0 bash -n spinnaker
hal config security ui edit --override-base-url http://spinnaker.treesir.pub
hal config security api edit --override-base-url http://spin-gate.treesir.pub
hal deploy apply # 应用应用生效
配置管理 openLdap#
kubectl exec -it spinnaker-spinnaker-halyard-0 bash -n spinnaker
hal config security authn ldap edit \
--user-search-base 'ou=users,dc=treesir,dc=pub' \
--url 'ldap://192.168.8.1:389' \
--user-search-filter 'cn={0}' \
--manager-dn 'cn=admin,dc=treesir,dc=pub' \
--manager-password '123456'
hal config security authn ldap enable
hal deploy apply # 执行生效
备份#
创建备份
hal backup create
恢复备份
hal backup restore --backup-path /home/spinnaker/halyard-xxxx.tar
删除部署#
hal deploy clean
请注意,此命令将破坏目标部署环境中的所有 Spinnaker 组件。因此,请谨慎使用它并备份您的配置,以防您要还原它。
删除 Spinnaker 后,通过运行下面命令删除 halyard,下面命令在 helm 部署的集群中
不适应
,在helm
中 可以直接执行helm delete xx
进行删除sudo ~/.hal/uninstall.sh
授权管理#
Fiat
组件是 Spinnaker 的授权(authz)微服务。它可以授予用户执行管道,查看基础结构等访问权限。默认情况下处于禁用状态。与身份验证非常相似,Spinnaker 允许使用各种可插入的授权机制。使用 Fiat 主要可以实现如下功能:
限制对特定的clouddriver account 访问。(读、写)
限制对特定的APP 应用程序访问。(读、写、执行)
使用触发器对访问控制的程序运行管道。
支持角色提供者中定期更新用户角色。
当资源没有 定义允许谁访问资源时,就被认为是不受限制的。
如果集群账户不受限制,则任何用户都可以使用该帐户部署新应用程序。
如果应用程序不受限制,则任何用户都可以将该应用程序部署到其他帐户中。还能看到服务器组内的基本信息,例如实例名称。
Spinnaker中的每个权限可以赋予角色,而不能是哪一个用户。
一个帐户下可以包含多个应用程序,而应用程序也可以跨越多个帐户。
授予对帐户的访问权不会同时授予对应用程序的访问权,反之亦然。
Spinnaker支持: YamlFile、GitHubTeams、GoogleGroups、LDAPGroups、SAMLGroups。
YamlFile: 使用yaml文件描述用户与角色的绑定。
LDAPGroups:将用户与其在LDAP中所属组绑定
授权(根据LDAP组进行同步)#
使用 关联 openLdap 命令方式#
与下面
yaml
方式部署 二选一
hal config security authz ldap edit \
--url 'ldap://192.168.8.1:389/dc=treesir,dc=pub' \
--manager-dn 'cn=admin,dc=treesir,dc=pub' \
--manager-password '123456' \
--user-dn-pattern 'cn={0}' \
--group-search-base 'ou=groups' \
--group-search-filter 'uniqueMember={0}' \
--group-role-attributes 'cn' \
--user-search-filter 'cn={0}'
hal config security authz edit --type ldap
hal config security authz enable
cat ~/.hal/config # 检查对应配置文件
...
authz:
groupMembership:
service: LDAP
google:
roleProviderType: GOOGLE
github:
roleProviderType: GITHUB
file:
roleProviderType: FILE
ldap:
roleProviderType: LDAP
url: ldap://192.168.8.1:389/dc=treesir,dc=pub
managerDn: cn=admin,dc=treesir,dc=pub
managerPassword: '123456'
userDnPattern: cn={0}
groupSearchBase: ou=groups
userSearchFilter: cn={0}
groupSearchFilter: uniqueMember={0}
groupRoleAttributes: cn
enabled: true
...
hal deploy apply # 执行生效
生效后,可以选择使用下面的 traefik 对 认证授权组件暴露出来,或者是使用内部ip进行访问
测试是否有生效
curl -X POST http://spin-fiat.treesir.pub/roles/sync
curl http://spin-fiat.treesir.pub/authorize/userid 2>&1|grep -A 10 roles
userid
对应用户需要在 前端页面进行登录,不然会提示接口404
使用 yaml 方式#
#使用Yaml文件
hal config security authz enable
hal config security authz file edit --file-path=$HOME/userrole.yaml
hal config security authz edit --type file
认证授权服务组件 fiat
使用 traefik 进行暴露#
cat <<EOF | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: spin-fiat
namespace: spinnaker
spec:
entryPoints:
- web
routes:
- match: Host(\`spin-fiat.treesir.pub\`) && PathPrefix(\`/\`)
kind: Rule
services:
- name: spin-fiat
port: 7003
EOF
授权管理#
现在我们有两个组,设置 ops 组只读,devops 组可以读写
kubectl exec -it spinnaker-spinnaker-halyard-0 bash -n spinnaker
hal config provider kubernetes account edit default \
--add-read-permission devops,ops \
--add-write-permission devops
# 下面这两个可以指定删除权限
--remove-read-permission
--remove-write-permission
cat ~/.hal/config # 检查配置文件
...
kubernetes:
enabled: true
accounts:
- name: default
requiredGroupMembership: []
providerVersion: V2
permissions:
READ:
- devops
WRITE:
- devops
...
hal deploy apply # 执行生效
使用 yaml
定义角色和用户#
1.首先先关闭LDAP权限。
hal config security authz disable
vi $HOME/userrole.yml
users:
- username: yangzun
roles:
- devops
- bar
- foo
- username: test
roles:
- test
- bar
- username: anonymous
roles: []
2.配置Yaml文件
hal config security authz enable
hal config security authz file edit --file-path=$HOME/userrole.yml
hal config security authz edit --type file
cat ~/.hal/config
...
authz:
groupMembership:
service: FILE
google:
roleProviderType: GOOGLE
github:
roleProviderType: GITHUB
file:
roleProviderType: FILE
path: /home/spinnaker/userrole.yml
enabled: true
...
hal deploy apply # 执行生效
创建管理员权限
vi ~/.hal/default/profiles/fiat-local.yml
fiat:
admin:
roles:
- devops-admin # 将此组 添加管理员权限
vi $HOME/userrole.yml # 用户添加进组
users:
- username: yangzun
roles:
- devops
- bar
- foo
- devops-admin # 设置使用刚添加的权限
...
hal deploy apply
关联 jenkins#
kubectl exec -it spinnaker-spinnaker-halyard-0 bash -n spinnaker
hal config ci jenkins enable
hal config ci jenkins master add jenkins-master \
--address http://ci.treesir.pub \
--username yangzun \
--password 117a723c9b729b2256e3ffc40c3d2b2156
## 启用csrf
hal config ci jenkins master edit jenkins-master --csrf true
cat ~/.hal/config
...
ci:
jenkins:
enabled: true
masters:
- name: jenkins-master
permissions: {}
address: http://ci.treesir.pub
username: yangzun
password: 117a723c9b729b2256e3ffc40c3d2b2156
csrf: true
...
hal deploy apply # 应用并生效
在 Jenkins 中安装Strict Crumb Issuer插件
全局安全设置中 开启对应参数
测试;在 spinnaker 中 新建 jenkins 类型触发 ,查看是否可以看到对应 jenkins 中的 pipeline
消息通知之邮件通知#
kubectl exec -it spinnaker-spinnaker-halyard-0 bash -n spinnaker
cd /home/spinnaker/.hal/default/profiles
cat >> settings-local.js << EOF
window.spinnakerSettings.notifications.email.enabled = true;
EOF
cat > echo-local.yml << EOF
mail:
enabled: true
from: amoaloas@163.com
spring:
mail:
host: smtp.163.com
username: amoaloas@163.com
password: FZXIQXXO
protocol: smtp
default-encoding: utf-8
properties:
mail:
display:
sendname: SpinnakerAdmin
smtp:
port: 465
auth: true
starttls:
enable: true
required: true
ssl:
enable: true
transport:
protocol: smtp
debug: true
EOF
hal deploy apply # 应用生效
更改时区#
hal config edit --timezone 'Asia/Shanghai'
hal deploy apply # 应用生效
开启制品空间#
开启http
hal config artifact http enable echo ${USERNAME}:${PASSWORD} > $USERNAME_PASSWORD_FILE hal config artifact http account add my-http-account \ --username-password-file $USERNAME_PASSWORD_FILE # 添加对应账号密码
开启特征功能#
hal config features edit --pipeline-templates true
hal config features edit --artifacts true
hal config features edit --managed-pipeline-templates-v2-ui true
开启对 pipeline 的权限管理#
~/.hal/default/profiles/orca-local.yml
tasks:
useManagedServiceAccounts: true
~/.hal/default/profiles/settings-local.js
window.spinnakerSettings.feature.managedServiceAccounts = true;
hal deploy apply # 应用生效
添加 k8s 集群#
hal config provider kubernetes enable
hal config provider kubernetes account add k3s \
--context $(kubectl config current-context --kubeconfig ~/.kube/k3s) \
--service-account true \
--omit-namespaces=kube-system,kube-public \
--kubeconfig-file ~/.kube/k3s \
--provider-version v2
hal config deploy edit --type distributed --account-name k3s
CONTEXT=$(kubectl config current-context) hal config provider kubernetes account add default \ --context $CONTEXT
添加 dokcer 镜像仓库#
hal config provider docker-registry enable --no-validate
hal config provider docker-registry account add my-harborregistry \
--address https://harbor.treesir.pub \
--username yangzun \
--password 123456
helm 部署 spinnaker 添加 集群#
kubectl get po --kubeconfig ~/.kube/k3s --all-namespaces # 测试 对应 config 文件是否有效
kubectl create secret generic --from-file=$HOME/.kube/config kube-config -n spinnaker
kubeConfig:
enabled: true
secretName: kube-config
secretKey: config
contexts:
==
- my-context
# This is the context from the list above that you would like
# to deploy Spinnaker itself to.
deploymentContext: my-context
手动启动 halyard#
部署 minio
kubectl create ns devops-minio helm repo add minio https://helm.min.io/ helm repo update cat > prod-values.yaml << EOF image: tag: RELEASE.2021-03-17T02-33-02Z accessKey: "admin" secretKey: "ancun123" persistence: existingClaim: "devops-minio-pvc" accessMode: ReadWriteOnce size: 100Gi service: type: NodePort buckets: - name: spinnaker policy: none purge: false EOF cat > devops-minio-pvPvc.yaml << EOF apiVersion: v1 kind: PersistentVolume metadata: name: devops-minio-pv spec: storageClassName: local-storage # Local PV capacity: storage: 100Gi volumeMode: Filesystem accessModes: - ReadWriteOnce local: path: /data/devops/minio nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - mn105 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: devops-minio-pvc namespace: devops-minio spec: storageClassName: local-storage accessModes: - ReadWriteOnce resources: requests: storage: 100Gi EOF mkdir -p /data/devops/minio # 创建 localPv 目录 kubectl apply -f ./devops-minio-pvPvc.yaml
docker pull gcr.io/spinnaker-marketplace/halyard:1.32.0
mkdir ~/.hal
chmod -R 777 ~/.hal
docker run -itd --name halyard \
-v /root/.hal:/home/spinnaker/.hal \
-v /root/.kube:/home/spinnaker/.kube \
--restart=always \
--net=host \
idocker.io/spinnaker-marketplace/halyard:1.32.0
docker exec -it halyard bash
hal config version edit --version 1.25.5
hal config edit --timezone Asia/Shanghai
hal config storage s3 edit \
--endpoint http://s3.treesir.pub \
--access-key-id admin \
--secret-access-key 12345678 \
--bucket spinnaker \
--path-style-access true
hal config storage edit --type s3
hal config security ui edit --override-base-url http://spinnaker.treesir.pub
hal config security api edit --override-base-url http://spin-gate.treesir.pub
hal config provider docker-registry enable
hal config provider kubernetes enable
hal config provider kubernetes account add default \
--context $(kubectl config current-context) \
--service-account true \
--omit-namespaces=kube-system,kube-public,cattle-system,cattle-prometheus \
--provider-version v2 \
--no-validate
hal config deploy edit \
--account-name default \
--type distributed \
--location spinnaker # 部署集群
hal deploy apply # 执行生效