<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.csclub.uwaterloo.ca/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=A2lianto</id>
	<title>CSCWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.csclub.uwaterloo.ca/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=A2lianto"/>
	<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/Special:Contributions/A2lianto"/>
	<updated>2026-09-14T07:42:00Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.5</generator>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Kubernetes&amp;diff=5695</id>
		<title>Kubernetes</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Kubernetes&amp;diff=5695"/>
		<updated>2026-09-11T03:26:26Z</updated>

		<summary type="html">&lt;p&gt;A2lianto: Changed user documentation to point to CSClub Wiki&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We are running a [https://kubernetes.io/ Kubernetes] cluster on top of [[CloudStack]].&lt;br /&gt;
&lt;br /&gt;
User documentation is here: [[Kubernetes User Guide]]&lt;br /&gt;
&lt;br /&gt;
== CloudStack setup ==&lt;br /&gt;
Enable the [https://docs.cloudstack.apache.org/en/latest/plugins/cloudstack-kubernetes-service.html Kubernetes plugin] from the CloudStack UI. This will require a restart of the management servers.&lt;br /&gt;
&lt;br /&gt;
We currently have one control node and 3 worker nodes. Each node is using the same Compute offering (8 CPUs, 16GB of RAM). Autoscaling is enabled, so CloudStack will automatically create more worker nodes if necessary.&lt;br /&gt;
&lt;br /&gt;
The admin kubeconfig has been installed on biloba and chamomile.&lt;br /&gt;
&lt;br /&gt;
Note that we cannot use LoadBalancers because we are basically running our own load balancer (NGINX) outside of Kubernetes which accepts external traffic. To expose services, use Ingresses or NodePorts instead.&lt;br /&gt;
&lt;br /&gt;
== NGINX Ingress ==&lt;br /&gt;
Read this first: https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters&lt;br /&gt;
&lt;br /&gt;
Then run:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/baremetal/deploy.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Get the NodePort:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n ingress-nginx get svc&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Create an upstream in /etc/nginx/nginx.conf which points to the IPs of one or more Kubernetes VMs, with the HTTP port from the NodePort.&lt;br /&gt;
Then, reload NGINX on biloba and chamomile.&lt;br /&gt;
&lt;br /&gt;
Mark the NGINX IngressClass as the default IngressClass:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl edit ingressclass nginx&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will open up Vim; add the annotation &amp;lt;code&amp;gt;ingressclass.kubernetes.io/is-default-class: &amp;quot;true&amp;quot;&amp;lt;/code&amp;gt; to the annotations section.&lt;br /&gt;
&lt;br /&gt;
Edit the global ConfigMap:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl -n ingress-nginx edit configmap ingress-nginx-controller&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Add the following to the &#039;data&#039; section:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  allow-backend-server-header: &amp;quot;true&amp;quot;&lt;br /&gt;
  use-forwarded-headers: &amp;quot;true&amp;quot;&lt;br /&gt;
  proxy-buffer-size: 128k&lt;br /&gt;
  server-snippet: |&lt;br /&gt;
    proxy_http_version 1.1;&lt;br /&gt;
    proxy_pass_header Connection;&lt;br /&gt;
    proxy_pass_header Upgrade;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CSI Driver ==&lt;br /&gt;
We are using a [https://github.com/apalia/cloudstack-csi-driver CSI driver] for PersistentVolume storage.&lt;br /&gt;
&lt;br /&gt;
Installation: &amp;lt;br&amp;gt;&lt;br /&gt;
UPDATE: don&#039;t apply the manifest directly; you&#039;ll need to download and edit it first. It seems like the labels on the control plane node changed starting from v1.24. &amp;lt;br&amp;gt;&lt;br /&gt;
After downloading the manifest, open it in an editor and change &amp;lt;code&amp;gt;node-role.kubernetes.io/master: &amp;quot;&amp;quot;&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;node-role.kubernetes.io/control-plane: &amp;quot;&amp;quot;&amp;lt;/code&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
If you already applied the manifest and need to edit it, just run &amp;lt;code&amp;gt;kubectl -n kube-system edit deployment cloudstack-csi-controller&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget https://github.com/apalia/cloudstack-csi-driver/releases/latest/download/manifest.yaml&lt;br /&gt;
# Make necessary edits&lt;br /&gt;
vim manifest.yaml&lt;br /&gt;
kubectl apply -f manifest.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To make this the default StorageClass, clone the [https://github.com/apalia/cloudstack-csi-driver repo], and edit examples/k8s/0-storageclass.yml so that it looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apiVersion: storage.k8s.io/v1&lt;br /&gt;
kind: StorageClass&lt;br /&gt;
metadata:&lt;br /&gt;
  name: cloudstack-storage&lt;br /&gt;
  annotations:&lt;br /&gt;
    storageclass.kubernetes.io/is-default-class: &amp;quot;true&amp;quot;&lt;br /&gt;
provisioner: csi.cloudstack.apache.org&lt;br /&gt;
reclaimPolicy: Delete&lt;br /&gt;
volumeBindingMode: WaitForFirstConsumer&lt;br /&gt;
allowVolumeExpansion: false&lt;br /&gt;
parameters:&lt;br /&gt;
  csi.cloudstack.apache.org/disk-offering-id: 0da1f706-fd2e-4203-8bae-1b740aef9886&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Change the disk-offering-id to the ID of the &#039;custom&#039; disk size offering in CloudStack. Apply the YAML file once you are done editing it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note&amp;lt;/b&amp;gt;: only a single writer is allowed, so do NOT use ReadWriteMany on any PersistentVolumeClaims.&lt;br /&gt;
&lt;br /&gt;
=== Testing ===&lt;br /&gt;
Create a PersistentVolumeClaim and bind it to a Pod just to make sure that everything&#039;s working:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl apply -f ./examples/k8s/pvc.yaml&lt;br /&gt;
kubectl apply -f ./examples/k8s/pod.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Run &amp;lt;code&amp;gt;kubectl get pv&amp;lt;/code&amp;gt; to make sure that a PersistentVolume was dynamically provisioned.&lt;br /&gt;
&lt;br /&gt;
Once you&#039;re done testing, delete the resources:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl delete -f ./examples/k8s/pvc.yaml&lt;br /&gt;
kubectl delete -f ./examples/k8s/pod.yaml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SSH&#039;ing into a node ==&lt;br /&gt;
If you need to SSH into one of the Kubernetes nodes, get the IP from the CloudStack UI, and run e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ssh -i /var/lib/cloudstack/management/.ssh/id_rsa core@172.19.134.149&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(Do this from biloba or chamomile.)&lt;br /&gt;
&lt;br /&gt;
== Docker shim ==&lt;br /&gt;
The original CloudStack Kubernetes ISO which we used (v1.22) used Docker as the container engine, which is no longer supported; after upgrading to v1.24, all hell broke loose because kubelet tried to use containerd instead. As a workaround, we are using [https://github.com/Mirantis/cri-dockerd cri-dockerd] on the control plane and the worker nodes. Each VM should have this in /var/lib/kubelet/kubeadm-flags.env:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KUBELET_KUBEADM_ARGS=&amp;quot;--container-runtime=remote --container-runtime-endpoint=unix:///run/cri-dockerd.sock --pod-infra-container-image=k8s.gcr.io/pause:3.7&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The solution was found [https://discuss.kubernetes.io/t/unable-to-determine-runtime-api-version-rpc-error/20736 here].&lt;br /&gt;
&lt;br /&gt;
== Enabling a feature gate ==&lt;br /&gt;
UPDATE: starting from v1.23, the PodSecurity feature gate is [https://v1-23.docs.kubernetes.io/docs/concepts/security/pod-security-admission/#enabling-the-podsecurity-admission-plugin enabled by default], so there is no need to manually enable it. The rest of this section was kept for historical purposes only.&lt;br /&gt;
&lt;br /&gt;
In v1.22, the PodSecurity feature gate is an Alpha feature and must be enabled in kube-apiserver (https://kubernetes.io/docs/concepts/security/pod-security-admission/).&lt;br /&gt;
&lt;br /&gt;
SSH into the control node, and edit /etc/kubernetes/manifests/kube-apiserver.yaml so that the &#039;command&#039; list has the following flag:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--feature-gates=PodSecurity=true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
(If the flag is already present, add the gate after a comma, e.g. &amp;lt;code&amp;gt;--feature-gates=Feature1=true,PodSecurity=true&amp;lt;/code&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
This will &amp;lt;b&amp;gt;automatically&amp;lt;/b&amp;gt; restart the kube-apiserver; wait a minute and run &amp;lt;code&amp;gt;kubectl -n kube-system get pods&amp;lt;/code&amp;gt; to check.&lt;br /&gt;
&lt;br /&gt;
== Certificates ==&lt;br /&gt;
=== Admin kubeconfig ===&lt;br /&gt;
The kubeconfig in the CloudStack UI will only last one year (as of this writing, it is expired, so don&#039;t use it). If it expires again, here&#039;s how you can renew it:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;SSH into the control plane VM (see instructions above)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Create a file called e.g. kubeadm-config.yaml with this content:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
apiVersion: kubeadm.k8s.io/v1beta3&lt;br /&gt;
kind: ClusterConfiguration&lt;br /&gt;
clusterName: &amp;quot;kubernetes&amp;quot;&lt;br /&gt;
controlPlaneEndpoint: &amp;quot;172.19.134.149:6443&amp;quot;&lt;br /&gt;
certificatesDir: &amp;quot;/etc/kubernetes/pki&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Generate a new admin kubeconfig which will last ten years:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubeadm kubeconfig user --config=kubeadm-config.yaml --client-name=kubernetes-admin --org=system:masters --validity-period=87600h0m0s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Reference: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#kubeconfig-additional-users&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Copy the output into &amp;lt;code&amp;gt;/root/.kube/config&amp;lt;/code&amp;gt; on biloba and chamomile.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kubelet certificate rotation ===&lt;br /&gt;
See https://kubernetes.io/docs/tasks/tls/certificate-rotation/.&lt;br /&gt;
&lt;br /&gt;
SSH into the control plane and make sure that &amp;lt;code&amp;gt;rotateCertificates: true&amp;lt;/code&amp;gt; is set in /var/lib/kubelet/config.yaml.&lt;br /&gt;
&lt;br /&gt;
=== What to do if the certificates expire ===&lt;br /&gt;
SSH into the control plane VM. To check the expired certs, run &amp;lt;code&amp;gt;kubeadm certs check-expiration&amp;lt;/code&amp;gt;. From biloba or chamomile, you can also run &amp;lt;code&amp;gt;kubectl -n kube-system get cm kubeadm-config -o yaml&amp;lt;/code&amp;gt; if the admin kubeconfig has not expired.&lt;br /&gt;
&lt;br /&gt;
To renew the expired certificates, run&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
kubeadm certs renew all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You now need to restart kube-apiserver, kube-controller-manager, kube-scheduler and etcd. Unfortunately I was never able to figure out how to do this. Deleting the pods doesn&#039;t seem to work. We might need to restart all of the Docker containers running on the control plane. You can check the logs of the kube-apiserver pod to see if it&#039;s still having certificate expiry issues.&lt;br /&gt;
&lt;br /&gt;
Anywho, the safe but slow option is to just restart all of the Kubernetes VMs from the CloudStack web UI.&lt;br /&gt;
&lt;br /&gt;
To be sure that everything is working again, make sure that you can create a temporary pod successfully.&lt;br /&gt;
&lt;br /&gt;
== Members ==&lt;br /&gt;
[[ceo]] manages the creation of new Kubernetes namespaces for members. See [https://git.csclub.uwaterloo.ca/public/pyceo/src/branch/master/ceod/model/KubernetesService.py here] to see how this works.&lt;br /&gt;
&lt;br /&gt;
We are also using [https://open-policy-agent.github.io/gatekeeper/website/docs/ OPA Gatekeeper] to restrict the Ingresses which members can create. See [https://git.csclub.uwaterloo.ca/cloud/manifests/src/branch/master/cscingressconstraint-template.yaml here] and [https://git.csclub.uwaterloo.ca/cloud/manifests/src/branch/master/cscingressconstraint-constraint.yaml here] for details.&lt;br /&gt;
&lt;br /&gt;
=== Certificate Signing Requests ===&lt;br /&gt;
We&#039;re going to set the max. CSR signing duration to 10 years so that members don&#039;t have to worry about their kubeconfig cert expiring (at least, not for a long time).&lt;br /&gt;
&lt;br /&gt;
SSH into the control node and edit /etc/kubernetes/manifests/kube-controller-manager.yaml so that it has the following CLI flag:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--cluster-signing-duration=87600h&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The controller will automatically restart after you save and close the file.&lt;/div&gt;</summary>
		<author><name>A2lianto</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Kubernetes_User_Guide&amp;diff=5694</id>
		<title>Kubernetes User Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Kubernetes_User_Guide&amp;diff=5694"/>
		<updated>2026-09-11T03:24:47Z</updated>

		<summary type="html">&lt;p&gt;A2lianto: removed &amp;quot;template:info&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Kubernetes =&lt;br /&gt;
We are running a [https://kubernetes.io/ Kubernetes] cluster on-prem on Tahini and Teriyaki servers. Each member gets their own namespace in which they can deploy their applications.&lt;br /&gt;
&lt;br /&gt;
== Account resource limits ==&lt;br /&gt;
As of August 23, 2026, the per-namespace resource limits for each member are:&lt;br /&gt;
&lt;br /&gt;
* 40 pods&lt;br /&gt;
* 10 jobs&lt;br /&gt;
* 10 cron jobs&lt;br /&gt;
* 25 GB of Persistent Volume Claims&lt;br /&gt;
* 5 NodePort services&lt;br /&gt;
&lt;br /&gt;
If you wish to acquire more resources, please send an email to the Systems Committee with a brief justification.&lt;br /&gt;
&lt;br /&gt;
== Create a new namespace ==&lt;br /&gt;
Log into a general-use machine and run the following:&amp;lt;pre&amp;gt;&lt;br /&gt;
ceo k8s account activate&lt;br /&gt;
&amp;lt;/pre&amp;gt;This will create a new Kubernetes namespace with the name &amp;lt;code&amp;gt;csc-username&amp;lt;/code&amp;gt;. A new kubeconfig file will be placed into &amp;lt;code&amp;gt;~/.kube/config&amp;lt;/code&amp;gt;. Your kubeconfig points at your namespace by default, so all commands you run will land there unless you specify otherwise.&lt;br /&gt;
&lt;br /&gt;
To verify that everything is working, run:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl cluster-info&lt;br /&gt;
&amp;lt;/pre&amp;gt;The output should look something like this:&amp;lt;pre&amp;gt;&lt;br /&gt;
Kubernetes control plane is running at https://129.97.134.5:6443&lt;br /&gt;
CoreDNS is running at https://129.97.134.5:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Quickstart ==&lt;br /&gt;
Say you have a Dockerized app and the image is available on a public registry such as [https://hub.docker.com/ Docker Hub] or [https://quay.io/ Quay.io]. Here is the minimum you need to get your app running in the cluster.&lt;br /&gt;
&lt;br /&gt;
First, create a Deployment:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl create deployment demo --image=ctdalek/myapp --port=80&lt;br /&gt;
&amp;lt;/pre&amp;gt;Replace &amp;lt;code&amp;gt;--image&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--port&amp;lt;/code&amp;gt; as needed.&lt;br /&gt;
&lt;br /&gt;
If your app does not need to be publicly accessible, you are done. Otherwise, create a Service to expose your Deployment:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl expose deployment demo&lt;br /&gt;
&amp;lt;/pre&amp;gt;Then create an Ingress to expose the Service to the outside world:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl create ingress demo --rule=&#039;ctdalek.k8s.csclub.cloud/*=demo:80&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;Your app will be accessible at &amp;lt;code&amp;gt;https://ctdalek.k8s.csclub.cloud&amp;lt;/code&amp;gt;. If you wish to use a custom domain, please contact the Systems Committee.&lt;br /&gt;
&lt;br /&gt;
For non-web apps, use a NodePort instead of an Ingress. NodePorts are only accessible from on-campus.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
Kubernetes is well documented, so we will not repeat it here:&lt;br /&gt;
&lt;br /&gt;
* [https://kubernetes.io/docs/home/ Kubernetes documentation]&lt;br /&gt;
* [https://kubernetes.io/docs/tutorials/ Kubernetes tutorials]&lt;br /&gt;
* [https://kubectl.docs.kubernetes.io/guides/ kubectl guides]&lt;br /&gt;
&lt;br /&gt;
You may also contact the [mailto:syscom@csclub.uwaterloo.ca Systems Committee] if something is not working the way you expect.&lt;/div&gt;</summary>
		<author><name>A2lianto</name></author>
	</entry>
	<entry>
		<id>https://wiki.csclub.uwaterloo.ca/index.php?title=Kubernetes_User_Guide&amp;diff=5693</id>
		<title>Kubernetes User Guide</title>
		<link rel="alternate" type="text/html" href="https://wiki.csclub.uwaterloo.ca/index.php?title=Kubernetes_User_Guide&amp;diff=5693"/>
		<updated>2026-09-11T03:24:17Z</updated>

		<summary type="html">&lt;p&gt;A2lianto: Created Kubernetes User Guide for new k3s cluster&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Kubernetes =&lt;br /&gt;
We are running a [https://kubernetes.io/ Kubernetes] cluster on-prem on Tahini and Teriyaki servers. Each member gets their own namespace in which they can deploy their applications.&lt;br /&gt;
&lt;br /&gt;
{{Info|If you wish to learn about how to operate a Kubernetes cluster, you may create your own cluster using software such as [https://k3s.io/ k3s]. If all you want to do is run some containerized apps, then we suggest that you use our cluster instead, since it has far more resources.}}&lt;br /&gt;
&lt;br /&gt;
== Account resource limits ==&lt;br /&gt;
As of August 23, 2026, the per-namespace resource limits for each member are:&lt;br /&gt;
&lt;br /&gt;
* 40 pods&lt;br /&gt;
* 10 jobs&lt;br /&gt;
* 10 cron jobs&lt;br /&gt;
* 25 GB of Persistent Volume Claims&lt;br /&gt;
* 5 NodePort services&lt;br /&gt;
&lt;br /&gt;
If you wish to acquire more resources, please send an email to the Systems Committee with a brief justification.&lt;br /&gt;
&lt;br /&gt;
{{Info|LoadBalancer services are disabled because we handle external traffic through Traefik, which we manage ourselves. See [[#Exposing your app|Exposing your app]] below.}}&lt;br /&gt;
&lt;br /&gt;
== Create a new namespace ==&lt;br /&gt;
Log into a general-use machine and run the following:&amp;lt;pre&amp;gt;&lt;br /&gt;
ceo k8s account activate&lt;br /&gt;
&amp;lt;/pre&amp;gt;This will create a new Kubernetes namespace with the name &amp;lt;code&amp;gt;csc-username&amp;lt;/code&amp;gt;. A new kubeconfig file will be placed into &amp;lt;code&amp;gt;~/.kube/config&amp;lt;/code&amp;gt;. Your kubeconfig points at your namespace by default, so all commands you run will land there unless you specify otherwise.&lt;br /&gt;
&lt;br /&gt;
To verify that everything is working, run:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl cluster-info&lt;br /&gt;
&amp;lt;/pre&amp;gt;The output should look something like this:&amp;lt;pre&amp;gt;&lt;br /&gt;
Kubernetes control plane is running at https://129.97.134.5:6443&lt;br /&gt;
CoreDNS is running at https://129.97.134.5:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Quickstart ==&lt;br /&gt;
Say you have a Dockerized app and the image is available on a public registry such as [https://hub.docker.com/ Docker Hub] or [https://quay.io/ Quay.io]. Here is the minimum you need to get your app running in the cluster.&lt;br /&gt;
&lt;br /&gt;
First, create a Deployment:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl create deployment demo --image=ctdalek/myapp --port=80&lt;br /&gt;
&amp;lt;/pre&amp;gt;Replace &amp;lt;code&amp;gt;--image&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--port&amp;lt;/code&amp;gt; as needed.&lt;br /&gt;
&lt;br /&gt;
If your app does not need to be publicly accessible, you are done. Otherwise, create a Service to expose your Deployment:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl expose deployment demo&lt;br /&gt;
&amp;lt;/pre&amp;gt;Then create an Ingress to expose the Service to the outside world:&amp;lt;pre&amp;gt;&lt;br /&gt;
kubectl create ingress demo --rule=&#039;ctdalek.k8s.csclub.cloud/*=demo:80&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;Your app will be accessible at &amp;lt;code&amp;gt;https://ctdalek.k8s.csclub.cloud&amp;lt;/code&amp;gt;. If you wish to use a custom domain, please contact the Systems Committee.&lt;br /&gt;
&lt;br /&gt;
For non-web apps, use a NodePort instead of an Ingress. NodePorts are only accessible from on-campus.&lt;br /&gt;
&lt;br /&gt;
== Further reading ==&lt;br /&gt;
Kubernetes is well documented, so we will not repeat it here:&lt;br /&gt;
&lt;br /&gt;
* [https://kubernetes.io/docs/home/ Kubernetes documentation]&lt;br /&gt;
* [https://kubernetes.io/docs/tutorials/ Kubernetes tutorials]&lt;br /&gt;
* [https://kubectl.docs.kubernetes.io/guides/ kubectl guides]&lt;br /&gt;
&lt;br /&gt;
You may also contact the [mailto:syscom@csclub.uwaterloo.ca Systems Committee] if something is not working the way you expect.&lt;/div&gt;</summary>
		<author><name>A2lianto</name></author>
	</entry>
</feed>