From 2469b11d65225effa6d1e6c05ac6a1e6806dfbea Mon Sep 17 00:00:00 2001 From: David Date: Mon, 25 Feb 2019 17:41:52 +0200 Subject: [PATCH 1/4] Altered the creation scripts for polaris --- README.md | 264 +----------------- charts/polaris/Chart.yaml | 6 +- charts/polaris/SOURCES.txt | 2 - .../charts/aws-service-operator/.helmignore | 21 -- .../charts/aws-service-operator/Chart.yaml | 5 - .../aws-service-operator/templates/NOTES.txt | 8 - .../templates/_helpers.tpl | 32 --- .../templates/clusterrole.yaml | 48 ---- .../templates/clusterrolebinding.yaml | 12 - .../templates/deployment.yaml | 29 -- .../templates/serviceaccount.yaml | 5 - .../charts/aws-service-operator/values.yaml | 0 .../charts/dex-k8s-authenticator/values.yaml | 100 +++++++ charts/polaris/charts/dex/values.yaml | 137 +++++++++ .../charts/kube-prometheus-0.0.105.tgz | Bin 51023 -> 0 bytes charts/polaris/values.yaml | 108 ++++--- charts/prometheus-operator-0.0.29.tgz | Bin 5106 -> 0 bytes create-cluster.sh | 94 +++++-- create-polaris.sh | 49 ++++ dex/README.md | 1 + dex/gen-dex-ca.sh | 38 --- environment | 15 + infrastructure/README.md | 1 + ingress/ingress.yaml | 33 +++ permissions/permissions_scaffold | 80 ++++++ run-cluster.sh | 12 + run-polaris.sh | 8 + 27 files changed, 591 insertions(+), 517 deletions(-) delete mode 100644 charts/polaris/charts/aws-service-operator/.helmignore delete mode 100644 charts/polaris/charts/aws-service-operator/Chart.yaml delete mode 100644 charts/polaris/charts/aws-service-operator/templates/NOTES.txt delete mode 100644 charts/polaris/charts/aws-service-operator/templates/_helpers.tpl delete mode 100644 charts/polaris/charts/aws-service-operator/templates/clusterrole.yaml delete mode 100644 charts/polaris/charts/aws-service-operator/templates/clusterrolebinding.yaml delete mode 100644 charts/polaris/charts/aws-service-operator/templates/deployment.yaml delete mode 100644 charts/polaris/charts/aws-service-operator/templates/serviceaccount.yaml delete mode 100644 charts/polaris/charts/aws-service-operator/values.yaml delete mode 100644 charts/polaris/charts/kube-prometheus-0.0.105.tgz delete mode 100644 charts/prometheus-operator-0.0.29.tgz create mode 100755 create-polaris.sh create mode 100644 dex/README.md delete mode 100755 dex/gen-dex-ca.sh create mode 100644 environment create mode 100644 infrastructure/README.md create mode 100644 ingress/ingress.yaml create mode 100644 permissions/permissions_scaffold create mode 100755 run-cluster.sh create mode 100755 run-polaris.sh diff --git a/README.md b/README.md index 61528d1..f82f5a1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ ______ ____ | | _____ _______|__| ______ # Overview -Polaris is an open-source, opiniated & validated architecture for hyper-scale enterprise clusters that allows for easy setup of a cluster with all the essentials ready for application development and deployment. The authors of Polaris believe that event-driven microservice architectures will eat the current legacy RESTful request/response world, and therefore a slant towards hyper-scale, streaming technology is evident in the Polaris design. +Polaris is an open-source, opiniated & validated architecture for hyper-scale enterprise clusters that allows for easy setup of a cluster with all the essentials ready for application development and deployment. The authors of Polaris believe that event-driven microservice architectures will eat the current legacy RESTful request/response world, and therefore a slant towards hyper-scale, streaming technology is evident in the Polaris design. Polaris has the following features: @@ -84,7 +84,7 @@ You can view the [kops aws docs](https://github.com/kubernetes/kops/blob/master/ ``` The Helm client can be installed either from source, or from pre-built binary releases. - + From Snap(Linux) $ sudo snap install helm --classic @@ -95,277 +95,41 @@ You can view the [kops aws docs](https://github.com/kubernetes/kops/blob/master/ $ choco install kubernetes-helm ``` -2. Generate the DEX Certificate Authority bits - -``` -$ dex/gen-dex-ca.sh -``` - -3. Create SSH key that will be used by the Kubernetes cluster +2. Run cluster script which creates your vanilla cluster it also generates yaml files in infrastructure/ ``` -$ ssh-keygen -t rsa -``` - -4. Create the cluster definition using kops - -``` -$ create-cluster.sh -``` - -5. Edit the cluster to CA cert, OIDC and additional policies: - -``` -$ kops edit cluster --state=s3://kops-state-bucket --name=example.cluster.k8s --yes - -Then add under spec: - fileAssets: - - name: dex-ca-cert - path: /srv/kubernetes/assets/dex-ca-cert.pem - roles: [Master] # a list of roles to apply the asset to, zero defaults to all - content: | - *<< CONTENTS OF /dex/ca/dex-ca-cert.pem >>* - kubeAPIServer: - oidcIssuerURL: *<< URL FOR DEX HERE (eg. https://dex.example.cluster.k8s) >>* - oidcClientID: kubectl-access - oidcUsernameClaim: email - oidcGroupsClaim: groups - oidcCAFile: /srv/kubernetes/assets/dex-ca-cert.pem - additionalPolicies: - node: | - [ - { - "Effect": "Allow", - "Action": [ - "route53:ListHostedZones", - "route53:ListResourceRecordSets" - ], - "Resource": [ - "*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "route53:ChangeResourceRecordSets" - ], - "Resource": [ - "arn:aws:route53:::hostedzone/*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "ec2:AttachVolume", - "ec2:DetachVolume" - ], - "Resource": [ - "*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "autoscaling:DescribeAutoScalingGroups", - "autoscaling:DescribeAutoScalingInstances", - "autoscaling:DescribeLaunchConfigurations", - "autoscaling:DescribeTags", - "autoscaling:SetDesiredCapacity", - "autoscaling:TerminateInstanceInAutoScalingGroup" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "codecommit:BatchGet*", - "codecommit:Get*", - "codecommit:Describe*", - "codecommit:List*", - "codecommit:GitPull" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "sqs:*", - "sns:*", - "cloudformation:*", - "ecr:*", - "dynamodb:*", - "s3:*" - ], - "Resource": "*" - } - ] -``` - -6. Edit polaris/values.yaml file to change the cluster name,region, etc. - -``` -Dex and Dex-k8s-authenticator: -- enables RBAC for kubectl accsess (logs user into their cluster), gets the CA - cert from s3 after the cluster has been created. - -Cluster-autoscaler: -- automatically adjusts the size of a Kubernetes Cluster so that all pods have a - place to run and there are no unneeded nodes. - -nginx-ingress: -- allows simple host or URL based HTTP routing. - -Flux: -- watches the changes on ECR and communicates updates to cluster to be - deployed - -polaris-prometheus-operator: - - Installs prometheus-operator (https://github.com/coreos/prometheusoperator) to create/configure/manage Prometheus clusters atop Kubernetes (i.e. - The Prometheus Operator for Kubernetes provides easy monitoring definitions - for Kubernetes services and deployment and management of Prometheus instances.) - -charts/polaris: - - installs the addons with the predefined configurations from the helm - packages located in the same directory and customized with all the values above +$ sudo ./run-cluster +Wait for cluster to come up it should have atleast one master node and one worker node in status READY also make sure all operators are READY ``` -7. Edit the node instance group to enable spot instances (Optional - for running cheap). - -``` -$ kops edit ig nodes --state=s3://kops-state-bucket --name=example.cluster.k8s +3. Run polaris script which install polaris operators on your cluster -Then add under spec: - maxPrice: "0.10" - minSize: 1 - maxSize: 6 ``` - -8. Create the cluster. - +$ sudo ./run-polaris ``` -Test run: -$ kops update cluster --state=s3://kops-state-bucket --name=example.cluster.k8s -Apply changes: -$ kops update cluster --state=s3://kops-state-bucket --name=example.cluster.k8s --yes +4. Install polaris-kafka -... wait for cluster to come up ... -$ watch -d 'kubectl get nodes -o wide; kubectl get pods --all-namespaces' ``` +$ helm --name polaris-kafka-cp-kafka --namespace app install polaris-kafka/ -9. Create Polaris Namespace and Install ServiceAccounts, helm and charts. - +Deploy other containers to this namespace to interact with Kafka topics ``` -$ kubectl create namespace polaris - -$ kubectl apply -f k8/serviceaccounts/tiller-serviceaccount.yaml - -$ helm init --service-account helm-tiller --upgrade --debug --wait -$ helm upgrade --namespace polaris --install polaris-prometheus-operator charts/prometheus-operator-0.0.29.tgz +5. Cleanup -$ helm upgrade --namespace polaris --install polaris charts/polaris ``` -10. Setup DEX - -``` -Install the dex certificates: - - - -$ kubectl create configmap dex-ca --namespace polaris --from-file dex-ca.pem=dex/ca/dex-ca-cert.pem - -$ kubectl create secret tls dex-ca --namespace polaris --cert=dex/ca/dex-ca-cert.pem --key=dex/ca/dex-ca-key.pem - -$ kubectl create secret tls dex-tls --namespace polaris --cert=dex/ca/dex-issuer-cert.pem --key=dex/ca/dex-issuer-key.pem - -Hit dex on https://dex.example.cluster.k8s/.well-known/openid-configuration and ensure you get the dex-kube-issuer cert. - -Modify charts/dex-k8s-authenticator/values.yaml and ensure: -1. CA certificate link is set to public in S3 -2. CA certificate contents exists in cacerts section (as base64 encoded value) - -Install a clusterrole for the admin@example.com administrator: - -$ kubectl apply --namespace polaris -f k8/serviceaccounts/admin@example.com.yaml -``` - -11. Login and get a kubectl token: - -``` -https://login.example.cluster.k8s - -Load up the kube-config as directed (maybe take a backup of existing!) -``` - -12. Setup Flux for CD - -``` -Create a code-commit repo in AWS (manually for now...) - e.g. kubernetes-example-cluster. - -Create an IAM user in AWS (manually for now...) - e.g. flux-example-user. - -Create an HTTPS Git credentials for AWS CodeCommit for that IAM user, and note the -username and password. - -Edit charts/flux/values.yaml and ensure you setup the following: -git.url to have the correct username and password, VERY IMPORTANT that the password is URLEncoded! Otherwise you will get weird errors from flux. - -$ kubectl create namespace devops - -$ helm upgrade --namespace devops --install flux k8/charts/flux - -Watch flux log itself connecting and syncing the repository. - -You should now be able to: - -$ fluxctl --k8s-fwd-ns polaris list-controllers - -$ fluxctl --k8s-fwd-ns polaris list-images - -Any specs you put in /cluster-repo and push will be applied to the cluster. - -Charts must be in /cluster-repo/charts and a corresponding release/blah.yaml containing -a FluxHelmRelease for it would also be applied. - -Cool watch to see stuff happening: - -$ watch -d 'fluxctl --k8s-fwd-ns polaris -n example list-controllers; fluxctl --k8s-fwd-ns polaris -n example list-images -c example:deployment/example-example' - -Then to setup example as an automated deployment: - -$ fluxctl --k8s-fwd-ns polaris -n example automate -c example:fluxhelmrelease/example -``` - -13. Upgrade Cilium to newer version (to avoid a crash when applying CiliumNetworkPolicies): - -``` -$ kubectl edit deployment daemonset cilium -n kube-system - -Change from: - image: cilium/cilium:v1.0-stable -to: - image: cilium/cilium:v1.2 - -Then delete every cilium pod (and have it restart). -``` - -14. Install aws-service-operator (early beta, but cool for creating ECRs) - -``` -Edit values and make sure you have sane values: - -$ helm install --name=aws-service-operator k8/charts/aws-service-operator +$ kops delete cluster kops delete cluster example.cluster.k8s --state s3://{bucket_name} --yes -Test that it's working by pushing an ECRRepository into the flux pipe or manually applying it - then login to AWS and list. +Also remove files from dex folder and revert all changes in git to start again. ``` ## Other administrative stuff - Shell access to the cluster (using creators id_rsa): ``` -$ ssh -i ~/.ssh/id_rsa admin@api.example.cluster.k8s +$ ssh -i ~/.ssh/polaris@api.example.cluster.k8s ``` ## Related Polaris Projects diff --git a/charts/polaris/Chart.yaml b/charts/polaris/Chart.yaml index 7b5cacd..33326d5 100644 --- a/charts/polaris/Chart.yaml +++ b/charts/polaris/Chart.yaml @@ -1,7 +1,5 @@ apiVersion: v1 -name: Polaris appVersion: "1.0" -description: Polaris is an open-source, opinionated & validated architecture for hyper-scale AI first enterprise clusters. -sources: - - https://github.com/synthesis-labs/polaris +description: Polaris by Synthesis +name: polaris version: 1.0.0 diff --git a/charts/polaris/SOURCES.txt b/charts/polaris/SOURCES.txt index 5da3a17..a0c61dc 100644 --- a/charts/polaris/SOURCES.txt +++ b/charts/polaris/SOURCES.txt @@ -10,7 +10,5 @@ stable/external-dns stable/cluster-autoscaler stable/nginx-ingress stable/metrics-server -coreos/kube-prometheus -coreos/prometheus-operator stable/dex weaveworks/flux diff --git a/charts/polaris/charts/aws-service-operator/.helmignore b/charts/polaris/charts/aws-service-operator/.helmignore deleted file mode 100644 index f0c1319..0000000 --- a/charts/polaris/charts/aws-service-operator/.helmignore +++ /dev/null @@ -1,21 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*~ -# Various IDEs -.project -.idea/ -*.tmproj diff --git a/charts/polaris/charts/aws-service-operator/Chart.yaml b/charts/polaris/charts/aws-service-operator/Chart.yaml deleted file mode 100644 index 72df9a6..0000000 --- a/charts/polaris/charts/aws-service-operator/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -appVersion: "1.0" -description: A Helm chart for provisioning AWS resources using Kubernetes Custom Resources Definitions -name: aws-service-operator -version: 0.1.0 diff --git a/charts/polaris/charts/aws-service-operator/templates/NOTES.txt b/charts/polaris/charts/aws-service-operator/templates/NOTES.txt deleted file mode 100644 index 83b21de..0000000 --- a/charts/polaris/charts/aws-service-operator/templates/NOTES.txt +++ /dev/null @@ -1,8 +0,0 @@ -Helm chart to manage AWS resources using Kubernetes Custom Resource Definitions. - -Example: Creating a CRD that will create a new ECR repository named example-repository: - -apiVersion: service-operator.aws/v1alpha1 -kind: ECRRepository -metadata: - name: example-repository diff --git a/charts/polaris/charts/aws-service-operator/templates/_helpers.tpl b/charts/polaris/charts/aws-service-operator/templates/_helpers.tpl deleted file mode 100644 index 35f3f17..0000000 --- a/charts/polaris/charts/aws-service-operator/templates/_helpers.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "aws-service-operator.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "aws-service-operator.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "aws-service-operator.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/charts/polaris/charts/aws-service-operator/templates/clusterrole.yaml b/charts/polaris/charts/aws-service-operator/templates/clusterrole.yaml deleted file mode 100644 index a2c17fb..0000000 --- a/charts/polaris/charts/aws-service-operator/templates/clusterrole.yaml +++ /dev/null @@ -1,48 +0,0 @@ -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: aws-service-operator -rules: -- apiGroups: - - "" - resources: - - secrets - - pods - - configmaps - - services - - events - verbs: - - get - - list - - watch - - create - - delete - - update - - patch -- apiGroups: - - extensions - resources: - - thirdpartyresources - verbs: - - get - - list - - watch - - create - - delete - - update -- apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - service-operator.aws - resources: - - "*" - verbs: - - "*" diff --git a/charts/polaris/charts/aws-service-operator/templates/clusterrolebinding.yaml b/charts/polaris/charts/aws-service-operator/templates/clusterrolebinding.yaml deleted file mode 100644 index 4f29809..0000000 --- a/charts/polaris/charts/aws-service-operator/templates/clusterrolebinding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1beta1 -metadata: - name: aws-service-operator -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: aws-service-operator -subjects: -- kind: ServiceAccount - name: aws-service-operator - namespace: {{ .Release.Namespace }} diff --git a/charts/polaris/charts/aws-service-operator/templates/deployment.yaml b/charts/polaris/charts/aws-service-operator/templates/deployment.yaml deleted file mode 100644 index 823c13e..0000000 --- a/charts/polaris/charts/aws-service-operator/templates/deployment.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: {{ include "aws-service-operator.fullname" . }} - labels: - app: {{ include "aws-service-operator.name" . }} - chart: {{ include "aws-service-operator.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - replicas: {{ .Values.replicaCount }} - template: - metadata: - annotations: - iam.amazonaws.com/role: "arn:aws:iam::{{ .Values.operator.account }}:role/aws-service-operator" - labels: - app: {{ include "aws-service-operator.name" . }} - release: {{ .Release.Name }} - spec: - serviceAccountName: aws-service-operator - containers: - - name: aws-service-operator - image: awsserviceoperator/aws-service-operator:v0.0.1-alpha2 - imagePullPolicy: Always - args: - - server - - --cluster-name={{ .Values.operator.cluster }} - - --region={{ .Values.operator.region }} - - --account-id={{ .Values.operator.account }} diff --git a/charts/polaris/charts/aws-service-operator/templates/serviceaccount.yaml b/charts/polaris/charts/aws-service-operator/templates/serviceaccount.yaml deleted file mode 100644 index 7373d9f..0000000 --- a/charts/polaris/charts/aws-service-operator/templates/serviceaccount.yaml +++ /dev/null @@ -1,5 +0,0 @@ -kind: ServiceAccount -apiVersion: v1 -metadata: - name: aws-service-operator - #namespace: aws-service-operator diff --git a/charts/polaris/charts/aws-service-operator/values.yaml b/charts/polaris/charts/aws-service-operator/values.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/charts/polaris/charts/dex-k8s-authenticator/values.yaml b/charts/polaris/charts/dex-k8s-authenticator/values.yaml index e69de29..03b6571 100644 --- a/charts/polaris/charts/dex-k8s-authenticator/values.yaml +++ b/charts/polaris/charts/dex-k8s-authenticator/values.yaml @@ -0,0 +1,100 @@ +# Default values for dex-k8s-authenticator. + +# Deploy environment label, e.g. dev, test, prod +global: + deployEnv: dev + +replicaCount: 1 + +image: + repository: mintel/dex-k8s-authenticator + tag: latest + pullPolicy: Always + +dexK8sAuthenticator: + port: 5555 + debug: false + web_path_prefix: / + #logoUrl: http:// + #tlsCert: /path/to/dex-client.crt + #tlsKey: /path/to/dex-client.key + clusters: + - name: <> + short_description: "Ref4 Cluster" + description: "Reference number 4" + client_secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B + issuer: https://dex.<> + k8s_master_uri: https://api.<> + client_id: kubectl-access + redirect_uri: https://login.<>/callback/<> + # + # Make this particular link public in s3: + k8s_ca_uri: + <> + +service: + type: ClusterIP + port: 5555 + + # For nodeport, specify the following: + # type: NodePort + # nodePort: + +ingress: + enabled: true + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - login.<> + tls: + - hosts: + - login.<> + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +caCerts: + enabled: true + secrets: + # Array of Self Signed Certificates + # cat CA.crt | base64 -w 0 + # + # name: The internal k8s name of the secret we create. It's also used in + # the volumeMount name. It must respect the k8s naming convension (avoid + # upper-case and '.' to be safe). + # + # filename: The filename of the CA to be mounted. It must end in .crt for + # update-ca-certificates to work + # + # value: The base64 encoded value of the CA + # + #secrets: + #- name: ca-cert1 + # filename: ca1.crt + # value: LS0tLS1......X2F + #- name: ca-cert2 + # filename: ca2.crt + # value: DS1tFA1......X2F + # + # Get this value by: cat k8/dex/ca/dex-ca-cert.pem | base64 + - name: ca1 + filename: ca1.crt + value: + <> + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/polaris/charts/dex/values.yaml b/charts/polaris/charts/dex/values.yaml index e69de29..593d74b 100644 --- a/charts/polaris/charts/dex/values.yaml +++ b/charts/polaris/charts/dex/values.yaml @@ -0,0 +1,137 @@ +# Default values for dex +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name: value + +image: quay.io/dexidp/dex +imageTag: "v2.11.0" +imagePullPolicy: "IfNotPresent" + +inMiniKube: false + +nodeSelector: {} + +replicas: 1 + +# TBD - make this an ingress rather +service: + type: ClusterIP + port: 443 +# annotations: +# external-dns.alpha.kubernetes.io/hostname: dex.<> + # externalIPs: + +# Added these to create the ingress with correct hostname +# and class to match ingress-controller +ingress: + host: dex.<> + class: nginx + +resources: + # Normal resource usage of dex server + # limits: + # cpu: 100m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 50Mi + +extraVolumes: [] +extraVolumeMounts: [] + +selfSigned: + create: false + #image: gcr.io/google_containers/kubernetes-dashboard-init-amd64 + #imageTag: "v1.0.0" + #imagePullPolicy: "IfNotPresent" + #caDays: 10000 + #certDays: 10000 + #altNames: + #- dex.minikube.local + #altIPs: {} + #- 192.168.42.219 + +secret: {} +# Override the default secret names here. +# tlsName: dex-tls +# caName: dex-ca + +env: [] + +rbac: + # Specifies whether RBAC resources should be created + create: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + +config: + issuer: https://dex.<> + storage: + type: kubernetes + config: + inCluster: true + logger: + level: debug + web: + https: 0.0.0.0:5556 + tlsCert: /etc/dex/tls/tls.crt + tlsKey: /etc/dex/tls/tls.key + connectors: +# - type: github +# id: github +# name: GitHub +# config: +# clientID: xxxxxxxxxxxxxxx +# clientSecret: yyyyyyyyyyyyyyyyyyyyy +# redirectURI: https://dex.minikube.local:5556/callback +# org: kubernetes + - type: microsoft + id: microsoft + # Required field for connector name. + name: Microsoft + config: + # Credentials can be string literals or pulled from the environment. + clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df + clientSecret: lmwcHDOCUH74+zgbA152:]! + redirectURI: https://dex.<>/callback + # tenant: organizations + # + # Also - edit the application manifest (in MS Apps) and + # edit to include the valid reply urls: + # "replyUrls": [ + # "https://dex.<>/callback" + #] + # + # Then - need to approve the access using something like this: + # + # https://login.microsoftonline.com/94cfdb85-3d23-4849-a066-5cdad965ccd8/adminconsent?client_id=33d82f8b-4db4-4d99-b610-0768ddd246df + + + oauth2: + skipApprovalScreen: true + + staticClients: + - id: kubectl-access + redirectURIs: + - 'http://127.0.0.1:5555/callback' + - 'https://login.<>/callback/<>' + name: 'Kubectl Access' + secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B + + enablePasswordDB: true + staticPasswords: + - email: "admin@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "admin" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" + - email: "retail@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "retail" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5467" diff --git a/charts/polaris/charts/kube-prometheus-0.0.105.tgz b/charts/polaris/charts/kube-prometheus-0.0.105.tgz deleted file mode 100644 index 9b0285ec17fecf5eff041250c72bd7c96c10df83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51023 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 ImjJ*B0O#{|a{vGU diff --git a/charts/polaris/values.yaml b/charts/polaris/values.yaml index b5e86a1..5044e31 100644 --- a/charts/polaris/values.yaml +++ b/charts/polaris/values.yaml @@ -1,11 +1,10 @@ - global: - cluster-name: example.cluster.k8s + cluster-name: frodo.synthesis.rocks aws-service-operator: operator: - account: "123412341234" - cluster: example # Can't contain any weird characters! + account: "931486170612" + cluster: polaris # Can't contain any weird characters! region: eu-west-1 external-dns: @@ -22,7 +21,7 @@ cluster-autoscaler: cloudProvider: aws awsRegion: eu-west-1 autoscalingGroups: - - name: nodes.example.cluster.k8s + - name: nodes.frodo.synthesis.rocks minSize: 1 maxSize: 6 @@ -34,20 +33,18 @@ nginx-ingress: enabled: true extraArgs: enable-ssl-passthrough: true - proxy-read-timeout: "3600" - proxy-send-timeout: "3600" flux: helmOperator: create: true git: - chartsPath: "example/cluster-repo/charts" + chartsPath: "ref4/cluster-repo/charts" git: - url: "" # url for git repo + url: "git@github.com:davidwebstar34/ExampleFluxRepo.git" branch: "master" - path: "example/cluster-repo/" # directories to watch - user: "Flux on Example" - email: "flux@example.com" + path: "ref4/cluster-repo/" + user: "polaris" + email: "davidw4@synthesis.co.za" setAuthor: true pollInterval: "1m" registry: @@ -58,29 +55,47 @@ dex: tlsName: dex-tls caName: dex-ca ingress: - host: dex.example.cluster.k8s + host: dex.frodo.synthesis.rocks config: - issuer: https://dex.example.cluster.k8s - connectors: [] - staticClients: - - id: kubectl-access - redirectURIs: - - 'http://127.0.0.1:5555/callback' - - 'https://login.example.cluster.k8s/callback/example.cluster.k8s' - name: 'Kubectl Access' - secret: "" # set this and match it with dexK8sAuthenticator.clusters[0].client_secret - enablePasswordDB: true - staticPasswords: - - email: "admin@example.com" - # bcrypt hash of the string "password" - hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" - username: "admin" - userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" - - email: "retail@example.com" - # bcrypt hash of the string "password" - hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" - username: "retail" - userID: "08a8684b-db88-4b73-90a9-3cd1661f5467" + issuer: https://dex.frodo.synthesis.rocks + connectors: + - type: microsoft + id: microsoft + name: Microsoft + config: + clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df + clientSecret: lmwcHDOCUH74+zgbA152:]! + redirectURI: https://dex.frodo.synthesis.rocks/callback + # tenant: organizations + # + # Also - edit the application manifest (in MS Apps) and + # edit to include the valid reply urls: + # "replyUrls": [ + # "https://dex.ref4.onlabs.cloud/callback" + #] + # + # Then - need to approve the access using something like this: + # + # https://login.microsoftonline.com/94cfdb85-3d23-4849-a066-5cdad965ccd8/adminconsent?client_id=33d82f8b-4db4-4d99-b610-0768ddd246df + staticClients: + - id: kubectl-access + redirectURIs: + - 'http://127.0.0.1:5555/callback' + - 'https://login.frodo.synthesis.rocks/callback/frodo.synthesis.rocks' + name: 'Kubectl Access' + secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B + enablePasswordDB: true + staticPasswords: + - email: "admin@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "admin" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" + - email: "retail@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "retail" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5467" dex-k8s-authenticator: dexK8sAuthenticator: @@ -88,25 +103,26 @@ dex-k8s-authenticator: debug: false web_path_prefix: / clusters: - - name: example.cluster.k8s - short_description: "example Cluster" - description: "Example cluster" - client_secret: "" - issuer: https://dex.example.cluster.k8s - k8s_master_uri: https://api.example.cluster.k8s + - name: frodo.synthesis.rocks + short_description: "Ref4 Cluster" + description: "Reference number 4" + client_secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B + issuer: https://dex.frodo.synthesis.rocks + k8s_master_uri: https://api.frodo.synthesis.rocks client_id: kubectl-access - redirect_uri: https://login.example.cluster.k8s/callback/example.cluster.k8s + redirect_uri: https://login.frodo.synthesis.rocks/callback/frodo.synthesis.rocks # # Make this particular link public in s3: k8s_ca_uri: - https://s3.eu-west-1.amazonaws.com/kops-state-bucket/example.cluster.k8s/pki/issued/ca/123412341234.crt # url to CA cert on s3 + https://s3-eu-west-1.amazonaws.com/kops-mimic/frodo.synthesis.rocks/pki/issued/ca/6661957841380198014448874128.crt caCerts: enabled: true secrets: - # Get this value by: cat dex/ca/dex-ca-cert.pem | base64 [-w 0] + # Get this value by: cat k8/dex/ca/dex-ca-cert.pem | base64 [-w 0] - name: ca1 filename: ca1.crt - value: "" + value: + LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRRDBvK0l3S0pmNXlEQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdGsKWlhndGEzVmlaUzFqWVRBZUZ3MHhPVEF5TWpVeE5URTRNamxhRncwME5qQTNNVEl4TlRFNE1qbGFNQll4RkRBUwpCZ05WQkFNTUMyUmxlQzFyZFdKbExXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFybDhaNGZQV0o2LzZaT1MxTFJ4eHpIWThmVnR3RXdVU3lqVXVURzkvT05RWWZCOHdNSkpGSmR2YWhVRnMKQjdubVU4KzYxd1RyYk1tYW5BK2Yxdy9jbjNZL1dlaHdCYWl5U0NERGpmL0pkUlpnVFMwdk5vaEJYNWYvUk5IRQpnVTlhYTIxQzJmdDFVTWpCWFMvMmdhM3ArZUh6WVNSQ0RNYm5seUhsenhNOFZyc0hXaHRINFN5a0RzTWRaY0gzClpWV3psaFBqYXU2cDRrWDgzaVRoNXBwV1ZHMnBwTDFFaTdKYm1ucTJUdEZLYmVubVllbWprKzYyWlN1WmtKSEoKcDlCakp2VVEvVG9STTcwN294Vmc3MzF0T2ZKR0NtSEpPN3NYU2J6ZkhwVm4rWWcrR2tBWTBlbHBMS3djeW1JVApobjg4Zkt2YkFpb2pEZzdwbkZsb2Z2dUVuUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ0sxR0tuCmdJY1dsRGlkR3VVcmVXb2ZjdjBqVHd6UENzU09NSVg4amRDbUlCUG5TM2hNVUF0QThZNFA4bVdqVG9wRCtSdHYKbmlWaUk1eVd0RDdRMnJOSjJ5VnZncmFGSkpjSVI5a241N1BSKzZiK3VWclUrblhpcE9Rb3hjUENBb1BZK09kbwp3RFJNbURic3IyU3Q1WlpTT2U3c0NQYmRESXlaS1RXVW5zSlJyVEMwS3h6eUZmc1dDL2ZDYkhJTkVBc09Ic1JFClJZTUdUdmRrTHQ3YkFqa0dSbTVFRmFidC9uUTl3bHhaU1JZL2ZBMTgzZjVJSzRJVndwZVJoZTBLL0lHOVBqNHIKSzR1cDhsd2pUOHZkREUyb00zV0piSmRvWEtXNmFDYjh5R2Q3WitGUGJQbGFxMWVITmlZL0RBcEdQV2tPaG53NQo2MDE4THFKQ016U1hvM2RvCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K ingress: enabled: true annotations: {} @@ -114,7 +130,7 @@ dex-k8s-authenticator: # kubernetes.io/tls-acme: "true" path: / hosts: - - login.example.cluster.k8s + - login.frodo.synthesis.rocks tls: - hosts: - - login.example.cluster.k8s + - login.frodo.synthesis.rocks diff --git a/charts/prometheus-operator-0.0.29.tgz b/charts/prometheus-operator-0.0.29.tgz deleted file mode 100644 index 81c3875294f919683c63cdec1916c2333f283744..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5106 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 U{29vs2LJ&7{}BaECjfo`0PxQ9#Q*>R diff --git a/create-cluster.sh b/create-cluster.sh index 22ae9d9..f827014 100755 --- a/create-cluster.sh +++ b/create-cluster.sh @@ -1,18 +1,17 @@ +#!/bin/bash +# A Simple Shell Script To Create a Polaris Cluster +# David Webstar - 16/02/2019 +export KUBECONFIG=/root/.kube/config +export AWS_REGION=${REGION} +export AWS_DEFAULT_REGION=${REGION} +export KOPS_STATE_STORE=s3://${STATE_BUCKET} +echo 'AWS_REGION: ' ${AWS_REGION} +echo 'KOPS_STATE_STORE: ' ${KOPS_STATE_STORE} -CLUSTER_NAME=example.cluster.k8s # name of the cluster -STATE_BUCKET="" # name of s3 bucket where the state of the cluster will live -REGION=eu-west-1 -AVAILABILITY_ZONES=${REGION}a,${REGION}b,${REGION}c # select AZ's - depending on the region but some may only have 2 -KUBERNETES_VERSION=1.10.5 -MASTER_ZONES=${REGION}b -CLUSTER_CIDR=10.0.0.0/20 - -# Newer kernel version for cilium support -IMAGE=595879546273/CoreOS-stable-1855.4.0-hvm - -MASTER_COUNT=1 -NODE_COUNT=3 +ssh-keygen -q -t rsa -f /root/.ssh/polaris -N '' +echo 'Generating polaris ssh key' +echo 'Creating vanilla cluster' # To allow overriding of etcd version (to v3) for cilium KOPS_FEATURE_FLAGS=SpecOverrideFlag \ kops create cluster \ @@ -20,7 +19,7 @@ kops create cluster \ --override=cluster.spec.etcdClusters[*].version=3.1.11 `# Specify etcd3 version (instead of etcd v2)` \ --state s3://${STATE_BUCKET} `# Name of bucket to store state` \ `#--dry-run # Dont actually do it` \ - `#--output yaml # Output of dry-run [yaml | json]` \ + `#--output yaml # Output of dry-run [yaml | json]` \ `#--out # Stdout redirect` \ `#--target # direct, terraform, cloudformation` \ `#--yes # Specify --yes to immediately create the cluster` \ @@ -48,15 +47,76 @@ kops create cluster \ --networking cilium `# kubenet, classic, external, kopeio-vxlan, kopeio), weave, flannel-vxlan, flannel, flannel-udp, calico, canal, kube-router, romana, amazon-vpc-routed-eni, cilium` \ --node-count ${NODE_COUNT} `# Number of worker nodes` \ `#--node-security-groups # Existing SGs to apply to nodes` \ - --node-size c4.xlarge `# Node instance type` \ + --node-size m4.large `# Node instance type` \ `#--node-tenancy default # [default | dedicated]` \ --node-volume-size 30 `# Node volume size in GB` \ `#--project # Project to use (must be set on GCE)` \ `#--ssh-access # Restrict SSH access to this CIDR. If not set, access will not be restricted by IP. (default [0.0.0.0/0])` \ - `#--ssh-public-key # SSH public key to use (default "~/.ssh/id_rsa.pub")` \ + --ssh-public-key ~/.ssh/polaris.pub `# SSH public key to use (default "~/.ssh/id_rsa.pub")` \ `#--subnets # Set to use shared subnets` \ --topology private `# [public | private]` \ `#--utility-subnets # Set to use shared utility subnets` \ - `#--vpc # Set to use a shared VPC` \ + `#--vpc vpc-07d5a9727cf0103d7 # Set to use a shared VPC` \ --zones ${AVAILABILITY_ZONES} `# Zones in which to run the cluster (nodes?)` \ $1 $2 $3 $4 $5 $6 $7 $8 $9 + + +kops get --name ${CLUSTER_NAME} --state=s3://kops-mimic -o yaml > infrastructure/vanilla_cluster.yaml + +ROOT=$( dirname "${BASH_SOURCE[0]}" ) +FOLDER=$ROOT/dex/ca + +echo Will create CA in $FOLDER + +mkdir -p $FOLDER +cd $FOLDER + +cat << EOF > req.cnf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name + +[req_distinguished_name] + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = dex.${CLUSTER_NAME} +EOF + +# CA Private and Self-signed Certificate +# +openssl genrsa -out dex-ca-key.pem 2048 +openssl req -x509 -new -nodes -key dex-ca-key.pem -days 9999 -out dex-ca-cert.pem -subj "/CN=dex-kube-ca" + +# Issuer private key and signed by CA +# +openssl genrsa -out dex-issuer-key.pem 2048 +openssl req -new -key dex-issuer-key.pem -out dex-issuer-csr.pem -subj "/CN=dex-kube-issuer" -config req.cnf +openssl x509 -req -in dex-issuer-csr.pem -CA dex-ca-cert.pem -CAkey dex-ca-key.pem -CAcreateserial -out dex-issuer-cert.pem -days 9999 -extensions v3_req -extfile req.cnf + +cd - + + +DEX='https:\/\/dex.'${CLUSTER_NAME} + +sed 's/^/ /' dex/ca/dex-ca-cert.pem > dex/ca/temp.txt +sed -i -e '/<>/{r dex/ca/temp.txt' -e 'd' -e '}' permissions/permissions_scaffold +sed -i 's/<>/'${DEX}'/g' permissions/permissions_scaffold + +cat infrastructure/vanilla_cluster.yaml | awk ' +/api:/ { + line = $0; + while ((getline < "permissions/permissions_scaffold") > 0) {print}; + print line; + next +} +{print}' > infrastructure/dex_cluster.yaml + +kops replace -f infrastructure/dex_cluster.yaml --state ${KOPS_STATE_STORE} +kops update cluster ${CLUSTER_NAME} --state ${KOPS_STATE_STORE} --yes + +watch -d 'kubectl get nodes -o wide; kubectl get pods --all-namespaces' diff --git a/create-polaris.sh b/create-polaris.sh new file mode 100755 index 0000000..0b51fe9 --- /dev/null +++ b/create-polaris.sh @@ -0,0 +1,49 @@ +#!/bin/bash +export KUBECONFIG=/root/.kube/config +export AWS_REGION=${REGION} +export AWS_DEFAULT_REGION=${REGION} +export KOPS_STATE_STORE=s3://${STATE_BUCKET} +echo 'AWS_REGION: ' ${AWS_REGION} +echo 'KOPS_STATE_STORE: ' ${KOPS_STATE_STORE} + +# helm --tiller-connection-timeout 900 + +echo 'Getting certificate name from AWS' +TEMP_CRT_NAME=$(aws s3 ls ${KOPS_STATE_STORE}/${CLUSTER_NAME}/pki/issued/ca/ --recursive | awk '{print $4}' | grep -o [0-9]*.crt) +echo 'Certificate: '$TEMP_CRT_NAME +echo 'Making certificate public' +aws s3api put-object-acl --bucket kops-mimic --key ${CLUSTER_NAME}'/pki/issued/ca/'${TEMP_CRT_NAME} --acl public-read + + +TEMP_CRT_CREDS=$(cat dex/ca/dex-ca-cert.pem | base64 -w 0) +TEMP_CRT_NAME_ESCAPED=$(echo $TEMP_CRT_NAME | sed 's/\//\\\//g') + +sed -i 's/<>/'${CLUSTER_NAME}'/g' charts/polaris/values.yaml +sed -i 's/<>/'${TEMP_CRT_CREDS}'/g' charts/polaris/values.yaml +sed -i 's/<>/https:\/\/s3-eu-west-1.amazonaws.com\/'${STATE_BUCKET}'\/'${CLUSTER_NAME}'\/pki\/issued\/ca\/'${TEMP_CRT_NAME_ESCAPED}'/g' charts/polaris/values.yaml + +sed -i 's/<>/'${CLUSTER_NAME}'/g' charts/polaris/charts/dex/values.yaml +sed -i 's/<>/'${TEMP_CRT_CREDS}'/g' charts/polaris/charts/dex/values.yaml +sed -i 's/<>/https:\/\/s3-eu-west-1.amazonaws.com\/'${STATE_BUCKET}'\/'${CLUSTER_NAME}'\/pki\/issued\/ca\/'${TEMP_CRT_NAME_ESCAPED}'/g' charts/polaris/charts/dex/values.yaml + +sed -i 's/<>/'${CLUSTER_NAME}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml +sed -i 's/<>/'${TEMP_CRT_CREDS}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml +sed -i 's/<>/https:\/\/s3-eu-west-1.amazonaws.com\/'${STATE_BUCKET}'\/'${CLUSTER_NAME}'\/pki\/issued\/ca\/'${TEMP_CRT_NAME_ESCAPED}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml + +sed -i 's/<>/'${CLUSTER_NAME}'/g' ingress/ingress.yaml +sed -i 's/<>/'${CLUSTER_NAME}'/g' ingress/ingress.yaml + +kubectl create namespace polaris +kubectl apply -f serviceaccounts/tiller-serviceaccount.yaml +helm init --service-account helm-tiller --upgrade --debug --wait + +echo 'Installing helm charts this may take a few minutes' +helm upgrade --namespace polaris --install polaris charts/polaris + +kubectl create configmap dex-ca --namespace polaris --from-file dex-ca.pem=dex/ca/dex-ca-cert.pem +kubectl create secret tls dex-ca --namespace polaris --cert=dex/ca/dex-ca-cert.pem --key=dex/ca/dex-ca-key.pem +kubectl create secret tls dex-tls --namespace polaris --cert=dex/ca/dex-issuer-cert.pem --key=dex/ca/dex-issuer-key.pem + +kubectl apply -f ingress/ingress.yaml + +helm upgrade --namespace polaris --install polaris-prometheus-operator stable/prometheus-operator diff --git a/dex/README.md b/dex/README.md new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/dex/README.md @@ -0,0 +1 @@ + diff --git a/dex/gen-dex-ca.sh b/dex/gen-dex-ca.sh deleted file mode 100755 index 782d7ae..0000000 --- a/dex/gen-dex-ca.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -ROOT=$( dirname "${BASH_SOURCE[0]}" ) -FOLDER=$ROOT/ca - -echo Will create CA in $FOLDER - -mkdir -p $FOLDER -cd $FOLDER - -cat << EOF > req.cnf -[req] -req_extensions = v3_req -distinguished_name = req_distinguished_name - -[req_distinguished_name] - -[ v3_req ] -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment -subjectAltName = @alt_names - -[alt_names] -DNS.1 = dex.example.cluster.k8s -EOF - -# CA Private and Self-signed Certificate -# -openssl genrsa -out dex-ca-key.pem 2048 -openssl req -x509 -new -nodes -key dex-ca-key.pem -days 9999 -out dex-ca-cert.pem -subj "/CN=dex-kube-ca" - -# Issuer private key and signed by CA -# -openssl genrsa -out dex-issuer-key.pem 2048 -openssl req -new -key dex-issuer-key.pem -out dex-issuer-csr.pem -subj "/CN=dex-kube-issuer" -config req.cnf -openssl x509 -req -in dex-issuer-csr.pem -CA dex-ca-cert.pem -CAkey dex-ca-key.pem -CAcreateserial -out dex-issuer-cert.pem -days 9999 -extensions v3_req -extfile req.cnf - -cd - diff --git a/environment b/environment new file mode 100644 index 0000000..dd03426 --- /dev/null +++ b/environment @@ -0,0 +1,15 @@ +CLUSTER_NAME=example.cluster.k8s +STATE_BUCKET=ENTER_BUCKET_NAME_HERE + +REGION=eu-west-1 +AVAILABILITY_ZONES=eu-west-1a +KUBERNETES_VERSION=1.10.5 + +MASTER_ZONES=eu-west-1a +CLUSTER_CIDR=10.192.0.0/16 +MASTER_COUNT=1 +NODE_COUNT=1 + +AWS_PROFILE=default + +IMAGE=595879546273/CoreOS-stable-1855.4.0-hvm diff --git a/infrastructure/README.md b/infrastructure/README.md new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/infrastructure/README.md @@ -0,0 +1 @@ + diff --git a/ingress/ingress.yaml b/ingress/ingress.yaml new file mode 100644 index 0000000..cf7574e --- /dev/null +++ b/ingress/ingress.yaml @@ -0,0 +1,33 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: grafana + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: grafana.frodo.synthesis.rocks + http: + paths: + - path: / + backend: + serviceName: polaris-prometheus-operator-grafana + servicePort: 80 + +--- + +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: prometheus + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: prometheus.frodo.synthesis.rocks + http: + paths: + - path: / + backend: + serviceName: polaris-prometheus-operato-prometheus + servicePort: 9090 diff --git a/permissions/permissions_scaffold b/permissions/permissions_scaffold new file mode 100644 index 0000000..29e108d --- /dev/null +++ b/permissions/permissions_scaffold @@ -0,0 +1,80 @@ + fileAssets: + - name: dex-ca-cert + path: /srv/kubernetes/assets/dex-ca-cert.pem + roles: [Master] # a list of roles to apply the asset to, zero defaults to all + content: | + <> + kubeAPIServer: + oidcIssuerURL: <> + oidcClientID: kubectl-access + oidcUsernameClaim: email + oidcGroupsClaim: groups + oidcCAFile: /srv/kubernetes/assets/dex-ca-cert.pem + additionalPolicies: + node: | + [ + { + "Effect": "Allow", + "Action": [ + "route53:ListHostedZones", + "route53:ListResourceRecordSets" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "route53:ChangeResourceRecordSets" + ], + "Resource": [ + "arn:aws:route53:::hostedzone/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "ec2:AttachVolume", + "ec2:DetachVolume" + ], + "Resource": [ + "*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeTags", + "autoscaling:SetDesiredCapacity", + "autoscaling:TerminateInstanceInAutoScalingGroup" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "codecommit:BatchGet*", + "codecommit:Get*", + "codecommit:Describe*", + "codecommit:List*", + "codecommit:GitPull" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "sqs:*", + "sns:*", + "cloudformation:*", + "ecr:*", + "dynamodb:*", + "s3:*" + ], + "Resource": "*" + } + ] diff --git a/run-cluster.sh b/run-cluster.sh new file mode 100755 index 0000000..76c05ed --- /dev/null +++ b/run-cluster.sh @@ -0,0 +1,12 @@ +mkdir -p "$HOME"/.ssh +mkdir -p "$HOME"/.aws +mkdir -p "$HOME"/.kube + +sudo docker run --rm -it \ + -v "$HOME"/.ssh:/root/.ssh:rw \ + -v "$HOME"/.aws:/root/.aws:ro \ + -v "$HOME"/.kube:/root/.kube:rw \ + -v "$(pwd)":/workdir \ + -w /workdir \ + --env-file environment \ + webstar34/polaris:1.0.0 bash -c '/workdir/create-cluster.sh' diff --git a/run-polaris.sh b/run-polaris.sh new file mode 100755 index 0000000..ce9a70d --- /dev/null +++ b/run-polaris.sh @@ -0,0 +1,8 @@ +sudo docker run --rm -it \ + -v "$HOME"/.ssh:/root/.ssh:rw \ + -v "$HOME"/.aws:/root/.aws:ro \ + -v "$HOME"/.kube:/root/.kube:rw \ + -v "$(pwd)":/workdir \ + -w /workdir \ + --env-file environment \ + webstar34/polaris:1.0.0 bash -c '/workdir/create-polaris.sh' From 6ecec248d4d76e321afd45f060745a161d3114e0 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 25 Feb 2019 21:35:36 +0200 Subject: [PATCH 2/4] removed sudo out of files --- run-cluster.sh | 2 +- run-polaris.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/run-cluster.sh b/run-cluster.sh index 76c05ed..a84086d 100755 --- a/run-cluster.sh +++ b/run-cluster.sh @@ -2,7 +2,7 @@ mkdir -p "$HOME"/.ssh mkdir -p "$HOME"/.aws mkdir -p "$HOME"/.kube -sudo docker run --rm -it \ +docker run --rm -it \ -v "$HOME"/.ssh:/root/.ssh:rw \ -v "$HOME"/.aws:/root/.aws:ro \ -v "$HOME"/.kube:/root/.kube:rw \ diff --git a/run-polaris.sh b/run-polaris.sh index ce9a70d..9e38101 100755 --- a/run-polaris.sh +++ b/run-polaris.sh @@ -1,4 +1,4 @@ -sudo docker run --rm -it \ +docker run --rm -it \ -v "$HOME"/.ssh:/root/.ssh:rw \ -v "$HOME"/.aws:/root/.aws:ro \ -v "$HOME"/.kube:/root/.kube:rw \ From 0697e353af6f27adaefad811acfef84f30055db8 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 27 Feb 2019 22:14:40 +0200 Subject: [PATCH 3/4] bugs --- charts/polaris/values.yaml | 28 ++++++++++++++-------------- create-cluster.sh | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/charts/polaris/values.yaml b/charts/polaris/values.yaml index 5044e31..2898c60 100644 --- a/charts/polaris/values.yaml +++ b/charts/polaris/values.yaml @@ -1,5 +1,5 @@ global: - cluster-name: frodo.synthesis.rocks + cluster-name: <> aws-service-operator: operator: @@ -21,7 +21,7 @@ cluster-autoscaler: cloudProvider: aws awsRegion: eu-west-1 autoscalingGroups: - - name: nodes.frodo.synthesis.rocks + - name: nodes.<> minSize: 1 maxSize: 6 @@ -55,9 +55,9 @@ dex: tlsName: dex-tls caName: dex-ca ingress: - host: dex.frodo.synthesis.rocks + host: dex.<> config: - issuer: https://dex.frodo.synthesis.rocks + issuer: https://dex.<> connectors: - type: microsoft id: microsoft @@ -65,7 +65,7 @@ dex: config: clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df clientSecret: lmwcHDOCUH74+zgbA152:]! - redirectURI: https://dex.frodo.synthesis.rocks/callback + redirectURI: https://dex.<>/callback # tenant: organizations # # Also - edit the application manifest (in MS Apps) and @@ -81,7 +81,7 @@ dex: - id: kubectl-access redirectURIs: - 'http://127.0.0.1:5555/callback' - - 'https://login.frodo.synthesis.rocks/callback/frodo.synthesis.rocks' + - 'https://login.<>/callback/<>' name: 'Kubectl Access' secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B enablePasswordDB: true @@ -103,18 +103,18 @@ dex-k8s-authenticator: debug: false web_path_prefix: / clusters: - - name: frodo.synthesis.rocks + - name: <> short_description: "Ref4 Cluster" description: "Reference number 4" client_secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B - issuer: https://dex.frodo.synthesis.rocks - k8s_master_uri: https://api.frodo.synthesis.rocks + issuer: https://dex.<> + k8s_master_uri: https://api.<> client_id: kubectl-access - redirect_uri: https://login.frodo.synthesis.rocks/callback/frodo.synthesis.rocks + redirect_uri: https://login.<>/callback/<> # # Make this particular link public in s3: k8s_ca_uri: - https://s3-eu-west-1.amazonaws.com/kops-mimic/frodo.synthesis.rocks/pki/issued/ca/6661957841380198014448874128.crt + <> caCerts: enabled: true secrets: @@ -122,7 +122,7 @@ dex-k8s-authenticator: - name: ca1 filename: ca1.crt value: - LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRRDBvK0l3S0pmNXlEQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdGsKWlhndGEzVmlaUzFqWVRBZUZ3MHhPVEF5TWpVeE5URTRNamxhRncwME5qQTNNVEl4TlRFNE1qbGFNQll4RkRBUwpCZ05WQkFNTUMyUmxlQzFyZFdKbExXTmhNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFybDhaNGZQV0o2LzZaT1MxTFJ4eHpIWThmVnR3RXdVU3lqVXVURzkvT05RWWZCOHdNSkpGSmR2YWhVRnMKQjdubVU4KzYxd1RyYk1tYW5BK2Yxdy9jbjNZL1dlaHdCYWl5U0NERGpmL0pkUlpnVFMwdk5vaEJYNWYvUk5IRQpnVTlhYTIxQzJmdDFVTWpCWFMvMmdhM3ArZUh6WVNSQ0RNYm5seUhsenhNOFZyc0hXaHRINFN5a0RzTWRaY0gzClpWV3psaFBqYXU2cDRrWDgzaVRoNXBwV1ZHMnBwTDFFaTdKYm1ucTJUdEZLYmVubVllbWprKzYyWlN1WmtKSEoKcDlCakp2VVEvVG9STTcwN294Vmc3MzF0T2ZKR0NtSEpPN3NYU2J6ZkhwVm4rWWcrR2tBWTBlbHBMS3djeW1JVApobjg4Zkt2YkFpb2pEZzdwbkZsb2Z2dUVuUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ0sxR0tuCmdJY1dsRGlkR3VVcmVXb2ZjdjBqVHd6UENzU09NSVg4amRDbUlCUG5TM2hNVUF0QThZNFA4bVdqVG9wRCtSdHYKbmlWaUk1eVd0RDdRMnJOSjJ5VnZncmFGSkpjSVI5a241N1BSKzZiK3VWclUrblhpcE9Rb3hjUENBb1BZK09kbwp3RFJNbURic3IyU3Q1WlpTT2U3c0NQYmRESXlaS1RXVW5zSlJyVEMwS3h6eUZmc1dDL2ZDYkhJTkVBc09Ic1JFClJZTUdUdmRrTHQ3YkFqa0dSbTVFRmFidC9uUTl3bHhaU1JZL2ZBMTgzZjVJSzRJVndwZVJoZTBLL0lHOVBqNHIKSzR1cDhsd2pUOHZkREUyb00zV0piSmRvWEtXNmFDYjh5R2Q3WitGUGJQbGFxMWVITmlZL0RBcEdQV2tPaG53NQo2MDE4THFKQ016U1hvM2RvCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + <> ingress: enabled: true annotations: {} @@ -130,7 +130,7 @@ dex-k8s-authenticator: # kubernetes.io/tls-acme: "true" path: / hosts: - - login.frodo.synthesis.rocks + - login.<> tls: - hosts: - - login.frodo.synthesis.rocks + - login.<> diff --git a/create-cluster.sh b/create-cluster.sh index f827014..28c932a 100755 --- a/create-cluster.sh +++ b/create-cluster.sh @@ -61,7 +61,7 @@ kops create cluster \ $1 $2 $3 $4 $5 $6 $7 $8 $9 -kops get --name ${CLUSTER_NAME} --state=s3://kops-mimic -o yaml > infrastructure/vanilla_cluster.yaml +kops get --name ${CLUSTER_NAME} --state=s3://${STATE_BUCKET} -o yaml > infrastructure/vanilla_cluster.yaml ROOT=$( dirname "${BASH_SOURCE[0]}" ) FOLDER=$ROOT/dex/ca From 63b1f73a7d2de3059d732d8ff0c086b634ede850 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 28 Feb 2019 00:01:52 +0200 Subject: [PATCH 4/4] minor bugs --- .../charts/dex-k8s-authenticator/values.yaml | 4 +-- charts/polaris/charts/dex/values.yaml | 27 ++++++++----------- charts/polaris/values.yaml | 27 ++++++++----------- create-cluster.sh | 2 +- create-polaris.sh | 2 ++ environment | 7 ++--- 6 files changed, 31 insertions(+), 38 deletions(-) diff --git a/charts/polaris/charts/dex-k8s-authenticator/values.yaml b/charts/polaris/charts/dex-k8s-authenticator/values.yaml index 03b6571..4fc3472 100644 --- a/charts/polaris/charts/dex-k8s-authenticator/values.yaml +++ b/charts/polaris/charts/dex-k8s-authenticator/values.yaml @@ -20,8 +20,8 @@ dexK8sAuthenticator: #tlsKey: /path/to/dex-client.key clusters: - name: <> - short_description: "Ref4 Cluster" - description: "Reference number 4" + short_description: <> + description: "This cluster is build from a automated script" client_secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B issuer: https://dex.<> k8s_master_uri: https://api.<> diff --git a/charts/polaris/charts/dex/values.yaml b/charts/polaris/charts/dex/values.yaml index 593d74b..f5473d1 100644 --- a/charts/polaris/charts/dex/values.yaml +++ b/charts/polaris/charts/dex/values.yaml @@ -81,7 +81,7 @@ config: https: 0.0.0.0:5556 tlsCert: /etc/dex/tls/tls.crt tlsKey: /etc/dex/tls/tls.key - connectors: + connectors: [] # - type: github # id: github # name: GitHub @@ -90,15 +90,15 @@ config: # clientSecret: yyyyyyyyyyyyyyyyyyyyy # redirectURI: https://dex.minikube.local:5556/callback # org: kubernetes - - type: microsoft - id: microsoft - # Required field for connector name. - name: Microsoft - config: - # Credentials can be string literals or pulled from the environment. - clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df - clientSecret: lmwcHDOCUH74+zgbA152:]! - redirectURI: https://dex.<>/callback + #- type: microsoft + #id: microsoft + ## Required field for connector name. + #name: Microsoft + #config: + ## Credentials can be string literals or pulled from the environment. + #clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df + #clientSecret: lmwcHDOCUH74+zgbA152:]! + #redirectURI: https://dex.<>/callback # tenant: organizations # # Also - edit the application manifest (in MS Apps) and @@ -125,13 +125,8 @@ config: enablePasswordDB: true staticPasswords: - - email: "admin@example.com" + - email: "admin@synthesis.com" # bcrypt hash of the string "password" hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" username: "admin" userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" - - email: "retail@example.com" - # bcrypt hash of the string "password" - hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" - username: "retail" - userID: "08a8684b-db88-4b73-90a9-3cd1661f5467" diff --git a/charts/polaris/values.yaml b/charts/polaris/values.yaml index 2898c60..c3605d1 100644 --- a/charts/polaris/values.yaml +++ b/charts/polaris/values.yaml @@ -58,14 +58,14 @@ dex: host: dex.<> config: issuer: https://dex.<> - connectors: - - type: microsoft - id: microsoft - name: Microsoft - config: - clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df - clientSecret: lmwcHDOCUH74+zgbA152:]! - redirectURI: https://dex.<>/callback + connectors: [] + #- type: microsoft + #id: microsoft + #name: Microsoft + #config: + #clientID: 33d82f8b-4db4-4d99-b610-0768ddd246df + #clientSecret: lmwcHDOCUH74+zgbA152:]! + #redirectURI: https://dex.<>/callback # tenant: organizations # # Also - edit the application manifest (in MS Apps) and @@ -86,16 +86,11 @@ dex: secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B enablePasswordDB: true staticPasswords: - - email: "admin@example.com" + - email: "admin@synthesis.com" # bcrypt hash of the string "password" hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" username: "admin" userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" - - email: "retail@example.com" - # bcrypt hash of the string "password" - hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" - username: "retail" - userID: "08a8684b-db88-4b73-90a9-3cd1661f5467" dex-k8s-authenticator: dexK8sAuthenticator: @@ -104,8 +99,8 @@ dex-k8s-authenticator: web_path_prefix: / clusters: - name: <> - short_description: "Ref4 Cluster" - description: "Reference number 4" + short_description: <> + description: "This cluster is build from a automated script" client_secret: rkKR4TX1RsK8OvVVufe45KIsuxN4A86B issuer: https://dex.<> k8s_master_uri: https://api.<> diff --git a/create-cluster.sh b/create-cluster.sh index 28c932a..48290ce 100755 --- a/create-cluster.sh +++ b/create-cluster.sh @@ -47,7 +47,7 @@ kops create cluster \ --networking cilium `# kubenet, classic, external, kopeio-vxlan, kopeio), weave, flannel-vxlan, flannel, flannel-udp, calico, canal, kube-router, romana, amazon-vpc-routed-eni, cilium` \ --node-count ${NODE_COUNT} `# Number of worker nodes` \ `#--node-security-groups # Existing SGs to apply to nodes` \ - --node-size m4.large `# Node instance type` \ + --node-size m4.xlarge `# Node instance type` \ `#--node-tenancy default # [default | dedicated]` \ --node-volume-size 30 `# Node volume size in GB` \ `#--project # Project to use (must be set on GCE)` \ diff --git a/create-polaris.sh b/create-polaris.sh index 0b51fe9..7a9eeeb 100755 --- a/create-polaris.sh +++ b/create-polaris.sh @@ -19,6 +19,7 @@ TEMP_CRT_CREDS=$(cat dex/ca/dex-ca-cert.pem | base64 -w 0) TEMP_CRT_NAME_ESCAPED=$(echo $TEMP_CRT_NAME | sed 's/\//\\\//g') sed -i 's/<>/'${CLUSTER_NAME}'/g' charts/polaris/values.yaml +sed -i 's/<>/'${CLUSTER_SHORT_DESCRIPTION}'/g' charts/polaris/values.yaml sed -i 's/<>/'${TEMP_CRT_CREDS}'/g' charts/polaris/values.yaml sed -i 's/<>/https:\/\/s3-eu-west-1.amazonaws.com\/'${STATE_BUCKET}'\/'${CLUSTER_NAME}'\/pki\/issued\/ca\/'${TEMP_CRT_NAME_ESCAPED}'/g' charts/polaris/values.yaml @@ -27,6 +28,7 @@ sed -i 's/<>/'${TEMP_CRT_CREDS}'/g' charts/polaris/charts/dex/values sed -i 's/<>/https:\/\/s3-eu-west-1.amazonaws.com\/'${STATE_BUCKET}'\/'${CLUSTER_NAME}'\/pki\/issued\/ca\/'${TEMP_CRT_NAME_ESCAPED}'/g' charts/polaris/charts/dex/values.yaml sed -i 's/<>/'${CLUSTER_NAME}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml +sed -i 's/<>/'${CLUSTER_SHORT_DESCRIPTION}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml sed -i 's/<>/'${TEMP_CRT_CREDS}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml sed -i 's/<>/https:\/\/s3-eu-west-1.amazonaws.com\/'${STATE_BUCKET}'\/'${CLUSTER_NAME}'\/pki\/issued\/ca\/'${TEMP_CRT_NAME_ESCAPED}'/g' charts/polaris/charts/dex-k8s-authenticator/values.yaml diff --git a/environment b/environment index dd03426..da2a955 100644 --- a/environment +++ b/environment @@ -1,5 +1,6 @@ -CLUSTER_NAME=example.cluster.k8s -STATE_BUCKET=ENTER_BUCKET_NAME_HERE +CLUSTER_NAME=cv.hackathon.s7s.cloud +CLUSTER_SHORT_DESCRIPTION=Computer-Vision +STATE_BUCKET=hackathon-computer-vision-bucket REGION=eu-west-1 AVAILABILITY_ZONES=eu-west-1a @@ -8,7 +9,7 @@ KUBERNETES_VERSION=1.10.5 MASTER_ZONES=eu-west-1a CLUSTER_CIDR=10.192.0.0/16 MASTER_COUNT=1 -NODE_COUNT=1 +NODE_COUNT=3 AWS_PROFILE=default