Skip to content
93 changes: 93 additions & 0 deletions deploy/manifests/agent/ee/portainer-ee213-agent-edge-k8s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
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.12.0
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_KEY
valueFrom:
secretKeyRef:
name: portainer-agent-edge-key
key: edge.key
envFrom:
- configMapRef:
name: portainer-agent-edge
ports:
- containerPort: 9001
protocol: TCP
- containerPort: 80
protocol: TCP
107 changes: 107 additions & 0 deletions deploy/manifests/agent/ee/portainer-ee213-edge-agent-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env bash

# Script used to deploy the Portainer Edge agent inside a Kubernetes cluster.

# Requires:
# curl
# kubectl

### COLOR OUTPUT ###

ESeq="\x1b["
RCol="$ESeq"'0m' # Text Reset

# Regular Bold Underline High Intensity BoldHigh Intens Background High Intensity Backgrounds
Bla="$ESeq"'0;30m'; BBla="$ESeq"'1;30m'; UBla="$ESeq"'4;30m'; IBla="$ESeq"'0;90m'; BIBla="$ESeq"'1;90m'; On_Bla="$ESeq"'40m'; On_IBla="$ESeq"'0;100m';
Red="$ESeq"'0;31m'; BRed="$ESeq"'1;31m'; URed="$ESeq"'4;31m'; IRed="$ESeq"'0;91m'; BIRed="$ESeq"'1;91m'; On_Red="$ESeq"'41m'; On_IRed="$ESeq"'0;101m';
Gre="$ESeq"'0;32m'; BGre="$ESeq"'1;32m'; UGre="$ESeq"'4;32m'; IGre="$ESeq"'0;92m'; BIGre="$ESeq"'1;92m'; On_Gre="$ESeq"'42m'; On_IGre="$ESeq"'0;102m';
Yel="$ESeq"'0;33m'; BYel="$ESeq"'1;33m'; UYel="$ESeq"'4;33m'; IYel="$ESeq"'0;93m'; BIYel="$ESeq"'1;93m'; On_Yel="$ESeq"'43m'; On_IYel="$ESeq"'0;103m';
Blu="$ESeq"'0;34m'; BBlu="$ESeq"'1;34m'; UBlu="$ESeq"'4;34m'; IBlu="$ESeq"'0;94m'; BIBlu="$ESeq"'1;94m'; On_Blu="$ESeq"'44m'; On_IBlu="$ESeq"'0;104m';
Pur="$ESeq"'0;35m'; BPur="$ESeq"'1;35m'; UPur="$ESeq"'4;35m'; IPur="$ESeq"'0;95m'; BIPur="$ESeq"'1;95m'; On_Pur="$ESeq"'45m'; On_IPur="$ESeq"'0;105m';
Cya="$ESeq"'0;36m'; BCya="$ESeq"'1;36m'; UCya="$ESeq"'4;36m'; ICya="$ESeq"'0;96m'; BICya="$ESeq"'1;96m'; On_Cya="$ESeq"'46m'; On_ICya="$ESeq"'0;106m';
Whi="$ESeq"'0;37m'; BWhi="$ESeq"'1;37m'; UWhi="$ESeq"'4;37m'; IWhi="$ESeq"'0;97m'; BIWhi="$ESeq"'1;97m'; On_Whi="$ESeq"'47m'; On_IWhi="$ESeq"'0;107m';

printSection() {
echo -e "${BIYel}>>>> ${BIWhi}${1}${RCol}"
}

info() {
echo -e "${BIWhi}${1}${RCol}"
}

success() {
echo -e "${BIGre}${1}${RCol}"
}

error() {
echo -e "${BIRed}${1}${RCol}"
}

errorAndExit() {
echo -e "${BIRed}${1}${RCol}"
exit 1
}

### !COLOR OUTPUT ###

parseEnvVars() {
envs=""
local ENV_SOURCE=$1
IFS="," read -r -a env_array <<< "$ENV_SOURCE"
for env in "${env_array[@]}"
do
IFS="=" read -r -a env_pair <<< "$env"
local key="${env_pair[0]}"
local value="${env_pair[1]:-$(eval "echo \$$key")}"
envs="$envs --from-literal=$key=$value"
done
echo "$envs"
}

main() {
if [[ $# -lt 2 ]]; then
error "Not enough arguments"
error "Usage: ${0} <EDGE_ID> <EDGE_KEY> <EDGE_INSECURE_POLL> <EDGE_SECRET:optional>"
exit 1
fi

local EDGE_ID="$1"
local EDGE_KEY="$2"
local EDGE_INSECURE_POLL="$3"
local EDGE_SECRET="$4"
local ENV_SOURCE="$5"

[[ "$(command -v curl)" ]] || errorAndExit "Unable to find curl binary. Please ensure curl is installed before running this script."
[[ "$(command -v kubectl)" ]] || errorAndExit "Unable to find kubectl binary. Please ensure kubectl is installed before running this script."

info "Downloading agent manifest..."
curl -L https://downloads.portainer.io/קe213/portainer-agent-edge-k8s.yaml -o portainer-agent-edge-k8s.yaml || errorAndExit "Unable to download agent manifest"

info "Creating Portainer namespace..."
kubectl create namespace portainer

info "Creating agent configuration..."
configmapCmd="kubectl create configmap -n portainer portainer-agent-edge"
configmapCmd+=" --from-literal="EDGE_ID=$EDGE_ID""
configmapCmd+=" --from-literal="EDGE_INSECURE_POLL=$EDGE_INSECURE_POLL""
if [ -n "$EDGE_SECRET" ]; then
configmapCmd+=" --from-literal="EDGE_SECRET=$EDGE_SECRET""
fi

if [[ -n "$ENV_SOURCE" ]]; then
configmapCmd="$configmapCmd $(parseEnvVars "$ENV_SOURCE")"
fi
echo "$configmapCmd"
$configmapCmd

info "Creating agent secret..."
kubectl create secret generic portainer-agent-edge-key "--from-literal=edge.key=$EDGE_KEY" -n portainer

info "Deploying agent..."
kubectl apply -f portainer-agent-edge-k8s.yaml || errorAndExit "Unable to deploy agent manifest"

success "Portainer Edge agent successfully deployed"
exit 0
}

main "$@"
93 changes: 93 additions & 0 deletions deploy/manifests/agent/portainer-ce213-agent-edge-k8s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
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.12.0
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_KEY
valueFrom:
secretKeyRef:
name: portainer-agent-edge-key
key: edge.key
envFrom:
- configMapRef:
name: portainer-agent-edge
ports:
- containerPort: 9001
protocol: TCP
- containerPort: 80
protocol: TCP
Loading