diff --git a/WORKSPACE b/WORKSPACE index f57c5e6adf..b8d7de12cc 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -59,22 +59,22 @@ load("@io_bazel_rules_k8s//k8s:k8s.bzl", "k8s_repositories", "k8s_defaults") k8s_repositories() -_CLUSTER = "minikube" - -_NAMESPACE = "default" - [k8s_defaults( name = "k8s_" + kind, - cluster = _CLUSTER, - #context = _CONTEXT, + cluster = "minikube", kind = kind, - namespace = _NAMESPACE, ) for kind in [ + "cluster_role", + "configmap", "deploy", - "service", - "secret", - "priority_class", + "ingress", + "job", + "namespace", "pod", + "priority_class", + "secret", + "service", + "service_account", ]] load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") diff --git a/k8s/BUILD.bazel b/k8s/BUILD.bazel index b3dc3a0b5c..facd8f8e2a 100644 --- a/k8s/BUILD.bazel +++ b/k8s/BUILD.bazel @@ -4,12 +4,15 @@ load("@k8s_priority_class//:defaults.bzl", "k8s_priority_class") k8s_objects( name = "everything", objects = [ - "//k8s/geth:everything", ":priority_class", + "//k8s/geth:everything", + "//k8s/beacon-chain:everything", + "//k8s/nginx:everything", ], ) k8s_priority_class( name = "priority_class", template = "priority.yaml", + namespace = "default", ) diff --git a/k8s/beacon-chain/BUILD.bazel b/k8s/beacon-chain/BUILD.bazel index e138327a32..8ac05f4749 100644 --- a/k8s/beacon-chain/BUILD.bazel +++ b/k8s/beacon-chain/BUILD.bazel @@ -1,25 +1,61 @@ package(default_visibility = ["//k8s:__subpackages__"]) load("@io_bazel_rules_k8s//k8s:objects.bzl", "k8s_objects") +load("@k8s_configmap//:defaults.bzl", "k8s_configmap") load("@k8s_deploy//:defaults.bzl", "k8s_deploy") +load("@k8s_job//:defaults.bzl", "k8s_job") +load("@k8s_namespace//:defaults.bzl", "k8s_namespace") load("@k8s_service//:defaults.bzl", "k8s_service") +load("@k8s_service_account//:defaults.bzl", "k8s_service_account") k8s_objects( name = "everything", objects = [ + ":namespace", # Must be first + ":configs", ":deployments", ":services", + ":jobs", ], ) +_NAMESPACE = "beacon-chain" + +_configs = [ + "beacon-config", +] + _deployments = [ "beacon-chain", + "bootnode", + "relay", +] + +_jobs = [ + "deployvrc", ] _services = [ "beacon-chain", + "bootnode", + "relay", ] +_service_accounts = [ + "deployvrc", +] + +k8s_objects( + name = "configs", + objects = [":" + name + ".config" for name in _configs], +) + +[k8s_configmap( + name = name + ".config", + template = name + ".config.yaml", + namespace = _NAMESPACE, +) for name in _configs] + k8s_objects( name = "deployments", objects = [":" + name + ".deploy" for name in _deployments], @@ -28,8 +64,20 @@ k8s_objects( [k8s_deploy( name = name + ".deploy", template = name + ".deploy.yaml", + namespace = _NAMESPACE, ) for name in _deployments] +k8s_objects( + name = "jobs", + objects = [":" + name + ".job" for name in _jobs], +) + +[k8s_job( + name = name + ".job", + template = name + ".job.yaml", + namespace = _NAMESPACE, +) for name in _jobs] + k8s_objects( name = "services", objects = [":" + name + ".service" for name in _services], @@ -38,4 +86,21 @@ k8s_objects( [k8s_service( name = name + ".service", template = name + ".service.yaml", + namespace = _NAMESPACE, ) for name in _services] + +k8s_objects( + name = "service_accounts", + objects = [":" + name + ".service_account" for name in _service_accounts], +) + +[k8s_service_account( + name = name + ".service_account", + template = name + ".serviceaccount.yaml", + namespace = _NAMESPACE, +) for name in _service_accounts] + +k8s_namespace( + name = "namespace", + template = "namespace.yaml", +) diff --git a/k8s/beacon-chain/beacon-chain.deploy.yaml b/k8s/beacon-chain/beacon-chain.deploy.yaml index d56a2cef64..6d9542fe76 100644 --- a/k8s/beacon-chain/beacon-chain.deploy.yaml +++ b/k8s/beacon-chain/beacon-chain.deploy.yaml @@ -2,6 +2,7 @@ kind: Deployment apiVersion: apps/v1beta1 metadata: name: beacon-chain + namespace: beacon-chain spec: replicas: 3 selector: @@ -13,17 +14,24 @@ spec: labels: component: beacon-chain universe: beacon-chain + annotations: + prometheus.io/scrape: 'true' + prometheus.io/port: '9090' spec: priorityClassName: production-priority containers: - name: beacon-chain image: gcr.io/prysmaticlabs/prysm/beacon-chain:latest args: - - "--web3provider=ws://$(GETH_NODES_SERVICE_HOST):$(GETH_NODES_SERVICE_PORT_WS)" + - "--web3provider=ws://geth-nodes.pow.svc.cluster.local:8546" - "--verbosity=debug" - - "--vrcaddr=0x541AfaC5266c534de039B4A1a53519e76ea82846" + - "--vrcaddr=$(VALIDATOR_REGISTRATION_CONTRACT_ADDRESS)" - "--rpc-port=4000" - "--simulator=false" + - "--monitoring-port=9090" + - "--bootstrap-node=/ip4/$(BOOTNODE_SERVICE_HOST)/tcp/$(BOOTNODE_SERVICE_PORT)/p2p/QmUWTsZwoJ51tey4fEE9EAqzQeHFHm4FE9aSfgTv8xyuG5" + - "--relay-node=/ip4/35.221.47.224/tcp/20000/p2p/QmXNZeGdHYshgwyYyJnYG7u5iQ1Hej5R9QshgEZ5NACc1x" + - "--p2p-port=5000" resources: requests: memory: "100Mi" @@ -34,3 +42,13 @@ spec: ports: - containerPort: 4000 name: grpc + - containerPort: 5000 + name: p2p + - containerPort: 9090 + name: prometheus + env: + - name: VALIDATOR_REGISTRATION_CONTRACT_ADDRESS + valueFrom: + configMapKeyRef: + name: beacon-config + key: VALIDATOR_REGISTRATION_CONTRACT_ADDRESS diff --git a/k8s/beacon-chain/beacon-chain.service.yaml b/k8s/beacon-chain/beacon-chain.service.yaml index 2bbcb6ac4e..0c483ba629 100644 --- a/k8s/beacon-chain/beacon-chain.service.yaml +++ b/k8s/beacon-chain/beacon-chain.service.yaml @@ -2,6 +2,7 @@ kind: Service apiVersion: v1 metadata: name: beacon-chain + namespace: beacon-chain spec: selector: component: beacon-chain @@ -10,4 +11,4 @@ spec: - port: 4000 targetPort: 4000 name: grpc - type: LoadBalancer + type: ClusterIP diff --git a/k8s/beacon-chain/beacon-config.config.yaml b/k8s/beacon-chain/beacon-config.config.yaml new file mode 100644 index 0000000000..2bc9aa4f99 --- /dev/null +++ b/k8s/beacon-chain/beacon-config.config.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: beacon-config + namespace: beacon-chain +data: + VALIDATOR_REGISTRATION_CONTRACT_ADDRESS: "0x0" diff --git a/k8s/beacon-chain/bootnode.deploy.yaml b/k8s/beacon-chain/bootnode.deploy.yaml new file mode 100644 index 0000000000..7c1864bfcc --- /dev/null +++ b/k8s/beacon-chain/bootnode.deploy.yaml @@ -0,0 +1,32 @@ +kind: Deployment +apiVersion: apps/v1beta1 +metadata: + name: bootnode + namespace: beacon-chain + annotations: + prometheus.io/scrape: 'true' +spec: + replicas: 1 + selector: + matchLabels: + component: bootnode + template: + metadata: + labels: + component: bootnode + spec: + priorityClassName: production-priority + containers: + - name: relay + image: gcr.io/prysmaticlabs/prysm/bootnode:latest + args: + - "-debug" + - "-port=4000" + - "-private=CAASpwkwggSjAgEAAoIBAQDLd5Sfv/8+ybSSeEj3980Bk1JOd8SXQ8e22ntKqtCWOoQ27jwUn6FH03poMvikJlHzkgnEXCZugeAbc/8rP1q/JRlOqhO/Zw7aQm6e+VjyKdzbTMv/YPkctsvStJw66U2EKkah02t7KTLO82qOQW3rgQFtRqKcN/jT0K2M4l6ED6DFhAYzjnBZpxEX3rCbqmKJQMYBFxlXa7T1kfpUQ7MdRtGtxW/GxJvo5CPf7e8T2SrKok437TN4aoD03W+czaJd48EFb/kgQNKbBoGX7+2c/liatm7QqvYbNkuU+N0sPZ7tkoxyxVQN2ie6WsZDVH3F1LOyI638w6WhYu2TmY9pAgMBAAECggEAYyCSRzYqK7PnhoiVvEF9Hmxg6BvPqoZ6MWrGMH2B+/7sVTrCCKYw1CaC92sF2itVN96JZaIjkykxPw7HXZGTK5buenXAAzs5cDp3XHpMzEZ69Fi49mWPWF7ydGhLySPLAT37hXHUZn+O4maTHlVgMSF7yXplVMisML31H7NVqu53N8U697Me+GIdB6dNn8in3n7O4Kkzo0V/h1YhPWwvds9Vzbh3CHnskeoY/J1UVIpwrELKS9OgcgXP+Kdx4jV4sPT4HAXvRj4dcCE2uAdbdKVVnrIhYBaIdNWzpXxj9cNcV/3P5XjrDsuVghKSrB86C/iM7YncvtVadwswc0oEEQKBgQD2IdGXHU9Hzqdus6Dj16ndCuVcKWqeHZcLR/tkk/HnsRuGmj4o5FdPrZ0yR1HBsSkLuJbw6trJtO7xzkvYmR9abXrKIqKAHRclwXopF6IdroOSjQj9j7GJp9YT/EQ3fqH0yw3h2ELyRRmxlQmKDQQDTM7CTUgYZ2WOK4hLsMcpPQKBgQDTn95yGBkd2eizPSLPTG41JWb89xQsS4RRcZHdqpiNce993lgiXzdWco/8kRhI+9h7MHPAaXrFP9gyX4H5ln3e0ovlulo/JYQSABGHycU1krOeHdfnbyxtrrbYdLan9DfZq2N/at58cAeiC8GGwYk8KCrC7h+9w1c76gCkB+ypnQKBgQDELbhshgQG7AQwDCSU9fSCJokhqDE+zb7yUvFg/Tq2vUd/Rbl9xmKBM5Qz2vyjMZ3RpdNJOygf1YMOYKu7fHCtFs3kBy8WhhlJEqlXz2p71fkw+hDMaZfMbGYJj+yffuN/xcjO1hymFcWg8XWk/zLPnoy9+fMY4HDlnHUKP2C+0QKBgHudpQisfu9q/HzGt3CzyqSMxo35nfUJ367bUkNThW0KIsU5fe4GBIMgxG7aKn9nbVr4QIUimC5kTtuN4pRyje/8uO9mXZUJSw5gr9zLxcC3guhXsmhkDmW7at8hvhh5la42aRZizLePkUXc7BzVLF7Rb7kR88SbOHetBtbKMjoZAoGAXJvdjLmx5rYOZvTgwEbZ0vIrAmexLU8uJ5B+VC4ScQ7MvXwGq4S3GRN3OD4mBfscJ/XCsMrg+9famUOxE+5uWWnQOPBjLu53q8/uQYLWlaxCijo7aGTTX2XgiuNMTvwbRoxpiUwyBi0zv5C7u/bjBvwYX37aYKIr7xnvEPk9pYQ=" + resources: + requests: + memory: "100Mi" + cpu: "100m" + ports: + - containerPort: 4000 + name: bootnodeport diff --git a/k8s/beacon-chain/bootnode.service.yaml b/k8s/beacon-chain/bootnode.service.yaml new file mode 100644 index 0000000000..cff9424b7c --- /dev/null +++ b/k8s/beacon-chain/bootnode.service.yaml @@ -0,0 +1,13 @@ +kind: Service +apiVersion: v1 +metadata: + name: bootnode + namespace: beacon-chain +spec: + selector: + component: bootnode + ports: + - port: 4000 + targetPort: 4000 + name: bootnodeport + type: ClusterIP diff --git a/k8s/beacon-chain/deployvrc.job.yaml b/k8s/beacon-chain/deployvrc.job.yaml new file mode 100644 index 0000000000..30cdf54986 --- /dev/null +++ b/k8s/beacon-chain/deployvrc.job.yaml @@ -0,0 +1,21 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: deploy-vrc + namespace: beacon-chain +spec: + #ttlSecondsAfterFinished: 7200 + activeDeadlineSeconds: 600 + backoffLimit: 3 + template: + spec: + priorityClassName: batch-priority + serviceAccountName: deployvrc + containers: + - name: deployvcr + image: gcr.io/prysmaticlabs/prysm/deployvrc:latest + args: + - "--httpPath=http://geth-nodes.pow.svc.cluster.local:8545" + - "--privKey=783da8ef5343c3019748506305d400bca8c324a5819f3a7f7fbf0c0a0d799b09" + - "--k8s-config=beacon-config" + restartPolicy: OnFailure diff --git a/k8s/beacon-chain/deployvrc.serviceaccount.yaml b/k8s/beacon-chain/deployvrc.serviceaccount.yaml new file mode 100644 index 0000000000..d449147cb5 --- /dev/null +++ b/k8s/beacon-chain/deployvrc.serviceaccount.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: deployvrc + namespace: beacon-chain +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: deployvrc +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - update +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: deployvrc +subjects: +- kind: ServiceAccount + name: deployvrc + namespace: beacon-chain +roleRef: + kind: ClusterRole + name: deployvrc + apiGroup: rbac.authorization.k8s.io + diff --git a/k8s/beacon-chain/namespace.yaml b/k8s/beacon-chain/namespace.yaml new file mode 100644 index 0000000000..02cff2e112 --- /dev/null +++ b/k8s/beacon-chain/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: beacon-chain diff --git a/k8s/beacon-chain/relay.deploy.yaml b/k8s/beacon-chain/relay.deploy.yaml new file mode 100644 index 0000000000..6354552c0f --- /dev/null +++ b/k8s/beacon-chain/relay.deploy.yaml @@ -0,0 +1,31 @@ +kind: Deployment +apiVersion: apps/v1beta1 +metadata: + name: relay + namespace: beacon-chain + annotations: + prometheus.io/scrape: 'true' +spec: + replicas: 1 + selector: + matchLabels: + component: relay + template: + metadata: + labels: + component: relay + spec: + priorityClassName: production-priority + containers: + - name: relay + image: gcr.io/prysmaticlabs/prysm/relaynode:latest + args: + - "-debug" + - "-port=4000" + resources: + requests: + memory: "100Mi" + cpu: "100m" + ports: + - containerPort: 4000 + name: relayport diff --git a/k8s/beacon-chain/relay.service.yaml b/k8s/beacon-chain/relay.service.yaml new file mode 100644 index 0000000000..c46fde2156 --- /dev/null +++ b/k8s/beacon-chain/relay.service.yaml @@ -0,0 +1,13 @@ +kind: Service +apiVersion: v1 +metadata: + name: relay + namespace: beacon-chain +spec: + selector: + component: relay + ports: + - port: 4000 + targetPort: 4000 + name: relayport + type: ClusterIP diff --git a/k8s/geth/BUILD.bazel b/k8s/geth/BUILD.bazel index 2f180656c3..b8f61e199d 100644 --- a/k8s/geth/BUILD.bazel +++ b/k8s/geth/BUILD.bazel @@ -2,21 +2,28 @@ package(default_visibility = ["//k8s:__subpackages__"]) load("@io_bazel_rules_k8s//k8s:objects.bzl", "k8s_objects") load("@k8s_deploy//:defaults.bzl", "k8s_deploy") -load("@k8s_service//:defaults.bzl", "k8s_service") +load("@k8s_ingress//:defaults.bzl", "k8s_ingress") +load("@k8s_namespace//:defaults.bzl", "k8s_namespace") load("@k8s_secret//:defaults.bzl", "k8s_secret") +load("@k8s_service//:defaults.bzl", "k8s_service") k8s_objects( name = "everything", objects = [ + ":namespace", # Must be first + ":deployments", + ":ingress", ":secrets", ":services", - ":deployments", ], ) +_NAMESPACE = "pow" + _deployments = [ "bootnode", "ethstats", + "faucet", "miners", "nodes", ] @@ -24,15 +31,28 @@ _deployments = [ _services = [ "bootnode", "ethstats", + "faucet", "nodes", ] _secrets = [ "bootnode", "ethstats", + "faucet", "genesis", ] +k8s_ingress( + name = "ingress", + template = "ingress.yaml", + namespace = _NAMESPACE, +) + +k8s_namespace( + name = "namespace", + template = "namespace.yaml", +) + k8s_objects( name = "deployments", objects = [":" + name + ".deploy" for name in _deployments], @@ -41,6 +61,7 @@ k8s_objects( [k8s_deploy( name = name + ".deploy", template = name + ".deploy.yaml", + namespace = _NAMESPACE, ) for name in _deployments] k8s_objects( @@ -51,6 +72,7 @@ k8s_objects( [k8s_secret( name = name + ".secret", template = name + ".secret.yaml", + namespace = _NAMESPACE, ) for name in _secrets] k8s_objects( @@ -61,4 +83,5 @@ k8s_objects( [k8s_service( name = name + ".service", template = name + ".service.yaml", + namespace = _NAMESPACE, ) for name in _services] diff --git a/k8s/geth/bootnode.deploy.yaml b/k8s/geth/bootnode.deploy.yaml index 77ee1046bb..a0c9653d10 100644 --- a/k8s/geth/bootnode.deploy.yaml +++ b/k8s/geth/bootnode.deploy.yaml @@ -1,13 +1,14 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: - name: geth-bootnode + name: geth-bootnode-v4 + namespace: pow spec: replicas: 1 template: metadata: labels: - component: bootnode + component: bootnode-v4 universe: geth spec: priorityClassName: production-priority @@ -44,4 +45,54 @@ spec: volumes: - name: secrets secret: - secretName: geth-bootnode-secret \ No newline at end of file + secretName: geth-bootnode-secret +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: geth-bootnode-v5 + namespace: pow +spec: + replicas: 1 + template: + metadata: + labels: + component: bootnode-v5 + universe: geth + spec: + priorityClassName: production-priority + containers: + - name: bootnode + image: ethereum/client-go:alltools-stable + ports: + - containerPort: 8545 + name: rpc + - containerPort: 30303 + name: discovery-tcp + protocol: TCP + - containerPort: 30303 + name: discovery-udp + protocol: UDP + - containerPort: 30301 + name: bootnode-udp + protocol: UDP + command: ["bootnode"] + args: + - "--nodekey=/data/private_key" + - "--verbosity=4" + - "--v5" + volumeMounts: + - name: secrets + mountPath: "/data/" + readOnly: true + resources: + requests: + memory: "25Mi" + cpu: "25m" + limits: + memory: "100Mi" + cpu: "150m" + volumes: + - name: secrets + secret: + secretName: geth-bootnode-secret diff --git a/k8s/geth/bootnode.secret.yaml b/k8s/geth/bootnode.secret.yaml index e624b5b3a2..3583252e59 100644 --- a/k8s/geth/bootnode.secret.yaml +++ b/k8s/geth/bootnode.secret.yaml @@ -2,7 +2,8 @@ apiVersion: v1 kind: Secret metadata: name: geth-bootnode-secret + namespace: pow data: public_key: MDZmMmI0OGFhODY1OTQ2OTdiZjZjMmI0NjRhMjFhMmYwMWVhNzYyM2MxNGQxOWU5MTE3OGMzZTRkNDNhZDg2M2FjMzdjZmQwODA0OWY3OWIxOTgxN2VmNGZlZjk5NDUxNTYzNjM3N2M1ZjhjN2UyY2MwYWJlY2VmZjkyZTc0MWY= private_key: OGUxMDg1YmQwZThmOGI2MTY0OWRjMWNlYjA2Y2Q1ZTQyNTllY2YwOWRmYTFmZWRlNGNmNDVhMmZiZDE0ODVmNg== -type: Opaque \ No newline at end of file +type: Opaque diff --git a/k8s/geth/bootnode.service.yaml b/k8s/geth/bootnode.service.yaml index cfe2fbc1fa..695af19dce 100644 --- a/k8s/geth/bootnode.service.yaml +++ b/k8s/geth/bootnode.service.yaml @@ -1,10 +1,11 @@ kind: Service apiVersion: v1 metadata: - name: geth-bootnode + name: geth-bootnode-v4 + namespace: pow spec: selector: - component: bootnode + component: bootnode-v4 universe: geth ports: - port: 8545 @@ -22,4 +23,33 @@ spec: - port: 30301 targetPort: 30301 name: bootnode-udp - protocol: UDP \ No newline at end of file + protocol: UDP + type: ClusterIP +--- +kind: Service +apiVersion: v1 +metadata: + name: geth-bootnode-v5 + namespace: pow +spec: + selector: + component: bootnode-v5 + universe: geth + ports: + - port: 8545 + targetPort: 8545 + name: rpc + protocol: TCP + - port: 30303 + targetPort: 30303 + name: discovery-tcp + protocol: TCP + - port: 30303 + targetPort: 30303 + name: discovery-udp + protocol: UDP + - port: 30301 + targetPort: 30301 + name: bootnode-udp + protocol: UDP + type: ClusterIP diff --git a/k8s/geth/ethstats.deploy.yaml b/k8s/geth/ethstats.deploy.yaml index 2daa369f43..8f763b6f46 100644 --- a/k8s/geth/ethstats.deploy.yaml +++ b/k8s/geth/ethstats.deploy.yaml @@ -2,6 +2,7 @@ kind: Deployment apiVersion: apps/v1beta1 metadata: name: geth-ethstats + namespace: pow spec: replicas: 1 selector: diff --git a/k8s/geth/ethstats.secret.yaml b/k8s/geth/ethstats.secret.yaml index edd76ec68f..59e1393de4 100644 --- a/k8s/geth/ethstats.secret.yaml +++ b/k8s/geth/ethstats.secret.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Secret metadata: name: ethstats-secrets + namespace: pow type: Opaque data: # Secret for websocket connections diff --git a/k8s/geth/ethstats.service.yaml b/k8s/geth/ethstats.service.yaml index 025ab7f483..2aa5698f1f 100644 --- a/k8s/geth/ethstats.service.yaml +++ b/k8s/geth/ethstats.service.yaml @@ -2,6 +2,7 @@ kind: Service apiVersion: v1 metadata: name: geth-ethstats + namespace: pow spec: selector: component: ethstats @@ -9,4 +10,4 @@ spec: ports: - port: 3000 targetPort: 3000 - type: LoadBalancer \ No newline at end of file + type: ClusterIP diff --git a/k8s/geth/faucet.deploy.yaml b/k8s/geth/faucet.deploy.yaml new file mode 100644 index 0000000000..0fbe74ce91 --- /dev/null +++ b/k8s/geth/faucet.deploy.yaml @@ -0,0 +1,99 @@ +kind: Deployment +apiVersion: apps/v1beta1 +metadata: + name: faucet + namespace: pow + labels: + component: faucet +spec: + replicas: 1 + selector: + matchLabels: + universe: geth + component: faucet + template: + metadata: + labels: + universe: geth + component: faucet + spec: + priorityClassName: batch-priority + containers: + - name: faucet + image: ethereum/client-go:alltools-stable + ports: + - containerPort: 8080 + name: api + - containerPort: 30303 + name: discovery-tcp + protocol: TCP + - containerPort: 30303 + name: discovery-udp + protocol: UDP + # Use /bin/sh -c to execute geth so that we have access to HOSTNAME in + # the command arguments. + # https://github.com/kubernetes/kubernetes/issues/57726 + command: + - "/bin/sh" + - "-c" + - > + touch /tmp/pwd; + faucet + -account.json=/data/accounts/account.json + -account.pass=/tmp/pwd + -apiport=8080 + -bootnodes=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_V5_SERVICE_HOST):$(GETH_BOOTNODE_V5_SERVICE_PORT_BOOTNODE_UDP) + -ethport=30303 + -ethstats=$HOSTNAME:$(ETHSTATS_WS_SECRET)@$(GETH_ETHSTATS_SERVICE_HOST):$(GETH_ETHSTATS_SERVICE_PORT) + -faucet.amount=35 + -faucet.minutes=1440 + -faucet.name=validator-faucet + -faucet.tiers=3 + -genesis=/data/genesis.json + -loglevel=3 + -network=1337 + -noauth + env: + - name: ETHSTATS_WS_SECRET + valueFrom: + secretKeyRef: + name: ethstats-secrets + key: ws + - name: BOOTNODE_PUBKEY + valueFrom: + secretKeyRef: + name: geth-bootnode-secret + key: public_key + volumeMounts: + - name: genesis + mountPath: "/data" + readOnly: true + - name: accounts + mountPath: "/data/accounts" + readOnly: true + - name: faucet-data + mountPath: "/root/.faucet/keys" + resources: + requests: + memory: "500Mi" + cpu: "50m" + limits: + memory: "750Mi" + cpu: "100m" + volumes: + - name: genesis + secret: + secretName: geth-genesis + items: + - key: json + path: genesis.json + - name: accounts + secret: + secretName: geth-faucet-accounts-secret + items: + - key: json + path: account.json + - key: password + path: password + - name: faucet-data + emptyDir: {} diff --git a/k8s/geth/faucet.secret.yaml b/k8s/geth/faucet.secret.yaml new file mode 100644 index 0000000000..a35b230019 --- /dev/null +++ b/k8s/geth/faucet.secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: geth-faucet-accounts-secret + namespace: pow +data: + json: eyJhZGRyZXNzIjoiODg4MjA0MmI4ZTkzYzg1MzEyZjYyM2YwNThlZjI1MmM4MDI1YTdhZSIsImNyeXB0byI6eyJjaXBoZXIiOiJhZXMtMTI4LWN0ciIsImNpcGhlcnRleHQiOiJjZDYxMDM4N2ExZDU1MDgyMDRhNzExZTNkMGExZTkwMzMzMzE0NTI3MzllNzlkZGQzMmNhZTRmNjZhMzVkODI2IiwiY2lwaGVycGFyYW1zIjp7Iml2IjoiNGFkMzUyOTExMjNjNDEzYzg3YzBhODFjZDBkNjZhN2YifSwia2RmIjoic2NyeXB0Iiwia2RmcGFyYW1zIjp7ImRrbGVuIjozMiwibiI6MjYyMTQ0LCJwIjoxLCJyIjo4LCJzYWx0IjoiMGRiNmFiZDZiNDhmZGYxZjcxM2YzMjkyYjVmMjkwMTY0ZDYzYjQ1NGY0OWIzOTEzYjYyNTE3NGRmNDNmYTQ4NyJ9LCJtYWMiOiJkYWUzODFlZTAwM2JlNWFhZTMxZGVmYzg2YmMyNWMyYzlmNDJiZDlmYzgxNzc1OGU2MDhhMGI1YTFiYmIyMWYwIn0sImlkIjoiYjFmYmNiNTctNjJlYy00YTE4LTllN2YtOGQ4MjE2OTQ4N2M5IiwidmVyc2lvbiI6M30= + password: Cgo= +type: Opaque + diff --git a/k8s/geth/faucet.service.yaml b/k8s/geth/faucet.service.yaml new file mode 100644 index 0000000000..31bdce726e --- /dev/null +++ b/k8s/geth/faucet.service.yaml @@ -0,0 +1,13 @@ +kind: Service +apiVersion: v1 +metadata: + name: geth-faucet + namespace: pow +spec: + selector: + component: faucet + universe: geth + ports: + - port: 8080 + targetPort: 8080 + type: ClusterIP diff --git a/k8s/geth/genesis.secret.yaml b/k8s/geth/genesis.secret.yaml index 7778b70916..8f90696954 100644 --- a/k8s/geth/genesis.secret.yaml +++ b/k8s/geth/genesis.secret.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Secret metadata: name: geth-genesis + namespace: pow data: json: eyJjb25maWciOnsiY2hhaW5JZCI6MTMzNywiaG9tZXN0ZWFkQmxvY2siOjAsImVpcDE1NUJsb2NrIjowLCJlaXAxNThCbG9jayI6MH0sImRpZmZpY3VsdHkiOiIweDAiLCJnYXNMaW1pdCI6IjB4MjEwMDAwMCIsImFsbG9jIjp7IjcxN2MzYTZlNGNiZDQ3NmMyMzEyNjEyMTU1ZWIyMzNiZjQ5OGRkNWIiOnsiYmFsYW5jZSI6IjB4MTMzNzAwMDAwMDAwMDAwMDAwMDAwMCJ9fX0K -type: Opaque \ No newline at end of file +type: Opaque diff --git a/k8s/geth/ingress.yaml b/k8s/geth/ingress.yaml new file mode 100644 index 0000000000..abb0ae295e --- /dev/null +++ b/k8s/geth/ingress.yaml @@ -0,0 +1,37 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: nginx-ingress + namespace: pow + annotations: + nginx.org/websocket-services: "geth-ethstats,geth-faucet" +spec: + rules: + - host: ethstats.prylabs.network + http: + paths: + - path: / + backend: + serviceName: geth-ethstats + servicePort: 3000 + - host: powexplorer.prylabs.network + http: + paths: + - path: / + backend: + serviceName: blockscout + servicePort: 4000 + - host: powfaucet.prylabs.network + http: + paths: + - path: / + backend: + serviceName: geth-faucet + servicePort: 8080 + - host: powchain.prylabs.network + http: + paths: + - paths: + backend: + serviceName: geth-nodes + servicePort: 8545 diff --git a/k8s/geth/miners.deploy.yaml b/k8s/geth/miners.deploy.yaml index 2c2cb3cad5..dcce37c614 100644 --- a/k8s/geth/miners.deploy.yaml +++ b/k8s/geth/miners.deploy.yaml @@ -2,6 +2,7 @@ kind: StatefulSet apiVersion: apps/v1 metadata: name: miner + namespace: pow labels: universe: geth component: miner @@ -42,7 +43,8 @@ spec: - > geth --networkid=1337 - --bootnodes=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_SERVICE_HOST):$(GETH_BOOTNODE_SERVICE_PORT_BOOTNODE_UDP) + --bootnodesv4=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_V4_SERVICE_HOST):$(GETH_BOOTNODE_V4_SERVICE_PORT_BOOTNODE_UDP) + --bootnodesv5=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_V5_SERVICE_HOST):$(GETH_BOOTNODE_V5_SERVICE_PORT_BOOTNODE_UDP) --ethstats=$HOSTNAME:$(ETHSTATS_WS_SECRET)@$(GETH_ETHSTATS_SERVICE_HOST):$(GETH_ETHSTATS_SERVICE_PORT) --rpc --rpcaddr=0.0.0.0 @@ -53,7 +55,7 @@ spec: --verbosity=4 --mine --minerthreads=1 - --etherbase=0x717c3a6e4cbd476c2312612155eb233bf498dd5b + --etherbase=0x8882042b8e93c85312f623f058ef252c8025a7ae --extradata=$HOSTNAME --ethash.dagsinmem=1 --ethash.dagsondisk=2 @@ -82,7 +84,7 @@ spec: memory: "2Gi" cpu: "500m" limits: - memory: "2.5Gi" + memory: "4Gi" cpu: "500m" initContainers: - name: genesis @@ -111,4 +113,4 @@ spec: accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: 2Gi + storage: 5Gi diff --git a/k8s/geth/namespace.yaml b/k8s/geth/namespace.yaml new file mode 100644 index 0000000000..54aa9d5325 --- /dev/null +++ b/k8s/geth/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: pow diff --git a/k8s/geth/nodes.deploy.yaml b/k8s/geth/nodes.deploy.yaml index 55f752a386..cd627dc4b2 100644 --- a/k8s/geth/nodes.deploy.yaml +++ b/k8s/geth/nodes.deploy.yaml @@ -2,6 +2,7 @@ kind: Deployment apiVersion: apps/v1beta1 metadata: name: node + namespace: pow labels: universe: geth component: node @@ -41,11 +42,13 @@ spec: - > geth --networkid=1337 - --bootnodes=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_SERVICE_HOST):$(GETH_BOOTNODE_SERVICE_PORT_BOOTNODE_UDP) + --bootnodesv4=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_V4_SERVICE_HOST):$(GETH_BOOTNODE_V4_SERVICE_PORT_BOOTNODE_UDP) + --bootnodesv5=enode://$(BOOTNODE_PUBKEY)@$(GETH_BOOTNODE_V5_SERVICE_HOST):$(GETH_BOOTNODE_V5_SERVICE_PORT_BOOTNODE_UDP) --ethstats=$HOSTNAME:$(ETHSTATS_WS_SECRET)@$(GETH_ETHSTATS_SERVICE_HOST):$(GETH_ETHSTATS_SERVICE_PORT) --rpc --rpcaddr=0.0.0.0 --rpccorsdomain="*" + --rpcvhosts="*" --ws --wsaddr=0.0.0.0 --wsorigins="*" @@ -53,6 +56,7 @@ spec: --debug --verbosity=4 --nousb + --lightserv=50 volumeMounts: - name: chaindata mountPath: "/ethereum" diff --git a/k8s/geth/nodes.service.yaml b/k8s/geth/nodes.service.yaml index dda774f971..44fc3e3cc6 100644 --- a/k8s/geth/nodes.service.yaml +++ b/k8s/geth/nodes.service.yaml @@ -2,6 +2,7 @@ kind: Service apiVersion: v1 metadata: name: geth-nodes + namespace: pow spec: selector: component: node @@ -15,4 +16,4 @@ spec: targetPort: 8546 name: ws protocol: TCP - type: LoadBalancer \ No newline at end of file + type: ClusterIP diff --git a/k8s/monitoring/BUILD.bazel b/k8s/monitoring/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/k8s/monitoring/ingress.yaml b/k8s/monitoring/ingress.yaml new file mode 100644 index 0000000000..29d7e374d3 --- /dev/null +++ b/k8s/monitoring/ingress.yaml @@ -0,0 +1,29 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: nginx-ingress + namespace: monitoring +spec: + rules: + - host: alertmanager.prylabs.network + http: + paths: + - path: / + backend: + serviceName: alertmanager + servicePort: 9093 + - host: grafana.prylabs.network + http: + paths: + - path: / + backend: + serviceName: grafana + servicePort: 3000 + - host: prometheus.prylabs.network + http: + paths: + - path: / + backend: + serviceName: prometheus + servicePort: 9090 + diff --git a/k8s/monitoring/manifests-all.yaml b/k8s/monitoring/manifests-all.yaml new file mode 100644 index 0000000000..095b12c934 --- /dev/null +++ b/k8s/monitoring/manifests-all.yaml @@ -0,0 +1,2899 @@ +# Derived from https://github.com/giantswarm/kubernetes-prometheus +# All deployments should have priorityClassName: monitoring-priority. +# +# This should be broken into smaller pieces. +--- +apiVersion: v1 +kind: Namespace +metadata: + name: monitoring +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: prometheus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: monitoring +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: prometheus +rules: +- apiGroups: [""] + resources: + - nodes + - nodes/proxy + - services + - endpoints + - pods + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: + - configmaps + verbs: ["get"] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: prometheus-k8s + namespace: monitoring +--- +apiVersion: v1 +data: + default.tmpl: | + {{ define "__alertmanager" }}AlertManager{{ end }} + {{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver }}{{ end }} + + {{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }} + {{ define "__description" }}{{ end }} + + {{ define "__text_alert_list" }}{{ range . }}Labels: + {{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }} + {{ end }}Annotations: + {{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }} + {{ end }}Source: {{ .GeneratorURL }} + {{ end }}{{ end }} + + + {{ define "slack.default.title" }}{{ template "__subject" . }}{{ end }} + {{ define "slack.default.username" }}{{ template "__alertmanager" . }}{{ end }} + {{ define "slack.default.fallback" }}{{ template "slack.default.title" . }} | {{ template "slack.default.titlelink" . }}{{ end }} + {{ define "slack.default.pretext" }}{{ end }} + {{ define "slack.default.titlelink" }}{{ template "__alertmanagerURL" . }}{{ end }} + {{ define "slack.default.iconemoji" }}{{ end }} + {{ define "slack.default.iconurl" }}{{ end }} + {{ define "slack.default.text" }}{{ end }} + + + {{ define "hipchat.default.from" }}{{ template "__alertmanager" . }}{{ end }} + {{ define "hipchat.default.message" }}{{ template "__subject" . }}{{ end }} + + + {{ define "pagerduty.default.description" }}{{ template "__subject" . }}{{ end }} + {{ define "pagerduty.default.client" }}{{ template "__alertmanager" . }}{{ end }} + {{ define "pagerduty.default.clientURL" }}{{ template "__alertmanagerURL" . }}{{ end }} + {{ define "pagerduty.default.instances" }}{{ template "__text_alert_list" . }}{{ end }} + + + {{ define "opsgenie.default.message" }}{{ template "__subject" . }}{{ end }} + {{ define "opsgenie.default.description" }}{{ .CommonAnnotations.SortedPairs.Values | join " " }} + {{ if gt (len .Alerts.Firing) 0 -}} + Alerts Firing: + {{ template "__text_alert_list" .Alerts.Firing }} + {{- end }} + {{ if gt (len .Alerts.Resolved) 0 -}} + Alerts Resolved: + {{ template "__text_alert_list" .Alerts.Resolved }} + {{- end }} + {{- end }} + {{ define "opsgenie.default.source" }}{{ template "__alertmanagerURL" . }}{{ end }} + + + {{ define "victorops.default.message" }}{{ template "__subject" . }} | {{ template "__alertmanagerURL" . }}{{ end }} + {{ define "victorops.default.from" }}{{ template "__alertmanager" . }}{{ end }} + + + {{ define "email.default.subject" }}{{ template "__subject" . }}{{ end }} + {{ define "email.default.html" }} + + + + + + + {{ template "__subject" . }} + + + + + + + + + + + +
+
+ + + + + + + +
+ {{ .Alerts | len }} alert{{ if gt (len .Alerts) 1 }}s{{ end }} for {{ range .GroupLabels.SortedPairs }} + {{ .Name }}={{ .Value }} + {{ end }} +
+ + + + + {{ if gt (len .Alerts.Firing) 0 }} + + + + {{ end }} + {{ range .Alerts.Firing }} + + + + {{ end }} + + {{ if gt (len .Alerts.Resolved) 0 }} + {{ if gt (len .Alerts.Firing) 0 }} + + + + {{ end }} + + + + {{ end }} + {{ range .Alerts.Resolved }} + + + + {{ end }} +
+ View in {{ template "__alertmanager" . }} +
+ [{{ .Alerts.Firing | len }}] Firing +
+ Labels
+ {{ range .Labels.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + {{ if gt (len .Annotations) 0 }}Annotations
{{ end }} + {{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + Source
+
+
+
+
+
+ [{{ .Alerts.Resolved | len }}] Resolved +
+ Labels
+ {{ range .Labels.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + {{ if gt (len .Annotations) 0 }}Annotations
{{ end }} + {{ range .Annotations.SortedPairs }}{{ .Name }} = {{ .Value }}
{{ end }} + Source
+
+
+ +
+
+ + + + + {{ end }} + + {{ define "pushover.default.title" }}{{ template "__subject" . }}{{ end }} + {{ define "pushover.default.message" }}{{ .CommonAnnotations.SortedPairs.Values | join " " }} + {{ if gt (len .Alerts.Firing) 0 }} + Alerts Firing: + {{ template "__text_alert_list" .Alerts.Firing }} + {{ end }} + {{ if gt (len .Alerts.Resolved) 0 }} + Alerts Resolved: + {{ template "__text_alert_list" .Alerts.Resolved }} + {{ end }} + {{ end }} + {{ define "pushover.default.url" }}{{ template "__alertmanagerURL" . }}{{ end }} + slack.tmpl: | + {{ define "slack.devops.text" }} + {{range .Alerts}}{{.Annotations.DESCRIPTION}} + {{end}} + {{ end }} +kind: ConfigMap +metadata: + creationTimestamp: null + name: alertmanager-templates + namespace: monitoring +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: alertmanager + namespace: monitoring +data: + config.yml: |- + global: + # ResolveTimeout is the time after which an alert is declared resolved + # if it has not been updated. + resolve_timeout: 5m + + # The smarthost and SMTP sender used for mail notifications. + smtp_smarthost: 'smtp.gmail.com:587' + smtp_from: 'foo@bar.com' + smtp_auth_username: 'foo@bar.com' + smtp_auth_password: 'barfoo' + + # The API URL to use for Slack notifications. + slack_api_url: 'https://hooks.slack.com/services/some/api/token' + + # # The directory from which notification templates are read. + templates: + - '/etc/alertmanager-templates/*.tmpl' + + # The root route on which each incoming alert enters. + route: + + # The labels by which incoming alerts are grouped together. For example, + # multiple alerts coming in for cluster=A and alertname=LatencyHigh would + # be batched into a single group. + + group_by: ['alertname', 'cluster', 'service'] + + # When a new group of alerts is created by an incoming alert, wait at + # least 'group_wait' to send the initial notification. + # This way ensures that you get multiple alerts for the same group that start + # firing shortly after another are batched together on the first + # notification. + + group_wait: 30s + + # When the first notification was sent, wait 'group_interval' to send a batch + # of new alerts that started firing for that group. + + group_interval: 5m + + # If an alert has successfully been sent, wait 'repeat_interval' to + # resend them. + + #repeat_interval: 1m + repeat_interval: 15m + + # A default receiver + + # If an alert isn't caught by a route, send it to default. + receiver: default + + # All the above attributes are inherited by all child routes and can + # overwritten on each. + + # The child route trees. + routes: + # Send severity=slack alerts to slack. + - match: + severity: slack + receiver: slack_alert + # - match: + # severity: email + # receiver: email_alert + + receivers: + - name: 'default' + slack_configs: + - channel: '#alertmanager-test' + text: '{{ template "slack.devops.text" . }}' + send_resolved: true + + - name: 'slack_alert' + slack_configs: + - channel: '#alertmanager-test' + send_resolved: true +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: alertmanager + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + app: alertmanager + template: + metadata: + name: alertmanager + labels: + app: alertmanager + spec: + priorityClassName: monitoring-priority + containers: + - name: alertmanager + image: quay.io/prometheus/alertmanager:v0.7.1 + args: + - '-config.file=/etc/alertmanager/config.yml' + - '-storage.path=/alertmanager' + ports: + - name: alertmanager + containerPort: 9093 + volumeMounts: + - name: config-volume + mountPath: /etc/alertmanager + - name: templates-volume + mountPath: /etc/alertmanager-templates + - name: alertmanager + mountPath: /alertmanager + volumes: + - name: config-volume + configMap: + name: alertmanager + - name: templates-volume + configMap: + name: alertmanager-templates + - name: alertmanager + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/scrape: 'true' + prometheus.io/path: '/metrics' + labels: + name: alertmanager + name: alertmanager + namespace: monitoring +spec: + selector: + app: alertmanager + type: ClusterIP + ports: + - name: alertmanager + protocol: TCP + port: 9093 + targetPort: 9093 +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: grafana-core + namespace: monitoring + labels: + app: grafana + component: core +spec: + replicas: 1 + template: + metadata: + labels: + app: grafana + component: core + spec: + priorityClassName: monitoring-priority + containers: + - image: grafana/grafana:4.2.0 + name: grafana-core + imagePullPolicy: IfNotPresent + # env: + resources: + # keep request = limit to keep this container in guaranteed class + limits: + cpu: 100m + memory: 100Mi + requests: + cpu: 100m + memory: 100Mi + env: + # The following env variables set up basic auth twith the default admin user and admin password. + - name: GF_AUTH_BASIC_ENABLED + value: "true" + - name: GF_SECURITY_ADMIN_USER + valueFrom: + secretKeyRef: + name: grafana + key: admin-username + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: grafana + key: admin-password + - name: GF_AUTH_ANONYMOUS_ENABLED + value: "false" + # - name: GF_AUTH_ANONYMOUS_ORG_ROLE + # value: Admin + # does not really work, because of template variables in exported dashboards: + # - name: GF_DASHBOARDS_JSON_ENABLED + # value: "true" + readinessProbe: + httpGet: + path: /login + port: 3000 + # initialDelaySeconds: 30 + # timeoutSeconds: 1 + volumeMounts: + - name: grafana-persistent-storage + mountPath: /var/lib/grafana + volumes: + - name: grafana-persistent-storage + emptyDir: {} +--- +apiVersion: v1 +data: + grafana-net-2-dashboard.json: | + { + "__inputs": [{ + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + }], + "__requires": [{ + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "" + }, { + "type": "panel", + "id": "text", + "name": "Text", + "version": "" + }, { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "3.1.0" + }, { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }], + "id": null, + "title": "Prometheus Stats", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": true, + "sharedCrosshair": false, + "rows": [{ + "collapse": false, + "editable": true, + "height": 178, + "panels": [{ + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"], + "datasource": "${DS_PROMETHEUS}", + "decimals": 1, + "editable": true, + "error": false, + "format": "s", + "id": 5, + "interval": null, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "(time() - process_start_time_seconds{job=\"prometheus\"})", + "intervalFactor": 2, + "refId": "A", + "step": 4 + }], + "thresholds": "", + "title": "Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current", + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "rangeMaps": [{ + "from": "null", + "to": "null", + "text": "N/A" + }], + "mappingType": 1, + "gauge": { + "show": false, + "minValue": 0, + "maxValue": 100, + "thresholdMarkers": true, + "thresholdLabels": false + } + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": ["rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)"], + "datasource": "${DS_PROMETHEUS}", + "editable": true, + "error": false, + "format": "none", + "id": 6, + "interval": null, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "targets": [{ + "expr": "prometheus_local_storage_memory_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + }], + "thresholds": "1,5", + "title": "Local Storage Memory Series", + "type": "singlestat", + "valueFontSize": "70%", + "valueMaps": [], + "valueName": "current", + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "rangeMaps": [{ + "from": "null", + "to": "null", + "text": "N/A" + }], + "mappingType": 1, + "gauge": { + "show": false, + "minValue": 0, + "maxValue": 100, + "thresholdMarkers": true, + "thresholdLabels": false + } + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": ["rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)"], + "datasource": "${DS_PROMETHEUS}", + "editable": true, + "error": false, + "format": "none", + "id": 7, + "interval": null, + "links": [], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "span": 3, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "targets": [{ + "expr": "prometheus_local_storage_indexing_queue_length", + "intervalFactor": 2, + "refId": "A", + "step": 4 + }], + "thresholds": "500,4000", + "title": "Internal Storage Queue Length", + "type": "singlestat", + "valueFontSize": "70%", + "valueMaps": [{ + "op": "=", + "text": "Empty", + "value": "0" + }], + "valueName": "current", + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "rangeMaps": [{ + "from": "null", + "to": "null", + "text": "N/A" + }], + "mappingType": 1, + "gauge": { + "show": false, + "minValue": 0, + "maxValue": 100, + "thresholdMarkers": true, + "thresholdLabels": false + } + }, { + "content": "\"Prometheus\nPrometheus\n\n

You're using Prometheus, an open-source systems monitoring and alerting toolkit originally built at SoundCloud. For more information, check out the Grafana and Prometheus projects.

", + "editable": true, + "error": false, + "id": 9, + "links": [], + "mode": "html", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + }], + "title": "New row" + }, { + "collapse": false, + "editable": true, + "height": 227, + "panels": [{ + "aliasColors": { + "prometheus": "#C15C17", + "{instance=\"localhost:9090\",job=\"prometheus\"}": "#C15C17" + }, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "rate(prometheus_local_storage_ingested_samples_total[5m])", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{job}}", + "metric": "", + "refId": "A", + "step": 2 + }], + "timeFrom": null, + "timeShift": null, + "title": "Samples ingested (rate-5m)", + "tooltip": { + "shared": true, + "value_type": "cumulative", + "ordering": "alphabetical", + "msResolution": false + }, + "type": "graph", + "yaxes": [{ + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }, { + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }], + "xaxis": { + "show": true + } + }, { + "content": "#### Samples Ingested\nThis graph displays the count of samples ingested by the Prometheus server, as measured over the last 5 minutes, per time series in the range vector. When troubleshooting an issue on IRC or Github, this is often the first stat requested by the Prometheus team. ", + "editable": true, + "error": false, + "id": 8, + "links": [], + "mode": "markdown", + "span": 2.995914043583536, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + }], + "title": "New row" + }, { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [{ + "aliasColors": { + "prometheus": "#F9BA8F", + "{instance=\"localhost:9090\",interval=\"5s\",job=\"prometheus\"}": "#F9BA8F" + }, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "rate(prometheus_target_interval_length_seconds_count[5m])", + "intervalFactor": 2, + "legendFormat": "{{job}}", + "refId": "A", + "step": 2 + }], + "timeFrom": null, + "timeShift": null, + "title": "Target Scrapes (last 5m)", + "tooltip": { + "shared": true, + "value_type": "cumulative", + "ordering": "alphabetical", + "msResolution": false + }, + "type": "graph", + "yaxes": [{ + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }, { + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }], + "xaxis": { + "show": true + } + }, { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "prometheus_target_interval_length_seconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}} ({{interval}})", + "metric": "", + "refId": "A", + "step": 2 + }], + "timeFrom": null, + "timeShift": null, + "title": "Scrape Duration", + "tooltip": { + "shared": true, + "value_type": "cumulative", + "ordering": "alphabetical", + "msResolution": false + }, + "type": "graph", + "yaxes": [{ + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }, { + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }], + "xaxis": { + "show": true + } + }, { + "content": "#### Scrapes\nPrometheus scrapes metrics from instrumented jobs, either directly or via an intermediary push gateway for short-lived jobs. Target scrapes will show how frequently targets are scraped, as measured over the last 5 minutes, per time series in the range vector. Scrape Duration will show how long the scrapes are taking, with percentiles available as series. ", + "editable": true, + "error": false, + "id": 11, + "links": [], + "mode": "markdown", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + }], + "title": "New row" + }, { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [{ + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 12, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "prometheus_evaluator_duration_milliseconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}}", + "refId": "A", + "step": 2 + }], + "timeFrom": null, + "timeShift": null, + "title": "Rule Eval Duration", + "tooltip": { + "shared": true, + "value_type": "cumulative", + "ordering": "alphabetical", + "msResolution": false + }, + "type": "graph", + "yaxes": [{ + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "percentunit", + "label": "" + }, { + "show": true, + "min": null, + "max": null, + "logBase": 1, + "format": "short" + }], + "xaxis": { + "show": true + } + }, { + "content": "#### Rule Evaluation Duration\nThis graph panel plots the duration for all evaluations to execute. The 50th percentile, 90th percentile and 99th percentile are shown as three separate series to help identify outliers that may be skewing the data.", + "editable": true, + "error": false, + "id": 15, + "links": [], + "mode": "markdown", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + }], + "title": "New row" + }], + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], + "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": false, + "schemaVersion": 12, + "version": 0, + "links": [{ + "icon": "info", + "tags": [], + "targetBlank": true, + "title": "Grafana Docs", + "tooltip": "", + "type": "link", + "url": "http://www.grafana.org/docs" + }, { + "icon": "info", + "tags": [], + "targetBlank": true, + "title": "Prometheus Docs", + "type": "link", + "url": "http://prometheus.io/docs/introduction/overview/" + }], + "gnetId": 2, + "description": "The official, pre-built Prometheus Stats Dashboard." + } + grafana-net-737-dashboard.json: | + { + "__inputs": [{ + "name": "DS_PROMETHEUS", + "label": "prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + }], + "__requires": [{ + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "" + }, { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "3.1.0" + }, { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }], + "id": null, + "title": "Kubernetes Pod Resources", + "description": "Shows resource usage of Kubernetes pods.", + "tags": [ + "kubernetes" + ], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "sharedCrosshair": false, + "rows": [{ + "collapse": false, + "editable": true, + "height": "250px", + "panels": [{ + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "180px", + "id": 4, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum (container_memory_working_set_bytes{id=\"/\",instance=~\"^$instance$\"}) / sum (machine_memory_bytes{instance=~\"^$instance$\"}) * 100", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "refId": "A", + "step": 2 + }], + "thresholds": "65, 90", + "timeFrom": "1m", + "timeShift": null, + "title": "Memory Working Set", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "180px", + "id": 6, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum(rate(container_cpu_usage_seconds_total{id=\"/\",instance=~\"^$instance$\"}[1m])) / sum (machine_cpu_cores{instance=~\"^$instance$\"}) * 100", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "65, 90", + "timeFrom": "1m", + "timeShift": null, + "title": "Cpu Usage", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "180px", + "id": 7, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum(container_fs_usage_bytes{id=\"/\",instance=~\"^$instance$\"}) / sum(container_fs_limit_bytes{id=\"/\",instance=~\"^$instance$\"}) * 100", + "interval": "10s", + "intervalFactor": 1, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 10 + }], + "thresholds": "65, 90", + "timeFrom": "1m", + "timeShift": null, + "title": "Filesystem Usage", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "hideTimeOverride": true, + "id": 9, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum(container_memory_working_set_bytes{id=\"/\",instance=~\"^$instance$\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "", + "timeFrom": "1m", + "title": "Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "hideTimeOverride": true, + "id": 10, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum (machine_memory_bytes{instance=~\"^$instance$\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "", + "timeFrom": "1m", + "title": "Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "hideTimeOverride": true, + "id": 11, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": " cores", + "postfixFontSize": "30%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum (rate (container_cpu_usage_seconds_total{id=\"/\",instance=~\"^$instance$\"}[1m]))", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "", + "timeFrom": "1m", + "timeShift": null, + "title": "Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "hideTimeOverride": true, + "id": 12, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": " cores", + "postfixFontSize": "30%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum (machine_cpu_cores{instance=~\"^$instance$\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "", + "timeFrom": "1m", + "title": "Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "hideTimeOverride": true, + "id": 13, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum(container_fs_usage_bytes{id=\"/\",instance=~\"^$instance$\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "", + "timeFrom": "1m", + "title": "Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "hideTimeOverride": true, + "id": 14, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [{ + "name": "value to text", + "value": 1 + }, { + "name": "range to text", + "value": 2 + }], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [{ + "from": "null", + "text": "N/A", + "to": "null" + }], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "targets": [{ + "expr": "sum (container_fs_limit_bytes{id=\"/\",instance=~\"^$instance$\"})", + "interval": "10s", + "intervalFactor": 1, + "refId": "A", + "step": 10 + }], + "thresholds": "", + "timeFrom": "1m", + "title": "Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [{ + "op": "=", + "text": "N/A", + "value": "null" + }], + "valueName": "current" + }, { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)", + "thresholdLine": false + }, + "height": "200px", + "id": 32, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "sum(rate(container_network_receive_bytes_total{instance=~\"^$instance$\",namespace=~\"^$namespace$\"}[1m]))", + "interval": "", + "intervalFactor": 2, + "legendFormat": "receive", + "metric": "network", + "refId": "A", + "step": 240 + }, { + "expr": "- sum(rate(container_network_transmit_bytes_total{instance=~\"^$instance$\",namespace=~\"^$namespace$\"}[1m]))", + "interval": "", + "intervalFactor": 2, + "legendFormat": "transmit", + "metric": "network", + "refId": "B", + "step": 240 + }], + "timeFrom": null, + "timeShift": null, + "title": "Network", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [{ + "format": "Bps", + "label": "transmit / receive", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + }] + }], + "showTitle": true, + "title": "all pods" + }, { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [{ + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 3, + "editable": true, + "error": false, + "fill": 0, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "height": "", + "id": 17, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "sum(rate(container_cpu_usage_seconds_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[1m])) by (pod_name)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ pod_name }}", + "metric": "container_cpu", + "refId": "A", + "step": 240 + }], + "timeFrom": null, + "timeShift": null, + "title": "Cpu Usage", + "tooltip": { + "msResolution": true, + "shared": false, + "sort": 2, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [{ + "format": "none", + "label": "cores", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + }] + }, { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 0, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 33, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "sum (container_memory_working_set_bytes{image!=\"\",name=~\"^k8s_.*\",instance=~\"^$instance$\",namespace=~\"^$namespace$\"}) by (pod_name)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ pod_name }}", + "metric": "", + "refId": "A", + "step": 240 + }], + "timeFrom": null, + "timeShift": null, + "title": "Memory Working Set", + "tooltip": { + "msResolution": false, + "shared": false, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [{ + "format": "bytes", + "label": "used", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + }] + }, { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 16, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "sum (rate (container_network_receive_bytes_total{image!=\"\",name=~\"^k8s_.*\",instance=~\"^$instance$\",namespace=~\"^$namespace$\"}[1m])) by (pod_name)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ pod_name }} < in", + "metric": "network", + "refId": "A", + "step": 240 + }, { + "expr": "- sum (rate (container_network_transmit_bytes_total{image!=\"\",name=~\"^k8s_.*\",instance=~\"^$instance$\",namespace=~\"^$namespace$\"}[1m])) by (pod_name)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ pod_name }} > out", + "metric": "network", + "refId": "B", + "step": 240 + }], + "timeFrom": null, + "timeShift": null, + "title": "Network", + "tooltip": { + "msResolution": false, + "shared": false, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [{ + "format": "Bps", + "label": "transmit / receive", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + }] + }, { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_PROMETHEUS}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": { + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 34, + "isNew": true, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [{ + "expr": "sum(container_fs_usage_bytes{image!=\"\",name=~\"^k8s_.*\",instance=~\"^$instance$\",namespace=~\"^$namespace$\"}) by (pod_name)", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ pod_name }}", + "metric": "network", + "refId": "A", + "step": 240 + }], + "timeFrom": null, + "timeShift": null, + "title": "Filesystem", + "tooltip": { + "msResolution": false, + "shared": false, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "show": true + }, + "yaxes": [{ + "format": "bytes", + "label": "used", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + }] + }], + "showTitle": true, + "title": "each pod" + }], + "time": { + "from": "now-3d", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [{ + "allValue": ".*", + "current": {}, + "datasource": "${DS_PROMETHEUS}", + "hide": 0, + "includeAll": true, + "label": "Instance", + "multi": false, + "name": "instance", + "options": [], + "query": "label_values(instance)", + "refresh": 1, + "regex": "", + "type": "query" + }, { + "current": {}, + "datasource": "${DS_PROMETHEUS}", + "hide": 0, + "includeAll": true, + "label": "Namespace", + "multi": true, + "name": "namespace", + "options": [], + "query": "label_values(namespace)", + "refresh": 1, + "regex": "", + "type": "query" + }] + }, + "annotations": { + "list": [] + }, + "refresh": false, + "schemaVersion": 12, + "version": 8, + "links": [], + "gnetId": 737 + } + prometheus-datasource.json: | + { + "name": "prometheus", + "type": "prometheus", + "url": "http://prometheus:9090", + "access": "proxy", + "basicAuth": false + } +kind: ConfigMap +metadata: + creationTimestamp: null + name: grafana-import-dashboards + namespace: monitoring +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: grafana-import-dashboards + namespace: monitoring + labels: + app: grafana + component: import-dashboards +spec: + template: + metadata: + name: grafana-import-dashboards + labels: + app: grafana + component: import-dashboards + spec: + serviceAccountName: prometheus-k8s + initContainers: + - name: wait-for-grafana + image: giantswarm/tiny-tools + args: + - /bin/sh + - -c + - > + set -x; + while [ $(curl -sw '%{http_code}' "http://grafana:3000" -o /dev/null) -ne 200]; do + echo '.' + sleep 15; + done + containers: + - name: grafana-import-dashboards + image: giantswarm/tiny-tools + command: ["/bin/sh", "-c"] + workingDir: /opt/grafana-import-dashboards + args: + - > + for file in *-datasource.json ; do + if [ -e "$file" ] ; then + echo "importing $file" && + curl --silent --fail --show-error \ + --request POST http://${GF_ADMIN_USER}:${GF_ADMIN_PASSWORD}@grafana:3000/api/datasources \ + --header "Content-Type: application/json" \ + --data-binary "@$file" ; + echo "" ; + fi + done ; + for file in *-dashboard.json ; do + if [ -e "$file" ] ; then + echo "importing $file" && + ( echo '{"dashboard":'; \ + cat "$file"; \ + echo ',"overwrite":true,"inputs":[{"name":"DS_PROMETHEUS","type":"datasource","pluginId":"prometheus","value":"prometheus"}]}' ) \ + | jq -c '.' \ + | curl --silent --fail --show-error \ + --request POST http://${GF_ADMIN_USER}:${GF_ADMIN_PASSWORD}@grafana:3000/api/dashboards/import \ + --header "Content-Type: application/json" \ + --data-binary "@-" ; + echo "" ; + fi + done + + env: + - name: GF_ADMIN_USER + valueFrom: + secretKeyRef: + name: grafana + key: admin-username + - name: GF_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: grafana + key: admin-password + volumeMounts: + - name: config-volume + mountPath: /opt/grafana-import-dashboards + restartPolicy: Never + volumes: + - name: config-volume + configMap: + name: grafana-import-dashboards +--- +# apiVersion: extensions/v1beta1 +# kind: Ingress +# metadata: +# name: grafana +# namespace: monitoring +# spec: +# rules: +# - host: ..k8s.gigantic.io +# http: +# paths: +# - path: / +# backend: +# serviceName: grafana +# servicePort: 3000 +--- +apiVersion: v1 +kind: Secret +data: + admin-password: YWRtaW4= + admin-username: YWRtaW4= +metadata: + name: grafana + namespace: monitoring +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + name: grafana + namespace: monitoring + labels: + app: grafana + component: core +spec: + type: ClusterIP + ports: + - port: 3000 + selector: + app: grafana + component: core +--- +apiVersion: v1 +data: + prometheus.yaml: | + global: + scrape_interval: 10s + scrape_timeout: 10s + evaluation_interval: 10s + rule_files: + - "/etc/prometheus-rules/*.rules" + scrape_configs: + + # https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml#L37 + - job_name: 'kubernetes-nodes' + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + kubernetes_sd_configs: + - role: node + relabel_configs: + - source_labels: [__address__] + regex: '(.*):10250' + replacement: '${1}:10255' + target_label: __address__ + + # https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml#L79 + - job_name: 'kubernetes-endpoints' + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: (.+)(?::\d+);(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: kubernetes_name + + # https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml#L119 + - job_name: 'kubernetes-services' + metrics_path: /probe + params: + module: [http_2xx] + kubernetes_sd_configs: + - role: service + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] + action: keep + regex: true + - source_labels: [__address__] + target_label: __param_target + - target_label: __address__ + replacement: blackbox + - source_labels: [__param_target] + target_label: instance + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_service_name] + target_label: kubernetes_name + + # https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml#L156 + - job_name: 'kubernetes-pods' + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: (.+):(?:\d+);(\d+) + replacement: ${1}:${2} + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + - source_labels: [__meta_kubernetes_pod_container_port_number] + action: keep + regex: 9\d{3} + + - job_name: 'kubernetes-cadvisor' + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + kubernetes_sd_configs: + - role: node + relabel_configs: + - action: labelmap + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - target_label: __address__ + replacement: kubernetes.default.svc:443 + - source_labels: [__meta_kubernetes_node_name] + regex: (.+) + target_label: __metrics_path__ + replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor + +kind: ConfigMap +metadata: + creationTimestamp: null + name: prometheus-core + namespace: monitoring +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: prometheus-core + namespace: monitoring + labels: + app: prometheus + component: core +spec: + replicas: 1 + template: + metadata: + name: prometheus-main + labels: + app: prometheus + component: core + spec: + priorityClassName: monitoring-priority + serviceAccountName: prometheus-k8s + containers: + - name: prometheus + image: prom/prometheus:v1.7.0 + args: + - '-storage.local.retention=12h' + - '-storage.local.memory-chunks=500000' + - '-config.file=/etc/prometheus/prometheus.yaml' + - '-alertmanager.url=http://alertmanager:9093/' + ports: + - name: webui + containerPort: 9090 + resources: + requests: + cpu: 500m + memory: 500M + limits: + cpu: 500m + memory: 500M + volumeMounts: + - name: config-volume + mountPath: /etc/prometheus + - name: rules-volume + mountPath: /etc/prometheus-rules + volumes: + - name: config-volume + configMap: + name: prometheus-core + - name: rules-volume + configMap: + name: prometheus-rules +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: kube-state-metrics + namespace: monitoring +spec: + replicas: 1 + template: + metadata: + labels: + app: kube-state-metrics + spec: + serviceAccountName: kube-state-metrics + priorityClassName: monitoring-priority + containers: + - name: kube-state-metrics + image: gcr.io/google_containers/kube-state-metrics:v0.5.0 + ports: + - containerPort: 8080 +--- +# --- +# apiVersion: rbac.authorization.k8s.io/v1beta1 +# kind: ClusterRoleBinding +# metadata: +# name: kube-state-metrics +# roleRef: +# apiGroup: rbac.authorization.k8s.io +# kind: ClusterRole +# name: kube-state-metrics +# subjects: +# - kind: ServiceAccount +# name: kube-state-metrics +# namespace: monitoring +# --- +# apiVersion: rbac.authorization.k8s.io/v1beta1 +# kind: ClusterRole +# metadata: +# name: kube-state-metrics +# rules: +# - apiGroups: [""] +# resources: +# - nodes +# - pods +# - services +# - resourcequotas +# - replicationcontrollers +# - limitranges +# verbs: ["list", "watch"] +# - apiGroups: ["extensions"] +# resources: +# - daemonsets +# - deployments +# - replicasets +# verbs: ["list", "watch"] +# --- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kube-state-metrics + namespace: monitoring +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/scrape: 'true' + name: kube-state-metrics + namespace: monitoring + labels: + app: kube-state-metrics +spec: + ports: + - name: kube-state-metrics + port: 8080 + protocol: TCP + selector: + app: kube-state-metrics + +--- +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: node-directory-size-metrics + namespace: monitoring + annotations: + description: | + This `DaemonSet` provides metrics in Prometheus format about disk usage on the nodes. + The container `read-du` reads in sizes of all directories below /mnt and writes that to `/tmp/metrics`. It only reports directories larger then `100M` for now. + The other container `caddy` just hands out the contents of that file on request via `http` on `/metrics` at port `9102` which are the defaults for Prometheus. + These are scheduled on every node in the Kubernetes cluster. + To choose directories from the node to check, just mount them on the `read-du` container below `/mnt`. +spec: + template: + metadata: + labels: + app: node-directory-size-metrics + annotations: + prometheus.io/scrape: 'true' + prometheus.io/port: '9102' + description: | + This `Pod` provides metrics in Prometheus format about disk usage on the node. + The container `read-du` reads in sizes of all directories below /mnt and writes that to `/tmp/metrics`. It only reports directories larger then `100M` for now. + The other container `caddy` just hands out the contents of that file on request on `/metrics` at port `9102` which are the defaults for Prometheus. + This `Pod` is scheduled on every node in the Kubernetes cluster. + To choose directories from the node to check just mount them on `read-du` below `/mnt`. + spec: + containers: + - name: read-du + image: giantswarm/tiny-tools + imagePullPolicy: Always + # FIXME threshold via env var + # The + command: + - fish + - --command + - | + touch /tmp/metrics-temp + while true + for directory in (du --bytes --separate-dirs --threshold=100M /mnt) + echo $directory | read size path + echo "node_directory_size_bytes{path=\"$path\"} $size" \ + >> /tmp/metrics-temp + end + mv /tmp/metrics-temp /tmp/metrics + sleep 300 + end + volumeMounts: + - name: host-fs-var + mountPath: /mnt/var + readOnly: true + - name: metrics + mountPath: /tmp + - name: caddy + image: dockermuenster/caddy:0.9.3 + command: + - "caddy" + - "-port=9102" + - "-root=/var/www" + ports: + - containerPort: 9102 + volumeMounts: + - name: metrics + mountPath: /var/www + volumes: + - name: host-fs-var + hostPath: + path: /var + - name: metrics + emptyDir: + medium: Memory +--- +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: prometheus-node-exporter + namespace: monitoring + labels: + app: prometheus + component: node-exporter +spec: + template: + metadata: + name: prometheus-node-exporter + labels: + app: prometheus + component: node-exporter + spec: + containers: + - image: prom/node-exporter:v0.14.0 + name: prometheus-node-exporter + ports: + - name: prom-node-exp + #^ must be an IANA_SVC_NAME (at most 15 characters, ..) + containerPort: 9100 + hostPort: 9100 + hostNetwork: true + hostPID: true +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/scrape: 'true' + name: prometheus-node-exporter + namespace: monitoring + labels: + app: prometheus + component: node-exporter +spec: + clusterIP: None + ports: + - name: prometheus-node-exporter + port: 9100 + protocol: TCP + selector: + app: prometheus + component: node-exporter + type: ClusterIP +--- +apiVersion: v1 +data: + cpu-usage.rules: | + ALERT NodeCPUUsage + IF (100 - (avg by (instance) (irate(node_cpu{name="node-exporter",mode="idle"}[5m])) * 100)) > 75 + FOR 2m + LABELS { + severity="page" + } + ANNOTATIONS { + SUMMARY = "{{$labels.instance}}: High CPU usage detected", + DESCRIPTION = "{{$labels.instance}}: CPU usage is above 75% (current value is: {{ $value }})" + } + instance-availability.rules: | + ALERT InstanceDown + IF up == 0 + FOR 1m + LABELS { severity = "page" } + ANNOTATIONS { + summary = "Instance {{ $labels.instance }} down", + description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute.", + } + low-disk-space.rules: | + ALERT NodeLowRootDisk + IF ((node_filesystem_size{mountpoint="/root-disk"} - node_filesystem_free{mountpoint="/root-disk"} ) / node_filesystem_size{mountpoint="/root-disk"} * 100) > 75 + FOR 2m + LABELS { + severity="page" + } + ANNOTATIONS { + SUMMARY = "{{$labels.instance}}: Low root disk space", + DESCRIPTION = "{{$labels.instance}}: Root disk usage is above 75% (current value is: {{ $value }})" + } + + ALERT NodeLowDataDisk + IF ((node_filesystem_size{mountpoint="/data-disk"} - node_filesystem_free{mountpoint="/data-disk"} ) / node_filesystem_size{mountpoint="/data-disk"} * 100) > 75 + FOR 2m + LABELS { + severity="page" + } + ANNOTATIONS { + SUMMARY = "{{$labels.instance}}: Low data disk space", + DESCRIPTION = "{{$labels.instance}}: Data disk usage is above 75% (current value is: {{ $value }})" + } + mem-usage.rules: | + ALERT NodeSwapUsage + IF (((node_memory_SwapTotal-node_memory_SwapFree)/node_memory_SwapTotal)*100) > 75 + FOR 2m + LABELS { + severity="page" + } + ANNOTATIONS { + SUMMARY = "{{$labels.instance}}: Swap usage detected", + DESCRIPTION = "{{$labels.instance}}: Swap usage usage is above 75% (current value is: {{ $value }})" + } + + ALERT NodeMemoryUsage + IF (((node_memory_MemTotal-node_memory_MemFree-node_memory_Cached)/(node_memory_MemTotal)*100)) > 75 + FOR 2m + LABELS { + severity="page" + } + ANNOTATIONS { + SUMMARY = "{{$labels.instance}}: High memory usage detected", + DESCRIPTION = "{{$labels.instance}}: Memory usage is above 75% (current value is: {{ $value }})" + } +kind: ConfigMap +metadata: + creationTimestamp: null + name: prometheus-rules + namespace: monitoring +--- +apiVersion: v1 +kind: Service +metadata: + name: prometheus + namespace: monitoring + labels: + app: prometheus + component: core + annotations: + prometheus.io/scrape: 'true' +spec: + type: ClusterIP + ports: + - port: 9090 + protocol: TCP + name: webui + selector: + app: prometheus + component: core diff --git a/k8s/nginx/BUILD.bazel b/k8s/nginx/BUILD.bazel new file mode 100644 index 0000000000..9b9127a16c --- /dev/null +++ b/k8s/nginx/BUILD.bazel @@ -0,0 +1,66 @@ +package(default_visibility = ["//k8s:__subpackages__"]) + +load("@io_bazel_rules_k8s//k8s:objects.bzl", "k8s_objects") +load("@k8s_cluster_role//:defaults.bzl", "k8s_cluster_role") +load("@k8s_configmap//:defaults.bzl", "k8s_configmap") +load("@k8s_deploy//:defaults.bzl", "k8s_deploy") +load("@k8s_namespace//:defaults.bzl", "k8s_namespace") +load("@k8s_secret//:defaults.bzl", "k8s_secret") +load("@k8s_service//:defaults.bzl", "k8s_service") +load("@k8s_service_account//:defaults.bzl", "k8s_service_account") + +k8s_objects( + name = "everything", + objects = [ + ":namespace", # Must be first + ":config", + ":default_server_secret", + ":deployment", + ":rbac", + ":service", + ":service_account", + ], +) + +_NAMESPACE = "nginx-ingress" + +k8s_secret( + name = "default_server_secret", + template = ":default-server-secret.yaml", + namespace = _NAMESPACE, +) + +k8s_deploy( + name = "deployment", + template = ":deployment.yaml", + namespace = _NAMESPACE, +) + +k8s_service( + name = "service", + template = ":loadbalancer.yaml", + namespace = _NAMESPACE, +) + +k8s_namespace( + name = "namespace", + template = ":namespace.yaml", +) + +k8s_configmap( + name = "config", + template = ":nginx-config.yaml", + namespace = _NAMESPACE, +) + +k8s_cluster_role( + name = "rbac", + template = ":rbac.yaml", + namespace = _NAMESPACE, +) + +k8s_service_account( + name = "service_account", + template = ":service-account.yaml", + namespace = _NAMESPACE, +) diff --git a/k8s/nginx/default-server-secret.yaml b/k8s/nginx/default-server-secret.yaml new file mode 100644 index 0000000000..027fde84d7 --- /dev/null +++ b/k8s/nginx/default-server-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: default-server-secret + namespace: nginx-ingress +type: Opaque +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN2akNDQWFZQ0NRREFPRjl0THNhWFhEQU5CZ2txaGtpRzl3MEJBUXNGQURBaE1SOHdIUVlEVlFRRERCWk8KUjBsT1dFbHVaM0psYzNORGIyNTBjbTlzYkdWeU1CNFhEVEU0TURreE1qRTRNRE16TlZvWERUSXpNRGt4TVRFNApNRE16TlZvd0lURWZNQjBHQTFVRUF3d1dUa2RKVGxoSmJtZHlaWE56UTI5dWRISnZiR3hsY2pDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUwvN2hIUEtFWGRMdjNyaUM3QlBrMTNpWkt5eTlyQ08KR2xZUXYyK2EzUDF0azIrS3YwVGF5aGRCbDRrcnNUcTZzZm8vWUk1Y2Vhbkw4WGM3U1pyQkVRYm9EN2REbWs1Qgo4eDZLS2xHWU5IWlg0Rm5UZ0VPaStlM2ptTFFxRlBSY1kzVnNPazFFeUZBL0JnWlJVbkNHZUtGeERSN0tQdGhyCmtqSXVuektURXUyaDU4Tlp0S21ScUJHdDEwcTNRYzhZT3ExM2FnbmovUWRjc0ZYYTJnMjB1K1lYZDdoZ3krZksKWk4vVUkxQUQ0YzZyM1lma1ZWUmVHd1lxQVp1WXN2V0RKbW1GNWRwdEMzN011cDBPRUxVTExSakZJOTZXNXIwSAo1TmdPc25NWFJNV1hYVlpiNWRxT3R0SmRtS3FhZ25TZ1JQQVpQN2MwQjFQU2FqYzZjNGZRVXpNQ0F3RUFBVEFOCkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQWpLb2tRdGRPcEsrTzhibWVPc3lySmdJSXJycVFVY2ZOUitjb0hZVUoKdGhrYnhITFMzR3VBTWI5dm15VExPY2xxeC9aYzJPblEwMEJCLzlTb0swcitFZ1U2UlVrRWtWcitTTFA3NTdUWgozZWI4dmdPdEduMS9ienM3bzNBaS9kclkrcUI5Q2k1S3lPc3FHTG1US2xFaUtOYkcyR1ZyTWxjS0ZYQU80YTY3Cklnc1hzYktNbTQwV1U3cG9mcGltU1ZmaXFSdkV5YmN3N0NYODF6cFErUyt1eHRYK2VBZ3V0NHh3VlI5d2IyVXYKelhuZk9HbWhWNThDd1dIQnNKa0kxNXhaa2VUWXdSN0diaEFMSkZUUkk3dkhvQXprTWIzbjAxQjQyWjNrN3RXNQpJUDFmTlpIOFUvOWxiUHNoT21FRFZkdjF5ZytVRVJxbStGSis2R0oxeFJGcGZnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdi91RWM4b1JkMHUvZXVJTHNFK1RYZUprckxMMnNJNGFWaEMvYjVyYy9XMlRiNHEvClJOcktGMEdYaVN1eE9ycXgrajlnamx4NXFjdnhkenRKbXNFUkJ1Z1B0ME9hVGtIekhvb3FVWmcwZGxmZ1dkT0EKUTZMNTdlT1l0Q29VOUZ4amRXdzZUVVRJVUQ4R0JsRlNjSVo0b1hFTkhzbysyR3VTTWk2Zk1wTVM3YUhudzFtMApxWkdvRWEzWFNyZEJ6eGc2clhkcUNlUDlCMXl3VmRyYURiUzc1aGQzdUdETDU4cGszOVFqVUFQaHpxdmRoK1JWClZGNGJCaW9CbTVpeTlZTW1hWVhsMm0wTGZzeTZuUTRRdFFzdEdNVWozcGJtdlFmazJBNnljeGRFeFpkZFZsdmwKMm82MjBsMllxcHFDZEtCRThCay90elFIVTlKcU56cHpoOUJUTXdJREFRQUJBb0lCQVFDZklHbXowOHhRVmorNwpLZnZJUXQwQ0YzR2MxNld6eDhVNml4MHg4Mm15d1kxUUNlL3BzWE9LZlRxT1h1SENyUlp5TnUvZ2IvUUQ4bUFOCmxOMjRZTWl0TWRJODg5TEZoTkp3QU5OODJDeTczckM5bzVvUDlkazAvYzRIbjAzSkVYNzZ5QjgzQm9rR1FvYksKMjhMNk0rdHUzUmFqNjd6Vmc2d2szaEhrU0pXSzBwV1YrSjdrUkRWYmhDYUZhNk5nMUZNRWxhTlozVDhhUUtyQgpDUDNDeEFTdjYxWTk5TEI4KzNXWVFIK3NYaTVGM01pYVNBZ1BkQUk3WEh1dXFET1lvMU5PL0JoSGt1aVg2QnRtCnorNTZud2pZMy8yUytSRmNBc3JMTnIwMDJZZi9oY0IraVlDNzVWYmcydVd6WTY3TWdOTGQ5VW9RU3BDRkYrVm4KM0cyUnhybnhBb0dCQU40U3M0ZVlPU2huMVpQQjdhTUZsY0k2RHR2S2ErTGZTTXFyY2pOZjJlSEpZNnhubmxKdgpGenpGL2RiVWVTbWxSekR0WkdlcXZXaHFISy9iTjIyeWJhOU1WMDlRQ0JFTk5jNmtWajJTVHpUWkJVbEx4QzYrCk93Z0wyZHhKendWelU0VC84ajdHalRUN05BZVpFS2FvRHFyRG5BYWkyaW5oZU1JVWZHRXFGKzJyQW9HQkFOMVAKK0tZL0lsS3RWRzRKSklQNzBjUis3RmpyeXJpY05iWCtQVzUvOXFHaWxnY2grZ3l4b25BWlBpd2NpeDN3QVpGdwpaZC96ZFB2aTBkWEppc1BSZjRMazg5b2pCUmpiRmRmc2l5UmJYbyt3TFU4NUhRU2NGMnN5aUFPaTVBRHdVU0FkCm45YWFweUNweEFkREtERHdObit3ZFhtaTZ0OHRpSFRkK3RoVDhkaVpBb0dCQUt6Wis1bG9OOTBtYlF4VVh5YUwKMjFSUm9tMGJjcndsTmVCaWNFSmlzaEhYa2xpSVVxZ3hSZklNM2hhUVRUcklKZENFaHFsV01aV0xPb2I2NTNyZgo3aFlMSXM1ZUtka3o0aFRVdnpldm9TMHVXcm9CV2xOVHlGanIrSWhKZnZUc0hpOGdsU3FkbXgySkJhZUFVWUNXCndNdlQ4NmNLclNyNkQrZG8wS05FZzFsL0FvR0FlMkFVdHVFbFNqLzBmRzgrV3hHc1RFV1JqclRNUzRSUjhRWXQKeXdjdFA4aDZxTGxKUTRCWGxQU05rMXZLTmtOUkxIb2pZT2pCQTViYjhibXNVU1BlV09NNENoaFJ4QnlHbmR2eAphYkJDRkFwY0IvbEg4d1R0alVZYlN5T294ZGt5OEp0ek90ajJhS0FiZHd6NlArWDZDODhjZmxYVFo5MWpYL3RMCjF3TmRKS2tDZ1lCbyt0UzB5TzJ2SWFmK2UwSkN5TGhzVDQ5cTN3Zis2QWVqWGx2WDJ1VnRYejN5QTZnbXo5aCsKcDNlK2JMRUxwb3B0WFhNdUFRR0xhUkcrYlNNcjR5dERYbE5ZSndUeThXczNKY3dlSTdqZVp2b0ZpbmNvVlVIMwphdmxoTUVCRGYxSjltSDB5cDBwWUNaS2ROdHNvZEZtQktzVEtQMjJhTmtsVVhCS3gyZzR6cFE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= \ No newline at end of file diff --git a/k8s/nginx/deployment.yaml b/k8s/nginx/deployment.yaml new file mode 100644 index 0000000000..2d85ca8a3e --- /dev/null +++ b/k8s/nginx/deployment.yaml @@ -0,0 +1,58 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: nginx-ingress + namespace: nginx-ingress +spec: + replicas: 3 + selector: + matchLabels: + app: nginx-ingress + template: + metadata: + labels: + app: nginx-ingress + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9113" + spec: + serviceAccountName: nginx-ingress + priorityClassName: production-priority + containers: + - image: nginx/nginx-ingress:edge + name: nginx-ingress + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 + - name: beacon-relay + containerPort: 20000 + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + args: + - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config + - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret + #- -v=3 # Enables extensive logging. Useful for troubleshooting. + - -nginx-status + - -nginx-status-port=8080 + - -report-ingress-status + - -external-service=nginx-ingress + - -enable-leader-election + - image: nginx/nginx-prometheus-exporter:0.1.0 + name: nginx-prometheus-exporter + ports: + - name: prometheus + containerPort: 9113 + args: + - -web.listen-address + - :9113 + - nginx.scrape-uri + - http://127.0.0.1:8080/stub_status diff --git a/k8s/nginx/loadbalancer.yaml b/k8s/nginx/loadbalancer.yaml new file mode 100644 index 0000000000..ed1bda705f --- /dev/null +++ b/k8s/nginx/loadbalancer.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx-ingress + namespace: nginx-ingress +spec: + externalTrafficPolicy: Local + type: LoadBalancer + loadBalancerIP: 35.221.47.224 + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + - port: 443 + targetPort: 443 + protocol: TCP + name: https + - port: 20000 + targetPort: 20000 + protocol: TCP + name: beacon-relay + - port: 20001 + targetPort: 20001 + protocol: TCP + name: beacon-bootnode + selector: + app: nginx-ingress diff --git a/k8s/nginx/namespace.yaml b/k8s/nginx/namespace.yaml new file mode 100644 index 0000000000..cfce76e478 --- /dev/null +++ b/k8s/nginx/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: nginx-ingress \ No newline at end of file diff --git a/k8s/nginx/nginx-config.yaml b/k8s/nginx/nginx-config.yaml new file mode 100644 index 0000000000..3a071aabb1 --- /dev/null +++ b/k8s/nginx/nginx-config.yaml @@ -0,0 +1,24 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: nginx-config + namespace: nginx-ingress +data: + stream-snippets: | + upstream beacon-chain-relay-tcp { + server relay.beacon-chain.svc.cluster.local:4000; + } + + server { + listen 20000; + proxy_pass beacon-chain-relay-tcp; + } + + upstream beacon-chain-bootnode-tcp { + server bootnode.beacon-chain.svc.cluster.local:4000; + } + + server { + listen 20001; + proxy_pass beacon-chain-bootnode-tcp; + } diff --git a/k8s/nginx/rbac.yaml b/k8s/nginx/rbac.yaml new file mode 100644 index 0000000000..2716a600e8 --- /dev/null +++ b/k8s/nginx/rbac.yaml @@ -0,0 +1,72 @@ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: nginx-ingress +rules: +- apiGroups: + - "" + resources: + - services + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - update + - create +- apiGroups: + - "" + resources: + - pods + verbs: + - list +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - extensions + resources: + - ingresses + verbs: + - list + - watch + - get +- apiGroups: + - "extensions" + resources: + - ingresses/status + verbs: + - update +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: nginx-ingress +subjects: +- kind: ServiceAccount + name: nginx-ingress + namespace: nginx-ingress +roleRef: + kind: ClusterRole + name: nginx-ingress + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/k8s/nginx/service-account.yaml b/k8s/nginx/service-account.yaml new file mode 100644 index 0000000000..866db0dde1 --- /dev/null +++ b/k8s/nginx/service-account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nginx-ingress + namespace: nginx-ingress \ No newline at end of file diff --git a/k8s/tools/BUILD.bazel b/k8s/tools/BUILD.bazel index 26b6d3ba3d..56636127c7 100644 --- a/k8s/tools/BUILD.bazel +++ b/k8s/tools/BUILD.bazel @@ -5,4 +5,5 @@ load("@k8s_pod//:defaults.bzl", "k8s_pod") k8s_pod( name = "busybox.pod", template = "busybox.yaml", + namespace = "default", )