[stage-5] improve jenkins helm chart, add scripts for jenkins pipeline

This commit is contained in:
2023-04-01 11:53:06 +07:00
parent b050b04af8
commit 6c1f175616
13 changed files with 244 additions and 43 deletions

62
jenkins/ref.jenkinsfile Normal file
View File

@@ -0,0 +1,62 @@
repository="dannecron/parcel-example-neko"
podTemplate(
label: 'app-image-builder',
cloud: 'kubernetes',
serviceAccount: 'jenkins-admin',
namespace: "ci-cd",
containers: [
containerTemplate(
name: 'builder',
image: 'moby/buildkit:v0.11.5',
ttyEnabled: true,
privileged: true
)
],
volumes: [
secretVolume(secretName: 'docker-config', mountPath: '/root/.docker')
]
) {
node('app-image-builder') {
properties([
pipelineTriggers([
[
$class: 'GenericTrigger',
genericVariables: [
[key: 'ref', value: '$.ref'],
[key: 'commit', value: '$.after']
],
printContributedVariables: true,
printPostContent: true,
regexpFilterText: '$ref',
regexpFilterExpression: '^refs/heads/.+$',
token: 'push'
]
])
])
stage('build') {
def branchName = (ref =~ /^refs\/heads\/(.+)$/)[0][1]
echo "checkout branch ${branchName}"
git credentialsId: 'github-key',
url: 'git@github.com:Dannecron/parcel-example-neko.git',
branch: branchName
container('builder') {
def tag = 'latest'
if (branchName != 'main') {
tag = "${branchName}"
}
def image="${repository}:${tag}"
echo "start building image ${image}"
sh """
buildctl build --frontend dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=${image},push=true
"""
}
}
}
}

91
jenkins/tag.jenkinsfile Normal file
View File

@@ -0,0 +1,91 @@
repository="dannecron/parcel-example-neko"
podTemplate(
label: 'app-image-builder',
cloud: 'kubernetes',
serviceAccount: 'jenkins-admin',
namespace: "ci-cd",
containers: [
containerTemplate(
name: 'builder',
image: 'moby/buildkit:v0.11.5',
ttyEnabled: true,
privileged: true
),
containerTemplate(
name: 'deployer',
image: 'alpine/k8s:1.26.3',
ttyEnabled: true,
privileged: true,
command: 'cat'
)
],
volumes: [
secretVolume(secretName: 'docker-config', mountPath: '/root/.docker')
]
) {
node('app-image-builder') {
properties([
pipelineTriggers([
[
$class: 'GenericTrigger',
genericVariables: [
[key: 'ref', value: '$.ref'],
[key: 'refType', value: '$.ref_type']
],
printContributedVariables: true,
printPostContent: true,
regexpFilterText: '$refType',
regexpFilterExpression: '^tag$',
token: 'tag'
]
])
])
stage('build') {
def tagName = "$ref"
def image="${repository}:${tagName}"
dir('app') {
echo "checkout tag ${tagName}"
// checkout scm: [
// $class: 'GitSCM',
// userRemoteConfigs: [[
// url: 'git@github.com:Dannecron/parcel-example-neko.git',
// credentialsId: 'github-key'
// ]],
// branches: [[name: "refs/tags/${tagName}"]]],
// poll: false
}
//
// container('builder') {
// dir ('app') {
// echo "start building image ${image}"
// sh """
// buildctl build --frontend dockerfile.v0 --local context=. --local dockerfile=. --output type=image,name=${image},push=true
// """
// }
// }
}
stage('deploy') {
def tagName = "$ref"
dir('infra') {
echo 'checkout infra repo'
git credentialsId: 'github-key',
url: 'git@github.com:Dannecron/netology-devops-gw-infra.git',
branch: 'main'
}
container('deployer') {
dir('infra') {
echo "start deploy with version ${tagName}"
sh """
helm --namespace=default upgrade --set 'image.tag=${tagName}' simple-app k8s/helm/simple-app
"""
}
}
}
}
}

View File

@@ -1,6 +1,6 @@
---------------------------------------------------------
Jenkins CI/CD main instance.
Deployed version {{ .Values.image.tag | default .Chart.AppVersion }}.
Deployed version {{ .Values.image.tag | default .Chart.AppVersion }} in namespace {{ .Values.namespace }}.
---------------------------------------------------------

View File

@@ -0,0 +1,6 @@
{{- define "docker_config" -}}
{{ $auth := printf "%s:%s" .Values.docker.dockerHubUser .Values.docker.dockerHubPassword }}
auths:
"https://index.docker.io/v1/":
auth: {{ $auth | b64enc }}
{{- end -}}

View File

@@ -3,7 +3,7 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Chart.Name }}-{{ .Values.environment }}-ingress
namespace: devops-tools
namespace: {{ .Values.namespace }}
annotations:
kubernetes.io/ingress.class: nginx
spec:

View File

@@ -2,4 +2,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: devops-tools
name: {{ .Values.namespace }}

View File

@@ -0,0 +1,8 @@
---
apiVersion: v1
kind: Secret
metadata:
name: docker-config
namespace: {{ .Values.namespace }}
data:
config.json: {{ include "docker_config" . | fromYaml | toJson | b64enc }}

View File

