demos --> examples

examples/ is pretty standard whereas demos/ isn't. So I just refactored that.

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
Ahmet Alp Balkan
2018-05-25 10:07:46 -07:00
parent 4d111436aa
commit 7086e4f974
38 changed files with 38 additions and 38 deletions

281
examples/ldap/README.md Normal file
View File

@@ -0,0 +1,281 @@
[base]: ../../docs/glossary.md#base
[gitops]: ../../docs/glossary.md#gitops
[kustomization]: ../../docs/glossary.md#kustomization
[overlay]: ../../docs/glossary.md#overlay
[overlays]: ../../docs/glossary.md#overlay
[variant]: ../../docs/glossary.md#variant
[variants]: ../../docs/glossary.md#variant
# Demo: LDAP with variants
Steps:
1. Clone an existing configuration as a [base].
1. Customize it.
1. Create two different [overlays] (_staging_ and _production_)
from the customized base.
1. Run kustomize and kubectl to deploy staging and production.
First define a place to work:
<!-- @makeWorkplace @test -->
```
DEMO_HOME=$(mktemp -d)
```
Alternatively, use
> ```
> DEMO_HOME=~/ldap
> ```
## Establish the base
To use [overlays] to create [variants], we must
first establish a common [base].
To keep this document shorter, the base resources are
off in a supplemental data directory rather than
declared here as HERE documents. Download them:
<!-- @downloadBase @test -->
```
BASE=$DEMO_HOME/base
mkdir -p $BASE
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/ldap"
curl -s -o "$BASE/#1" "$CONTENT/base\
/{deployment.yaml,kustomization.yaml,service.yaml,env.startup.txt}"
```
Look at the directory:
<!-- @runTree @test -->
```
tree $DEMO_HOME
```
Expect something like:
> ```
> /tmp/tmp.IyYQQlHaJP
> └── base
> ├── deployment.yaml
> ├── env.startup.txt
> ├── kustomization.yaml
> └── service.yaml
> ```
One could immediately apply these resources to a
cluster:
> ```
> kubectl apply -f $DEMO_HOME/base
> ```
to instantiate the _ldap_ service. `kubectl`
would only recognize the resource files.
### The Base Kustomization
The `base` directory has a [kustomization] file:
<!-- @showKustomization @test -->
```
more $BASE/kustomization.yaml
```
Optionally, run `kustomize` on the base to emit
customized resources to `stdout`:
<!-- @buildBase @test -->
```
kustomize build $BASE
```
### Customize the base
A first customization step could be to set the name prefix to all resources:
<!-- @namePrefix @test -->
```
cd $BASE
kustomize edit set nameprefix "my-"
```
See the effect:
<!-- @checkNameprefix @test -->
```
kustomize build $BASE | grep -C 3 "my-"
```
## Create Overlays
Create a _staging_ and _production_ [overlay]:
* _Staging_ adds a configMap.
* _Production_ has a higher replica count and a persistent disk.
* [variants] will differ from each other.
<!-- @overlayDirectories @test -->
```
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/staging
mkdir -p $OVERLAYS/production
```
#### Staging Kustomization
Download the staging customization and patch.
<!-- @downloadStagingKustomization @test -->
```
curl -s -o "$OVERLAYS/staging/#1" "$CONTENT/overlays/staging\
/{config.env,deployment.yaml,kustomization.yaml}"
```
The staging customization adds a configMap.
> ```cat $OVERLAYS/staging/kustomization.yaml
> (...truncated)
> configMapGenerator:
> - name: env-config
> files:
> - config.env
> ```
as well as 2 replica
> ```cat $OVERLAYS/staging/deployment.yaml
> apiVersion: apps/v1beta2
> kind: Deployment
> metadata:
> name: ldap
> spec:
> replicas: 2
> ```
#### Production Kustomization
Download the production customization and patch.
<!-- @downloadProductionKustomization @test -->
```
curl -s -o "$OVERLAYS/production/#1" "$CONTENT/overlays/production\
/{deployment.yaml,kustomization.yaml}"
```
The production customization adds 6 replica as well as a consistent disk.
> ```cat $OVERLAYS/production/deployment.yaml
> apiVersion: apps/v1beta2
> kind: Deployment
> metadata:
> name: ldap
> spec:
> replicas: 6
> template:
> spec:
> volumes:
> - name: ldap-data
> emptyDir: null
> gcePersistentDisk:
> pdName: ldap-persistent-storage
> ```
## Compare overlays
`DEMO_HOME` now contains:
- a _base_ directory - a slightly customized clone
of the original configuration, and
- an _overlays_ directory, containing the kustomizations
and patches required to create distinct _staging_
and _production_ [variants] in a cluster.
Review the directory structure and differences:
<!-- @listFiles @test -->
```
tree $DEMO_HOME
```
Expecting something like:
> ```
> /tmp/tmp.IyYQQlHaJP1
> ├── base
> │   ├── deployment.yaml
> │   ├── env.startup.txt
> │   ├── kustomization.yaml
> │   └── service.yaml
> └── overlays
> ├── production
> │   ├── deployment.yaml
> │   └── kustomization.yaml
> └── staging
> ├── config.env
> ├── deployment.yaml
> └── kustomization.yaml
> ```
Compare the output directly
to see how _staging_ and _production_ differ:
<!-- @compareOutput -->
```
diff \
<(kustomize build $OVERLAYS/staging) \
<(kustomize build $OVERLAYS/production) |\
more
```
The difference output should look something like
> ```diff
> (...truncated)
> < name: staging-my-ldap-configmap-kftftt474h
> ---
> > name: production-my-ldap-configmap-k27f7hkg4f
> 85c75
> < name: staging-my-ldap-service
> ---
> > name: production-my-ldap-service
> 97c87
> < name: staging-my-ldap
> ---
> > name: production-my-ldap
> 99c89
> < replicas: 2
> ---
> > replicas: 6
> (...truncated)
> ```
## Deploy
The individual resource sets are:
<!-- @buildStaging @test -->
```
kustomize build $OVERLAYS/staging
```
<!-- @buildProduction @test -->
```
kustomize build $OVERLAYS/production
```
To deploy, pipe the above commands to kubectl apply:
> ```
> kustomize build $OVERLAYS/staging |\
> kubectl apply -f -
> ```
> ```
> kustomize build $OVERLAYS/production |\
> kubectl apply -f -
> ```

