constellation/coordinator/kubernetes/k8sapi/resources/flannel.go
Leonard Cohnen 2d8fcd9bf4 monorepo
Co-authored-by: Malte Poll <mp@edgeless.systems>
Co-authored-by: katexochen <katexochen@users.noreply.github.com>
Co-authored-by: Daniel Weiße <dw@edgeless.systems>
Co-authored-by: Thomas Tendyck <tt@edgeless.systems>
Co-authored-by: Benedict Schlueter <bs@edgeless.systems>
Co-authored-by: leongross <leon.gross@rub.de>
Co-authored-by: Moritz Eckert <m1gh7ym0@gmail.com>
2022-03-22 16:09:39 +01:00

340 lines
9.4 KiB
Go

package resources
import (
"google.golang.org/protobuf/proto"
apps "k8s.io/api/apps/v1"
k8s "k8s.io/api/core/v1"
policy "k8s.io/api/policy/v1beta1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/resource"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
cniConfJSON = `{"name":"cbr0","cniVersion":"0.3.1","plugins":[{"type":"flannel","delegate":{"hairpinMode":true,"isDefaultGateway":true}},{"type":"portmap","capabilities":{"portMappings":true}}]}`
netConfJSON = `{"Network":"10.244.0.0/16","Backend":{"Type":"vxlan"}}`
)
// Reference: https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
// Changes compared to the reference: added the wireguard interface "wg0" to the args of the "kube-flannel" container of the DaemonSet.
type FlannelDeployment struct {
PodSecurityPolicy policy.PodSecurityPolicy
ClusterRole rbac.ClusterRole
ClusterRoleBinding rbac.ClusterRoleBinding
ServiceAccount k8s.ServiceAccount
ConfigMap k8s.ConfigMap
DaemonSet apps.DaemonSet
}
func NewDefaultFlannelDeployment() *FlannelDeployment {
return &FlannelDeployment{
PodSecurityPolicy: policy.PodSecurityPolicy{
TypeMeta: v1.TypeMeta{
APIVersion: "policy/v1beta1",
Kind: "PodSecurityPolicy",
},
ObjectMeta: v1.ObjectMeta{
Name: "psp.flannel.unprivileged",
Annotations: map[string]string{
"seccomp.security.alpha.kubernetes.io/allowedProfileNames": "docker/default",
"seccomp.security.alpha.kubernetes.io/defaultProfileName": "docker/default",
"apparmor.security.beta.kubernetes.io/allowedProfileNames": "runtime/default",
"apparmor.security.beta.kubernetes.io/defaultProfileName": "runtime/default",
},
},
Spec: policy.PodSecurityPolicySpec{
Privileged: false,
Volumes: []policy.FSType{
policy.FSType("configMap"),
policy.FSType("secret"),
policy.FSType("emptyDir"),
policy.FSType("hostPath"),
},
AllowedHostPaths: []policy.AllowedHostPath{
{PathPrefix: "/etc/cni/net.d"},
{PathPrefix: "/etc/kube-flannel"},
{PathPrefix: "/run/flannel"},
},
ReadOnlyRootFilesystem: false,
RunAsUser: policy.RunAsUserStrategyOptions{
Rule: policy.RunAsUserStrategyRunAsAny,
},
SupplementalGroups: policy.SupplementalGroupsStrategyOptions{
Rule: policy.SupplementalGroupsStrategyRunAsAny,
},
FSGroup: policy.FSGroupStrategyOptions{
Rule: policy.FSGroupStrategyRunAsAny,
},
AllowPrivilegeEscalation: proto.Bool(false),
DefaultAllowPrivilegeEscalation: proto.Bool(false),
AllowedCapabilities: []k8s.Capability{
k8s.Capability("NET_ADMIN"),
k8s.Capability("NET_RAW"),
},
HostPID: false,
HostIPC: false,
HostNetwork: true,
HostPorts: []policy.HostPortRange{
{Min: 0, Max: 65535},
},
SELinux: policy.SELinuxStrategyOptions{
Rule: policy.SELinuxStrategyRunAsAny,
},
},
},
ClusterRole: rbac.ClusterRole{
TypeMeta: v1.TypeMeta{
APIVersion: "rbac.authorization.k8s.io/v1",
Kind: "ClusterRole",
},
ObjectMeta: v1.ObjectMeta{
Name: "flannel",
},
Rules: []rbac.PolicyRule{
{
APIGroups: []string{"extensions"},
Resources: []string{"podsecuritypolicies"},
Verbs: []string{"use"},
ResourceNames: []string{"psp.flannel.unprivileged"},
},
{
APIGroups: []string{""},
Resources: []string{"pods"},
Verbs: []string{"get"},
},
{
APIGroups: []string{""},
Resources: []string{"nodes"},
Verbs: []string{"list", "watch"},
},
{
APIGroups: []string{""},
Resources: []string{"nodes/status"},
Verbs: []string{"patch"},
},
},
},
ClusterRoleBinding: rbac.ClusterRoleBinding{
TypeMeta: v1.TypeMeta{
Kind: "ClusterRoleBinding",
APIVersion: "rbac.authorization.k8s.io/v1",
},
ObjectMeta: v1.ObjectMeta{
Name: "flannel",
},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "flannel",
},
Subjects: []rbac.Subject{
{
Kind: "ServiceAccount",
Name: "flannel",
Namespace: "kube-system",
},
},
},
ServiceAccount: k8s.ServiceAccount{
TypeMeta: v1.TypeMeta{
APIVersion: "v1",
Kind: "ServiceAccount",
},
ObjectMeta: v1.ObjectMeta{
Name: "flannel",
Namespace: "kube-system",
},
},
ConfigMap: k8s.ConfigMap{
TypeMeta: v1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: v1.ObjectMeta{
Name: "kube-flannel-cfg",
Namespace: "kube-system",
Labels: map[string]string{
"tier": "node",
"app": "flannel",
},
},
Data: map[string]string{
"cni-conf.json": cniConfJSON,
"net-conf.json": netConfJSON,
},
},
DaemonSet: apps.DaemonSet{
TypeMeta: v1.TypeMeta{
APIVersion: "apps/v1",
Kind: "DaemonSet",
},
ObjectMeta: v1.ObjectMeta{
Name: "kube-flannel-ds",
Namespace: "kube-system",
Labels: map[string]string{
"tier": "node",
"app": "flannel",
},
},
Spec: apps.DaemonSetSpec{
Selector: &v1.LabelSelector{
MatchLabels: map[string]string{"app": "flannel"},
},
Template: k8s.PodTemplateSpec{
ObjectMeta: v1.ObjectMeta{
Labels: map[string]string{
"tier": "node",
"app": "flannel",
},
},
Spec: k8s.PodSpec{
Affinity: &k8s.Affinity{
NodeAffinity: &k8s.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &k8s.NodeSelector{
NodeSelectorTerms: []k8s.NodeSelectorTerm{
{MatchExpressions: []k8s.NodeSelectorRequirement{
{
Key: "kubernetes.io/os",
Operator: k8s.NodeSelectorOpIn,
Values: []string{"linux"},
},
}},
},
},
},
},
HostNetwork: true,
PriorityClassName: "system-node-critical",
Tolerations: []k8s.Toleration{
{
Operator: k8s.TolerationOpExists,
Effect: k8s.TaintEffectNoSchedule,
},
},
ServiceAccountName: "flannel",
InitContainers: []k8s.Container{
{
Name: "install-cni-plugin",
Image: "rancher/mirrored-flannelcni-flannel-cni-plugin:v1.0.0",
Command: []string{"cp"},
Args: []string{"-f", "/flannel", "/opt/cni/bin/flannel"},
VolumeMounts: []k8s.VolumeMount{
{
Name: "cni-plugin",
MountPath: "/opt/cni/bin",
},
},
},
{
Name: "install-cni",
Image: "quay.io/coreos/flannel:v0.15.1",
Command: []string{"cp"},
Args: []string{"-f", "/etc/kube-flannel/cni-conf.json", "/etc/cni/net.d/10-flannel.conflist"},
VolumeMounts: []k8s.VolumeMount{
{
Name: "cni",
MountPath: "/etc/cni/net.d",
},
{
Name: "flannel-cfg",
MountPath: "/etc/kube-flannel/",
},
},
},
},
Containers: []k8s.Container{
{
Name: "kube-flannel",
Image: "quay.io/coreos/flannel:v0.15.1",
Command: []string{"/opt/bin/flanneld"},
Args: []string{"--ip-masq", "--kube-subnet-mgr", "--iface", "wg0"},
Resources: k8s.ResourceRequirements{
Requests: k8s.ResourceList{
"cpu": resource.MustParse("100m"),
"memory": resource.MustParse("50Mi"),
},
Limits: k8s.ResourceList{
"cpu": resource.MustParse("100m"),
"memory": resource.MustParse("50Mi"),
},
},
SecurityContext: &k8s.SecurityContext{
Privileged: proto.Bool(false),
Capabilities: &k8s.Capabilities{
Add: []k8s.Capability{k8s.Capability("NET_ADMIN"), k8s.Capability("NET_RAW")},
},
},
Env: []k8s.EnvVar{
{
Name: "POD_NAME",
ValueFrom: &k8s.EnvVarSource{
FieldRef: &k8s.ObjectFieldSelector{FieldPath: "metadata.name"},
},
},
{
Name: "POD_NAMESPACE",
ValueFrom: &k8s.EnvVarSource{
FieldRef: &k8s.ObjectFieldSelector{FieldPath: "metadata.namespace"},
},
},
},
VolumeMounts: []k8s.VolumeMount{
{
Name: "run",
MountPath: "/run/flannel",
},
{
Name: "flannel-cfg",
MountPath: "/etc/kube-flannel/",
},
},
},
},
Volumes: []k8s.Volume{
{
Name: "run",
VolumeSource: k8s.VolumeSource{
HostPath: &k8s.HostPathVolumeSource{
Path: "/run/flannel",
},
},
},
{
Name: "cni-plugin",
VolumeSource: k8s.VolumeSource{
HostPath: &k8s.HostPathVolumeSource{
Path: "/opt/cni/bin",
},
},
},
{
Name: "cni",
VolumeSource: k8s.VolumeSource{
HostPath: &k8s.HostPathVolumeSource{
Path: "/etc/cni/net.d",
},
},
},
{
Name: "flannel-cfg",
VolumeSource: k8s.VolumeSource{
ConfigMap: &k8s.ConfigMapVolumeSource{
LocalObjectReference: k8s.LocalObjectReference{
Name: "kube-flannel-cfg",
},
},
},
},
},
},
},
},
},
}
}
func (f *FlannelDeployment) Marshal() ([]byte, error) {
return MarshalK8SResources(f)
}