-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathaction.yml
228 lines (210 loc) · 9.17 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# This is the GitHub Action definition file, similar to a GitHub Workflow but
# different. Noteworthy differences are for example that we cannot set
# defaults.run.shell=bash, and any output we set in collective steps must be
# re-mapped under the outputs field.
#
# yamllint disable rule:line-length
#
# Reference: https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions
#
---
name: K3S with Calico and Helm
description: |
Install Kubernetes (K3S) and Helm 3.
Includes Calico network plugin for network policy support.
branding:
icon: server
color: purple
# Copied from
# https://github.com/jupyterhub/zero-to-jupyterhub-k8s/blob/08c13609c1d0c6cb07d45d49d0a876100cf941eb/ci/common
# Thanks @consideratio !
inputs:
k3s-version:
description: K3S version (https://github.com/rancher/k3s/releases)
required: false
default: ""
k3s-channel:
description: K3S channel (https://update.k3s.io/v1-release/channels)
required: false
default: ""
helm-version:
description: Helm 3 version (https://github.com/helm/helm/releases)
required: false
default: ""
metrics-enabled:
description: Enable or disable K3S metrics-server
required: false
default: "true"
traefik-enabled:
description: Enable or disable K3S Traefik ingress
required: false
default: "true"
docker-enabled:
description: Enable K3s to use the Docker daemon
required: false
default: "false"
extra-setup-args:
description: Addition arguments to be passed to the K3S setup script
required: false
default: ""
outputs:
kubeconfig:
description: Path to kubeconfig file
value: ${{ steps.set-output.outputs.kubeconfig }}
k3s-version:
description: "Installed k3s version, such as v1.29.0+k3s1"
value: "${{ steps.set-output.outputs.k3s-version }}"
k8s-version:
description: "Installed k8s version, such as v1.29.0"
value: "${{ steps.set-output.outputs.k8s-version }}"
calico-version:
description: "Installed calico version, such as v3.28.1"
value: "${{ steps.set-output.outputs.calico-version }}"
helm-version:
description: "Installed helm version, such as v3.13.0"
value: "${{ steps.set-output.outputs.helm-version }}"
runs:
using: "composite"
steps:
# https://rancher.com/docs/k3s/latest/en/installation/install-options/how-to-flags/
#
# NOTE: k3s has a Network Policy controller called kube-router, but it is
# not robust enough for use, so we disable it and install our own:
# calico. --flannel-backend=none should not be passed if we don't want
# to install our own CNI.
#
# ref: https://github.com/rancher/k3s/issues/947#issuecomment-627641541
#
- name: Validate input
run: |
echo "::group::Validate input"
if [[ -n "${{ inputs.k3s-version }}" && -n "${{ inputs.k3s-channel }}" ]]; then
echo "k3s-version and k3s-channel must not be specified simultaneously!"
exit 1
fi
echo "::endgroup::"
shell: bash
# NOTE: We apply a workaround as of version 3.0.1 by passing
# --egress-selector-mode=disabled by default as not doing so following
# modern versions of k3s has led to issues with `kubectl exec` and
# `kubectl logs`.
#
# For more details, see
# https://github.com/k3s-io/k3s/issues/5633
# and https://github.com/jupyterhub/action-k3s-helm/issues/59.
#
- name: Setup k3s ${{ inputs.k3s-version }}${{ inputs.k3s-channel }}
run: |
echo "::group::Setup k3s ${{ inputs.k3s-version }}${{ inputs.k3s-channel }}"
if [[ "${{ inputs.metrics-enabled }}" != true ]]; then
k3s_disable_metrics="--disable metrics-server"
fi
if [[ "${{ inputs.traefik-enabled }}" != true ]]; then
k3s_disable_traefik="--disable traefik"
fi
if [[ "${{ inputs.docker-enabled }}" == true ]]; then
k3s_docker=--docker
fi
# We want to provide a new default value for the --egress-selector-mode
# flag to avoid an intermittent issue possibly not fully resolved:
# https://github.com/k3s-io/k3s/issues/5633#issuecomment-1181424511.
#
# Details about the option available at
# https://docs.k3s.io/installation/network-options#control-plane-egress-selector-configuration.
#
if [[ "${{ inputs.extra-setup-args }}" != *--egress-selector-mode* ]]; then
default_extra_setup_args=--egress-selector-mode=disabled
fi
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="${{ inputs.k3s-version }}" INSTALL_K3S_CHANNEL="${{ inputs.k3s-channel }}" sh -s - \
${k3s_disable_metrics} \
${k3s_disable_traefik} \
--disable-network-policy \
--flannel-backend=none \
${k3s_docker} \
${{ inputs.extra-setup-args }} \
${default_extra_setup_args}
echo "::endgroup::"
shell: bash
# By providing a kubeconfig owned by the current user with 600 permissions,
# kubectl becomes usable without sudo, and helm won't emit warnings about
# bloated access to group/world.
- name: Prepare a kubeconfig in ~/.kube/config
run: |
echo "::group::Prepare a kubeconfig in ~/.kube/config"
mkdir -p ~/.kube
sudo cat /etc/rancher/k3s/k3s.yaml > "$HOME/.kube/config"
chmod 600 "$HOME/.kube/config"
echo "KUBECONFIG=$HOME/.kube/config" >> $GITHUB_ENV
echo "::endgroup::"
shell: bash
# Install calico as a CNI to enforce our NetworkPolicies. Note that canal
# could do this job as well.
#
# ref: https://rancher.com/docs/k3s/latest/en/installation/network-options/
#
- name: Setup calico
run: |
echo "::group::Setup calico"
# Download calico.yaml k8s and split into separate manifests
curl -sfL --output /tmp/calico.yaml https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/calico.yaml
mkdir calico
cd calico
yq -s '"\(.kind)-\(.metadata.name).yaml"' /tmp/calico.yaml
# Modify ConfigMap/calico-config: Look for `"type": "calico"` and add
# `"container_settings": ...` on the next line
sed -i.bak '/"type": "calico"/a\
"container_settings": {"allow_ip_forwarding": true},'\
ConfigMap-calico-config.yaml
for f in *.yaml.bak; do
diff -u "$f" "${f%.bak}" || :
done
cat ./*.yaml | kubectl apply -f -
echo "::endgroup::"
shell: bash
# There will be some waiting for calico to make the k8s Nodes ready and for
# the k3s related pods to start and become ready, so there is time to
# install Helm at this point for example.
- name: Setup Helm ${{ inputs.helm-version }}
run: |
echo "::group::Setup Helm ${{ inputs.helm-version }}"
curl -sf https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | DESIRED_VERSION="${{ inputs.helm-version }}" bash
echo "::endgroup::"
shell: bash
- name: Set version output
id: set-output
run: |
echo "::group::Set version output"
echo "kubeconfig=$HOME/.kube/config" >> $GITHUB_OUTPUT
echo "k3s-version=$(k3s --version | grep --max-count=1 'k3s' | sed 's/.*\(v[0-9][^ ]*\).*/\1/')" >> $GITHUB_OUTPUT
echo "k8s-version=$(k3s --version | grep --max-count=1 'k3s' | sed 's/.*\(v[0-9][^+]*\).*/\1/')" >> $GITHUB_OUTPUT
echo "calico-version=$(cat /tmp/calico.yaml | grep --max-count=1 'calico/cni:v' | sed 's/.*calico\/cni:\(.*\)/\1/')" >> $GITHUB_OUTPUT
echo "helm-version=$(helm version --short | sed 's/\([^+]*\).*/\1/')" >> $GITHUB_OUTPUT
echo "::endgroup::"
shell: bash
- name: Wait for calico, coredns, metrics server, traefik
run: |
echo "::group::Wait for daemonset/calico-node"
kubectl rollout status --watch --timeout=5m daemonset/calico-node -n kube-system
echo "::endgroup::"
echo "::group::Wait for deployment/calico-kube-controllers"
kubectl rollout status --watch --timeout=5m deployment/calico-kube-controllers -n kube-system
echo "::endgroup::"
echo "::group::Wait for deployment/coredns"
kubectl rollout status --watch --timeout=5m deployment/coredns -n kube-system
echo "::endgroup::"
echo "::group::Wait for deployment/metrics-server"
if [[ "${{ inputs.metrics-enabled }}" == true ]]; then
kubectl rollout status --watch --timeout=5m deployment/metrics-server -n kube-system
fi
echo "::endgroup::"
echo "::group::Wait for deployment/traefik"
if [[ "${{ inputs.traefik-enabled }}" == true ]]; then
# NOTE: Different versions of k3s install traefik in different ways,
# by waiting for these jobs if they exist, we will be fine no
# matter what.
kubectl wait --for=condition=complete --timeout=5m job/helm-install-traefik-crd -n kube-system || true
kubectl wait --for=condition=complete --timeout=5m job/helm-install-traefik -n kube-system || true
kubectl rollout status --watch --timeout=5m deployment/traefik -n kube-system
fi
echo "::endgroup::"
shell: bash