diff --git a/k8s/portworx.yaml b/k8s/portworx.yaml index 4a196441..c3e21d0a 100644 --- a/k8s/portworx.yaml +++ b/k8s/portworx.yaml @@ -1,5 +1,4 @@ # SOURCE: https://install.portworx.com/?kbver=1.15.2&b=true&s=/dev/loop4&c=px-workshop&stork=true&lh=true&st=k8s&mc=false -# SOURCE: https://install.portworx.com/?kbver=1.15.2&b=true&s=/dev/loop4&c=px-workshop&stork=true&lh=true&st=k8s&mc=false --- kind: Service apiVersion: v1 @@ -751,3 +750,16 @@ spec: volumes: - name: config emptyDir: {} +--- +# That one is an extra. +# Create a default Storage Class to simplify Portworx setup. +kind: StorageClass +apiVersion: storage.k8s.io/v1beta1 +metadata: + name: portworx-replicated + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: kubernetes.io/portworx-volume +parameters: + repl: "2" + priority_io: "high" diff --git a/k8s/postgres.yaml b/k8s/postgres.yaml index 75ac4b8e..a9331f2a 100644 --- a/k8s/postgres.yaml +++ b/k8s/postgres.yaml @@ -12,7 +12,14 @@ spec: labels: app: postgres spec: - schedulerName: stork + #schedulerName: stork + initContainers: + - name: rmdir + image: alpine + volumeMounts: + - mountPath: /vol + name: postgres + command: ["sh", "-c", "if [ -d /vol/lost+found ]; then rmdir /vol/lost+found; fi"] containers: - name: postgres image: postgres:11 diff --git a/prepare-vms/lib/commands.sh b/prepare-vms/lib/commands.sh index ade36b6e..68904fa5 100644 --- a/prepare-vms/lib/commands.sh +++ b/prepare-vms/lib/commands.sh @@ -362,6 +362,16 @@ _cmd_opensg() { infra_opensg } +_cmd portworx "Prepare the nodes for Portworx deployment" +_cmd_portworx() { + TAG=$1 + need_tag + + pssh " + sudo truncate --size 10G /portworx.blk && + sudo losetup /dev/loop4 /portworx.blk" +} + _cmd disableaddrchecks "Disable source/destination IP address checks" _cmd_disableaddrchecks() { TAG=$1 diff --git a/slides/k8s/kubectlexpose.md b/slides/k8s/kubectlexpose.md index 0e6c5ecd..e6cc8f03 100644 --- a/slides/k8s/kubectlexpose.md +++ b/slides/k8s/kubectlexpose.md @@ -14,42 +14,80 @@ `ClusterIP`, `NodePort`, `LoadBalancer`, `ExternalName` ---- - -## Basic service types - -- `ClusterIP` (default type) - - - a virtual IP address is allocated for the service (in an internal, private range) - - this IP address is reachable only from within the cluster (nodes and pods) - - our code can connect to the service using the original port number - -- `NodePort` - - - a port is allocated for the service (by default, in the 30000-32768 range) - - that port is made available *on all our nodes* and anybody can connect to it - - our code must be changed to connect to that new port number - -These service types are always available. - -Under the hood: `kube-proxy` is using a userland proxy and a bunch of `iptables` rules. +- HTTP services can also use `Ingress` resources (more on that later) --- -## More service types +## `ClusterIP` -- `LoadBalancer` +- It's the default service type - - an external load balancer is allocated for the service - - the load balancer is configured accordingly -
(e.g.: a `NodePort` service is created, and the load balancer sends traffic to that port) - - available only when the underlying infrastructure provides some "load balancer as a service" -
(e.g. AWS, Azure, GCE, OpenStack...) +- A virtual IP address is allocated for the service -- `ExternalName` + (in an internal, private range; e.g. 10.96.0.0/12) - - the DNS entry managed by CoreDNS will just be a `CNAME` to a provided record - - no port, no IP address, no nothing else is allocated +- This IP address is reachable only from within the cluster (nodes and pods) + +- Our code can connect to the service using the original port number + +- Perfect for internal communication, within the cluster + +--- + +## `LoadBalancer` + +- An external load balancer is allocated for the service + + (typically a cloud load balancer, e.g. ELB on AWS, GLB on GCE ...) + +- This is available only when the underlying infrastructure provides some kind of + "load balancer as a service" + +- Each service of that type will typically cost a little bit of money + + (e.g. a few cents per hour on AWS or GCE) + +- Ideally, traffic would flow directly from the load balancer to the pods + +- In practice, it will often flow through a `NodePort` first + +--- + +## `NodePort` + +- A port number is allocated for the service + + (by default, in the 30000-32768 range) + +- That port is made available *on all our nodes* and anybody can connect to it + + (we can connect to any node on that port to reach the service) + +- Our code needs to be changed to connect to that new port number + +- Under the hood: `kube-proxy` sets up a bunch of `iptables` rules on our nodes + +- Sometimes, it's the only available option for external traffic + + (e.g. most clusters deployed with kubeadm or on-premises) + +--- + +class: extra-details + +## `ExternalName` + +- No load balancer (internal or external) is created + +- Only a DNS entry gets added to the DNS managed by Kubernetes + +- That DNS entry will just be a `CNAME` to a provided record + +Example: +```bash +kubectl create service externalname k8s --external-name kubernetes.io +``` +*Creates a CNAME `k8s` pointing to `kubernetes.io`* --- @@ -279,18 +317,28 @@ error: the server doesn't have a resource type "endpoint" --- -## Exposing services to the outside world +class: extra-details -- The default type (ClusterIP) only works for internal traffic +## `ExternalIP` -- If we want to accept external traffic, we can use one of these: +- When creating a servivce, we can also specify an `ExternalIP` - - NodePort (expose a service on a TCP port between 30000-32768) + (this is not a type, but an extra attribute to the service) - - LoadBalancer (provision a cloud load balancer for our service) +- It will make the service availableon this IP address - - ExternalIP (use one node's external IP address) + (if the IP address belongs to a node of the cluster) - - Ingress (a special mechanism for HTTP services) +--- -*We'll see NodePorts and Ingresses more in detail later.* +## `Ingress` + +- Ingresses are another type (kind) of resource + +- They are specifically for HTTP services + + (not TCP or UDP) + +- They can also handle TLS certificates, URL rewriting ... + +- They require an *Ingress Controller* to function diff --git a/slides/k8s/portworx.md b/slides/k8s/portworx.md index a78a5d24..ac0b7abd 100644 --- a/slides/k8s/portworx.md +++ b/slides/k8s/portworx.md @@ -240,6 +240,25 @@ If you want to use an external key/value store, add one of the following: --- +## Check our default Storage Class + +- The YAML manifest applied earlier should define a default storage class + +.exercise[ + +- Check that we have a default storage class: + ```bash + kubectl get storageclass + ``` + +] + +There should be a storage class showing as `portworx-replicated (default)`. + +--- + +class: extra-details + ## Our default Storage Class This is our Storage Class (in `k8s/storage-class.yaml`): @@ -265,28 +284,6 @@ parameters: --- -## Creating our Storage Class - -- Let's apply that YAML file! - -.exercise[ - -- Create the Storage Class: - ```bash - kubectl apply -f ~/container.training/k8s/storage-class.yaml - ``` - -- Check that it is now available: - ```bash - kubectl get sc - ``` - -] - -It should show as `portworx-replicated (default)`. - ---- - ## Our Postgres Stateful set - The next slide shows `k8s/postgres.yaml` @@ -326,7 +323,7 @@ spec: schedulerName: stork containers: - name: postgres - image: postgres:10.5 + image: postgres:11 volumeMounts: - mountPath: /var/lib/postgresql/data name: postgres