forked from hswaw/hscloud
208 lines
7.1 KiB
Plaintext
208 lines
7.1 KiB
Plaintext
# Deploy MetalLB
|
|
|
|
local kube = import "../../../kube/kube.libsonnet";
|
|
local policies = import "../../../kube/policies.libsonnet";
|
|
|
|
local bindServiceAccountClusterRole(sa, cr) = kube.ClusterRoleBinding(cr.metadata.name) {
|
|
roleRef: {
|
|
apiGroup: "rbac.authorization.k8s.io",
|
|
kind: "ClusterRole",
|
|
name: cr.metadata.name,
|
|
},
|
|
subjects: [
|
|
{
|
|
kind: "ServiceAccount",
|
|
name: sa.metadata.name,
|
|
namespace: sa.metadata.namespace,
|
|
},
|
|
],
|
|
};
|
|
|
|
{
|
|
Environment: {
|
|
local env = self,
|
|
local cfg = env.cfg,
|
|
cfg:: {
|
|
namespace: "metallb-system",
|
|
namespaceCreate: true,
|
|
version:: "v0.8.3",
|
|
imageController: "metallb/controller:" + cfg.version,
|
|
//imageSpeaker: "metallb/speaker:" + cfg.version,
|
|
imageSpeaker: "derq3k/metallb-speaker:20191101-180123",
|
|
addressPools: error "addressPools must be set in config",
|
|
},
|
|
|
|
ns: if cfg.namespaceCreate then kube.Namespace(cfg.namespace),
|
|
|
|
insecurePolicy: policies.AllowNamespaceInsecure(cfg.namespace),
|
|
|
|
saController: kube.ServiceAccount("controller") {
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
},
|
|
|
|
saSpeaker: kube.ServiceAccount("speaker") {
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
},
|
|
|
|
crController: kube.ClusterRole("%s:controller" % cfg.namespace) {
|
|
rules: [
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["services"],
|
|
verbs: ["get", "list", "watch", "update"],
|
|
},
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["services/status"],
|
|
verbs: ["update"],
|
|
},
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["events"],
|
|
verbs: ["create", "patch"],
|
|
},
|
|
],
|
|
},
|
|
|
|
crbController: bindServiceAccountClusterRole(env.saController, env.crController),
|
|
|
|
crSpeaker: kube.ClusterRole("%s:speaker" % cfg.namespace) {
|
|
rules: [
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["services", "endpoints", "nodes"],
|
|
verbs: ["get", "list", "watch"],
|
|
},
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["events"],
|
|
verbs: ["create", "patch"],
|
|
},
|
|
],
|
|
},
|
|
|
|
crbSpeaker: bindServiceAccountClusterRole(env.saSpeaker, env.crSpeaker),
|
|
|
|
roleWatcher: kube.Role("config-watcher") {
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
rules: [
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["configmaps"],
|
|
verbs: ["get", "list", "watch"],
|
|
},
|
|
{
|
|
apiGroups: [""],
|
|
resources: ["events"],
|
|
verbs: ["create"],
|
|
},
|
|
],
|
|
},
|
|
|
|
rbWatcher: kube.RoleBinding("config-watcher") {
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
subjects: [
|
|
{ kind: "ServiceAccount", name: env.saController.metadata.name },
|
|
{ kind: "ServiceAccount", name: env.saSpeaker.metadata.name },
|
|
],
|
|
roleRef: {
|
|
apiGroup: "rbac.authorization.k8s.io",
|
|
kind: "Role",
|
|
name: env.roleWatcher.metadata.name,
|
|
},
|
|
},
|
|
|
|
deployController: kube.Deployment("controller") {
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
spec+: {
|
|
revisionHistoryLimit: 3,
|
|
template+: {
|
|
spec+: {
|
|
serviceAccountName: env.saController.metadata.name,
|
|
terminationGracePeriodSeconds: 0,
|
|
securityContext: {
|
|
runAsNonRoot: true,
|
|
runAsUser: 65534, # nobody
|
|
},
|
|
containers_: {
|
|
controller: kube.Container("controller") {
|
|
image: cfg.imageController,
|
|
args: [ "--port=7472", "--config=config" ],
|
|
ports: [
|
|
{ name: "monitoring", containerPort: 7472 },
|
|
],
|
|
resources: {
|
|
limits: { cpu: "200m", memory: "300Mi" },
|
|
},
|
|
securityContext: {
|
|
allowPrivilegeEscalation: false,
|
|
capabilities: { drop: [ "all" ] },
|
|
readOnlyRootFilesystem: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
daemonsetSpeaker: kube.DaemonSet("speaker") {
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
spec+: {
|
|
template+: {
|
|
spec+: {
|
|
serviceAccountName: env.saSpeaker.metadata.name,
|
|
hostNetwork: true,
|
|
containers_: {
|
|
speaker: kube.Container("speaker") {
|
|
image: cfg.imageSpeaker,
|
|
args: [ "--port=7472", "--config=config" ],
|
|
env_: {
|
|
METALLB_NODE_NAME: kube.FieldRef("spec.nodeName"),
|
|
METALLB_HOST: kube.FieldRef("status.hostIP"),
|
|
},
|
|
ports: [
|
|
{ name: "monitoring", containerPort: 7472 },
|
|
],
|
|
resources: {
|
|
limits: { cpu: "200m", memory: "300Mi" },
|
|
},
|
|
securityContext: {
|
|
allowPrivilegeEscalation: false,
|
|
capabilities: { drop: [ "all" ], add: [ "NET_ADMIN", "NET_RAW", "SYS_ADMIN" ] },
|
|
readOnlyRootFilesystem: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
configMap: kube.ConfigMap("config") {
|
|
local cm = self,
|
|
metadata+: {
|
|
namespace: cfg.namespace,
|
|
},
|
|
data: {
|
|
config: std.manifestYamlDoc({
|
|
"address-pools": cfg.addressPools,
|
|
"peers": cfg.peers,
|
|
}),
|
|
},
|
|
},
|
|
},
|
|
}
|