diff --git a/clr-k8s-examples/0-canal/canal.yaml b/clr-k8s-examples/0-canal/canal.yaml
new file mode 100644
index 0000000..9369f05
--- /dev/null
+++ b/clr-k8s-examples/0-canal/canal.yaml
@@ -0,0 +1,405 @@
+# Canal Version v3.3.0
+# https://docs.projectcalico.org/v3.3/releases#v3.3.0
+# This manifest includes the following component versions:
+# calico/node:v3.3.0
+# calico/cni:v3.3.0
+# coreos/flannel:v0.9.1
+
+# This ConfigMap is used to configure a self-hosted Canal installation.
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: canal-config
+ namespace: kube-system
+data:
+ # The interface used by canal for host <-> host communication.
+ # If left blank, then the interface is chosen using the node's
+ # default route.
+ canal_iface: ""
+
+ # Whether or not to masquerade traffic to destinations not within
+ # the pod network.
+ masquerade: "true"
+
+ # The CNI network configuration to install on each node. The special
+ # values in this config will be automatically populated.
+ cni_network_config: |-
+ {
+ "name": "k8s-pod-network",
+ "cniVersion": "0.3.0",
+ "plugins": [
+ {
+ "type": "calico",
+ "log_level": "info",
+ "datastore_type": "kubernetes",
+ "nodename": "__KUBERNETES_NODE_NAME__",
+ "ipam": {
+ "type": "host-local",
+ "subnet": "usePodCidr"
+ },
+ "policy": {
+ "type": "k8s"
+ },
+ "kubernetes": {
+ "kubeconfig": "__KUBECONFIG_FILEPATH__"
+ }
+ },
+ {
+ "type": "portmap",
+ "snat": true,
+ "capabilities": {"portMappings": true}
+ }
+ ]
+ }
+
+ # Flannel network configuration. Mounted into the flannel container.
+ net-conf.json: |
+ {
+ "Network": "10.244.0.0/16",
+ "Backend": {
+ "Type": "vxlan"
+ }
+ }
+
+---
+
+
+
+# This manifest installs the calico/node container, as well
+# as the Calico CNI plugins and network config on
+# each master and worker node in a Kubernetes cluster.
+kind: DaemonSet
+apiVersion: extensions/v1beta1
+metadata:
+ name: canal
+ namespace: kube-system
+ labels:
+ k8s-app: canal
+spec:
+ selector:
+ matchLabels:
+ k8s-app: canal
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxUnavailable: 1
+ template:
+ metadata:
+ labels:
+ k8s-app: canal
+ annotations:
+ # This, along with the CriticalAddonsOnly toleration below,
+ # marks the pod as a critical add-on, ensuring it gets
+ # priority scheduling and that its resources are reserved
+ # if it ever gets evicted.
+ scheduler.alpha.kubernetes.io/critical-pod: ''
+ spec:
+ nodeSelector:
+ beta.kubernetes.io/os: linux
+ hostNetwork: true
+ tolerations:
+ # Make sure canal gets scheduled on all nodes.
+ - effect: NoSchedule
+ operator: Exists
+ # Mark the pod as a critical add-on for rescheduling.
+ - key: CriticalAddonsOnly
+ operator: Exists
+ - effect: NoExecute
+ operator: Exists
+ serviceAccountName: canal
+ # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force
+ # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.
+ terminationGracePeriodSeconds: 0
+ containers:
+ # Runs calico/node container on each Kubernetes node. This
+ # container programs network policy and routes on each
+ # host.
+ - name: calico-node
+ image: quay.io/calico/node:v3.3.0
+ env:
+ # Use Kubernetes API as the backing datastore.
+ - name: DATASTORE_TYPE
+ value: "kubernetes"
+ # Wait for the datastore.
+ - name: WAIT_FOR_DATASTORE
+ value: "true"
+ # Set based on the k8s node name.
+ - name: NODENAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ # Don't enable BGP.
+ - name: CALICO_NETWORKING_BACKEND
+ value: "none"
+ # Cluster type to identify the deployment type
+ - name: CLUSTER_TYPE
+ value: "k8s,canal"
+ # Period, in seconds, at which felix re-applies all iptables state
+ - name: FELIX_IPTABLESREFRESHINTERVAL
+ value: "60"
+ # No IP address needed.
+ - name: IP
+ value: ""
+ # The default IPv4 pool to create on startup if none exists. Pod IPs will be
+ # chosen from this range. Changing this value after installation will have
+ # no effect. This should fall within `--cluster-cidr`.
+ - name: CALICO_IPV4POOL_CIDR
+ value: "192.168.0.0/16"
+ # Disable file logging so `kubectl logs` works.
+ - name: CALICO_DISABLE_FILE_LOGGING
+ value: "true"
+ # Set Felix endpoint to host default action to ACCEPT.
+ - name: FELIX_DEFAULTENDPOINTTOHOSTACTION
+ value: "ACCEPT"
+ # Disable IPv6 on Kubernetes.
+ - name: FELIX_IPV6SUPPORT
+ value: "false"
+ # Set Felix logging to "info"
+ - name: FELIX_LOGSEVERITYSCREEN
+ value: "info"
+ - name: FELIX_HEALTHENABLED
+ value: "true"
+ securityContext:
+ privileged: true
+ resources:
+ requests:
+ cpu: 250m
+ livenessProbe:
+ httpGet:
+ path: /liveness
+ port: 9099
+ host: localhost
+ periodSeconds: 10
+ initialDelaySeconds: 10
+ failureThreshold: 6
+ readinessProbe:
+ httpGet:
+ path: /readiness
+ port: 9099
+ host: localhost
+ periodSeconds: 10
+ volumeMounts:
+ - mountPath: /lib/modules
+ name: lib-modules
+ readOnly: true
+ - mountPath: /run/xtables.lock
+ name: xtables-lock
+ readOnly: false
+ - mountPath: /var/run/calico
+ name: var-run-calico
+ readOnly: false
+ - mountPath: /var/lib/calico
+ name: var-lib-calico
+ readOnly: false
+ # This container installs the Calico CNI binaries
+ # and CNI network config file on each node.
+ - name: install-cni
+ image: quay.io/calico/cni:v3.3.0
+ command: ["/install-cni.sh"]
+ env:
+ # Name of the CNI config file to create.
+ - name: CNI_CONF_NAME
+ value: "10-canal.conflist"
+ # Set the hostname based on the k8s node name.
+ - name: KUBERNETES_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
+ # The CNI network config to install on each node.
+ - name: CNI_NETWORK_CONFIG
+ valueFrom:
+ configMapKeyRef:
+ name: canal-config
+ key: cni_network_config
+ volumeMounts:
+ - mountPath: /host/opt/cni/bin
+ name: cni-bin-dir
+ - mountPath: /host/etc/cni/net.d
+ name: cni-net-dir
+ # This container runs flannel using the kube-subnet-mgr backend
+ # for allocating subnets.
+ - name: kube-flannel
+ image: quay.io/coreos/flannel:v0.9.1
+ command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr" ]
+ securityContext:
+ privileged: true
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
+ - name: POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: FLANNELD_IFACE
+ valueFrom:
+ configMapKeyRef:
+ name: canal-config
+ key: canal_iface
+ - name: FLANNELD_IP_MASQ
+ valueFrom:
+ configMapKeyRef:
+ name: canal-config
+ key: masquerade
+ volumeMounts:
+ - mountPath: /run/xtables.lock
+ name: xtables-lock
+ readOnly: false
+ - name: flannel-cfg
+ mountPath: /etc/kube-flannel/
+ volumes:
+ # Used by calico/node.
+ - name: lib-modules
+ hostPath:
+ path: /lib/modules
+ - name: var-run-calico
+ hostPath:
+ path: /var/run/calico
+ - name: var-lib-calico
+ hostPath:
+ path: /var/lib/calico
+ - name: xtables-lock
+ hostPath:
+ path: /run/xtables.lock
+ type: FileOrCreate
+ # Used by flannel.
+ - name: flannel-cfg
+ configMap:
+ name: canal-config
+ # Used to install CNI.
+ - name: cni-bin-dir
+ hostPath:
+ path: /opt/cni/bin
+ - name: cni-net-dir
+ hostPath:
+ path: /etc/cni/net.d
+---
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: canal
+ namespace: kube-system
+
+---
+
+# Create all the CustomResourceDefinitions needed for
+# Calico policy and networking mode.
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: felixconfigurations.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: FelixConfiguration
+ plural: felixconfigurations
+ singular: felixconfiguration
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: bgpconfigurations.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: BGPConfiguration
+ plural: bgpconfigurations
+ singular: bgpconfiguration
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: ippools.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: IPPool
+ plural: ippools
+ singular: ippool
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: hostendpoints.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: HostEndpoint
+ plural: hostendpoints
+ singular: hostendpoint
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: clusterinformations.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: ClusterInformation
+ plural: clusterinformations
+ singular: clusterinformation
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: globalnetworkpolicies.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: GlobalNetworkPolicy
+ plural: globalnetworkpolicies
+ singular: globalnetworkpolicy
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: globalnetworksets.crd.projectcalico.org
+spec:
+ scope: Cluster
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: GlobalNetworkSet
+ plural: globalnetworksets
+ singular: globalnetworkset
+
+---
+
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: networkpolicies.crd.projectcalico.org
+spec:
+ scope: Namespaced
+ group: crd.projectcalico.org
+ version: v1
+ names:
+ kind: NetworkPolicy
+ plural: networkpolicies
+ singular: networkpolicy
diff --git a/clr-k8s-examples/0-canal/rbac.yaml b/clr-k8s-examples/0-canal/rbac.yaml
new file mode 100644
index 0000000..582954f
--- /dev/null
+++ b/clr-k8s-examples/0-canal/rbac.yaml
@@ -0,0 +1,131 @@
+# {{site.prodname}} Roles
+# Reference {{site.url}}/{{page.version}}/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: calico
+rules:
+ - apiGroups: [""]
+ resources:
+ - namespaces
+ - serviceaccounts
+ verbs:
+ - get
+ - list
+ - watch
+ - apiGroups: [""]
+ resources:
+ - pods/status
+ verbs:
+ - patch
+ - apiGroups: [""]
+ resources:
+ - pods
+ verbs:
+ - get
+ - list
+ - watch
+ - apiGroups: [""]
+ resources:
+ - services
+ verbs:
+ - get
+ - apiGroups: [""]
+ resources:
+ - endpoints
+ verbs:
+ - get
+ - apiGroups: [""]
+ resources:
+ - nodes
+ verbs:
+ - get
+ - list
+ - update
+ - watch
+ - apiGroups: ["networking.k8s.io"]
+ resources:
+ - networkpolicies
+ verbs:
+ - get
+ - list
+ - watch
+ - apiGroups: ["crd.projectcalico.org"]
+ resources:
+ - globalfelixconfigs
+ - felixconfigurations
+ - bgppeers
+ - globalbgpconfigs
+ - globalnetworksets
+ - hostendpoints
+ - bgpconfigurations
+ - ippools
+ - globalnetworkpolicies
+ - networkpolicies
+ - clusterinformations
+ verbs:
+ - create
+ - get
+ - list
+ - update
+ - watch
+
+---
+
+# Flannel roles
+# Pulled from https://github.com/coreos/flannel/blob/master/Documentation/kube-flannel-rbac.yml
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: flannel
+rules:
+ - apiGroups:
+ - ""
+ resources:
+ - pods
+ verbs:
+ - get
+ - apiGroups:
+ - ""
+ resources:
+ - nodes
+ verbs:
+ - list
+ - watch
+ - apiGroups:
+ - ""
+ resources:
+ - nodes/status
+ verbs:
+ - patch
+---
+
+# Bind the flannel ClusterRole to the canal ServiceAccount.
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: canal-flannel
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: flannel
+subjects:
+- kind: ServiceAccount
+ name: canal
+ namespace: kube-system
+
+---
+
+# Bind the {{site.prodname}} ClusterRole to the canal ServiceAccount.
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+ name: canal-calico
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: calico
+subjects:
+- kind: ServiceAccount
+ name: canal
+ namespace: kube-system
diff --git a/clr-k8s-examples/0-canal/versions b/clr-k8s-examples/0-canal/versions
new file mode 100644
index 0000000..4cc6f03
--- /dev/null
+++ b/clr-k8s-examples/0-canal/versions
@@ -0,0 +1,2 @@
+https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
+https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/canal/canal.yaml
diff --git a/clr-k8s-examples/1-core-metrics/aggregated-metrics-reader.yaml b/clr-k8s-examples/1-core-metrics/aggregated-metrics-reader.yaml
new file mode 100644
index 0000000..cdf3415
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/aggregated-metrics-reader.yaml
@@ -0,0 +1,12 @@
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: system:aggregated-metrics-reader
+ labels:
+ rbac.authorization.k8s.io/aggregate-to-view: "true"
+ rbac.authorization.k8s.io/aggregate-to-edit: "true"
+ rbac.authorization.k8s.io/aggregate-to-admin: "true"
+rules:
+- apiGroups: ["metrics.k8s.io"]
+ resources: ["pods"]
+ verbs: ["get", "list", "watch"]
diff --git a/clr-k8s-examples/1-core-metrics/auth-delegator.yaml b/clr-k8s-examples/1-core-metrics/auth-delegator.yaml
new file mode 100644
index 0000000..e3442c5
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/auth-delegator.yaml
@@ -0,0 +1,13 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+ name: metrics-server:system:auth-delegator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: system:auth-delegator
+subjects:
+- kind: ServiceAccount
+ name: metrics-server
+ namespace: kube-system
diff --git a/clr-k8s-examples/1-core-metrics/auth-reader.yaml b/clr-k8s-examples/1-core-metrics/auth-reader.yaml
new file mode 100644
index 0000000..f0616e1
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/auth-reader.yaml
@@ -0,0 +1,14 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: RoleBinding
+metadata:
+ name: metrics-server-auth-reader
+ namespace: kube-system
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: extension-apiserver-authentication-reader
+subjects:
+- kind: ServiceAccount
+ name: metrics-server
+ namespace: kube-system
diff --git a/clr-k8s-examples/1-core-metrics/metrics-apiservice.yaml b/clr-k8s-examples/1-core-metrics/metrics-apiservice.yaml
new file mode 100644
index 0000000..08b0530
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/metrics-apiservice.yaml
@@ -0,0 +1,14 @@
+---
+apiVersion: apiregistration.k8s.io/v1beta1
+kind: APIService
+metadata:
+ name: v1beta1.metrics.k8s.io
+spec:
+ service:
+ name: metrics-server
+ namespace: kube-system
+ group: metrics.k8s.io
+ version: v1beta1
+ insecureSkipTLSVerify: true
+ groupPriorityMinimum: 100
+ versionPriority: 100
diff --git a/clr-k8s-examples/1-core-metrics/metrics-server-deployment.yaml b/clr-k8s-examples/1-core-metrics/metrics-server-deployment.yaml
new file mode 100644
index 0000000..af70451
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/metrics-server-deployment.yaml
@@ -0,0 +1,41 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: metrics-server
+ namespace: kube-system
+---
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+ name: metrics-server
+ namespace: kube-system
+ labels:
+ k8s-app: metrics-server
+spec:
+ selector:
+ matchLabels:
+ k8s-app: metrics-server
+ template:
+ metadata:
+ name: metrics-server
+ labels:
+ k8s-app: metrics-server
+ spec:
+ serviceAccountName: metrics-server
+ volumes:
+ # mount in tmp so we can safely use from-scratch images and/or read-only containers
+ - name: tmp-dir
+ emptyDir: {}
+ containers:
+ - name: metrics-server
+ image: k8s.gcr.io/metrics-server-amd64:v0.3.1
+ imagePullPolicy: Always
+ args:
+ - --kubelet-insecure-tls
+ - --kubelet-preferred-address-types=InternalIP
+ - --logtostderr
+ volumeMounts:
+ - name: tmp-dir
+ mountPath: /tmp
+
diff --git a/clr-k8s-examples/1-core-metrics/metrics-server-service.yaml b/clr-k8s-examples/1-core-metrics/metrics-server-service.yaml
new file mode 100644
index 0000000..082b00c
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/metrics-server-service.yaml
@@ -0,0 +1,15 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: metrics-server
+ namespace: kube-system
+ labels:
+ kubernetes.io/name: "Metrics-server"
+spec:
+ selector:
+ k8s-app: metrics-server
+ ports:
+ - port: 443
+ protocol: TCP
+ targetPort: 443
diff --git a/clr-k8s-examples/1-core-metrics/resource-reader.yaml b/clr-k8s-examples/1-core-metrics/resource-reader.yaml
new file mode 100644
index 0000000..34294a3
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/resource-reader.yaml
@@ -0,0 +1,38 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: system:metrics-server
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ - nodes
+ - nodes/stats
+ - namespaces
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - "extensions"
+ resources:
+ - deployments
+ verbs:
+ - get
+ - list
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: system:metrics-server
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: system:metrics-server
+subjects:
+- kind: ServiceAccount
+ name: metrics-server
+ namespace: kube-system
diff --git a/clr-k8s-examples/1-core-metrics/versions b/clr-k8s-examples/1-core-metrics/versions
new file mode 100644
index 0000000..f96508a
--- /dev/null
+++ b/clr-k8s-examples/1-core-metrics/versions
@@ -0,0 +1 @@
+https://github.com/kubernetes-incubator/metrics-server/tree/v0.3.1/deploy/1.8%2B
diff --git a/clr-k8s-examples/2-dashboard/dashboard-admin.yaml b/clr-k8s-examples/2-dashboard/dashboard-admin.yaml
new file mode 100644
index 0000000..5d76d39
--- /dev/null
+++ b/clr-k8s-examples/2-dashboard/dashboard-admin.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+ name: kubernetes-dashboard
+ labels:
+ k8s-app: kubernetes-dashboard
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: cluster-admin
+subjects:
+- kind: ServiceAccount
+ name: kubernetes-dashboard
+ namespace: kube-system
diff --git a/clr-k8s-examples/2-dashboard/kubernetes-dashboard.yaml b/clr-k8s-examples/2-dashboard/kubernetes-dashboard.yaml
new file mode 100644
index 0000000..8392c90
--- /dev/null
+++ b/clr-k8s-examples/2-dashboard/kubernetes-dashboard.yaml
@@ -0,0 +1,176 @@
+# Copyright 2017 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ------------------- Dashboard Secret ------------------- #
+
+apiVersion: v1
+kind: Secret
+metadata:
+ labels:
+ k8s-app: kubernetes-dashboard
+ name: kubernetes-dashboard-certs
+ namespace: kube-system
+type: Opaque
+
+---
+# ------------------- Dashboard Service Account ------------------- #
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ k8s-app: kubernetes-dashboard
+ name: kubernetes-dashboard
+ namespace: kube-system
+
+---
+# ------------------- Dashboard Role & Role Binding ------------------- #
+
+kind: Role
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: kubernetes-dashboard-minimal
+ namespace: kube-system
+rules:
+ # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
+- apiGroups: [""]
+ resources: ["secrets"]
+ verbs: ["create"]
+ # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
+- apiGroups: [""]
+ resources: ["configmaps"]
+ verbs: ["create"]
+ # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
+- apiGroups: [""]
+ resources: ["secrets"]
+ resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
+ verbs: ["get", "update", "delete"]
+ # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
+- apiGroups: [""]
+ resources: ["configmaps"]
+ resourceNames: ["kubernetes-dashboard-settings"]
+ verbs: ["get", "update"]
+ # Allow Dashboard to get metrics from heapster.
+- apiGroups: [""]
+ resources: ["services"]
+ resourceNames: ["heapster"]
+ verbs: ["proxy"]
+- apiGroups: [""]
+ resources: ["services/proxy"]
+ resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
+ verbs: ["get"]
+
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: kubernetes-dashboard-minimal
+ namespace: kube-system
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: kubernetes-dashboard-minimal
+subjects:
+- kind: ServiceAccount
+ name: kubernetes-dashboard
+ namespace: kube-system
+
+---
+# ------------------- Dashboard Deployment ------------------- #
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: kubernetes-dashboard-pvc
+ namespace: kube-system
+ labels:
+ k8s-app: kubernetes-dashboard
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+---
+kind: Deployment
+apiVersion: apps/v1beta2
+metadata:
+ labels:
+ k8s-app: kubernetes-dashboard
+ name: kubernetes-dashboard
+ namespace: kube-system
+spec:
+ replicas: 1
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ k8s-app: kubernetes-dashboard
+ template:
+ metadata:
+ labels:
+ k8s-app: kubernetes-dashboard
+ spec:
+ containers:
+ - name: kubernetes-dashboard
+ image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
+ ports:
+ - containerPort: 8443
+ protocol: TCP
+ args:
+ - --auto-generate-certificates
+ # Uncomment the following line to manually specify Kubernetes API server Host
+ # If not specified, Dashboard will attempt to auto discover the API server and connect
+ # to it. Uncomment only if the default does not work.
+ # - --apiserver-host=http://my-address:port
+ volumeMounts:
+ - name: kubernetes-dashboard-certs
+ mountPath: /certs
+ # Create on-disk volume to store exec logs
+ - mountPath: /tmp
+ name: tmp-volume
+ livenessProbe:
+ httpGet:
+ scheme: HTTPS
+ path: /
+ port: 8443
+ initialDelaySeconds: 30
+ timeoutSeconds: 30
+ volumes:
+ - name: kubernetes-dashboard-certs
+ secret:
+ secretName: kubernetes-dashboard-certs
+ - name: tmp-volume
+ persistentVolumeClaim:
+ claimName: kubernetes-dashboard-pvc
+ serviceAccountName: kubernetes-dashboard
+ # Comment the following tolerations if Dashboard must not be deployed on master
+ #tolerations:
+ #- key: node-role.kubernetes.io/master
+ # effect: NoSchedule
+
+---
+# ------------------- Dashboard Service ------------------- #
+
+kind: Service
+apiVersion: v1
+metadata:
+ labels:
+ k8s-app: kubernetes-dashboard
+ name: kubernetes-dashboard
+ namespace: kube-system
+spec:
+ ports:
+ - port: 443
+ targetPort: 8443
+ selector:
+ k8s-app: kubernetes-dashboard
diff --git a/clr-k8s-examples/2-dashboard/versions b/clr-k8s-examples/2-dashboard/versions
new file mode 100644
index 0000000..5dfe879
--- /dev/null
+++ b/clr-k8s-examples/2-dashboard/versions
@@ -0,0 +1 @@
+https://github.com/kubernetes/dashboard/commit/5728e0303a742a889d9a25c7ae9c07e426917e90
diff --git a/clr-k8s-examples/3-efk/es-service.yaml b/clr-k8s-examples/3-efk/es-service.yaml
new file mode 100644
index 0000000..ede9306
--- /dev/null
+++ b/clr-k8s-examples/3-efk/es-service.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: elasticsearch-logging
+ namespace: kube-system
+ labels:
+ k8s-app: elasticsearch-logging
+ kubernetes.io/cluster-service: "true"
+ addonmanager.kubernetes.io/mode: Reconcile
+ kubernetes.io/name: "Elasticsearch"
+spec:
+ ports:
+ - port: 9200
+ protocol: TCP
+ targetPort: db
+ selector:
+ k8s-app: elasticsearch-logging
diff --git a/clr-k8s-examples/3-efk/es-statefulset.yaml b/clr-k8s-examples/3-efk/es-statefulset.yaml
new file mode 100644
index 0000000..c90c0ec
--- /dev/null
+++ b/clr-k8s-examples/3-efk/es-statefulset.yaml
@@ -0,0 +1,117 @@
+# RBAC authn and authz
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: elasticsearch-logging
+ namespace: kube-system
+ labels:
+ k8s-app: elasticsearch-logging
+ kubernetes.io/cluster-service: "true"
+ addonmanager.kubernetes.io/mode: Reconcile
+---
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ name: elasticsearch-logging
+ labels:
+ k8s-app: elasticsearch-logging
+ kubernetes.io/cluster-service: "true"
+ addonmanager.kubernetes.io/mode: Reconcile
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - "services"
+ - "namespaces"
+ - "endpoints"
+ verbs:
+ - "get"
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+ namespace: kube-system
+ name: elasticsearch-logging
+ labels:
+ k8s-app: elasticsearch-logging
+ kubernetes.io/cluster-service: "true"
+ addonmanager.kubernetes.io/mode: Reconcile
+subjects:
+- kind: ServiceAccount
+ name: elasticsearch-logging
+ namespace: kube-system
+ apiGroup: ""
+roleRef:
+ kind: ClusterRole
+ name: elasticsearch-logging
+ apiGroup: ""
+---
+# Elasticsearch deployment itself
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: elasticsearch-logging
+ namespace: kube-system
+ labels:
+ k8s-app: elasticsearch-logging
+ version: v6.3.0
+ kubernetes.io/cluster-service: "true"
+ addonmanager.kubernetes.io/mode: Reconcile
+spec:
+ serviceName: elasticsearch-logging
+ replicas: 2
+ volumeClaimTemplates:
+ - metadata:
+ name: elasticsearch-logging
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ selector:
+ matchLabels:
+ k8s-app: elasticsearch-logging
+ version: v6.3.0
+ template:
+ metadata:
+ labels:
+ k8s-app: elasticsearch-logging
+ version: v6.3.0
+ kubernetes.io/cluster-service: "true"
+ spec:
+ serviceAccountName: elasticsearch-logging
+ containers:
+ - image: k8s.gcr.io/elasticsearch:v6.3.0
+ name: elasticsearch-logging
+ resources:
+ # need more cpu upon initialization, therefore burstable class
+ limits:
+ cpu: 1000m
+ requests:
+ cpu: 100m
+ ports:
+ - containerPort: 9200
+ name: db
+ protocol: TCP
+ - containerPort: 9300
+ name: transport
+ protocol: TCP
+ volumeMounts:
+ - name: elasticsearch-logging
+ mountPath: /data
+ env:
+ - name: "NAMESPACE"
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+
+ # Elasticsearch requires vm.max_map_count to be at least 262144.
+ # If your OS already sets up this number to a higher value, feel free
+ # to remove this init container.
+ initContainers:
+ - image: alpine:3.6
+ command: ["/sbin/sysctl", "-w", "vm.max_map_count=262144"]
+ name: elasticsearch-logging-init
+ securityContext:
+ privileged: true
diff --git a/clr-k8s-examples/3-efk/fluentd-es-configmap.yaml b/clr-k8s-examples/3-efk/fluentd-es-configmap.yaml
new file mode 100644
index 0000000..e383499
--- /dev/null
+++ b/clr-k8s-examples/3-efk/fluentd-es-configmap.yaml
@@ -0,0 +1,464 @@
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: fluentd-es-config-v0.1.6
+ namespace: kube-system
+ labels:
+ addonmanager.kubernetes.io/mode: Reconcile
+data:
+ system.conf: |-
+
+ root_dir /tmp/fluentd-buffers/
+
+
+ containers.input.conf: |-
+ # This configuration file for Fluentd / td-agent is used
+ # to watch changes to Docker log files. The kubelet creates symlinks that
+ # capture the pod name, namespace, container name & Docker container ID
+ # to the docker logs for pods in the /var/log/containers directory on the host.
+ # If running this fluentd configuration in a Docker container, the /var/log
+ # directory should be mounted in the container.
+ #
+ # These logs are then submitted to Elasticsearch which assumes the
+ # installation of the fluent-plugin-elasticsearch & the
+ # fluent-plugin-kubernetes_metadata_filter plugins.
+ # See https://github.com/uken/fluent-plugin-elasticsearch &
+ # https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter for
+ # more information about the plugins.
+ #
+ # Example
+ # =======
+ # A line in the Docker log file might look like this JSON:
+ #
+ # {"log":"2014/09/25 21:15:03 Got request with path wombat\n",
+ # "stream":"stderr",
+ # "time":"2014-09-25T21:15:03.499185026Z"}
+ #
+ # The time_format specification below makes sure we properly
+ # parse the time format produced by Docker. This will be
+ # submitted to Elasticsearch and should appear like:
+ # $ curl 'http://elasticsearch-logging:9200/_search?pretty'
+ # ...
+ # {
+ # "_index" : "logstash-2014.09.25",
+ # "_type" : "fluentd",
+ # "_id" : "VBrbor2QTuGpsQyTCdfzqA",
+ # "_score" : 1.0,
+ # "_source":{"log":"2014/09/25 22:45:50 Got request with path wombat\n",
+ # "stream":"stderr","tag":"docker.container.all",
+ # "@timestamp":"2014-09-25T22:45:50+00:00"}
+ # },
+ # ...
+ #
+ # The Kubernetes fluentd plugin is used to write the Kubernetes metadata to the log
+ # record & add labels to the log record if properly configured. This enables users
+ # to filter & search logs on any metadata.
+ # For example a Docker container's logs might be in the directory:
+ #
+ # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b
+ #
+ # and in the file:
+ #
+ # 997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
+ #
+ # where 997599971ee6... is the Docker ID of the running container.
+ # The Kubernetes kubelet makes a symbolic link to this file on the host machine
+ # in the /var/log/containers directory which includes the pod name and the Kubernetes
+ # container name:
+ #
+ # synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ # ->
+ # /var/lib/docker/containers/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b/997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b-json.log
+ #
+ # The /var/log directory on the host is mapped to the /var/log directory in the container
+ # running this instance of Fluentd and we end up collecting the file:
+ #
+ # /var/log/containers/synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ #
+ # This results in the tag:
+ #
+ # var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ #
+ # The Kubernetes fluentd plugin is used to extract the namespace, pod name & container name
+ # which are added to the log message as a kubernetes field object & the Docker container ID
+ # is also added under the docker field object.
+ # The final tag is:
+ #
+ # kubernetes.var.log.containers.synthetic-logger-0.25lps-pod_default_synth-lgr-997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b.log
+ #
+ # And the final log record look like:
+ #
+ # {
+ # "log":"2014/09/25 21:15:03 Got request with path wombat\n",
+ # "stream":"stderr",
+ # "time":"2014-09-25T21:15:03.499185026Z",
+ # "kubernetes": {
+ # "namespace": "default",
+ # "pod_name": "synthetic-logger-0.25lps-pod",
+ # "container_name": "synth-lgr"
+ # },
+ # "docker": {
+ # "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b"
+ # }
+ # }
+ #
+ # This makes it easier for users to search for logs by pod name or by
+ # the name of the Kubernetes container regardless of how many times the
+ # Kubernetes pod has been restarted (resulting in a several Docker container IDs).
+
+ # Json Log Example:
+ # {"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}
+ # CRI Log Example:
+ # 2016-02-17T00:04:05.931087621Z stdout F [info:2016-02-16T16:04:05.930-08:00] Some log text here
+
+ @id fluentd-containers.log
+ @type tail
+ path /var/log/containers/*.log
+ pos_file /var/log/es-containers.log.pos
+ tag raw.kubernetes.*
+ read_from_head true
+
+ @type multi_format
+
+ format json
+ time_key time
+ time_format %Y-%m-%dT%H:%M:%S.%NZ
+
+
+ format /^(?
+
+
+
+ # Detect exceptions in the log output and forward them as one log entry.
+
+ @id raw.kubernetes
+ @type detect_exceptions
+ remove_tag_prefix raw
+ message log
+ stream stream
+ multiline_flush_interval 5
+ max_bytes 500000
+ max_lines 1000
+
+
+ system.input.conf: |-
+ # Example:
+ # 2015-12-21 23:17:22,066 [salt.state ][INFO ] Completed state [net.ipv4.ip_forward] at time 23:17:22.066081
+
+ @id minion
+ @type tail
+ format /^(?
+
+ # Example:
+ # Dec 21 23:17:22 gke-foo-1-1-4b5cbd14-node-4eoj startupscript: Finished running startup script /var/run/google.startup.script
+
+ @id startupscript.log
+ @type tail
+ format syslog
+ path /var/log/startupscript.log
+ pos_file /var/log/es-startupscript.log.pos
+ tag startupscript
+
+
+ # Examples:
+ # time="2016-02-04T06:51:03.053580605Z" level=info msg="GET /containers/json"
+ # time="2016-02-04T07:53:57.505612354Z" level=error msg="HTTP Error" err="No such image: -f" statusCode=404
+ # TODO(random-liu): Remove this after cri container runtime rolls out.
+
+ @id docker.log
+ @type tail
+ format /^time="(?
+
+ # Example:
+ # 2016/02/04 06:52:38 filePurge: successfully removed file /var/etcd/data/member/wal/00000000000006d0-00000000010a23d1.wal
+
+ @id etcd.log
+ @type tail
+ # Not parsing this, because it doesn't have anything particularly useful to
+ # parse out of it (like severities).
+ format none
+ path /var/log/etcd.log
+ pos_file /var/log/es-etcd.log.pos
+ tag etcd
+
+
+ # Multi-line parsing is required for all the kube logs because very large log
+ # statements, such as those that include entire object bodies, get split into
+ # multiple lines by glog.
+
+ # Example:
+ # I0204 07:32:30.020537 3368 server.go:1048] POST /stats/container/: (13.972191ms) 200 [[Go-http-client/1.1] 10.244.1.3:40537]
+
+ @id kubelet.log
+ @type tail
+ format multiline
+ multiline_flush_interval 5s
+ format_firstline /^\w\d{4}/
+ format1 /^(?\w)(?