Comment j'ai déployé ce blog
Ici, je vais vous expliquer comment j'ai déployé ce blog sur Kubernetes.
Introduction
Jekyll est un générateur de sites statiques qui transforme votre texte brut en superbes sites web et blogs statiques.
Il peut être utilisé pour un site de documentation, un blog, un site événementiel, ou tout autre type de site web. Rapide, sécurisé, simple et open source.
Aujourd’hui, nous allons installer et configurer Jekyll avec le thème Chirpy. Nous configurerons le site, créerons des pages en Markdown, générerons le site automatiquement grâce à GitLab-CI, et automatiserons son déploiement via Kubernetes.
Installation
Pour commencer, j’ai personnellement créé un dépôt Git dans lequel j’ai ensuite ajouté un upstream du thème Chirpy comme ceci :
1
2
git remote add upstream https://github.com/cotes2020/chirpy-starter
git fetch upstream
J’ai ensuite intégré les modifications de l’upstream en local.
1
git reset --hard upstream/main
Pour faciliter la suite, je suis passé par Docker.
1
docker run --rm -it -v $(PWD):/src --workdir=/src -p 4000:4000 ruby:3.1.7 /bin/bash
Puis installer les dépendances système :
1
2
apt update
apt install ruby-full build-essential zlib1g-dev git
Installer Jekyll et Bundler :
1
gem install jekyll bundler
Puis les dépendances Ruby :
1
bundle install
Après ça, toutes les dépendances sont installées et on peut lancer notre site en local :
1
bundle exec jekyll server -H 0.0.0.0
Par la suite il vous faut configuréer votre site avec le fichier _config.yml ici un exemple de ma Configuration.
Build
J’ai décidé de build une image OCI qui va comporter tout mon site pour faciliter son déploiement sur Kubernetes.
Voici comment j’ai fait ça via gitlab-ci.
J’y ai implémenter :
- le build via Kaniko
- le versionnement via Semantic-release
- ainsi que son déployment sur Kubernetes
Build du site
Toujours depuis mon container, on peut build son site simplement via la commande :
1
JEKYLL_ENV=production bundle exec jekyll build
Après notre site est présent dans le dossier _site
Build de l’image OCI
Le build de l’OCI lui aussi est simple je pars d’une image nginx.
j’ai juste à copier ma config nginx.conf et le dossier _site
1
2
3
4
5
6
7
8
9
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY _site /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=15s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1/health || exit 1
Puis lancer le build de celle-ci
1
docker build . -t monsite
À partir de là, tout est possible pour exposer son site. Dans mon cas, je suis passé par Kubernetes. Je prévois de revoir cette partie pour builder l’image en multi-stage dans le but de gagner un job en CI.
Déploiement
Pour le déploiment de mon site via kubernetes j’ai écrit un manifest qui comporte :
- Deployment
- service
- ingress
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
apiVersion: apps/v1
kind: Deployment
metadata:
name: axelmrv-blog
namespace: blog
spec:
selector:
matchLabels:
app: axelmrv-blog
progressDeadlineSeconds: 600
revisionHistoryLimit: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels:
app: axelmrv-blog
spec:
containers:
- name: axelmrv-blog
image: "registry.gitlab.com/axelmrv/blog-homelab:1.1.0"
imagePullPolicy: Always
resources:
requests:
cpu: 50m
memory: 64Mi
ports:
- containerPort: 80
name: http
startupProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 0
periodSeconds: 1
failureThreshold: 30
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 0
periodSeconds: 5
failureThreshold: 3
timeoutSeconds: 2
successThreshold: 1
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 0
periodSeconds: 15
failureThreshold: 3
timeoutSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: axelmrv-blog
namespace: blog
spec:
ports:
- name: web
port: 80
targetPort: 80
selector:
app: axelmrv-blog
---
apiVersion: networking.Kubernetes.io/v1
kind: Ingress
metadata:
name: axelmrv-blog
namespace: blog
annotations:
cert-manager.io/cluster-issuer: le-prod
external-dns.alpha.kubernetes.io/target: "82.67.0.129"
spec:
tls:
- hosts:
- blog.axelmrv.fr
secretName: tls-blog
rules:
- host: blog.axelmrv.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: axelmrv-blog
port:
name: web
Puis que j’ai via kubectl :
1
kubectl apply -f kubernetes/jekyll.yaml