@@ -7,14 +7,12 @@ rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-admin
namespace: devops-tools
namespace: {{ .Values.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
@@ -27,4 +25,17 @@ roleRef:
subjects:
- kind: ServiceAccount
name: jenkins-admin
namespace: devops-tools
namespace: {{ .Values.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: jenkins-admin
namespace: {{ .Values.namespace }}

View File

@@ -3,7 +3,7 @@ apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}-{{ .Values.environment }}-main
namespace: devops-tools
namespace: {{ .Values.namespace }}
spec:
ports:
- name: web
@@ -16,7 +16,7 @@ apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}-{{ .Values.environment }}-main-np
namespace: devops-tools
namespace: {{ .Values.namespace }}
spec:
type: NodePort
ports:

View File

@@ -1,13 +1,14 @@
---
apiVersion: apps/v1
kind: Deployment
kind: StatefulSet
metadata:
labels:
app: {{ .Chart.Name }}-{{ .Values.environment }}-main
service: jenkins
name: {{ .Chart.Name }}-{{ .Values.environment }}-main
namespace: devops-tools
namespace: {{ .Values.namespace }}
spec:
serviceName: jenkins
replicas: 1
selector:
matchLabels:
@@ -35,10 +36,12 @@ spec:
- name: web
containerPort: 8080
- name: jnlp
containerPort: 50000
containerPort: 30000
env:
- name: JENKINS_OPTS
value: "--prefix=/jenkins"
- name: JENKINS_SLAVE_AGENT_PORT
value: '30000'
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:

View File

@@ -3,17 +3,15 @@ apiVersion: v1
kind: PersistentVolume
metadata:
name: jenkins-pv-volume
labels:
type: local
spec:
storageClassName: manual
claimRef:
name: jenkins-pv-claim
namespace: devops-tools
namespace: {{ .Values.namespace }}
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
- ReadWriteMany
hostPath:
path: /mnt/jenkins
nodeAffinity:
@@ -31,11 +29,11 @@ apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pv-claim
namespace: devops-tools
namespace: {{ .Values.namespace }}
spec:
storageClassName: local-storage
storageClassName: manual
accessModes:
- ReadWriteOnce
- ReadWriteMany
resources:
requests:
storage: 3Gi

View File

@@ -1,4 +1,5 @@
environment: production
namespace: ci-cd
image:
name: jenkins/jenkins
@@ -11,3 +12,7 @@ resources:
requests:
cpu: 500m
memory: 500Mi
docker:
dockerHubUser: user
dockerHubPassword: pass

View File

@@ -66,32 +66,49 @@ ansible-playbook -i ansible/kubectl_init kubectl_init.yml
### Деплой сервисов
* [kube-prometheus-stack](https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack)
#### Приложение
```shell
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack -f k8s/helm/kube-prometheus-stack/values.yml
```
* [приложение](https://github.com/Dannecron/parcel-example-neko)
[репозиторий](https://github.com/Dannecron/parcel-example-neko)
```shell
helm install simple-app k8s/helm/simple-app
```
или, если чарт уже задеплоен
```shell
helm upgrade simple-app k8s/helm/simple-app
```
* [atlantis](https://www.runatlantis.io)
```shell
helm upgrade -i simple-app k8s/helm/simple-app
```
```shell
helm install --set "atlantis.config.github.user=<access_token>" --set "atlantis.config.github.token=<token_secret>" --set "atlantis.config.github.secret=<webhook_secret>" atlantis k8s/helm/atlantis
```
где `<access_token>`, `<token_secret>` - это данные персонального access-токена, созданного на github,
а `<webhook_secret>` - строка, которая должна совпадать в конфигурации webhook и atlantis.
#### kube-prometheus-stack
* [jenkins](https://www.jenkins.io/)
[helm-чарт](https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack)
```shell
helm isntall jenkins k8s/helm/jenkins
```
```shell
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm upgrade -i monitoring prometheus-community/kube-prometheus-stack -f k8s/helm/kube-prometheus-stack/values.yml
```
#### Atlantis
[документация](https://www.runatlantis.io)
```shell
helm upgrade -i --set "config.github.user=<access_token>" --set "config.github.token=<token_secret>" --set "config.github.secret=<webhook_secret>" atlantis k8s/helm/atlantis
```
где `<access_token>`, `<token_secret>` - это данные персонального access-токена, созданного на github,
а `<webhook_secret>` - строка, которая должна совпадать в конфигурации webhook и atlantis.
#### Jenkins
[документация](https://www.jenkins.io/)
```shell
helm upgrade -i --set "docker.dockerHubUser=<dockerHubUser>" --set "docker.dockerHubPassword=<dockerHubPassword>" jenkins k8s/helm/jenkins
```
Необходимые плагины:
* [kubernetes](https://plugins.jenkins.io/kubernetes/)
* [generic webhook trigger](https://plugins.jenkins.io/generic-webhook-trigger/)
Необходимая конфигурация:
* Автоматически прописывать `known_hosts`
* Добавить секрет с названием `github-key` с именем пользователя и ssh-ключом к github
* Настроить облачную конфигурацию воркеров для kubernetes и убрать запуск воркеров на master-ноде
* Создать новый pipeline-проект для обработки push-эвентов по всем git-веткам со скриптом [jenkins/ref.jenkinsfile](./jenkins/ref.jenkinsfile).
* Создать новый pipeline-проект для обработки создания git-тэгов со скриптом [jenkins/tag.jenkinsfile](./jenkins/tag.jenkinsfile).