diff --git a/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org b/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org index 47647fd..d52b0ee 100644 --- a/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org +++ b/structured/challenges.suse-cloud-native-fundamentals-scholarship-program.org @@ -1,6 +1,9 @@ +:PROPERTIES: +:ID: 0617c544-0d04-4a55-9d70-b8b4998fad92 +:END: #+title: Solutions to SUSE Cloud native fundamentals scholarship exercises #+date: "2021-06-08 23:23:35 +08:00" -#+date_modified: "2021-06-12 12:24:19 +08:00" +#+date_modified: "2021-06-16 18:18:39 +08:00" #+language: en @@ -333,3 +336,173 @@ While the solution gave it as user and passwords, the kubeconfig I have seem to Also, you can get the configuration of the cluster with ~kubectl config view~. Pretty handy. + + + + +* Kubernetes resources + +Now you have learned many Kubernetes recourses, in this exercise, you will deploy the following resources using the kubectl command. + +- a namespace + + name: =demo= + + label: =tier: test= +- a deployment: + + image: =nginx:alpine= + + name: =nginx-apline= + + namespace: =demo= + + replicas: =3= + + labels: =app: nginx, tag: alpine= +- a service: + + expose the above deployment on port 8111 + + namespace: =demo= +- a configmap: + + name: =nginx-version= + + containing key-value pair: =version=alpine= + + namespace: =demo= + + +** Solution + +This is practical test but it can summarized with a shell script. + +#+begin_src bash :eval no +# Create the namespace with the specified label. +kubectl create namespaces demo +kubectl label namespaces demo tier=test + +# Create the specified deployment. +kubectl create deployment nginx-alpine --image=nginx:alpine --replicas=3 --namespace=demo +kubectl label deployment nginx-alpine app=nginx tag=alpine --namespace=demo + +# Expose the deployment as a service. +kubectl expose deployment nginx-alpine --namespace=demo --port=8111 + +# Create the config map. +kubectl create configmaps nginx-version --namespace=demo --from-literal=version=alpine +#+end_src + + + + +* Declarative Kubernetes manifests + +Kubernetes is widely known for its imperative and declarative management techniques. +In the previous exercise, you have deployed the following resources using the imperative approach. +Now deploy them using the declarative approach. + +- a namespace + + name: demo + + label: tier: test +- a deployment: + + image: nginx:alpine + + name:nginx-apline + + namespace: demo + + replicas: 3 + + labels: app: nginx, tag: alpine +- a service: + + expose the above deployment on port 8111 + + namespace: demo +- a configmap: + + name: nginx-version + + containing key-value pair: version=alpine + + namespace: demo + + +** Solution + +Since they ask for 4 resources, we need 4 manifests. +We'll create four YAML manifests for this exercise. + +The following manifests are created with the option to print the resources in YAML format with some modifications. + +Here's one for the namespace. +The command used to make the template is ~kubectl create namespace demo --dry-run=client --output=yaml~. + +#+begin_src yaml +apiVersion: v1 +kind: Namespace +metadata: + creationTimestamp: null + name: demo + labels: + tier: test +spec: {} +status: {} +#+end_src + +The manifest for the deployment. +The command used to create the starting template is ~kubectl create deployment nginx-alpine --namespace=demo --replicas=3 --image=nginx:alpine --dry-run=client --output=yaml~. + +#+begin_src yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + labels: + app: nginx + tag: alpine + name: nginx-alpine + namespace: demo +spec: + replicas: 3 + selector: + matchLabels: + app: nginx-alpine + strategy: {} + template: + metadata: + creationTimestamp: null + labels: + app: nginx-alpine + spec: + containers: + - image: nginx:alpine + name: nginx + resources: {} +status: {} +#+end_src + +The service manifest should be created after the deployment manifest is applied (i.e., ~kubectl apply -f deployment.yaml~). +It is created with ~kubectl expose deploy nginx-alpine --port=8111 --dry-run=client --output=yaml --namespace=demo~. + +#+begin_src yaml +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + app: nginx + tag: alpine + name: nginx-alpine + namespace: demo +spec: + ports: + - port: 8111 + protocol: TCP + targetPort: 8111 + selector: + app: nginx-alpine +status: + loadBalancer: {} +#+end_src + +The resulting YAML output is from running the command (i.e., ~kubectl create configmap nginx-version --from-literal=version=alpine --dry-run=client --output=yaml --namespace=demo~). +No cleaning up is required. + +#+begin_src yaml +apiVersion: v1 +data: + version: alpine +kind: ConfigMap +metadata: + creationTimestamp: null + name: nginx-version + namespace: demo +#+end_src + + +** Findings after solution + +Aside from the mostly correct answers, I also found out ~kubectl get all -n demo~ to get all of the resources in the specified namespace. +Pretty handy for inspecting application-specific resources. diff --git a/structured/cli.fzf.org b/structured/cli.fzf.org index 31701a3..fc4be7f 100644 --- a/structured/cli.fzf.org +++ b/structured/cli.fzf.org @@ -3,7 +3,7 @@ :END: #+title: fzf #+date: "2021-05-31 23:08:57 +08:00" -#+date_modified: "2021-06-04 07:52:35 +08:00" +#+date_modified: "2021-06-14 22:33:37 +08:00" #+language: en @@ -64,7 +64,7 @@ function fzf-cd() { } #+end_src -Even better when you bind it with a keyboard shortcut (e.g., ~bind '"\C-f":'fzf-cd\n"'~). +Even better when you bind it with a keyboard shortcut (e.g., ~bind '"\C-f":'fzf-cd\n"'~ on your Bash config). ** Package selection in Arch Linux diff --git a/structured/cli.kubectl.org b/structured/cli.kubectl.org index 902a73e..e545c1a 100644 --- a/structured/cli.kubectl.org +++ b/structured/cli.kubectl.org @@ -3,7 +3,7 @@ :END: #+title: kubectl #+date: "2021-06-13 00:29:49 +08:00" -#+date_modified: "2021-06-14 22:48:57 +08:00" +#+date_modified: "2021-06-14 23:27:29 +08:00" #+language: en #+property: header-arg :eval no @@ -18,6 +18,10 @@ The main binary when managing [[id:9e4f04d4-00a3-4898-ac98-924957fa868b][Kuberne - =api-resource= lists all of the resources it currently supports. - =cluster-info= prints information of the cluster and the add-ons installed. - =create [RESOURCE] [NAME]= creates the specified resource with the given name. + + =--dry-run= just initiates the process and does nothing. + Useful with =-o yaml= to create a minimal manifest. + + =-o [yaml|json|wide]= prints the created resource as the specified output. + Specially useful to create manifests and manage clusters declaratively. - =describe [RESOURCE] [NAME]= prints a detailed description of the given resource. - =logs [RESOURCE] [NAME]= shows the log printed from the given resource. - =explain [RESOURCE]= prints an explaination of the given resource — e.g., ~kubectl explain pods~, ~kubectl explain rs~. @@ -26,17 +30,7 @@ The main binary when managing [[id:9e4f04d4-00a3-4898-ac98-924957fa868b][Kuberne You can also print [[https://kubernetes.io/docs/reference/kubectl/overview/#custom-columns][the columns]] you only need. - =apply= applies a manifest, that is, a configuration file. - -** Resource names - -Most of the subcommands require a resource type and a name. -You can also refer to a specific resource with =${RESOURCE}/${NAME}= — e.g., =namespace/demo=, =deploy/hello=. - -In the command line, you can refer to it like the following. - -- ~kubectl create ns/demo~ -- ~kubectl describe deploy/hello~ -- ~kubectl create pod/python-app --namespace=demo~ +When referring to a specific resource with =${RESOURCE}/${NAME}= — e.g., =namespace/demo=, =deploy/hello=. diff --git a/2020-07-10-23-30-27.org b/structured/computing.endianness.org similarity index 100% rename from 2020-07-10-23-30-27.org rename to structured/computing.endianness.org diff --git a/structured/lang.oil.org b/structured/lang.oil.org index 564905e..810a9ba 100644 --- a/structured/lang.oil.org +++ b/structured/lang.oil.org @@ -1,6 +1,6 @@ #+title: Oil shell #+date: "2021-05-09 16:40:50 +08:00" -#+date_modified: "2021-06-05 16:36:01 +08:00" +#+date_modified: "2021-06-14 22:26:24 +08:00" #+language: en #+property: header-args:oil :eval no @@ -70,7 +70,7 @@ for i in @keywords { echo "keyword: $i" } ** Strings -While strings are similar to Bash strings [fn:: Really more like Python strings.], there are subtle differences. +While strings are similar to Bash strings[fn:: Really more like Python strings.], there are subtle differences. Most notably, Bash splits the string when trying to do something. #+begin_src bash diff --git a/structured/literature.cs50x.org b/structured/literature.cs50x.org index 07d746a..44a01b9 100644 --- a/structured/literature.cs50x.org +++ b/structured/literature.cs50x.org @@ -3,7 +3,7 @@ :END: #+title: CS50x #+date: "2021-06-06 17:58:08 +08:00" -#+date_modified: "2021-06-06 20:07:35 +08:00" +#+date_modified: "2021-06-15 12:30:13 +08:00" #+language: en #+source: https://courses.edx.org/courses/course-v1:HarvardX+CS50+X/course/ @@ -35,3 +35,11 @@ I'll finish this thing for real this time. + boolean expressions are yes/no questions to a conditional, entering that branch if said condition is met + abstractions are one way of solving a problem by framing the problem one level higher, focusing on the problems without worrying on the details; we could also think abstractions as wishful thinking + + + + +* Week 1 + +- writing good code should be foremost correct +- but style is also important just like with writing requiring correct use of punctuations and grammar diff --git a/structured/literature.fundamentals-of-music-theory.org b/structured/literature.fundamentals-of-music-theory.org index 6a105ca..9145452 100644 --- a/structured/literature.fundamentals-of-music-theory.org +++ b/structured/literature.fundamentals-of-music-theory.org @@ -3,7 +3,7 @@ :END: #+title: Fundamentals of music theory #+date: "2021-04-29 18:27:29 +08:00" -#+date_modified: "2021-05-18 15:26:56 +08:00" +#+date_modified: "2021-06-16 18:40:52 +08:00" #+language: en #+source: https://www.coursera.org/learn/edinburgh-music-theory/ @@ -46,7 +46,7 @@ Keep in mind this course mainly deals with western musical concepts and notation When the distance of each note is 2 semitone, it is considered as a tone. #+ATTR_ORG: :width 550 -[[file:assets/2021-04-29-18-27-29/fds-visual-octaves-and-tones.png]] +[[file:assets/literature.fundamentals-of-music-theory/fds-visual-octaves-and-tones.png]] - an interval is two pitches with a certain distance + starting from a note, the number of tones distanced between them is the name of an interval @@ -79,7 +79,7 @@ Keep in mind this course mainly deals with western musical concepts and notation #+end_src #+results: -[[file:assets/2021-04-29-18-27-29/modes.png]] +[[file:assets/literature.fundamentals-of-music-theory/modes.png]] - chords are three or more notes played together + when played with three, it is considered a triad @@ -97,7 +97,7 @@ Keep in mind this course mainly deals with western musical concepts and notation #+end_src #+results: -[[file:assets/2021-04-29-18-27-29/chords.png]] +[[file:assets/literature.fundamentals-of-music-theory/chords.png]] @@ -114,7 +114,7 @@ Keep in mind this course mainly deals with western musical concepts and notation #+end_src #+results: -[[file:assets/2021-04-29-18-27-29/accidentals.png]] +[[file:assets/literature.fundamentals-of-music-theory/accidentals.png]] #+begin_src lilypond :file accidental-with-chords.png <> @@ -123,4 +123,4 @@ Keep in mind this course mainly deals with western musical concepts and notation #+end_src #+results: -[[file:assets/2021-04-29-18-27-29/accidental-with-chords.png]] +[[file:assets/literature.fundamentals-of-music-theory/accidental-with-chords.png]] diff --git a/structured/literature.reproducible-research-methodological-principles-for-transparent-science.org b/structured/literature.reproducible-research-methodological-principles-for-transparent-science.org index f3591ff..716c06e 100644 --- a/structured/literature.reproducible-research-methodological-principles-for-transparent-science.org +++ b/structured/literature.reproducible-research-methodological-principles-for-transparent-science.org @@ -3,9 +3,9 @@ :END: #+title: Reproducible research: methodological principles for transparent science #+date: "2020-04-12 10:24:25 +08:00" -#+date_modified: "2021-06-05 20:29:35 +08:00" +#+date_modified: "2021-06-13 14:18:21 +08:00" #+language: en -#+source :: https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/about +#+source: https://www.fun-mooc.fr/courses/course-v1:inria+41016+self-paced/about #+tags: @fleeting courses research.reproducibility diff --git a/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org b/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org index 75c3582..b7dfebf 100644 --- a/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org +++ b/structured/literature.suse-cloud-native-fundamentals-scholarship-program.org @@ -3,11 +3,12 @@ :END: #+title: SUSE Cloud native fundamentals scholarship program #+date: "2021-06-07 18:21:19 +08:00" -#+date_modified: "2021-06-13 15:59:44 +08:00" +#+date_modified: "2021-06-16 19:46:33 +08:00" #+language: en A course from Udacity with SUSE from their scholarship program. +If you're interested in the exercises for other solutions, see [[id:0617c544-0d04-4a55-9d70-b8b4998fad92][Solutions to SUSE Cloud native fundamentals scholarship exercises]]. Some things to keep in mind: @@ -91,3 +92,35 @@ Best practices for application deployment: + services + ConfigMaps handles pod configurations + namespaces provide separation of logic between different applications, that is, application context + + + + + +* Lesson 4 + +- small organizations do not often have the resources to manage their own clusters thus often use third-party providers; + while some organizations do have the resources, the scope to manage clusters often overshadow the team managing it + +- in cases like those, it make sense to use Platform-as-a-Service platforms (PaaS) + +- there are different components in a technology stack that an organization can manage: + starting from servers, storage, virtualization, operating system, runtime, data, and application + +- several providers are offering the above components and usually go into several umbrellas: + + the organization can choose no provider and instead manage their own with their own hardware, infrastructure, and all; + having an on-premises instance lets the organization full control of the whole stack but it can take a while to setup before the team can manage their deployments + + + some organizations will choose a provider that offers a infrastructure-as-a-service (IaaS) — e.g., Google Cloud Platform, Amazon Web Services — just not providing a way to manage the hardware (e.g., servers, storage) + + + others will choose platform-as-a-service (PaaS), reducing further what the organization can manage, only the application and the data + + + some providers offer functions-as-a-service (FaaS) — e.g., Amazon Lambda, Netlify Lambda — that only invokes the application on-demand + +- the point is the more the organization has full control of, the more complexity the organization has to worry about; + while they have full control over the stack, they have also to cover the full expense for managing it; + having more control also means less chances of being vendor lock-in, thus, more flexibility with more options to add and remove features into the market + +- the less components they have control over, the less complexity; + with less things to worry about, it takes less time to create prototypes and less overall expenses; + but since they delegate the tasks to a third-party provider, they are vulnerable to vendor lock-in, thus, can only move from the limitations of the platform; diff --git a/structured/tools.nix.org b/structured/tools.nix.org index abf5531..e0f0e2e 100644 --- a/structured/tools.nix.org +++ b/structured/tools.nix.org @@ -3,7 +3,7 @@ :END: #+title: The basics of Nix package manager #+date: "2021-06-05 12:34:49 +08:00" -#+date_modified: "2021-06-09 17:39:23 +08:00" +#+date_modified: "2021-06-15 10:37:05 +08:00" #+language: en @@ -70,7 +70,7 @@ let overlay = self: super: #+end_src # TODO: Bring more examples -For another example, you can see some examples from [[https://github.com/neovim/neovim/blob/f695457f815544d0dc16469569c70556e3165bb6/contrib/flake.nix][Neovim]] (which also uses Nix flakes). +For another example, you can see some examples from [[https://github.com/neovim/neovim/blob/f695457f815544d0dc16469569c70556e3165bb6/contrib/flake.nix][Neovim]] and [[https://gitlab.com/veloren/veloren/-/tree/685f4971ac0deb31b301e9d2bc0201d2531fd895/nix][Veloren]] (which also uses Nix flakes). You can set overlays automatically either by setting =nixpkgs.overlays= from your system configuration or =~/.config/nixpkgs/overlays/= folder for user-specific settings. You could also set overlays for standalone Nix code similarly through the =overlays= key — e.g., ~import ? { overlays = (self: super: { } ); };~.