View File

@@ -0,0 +1,46 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: ldap
labels:
app: ldap
spec:
replicas: 1
selector:
matchLabels:
app: ldap
template:
metadata:
labels:
app: ldap
spec:
containers:
- name: ldap
image: osixia/openldap:1.1.11
args: ["--copy-service"]
volumeMounts:
- name: ldap-data
mountPath: /var/lib/ldap
- name: ldap-config
mountPath: /etc/ldap/slapd.d
- name: ldap-certs
mountPath: /container/service/slapd/assets/certs
- name: configmap-volume
mountPath: /container/environment/01-custom
- name: container-run
mountPath: /container/run
ports:
- containerPort: 389
name: openldap
volumes:
- name: ldap-data
emptyDir: {}
- name: ldap-config
emptyDir: {}
- name: ldap-certs
emptyDir: {}
- name: "configmap-volume"
configMap:
name: "ldap-configmap"
- name: container-run
emptyDir: {}

View File

@@ -0,0 +1,61 @@
# This is the default image startup configuration file
# this file define environment variables used during the container **first start** in **startup files**.
# This file is deleted right after startup files are processed for the first time,
# after that all these values will not be available in the container environment.
# This helps to keep your container configuration secret.
# more information : https://github.com/osixia/docker-light-baseimage
# Required and used for new ldap server only
LDAP_ORGANISATION: Example Inc.
LDAP_DOMAIN: example.org
LDAP_BASE_DN: #if empty automatically set from LDAP_DOMAIN
LDAP_ADMIN_PASSWORD: admin
LDAP_CONFIG_PASSWORD: config
LDAP_READONLY_USER: false
LDAP_READONLY_USER_USERNAME: readonly
LDAP_READONLY_USER_PASSWORD: readonly
LDAP_RFC2307BIS_SCHEMA: false
# Backend
LDAP_BACKEND: hdb
# Tls
LDAP_TLS: true
LDAP_TLS_CRT_FILENAME: ldap.crt
LDAP_TLS_KEY_FILENAME: ldap.key
LDAP_TLS_CA_CRT_FILENAME: ca.crt
LDAP_TLS_ENFORCE: false
LDAP_TLS_CIPHER_SUITE: SECURE256:+SECURE128:-VERS-TLS-ALL:+VERS-TLS1.2:-RSA:-DHE-DSS:-CAMELLIA-128-CBC:-CAMELLIA-256-CBC
LDAP_TLS_VERIFY_CLIENT: demand
# Replication
LDAP_REPLICATION: false
# variables $LDAP_BASE_DN, $LDAP_ADMIN_PASSWORD, $LDAP_CONFIG_PASSWORD
# are automaticaly replaced at run time
# if you want to add replication to an existing ldap
# adapt LDAP_REPLICATION_CONFIG_SYNCPROV and LDAP_REPLICATION_DB_SYNCPROV to your configuration
# avoid using $LDAP_BASE_DN, $LDAP_ADMIN_PASSWORD and $LDAP_CONFIG_PASSWORD variables
LDAP_REPLICATION_CONFIG_SYNCPROV: binddn="cn=admin,cn=config" bindmethod=simple credentials=$LDAP_CONFIG_PASSWORD searchbase="cn=config" type=refreshAndPersist retry="60 +" timeout=1 starttls=critical
LDAP_REPLICATION_DB_SYNCPROV: binddn="cn=admin,$LDAP_BASE_DN" bindmethod=simple credentials=$LDAP_ADMIN_PASSWORD searchbase="$LDAP_BASE_DN" type=refreshAndPersist interval=00:00:00:10 retry="60 +" timeout=1 starttls=critical
LDAP_REPLICATION_HOSTS:
- ldap://ldap.example.org # The order must be the same on all ldap servers
- ldap://ldap2.example.org
# Do not change the ldap config
# - If set to true with an existing database, config will remain unchanged. Image tls and replication config will not be run.
# The container can be started with LDAP_ADMIN_PASSWORD and LDAP_CONFIG_PASSWORD empty or filled with fake data.
# - If set to true when bootstrapping a new database, bootstap ldif and schema will not be added and tls and replication config will not be run.
KEEP_EXISTING_CONFIG: false
# Remove config after setup
LDAP_REMOVE_CONFIG_AFTER_SETUP: true
# ssl-helper environment variables prefix
LDAP_SSL_HELPER_PREFIX: ldap # ssl-helper first search config from LDAP_SSL_HELPER_* variables, before SSL_HELPER_* variables.

