From 74fc53bb6a8858660eaf908fa7199a85dbc8b743 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Wed, 7 Jul 2021 16:34:13 +0800 Subject: [PATCH] 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. --- config.el | 4 +- .../argocd-nginx-alpine.yaml | 15 + .../helm-nginx-prod.yaml | 18 ++ .../helm-nginx-staging.yaml | 18 ++ .../helm-nginx/Chart.yaml | 5 + .../helm-nginx/templates/deployment.yaml | 29 ++ .../helm-nginx/templates/namespace.yaml | 14 + .../helm-nginx/templates/service.yaml | 17 + .../helm-nginx/values-prod.yaml | 11 + .../helm-nginx/values-staging.yaml | 11 + .../helm-nginx/values.yaml | 26 ++ ...ative-fundamentals-scholarship-program.org | 292 +++++++++++++++++- ...ative-fundamentals-scholarship-program.org | 12 +- 13 files changed, 468 insertions(+), 4 deletions(-) create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/argocd-nginx-alpine.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-prod.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-staging.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/Chart.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/deployment.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/namespace.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/service.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-prod.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-staging.yaml create mode 100644 structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values.yaml diff --git a/config.el b/config.el index 42ec6f4..5e3c246 100644 --- a/config.el +++ b/config.el @@ -18,9 +18,9 @@ (f-join my/wiki-asset-directory-name (f-base buffer-file-name)) nil)) -(defun my/concat-assets-folder (path) +(defun my/concat-assets-folder (&rest args) "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 () "A quick convenient function to create an assets folder in the wiki folder." diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/argocd-nginx-alpine.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/argocd-nginx-alpine.yaml new file mode 100644 index 0000000..158faa0 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/argocd-nginx-alpine.yaml @@ -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: {} diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-prod.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-prod.yaml new file mode 100644 index 0000000..ec9b527 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-prod.yaml @@ -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: {} diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-staging.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-staging.yaml new file mode 100644 index 0000000..8ff0a6e --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx-staging.yaml @@ -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: {} diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/Chart.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/Chart.yaml new file mode 100644 index 0000000..c096163 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +name: nginx-deployment +version: 1.0.0 +keywords: +- nginx diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/deployment.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/deployment.yaml new file mode 100644 index 0000000..1bf2871 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/deployment.yaml @@ -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 diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/namespace.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/namespace.yaml new file mode 100644 index 0000000..62d67c2 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/namespace.yaml @@ -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 }} diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/service.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/service.yaml new file mode 100644 index 0000000..96e5f15 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/templates/service.yaml @@ -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 }} diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-prod.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-prod.yaml new file mode 100644 index 0000000..05dbf08 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-prod.yaml @@ -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" diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-staging.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-staging.yaml new file mode 100644 index 0000000..1c5bde9 --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values-staging.yaml @@ -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" diff --git a/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values.yaml b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values.yaml new file mode 100644 index 0000000..12567fb --- /dev/null +++ b/structured/assets/challenges.suse-cloud-native-fundamentals-scholarship-program/helm-nginx/values.yaml @@ -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" diff --git a/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org b/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org index c1f79dd..50030c3 100644 --- a/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org +++ b/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org @@ -3,7 +3,7 @@ :END: #+title: Solutions to SUSE Cloud native fundamentals scholarship exercises #+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 @@ -618,3 +618,293 @@ kubectl get rs -n demo #+end_src 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 diff --git a/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org b/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org index 07988fe..ac80de2 100644 --- a/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org +++ b/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org @@ -3,7 +3,7 @@ :END: #+title: SUSE Cloud native fundamentals scholarship program #+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 @@ -157,3 +157,13 @@ Best practices for application deployment: + it mainly manages charts which are basically packages in a package manager + 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 + +- 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