Merge "Replace flannel with calico"
[icn.git] / deploy / cluster / cluster.sh
1 #!/usr/bin/env bash
2 set -eux -o pipefail
3
4 SCRIPTDIR="$(readlink -f $(dirname ${BASH_SOURCE[0]}))"
5 LIBDIR="$(dirname $(dirname ${SCRIPTDIR}))/env/lib"
6
7 source $LIBDIR/logging.sh
8 source $LIBDIR/common.sh
9
10 CALICO_VERSION="v3.22.0"
11 FLANNEL_VERSION="v0.15.0"
12
13 function build_source_flannel {
14     curl -sL https://raw.githubusercontent.com/coreos/flannel/${FLANNEL_VERSION}/Documentation/kube-flannel.yml -o ${SCRIPTDIR}/addons/flannel.yaml
15     cat <<EOF >${SCRIPTDIR}/templates/flannel-addon.yaml
16 {{- if eq .Values.cni "flannel" }}
17 ---
18 $(kubectl create configmap flannel-addon --from-file=${SCRIPTDIR}/addons/flannel.yaml -o yaml --dry-run=client)
19 {{- end }}
20 EOF
21     sed -i -e 's/  name: flannel-addon/  name: {{ .Values.clusterName }}-flannel-addon/' ${SCRIPTDIR}/templates/flannel-addon.yaml
22     sed -i -e 's/10.244.0.0\/16/{{ .Values.podCidr }}/' ${SCRIPTDIR}/templates/flannel-addon.yaml
23 }
24
25 function build_source_flux {
26     flux install --export >${SCRIPTDIR}/addons/flux-system.yaml
27     cat <<EOF >>${SCRIPTDIR}/addons/flux-system.yaml
28 ---
29 apiVersion: rbac.authorization.k8s.io/v1
30 kind: RoleBinding
31 metadata:
32   name: psp:privileged:flux-system
33   namespace: flux-system
34 roleRef:
35   apiGroup: rbac.authorization.k8s.io
36   kind: ClusterRole
37   name: psp:privileged
38 subjects:
39 - kind: Group
40   name: system:serviceaccounts:flux-system
41   apiGroup: rbac.authorization.k8s.io
42 EOF
43     # The name "sync" must be sorted after "flux-system" to ensure
44     # CRDs are instantiated first
45     cat <<'EOF' >${SCRIPTDIR}/addons/sync.yaml
46 {{- if .Values.flux.decryptionSecret }}
47 ---
48 apiVersion: v1
49 type: Opaque
50 kind: Secret
51 metadata:
52   name: {{ .Values.flux.repositoryName }}-{{ .Values.flux.branch }}-sops-gpg
53   namespace: flux-system
54 data:
55   sops.asc: {{ .Values.flux.decryptionSecret | b64enc }}
56 {{- end }}
57 ---
58 apiVersion: source.toolkit.fluxcd.io/v1beta1
59 kind: GitRepository
60 metadata:
61   name: {{ .Values.flux.repositoryName }}
62   namespace: flux-system
63 spec:
64   gitImplementation: go-git
65   interval: 1m0s
66   ref:
67     branch: {{ .Values.flux.branch }}
68   timeout: 20s
69   url: {{ .Values.flux.url }}
70 ---
71 apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
72 kind: Kustomization
73 metadata:
74   name: {{ .Values.clusterName }}-flux-sync
75   namespace: flux-system
76 spec:
77   interval: 10m0s
78   path: {{ .Values.flux.path }}
79   prune: true
80   sourceRef:
81     kind: GitRepository
82     name: {{ .Values.flux.repositoryName }}
83 {{- if .Values.flux.decryptionSecret }}
84   decryption:
85     provider: sops
86     secretRef:
87       name: {{ .Values.flux.repositoryName }}-{{ .Values.flux.branch }}-sops-gpg
88 {{- end }}
89 EOF
90     cat <<EOF >${SCRIPTDIR}/templates/flux-addon.yaml
91 {{- if .Values.flux }}
92 ---
93 $(kubectl create configmap flux-addon --from-file=${SCRIPTDIR}/addons/flux-system.yaml,${SCRIPTDIR}/addons/sync.yaml -o yaml --dry-run=client)
94 {{- end }}
95 EOF
96     sed -i -e 's/  name: flux-addon/  name: {{ .Values.clusterName }}-flux-addon/' ${SCRIPTDIR}/templates/flux-addon.yaml
97 }
98
99 function build_source_podsecurity {
100     # PodSecurityPolicy is being replaced in future versions of K8s.
101     # The recommended practice is described by K8s at
102     # - https://kubernetes.io/docs/concepts/policy/pod-security-policy/#recommended-practice
103     # - https://kubernetes.io/docs/concepts/security/pod-security-standards/
104     # and provides three levels: privileged, baseline, and restricted.
105     #
106     # The question to answer here is how to reconcile the K8s levels
107     # against the Akraino security requirements.
108     #
109     # For the time being, the below populates the cluster with the K8s
110     # recommended levels and provides an additional policy (icn) bound
111     # to the system:authenticated group to meet the Akraino
112     # requirements.
113     cat <<EOF >${SCRIPTDIR}/addons/podsecurity.yaml
114 ---
115 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/privileged-psp.yaml)
116 ---
117 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/baseline-psp.yaml)
118 ---
119 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/restricted-psp.yaml)
120 ---
121 $(curl -sL https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/policy/privileged-psp.yaml |
122   sed -e 's/  name: privileged/  name: icn/' |
123   sed -e '/^  allowedCapabilities:/,/^  [!-]/d')
124   allowedCapabilities:
125     - 'NET_ADMIN'
126     - 'SYS_ADMIN'
127     - 'SYS_NICE'
128     - 'SYS_PTRACE'
129   requiredDropCapabilities:
130     - 'NET_RAW'
131 ---
132 apiVersion: rbac.authorization.k8s.io/v1
133 kind: ClusterRole
134 metadata:
135   name: psp:privileged
136   labels:
137     addonmanager.kubernetes.io/mode: Reconcile
138 rules:
139 - apiGroups:
140   - policy
141   resourceNames:
142   - privileged
143   resources:
144   - podsecuritypolicies
145   verbs:
146   - use
147 ---
148 apiVersion: rbac.authorization.k8s.io/v1
149 kind: ClusterRole
150 metadata:
151   name: psp:baseline
152   labels:
153     addonmanager.kubernetes.io/mode: Reconcile
154 rules:
155 - apiGroups:
156   - policy
157   resourceNames:
158   - baseline
159   resources:
160   - podsecuritypolicies
161   verbs:
162   - use
163 ---
164 apiVersion: rbac.authorization.k8s.io/v1
165 kind: ClusterRole
166 metadata:
167   name: psp:icn
168   labels:
169     addonmanager.kubernetes.io/mode: Reconcile
170 rules:
171 - apiGroups:
172   - policy
173   resourceNames:
174   - icn
175   resources:
176   - podsecuritypolicies
177   verbs:
178   - use
179 ---
180 apiVersion: rbac.authorization.k8s.io/v1
181 kind: ClusterRole
182 metadata:
183   name: psp:restricted
184   labels:
185     addonmanager.kubernetes.io/mode: Reconcile
186 rules:
187 - apiGroups:
188   - policy
189   resourceNames:
190   - restricted
191   resources:
192   - podsecuritypolicies
193   verbs:
194   - use
195 ---
196 apiVersion: rbac.authorization.k8s.io/v1
197 kind: RoleBinding
198 metadata:
199   name: psp:privileged:nodes
200   namespace: kube-system
201   labels:
202     addonmanager.kubernetes.io/mode: Reconcile
203 roleRef:
204   apiGroup: rbac.authorization.k8s.io
205   kind: ClusterRole
206   name: psp:privileged
207 subjects:
208 - kind: Group
209   name: system:nodes
210   apiGroup: rbac.authorization.k8s.io
211 ---
212 apiVersion: rbac.authorization.k8s.io/v1
213 kind: RoleBinding
214 metadata:
215   name: psp:privileged:kube-system
216   namespace: kube-system
217 roleRef:
218   apiGroup: rbac.authorization.k8s.io
219   kind: ClusterRole
220   name: psp:privileged
221 subjects:
222 - kind: Group
223   name: system:serviceaccounts:kube-system
224   apiGroup: rbac.authorization.k8s.io
225 ---
226 apiVersion: rbac.authorization.k8s.io/v1
227 kind: ClusterRoleBinding
228 metadata:
229   name: psp:icn:any
230 roleRef:
231   kind: ClusterRole
232   name: psp:icn
233   apiGroup: rbac.authorization.k8s.io
234 subjects:
235 - kind: Group
236   name: system:authenticated
237   apiGroup: rbac.authorization.k8s.io
238 EOF
239     cat <<EOF >${SCRIPTDIR}/templates/podsecurity-addon.yaml
240 ---
241 $(kubectl create configmap podsecurity-addon --from-file=${SCRIPTDIR}/addons/podsecurity.yaml -o yaml --dry-run=client)
242 EOF
243     sed -i -e 's/  name: podsecurity-addon/  name: {{ .Values.clusterName }}-podsecurity-addon/' ${SCRIPTDIR}/templates/podsecurity-addon.yaml
244 }
245
246 function build_source_calico {
247     mkdir -p ${SCRIPTDIR}/addons/calico
248     curl -sL https://docs.projectcalico.org/archive/${CALICO_VERSION%.*}/manifests/calico.yaml -o ${SCRIPTDIR}/addons/calico/calico.yaml
249     # Remove trailing whitespace so that kubectl create configmap
250     # doesn't insert explicit newlines
251     sed -i -r 's/\s+$//g' ${SCRIPTDIR}/addons/calico/calico.yaml
252     cat <<EOF >${SCRIPTDIR}/addons/calico/ip-autodetection-method-patch.yaml
253 kind: DaemonSet
254 apiVersion: apps/v1
255 metadata:
256   name: calico-node
257   namespace: kube-system
258 spec:
259   template:
260     spec:
261       containers:
262         - name: calico-node
263           env:
264             - name: IP_AUTODETECTION_METHOD
265               value: can-reach=www.google.com
266 EOF
267     cat <<EOF >${SCRIPTDIR}/addons/calico/kustomization.yaml
268 resources:
269 - calico.yaml
270 patches:
271 - path: ip-autodetection-method-patch.yaml
272 EOF
273     kustomize build ${SCRIPTDIR}/addons/calico >${SCRIPTDIR}/addons/calico.yaml
274     cat <<EOF >${SCRIPTDIR}/templates/calico-addon.yaml
275 {{- if eq .Values.cni "calico" }}
276 ---
277 $(kubectl create configmap calico-addon --from-file=${SCRIPTDIR}/addons/calico.yaml -o yaml --dry-run=client)
278 {{- end }}
279 EOF
280     sed -i -e 's/  name: calico-addon/  name: {{ .Values.clusterName }}-calico-addon/' ${SCRIPTDIR}/templates/calico-addon.yaml
281 }
282
283 # This may be used to update the in-place addon YAML files from the
284 # upstream projects
285 function build_source {
286     mkdir -p ${SCRIPTDIR}/addons
287     build_source_calico
288     build_source_flannel
289     build_source_flux
290     build_source_podsecurity
291 }
292
293 case $1 in
294     "build-source") build_source ;;
295     "foo") build_source_calico ;;
296     *) cat <<EOF
297 Usage: $(basename $0) COMMAND
298
299 Commands:
300   build-source  - Rebuild the in-tree addon YAML files
301 EOF
302        ;;
303 esac