View File

@@ -0,0 +1,7 @@
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: ldap-configmap
files:
- env.startup.txt

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: ldap
name: ldap-service
spec:
ports:
- port: 389
selector:
app: ldap

136
examples/ldap/integration_test.sh Executable file
View File

@@ -0,0 +1,136 @@
#!/bin/bash
# Copyright 2018 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.
#
# ----------------------------------------------------
#
# This script tests the ldap kustomization demo
# against a real cluster.
#
# - deploy a ldap server by the output of kustomize
# - add a user
# - query a user
# - delete a user
#
# This script is a test that (passes|fails) if exit
# code is (0|1).
set -x
function configureCluster {
local tmpDir=$1
local target=$2
echo Kustomizing: \"$target\"
ls $target
kustomize build $target > $tmpDir/my.yaml
[[ $? -eq 0 ]] || { exitWith "Failed to kustomize build"; }
# Setting the namespace this way is a test-infra thing?
kubectl config set-context \
$(kubectl config current-context) --namespace=default
kubectl apply -f $tmpDir/my.yaml
[[ $? -eq 0 ]] || { exitWith "Failed to run kubectl apply"; }
sleep 20
}
function tearDownCluster {
local tmpDir=$1
kubectl delete -f $tmpDir/my.yaml
rm -rf $tmpDir
}
function getPodField {
echo $(kubectl get pods -l app=ldap -o jsonpath=$1)
}
function podExec {
kubectl exec $podName -c $containerName -- "$@"
}
function addUser {
local tmpDir=$1
local namespace=`getPodField '{.items[0].metadata.namespace}'`
[[ -z $namespace ]] && { exitWith "Unable to get namespace"; }
local myUserFile=$tmpDir/user.ldif
local podUserFile=/tmp/user.ldif
cat <<EOF >$myUserFile
dn: cn=The Postmaster,dc=example,dc=org
objectClass: organizationalRole
cn: The Postmaster
EOF
[[ -f $myUserFile ]] || \
{ exitWith "Failed to create $myUserFile"; }
kubectl cp $myUserFile \
$namespace/$podName:$podUserFile || \
{ exitWith "Failed to copy $myUserFile to pod $podName"; }
rm $myUserFile
podExec \
ldapadd \
-x \
-w admin \
-H ldap://localhost \
-D "cn=admin,dc=example,dc=org" \
-f $podUserFile
}
function getUserCount {
local result=$(\
podExec \
ldapsearch \
-x \
-w admin \
-H ldap://localhost \
-D "cn=admin,dc=example,dc=org" \
-b dc=example,dc=org \
)
return $(echo $result | grep "cn: The Postmaster" | wc -l)
}
function deleteAddedUser {
podExec \
ldapdelete \
-v \
-x \
-w admin \
-H ldap://localhost \
-D "cn=admin,dc=example,dc=org" \
"cn=The Postmaster,dc=example,dc=org"
}
tmpDir=$(mktemp -d)
configureCluster $tmpDir $1
podName=`getPodField '{.items[0].metadata.name}'`
[[ -z $podName ]] && { exitWith "Unable to get pod name"; }
containerName="ldap"
getUserCount; [[ $? -eq 0 ]] || { exitWith "Expected no users."; }
addUser $tmpDir || { exitWith "Failed to add a user"; }
getUserCount; [[ $? -eq 1 ]] || { exitWith "Couldn't find the new added user"; }
deleteAddedUser || { exitWith "Failed to delete the user"; }
getUserCount; [[ $? -eq 0 ]] || { exitWith "User has not been deleted."; }
tearDownCluster $tmpDir

View File

@@ -0,0 +1,13 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: ldap
spec:
replicas: 6
template:
spec:
volumes:
- name: ldap-data
emptyDir: null
gcePersistentDisk:
pdName: ldap-persistent-storage

View File

@@ -0,0 +1,5 @@
bases:
- ../../base
patches:
- deployment.yaml
namePrefix: production-

View File

@@ -0,0 +1,2 @@
DB_USERNAME=admin
DB_PASSWORD=somepw

View File

@@ -0,0 +1,7 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: ldap
spec:
replicas: 2

View File

@@ -0,0 +1,9 @@
bases:
- ../../base
patches:
- deployment.yaml
nameprefix: staging-
configMapGenerator:
- name: env-config
files:
- config.env