mirror of
https://github.com/foo-dogsquared/wiki.git
synced 2025-02-07 09:18:59 +00:00
Update SUSE Cloud Native Computing course
Hoorah! Finally made it through the course! On the other hand, I also updated the `concat-asset-folder` function to accept multiple arguments representing the directory hierarchy instead of a separator.
This commit is contained in:
parent
83f047f8d4
commit
74fc53bb6a
@ -18,9 +18,9 @@
|
|||||||
(f-join my/wiki-asset-directory-name (f-base buffer-file-name))
|
(f-join my/wiki-asset-directory-name (f-base buffer-file-name))
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defun my/concat-assets-folder (path)
|
(defun my/concat-assets-folder (&rest args)
|
||||||
"Concatenate PATH to the assets folder."
|
"Concatenate PATH to the assets folder."
|
||||||
(f-join (my/get-assets-folder) path))
|
(apply #'f-join (my/get-assets-folder) args))
|
||||||
|
|
||||||
(defun my/create-assets-folder ()
|
(defun my/create-assets-folder ()
|
||||||
"A quick convenient function to create an assets folder in the wiki folder."
|
"A quick convenient function to create an assets folder in the wiki folder."
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: ngnix-alpine
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
destination:
|
||||||
|
namespace: default
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
path: exercises/manifests
|
||||||
|
repoURL: https://github.com/udacity/nd064_course_1
|
||||||
|
targetRevision: HEAD
|
||||||
|
syncPolicy: {}
|
@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: nginx-prod
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
destination:
|
||||||
|
namespace: default
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- values-prod.yaml
|
||||||
|
path: structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx
|
||||||
|
repoURL: https://github.com/foo-dogsquared/wiki
|
||||||
|
targetRevision: HEAD
|
||||||
|
syncPolicy: {}
|
@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: nginx-staging
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
destination:
|
||||||
|
namespace: default
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- values-staging.yaml
|
||||||
|
path: structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx
|
||||||
|
repoURL: https://github.com/foo-dogsquared/wiki
|
||||||
|
targetRevision: HEAD
|
||||||
|
syncPolicy: {}
|
@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
name: nginx-deployment
|
||||||
|
version: 1.0.0
|
||||||
|
keywords:
|
||||||
|
- nginx
|
@ -0,0 +1,29 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
name: nginx-alpine
|
||||||
|
namespace: {{ .Values.namespace.name }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 25%
|
||||||
|
maxUnavailable: 25%
|
||||||
|
type: RollingUpdate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
name: nginx-alpine
|
@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
data:
|
||||||
|
{{ .Values.configmap.data }}
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: nginx-version
|
||||||
|
namespace: {{ .Values.namespace.name }}
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
tier: test
|
||||||
|
name: {{ .Values.namespace.name }}
|
@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
name: nginx-alpine
|
||||||
|
namespace: {{ .Values.namespace.name }}
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: {{ .Values.service.port }}
|
||||||
|
selector:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
type: {{ .Values.service.type }}
|
@ -0,0 +1,11 @@
|
|||||||
|
namespace:
|
||||||
|
name: prod
|
||||||
|
replicaCount: 2
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: 1.17.0
|
||||||
|
resources:
|
||||||
|
cpu: 70m
|
||||||
|
memory: 256Mi
|
||||||
|
configmap:
|
||||||
|
data: "version: 1.17.0"
|
@ -0,0 +1,11 @@
|
|||||||
|
namespace:
|
||||||
|
name: staging
|
||||||
|
replicaCount: 1
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: 1.18.0
|
||||||
|
resources:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 128Mi
|
||||||
|
configmap:
|
||||||
|
data: "version: 1.18.0"
|
@ -0,0 +1,26 @@
|
|||||||
|
# namespace refers to the Kubernetes namespace resource.
|
||||||
|
namespace:
|
||||||
|
name: demo
|
||||||
|
|
||||||
|
# replicaCount is the number of instances to run in a replica set.
|
||||||
|
replicaCount: 3
|
||||||
|
|
||||||
|
# image contains the detail of the container image to be used
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: alpine
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
# resources dictate the amount to spend
|
||||||
|
resources:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 256Mi
|
||||||
|
|
||||||
|
# service configures the Kubernetes service resource
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8111
|
||||||
|
|
||||||
|
# configmap configures the Kubernetes configmap resource
|
||||||
|
configmap:
|
||||||
|
data: "version: alpine"
|
@ -3,7 +3,7 @@
|
|||||||
:END:
|
:END:
|
||||||
#+title: Solutions to SUSE Cloud native fundamentals scholarship exercises
|
#+title: Solutions to SUSE Cloud native fundamentals scholarship exercises
|
||||||
#+date: "2021-06-08 23:23:35 +08:00"
|
#+date: "2021-06-08 23:23:35 +08:00"
|
||||||
#+date_modified: "2021-07-02 16:48:37 +08:00"
|
#+date_modified: "2021-07-07 16:33:05 +08:00"
|
||||||
#+language: en
|
#+language: en
|
||||||
|
|
||||||
|
|
||||||
@ -618,3 +618,293 @@ kubectl get rs -n demo
|
|||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
You should see them up and running.
|
You should see them up and running.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* Configuration managers
|
||||||
|
|
||||||
|
Using the manifests provided in the course repository, create a helm chart (Chart.yaml, templates, values.yaml) that will template the following parameters:
|
||||||
|
|
||||||
|
- namespace name
|
||||||
|
- replica count
|
||||||
|
- image:
|
||||||
|
+ name
|
||||||
|
+ tag
|
||||||
|
+ pull policy
|
||||||
|
- resources
|
||||||
|
+ requests for CPU and memory
|
||||||
|
- service
|
||||||
|
+ port
|
||||||
|
+ type (e.g. ClusterIP)
|
||||||
|
- configmap data (e.g. the key-value pair)
|
||||||
|
|
||||||
|
The chart details should be as following:
|
||||||
|
|
||||||
|
- name: nginx-deployment
|
||||||
|
- version: 1.0.0
|
||||||
|
- keywords: nginx
|
||||||
|
|
||||||
|
Once the Helm chart is available make sure that a default values.yaml file is available. This values file will be used as a default input file for the Helm chart. The values.yaml file should have the following specification:
|
||||||
|
|
||||||
|
- values.yaml
|
||||||
|
+ namespace name: demo
|
||||||
|
+ replica count: 3
|
||||||
|
+ image repository: nginx
|
||||||
|
+ image tag: alpine
|
||||||
|
+ image pull policy: IfNotPresent
|
||||||
|
+ resources: CPU 50m and memory 256Mi
|
||||||
|
+ service type: ClusterIP
|
||||||
|
+ service port: 8111
|
||||||
|
+ configmap data: "version: alpine"
|
||||||
|
|
||||||
|
Next, create 2 values files with the following specifications:
|
||||||
|
|
||||||
|
- values-staging.yaml
|
||||||
|
+ namespace name: staging
|
||||||
|
+ replica count: 1
|
||||||
|
+ image repository: nginx
|
||||||
|
+ image tag: 1.18.0
|
||||||
|
+ resources: CPU 50m and memory 128Mi
|
||||||
|
+ configmap data: "version: 1.18.0"
|
||||||
|
|
||||||
|
- values-prod.yaml
|
||||||
|
+ namespace name: prod
|
||||||
|
+ replica count: 2
|
||||||
|
+ image repository: nginx
|
||||||
|
+ image tag: 1.17.0
|
||||||
|
+ resources: CPU 70m and memory 256Mi
|
||||||
|
+ service port: 80
|
||||||
|
+ configmap data: "version: 1.17.0"
|
||||||
|
|
||||||
|
Finally, using the values files above (values-prod, values-staging), create 2 ArgoCD application, nginx-staging and nginx-prod respectively. These should deploy the nginx Helm Chart referencing each input values files.
|
||||||
|
|
||||||
|
|
||||||
|
** Solution
|
||||||
|
|
||||||
|
With the given manifests, we'll have to create a Helm package (or a Chart).
|
||||||
|
Here's what the file structure of the chart.
|
||||||
|
|
||||||
|
#+begin_src
|
||||||
|
helm-nginx
|
||||||
|
├── templates
|
||||||
|
│ ├── configmap.yaml
|
||||||
|
│ ├── deployment.yaml
|
||||||
|
│ ├── namespace.yaml
|
||||||
|
│ └── service.yaml
|
||||||
|
├── Chart.yaml
|
||||||
|
├── values.yaml
|
||||||
|
├── values-prod.yaml
|
||||||
|
└── values-staging.yaml
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
The chart definition is the following file.
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "Chart.yaml")
|
||||||
|
apiVersion: v1
|
||||||
|
name: nginx-deployment
|
||||||
|
version: 1.0.0
|
||||||
|
keywords:
|
||||||
|
- nginx
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
With the chart definition, we move on to the values to be used in the templates.
|
||||||
|
It's up to you how to structure the data but here's my solution on it.
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "values.yaml")
|
||||||
|
# namespace refers to the Kubernetes namespace resource.
|
||||||
|
namespace:
|
||||||
|
name: demo
|
||||||
|
|
||||||
|
# replicaCount is the number of instances to run in a replica set.
|
||||||
|
replicaCount: 3
|
||||||
|
|
||||||
|
# image contains the detail of the container image to be used
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: alpine
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
# resources dictate the amount to spend
|
||||||
|
resources:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 256Mi
|
||||||
|
|
||||||
|
# service configures the Kubernetes service resource
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 8111
|
||||||
|
|
||||||
|
# configmap configures the Kubernetes configmap resource
|
||||||
|
configmap:
|
||||||
|
data: "version: alpine"
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
As for different versions of the values such as...
|
||||||
|
|
||||||
|
...for development version (=values-staging.yaml=)...
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "values-staging.yaml")
|
||||||
|
namespace:
|
||||||
|
name: staging
|
||||||
|
replicaCount: 1
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: 1.18.0
|
||||||
|
resources:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 128Mi
|
||||||
|
configmap:
|
||||||
|
data: "version: 1.18.0"
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
...and for production (=values-prod.yaml=).
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "values-prod.yaml")
|
||||||
|
namespace:
|
||||||
|
name: prod
|
||||||
|
replicaCount: 2
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: 1.17.0
|
||||||
|
resources:
|
||||||
|
cpu: 70m
|
||||||
|
memory: 256Mi
|
||||||
|
configmap:
|
||||||
|
data: "version: 1.17.0"
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
With the templates, it is already given to us from the course exercise repo.
|
||||||
|
We just have to parameterize some of the values from the value file.
|
||||||
|
|
||||||
|
Here's one for the configmap...
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "templates" "namespace.yaml")
|
||||||
|
apiVersion: v1
|
||||||
|
data:
|
||||||
|
{{ .Values.configmap.data }}
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: nginx-version
|
||||||
|
namespace: {{ .Values.namespace.name }}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
..., deployment...
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "templates" "deployment.yaml")
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
name: nginx-alpine
|
||||||
|
namespace: {{ .Values.namespace.name }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 25%
|
||||||
|
maxUnavailable: 25%
|
||||||
|
type: RollingUpdate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
name: nginx-alpine
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
..., namespace...
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "templates" "namespace.yaml")
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
tier: test
|
||||||
|
name: {{ .Values.namespace.name }}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
..., and service.
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx" "templates" "service.yaml")
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
name: nginx-alpine
|
||||||
|
namespace: {{ .Values.namespace.name }}
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: {{ .Values.service.port }}
|
||||||
|
selector:
|
||||||
|
app: nginx
|
||||||
|
tag: alpine
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
To deploy it in ArgoCD, we'll just have to specify it in the ArgoCD manifest.
|
||||||
|
Since ArgoCD is heavily a GitOps tool, we have to put the files in a Git repo.
|
||||||
|
For now, let's assume the course repo as ours. [fn:: Be sure to be honest to compare with the solutions from the repo.]
|
||||||
|
Just change the Git repo URL and the path if you have your own version.
|
||||||
|
|
||||||
|
Additionally, the exercise requires to deploy two ArgoCD applications: one for staging (i.e., =nginx-staging=) and production version (i.e., =nginx-prod=) of the app.
|
||||||
|
|
||||||
|
Here's one for the production version...
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx-prod.yaml")
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: nginx-prod
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
destination:
|
||||||
|
namespace: default
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- values-prod.yaml
|
||||||
|
path: structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx
|
||||||
|
repoURL: https://github.com/foo-dogsquared/wiki
|
||||||
|
targetRevision: HEAD
|
||||||
|
syncPolicy: {}
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
...and the development version.
|
||||||
|
|
||||||
|
#+begin_src yaml :tangle (my/concat-assets-folder "helm-nginx-staging.yaml")
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: nginx-staging
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
destination:
|
||||||
|
namespace: default
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- values-staging.yaml
|
||||||
|
path: structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx
|
||||||
|
repoURL: https://github.com/foo-dogsquared/wiki
|
||||||
|
targetRevision: HEAD
|
||||||
|
syncPolicy: {}
|
||||||
|
#+end_src
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
:END:
|
:END:
|
||||||
#+title: SUSE Cloud native fundamentals scholarship program
|
#+title: SUSE Cloud native fundamentals scholarship program
|
||||||
#+date: "2021-06-07 18:21:19 +08:00"
|
#+date: "2021-06-07 18:21:19 +08:00"
|
||||||
#+date_modified: "2021-07-02 18:58:12 +08:00"
|
#+date_modified: "2021-07-07 15:53:36 +08:00"
|
||||||
#+language: en
|
#+language: en
|
||||||
|
|
||||||
|
|
||||||
@ -157,3 +157,13 @@ Best practices for application deployment:
|
|||||||
+ it mainly manages charts which are basically packages in a package manager
|
+ it mainly manages charts which are basically packages in a package manager
|
||||||
+ a chart contains parameterized values which is mainly done through Go templates
|
+ a chart contains parameterized values which is mainly done through Go templates
|
||||||
+ Helm recognizes a chart with the =Chart.yaml= file that contains metadata about the deployment
|
+ Helm recognizes a chart with the =Chart.yaml= file that contains metadata about the deployment
|
||||||
|
|
||||||
|
- ArgoCD can accept multiple sources including Helm, making it easy to integrate Helm into it
|
||||||
|
|
||||||
|
- CI/CD tools can be categorized based on the push/pull methodology
|
||||||
|
+ traditionally, CI/CD platforms are push, delivering updates once changes have been pushed into the repository;
|
||||||
|
the changes will also be pushed to the CD where it will create new clusters;
|
||||||
|
while it makes update flow from new version easier, it also requires more resources and more awareness as it has more chance of a disruption, requiring more resources;
|
||||||
|
on the other hand, this makes versioning easier making it easier to debug and analyze
|
||||||
|
+ pull-based CI/CD platforms is mostly similar except it will detect changes and apply them to the cluster;
|
||||||
|
while this is easier to apply new changes, it also makes it harder to analyze for future improvements
|
||||||
|
Loading…
Reference in New Issue
Block a user