#92 — GitLab + Kubernetes+Rancher

Igor Kravchenko
It_challenge
Published in
4 min readApr 19, 2019

Прикрутил кластер Kubernetes к Gitlab и настроил автоматический deploy.

Добавление любого кластера в Gitlab:

Вместо “Create a file called gitlab-admin-service-account.yaml with contents”:

kubectl apply -f https://gitlab.com/snippets/1767299/raw

Особенности добавления Rancher:

Команда для Rancher:

wget https://gist.githubusercontent.com/superseb/f6cd637a7ad556124132ca39961789a4/raw/4db7da97073ccb6049f797df1880dcd36850179e/get_kubeconfig_custom_cluster_rancher2.shsudo apt-get install jqsh get_kubeconfig_custom_cluster_rancher2.sh kubiccat kubeconfig | grep server:

у меня адрес вида: https://ip:6443 или https://ip(master):6443 кластера

Для настройки Gitlab ci выкладки использовал статью https://edenmal.moe/post/2018/GitLab-Kubernetes-Using-GitLab-CIs-Kubernetes-Cluster-feature/ — она суперская! НО, код смотрите так же в https://github.com/galexrt/presentation-gitlab-k8s, так как в статье он устаревший.

Тест переменных для ветки: features/task-1234

$ echo $CI_PROJECT_NAME
meows.front
$ echo $K8S_APP_NAME

$ echo $CI_ENVIRONMENT_NAME

$ echo $CI_ENVIRONMENT_SLUG

$ echo $CI_BUILD_REF_SLUG
features-task-1234
$ echo $CI_BUILD_REF_NAME
features/task-1234

Завтра буду донастраивать и эксперементировать.

UPD. после эксперементов

gitlab jobs:

.kubic_job: &kubic_job
image:
name: lachlanevenson/k8s-kubectl:latest
entrypoint: ["/bin/sh", "-c"]
deploy_review:
<<: *kubic_job
stage: review
only:
- branches
except:
- master
- tags
# when: manual
environment:
name: review/$CI_BUILD_REF_NAME
url: https://$CI_BUILD_REF_SLUG.meows.app
on_stop: stop_review
variables:
hostUrl: $CI_BUILD_REF_SLUG.meows.app
refApp: ${CI_BUILD_REF_SLUG}
script:
- kubectl version
- cd manifests/
- sed -i "s/__CI_BUILD_REF_SLUG__/${refApp}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__BRANCH__/${refApp}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__VERSION__/${CI_PIPELINE_ID}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__HOST__/${hostUrl}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__NAMEAPP__/${appName}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__NAMESPACE__/${appNamespace}/" daemonset.yaml ingress.yaml service.yaml
- |
if kubectl apply -f daemonset.yaml | grep -q unchanged; then
echo "=> Patching daemonset to force image update."
kubectl patch -f daemonset.yaml -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"ci-last-updated\":\"$(date +'%s')\"}}}}}"
else
echo "=> DaemonSet apply has changed the object, no need to force image update."
fi
- kubectl apply -f service.yaml || true
- kubectl apply -f ingress.yaml
- kubectl rollout status -f daemonset.yaml
- kubectl get all,ing --namespace=${appNamespace} -l app=${appName},ref=${refApp}
stop_review:
stage: review
tags:
- docker
image:
name: lachlanevenson/k8s-kubectl:latest
entrypoint: ["/bin/sh", "-c"]
variables:
GIT_STRATEGY: none
refApp: ${CI_BUILD_REF_SLUG}
when: manual
only:
- branches
except:
- master
- tags
environment:
name: review/$CI_BUILD_REF_NAME
action: stop
script:
- kubectl version
- kubectl delete ing --namespace=${appNamespace} -l app=${appName},ref=${refApp}
- kubectl delete all --namespace=${appNamespace} -l app=${appName},ref=${refApp}
deploy_prod:
<<: *kubic_job
stage: deploy
environment:
name: prod
url: https://meows.app
only:
- master
# when: manual
except:
- tags
variables:
hostUrl: meows.app
refApp: prod
script:
- kubectl version
- cd manifests/
- sed -i "s/__CI_BUILD_REF_SLUG__/${refApp}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__BRANCH__/master/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__VERSION__/${CI_PIPELINE_ID}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__HOST__/${hostUrl}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__NAMEAPP__/${appName}/" daemonset.yaml ingress.yaml service.yaml
- sed -i "s/__NAMESPACE__/${appNamespace}/" daemonset.yaml ingress.yaml service.yaml
- kubectl apply -f daemonset.yaml
- kubectl apply -f service.yaml
- kubectl apply -f ingress.yaml
- kubectl rollout status -f daemonset.yaml
- kubectl get all,ing --namespace=${appNamespace} -l app=${appName},ref=${refApp}

daemonset.yaml:

apiVersion: apps/v1beta2
kind: DaemonSet
metadata:
name: __NAMEAPP__-__CI_BUILD_REF_SLUG__
namespace: __NAMESPACE__
labels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
track: stable
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
workload.user.cattle.io/workloadselector: daemonSet-__NAMESPACE__-__NAMEAPP__
updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
track: stable
workload.user.cattle.io/workloadselector: daemonSet-__NAMESPACE__-__NAMEAPP__
spec:
imagePullSecrets:
- name: gitlab
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: host
operator: NotIn
values:
- vultr
containers:
- image: registry.gitlab.com/.../ssr:__BRANCH__-__VERSION__
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: 4000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 2
name: app
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: 4000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 2
successThreshold: 2
timeoutSeconds: 2
resources: {}
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
runAsNonRoot: false
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30

deployment.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: __NAMEAPP__-__CI_BUILD_REF_SLUG__
namespace: __NAMESPACE__
labels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
track: stable
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
track: stable
spec:
imagePullSecrets:
- name: gitlab
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: host
operator: NotIn
values:
- home
containers:
- image: registry.gitlab.com/meows.app/meows.front/ssr:__BRANCH__-__VERSION__
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: 4000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 2
name: app
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: 4000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 2
successThreshold: 2
timeoutSeconds: 2
resources: {}
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
runAsNonRoot: false
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30

ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ing-__NAMEAPP__-__CI_BUILD_REF_SLUG__
namespace: __NAMESPACE__
labels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
- __HOST__
rules:
- host: __HOST__
http:
paths:
- path: /
backend:
serviceName: __NAMEAPP__-__CI_BUILD_REF_SLUG__
servicePort: 4000

service.yaml

apiVersion: v1
kind: Service
metadata:
name: __NAMEAPP__-__CI_BUILD_REF_SLUG__
namespace: __NAMESPACE__
labels:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__
spec:
type: ClusterIP
ports:
- name: http-metrics
port: 4000
protocol: TCP
selector:
app: __NAMEAPP__
ref: __CI_BUILD_REF_SLUG__

Подписка в телеграмм: https://t.me/It_challenge

19.04.2019

--

--