From 79052248fad591eea33a79227d72110387a5a269 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Mon, 7 Mar 2022 22:28:16 +1100 Subject: [PATCH] portainer files --- kubernetes/portainer/README.md | 124 ++++++++++++++++++ kubernetes/portainer/kind.yaml | 12 ++ .../portainer-agent-ce211-k8s-nodeport.yaml | 81 ++++++++++++ .../portainer/portainer-agent-edge-k8s.yaml | 100 ++++++++++++++ 4 files changed, 317 insertions(+) create mode 100644 kubernetes/portainer/README.md create mode 100644 kubernetes/portainer/kind.yaml create mode 100644 kubernetes/portainer/portainer-agent-ce211-k8s-nodeport.yaml create mode 100644 kubernetes/portainer/portainer-agent-edge-k8s.yaml diff --git a/kubernetes/portainer/README.md b/kubernetes/portainer/README.md new file mode 100644 index 0000000..21e02d7 --- /dev/null +++ b/kubernetes/portainer/README.md @@ -0,0 +1,124 @@ +# Introduction to Portainer + +Start here 👉🏽[https://www.portainer.io/](https://www.portainer.io/)
+Documentation 👉🏽[https://docs.portainer.io/](https://docs.portainer.io/) + +## Portainer installation + +In this demo, I will be running Kubernetes 1.22 using `kind`
+Which is compatible with portainer 2.11.1
+ +Let's go ahead with a local docker install: + +``` +cd kubernetes\portainer +mkdir volume-ce + +docker run -d -p 9443:9443 -p 8000:8000 --name portainer-ce ` +--restart=always ` +-v /var/run/docker.sock:/var/run/docker.sock ` +-v ${PWD}/volume-ce:/data ` +portainer/portainer-ce:2.11.1 +``` + +## SSL & DOMAIN + +We can also upload SSL certificates for our portainer.
+In this demo, portainer will issue self signed certificates.
+We will need a domain for our portainer server so our clusters can contact it.
+Let's use [nip.io](https://nip.io/) to create a public endpoint for portainer. + +## Create Kubernetes Cluster + +Let's start by creating a local `kind` [cluster](https://kind.sigs.k8s.io/) + +For local clusters, we can use the public endpoint Agent.
+We can get a public endpoint for the portainer agent by:
+ +* Ingress +* LoadBalancer +* NodePort + +So we'll deploy portainer agent with `NodePort` for local
+ +For production environments, I would recommend not to expose the portainer agent.
+In this case, for Production, we'll use the portainer edge agent.
+ + +To get `NodePort` exposed in `kind`, we'll open a host port with a [kind.yaml](./kind.yaml) config + +``` +kind create cluster --name local --config kind.yaml +``` + +## Manage Kubernetes Environments + +The portainer UI gives us a one line command to deploy the portainer agent.
+Note that in the video, we pick the `node port` option. + +## Local: Portainer Agent + +I download the YAML from [here](https://downloads.portainer.io/portainer-agent-ce211-k8s-nodeport.yaml) to take a closer look at what it is deploying
+ +Deploy the portainer agent in my `kind` cluster: + +``` +kubectl apply -f portainer-agent-ce211-k8s-nodeport.yaml +``` + +See the agent: + +``` +kubectl -n portainer get pods +``` + +See the service with the endpoint it exposes: + +``` +kubectl -n portainer get svc +``` + +Now since we dont have a public load balancer and using nodeport, our service will be exposed on the node IP.
+Since the Kubernetes node is our local machine, we should be able to access the portainer agent on `:30778`
+ +We can obtain our local IP with `ipconfig`
+The IP and NodePort will be used to connect our portainer server to the new agent.
+ +## Production: Portainer Edge Agent + +For the Edge agent, we get the command in the portainer UI.
+Once deployed, we can see the egde agent in our AKS cluster: + +``` +kubectl -n portainer get pods +``` + +## Helm + +Let's showcase how to deploy helm charts.
+Most folks would have helm charts for their ingress controllers, monitoring, logging and other +platform dependencies.
+ +Let's add Kubernetes NGINX Ingress repo: + +``` +https://kubernetes.github.io/ingress-nginx +``` + +## GitOps + +So from the Application menu, we can add an application from a `git` repository.
+Let's add this repo: + +``` +https://github.com/marcel-dempers/docker-development-youtube-series +``` + +We also specify all our manifests path that portainer needs to deploy: + +* kubernetes/portainer/example-application/deployment.yaml +* kubernetes/portainer/example-application/configmap.yaml +* kubernetes/portainer/example-application/service.yaml +* kubernetes/portainer/example-application/ingress.yaml + +Portainer will now poll our repo and deploy any updates, GitOps style! diff --git a/kubernetes/portainer/kind.yaml b/kubernetes/portainer/kind.yaml new file mode 100644 index 0000000..75d4b10 --- /dev/null +++ b/kubernetes/portainer/kind.yaml @@ -0,0 +1,12 @@ +apiVersion: kind.x-k8s.io/v1alpha4 +kind: Cluster +nodes: +- role: control-plane + image: kindest/node:v1.22.0@sha256:b8bda84bb3a190e6e028b1760d277454a72267a5454b57db34437c34a588d047 + extraPortMappings: + - containerPort: 30778 + hostPort: 30778 + listenAddress: "0.0.0.0" + protocol: tcp +- role: worker + image: kindest/node:v1.22.0@sha256:b8bda84bb3a190e6e028b1760d277454a72267a5454b57db34437c34a588d047 \ No newline at end of file diff --git a/kubernetes/portainer/portainer-agent-ce211-k8s-nodeport.yaml b/kubernetes/portainer/portainer-agent-ce211-k8s-nodeport.yaml new file mode 100644 index 0000000..73802a7 --- /dev/null +++ b/kubernetes/portainer/portainer-agent-ce211-k8s-nodeport.yaml @@ -0,0 +1,81 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: portainer +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: portainer-sa-clusteradmin + namespace: portainer +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: portainer-crb-clusteradmin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: portainer-sa-clusteradmin + namespace: portainer +--- +apiVersion: v1 +kind: Service +metadata: + name: portainer-agent + namespace: portainer +spec: + type: NodePort + selector: + app: portainer-agent + ports: + - name: http + protocol: TCP + port: 9001 + targetPort: 9001 + nodePort: 30778 +--- +apiVersion: v1 +kind: Service +metadata: + name: portainer-agent-headless + namespace: portainer +spec: + clusterIP: None + selector: + app: portainer-agent +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: portainer-agent + namespace: portainer +spec: + selector: + matchLabels: + app: portainer-agent + template: + metadata: + labels: + app: portainer-agent + spec: + serviceAccountName: portainer-sa-clusteradmin + containers: + - name: portainer-agent + image: portainer/agent:2.11.1 + imagePullPolicy: Always + env: + - name: LOG_LEVEL + value: DEBUG + - name: AGENT_CLUSTER_ADDR + value: "portainer-agent-headless" + - name: KUBERNETES_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + ports: + - containerPort: 9001 + protocol: TCP diff --git a/kubernetes/portainer/portainer-agent-edge-k8s.yaml b/kubernetes/portainer/portainer-agent-edge-k8s.yaml new file mode 100644 index 0000000..f1c9027 --- /dev/null +++ b/kubernetes/portainer/portainer-agent-edge-k8s.yaml @@ -0,0 +1,100 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: portainer +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: portainer-sa-clusteradmin + namespace: portainer +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: portainer-crb-clusteradmin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: portainer-sa-clusteradmin + namespace: portainer +# Optional: can be added to expose the agent port 80 to associate an Edge key. +# --- +# apiVersion: v1 +# kind: Service +# metadata: +# name: portainer-agent +# namespace: portainer +# spec: +# type: LoadBalancer +# selector: +# app: portainer-agent +# ports: +# - name: http +# protocol: TCP +# port: 80 +# targetPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: portainer-agent + namespace: portainer +spec: + clusterIP: None + selector: + app: portainer-agent +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: portainer-agent + namespace: portainer +spec: + selector: + matchLabels: + app: portainer-agent + template: + metadata: + labels: + app: portainer-agent + spec: + serviceAccountName: portainer-sa-clusteradmin + containers: + - name: portainer-agent + image: portainer/agent:2.11.1 + imagePullPolicy: Always + env: + - name: LOG_LEVEL + value: INFO + - name: KUBERNETES_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: EDGE + value: "1" + - name: AGENT_CLUSTER_ADDR + value: "portainer-agent" + - name: EDGE_ID + valueFrom: + configMapKeyRef: + name: portainer-agent-edge + key: edge.id + - name: EDGE_INSECURE_POLL + valueFrom: + configMapKeyRef: + name: portainer-agent-edge + key: edge.insecure_poll + - name: EDGE_KEY + valueFrom: + secretKeyRef: + name: portainer-agent-edge-key + key: edge.key + ports: + - containerPort: 9001 + protocol: TCP + - containerPort: 80 + protocol: TCP