Openshift上部署OpenLDAP也并不仅仅只是为了部署,更重要的是要用它来为各种应用统一账号管理。比如GitLab,Gogs, Nexus, Sonarqube等等,同时结合之前的Openshift使用OpenLDAP做账号管理。理想的世界是,一套Openshift,各种应用,它们的用户认证都在一套OpenLDAP上,同时这套OpenLDAP也是非常方便地部署在Openshift上。
为账号一统的第一步,就是我们需要部署OpenLDAP,这也是该篇主题。以下是之前分享的几篇与OpenLDAP有关的文章。
CentOS上搭建双主高可用OpenLDAP Server
Openshift使用OpenLDAP作为统一用户认证
CentOS上OpenLDAP Server使用cn=config方式配置
之前分享的与Openldap相关的几篇文章中,它的部署都是在虚拟机中进行的。那么在Openshift上能否完成部署呢,如果可以的话,那么那些复杂的部署我们都可以将它封装到镜像中去,岂不是更方便?那就一起来操作吧。
应用要求点
- 方便自定义域及管理员用户名与密码
通过环境变量
及secret
进行自定义配置 - 对pod添加健康检查,如果发现问题,主动重启恢复
监听389端口 - 数据持久化,pod重启后,该pod自动恢复数据
持久化目录为:数据目录/var/lib/ldap
, 配置目录/etc/openldap
以上是在Openshift运行Openldap的最基本的要求了,如果更苛刻点,需要添加Openldap的监控、Openldap的日志审计、多pod高可用方案等。
制作镜像
如果不希望自己构建,可以直接使用构建好的镜像:docker.io/xhuaustc/openldap-2441-centos7:latest
步骤如下:
- 基础镜像centos:centos7
- 安装openldap相关应用:openldap, openldap-clients, openldap-servers
- 部署:根据环境变量更新openldap的配置文件,并初始化基础结构,最后启动openldap
运行:启动openldap
说明
,部署与运行的区别在于该应用是否是第一次启动。如果是第一次启动的话,相关配置还未更新。在第一次配置更新后,在持久化文件夹中创建一个新文件,来标记已完成配置更新。以后的每次启动都会检查该文件,如果存在,则不作初始化操作,而直接运行openldap
对应的Dockerfile参考:https://github.com/openshift/openldap/blob/master/2.4.41/Dockerfile
FROM centos:centos7
# OpenLDAP server image for OpenShift Origin
#
# Volumes:
# * /var/lib/ldap/data - Datastore for OpenLDAP
# * /etc/openldap/ - Config directory for slapd
# Environment:
# * $OPENLDAP_ADMIN_PASSWORD - OpenLDAP administrator password
# * $OPENLDAP_DEBUG_LEVEL (Optional) - OpenLDAP debugging level, defaults to 256
MAINTAINER Steve Kuznetsov <skuznets@redhat.com>
LABEL io.k8s.description="OpenLDAP is an open source implementation of the Lightweight Directory Access Protocol." \
io.k8s.display-name="OpenLDAP 2.4.41" \
io.openshift.expose-services="389:ldap,636:ldaps" \
io.openshift.tags="directory,ldap,openldap,openldap2441" \
io.openshift.non-scalable="true"
# Add defaults for config
COPY ./contrib/config /opt/openshift/config
COPY ./contrib/lib /opt/openshift/lib
# Add startup scripts
COPY run-*.sh /usr/local/bin/
COPY contrib/*.ldif /usr/local/etc/openldap/
COPY contrib/*.schema /usr/local/etc/openldap/
COPY contrib/DB_CONFIG /usr/local/etc/openldap/
# Install OpenLDAP Server, give it permissionst to bind to low ports
RUN yum install -y openldap openldap-servers openldap-clients && \
yum clean all -y && \
setcap 'cap_net_bind_service=+ep' /usr/sbin/slapd && \
mkdir -p /var/lib/ldap && \
chmod a+rwx -R /var/lib/ldap && \
mkdir -p /etc/openldap && \
chmod a+rwx -R /etc/openldap && \
mkdir -p /var/run/openldap && \
chmod a+rwx -R /var/run/openldap && \
chmod -R a+rw /opt/openshift
# Set OpenLDAP data and config directories in a data volume
VOLUME ["/var/lib/ldap", "/etc/openldap"]
# Expose default ports for ldap and ldaps
EXPOSE 389 636
CMD ["/usr/local/bin/run-openldap.sh"]
对应的部署及运行脚本参考:
https://github.com/openshift/openldap/blob/master/2.4.41/run-openldap.sh
但是有所修改,如果用root用户启动时,会先初始化openldap配置。原来的脚本如果用root用户启动时,会报错,而用非root用户启动,则自定义配置无法生效。
#!/bin/bash
# Reduce maximum number of number of open file descriptors to 1024
# otherwise slapd consumes two orders of magnitude more of RAM
# see https://github.com/docker/docker/issues/8231
ulimit -n 1024
OPENLDAP_ROOT_PASSWORD=${OPENLDAP_ROOT_PASSWORD:-admin}
OPENLDAP_ROOT_DN_PREFIX=${OPENLDAP_ROOT_DN_PREFIX:-'cn=Manager'}
OPENLDAP_ROOT_DN_SUFFIX=${OPENLDAP_ROOT_DN_SUFFIX:-'dc=example,dc=com'}
OPENLDAP_DEBUG_LEVEL=${OPENLDAP_DEBUG_LEVEL:-256}
# Only run if no config has happened fully before
if [ ! -f /etc/openldap/CONFIGURED ]; then
user=`id | grep -Po "(?<=uid=)\d+"`
if (( user == 0 ))
then
# We are root, we can use user input!
# Bring in default databse config
cp /usr/local/etc/openldap/DB_CONFIG /var/lib/ldap/DB_CONFIG
if [ -f /opt/openshift/config/slapd.d/cn\=config/olcDatabase\=\{0\}config.ldif ]
then
# Use provided default config, get rid of current data
rm -rf /var/lib/ldap/*
rm -rf /etc/openldap/*
# Bring in associated default database files
mv -f /opt/openshift/lib/* /var/lib/ldap
mv -f /opt/openshift/config/* /etc/openldap
else
# Something has gone wrong with our image build
echo "FAILURE: Default configuration files from /contrib/ are not present in the image at /opt/openshift."
exit 1
fi
# start the daemon in another process and make config changes
slapd -h "ldap:/// ldaps:/// ldapi:///" -d $OPENLDAP_DEBUG_LEVEL &
for ((i=30; i>0; i--))
do
ping_result=`ldapsearch 2>&1 | grep "Can.t contact LDAP server"`
if [ -z "$ping_result" ]
then
break
fi
sleep 1
done
if [ $i -eq 0 ]
then
echo "slapd did not start correctly"
exit 1
fi
# Generate hash of password
OPENLDAP_ROOT_PASSWORD_HASH=$(slappasswd -s "${OPENLDAP_ROOT_PASSWORD}")
# Update configuration with root password, root DN, and root suffix
sed -e "s OPENLDAP_ROOT_PASSWORD ${OPENLDAP_ROOT_PASSWORD_HASH} g" \
-e "s OPENLDAP_ROOT_DN ${OPENLDAP_ROOT_DN_PREFIX} g" \
-e "s OPENLDAP_SUFFIX ${OPENLDAP_ROOT_DN_SUFFIX} g" /usr/local/etc/openldap/first_config.ldif |
ldapmodify -Y EXTERNAL -H ldapi:/// -d $OPENLDAP_DEBUG_LEVEL
# add test schema
ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/local/etc/openldap/testPerson.ldif -d $OPENLDAP_DEBUG_LEVEL
# add useful schemas
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif -d $OPENLDAP_DEBUG_LEVEL
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif -d $OPENLDAP_DEBUG_LEVEL
# load memberOf and refint modules
ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/local/etc/openldap/load_modules.ldif -d $OPENLDAP_DEBUG_LEVEL
# configure memberOf module
ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/local/etc/openldap/configure_memberof.ldif -d $OPENLDAP_DEBUG_LEVEL
# configure refint module
ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/local/etc/openldap/configure_refint.ldif -d $OPENLDAP_DEBUG_LEVEL
# extract dc name from root DN suffix
dc_name=$(echo "${OPENLDAP_ROOT_DN_SUFFIX}" | grep -Po "(?<=^dc\=)[\w\d]+")
# create base organization object
sed -e "s OPENLDAP_SUFFIX ${OPENLDAP_ROOT_DN_SUFFIX} g" \
-e "s FIRST_PART ${dc_name} g" \
usr/local/etc/openldap/base.ldif |
ldapadd -x -D "$OPENLDAP_ROOT_DN_PREFIX,$OPENLDAP_ROOT_DN_SUFFIX" -w "$OPENLDAP_ROOT_PASSWORD"
# stop the daemon
pid=$(ps -A | grep slapd | awk '{print $1}')
kill -2 $pid || echo $?
# ensure the daemon stopped
for ((i=30; i>0; i--))
do
exists=$(ps -A | grep $pid)
if [ -z "${exists}" ]
then
break
fi
sleep 1
done
if [ $i -eq 0 ]
then
echo "slapd did not stop correctly"
exit 1
fi
else
# We are not root, we need to populate from the default bind-mount source
if [ -f /opt/openshift/config/slapd.d/cn\=config/olcDatabase\=\{0\}config.ldif ]
then
# Use provided default config, get rid of current data
rm -rf /var/lib/ldap/*
rm -rf /etc/openldap/*
# Bring in associated default database files
mv -f /opt/openshift/lib/* /var/lib/ldap
mv -f /opt/openshift/config/* /etc/openldap
else
# Something has gone wrong with our image build
echo "FAILURE: Default configuration files from /contrib/ are not present in the image at /opt/openshift."
exit 1
fi
fi
# Test configuration files, log checksum errors. Errors may be tolerated and repaired by slapd so don't exit
LOG=`slaptest 2>&1`
CHECKSUM_ERR=$(echo "${LOG}" | grep -Po "(?<=ldif_read_file: checksum error on \").+(?=\")")
for err in $CHECKSUM_ERR
do
echo "The file ${err} has a checksum error. Ensure that this file is not edited manually, or re-calculate the checksum."
done
rm -rf /opt/openshift/*
touch /etc/openldap/CONFIGURED
fi
# Start the slapd service
exec slapd -h "ldap:/// ldaps:///" -d $OPENLDAP_DEBUG_LEVEL
说明
,本来我是准备按照之前部署经验自己写一个镜像构建,但是写到一半的时候,发现整个逻辑与openshift官方提供的差不多,所以就直接用官方的了。
从脚本中可以看到管理员(一般为cn=Manager)密码数据库管理员(一般为cn=config)密码是一样的,都是通过环境变量OPENLDAP_ROOT_PASSWORD
配置。
变量名 | 说明 | 默认值 |
---|---|---|
OPENLDAP_ROOT_PASSWORD | OpenLDAP olcRootPW 密码 | admin |
OPENLDAP_ROOT_DN_SUFFIX | OpenLDAP olcSuffix 域前缀 | dc=example,dc=com |
OPENLDAP_ROOT_DN_PREFIX | OpenLDAP olcRootDN 前缀 | cn=Manager |
OPENLDAP_DEBUG_LEVEL | OpenLDAP服务日志级别 | 256 |
使用openshift/openldap进行构建镜像操作
$ git clone https://github.com/openshift/openldap.git
$ cd openldap
$ export SKIP_SQUASH=1 && make build #构建出的镜像名为:openshift/openldap-2441-centos7:latest
部署Openldap
两种方法实现部署:
第一种. 使用openshift的client工具部署
$ #创建项目
$ oc new-project openldap --display-name=OpenLDAP
$ #创建单独的serviceaccount为方便以root用户启动pod
$ oc create serviceaccount openldap
$ #为openldap serviceaccount赋予以root启动pod的权限
$ oc adm policy add-scc-to-user anyuid -z openldap
$ #创建secret,设置openldap的域与密码
$ oc create secret generic openldap --from-literal=OPENLDAP_ROOT_PASSWORD=admin --from-literal=OPENLDAP_ROOT_DN_SUFFIX=dc=fcloudy,dc=com
$ # 部署应用(默认会是以default serviceaccount运行)
$ oc new-app --docker-image=xhuaustc/openldap-2441-centos7 --name=openldap
$ #为应用设置环境变量,即为openldap的域与密码
$ oc env --from=secret/openldap dc/openldap
$ #为应用设置以openldap serviceaccount启动
$ cat << EOF | oc apply -f -
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: openldap
spec:
template:
spec:
serviceAccount: openldap
EOF
当然以上配置没有添加健康检查,以及持久化是使用的emptyDir。这个可以后序自己补充。
第二种:使用yaml配置文件部署,主要是DeploymentConfig的配置。添加了健康检查
$ cat << EOF | oc create -f -
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
labels:
app: openldap
name: openldap
spec:
replicas: 1
selector:
app: openldap
deploymentconfig: openldap
template:
metadata:
labels:
app: openldap
deploymentconfig: openldap
spec:
containers:
- env:
- name: OPENLDAP_ROOT_DN_SUFFIX
valueFrom:
secretKeyRef:
key: OPENLDAP_ROOT_DN_SUFFIX
name: openldap
- name: OPENLDAP_ROOT_PASSWORD
valueFrom:
secretKeyRef:
key: OPENLDAP_ROOT_PASSWORD
name: openldap
image: 'xhuaustc/openldap-2441-centos7:latest'
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 389
timeoutSeconds: 1
name: openldap
ports:
- containerPort: 389
protocol: TCP
- containerPort: 636
protocol: TCP
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 389
timeoutSeconds: 1
name: openldap
ports:
- containerPort: 389
protocol: TCP
- containerPort: 636
protocol: TCP
volumeMounts:
- mountPath: /etc/openldap
name: openldap-volume-1
- mountPath: /var/lib/ldap
name: openldap-volume-2
volumes:
- emptyDir: {}
name: openldap-volume-1
- emptyDir: {}
name: openldap-volume-2
triggers:
- type: ConfigChange
测试验证
按照以上部署的配置,管理员账号为:cn=Manager,dc=fcloudy,dc=com
,密码为:admin
使用LDAPBrowser连接
最后一步,做成模板
将资源导出为模板文件
$ oc export dc,svc,secret --as-template=openldap > openldap-template.yaml
在此基础上手动编辑,最后得到可用的模板文件
apiVersion: template.openshift.io/v1
kind: Template
message: |-
OpenLDAP服务将会根据指定的参数创建
metadata:
annotations:
description: |-
OpenLDAP服务将会根据指定的参数创建
name: openldap
objects:
- apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
labels:
app: openldap
name: openldap
spec:
replicas: 1
selector:
app: openldap
deploymentconfig: openldap
strategy:
type: Rolling
template:
metadata:
labels:
app: openldap
deploymentconfig: openldap
spec:
containers:
- env:
- name: OPENLDAP_ROOT_DN_SUFFIX
valueFrom:
secretKeyRef:
key: OPENLDAP_ROOT_DN_SUFFIX
name: openldap
- name: OPENLDAP_ROOT_PASSWORD
valueFrom:
secretKeyRef:
key: OPENLDAP_ROOT_PASSWORD
name: openldap
- name: OPENLDAP_ROOT_DN_PREFIX
valueFrom:
secretKeyRef:
key: OPENLDAP_ROOT_DN_PREFIX
name: openldap
- name: OPENLDAP_DEBUG_LEVEL
valueFrom:
secretKeyRef:
key: OPENLDAP_DEBUG_LEVEL
name: openldap
image: xhuaustc/openldap-2441-centos7:latest
imagePullPolicy: IfNotPresent
name: openldap
ports:
- containerPort: 389
protocol: TCP
- containerPort: 636
protocol: TCP
volumeMounts:
- mountPath: /etc/openldap
name: openldap-volume-1
- mountPath: /var/lib/ldap
name: openldap-volume-2
restartPolicy: Always
serviceAccount: openldap
serviceAccountName: openldap
volumes:
- emptyDir: {}
name: openldap-volume-1
- emptyDir: {}
name: openldap-volume-2
triggers:
- type: ConfigChange
- apiVersion: v1
kind: Service
metadata:
labels:
app: openldap
name: openldap
spec:
ports:
- name: 389-tcp
port: 389
protocol: TCP
targetPort: 389
- name: 636-tcp
port: 636
protocol: TCP
targetPort: 636
selector:
app: openldap
deploymentconfig: openldap
sessionAffinity: None
type: ClusterIP
- apiVersion: v1
stringData:
OPENLDAP_ROOT_DN_SUFFIX: ${OPENLDAP_ROOT_DN_SUFFIX}
OPENLDAP_ROOT_DN_PREFIX: ${OPENLDAP_ROOT_DN_PREFIX}
OPENLDAP_ROOT_PASSWORD: ${OPENLDAP_ROOT_PASSWORD}
OPENLDAP_DEBUG_LEVEL: ${OPENLDAP_DEBUG_LEVEL}
kind: Secret
metadata:
name: openldap
type: Opaque
parameters:
- description: Openldap Root DN Suffix
displayName: Openldap Root DN Suffix
name: OPENLDAP_ROOT_DN_SUFFIX
value: dc=example,dc=com
- description: Openldap Root DN Manager Prefix
displayName: Openldap Root DN Manager Prefix
name: OPENLDAP_ROOT_DN_PREFIX
value: cn=Manager
- description: Openldap Root Password
displayName: Openldap Root Password
name: OPENLDAP_ROOT_PASSWORD
from: '[a-zA-Z0-9]{16}'
generate: expression
- description: Openldap Debug Level
displayName: Openldap Debug Level
name: OPENLDAP_DEBUG_LEVEL
value: "256"
在Openshift上将模板导入,完成后,创建Openldap就非常简单了,看截图。
Openshift模板创建OpenLDAPps:OpenLDAP的整个构建及部署过程可以作为Openshift的一种类型案例。当然该案例中没有使用PV、PVC做持久化。相信对Openshift有所了解的,在这个基础上做持久化应该不在话下。
千里之行,始于足下。完成OpenLDAP的部署,这只是一个开始,账号一统还有相当多的工作要去做。
欢迎关注
网友评论