├── screenshot-1.png ├── modules ├── traefik │ ├── main.yaml │ └── include │ │ └── traefik.yaml ├── external-dns │ ├── main.yaml │ └── include │ │ └── external-dns.yaml ├── Makefile ├── weavecloud │ ├── main.yaml │ ├── include │ │ ├── prometheus-svc.json │ │ ├── ssh-git.yaml │ │ └── weave-cloud.json │ ├── grafana.yaml │ └── cortex-config.yaml └── ide │ ├── include │ ├── pv.yaml │ ├── ingress.yaml │ ├── rbac.yaml │ └── ssh-git.yaml │ └── ide.yaml ├── Makefile ├── LICENSE ├── README.md └── manifests ├── traefik.yaml └── ide.yaml /screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/errordeveloper/k9c/HEAD/screenshot-1.png -------------------------------------------------------------------------------- /modules/traefik/main.yaml: -------------------------------------------------------------------------------- 1 | Kind: kubegen.k8s.io/Module.v1alpha2 2 | 3 | Parameters: 4 | 5 | - Name: external-dns/domain 6 | Type: String 7 | Default: test1.training.example.com. 8 | 9 | Resources: 10 | - path: include/traefik.yaml 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build_image: 2 | docker build --tag errordeveloper/k9c:latest ./build 3 | 4 | push_image: build_image 5 | docker push errordeveloper/k9c:latest 6 | 7 | generate_public_manifests: ide.yaml traefik.yaml 8 | 9 | %.yaml: 10 | ./kubegen module ./modules/$$(basename $@ .yaml) -s \ 11 | | /usr/local/bin/kubectl convert -f - > manifests/$@ 12 | -------------------------------------------------------------------------------- /modules/external-dns/main.yaml: -------------------------------------------------------------------------------- 1 | Kind: kubegen.k8s.io/Module.v1alpha2 2 | 3 | Parameters: 4 | 5 | - Name: external-dns/zone 6 | Type: String 7 | Required: true 8 | 9 | - Name: external-dns/google-project 10 | Type: String 11 | Required: true 12 | 13 | - Name: username 14 | Type: String 15 | Required: true 16 | 17 | Resources: 18 | - path: include/external-dns.yaml 19 | -------------------------------------------------------------------------------- /modules/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: weavecloud/include/weave-cloud.json 2 | 3 | weavecloud/include/weave-cloud.json: 4 | mkdir -p weavecloud/include 5 | curl --silent --location \ 6 | "https://cloud.weave.works/k8s/v1.8/weave-cloud.json?service-token=DummyToken&omit-support-info=true" \ 7 | | jq -S "" \ 8 | | jq '.items[1].data.token={ "kubegen.String.AsBASE64": { "kubegen.String.Lookup": "service-token" } }' \ 9 | | jq 'del(.items[19])' \ 10 | > "$@" 11 | -------------------------------------------------------------------------------- /modules/weavecloud/main.yaml: -------------------------------------------------------------------------------- 1 | Kind: kubegen.k8s.io/Module.v1alpha2 2 | 3 | Parameters: 4 | 5 | - Name: username 6 | Type: String 7 | Default: username 8 | - Name: password 9 | Type: String 10 | Default: password 11 | - Name: external-dns/domain 12 | Type: String 13 | Default: test1.training.example.com. 14 | 15 | - Name: service-token 16 | Type: String 17 | Required: true 18 | 19 | Resources: 20 | - path: include/weave-cloud.json 21 | - path: include/prometheus-svc.json 22 | - path: include/ssh-git.yaml 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Ilya Dmitrichenko. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /modules/weavecloud/include/prometheus-svc.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "labels": { 6 | "app": "weave-cortex", 7 | "name": "prometheus", 8 | "weave-cloud-component": "cortex", 9 | "weave-cortex-component": "agent" 10 | }, 11 | "name": "prometheus", 12 | "namespace": "weave" 13 | }, 14 | "spec": { 15 | "ports": [ 16 | { 17 | "name": "prometheus", 18 | "port": 80, 19 | "targetPort": 8080 20 | } 21 | ], 22 | "selector": { 23 | "app": "weave-cortex", 24 | "name": "prometheus", 25 | "weave-cloud-component": "cortex", 26 | "weave-cortex-component": "agent" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /modules/ide/include/pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | 5 | - apiVersion: v1 6 | kind: PersistentVolumeClaim 7 | metadata: 8 | name: ide-workspace-data 9 | namespace: {kubegen.String.Lookup: namespaces/ide} 10 | labels: 11 | name: ide 12 | spec: 13 | accessModes: [ReadWriteOnce] 14 | resources: 15 | requests: 16 | storage: 1Gi # TODO parametrize 17 | 18 | - apiVersion: v1 19 | kind: PersistentVolumeClaim 20 | metadata: 21 | name: git-server-data 22 | namespace: {kubegen.String.Lookup: namespaces/ide} 23 | labels: 24 | name: ide 25 | spec: 26 | accessModes: [ReadWriteOnce] 27 | resources: 28 | requests: 29 | storage: 500Mi # TODO parametrize 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `k9c` – Cloud9+kubectl container 2 | 3 | This repository has build script and deployment manifest for a container that has Cloud9 IDE and `kubectl` installed 4 | (along with other handy packages), it's intended to be used for training/workshops, as it can run as a pod in cluster 5 | so all attendees need is a browser. 6 | 7 | 8 | Deploy it to a GKE cluster (or other provider with functional storage and external load balancers): 9 | ``` 10 | kubectl create namespace ide 11 | kubectl create namespace ide-workspace 12 | kubectl apply -f https://raw.github.com/errordeveloper/k9c/master/manifests/ide.yaml 13 | kubectl apply -f https://raw.github.com/errordeveloper/k9c/master/manifests/traefik.yaml 14 | ``` 15 | 16 | Get exteral IP: 17 | ``` 18 | traefik_ip="$(kubectl get svc -n kube-system traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}{"\n"}')" 19 | ``` 20 | 21 | Next, open `http://${traefik_ip}/` in your browser and login with `username:password`. 22 | 23 | Have a great Kubernetes experience with Cloud9 in your cluster! 24 | 25 | > NOTE: it's mostly for training/workshops, at present it's not very secure – use it at your own risk. 26 | 27 | ![](screenshot-1.png) 28 | -------------------------------------------------------------------------------- /modules/weavecloud/grafana.yaml: -------------------------------------------------------------------------------- 1 | Kind: kubegen.k8s.io/Module.v1alpha2 2 | 3 | Deployments: 4 | 5 | - name: "grafana" 6 | namespace: "weave" 7 | replicas: 1 8 | volumes: 9 | - name: datasources 10 | configMap: 11 | name: grafana-datasources 12 | containers: 13 | - image: grafana/grafana:5.0.0-beta2 14 | name: grafana 15 | imagePullPolicy: Always 16 | ports: 17 | - name: grafana 18 | containerPort: 3000 19 | env: 20 | GF_SERVER_ROOT_URL: 21 | kubegen.String.Join: 22 | - 'http://' 23 | - {kubegen.String.Lookup: external-dns/domain} 24 | - '/grafana' 25 | GF_SECURITY_ADMIN_USER: {kubegen.String.Lookup: username} 26 | GF_SECURITY_ADMIN_PASSWORD: {kubegen.String.Lookup: password} 27 | volumeMounts: 28 | - name: datasources 29 | mountPath: /etc/grafana/provisioning/datasources 30 | 31 | ConfigMaps: 32 | 33 | - name: "grafana-datasources" 34 | namespace: "weave" 35 | data: 36 | prometheus.yaml: 37 | kubegen.String.AsYAML: 38 | apiVersion: 1 39 | datasources: 40 | - name: prometheus 41 | type: prometheus 42 | access: proxy 43 | url: http://prometheus.weave.svc.cluster.local/prometheus 44 | orgId: 1 45 | version: 1 46 | isDefault: true 47 | editable: false 48 | 49 | Services: 50 | 51 | - name: "grafana" 52 | namespace: "weave" 53 | ports: 54 | - name: grafana 55 | port: 80 56 | targetPort: 3000 57 | -------------------------------------------------------------------------------- /modules/ide/include/ingress.yaml: -------------------------------------------------------------------------------- 1 | kind: List 2 | apiVersion: v1 3 | items: 4 | 5 | - apiVersion: extensions/v1beta1 6 | kind: Ingress 7 | metadata: 8 | name: ide 9 | namespace: {kubegen.String.Lookup: namespaces/ide} 10 | annotations: 11 | kubernetes.io/ingress.class: {kubegen.String.Lookup: ingress/class} 12 | spec: 13 | # TODO we can actually setup DNS and TLS with Let's Encrypt and external DNS 14 | # https://github.com/kubernetes-incubator/external-dns/blob/master/docs/tutorials/gke.md 15 | # and use training.weave.works. DNS zone 16 | rules: 17 | - http: 18 | paths: 19 | - path: / 20 | backend: 21 | serviceName: ide 22 | servicePort: http 23 | 24 | - apiVersion: extensions/v1beta1 25 | kind: Ingress 26 | metadata: 27 | name: grafana 28 | namespace: weave 29 | annotations: 30 | kubernetes.io/ingress.class: {kubegen.String.Lookup: ingress/class} 31 | traefik.frontend.rule.type: PathPrefixStrip 32 | spec: 33 | rules: 34 | - http: 35 | paths: 36 | - path: /grafana 37 | backend: 38 | serviceName: grafana 39 | servicePort: grafana 40 | 41 | - apiVersion: extensions/v1beta1 42 | kind: Ingress 43 | metadata: 44 | name: prometheus 45 | namespace: weave 46 | annotations: 47 | kubernetes.io/ingress.class: {kubegen.String.Lookup: ingress/class} 48 | spec: 49 | rules: 50 | - http: 51 | paths: 52 | - path: /prometheus 53 | backend: 54 | serviceName: prometheus 55 | servicePort: prometheus 56 | -------------------------------------------------------------------------------- /modules/external-dns/include/external-dns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | 5 | - apiVersion: v1 6 | kind: ServiceAccount 7 | metadata: 8 | name: external-dns-controller 9 | namespace: kube-system 10 | 11 | - kind: ClusterRole 12 | apiVersion: rbac.authorization.k8s.io/v1beta1 13 | metadata: 14 | name: external-dns-controller 15 | rules: 16 | - apiGroups: 17 | - "" 18 | resources: 19 | - services 20 | verbs: 21 | - get 22 | - list 23 | - watch 24 | - apiGroups: 25 | - extensions 26 | resources: 27 | - ingresses 28 | verbs: 29 | - get 30 | - list 31 | - watch 32 | - kind: ClusterRoleBinding 33 | apiVersion: rbac.authorization.k8s.io/v1beta1 34 | metadata: 35 | name: external-dns-controller 36 | roleRef: 37 | apiGroup: rbac.authorization.k8s.io 38 | kind: ClusterRole 39 | name: external-dns-controller 40 | subjects: 41 | - kind: ServiceAccount 42 | name: external-dns-controller 43 | namespace: kube-system 44 | 45 | - apiVersion: extensions/v1beta1 46 | kind: Deployment 47 | metadata: 48 | name: external-dns-controller 49 | namespace: kube-system 50 | spec: 51 | strategy: 52 | type: Recreate 53 | template: 54 | metadata: 55 | labels: 56 | k8s-app: external-dns 57 | name: external-dns 58 | spec: 59 | serviceAccount: external-dns-controller 60 | containers: 61 | - name: external-dns 62 | image: registry.opensource.zalan.do/teapot/external-dns:v0.4.8 63 | args: 64 | - --source=service 65 | - --source=ingress 66 | # would prevent ExternalDNS from deleting any records, omit to enable full synchronization 67 | - --policy=upsert-only 68 | # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones 69 | - --provider=google 70 | - --registry=txt 71 | - kubegen.String.Join: 72 | - --txt-owner-id= 73 | - kubegen.String.Lookup: username 74 | - kubegen.String.Join: 75 | - --domain-filter= 76 | - kubegen.String.Lookup: external-dns/zone 77 | - kubegen.String.Join: 78 | - --google-project= 79 | - kubegen.String.Lookup: external-dns/google-project 80 | -------------------------------------------------------------------------------- /modules/traefik/include/traefik.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - kind: ClusterRole 5 | apiVersion: rbac.authorization.k8s.io/v1beta1 6 | metadata: 7 | name: traefik-ingress-controller 8 | rules: 9 | - apiGroups: 10 | - "" 11 | resources: 12 | - services 13 | - endpoints 14 | - secrets 15 | verbs: 16 | - get 17 | - list 18 | - watch 19 | - apiGroups: 20 | - extensions 21 | resources: 22 | - ingresses 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | - kind: ClusterRoleBinding 28 | apiVersion: rbac.authorization.k8s.io/v1beta1 29 | metadata: 30 | name: traefik-ingress-controller 31 | roleRef: 32 | apiGroup: rbac.authorization.k8s.io 33 | kind: ClusterRole 34 | name: traefik-ingress-controller 35 | subjects: 36 | - kind: ServiceAccount 37 | name: traefik-ingress-controller 38 | namespace: kube-system 39 | - apiVersion: v1 40 | kind: ServiceAccount 41 | metadata: 42 | name: traefik-ingress-controller 43 | namespace: kube-system 44 | - kind: DaemonSet 45 | apiVersion: extensions/v1beta1 46 | metadata: 47 | name: traefik-ingress-controller 48 | namespace: kube-system 49 | labels: 50 | k8s-app: traefik-ingress-lb 51 | spec: 52 | template: 53 | metadata: 54 | labels: 55 | k8s-app: traefik-ingress-lb 56 | name: traefik-ingress-lb 57 | spec: 58 | serviceAccountName: traefik-ingress-controller 59 | terminationGracePeriodSeconds: 60 60 | hostNetwork: true 61 | containers: 62 | - image: traefik:v1.5.1 63 | name: traefik-ingress-lb 64 | ports: 65 | - name: http 66 | containerPort: 80 67 | hostPort: 80 68 | - name: admin 69 | containerPort: 8080 70 | securityContext: 71 | privileged: true 72 | args: 73 | - -d 74 | - --web 75 | - --kubernetes 76 | - kind: Service 77 | apiVersion: v1 78 | metadata: 79 | name: traefik-admin 80 | namespace: kube-system 81 | spec: 82 | selector: 83 | k8s-app: traefik-ingress-lb 84 | ports: 85 | - protocol: TCP 86 | port: 8080 87 | name: admin 88 | type: ClusterIP 89 | - kind: Service 90 | apiVersion: v1 91 | metadata: 92 | name: traefik 93 | namespace: kube-system 94 | annotations: 95 | external-dns.alpha.kubernetes.io/hostname: {kubegen.String.Lookup: external-dns/domain} 96 | external-dns.alpha.kubernetes.io/ttl: "5" 97 | spec: 98 | selector: 99 | k8s-app: traefik-ingress-lb 100 | ports: 101 | - protocol: TCP 102 | port: 80 103 | name: web 104 | type: LoadBalancer 105 | -------------------------------------------------------------------------------- /manifests/traefik.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | items: 3 | - apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRole 5 | metadata: 6 | creationTimestamp: null 7 | name: traefik-ingress-controller 8 | rules: 9 | - apiGroups: 10 | - "" 11 | resources: 12 | - services 13 | - endpoints 14 | - secrets 15 | verbs: 16 | - get 17 | - list 18 | - watch 19 | - apiGroups: 20 | - extensions 21 | resources: 22 | - ingresses 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | - apiVersion: rbac.authorization.k8s.io/v1 28 | kind: ClusterRoleBinding 29 | metadata: 30 | creationTimestamp: null 31 | name: traefik-ingress-controller 32 | roleRef: 33 | apiGroup: rbac.authorization.k8s.io 34 | kind: ClusterRole 35 | name: traefik-ingress-controller 36 | subjects: 37 | - kind: ServiceAccount 38 | name: traefik-ingress-controller 39 | namespace: kube-system 40 | - apiVersion: v1 41 | kind: ServiceAccount 42 | metadata: 43 | creationTimestamp: null 44 | name: traefik-ingress-controller 45 | namespace: kube-system 46 | - apiVersion: apps/v1beta2 47 | kind: DaemonSet 48 | metadata: 49 | annotations: 50 | deprecated.daemonset.template.generation: "0" 51 | creationTimestamp: null 52 | labels: 53 | k8s-app: traefik-ingress-lb 54 | name: traefik-ingress-controller 55 | namespace: kube-system 56 | spec: 57 | revisionHistoryLimit: 10 58 | selector: 59 | matchLabels: 60 | k8s-app: traefik-ingress-lb 61 | name: traefik-ingress-lb 62 | template: 63 | metadata: 64 | creationTimestamp: null 65 | labels: 66 | k8s-app: traefik-ingress-lb 67 | name: traefik-ingress-lb 68 | spec: 69 | containers: 70 | - args: 71 | - -d 72 | - --web 73 | - --kubernetes 74 | image: traefik:v1.5.1 75 | imagePullPolicy: IfNotPresent 76 | name: traefik-ingress-lb 77 | ports: 78 | - containerPort: 80 79 | hostPort: 80 80 | name: http 81 | protocol: TCP 82 | - containerPort: 8080 83 | hostPort: 8080 84 | name: admin 85 | protocol: TCP 86 | resources: {} 87 | securityContext: 88 | privileged: true 89 | terminationMessagePath: /dev/termination-log 90 | terminationMessagePolicy: File 91 | dnsPolicy: ClusterFirst 92 | hostNetwork: true 93 | restartPolicy: Always 94 | schedulerName: default-scheduler 95 | securityContext: {} 96 | serviceAccount: traefik-ingress-controller 97 | serviceAccountName: traefik-ingress-controller 98 | terminationGracePeriodSeconds: 60 99 | updateStrategy: 100 | type: OnDelete 101 | status: 102 | currentNumberScheduled: 0 103 | desiredNumberScheduled: 0 104 | numberMisscheduled: 0 105 | numberReady: 0 106 | - apiVersion: v1 107 | kind: Service 108 | metadata: 109 | creationTimestamp: null 110 | name: traefik-admin 111 | namespace: kube-system 112 | spec: 113 | ports: 114 | - name: admin 115 | port: 8080 116 | protocol: TCP 117 | targetPort: 8080 118 | selector: 119 | k8s-app: traefik-ingress-lb 120 | sessionAffinity: None 121 | type: ClusterIP 122 | status: 123 | loadBalancer: {} 124 | - apiVersion: v1 125 | kind: Service 126 | metadata: 127 | annotations: 128 | external-dns.alpha.kubernetes.io/hostname: test1.training.example.com. 129 | external-dns.alpha.kubernetes.io/ttl: "5" 130 | creationTimestamp: null 131 | name: traefik 132 | namespace: kube-system 133 | spec: 134 | externalTrafficPolicy: Cluster 135 | ports: 136 | - name: web 137 | port: 80 138 | protocol: TCP 139 | targetPort: 80 140 | selector: 141 | k8s-app: traefik-ingress-lb 142 | sessionAffinity: None 143 | type: LoadBalancer 144 | status: 145 | loadBalancer: {} 146 | kind: List 147 | metadata: {} 148 | -------------------------------------------------------------------------------- /modules/ide/include/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | 5 | - apiVersion: v1 6 | kind: List 7 | items: 8 | 9 | - apiVersion: v1 10 | kind: Namespace 11 | metadata: 12 | name: {kubegen.String.Lookup: namespaces/ide} 13 | 14 | - apiVersion: v1 15 | kind: ServiceAccount 16 | metadata: 17 | name: ide 18 | namespace: {kubegen.String.Lookup: namespaces/ide} 19 | labels: 20 | name: ide 21 | 22 | - apiVersion: rbac.authorization.k8s.io/v1beta1 23 | kind: ClusterRole 24 | metadata: 25 | name: 26 | kubegen.String.Join: 27 | - {kubegen.String.Lookup: namespaces/ide} 28 | - -cluster-admin 29 | labels: 30 | name: ide 31 | rules: 32 | - apiGroups: [ '*' ] 33 | resources: [ '*' ] 34 | verbs: [ '*' ] 35 | - nonResourceURLs: [ '*' ] 36 | verbs: [ '*' ] 37 | 38 | - apiVersion: rbac.authorization.k8s.io/v1beta1 39 | kind: ClusterRoleBinding 40 | metadata: 41 | name: 42 | kubegen.String.Join: 43 | - {kubegen.String.Lookup: namespaces/ide} 44 | - -cluster-admin 45 | labels: 46 | name: ide 47 | roleRef: 48 | kind: ClusterRole 49 | name: 50 | kubegen.String.Join: 51 | - {kubegen.String.Lookup: namespaces/ide} 52 | - -cluster-admin 53 | apiGroup: rbac.authorization.k8s.io 54 | subjects: 55 | - kind: ServiceAccount 56 | name: ide 57 | namespace: {kubegen.String.Lookup: namespaces/ide} 58 | 59 | # see https://github.com/errordeveloper/k9c/issues/10 60 | 61 | # - apiVersion: rbac.authorization.k8s.io/v1beta1 62 | # kind: ClusterRole 63 | # metadata: 64 | # name: 65 | # kubegen.String.Join: 66 | # - {kubegen.String.Lookup: namespaces/ide} 67 | # - -cluster-view 68 | # labels: 69 | # name: ide 70 | # rules: 71 | # - apiGroups: [ '*' ] 72 | # resources: [ '*' ] 73 | # verbs: [ 'get', 'list', 'watch' ] 74 | # - nonResourceURLs: [ '*' ] 75 | # verbs: [ 'get', 'list', 'watch' ] 76 | 77 | # - apiVersion: rbac.authorization.k8s.io/v1beta1 78 | # kind: ClusterRoleBinding 79 | # metadata: 80 | # name: 81 | # kubegen.String.Join: 82 | # - {kubegen.String.Lookup: namespaces/ide} 83 | # - -cluster-view 84 | # labels: 85 | # name: ide 86 | # roleRef: 87 | # kind: ClusterRole 88 | # name: 89 | # kubegen.String.Join: 90 | # - {kubegen.String.Lookup: namespaces/ide} 91 | # - -cluster-view 92 | # apiGroup: rbac.authorization.k8s.io 93 | # subjects: 94 | # - kind: ServiceAccount 95 | # name: ide 96 | # namespace: {kubegen.String.Lookup: namespaces/ide} 97 | 98 | - apiVersion: v1 99 | kind: List 100 | items: 101 | 102 | - apiVersion: v1 103 | kind: Namespace 104 | metadata: 105 | name: {kubegen.String.Lookup: namespaces/workspace} 106 | 107 | # - apiVersion: rbac.authorization.k8s.io/v1beta1 108 | # kind: Role 109 | # metadata: 110 | # name: 111 | # kubegen.String.Join: 112 | # - {kubegen.String.Lookup: namespaces/workspace} 113 | # - -workspace-admin 114 | # namespace: {kubegen.String.Lookup: namespaces/workspace} 115 | # labels: 116 | # name: ide 117 | # rules: 118 | # - apiGroups: [ '*' ] 119 | # resources: [ '*' ] 120 | # verbs: [ '*' ] 121 | 122 | # - apiVersion: rbac.authorization.k8s.io/v1beta1 123 | # kind: RoleBinding 124 | # metadata: 125 | # name: 126 | # kubegen.String.Join: 127 | # - {kubegen.String.Lookup: namespaces/workspace} 128 | # - -workspace-admin 129 | # namespace: {kubegen.String.Lookup: namespaces/workspace} 130 | # labels: 131 | # name: ide 132 | # roleRef: 133 | # kind: Role 134 | # name: 135 | # kubegen.String.Join: 136 | # - {kubegen.String.Lookup: namespaces/workspace} 137 | # - -workspace-admin 138 | # apiGroup: rbac.authorization.k8s.io 139 | # subjects: 140 | # - kind: ServiceAccount 141 | # name: ide 142 | # namespace: {kubegen.String.Lookup: namespaces/ide} 143 | -------------------------------------------------------------------------------- /modules/weavecloud/include/ssh-git.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: ssh-git 5 | namespace: weave 6 | labels: 7 | name: ide 8 | type: Opaque 9 | data: 10 | known_hosts: 11 | kubegen.String.AsBASE64: | 12 | git-server ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLhQnVgMoas/3nXWsOVz/vNB/vtPwH1gRCdYKrYgYGFMfhunyQ2ITwKYoWkFgmtcGdC9gmS+AbvgqHJxwWzIsHE= 13 | git-server.ide.svc.cluster.local. ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLhQnVgMoas/3nXWsOVz/vNB/vtPwH1gRCdYKrYgYGFMfhunyQ2ITwKYoWkFgmtcGdC9gmS+AbvgqHJxwWzIsHE= 14 | identity: 15 | kubegen.String.AsBASE64: | 16 | -----BEGIN RSA PRIVATE KEY----- 17 | MIIEowIBAAKCAQEAs3nKlkvHKbPDVVBe2KtbRCGHrjaaNLVB7mTG210J6iEx8FrX 18 | WdGV/d2NQbaaQCCRChw7LwjHQdyNeTrhjm1lh3cLsFM8E2qEA0gHLuUr/geNLz+I 19 | 7jssLSjBt10z5eXW1c5BZYdAtIN+wNNjOLZmGmnWCBB0ARlv3wzDSc9q85vvQtcG 20 | qZ3gcKQy/YT7wMs4cNveoBX9A5VNrvkN9kOuAbiBLZT1kB1lq5UlCqQUJA4T8mSy 21 | Xyyslz8FqlSolZsQJBkRfiCbSPpCOpEfsXx/ymO9Bhes15A9n6p9Usnwt4cG8pb6 22 | hEz+FXCC97t+Qrz/gHWl5lb9HUbXROCqRhlYXQIDAQABAoIBADO6cap58tBRMIaB 23 | YKTgVrC/XUTYFgAFEhis0SfenAHwSV12QUVxA+MknRcIk1LSUBty4Zf/1rZj5B7B 24 | 2srbOv0dUbAjfVg3Rg9QDkn04YYZFRc+H7BSO7xUV+kKou+rHA2Jog2qOvsMP1dC 25 | VgG9iJYqVPcEDvtWIolOO2clsjS+DDdGxoBvjaQo8GVVdiFkzGNVgSBFg3WOftl8 26 | J26r6wsaUWd6+c+ui4EuKIN86HHMOKtl11n7zB3XUieLFUImFR8G4tGBVpexsyQi 27 | lcsgT3SgXFC9JzCERPdkMuKHuV00ZwMfiMY+sxgtlurQ2samXWNexxdejzCGTHqg 28 | WlQZBmECgYEA4NB7up26TDYTWKrgMxhbnxrZOL1cuaOYVABgYhyobg1eZlMt2MiV 29 | UilZjadFvyzfcGPSTJcJ5f2i/CGsKn7EqqQwhfwuKvQe42k80nNAqG3u9/vIxnIB 30 | qFendM17JSvZE75qBTOnMuUgSn4RhMzs8H7Q1fdT8Pc/MTfEUJq43pkCgYEAzF9C 31 | wX4gE/RvemfQsFUgoSCIPvDulXM73l+OWFpr8M41lixg/wIoCcEfZFpWKRJjJl/S 32 | NTXwaXg8h8Diwkwww2frcoY9vLcHploYTd7VcQY8PdJv3IxaQzWzHzLGst3oagO+ 33 | bCm+l0F9Nv4UGVDu+ODRB2rEj6oVFFhtID1ndmUCgYBGKuwjT+2AsfQR3auCZxzZ 34 | qQCZhAj37Aa0WTW8CaPMTaHkIBwUKG7qqPtJiibrx26p3o4Z156ASUzgkwXwcYai 35 | mAKJHy+tumoVopgYO1638y/9+Hku7xBzYYBjpWrFLE1hqzHeE8Qgz4DnnzeKkod1 36 | fK9jyQFLGXCAxR4h5ljDKQKBgQC+jR9f66obEPCT75HbpzOKKBwAm4HIZK3wc6Xz 37 | 6TL1Tj8WawBxI+CS37bWSYhGOTerAvKq3ETxAcNmS8jhokphF1am7FVJzFncl+pL 38 | SLY38LlgZwIXX+GVAs+lCiHLii32EtGMZgunWc9W4+V3iUeXU35x7PGihdGrq5rr 39 | 0XTTJQKBgAQyAtFYhTtN6KBHDv4WbL41rpmqIUqIiWDzkqOOVWpx3bJSueMx12R4 40 | XuUhi0/fjlao2f0Y0jm0CRT9fiaAnzXsLEss7bXCFYpkwWvk6sjWPBXgORpYnIG5 41 | QEcEzIsD1JBmDcDquligGgS3HthbY9yYn/SyxwJ0qNhopCKWv9cN 42 | -----END RSA PRIVATE KEY----- 43 | id_rsa: 44 | kubegen.String.AsBASE64: | 45 | -----BEGIN RSA PRIVATE KEY----- 46 | MIIEowIBAAKCAQEAs3nKlkvHKbPDVVBe2KtbRCGHrjaaNLVB7mTG210J6iEx8FrX 47 | WdGV/d2NQbaaQCCRChw7LwjHQdyNeTrhjm1lh3cLsFM8E2qEA0gHLuUr/geNLz+I 48 | 7jssLSjBt10z5eXW1c5BZYdAtIN+wNNjOLZmGmnWCBB0ARlv3wzDSc9q85vvQtcG 49 | qZ3gcKQy/YT7wMs4cNveoBX9A5VNrvkN9kOuAbiBLZT1kB1lq5UlCqQUJA4T8mSy 50 | Xyyslz8FqlSolZsQJBkRfiCbSPpCOpEfsXx/ymO9Bhes15A9n6p9Usnwt4cG8pb6 51 | hEz+FXCC97t+Qrz/gHWl5lb9HUbXROCqRhlYXQIDAQABAoIBADO6cap58tBRMIaB 52 | YKTgVrC/XUTYFgAFEhis0SfenAHwSV12QUVxA+MknRcIk1LSUBty4Zf/1rZj5B7B 53 | 2srbOv0dUbAjfVg3Rg9QDkn04YYZFRc+H7BSO7xUV+kKou+rHA2Jog2qOvsMP1dC 54 | VgG9iJYqVPcEDvtWIolOO2clsjS+DDdGxoBvjaQo8GVVdiFkzGNVgSBFg3WOftl8 55 | J26r6wsaUWd6+c+ui4EuKIN86HHMOKtl11n7zB3XUieLFUImFR8G4tGBVpexsyQi 56 | lcsgT3SgXFC9JzCERPdkMuKHuV00ZwMfiMY+sxgtlurQ2samXWNexxdejzCGTHqg 57 | WlQZBmECgYEA4NB7up26TDYTWKrgMxhbnxrZOL1cuaOYVABgYhyobg1eZlMt2MiV 58 | UilZjadFvyzfcGPSTJcJ5f2i/CGsKn7EqqQwhfwuKvQe42k80nNAqG3u9/vIxnIB 59 | qFendM17JSvZE75qBTOnMuUgSn4RhMzs8H7Q1fdT8Pc/MTfEUJq43pkCgYEAzF9C 60 | wX4gE/RvemfQsFUgoSCIPvDulXM73l+OWFpr8M41lixg/wIoCcEfZFpWKRJjJl/S 61 | NTXwaXg8h8Diwkwww2frcoY9vLcHploYTd7VcQY8PdJv3IxaQzWzHzLGst3oagO+ 62 | bCm+l0F9Nv4UGVDu+ODRB2rEj6oVFFhtID1ndmUCgYBGKuwjT+2AsfQR3auCZxzZ 63 | qQCZhAj37Aa0WTW8CaPMTaHkIBwUKG7qqPtJiibrx26p3o4Z156ASUzgkwXwcYai 64 | mAKJHy+tumoVopgYO1638y/9+Hku7xBzYYBjpWrFLE1hqzHeE8Qgz4DnnzeKkod1 65 | fK9jyQFLGXCAxR4h5ljDKQKBgQC+jR9f66obEPCT75HbpzOKKBwAm4HIZK3wc6Xz 66 | 6TL1Tj8WawBxI+CS37bWSYhGOTerAvKq3ETxAcNmS8jhokphF1am7FVJzFncl+pL 67 | SLY38LlgZwIXX+GVAs+lCiHLii32EtGMZgunWc9W4+V3iUeXU35x7PGihdGrq5rr 68 | 0XTTJQKBgAQyAtFYhTtN6KBHDv4WbL41rpmqIUqIiWDzkqOOVWpx3bJSueMx12R4 69 | XuUhi0/fjlao2f0Y0jm0CRT9fiaAnzXsLEss7bXCFYpkwWvk6sjWPBXgORpYnIG5 70 | QEcEzIsD1JBmDcDquligGgS3HthbY9yYn/SyxwJ0qNhopCKWv9cN 71 | -----END RSA PRIVATE KEY----- 72 | id_rsa.pub: 73 | kubegen.String.AsBASE64: 74 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzecqWS8cps8NVUF7Yq1tEIYeuNpo0tUHuZMbbXQnqITHwWtdZ0ZX93Y1BtppAIJEKHDsvCMdB3I15OuGObWWHdwuwUzwTaoQDSAcu5Sv+B40vP4juOywtKMG3XTPl5dbVzkFlh0C0g37A02M4tmYaadYIEHQBGW/fDMNJz2rzm+9C1wapneBwpDL9hPvAyzhw296gFf0DlU2u+Q32Q64BuIEtlPWQHWWrlSUKpBQkDhPyZLJfLKyXPwWqVKiVmxAkGRF+IJtI+kI6kR+xfH/KY70GF6zXkD2fqn1SyfC3hwbylvqETP4VcIL3u35CvP+AdaXmVv0dRtdE4KpGGVhd 75 | -------------------------------------------------------------------------------- /modules/ide/include/ssh-git.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: ssh-git 5 | namespace: {kubegen.String.Lookup: namespaces/ide} 6 | labels: 7 | name: ide 8 | type: Opaque 9 | data: 10 | known_hosts: 11 | kubegen.String.AsBASE64: | 12 | git-server ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLhQnVgMoas/3nXWsOVz/vNB/vtPwH1gRCdYKrYgYGFMfhunyQ2ITwKYoWkFgmtcGdC9gmS+AbvgqHJxwWzIsHE= 13 | git-server.ide.svc.cluster.local. ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLhQnVgMoas/3nXWsOVz/vNB/vtPwH1gRCdYKrYgYGFMfhunyQ2ITwKYoWkFgmtcGdC9gmS+AbvgqHJxwWzIsHE= 14 | identity: 15 | kubegen.String.AsBASE64: | 16 | -----BEGIN RSA PRIVATE KEY----- 17 | MIIEowIBAAKCAQEAs3nKlkvHKbPDVVBe2KtbRCGHrjaaNLVB7mTG210J6iEx8FrX 18 | WdGV/d2NQbaaQCCRChw7LwjHQdyNeTrhjm1lh3cLsFM8E2qEA0gHLuUr/geNLz+I 19 | 7jssLSjBt10z5eXW1c5BZYdAtIN+wNNjOLZmGmnWCBB0ARlv3wzDSc9q85vvQtcG 20 | qZ3gcKQy/YT7wMs4cNveoBX9A5VNrvkN9kOuAbiBLZT1kB1lq5UlCqQUJA4T8mSy 21 | Xyyslz8FqlSolZsQJBkRfiCbSPpCOpEfsXx/ymO9Bhes15A9n6p9Usnwt4cG8pb6 22 | hEz+FXCC97t+Qrz/gHWl5lb9HUbXROCqRhlYXQIDAQABAoIBADO6cap58tBRMIaB 23 | YKTgVrC/XUTYFgAFEhis0SfenAHwSV12QUVxA+MknRcIk1LSUBty4Zf/1rZj5B7B 24 | 2srbOv0dUbAjfVg3Rg9QDkn04YYZFRc+H7BSO7xUV+kKou+rHA2Jog2qOvsMP1dC 25 | VgG9iJYqVPcEDvtWIolOO2clsjS+DDdGxoBvjaQo8GVVdiFkzGNVgSBFg3WOftl8 26 | J26r6wsaUWd6+c+ui4EuKIN86HHMOKtl11n7zB3XUieLFUImFR8G4tGBVpexsyQi 27 | lcsgT3SgXFC9JzCERPdkMuKHuV00ZwMfiMY+sxgtlurQ2samXWNexxdejzCGTHqg 28 | WlQZBmECgYEA4NB7up26TDYTWKrgMxhbnxrZOL1cuaOYVABgYhyobg1eZlMt2MiV 29 | UilZjadFvyzfcGPSTJcJ5f2i/CGsKn7EqqQwhfwuKvQe42k80nNAqG3u9/vIxnIB 30 | qFendM17JSvZE75qBTOnMuUgSn4RhMzs8H7Q1fdT8Pc/MTfEUJq43pkCgYEAzF9C 31 | wX4gE/RvemfQsFUgoSCIPvDulXM73l+OWFpr8M41lixg/wIoCcEfZFpWKRJjJl/S 32 | NTXwaXg8h8Diwkwww2frcoY9vLcHploYTd7VcQY8PdJv3IxaQzWzHzLGst3oagO+ 33 | bCm+l0F9Nv4UGVDu+ODRB2rEj6oVFFhtID1ndmUCgYBGKuwjT+2AsfQR3auCZxzZ 34 | qQCZhAj37Aa0WTW8CaPMTaHkIBwUKG7qqPtJiibrx26p3o4Z156ASUzgkwXwcYai 35 | mAKJHy+tumoVopgYO1638y/9+Hku7xBzYYBjpWrFLE1hqzHeE8Qgz4DnnzeKkod1 36 | fK9jyQFLGXCAxR4h5ljDKQKBgQC+jR9f66obEPCT75HbpzOKKBwAm4HIZK3wc6Xz 37 | 6TL1Tj8WawBxI+CS37bWSYhGOTerAvKq3ETxAcNmS8jhokphF1am7FVJzFncl+pL 38 | SLY38LlgZwIXX+GVAs+lCiHLii32EtGMZgunWc9W4+V3iUeXU35x7PGihdGrq5rr 39 | 0XTTJQKBgAQyAtFYhTtN6KBHDv4WbL41rpmqIUqIiWDzkqOOVWpx3bJSueMx12R4 40 | XuUhi0/fjlao2f0Y0jm0CRT9fiaAnzXsLEss7bXCFYpkwWvk6sjWPBXgORpYnIG5 41 | QEcEzIsD1JBmDcDquligGgS3HthbY9yYn/SyxwJ0qNhopCKWv9cN 42 | -----END RSA PRIVATE KEY----- 43 | id_rsa: 44 | kubegen.String.AsBASE64: | 45 | -----BEGIN RSA PRIVATE KEY----- 46 | MIIEowIBAAKCAQEAs3nKlkvHKbPDVVBe2KtbRCGHrjaaNLVB7mTG210J6iEx8FrX 47 | WdGV/d2NQbaaQCCRChw7LwjHQdyNeTrhjm1lh3cLsFM8E2qEA0gHLuUr/geNLz+I 48 | 7jssLSjBt10z5eXW1c5BZYdAtIN+wNNjOLZmGmnWCBB0ARlv3wzDSc9q85vvQtcG 49 | qZ3gcKQy/YT7wMs4cNveoBX9A5VNrvkN9kOuAbiBLZT1kB1lq5UlCqQUJA4T8mSy 50 | Xyyslz8FqlSolZsQJBkRfiCbSPpCOpEfsXx/ymO9Bhes15A9n6p9Usnwt4cG8pb6 51 | hEz+FXCC97t+Qrz/gHWl5lb9HUbXROCqRhlYXQIDAQABAoIBADO6cap58tBRMIaB 52 | YKTgVrC/XUTYFgAFEhis0SfenAHwSV12QUVxA+MknRcIk1LSUBty4Zf/1rZj5B7B 53 | 2srbOv0dUbAjfVg3Rg9QDkn04YYZFRc+H7BSO7xUV+kKou+rHA2Jog2qOvsMP1dC 54 | VgG9iJYqVPcEDvtWIolOO2clsjS+DDdGxoBvjaQo8GVVdiFkzGNVgSBFg3WOftl8 55 | J26r6wsaUWd6+c+ui4EuKIN86HHMOKtl11n7zB3XUieLFUImFR8G4tGBVpexsyQi 56 | lcsgT3SgXFC9JzCERPdkMuKHuV00ZwMfiMY+sxgtlurQ2samXWNexxdejzCGTHqg 57 | WlQZBmECgYEA4NB7up26TDYTWKrgMxhbnxrZOL1cuaOYVABgYhyobg1eZlMt2MiV 58 | UilZjadFvyzfcGPSTJcJ5f2i/CGsKn7EqqQwhfwuKvQe42k80nNAqG3u9/vIxnIB 59 | qFendM17JSvZE75qBTOnMuUgSn4RhMzs8H7Q1fdT8Pc/MTfEUJq43pkCgYEAzF9C 60 | wX4gE/RvemfQsFUgoSCIPvDulXM73l+OWFpr8M41lixg/wIoCcEfZFpWKRJjJl/S 61 | NTXwaXg8h8Diwkwww2frcoY9vLcHploYTd7VcQY8PdJv3IxaQzWzHzLGst3oagO+ 62 | bCm+l0F9Nv4UGVDu+ODRB2rEj6oVFFhtID1ndmUCgYBGKuwjT+2AsfQR3auCZxzZ 63 | qQCZhAj37Aa0WTW8CaPMTaHkIBwUKG7qqPtJiibrx26p3o4Z156ASUzgkwXwcYai 64 | mAKJHy+tumoVopgYO1638y/9+Hku7xBzYYBjpWrFLE1hqzHeE8Qgz4DnnzeKkod1 65 | fK9jyQFLGXCAxR4h5ljDKQKBgQC+jR9f66obEPCT75HbpzOKKBwAm4HIZK3wc6Xz 66 | 6TL1Tj8WawBxI+CS37bWSYhGOTerAvKq3ETxAcNmS8jhokphF1am7FVJzFncl+pL 67 | SLY38LlgZwIXX+GVAs+lCiHLii32EtGMZgunWc9W4+V3iUeXU35x7PGihdGrq5rr 68 | 0XTTJQKBgAQyAtFYhTtN6KBHDv4WbL41rpmqIUqIiWDzkqOOVWpx3bJSueMx12R4 69 | XuUhi0/fjlao2f0Y0jm0CRT9fiaAnzXsLEss7bXCFYpkwWvk6sjWPBXgORpYnIG5 70 | QEcEzIsD1JBmDcDquligGgS3HthbY9yYn/SyxwJ0qNhopCKWv9cN 71 | -----END RSA PRIVATE KEY----- 72 | id_rsa.pub: 73 | kubegen.String.AsBASE64: 74 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzecqWS8cps8NVUF7Yq1tEIYeuNpo0tUHuZMbbXQnqITHwWtdZ0ZX93Y1BtppAIJEKHDsvCMdB3I15OuGObWWHdwuwUzwTaoQDSAcu5Sv+B40vP4juOywtKMG3XTPl5dbVzkFlh0C0g37A02M4tmYaadYIEHQBGW/fDMNJz2rzm+9C1wapneBwpDL9hPvAyzhw296gFf0DlU2u+Q32Q64BuIEtlPWQHWWrlSUKpBQkDhPyZLJfLKyXPwWqVKiVmxAkGRF+IJtI+kI6kR+xfH/KY70GF6zXkD2fqn1SyfC3hwbylvqETP4VcIL3u35CvP+AdaXmVv0dRtdE4KpGGVhd 75 | -------------------------------------------------------------------------------- /modules/ide/ide.yaml: -------------------------------------------------------------------------------- 1 | Kind: kubegen.k8s.io/Module.v1alpha2 2 | 3 | Parameters: 4 | 5 | - Name: username 6 | Type: String 7 | Default: username 8 | - Name: password 9 | Type: String 10 | Default: password 11 | 12 | ## Extenrnal parameters for image basename and digest, there is an internal 13 | ## one also that uses a macro to join these into one string 14 | - Name: images/ide-basename 15 | Type: String 16 | Default: errordeveloper/k9c 17 | 18 | - Name: images/ide-digest 19 | Type: String 20 | Default: 675d78c6645f202f9e84863d80595a8b8d427bef5bffdf00b1f138368081821a 21 | 22 | - Name: config-repo/tar-url 23 | Type: String 24 | Default: "https://storage.googleapis.com/kubecon0518/kubecon-cluster-e2e-test.tar.gz" 25 | 26 | - Name: workspace/clone-repos 27 | Type: String 28 | Default: | 29 | [ 30 | { 31 | "repo_url": "https://github.com/bricef/metrics-demo", 32 | "checkout_path": "/workspace/demo-app" 33 | } 34 | ] 35 | 36 | ## As plain resources do not allow us to override namespace 37 | ## we have namespaces set here 38 | - Name: namespaces/ide 39 | Type: String 40 | Default: ide 41 | - Name: namespaces/workspace 42 | Type: String 43 | Default: ide-workspace 44 | 45 | - Name: ingress/class 46 | Type: String 47 | Default: traefik 48 | 49 | Deployments: 50 | 51 | - name: ide 52 | namespace: {kubegen.String.Lookup: namespaces/ide} 53 | replicas: 1 54 | serviceAccountName: ide 55 | initContainers: 56 | - name: git-clone 57 | image: {kubegen.Object.Lookup: internals/images/ide-name} 58 | command: 59 | - 'clone-repos.sh' 60 | - kubegen.String.Lookup: 'workspace/clone-repos' 61 | volumeMounts: 62 | - mountPath: /root/.ssh 63 | name: ssh-git 64 | - name: ide-workspace-data 65 | mountPath: /workspace 66 | containers: 67 | - name: ide 68 | image: {kubegen.Object.Lookup: internals/images/ide-name} 69 | args: 70 | - "--auth" 71 | - {kubegen.Object.Lookup: internals/auth} 72 | env: 73 | IDE_USERNAME: {kubegen.String.Lookup: username} 74 | ports: 75 | - name: http 76 | containerPort: 8080 77 | livenessProbe: 78 | kubegen.Object.Lookup: internals/probes/with-auth 79 | initialDelaySeconds: 30 80 | periodSeconds: 5 81 | readinessProbe: 82 | kubegen.Object.Lookup: internals/probes/with-auth 83 | initialDelaySeconds: 5 84 | periodSeconds: 1 85 | volumeMounts: 86 | - name: ssh-git 87 | mountPath: /root/.ssh 88 | - name: ide-workspace-data 89 | mountPath: /workspace 90 | - name: dockersocket 91 | mountPath: /var/run/docker.sock 92 | volumes: 93 | - name: ssh-git 94 | secret: 95 | secretName: ssh-git 96 | defaultMode: 256 97 | - name: ide-workspace-data 98 | persistentVolumeClaim: 99 | claimName: ide-workspace-data 100 | - name: dockersocket 101 | hostPath: 102 | path: /var/run/docker.sock 103 | 104 | - name: git-server 105 | namespace: {kubegen.String.Lookup: namespaces/ide} 106 | containers: 107 | - name: git 108 | # NOTE for new image of gitsrv you may need to update ssh-git secret in this module and weavecloud also, 109 | # but only if it was rebuild without layer cache 110 | # TODO long term, it'd probably be easier/reliable to use bare repos instead of gitsrv 111 | image: stefanprodan/gitsrv:0.0.10 112 | env: 113 | REPO: "cluster.git" 114 | TAR_URL: {kubegen.String.Lookup: config-repo/tar-url} 115 | ports: 116 | - name: ssh 117 | containerPort: 22 118 | volumeMounts: 119 | - name: ssh-git 120 | mountPath: /git-server/keys 121 | - name: git-server-data 122 | mountPath: /git-server/repos 123 | volumes: 124 | - name: ssh-git 125 | secret: 126 | secretName: ssh-git 127 | - name: git-server-data 128 | persistentVolumeClaim: 129 | claimName: git-server-data 130 | 131 | Services: 132 | 133 | - name: ide 134 | namespace: {kubegen.String.Lookup: namespaces/ide} 135 | ports: 136 | - name: http 137 | port: 80 138 | 139 | - name: git-server 140 | namespace: {kubegen.String.Lookup: namespaces/ide} 141 | ports: 142 | - name: ssh 143 | port: 22 144 | 145 | Internals: 146 | 147 | - Name: internals/images/ide-name 148 | Type: Object 149 | Value: 150 | kubegen.String.Join: 151 | - kubegen.String.Lookup: images/ide-basename 152 | - '@sha256:' 153 | - kubegen.String.Lookup: images/ide-digest 154 | 155 | - Name: internals/auth 156 | Type: Object 157 | Value: 158 | kubegen.String.Join: 159 | - kubegen.String.Lookup: username 160 | - ':' 161 | - kubegen.String.Lookup: password 162 | 163 | - Name: internals/probes/with-auth 164 | Type: Object 165 | Value: 166 | httpGet: 167 | path: /ide.html 168 | httpHeaders: 169 | Authorization: 170 | kubegen.String.Join: 171 | - 'Basic ' 172 | - kubegen.String.AsBASE64: 173 | kubegen.Object.Lookup: internals/auth 174 | 175 | Resources: 176 | - path: include/rbac.yaml 177 | - path: include/pv.yaml 178 | - path: include/ingress.yaml 179 | - path: include/ssh-git.yaml 180 | -------------------------------------------------------------------------------- /manifests/ide.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | items: 3 | - apiVersion: apps/v1beta1 4 | kind: Deployment 5 | metadata: 6 | creationTimestamp: null 7 | labels: 8 | name: ide 9 | name: ide 10 | namespace: ide 11 | spec: 12 | progressDeadlineSeconds: 600 13 | replicas: 1 14 | revisionHistoryLimit: 10 15 | selector: 16 | matchLabels: 17 | name: ide 18 | strategy: 19 | rollingUpdate: 20 | maxSurge: 25% 21 | maxUnavailable: 25% 22 | type: RollingUpdate 23 | template: 24 | metadata: 25 | creationTimestamp: null 26 | labels: 27 | name: ide 28 | spec: 29 | containers: 30 | - args: 31 | - --auth 32 | - username:password 33 | image: errordeveloper/k9c@sha256:74afb6e7b76fb9895f86f13daf4909c094f3edee756b325b88a8ea417775a01a 34 | imagePullPolicy: IfNotPresent 35 | livenessProbe: 36 | failureThreshold: 3 37 | httpGet: 38 | httpHeaders: 39 | - name: Authorization 40 | value: Basic dXNlcm5hbWU6cGFzc3dvcmQ= 41 | path: /ide.html 42 | port: http 43 | scheme: HTTP 44 | initialDelaySeconds: 30 45 | periodSeconds: 5 46 | successThreshold: 1 47 | timeoutSeconds: 1 48 | name: ide 49 | ports: 50 | - containerPort: 8080 51 | name: http 52 | protocol: TCP 53 | readinessProbe: 54 | failureThreshold: 3 55 | httpGet: 56 | httpHeaders: 57 | - name: Authorization 58 | value: Basic dXNlcm5hbWU6cGFzc3dvcmQ= 59 | path: /ide.html 60 | port: http 61 | scheme: HTTP 62 | initialDelaySeconds: 5 63 | periodSeconds: 1 64 | successThreshold: 1 65 | timeoutSeconds: 1 66 | resources: {} 67 | terminationMessagePath: /dev/termination-log 68 | terminationMessagePolicy: File 69 | volumeMounts: 70 | - mountPath: /workspace 71 | name: ide-workspace-data 72 | - mountPath: /var/run/docker.sock 73 | name: dockersocket 74 | dnsPolicy: ClusterFirst 75 | initContainers: 76 | - command: 77 | - /bin/sh 78 | - -c 79 | - test -d /workspace/demo-app || git clone https://github.com/bricef/metrics-demo 80 | demo-app 81 | image: errordeveloper/k9c@sha256:74afb6e7b76fb9895f86f13daf4909c094f3edee756b325b88a8ea417775a01a 82 | imagePullPolicy: IfNotPresent 83 | name: git-clone 84 | resources: {} 85 | terminationMessagePath: /dev/termination-log 86 | terminationMessagePolicy: File 87 | volumeMounts: 88 | - mountPath: /workspace 89 | name: ide-workspace-data 90 | restartPolicy: Always 91 | schedulerName: default-scheduler 92 | securityContext: {} 93 | serviceAccount: ide 94 | serviceAccountName: ide 95 | terminationGracePeriodSeconds: 30 96 | volumes: 97 | - name: ide-workspace-data 98 | persistentVolumeClaim: 99 | claimName: ide-workspace-data 100 | - hostPath: 101 | path: /var/run/docker.sock 102 | type: "" 103 | name: dockersocket 104 | status: {} 105 | - apiVersion: v1 106 | kind: Service 107 | metadata: 108 | creationTimestamp: null 109 | labels: 110 | name: ide 111 | name: ide 112 | namespace: ide 113 | spec: 114 | ports: 115 | - name: http 116 | port: 80 117 | protocol: TCP 118 | targetPort: http 119 | selector: 120 | name: ide 121 | sessionAffinity: None 122 | type: ClusterIP 123 | status: 124 | loadBalancer: {} 125 | - apiVersion: v1 126 | kind: Namespace 127 | metadata: 128 | creationTimestamp: null 129 | name: ide 130 | spec: {} 131 | status: 132 | phase: Active 133 | - apiVersion: v1 134 | kind: ServiceAccount 135 | metadata: 136 | creationTimestamp: null 137 | labels: 138 | name: ide 139 | name: ide 140 | namespace: ide 141 | - apiVersion: rbac.authorization.k8s.io/v1 142 | kind: ClusterRole 143 | metadata: 144 | creationTimestamp: null 145 | labels: 146 | name: ide 147 | name: ide-cluster-view 148 | rules: 149 | - apiGroups: 150 | - '*' 151 | resources: 152 | - '*' 153 | verbs: 154 | - get 155 | - list 156 | - watch 157 | - nonResourceURLs: 158 | - '*' 159 | verbs: 160 | - get 161 | - list 162 | - watch 163 | - apiVersion: rbac.authorization.k8s.io/v1 164 | kind: ClusterRoleBinding 165 | metadata: 166 | creationTimestamp: null 167 | labels: 168 | name: ide 169 | name: ide-cluster-view 170 | roleRef: 171 | apiGroup: rbac.authorization.k8s.io 172 | kind: ClusterRole 173 | name: ide-cluster-view 174 | subjects: 175 | - kind: ServiceAccount 176 | name: ide 177 | namespace: ide 178 | - apiVersion: v1 179 | kind: Namespace 180 | metadata: 181 | creationTimestamp: null 182 | name: ide-workspace 183 | spec: {} 184 | status: 185 | phase: Active 186 | - apiVersion: rbac.authorization.k8s.io/v1 187 | kind: Role 188 | metadata: 189 | creationTimestamp: null 190 | labels: 191 | name: ide 192 | name: ide-workspace-workspace-admin 193 | namespace: ide-workspace 194 | rules: 195 | - apiGroups: 196 | - '*' 197 | resources: 198 | - '*' 199 | verbs: 200 | - '*' 201 | - apiVersion: rbac.authorization.k8s.io/v1 202 | kind: RoleBinding 203 | metadata: 204 | creationTimestamp: null 205 | labels: 206 | name: ide 207 | name: ide-workspace-workspace-admin 208 | namespace: ide-workspace 209 | roleRef: 210 | apiGroup: rbac.authorization.k8s.io 211 | kind: Role 212 | name: ide-workspace-workspace-admin 213 | subjects: 214 | - kind: ServiceAccount 215 | name: ide 216 | namespace: ide 217 | - apiVersion: v1 218 | kind: PersistentVolumeClaim 219 | metadata: 220 | creationTimestamp: null 221 | labels: 222 | name: ide 223 | name: ide-workspace-data 224 | namespace: ide 225 | spec: 226 | accessModes: 227 | - ReadWriteOnce 228 | resources: 229 | requests: 230 | storage: 1Gi 231 | status: 232 | phase: Pending 233 | - apiVersion: extensions/v1beta1 234 | kind: Ingress 235 | metadata: 236 | annotations: 237 | kubernetes.io/ingress.class: traefik 238 | creationTimestamp: null 239 | name: ide 240 | namespace: ide 241 | spec: 242 | rules: 243 | - http: 244 | paths: 245 | - backend: 246 | serviceName: ide 247 | servicePort: http 248 | path: / 249 | status: 250 | loadBalancer: {} 251 | - apiVersion: extensions/v1beta1 252 | kind: Ingress 253 | metadata: 254 | annotations: 255 | kubernetes.io/ingress.class: traefik 256 | traefik.frontend.rule.type: PathPrefixStrip 257 | creationTimestamp: null 258 | name: grafana 259 | namespace: weave 260 | spec: 261 | rules: 262 | - http: 263 | paths: 264 | - backend: 265 | serviceName: grafana 266 | servicePort: grafana 267 | path: /grafana 268 | status: 269 | loadBalancer: {} 270 | - apiVersion: extensions/v1beta1 271 | kind: Ingress 272 | metadata: 273 | annotations: 274 | kubernetes.io/ingress.class: traefik 275 | creationTimestamp: null 276 | name: prometheus 277 | namespace: weave 278 | spec: 279 | rules: 280 | - http: 281 | paths: 282 | - backend: 283 | serviceName: prometheus 284 | servicePort: prometheus 285 | path: /prometheus 286 | status: 287 | loadBalancer: {} 288 | kind: List 289 | metadata: {} 290 | -------------------------------------------------------------------------------- /modules/weavecloud/cortex-config.yaml: -------------------------------------------------------------------------------- 1 | Kind: kubegen.k8s.io/Module.v1alpha2 2 | 3 | ConfigMaps: 4 | 5 | - name: "weave-cortex-agent-config" 6 | namespace: "weave" 7 | labels: 8 | app: "weave-cortex" 9 | name: "weave-cortex-agent-config" 10 | weave-cloud-component: "cortex" 11 | weave-cortex-component: "agent-config" 12 | data: 13 | prometheus.yml: 14 | kubegen.String.AsYAML: 15 | global: 16 | scrape_interval: 15s 17 | remote_write: 18 | - url: 'https://cloud.weave.works./api/prom/push' 19 | bearer_token_file: /etc/weave-cloud/token 20 | queue_config: 21 | max_samples_per_send: 1000 22 | scrape_configs: 23 | - job_name: kubernetes-apiservers 24 | kubernetes_sd_configs: 25 | - role: endpoints 26 | scheme: https 27 | tls_config: 28 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 29 | insecure_skip_verify: true 30 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 31 | relabel_configs: 32 | - source_labels: 33 | - __meta_kubernetes_namespace 34 | - __meta_kubernetes_service_name 35 | - __meta_kubernetes_endpoint_port_name 36 | action: keep 37 | regex: default;kubernetes;https 38 | - source_labels: 39 | - __meta_kubernetes_namespace 40 | target_label: kubernetes_namespace 41 | - source_labels: 42 | - __meta_kubernetes_endpoints_name 43 | target_label: _weave_service 44 | - job_name: kubernetes-pods 45 | kubernetes_sd_configs: 46 | - role: pod 47 | relabel_configs: 48 | - source_labels: 49 | - __meta_kubernetes_pod_annotation_prometheus_io_scrape 50 | action: drop 51 | regex: 'false' 52 | - source_labels: 53 | - __meta_kubernetes_pod_annotation_prometheus_io_scheme 54 | action: replace 55 | target_label: __scheme__ 56 | regex: ^(https?)$ 57 | replacement: $1 58 | - source_labels: 59 | - __meta_kubernetes_pod_annotation_prometheus_io_path 60 | action: replace 61 | target_label: __metrics_path__ 62 | regex: ^(.+)$ 63 | replacement: $1 64 | - source_labels: 65 | - __address__ 66 | - __meta_kubernetes_pod_annotation_prometheus_io_port 67 | action: replace 68 | target_label: __address__ 69 | regex: '([^:]+)(?::\d+)?;(\d+)' 70 | replacement: '$1:$2' 71 | - source_labels: 72 | - __meta_kubernetes_namespace 73 | target_label: kubernetes_namespace 74 | - source_labels: 75 | - __meta_kubernetes_pod_name 76 | target_label: kubernetes_pod_name 77 | - source_labels: 78 | - __meta_kubernetes_pod_name 79 | - __meta_kubernetes_pod_node_name 80 | target_label: node 81 | regex: ^prom-node-exporter-.+;(.+)$ 82 | replacement: $1 83 | - source_labels: 84 | - _weave_service 85 | - __meta_kubernetes_pod_name 86 | target_label: _weave_service 87 | regex: '^;(kube-.*)-(?:ip|gke)-.*$' 88 | replacement: $1 89 | - source_labels: 90 | - _weave_service 91 | - __meta_kubernetes_pod_name 92 | target_label: _weave_service 93 | regex: '^;(.*?)(?:(?:-[0-9bcdf]+)?-[0-9a-z]{5})?$' 94 | replacement: $1 95 | - source_labels: 96 | - _weave_service 97 | - __meta_kubernetes_pod_name 98 | regex: ^;(.+)$ 99 | target_label: _weave_service 100 | replacement: $1 101 | - job_name: kubernetes-nodes 102 | kubernetes_sd_configs: 103 | - role: node 104 | tls_config: 105 | insecure_skip_verify: true 106 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 107 | relabel_configs: 108 | - target_label: __scheme__ 109 | replacement: https 110 | - target_label: kubernetes_namespace 111 | replacement: default 112 | - target_label: _weave_service 113 | replacement: kubelet 114 | - target_label: __address__ 115 | replacement: 'kubernetes.default.svc:443' 116 | - source_labels: 117 | - __meta_kubernetes_node_name 118 | regex: (.+) 119 | target_label: __metrics_path__ 120 | replacement: '/api/v1/nodes/${1}/proxy/metrics' 121 | - job_name: weave-net 122 | kubernetes_sd_configs: 123 | - role: pod 124 | relabel_configs: 125 | - source_labels: 126 | - __meta_kubernetes_namespace 127 | - __meta_kubernetes_pod_label_name 128 | action: keep 129 | regex: ^kube-system;weave-net$ 130 | - source_labels: 131 | - __meta_kubernetes_pod_container_name 132 | - __address__ 133 | action: replace 134 | target_label: __address__ 135 | regex: '^weave;(.+?)(?::\d+)?$' 136 | replacement: '$1:6782' 137 | - source_labels: 138 | - __meta_kubernetes_pod_container_name 139 | - __address__ 140 | action: replace 141 | target_label: __address__ 142 | regex: '^weave-npc;(.+?)(?::\d+)?$' 143 | replacement: '$1:6781' 144 | - source_labels: 145 | - __meta_kubernetes_namespace 146 | target_label: kubernetes_namespace 147 | - source_labels: 148 | - __meta_kubernetes_pod_name 149 | target_label: kubernetes_pod_name 150 | - target_label: _weave_service 151 | replacement: weave-net 152 | - job_name: cadvisor 153 | kubernetes_sd_configs: 154 | - role: node 155 | tls_config: 156 | insecure_skip_verify: true 157 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 158 | scheme: https 159 | relabel_configs: 160 | - target_label: kubernetes_namespace 161 | replacement: default 162 | - target_label: _weave_service 163 | replacement: cadvisor 164 | - target_label: __address__ 165 | replacement: 'kubernetes.default.svc:443' 166 | - source_labels: 167 | - __meta_kubernetes_node_name 168 | regex: (.+) 169 | target_label: __metrics_path__ 170 | replacement: '/api/v1/nodes/${1}/proxy/metrics/cadvisor' 171 | metric_relabel_configs: 172 | - source_labels: 173 | - _weave_pod_name 174 | - pod_name 175 | target_label: _weave_pod_name 176 | regex: '^;(kube-.*)-(?:ip|gke)-.*$' 177 | replacement: $1 178 | - source_labels: 179 | - _weave_pod_name 180 | - pod_name 181 | target_label: _weave_pod_name 182 | regex: '^;(.*?)(?:(?:-[0-9bcdf]+)?-[0-9a-z]{5})?$' 183 | replacement: $1 184 | - source_labels: 185 | - _weave_pod_name 186 | - pod_name 187 | regex: ^;(.+)$ 188 | target_label: _weave_pod_name 189 | replacement: $1 190 | -------------------------------------------------------------------------------- /modules/weavecloud/include/weave-cloud.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "items": [ 4 | { 5 | "apiVersion": "v1", 6 | "kind": "Namespace", 7 | "metadata": { 8 | "annotations": { 9 | "cloud.weave.works/version": "v1.0.0-114-g1567592" 10 | }, 11 | "name": "weave" 12 | } 13 | }, 14 | { 15 | "apiVersion": "v1", 16 | "data": { 17 | "token": { 18 | "kubegen.String.AsBASE64": { 19 | "kubegen.String.Lookup": "service-token" 20 | } 21 | } 22 | }, 23 | "kind": "Secret", 24 | "metadata": { 25 | "name": "weave-cloud", 26 | "namespace": "weave" 27 | }, 28 | "type": "Opaque" 29 | }, 30 | { 31 | "apiVersion": "v1", 32 | "kind": "ServiceAccount", 33 | "metadata": { 34 | "labels": { 35 | "name": "weave-flux" 36 | }, 37 | "name": "weave-flux", 38 | "namespace": "weave" 39 | } 40 | }, 41 | { 42 | "apiVersion": "rbac.authorization.k8s.io/v1beta1", 43 | "kind": "ClusterRole", 44 | "metadata": { 45 | "labels": { 46 | "name": "weave-flux" 47 | }, 48 | "name": "weave-flux" 49 | }, 50 | "rules": [ 51 | { 52 | "apiGroups": [ 53 | "*" 54 | ], 55 | "resources": [ 56 | "*" 57 | ], 58 | "verbs": [ 59 | "*" 60 | ] 61 | }, 62 | { 63 | "nonResourceURLs": [ 64 | "*" 65 | ], 66 | "verbs": [ 67 | "*" 68 | ] 69 | } 70 | ] 71 | }, 72 | { 73 | "apiVersion": "rbac.authorization.k8s.io/v1beta1", 74 | "kind": "ClusterRoleBinding", 75 | "metadata": { 76 | "labels": { 77 | "name": "weave-flux" 78 | }, 79 | "name": "weave-flux" 80 | }, 81 | "roleRef": { 82 | "apiGroup": "rbac.authorization.k8s.io", 83 | "kind": "ClusterRole", 84 | "name": "weave-flux" 85 | }, 86 | "subjects": [ 87 | { 88 | "kind": "ServiceAccount", 89 | "name": "weave-flux", 90 | "namespace": "weave" 91 | } 92 | ] 93 | }, 94 | { 95 | "apiVersion": "v1", 96 | "kind": "Secret", 97 | "metadata": { 98 | "name": "flux-git-deploy", 99 | "namespace": "weave" 100 | }, 101 | "type": "Opaque" 102 | }, 103 | { 104 | "apiVersion": "apps/v1beta1", 105 | "kind": "Deployment", 106 | "metadata": { 107 | "labels": { 108 | "app": "weave-flux", 109 | "name": "weave-flux-memcached", 110 | "weave-cloud-component": "flux", 111 | "weave-flux-component": "memcached" 112 | }, 113 | "name": "weave-flux-memcached", 114 | "namespace": "weave" 115 | }, 116 | "spec": { 117 | "replicas": 1, 118 | "revisionHistoryLimit": 2, 119 | "template": { 120 | "metadata": { 121 | "annotations": { 122 | "prometheus.io.scrape": "false" 123 | }, 124 | "labels": { 125 | "app": "weave-flux", 126 | "name": "weave-flux-memcached", 127 | "weave-cloud-component": "flux", 128 | "weave-flux-component": "memcached" 129 | } 130 | }, 131 | "spec": { 132 | "containers": [ 133 | { 134 | "args": [ 135 | "-m 64", 136 | "-p 11211" 137 | ], 138 | "image": "memcached:1.4.39-alpine", 139 | "imagePullPolicy": "IfNotPresent", 140 | "name": "memcached", 141 | "ports": [ 142 | { 143 | "containerPort": 11211, 144 | "name": "clients" 145 | } 146 | ] 147 | } 148 | ] 149 | } 150 | } 151 | } 152 | }, 153 | { 154 | "apiVersion": "v1", 155 | "kind": "Service", 156 | "metadata": { 157 | "labels": { 158 | "app": "weave-flux", 159 | "name": "weave-flux-memcached", 160 | "weave-cloud-component": "flux", 161 | "weave-flux-component": "memcached" 162 | }, 163 | "name": "weave-flux-memcached", 164 | "namespace": "weave" 165 | }, 166 | "spec": { 167 | "clusterIP": "None", 168 | "ports": [ 169 | { 170 | "name": "memcached", 171 | "port": 11211 172 | } 173 | ], 174 | "selector": { 175 | "app": "weave-flux", 176 | "name": "weave-flux-memcached", 177 | "weave-cloud-component": "flux", 178 | "weave-flux-component": "memcached" 179 | } 180 | } 181 | }, 182 | { 183 | "apiVersion": "apps/v1beta1", 184 | "kind": "Deployment", 185 | "metadata": { 186 | "labels": { 187 | "app": "weave-flux", 188 | "name": "weave-flux-agent", 189 | "weave-cloud-component": "flux", 190 | "weave-flux-component": "agent" 191 | }, 192 | "name": "weave-flux-agent", 193 | "namespace": "weave" 194 | }, 195 | "spec": { 196 | "replicas": 1, 197 | "revisionHistoryLimit": 2, 198 | "strategy": { 199 | "type": "Recreate" 200 | }, 201 | "template": { 202 | "metadata": { 203 | "annotations": { 204 | "prometheus.io.port": "3030" 205 | }, 206 | "labels": { 207 | "app": "weave-flux", 208 | "name": "weave-flux-agent", 209 | "weave-cloud-component": "flux", 210 | "weave-flux-component": "agent" 211 | } 212 | }, 213 | "spec": { 214 | "containers": [ 215 | { 216 | "args": [ 217 | "--token=$(WEAVE_CLOUD_TOKEN)", 218 | "--connect=wss://cloud.weave.works./api/flux", 219 | "--memcached-hostname=weave-flux-memcached.weave.svc.cluster.local", 220 | "--ssh-keygen-dir=/var/fluxd/keygen", 221 | "--k8s-secret-name=ssh-git", 222 | "--git-url=ssh://git@git-server.ide.svc.cluster.local./~/cluster.git", 223 | "--git-branch=master", 224 | "--git-poll-interval=30s", 225 | "--registry-poll-interval=30s", 226 | "--registry-rps=200", 227 | "--git-ci-skip=true" 228 | ], 229 | "env": [ 230 | { 231 | "name": "WEAVE_CLOUD_TOKEN", 232 | "valueFrom": { 233 | "secretKeyRef": { 234 | "key": "token", 235 | "name": "weave-cloud" 236 | } 237 | } 238 | } 239 | ], 240 | "image": "quay.io/weaveworks/flux:1.4.0", 241 | "imagePullPolicy": "IfNotPresent", 242 | "name": "flux-agent", 243 | "volumeMounts": [ 244 | { 245 | "name": "ssh-git", 246 | "mountPath": "/root/.ssh", 247 | "readOnly": true 248 | }, 249 | { 250 | "name": "ssh-git", 251 | "mountPath": "/etc/flux/ssh", 252 | "readOnly": true 253 | }, 254 | { 255 | "name": "ssh-keygen", 256 | "mountPath": "/var/fluxd/keygen" 257 | } 258 | ] 259 | } 260 | ], 261 | "serviceAccountName": "weave-flux", 262 | "volumes": [ 263 | { 264 | "name": "ssh-git", 265 | "secret": { 266 | "secretName": "ssh-git", 267 | "defaultMode": 256 268 | } 269 | }, 270 | { 271 | "name": "ssh-keygen", 272 | "emptyDir": { 273 | "medium": "Memory" 274 | } 275 | } 276 | ] 277 | } 278 | } 279 | } 280 | }, 281 | { 282 | "apiVersion": "v1", 283 | "kind": "ServiceAccount", 284 | "metadata": { 285 | "labels": { 286 | "name": "weave-scope" 287 | }, 288 | "name": "weave-scope", 289 | "namespace": "weave" 290 | } 291 | }, 292 | { 293 | "apiVersion": "rbac.authorization.k8s.io/v1beta1", 294 | "kind": "ClusterRole", 295 | "metadata": { 296 | "labels": { 297 | "name": "weave-scope" 298 | }, 299 | "name": "weave-scope" 300 | }, 301 | "rules": [ 302 | { 303 | "apiGroups": [ 304 | "" 305 | ], 306 | "resources": [ 307 | "pods" 308 | ], 309 | "verbs": [ 310 | "get", 311 | "list", 312 | "watch", 313 | "delete" 314 | ] 315 | }, 316 | { 317 | "apiGroups": [ 318 | "" 319 | ], 320 | "resources": [ 321 | "pods/log", 322 | "services", 323 | "nodes", 324 | "namespaces" 325 | ], 326 | "verbs": [ 327 | "get", 328 | "list", 329 | "watch" 330 | ] 331 | }, 332 | { 333 | "apiGroups": [ 334 | "apps" 335 | ], 336 | "resources": [ 337 | "statefulsets" 338 | ], 339 | "verbs": [ 340 | "get", 341 | "list", 342 | "watch" 343 | ] 344 | }, 345 | { 346 | "apiGroups": [ 347 | "batch" 348 | ], 349 | "resources": [ 350 | "cronjobs", 351 | "jobs" 352 | ], 353 | "verbs": [ 354 | "get", 355 | "list", 356 | "watch" 357 | ] 358 | }, 359 | { 360 | "apiGroups": [ 361 | "extensions" 362 | ], 363 | "resources": [ 364 | "deployments", 365 | "daemonsets" 366 | ], 367 | "verbs": [ 368 | "get", 369 | "list", 370 | "watch" 371 | ] 372 | }, 373 | { 374 | "apiGroups": [ 375 | "extensions" 376 | ], 377 | "resources": [ 378 | "deployments/scale" 379 | ], 380 | "verbs": [ 381 | "get", 382 | "update" 383 | ] 384 | } 385 | ] 386 | }, 387 | { 388 | "apiVersion": "rbac.authorization.k8s.io/v1beta1", 389 | "kind": "ClusterRoleBinding", 390 | "metadata": { 391 | "labels": { 392 | "name": "weave-scope" 393 | }, 394 | "name": "weave-scope" 395 | }, 396 | "roleRef": { 397 | "apiGroup": "rbac.authorization.k8s.io", 398 | "kind": "ClusterRole", 399 | "name": "weave-scope" 400 | }, 401 | "subjects": [ 402 | { 403 | "kind": "ServiceAccount", 404 | "name": "weave-scope", 405 | "namespace": "weave" 406 | } 407 | ] 408 | }, 409 | { 410 | "apiVersion": "extensions/v1beta1", 411 | "kind": "DaemonSet", 412 | "metadata": { 413 | "labels": { 414 | "app": "weave-scope", 415 | "name": "weave-scope-agent", 416 | "weave-cloud-component": "scope", 417 | "weave-scope-component": "agent" 418 | }, 419 | "name": "weave-scope-agent", 420 | "namespace": "weave" 421 | }, 422 | "spec": { 423 | "minReadySeconds": 5, 424 | "template": { 425 | "metadata": { 426 | "labels": { 427 | "app": "weave-scope", 428 | "name": "weave-scope-agent", 429 | "weave-cloud-component": "scope", 430 | "weave-scope-component": "agent" 431 | } 432 | }, 433 | "spec": { 434 | "containers": [ 435 | { 436 | "args": [ 437 | "--mode=probe", 438 | "--probe-only", 439 | "--probe.docker.bridge=docker0", 440 | "--probe.docker=true", 441 | "--probe.kubernetes=true", 442 | "https://$(WEAVE_CLOUD_TOKEN)@cloud.weave.works." 443 | ], 444 | "command": [ 445 | "/home/weave/scope" 446 | ], 447 | "env": [ 448 | { 449 | "name": "WEAVE_CLOUD_TOKEN", 450 | "valueFrom": { 451 | "secretKeyRef": { 452 | "key": "token", 453 | "name": "weave-cloud" 454 | } 455 | } 456 | }, 457 | { 458 | "name": "KUBERNETES_HOSTNAME", 459 | "valueFrom": { 460 | "fieldRef": { 461 | "apiVersion": "v1", 462 | "fieldPath": "spec.nodeName" 463 | } 464 | } 465 | } 466 | ], 467 | "image": "weaveworks/scope:1.9.0", 468 | "imagePullPolicy": "IfNotPresent", 469 | "name": "scope-agent", 470 | "securityContext": { 471 | "privileged": true 472 | }, 473 | "volumeMounts": [ 474 | { 475 | "mountPath": "/var/run/docker.sock", 476 | "name": "docker-socket" 477 | }, 478 | { 479 | "mountPath": "/var/run/scope/plugins", 480 | "name": "scope-plugins" 481 | }, 482 | { 483 | "mountPath": "/sys/kernel/debug", 484 | "name": "sys-kernel-debug" 485 | } 486 | ] 487 | } 488 | ], 489 | "dnsPolicy": "ClusterFirstWithHostNet", 490 | "hostNetwork": true, 491 | "hostPID": true, 492 | "serviceAccountName": "weave-scope", 493 | "tolerations": [ 494 | { 495 | "effect": "NoSchedule", 496 | "operator": "Exists" 497 | } 498 | ], 499 | "volumes": [ 500 | { 501 | "hostPath": { 502 | "path": "/var/run/docker.sock" 503 | }, 504 | "name": "docker-socket" 505 | }, 506 | { 507 | "hostPath": { 508 | "path": "/var/run/scope/plugins" 509 | }, 510 | "name": "scope-plugins" 511 | }, 512 | { 513 | "hostPath": { 514 | "path": "/sys/kernel/debug" 515 | }, 516 | "name": "sys-kernel-debug" 517 | } 518 | ] 519 | } 520 | }, 521 | "updateStrategy": { 522 | "type": "RollingUpdate" 523 | } 524 | } 525 | }, 526 | { 527 | "apiVersion": "v1", 528 | "kind": "ServiceAccount", 529 | "metadata": { 530 | "labels": { 531 | "name": "weave-cortex" 532 | }, 533 | "name": "weave-cortex", 534 | "namespace": "weave" 535 | } 536 | }, 537 | { 538 | "apiVersion": "rbac.authorization.k8s.io/v1beta1", 539 | "kind": "ClusterRole", 540 | "metadata": { 541 | "labels": { 542 | "name": "weave-cortex" 543 | }, 544 | "name": "weave-cortex" 545 | }, 546 | "rules": [ 547 | { 548 | "apiGroups": [ 549 | "" 550 | ], 551 | "resources": [ 552 | "configmaps", 553 | "endpoints", 554 | "limitranges", 555 | "namespaces", 556 | "nodes", 557 | "nodes/proxy", 558 | "persistentvolumeclaims", 559 | "persistentvolumes", 560 | "pods", 561 | "replicationcontrollers", 562 | "resourcequotas", 563 | "secrets", 564 | "services" 565 | ], 566 | "verbs": [ 567 | "get", 568 | "list", 569 | "watch" 570 | ] 571 | }, 572 | { 573 | "apiGroups": [ 574 | "extensions" 575 | ], 576 | "resources": [ 577 | "daemonsets", 578 | "deployments", 579 | "ingresses", 580 | "replicasets" 581 | ], 582 | "verbs": [ 583 | "get", 584 | "list", 585 | "watch" 586 | ] 587 | }, 588 | { 589 | "apiGroups": [ 590 | "apps" 591 | ], 592 | "resources": [ 593 | "statefulsets" 594 | ], 595 | "verbs": [ 596 | "get", 597 | "list", 598 | "watch" 599 | ] 600 | }, 601 | { 602 | "apiGroups": [ 603 | "batch" 604 | ], 605 | "resources": [ 606 | "cronjobs", 607 | "jobs" 608 | ], 609 | "verbs": [ 610 | "get", 611 | "list", 612 | "watch" 613 | ] 614 | }, 615 | { 616 | "apiGroups": [ 617 | "autoscaling" 618 | ], 619 | "resources": [ 620 | "horizontalpodautoscalers" 621 | ], 622 | "verbs": [ 623 | "get", 624 | "list", 625 | "watch" 626 | ] 627 | }, 628 | { 629 | "nonResourceURLs": [ 630 | "/metrics" 631 | ], 632 | "verbs": [ 633 | "get" 634 | ] 635 | } 636 | ] 637 | }, 638 | { 639 | "apiVersion": "rbac.authorization.k8s.io/v1beta1", 640 | "kind": "ClusterRoleBinding", 641 | "metadata": { 642 | "labels": { 643 | "name": "weave-cortex" 644 | }, 645 | "name": "weave-cortex" 646 | }, 647 | "roleRef": { 648 | "apiGroup": "rbac.authorization.k8s.io", 649 | "kind": "ClusterRole", 650 | "name": "weave-cortex" 651 | }, 652 | "subjects": [ 653 | { 654 | "kind": "ServiceAccount", 655 | "name": "weave-cortex", 656 | "namespace": "weave" 657 | } 658 | ] 659 | }, 660 | { 661 | "apiVersion": "apps/v1beta1", 662 | "kind": "Deployment", 663 | "metadata": { 664 | "labels": { 665 | "app": "weave-cortex", 666 | "name": "prometheus", 667 | "weave-cloud-component": "cortex", 668 | "weave-cortex-component": "agent" 669 | }, 670 | "name": "prometheus", 671 | "namespace": "weave" 672 | }, 673 | "spec": { 674 | "replicas": 1, 675 | "revisionHistoryLimit": 2, 676 | "template": { 677 | "metadata": { 678 | "annotations": { 679 | "prometheus.io.scrape": "true" 680 | }, 681 | "labels": { 682 | "app": "weave-cortex", 683 | "name": "prometheus", 684 | "weave-cloud-component": "cortex", 685 | "weave-cortex-component": "agent" 686 | } 687 | }, 688 | "spec": { 689 | "containers": [ 690 | { 691 | "args": [ 692 | "-config.file=/etc/prometheus/prometheus.yml", 693 | "-web.listen-address=:8080", 694 | { 695 | "kubegen.String.Join": [ 696 | "-web.external-url=http://", 697 | { "kubegen.String.Lookup": "external-dns/domain" }, 698 | "/prometheus" 699 | ] 700 | } 701 | ], 702 | "env": [], 703 | "image": "prom/prometheus:v1.8.2", 704 | "imagePullPolicy": "IfNotPresent", 705 | "name": "prometheus", 706 | "ports": [ 707 | { 708 | "containerPort": 8080, 709 | "protocol": "TCP" 710 | } 711 | ], 712 | "volumeMounts": [ 713 | { 714 | "mountPath": "/etc/weave-cloud", 715 | "name": "weave-cloud-secret", 716 | "readOnly": true 717 | }, 718 | { 719 | "mountPath": "/etc/prometheus", 720 | "name": "agent-config-volume" 721 | } 722 | ] 723 | }, 724 | { 725 | "args": [ 726 | "-v", 727 | "-t", 728 | "-p=/etc/prometheus", 729 | "curl", 730 | "-X", 731 | "POST", 732 | "--fail", 733 | "-o", 734 | "-", 735 | "-sS", 736 | "http://localhost:8080/-/reload" 737 | ], 738 | "env": [], 739 | "image": "quay.io/weaveworks/watch:master-85fdf1d", 740 | "imagePullPolicy": "IfNotPresent", 741 | "name": "watch-configmap", 742 | "volumeMounts": [ 743 | { 744 | "mountPath": "/etc/prometheus", 745 | "name": "agent-config-volume" 746 | } 747 | ] 748 | } 749 | ], 750 | "serviceAccountName": "weave-cortex", 751 | "volumes": [ 752 | { 753 | "name": "weave-cloud-secret", 754 | "secret": { 755 | "secretName": "weave-cloud" 756 | } 757 | }, 758 | { 759 | "configMap": { 760 | "name": "weave-cortex-agent-config" 761 | }, 762 | "name": "agent-config-volume" 763 | } 764 | ] 765 | } 766 | } 767 | } 768 | }, 769 | { 770 | "apiVersion": "extensions/v1beta1", 771 | "kind": "DaemonSet", 772 | "metadata": { 773 | "labels": { 774 | "app": "weave-cortex", 775 | "name": "prom-node-exporter", 776 | "weave-cloud-component": "cortex", 777 | "weave-cortex-component": "node-exporter" 778 | }, 779 | "name": "prom-node-exporter", 780 | "namespace": "weave" 781 | }, 782 | "spec": { 783 | "minReadySeconds": 5, 784 | "template": { 785 | "metadata": { 786 | "annotations": { 787 | "prometheus.io.scrape": "true" 788 | }, 789 | "labels": { 790 | "app": "weave-cortex", 791 | "name": "prom-node-exporter", 792 | "weave-cloud-component": "cortex", 793 | "weave-cortex-component": "node-exporter" 794 | } 795 | }, 796 | "spec": { 797 | "containers": [ 798 | { 799 | "env": [], 800 | "image": "prom/node-exporter:v0.15.2", 801 | "imagePullPolicy": "IfNotPresent", 802 | "name": "prom-node-exporter", 803 | "ports": [ 804 | { 805 | "containerPort": 9100, 806 | "protocol": "TCP" 807 | } 808 | ], 809 | "securityContext": { 810 | "privileged": true 811 | } 812 | } 813 | ], 814 | "hostNetwork": true, 815 | "hostPID": true, 816 | "serviceAccountName": "weave-cortex", 817 | "tolerations": [ 818 | { 819 | "effect": "NoSchedule", 820 | "operator": "Exists" 821 | } 822 | ] 823 | } 824 | }, 825 | "updateStrategy": { 826 | "type": "RollingUpdate" 827 | } 828 | } 829 | }, 830 | { 831 | "apiVersion": "apps/v1beta1", 832 | "kind": "Deployment", 833 | "metadata": { 834 | "labels": { 835 | "app": "weave-cortex", 836 | "name": "kube-state-metrics", 837 | "weave-cloud-component": "cortex", 838 | "weave-cortex-component": "state-metrics" 839 | }, 840 | "name": "kube-state-metrics", 841 | "namespace": "weave" 842 | }, 843 | "spec": { 844 | "replicas": 1, 845 | "revisionHistoryLimit": 2, 846 | "template": { 847 | "metadata": { 848 | "annotations": { 849 | "prometheus.io.scrape": "true" 850 | }, 851 | "labels": { 852 | "app": "weave-cortex", 853 | "name": "kube-state-metrics", 854 | "weave-cloud-component": "cortex", 855 | "weave-cortex-component": "state-metrics" 856 | } 857 | }, 858 | "spec": { 859 | "containers": [ 860 | { 861 | "env": [], 862 | "image": "quay.io/coreos/kube-state-metrics:v1.3.0", 863 | "name": "kube-state-metrics", 864 | "ports": [ 865 | { 866 | "containerPort": 8080, 867 | "name": "metrics" 868 | } 869 | ] 870 | } 871 | ], 872 | "serviceAccountName": "weave-cortex" 873 | } 874 | } 875 | } 876 | } 877 | ], 878 | "kind": "List" 879 | } 880 | --------------------------------------------------------------------------------