LDAP Server 前端Openldap + 后端Mysql Cluster

  1. 摘要:此处假定你已经熟悉LDAP协议,Openldap和Mysql Cluster的基本概念。我们可以用Openldap+Mysql Cluster来构建企业级或者电信级统一的用户数据管理,以下是理想的逻辑模型:Load Balancer可以采用F5或者LVS等,Openldap本身不直接提供对NDB访问的Distribution Access Layer机制。          
  2. 为简化起见,本次实验只会用到下面的实验模型:一台32位Linux虚拟机, 由于Mysql Cluster是内存数据库,带有4G内存的Laptop中只能启动2个Data Node,而且所有的实验节点都在同一台VM
  3. 安装Mysql Cluster
    • Extract mysql-cluster-gpl-7.2.12-linux2.6-i686.tar.gz to “/usr/local/mysql-cluster-gpl-7.2.12-linux2.6-i686”
    • ln -s /usr/local/mysql-cluster-gpl-7.2.12-linux2.6-i686 /usr/local/mysqlc
      # 将/usr/local/mysqlc/bin/:/usr/local/mysqlc/scripts/添加到PATH
      echo "/usr/local/mysqlc/lib" >> /etc/ld.so.conf
      ldconfig -v
  4. 安装Openldap
    • 安装openssl-1.0.1e
      cd ./openssl-1.0.1e
      ./Configure --prefix=/usr/local/ssl
      make
      make install
    • 安装BerkeleyDB db-5.3.21.gz
      cd ./db-5.3.21
      cd build_unix
      ../dist/configure --prefix=/usr/local/BerkeleyDB
      make
      make install
      echo "/usr/local/BerkeleyDB/lib" >> /etc/ld.so.conf
      ldconfig -v
    • 安装Openldap mysql-cluster-gpl-7.2.12-linux2.6-i686.tar.gz
      cd ./openldap-2.4.26
      export CPPFLAGS="-I/usr/local/BerkeleyDB/include -I/usr/local/ssl/include -I/usr/local/ssl/include/openssl" LDFLAGS="-L/usr/local/BerkeleyDB/lib -L/usr/local/ssl/lib"
      
      ./configure --with-tls=openssl --enable-ndb --enable-meta --enable-ldap --enable-dynamic --prefix=/usr/local/openldap
      
      make depend
      make
      make install
      # 将 /usr/local/openldap/bin/:/usr/local/openldap/sbin/:/usr/local/openldap/libexec/ 添加到PATH
  5. 配置Mysql Cluster
    • 本实验在同一台机器VM上配置2套Mysql Cluster, 鉴于内存有限,每一套Mysql Cluster配置1一个Data Node,3个API Node(2个也可以),一个MGM Node.  以root用户启动Openldap和Mysql Cluster
    • 配置第一套Mysql Cluster作为Master
      # Config master cluster
      mkdir -p /root/ws/mysql_cluster/test3/sql1/conf
      mkdir -p /root/ws/mysql_cluster/test3/sql1/log
      mkdir -p /root/ws/mysql_cluster/test3/sql1/mgmt_data
      mkdir -p /root/ws/mysql_cluster/test3/sql1/mysqld_data
      mkdir -p /root/ws/mysql_cluster/test3/sql1/ndb_data
      # cat  /root/ws/mysql_cluster/test3/sql1/conf/config.ini
      [ndb_mgmd default]
      datadir=/root/ws/mysql_cluster/test3/sql1/mgmt_data
      
      [ndb_mgmd] 
      hostname=localhost 
      logdestination=FILE:filename=/root/ws/mysql_cluster/test3/sql1/log/megm.log
      NodeId=1 
      portnumber=1186
      
      [ndbd default] 
      noofreplicas=1 
      datadir=/root/ws/mysql_cluster/test3/sql1/ndb_data 
      LockPagesInMainMemory=1
      DataMemory=16M
      IndexMemory=15M
      FragmentLogFileSize=8M
      NoOfFragmentLogFiles=8
      
      [ndbd] 
      hostname=localhost 
      NodeId=3 
      
      [mysqld] 
      hostname=localhost
      NodeId=50 
      [mysqld] 
      hostname=localhost
      NodeId=51 
      [mysqld] 
      hostname=localhost
      NodeId=52 
      # cat /root/ws/mysql_cluster/test3/sql1/conf/my.cnf
      [mysqld] 
      ndbcluster 
      datadir=/root/ws/mysql_cluster/test3/sql1/mysqld_data 
      basedir=/usr/local/mysqlc 
      port=3306 
      socket=/root/ws/mysql_cluster/test3/sql1/mysqld_data/mysql.socket
      
      general_log=1
      general_log_file=/root/ws/mysql_cluster/test3/sql1/log/query.log
      log_error=/root/ws/mysql_cluster/test3/sql1/log/error.log
      
      log-bin=/root/ws/mysql_cluster/test3/sql1/mysqld_data/binlogs
      #Database name which can be replicated. Please keep it as the same in Openldap config file mentioned later.
      binlog-do-db=openldap
    • 配置第二套Mysql Cluster作为Slave
      # Config master cluster
      mkdir -p /root/ws/mysql_cluster/test3/sql2/conf
      mkdir -p /root/ws/mysql_cluster/test3/sql2/log
      mkdir -p /root/ws/mysql_cluster/test3/sql2/mgmt_data
      mkdir -p /root/ws/mysql_cluster/test3/sql2/mysqld_data
      mkdir -p /root/ws/mysql_cluster/test3/sql2/ndb_data
      # cat /root/ws/mysql_cluster/test3/sql2/conf/config.ini
      [ndb_mgmd default]
      datadir=/root/ws/mysql_cluster/test3/sql2/mgmt_data
      
      [ndb_mgmd] 
      hostname=localhost 
      logdestination=FILE:filename=/root/ws/mysql_cluster/test3/sql2/log/megm.log
      NodeId=1 
      #Here we installed 2 clusters on the same VM, so it's mandatory to change the second cluster mgm port from default 1186 to other port like 1286 portnumber
      =1286 [ndbd default] noofreplicas=1 datadir=/root/ws/mysql_cluster/test3/sql2/ndb_data LockPagesInMainMemory=1 DataMemory=16MM IndexMemory=15M FragmentLogFileSize=8M NoOfFragmentLogFiles=8 [ndbd] hostname=localhost NodeId=3 [mysqld] hostname=localhost NodeId=50 [mysqld] hostname=localhost NodeId=51 [mysqld] hostname=localhost NodeId=52
      # cat /root/ws/mysql_cluster/test3/sql2/conf/my.cnf
      [mysqld] 
      ndbcluster 
      datadir=/root/ws/mysql_cluster/test3/sql2/mysqld_data 
      basedir=/usr/local/mysqlc 
      # Here we installed 2 clusters on the same VM, so it's mandatory to change mysqld listening port from default 3306 to other ports like 3406 port
      =3406 socket=/root/ws/mysql_cluster/test3/sql2/mysqld_data/mysql.socket general_log=1 general_log_file=/root/ws/mysql_cluster/test3/sql2/log/query.log log_error=/root/ws/mysql_cluster/test3/sql2/log/error.log # Replicate database "openldap" from master to slave replicate-do-db=openldap skip-slave-start slave_allow_batching=1 relay-log-purge=1 slave-net-timeout=10
  6. 启动Master Cluster
    • Start the Management Node and Data Node
    • #cd /usr/local/mysqlc

      #./scripts/mysql_install_db --no-defaults --datadir=/root/ws/mysql_cluster/test3/sql1/mysqld_data

      # Start Management node
      #ndb_mgmd --skip-config-cache --ndb-nodeid=1 --initial -f /root/ws/mysql_cluster/test3/sql1/conf/config.ini

      # Start ndb node
      #ndbmtd --ndb-nodeid=3 --ndb-connectstring=localhost:1186 --initial-start

      # Please wait node node to be from "starting" state to "started" as below:

      # ndb_mgm -e show

      Connected to Management Server at: localhost:1186
      Cluster Configuration
      ---------------------
      [ndbd(NDB)] 1 node(s)
      id=3 @127.0.0.1 (mysql-5.5.30 ndb-7.2.12, Nodegroup: 0, Master)

      [ndb_mgmd(MGM)] 1 node(s)
      id=1 @127.0.0.1 (mysql-5.5.30 ndb-7.2.12)

      [mysqld(API)] 3 node(s)
      id=50 (not connected, accepting connect from localhost)
      id=51 (not connected, accepting connect from localhost)
      id=52 (not connected, accepting connect from localhost)

    • After Ndb started, please Start one API node(Actually Openldap tool will use it for provision data and as master to handle replication)
      # mysqld --defaults-file=/root/ws/mysql_cluster/test3/sql1/conf/my.cnf  --port=3306  --skip-name-resolve --ndb-nodeid=50 --ndb-connectstring=localhost:1186  --user=root --datadir=/root/ws/mysql_cluster/test3/sql1/mysqld_data  --server-id=20001 &
      
      # ndb_mgm -e show
      Connected to Management Server at: localhost:1186
      Cluster Configuration
      ---------------------
      [ndbd(NDB)]     1 node(s)
      id=3    @127.0.0.1  (mysql-5.5.30 ndb-7.2.12, Nodegroup: 0, Master)
      
      [ndb_mgmd(MGM)] 1 node(s)
      id=1    @127.0.0.1  (mysql-5.5.30 ndb-7.2.12)
      
      [mysqld(API)]   3 node(s)
      id=50   @127.0.0.1  (mysql-5.5.30 ndb-7.2.12)
      id=51 (not connected, accepting connect from localhost)
      id=52 (not connected, accepting connect from localhost)
    • # you can use below commands to log in to the cluster to check status and grant privilege to slave
      mysql -uroot --socket /root/ws/mysql_cluster/test3/sql1/mysqld_data/mysql.socket
      mysql -uroot -h 127.0.0.1 -P 3306
      
      mysql> grant all privileges on *.* to 'root'@'<your VM IP>' identified by '';
      mysql> grant all privileges on *.* to 'root'@'127.0.0.1' identified by '';
      mysql> grant all privileges on *.* to 'root'@'localhost' identified by '';
    • Check Master status
      # mysql -uroot -h 127.0.0.1 -P 3306
      mysql> show master status;
      +----------------+----------+--------------+------------------+
      | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
      +----------------+----------+--------------+------------------+
      | binlogs.000001 |      112 | openldap     |                  |
      +----------------+----------+--------------+------------------+
      1 row in set (0.00 sec)
      
      mysql> show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | ndbinfo            |
      | performance_schema |
      | test               |
      +--------------------+
      5 rows in set (0.00 sec)
  7. 启动Slave Cluster
    • Start the Management Node and Data Node
      #cd /usr/local/mysqlc
      #./scripts/mysql_install_db --no-defaults --datadir=/root/ws/mysql_cluster/test3/sql2/mysqld_data
      
      # Start slave mgm node
      #ndb_mgmd --skip-config-cache --ndb-nodeid=1 --initial  -f /root/ws/mysql_cluster/test3/sql2/conf/config.ini
      
      #Start slave ndb node
      ndbmtd --ndb-nodeid=3 --ndb-connectstring=localhost:1286  --initial-start
      
      # Please wait node node to be from "starting" state to "started" as below: # ndb_mgm
      -c localhost:1286 -e show Connected to Management Server at: localhost:1286 Cluster Configuration --------------------- [ndbd(NDB)] 1 node(s) id=3 @127.0.0.1 (mysql-5.5.30 ndb-7.2.12, Nodegroup: 0, Master) [ndb_mgmd(MGM)] 1 node(s) id=1 @127.0.0.1 (mysql-5.5.30 ndb-7.2.12) [mysqld(API)] 3 node(s) id=50 (not connected, accepting connect from localhost) id=51 (not connected, accepting connect from localhost) id=52 (not connected, accepting connect from localhost)
    • After Ndb started, please Start one API node(as slave to do replication)
      # mysqld --defaults-file=/root/ws/mysql_cluster/test3/sql2/conf/my.cnf  --port=3316  --skip-name-resolve --ndb-nodeid=50 --ndb-connectstring=localhost:1286  --user=root --datadir=/root/ws/mysql_cluster/test3/sql2/mysqld_data  --server-id=20011 &
      
      # ndb_mgm -c localhost:1286 -e show
      Connected to Management Server at: localhost:1286
      Cluster Configuration
      ---------------------
      [ndbd(NDB)]     1 node(s)
      id=3    @127.0.0.1  (mysql-5.5.30 ndb-7.2.12, Nodegroup: 0, Master)
      
      [ndb_mgmd(MGM)] 1 node(s)
      id=1    @127.0.0.1  (mysql-5.5.30 ndb-7.2.12)
      
      [mysqld(API)]   3 node(s)
      id=50   @127.0.0.1  (mysql-5.5.30 ndb-7.2.12)
      id=51 (not connected, accepting connect from localhost)
      id=52 (not connected, accepting connect from localhost)
      # you can use below commands to log in to the cluster to check status and grant privilege to slave
      mysql -uroot --socket /root/ws/mysql_cluster/test3/sql2/mysqld_data/mysql.socket
      mysql -uroot -h 127.0.0.1 -P 3316  
      
      mysql> grant all privileges on *.* to 'root'@'<your VM IP>' identified by '';
      mysql> grant all privileges on *.* to 'root'@'127.0.0.1' identified by '';
      mysql> grant all privileges on *.* to 'root'@'localhost' identified by '';
    • Change master configuration on  Slave cluster as 
      # mysql -uroot -h 127.0.0.1 -P 3316
      mysql> change master to master_host='localhost', master_port=3306, master_user='root';
      mysql> start slave;
      mysql> show slave status\G
      *************************** 1. row ***************************
                     Slave_IO_State: Waiting for master to send event
                        Master_Host: localhost
                        Master_User: root
                        Master_Port: 3306
                      Connect_Retry: 60
                    Master_Log_File: binlogs.000001
                Read_Master_Log_Pos: 112
                     Relay_Log_File: Ubuntu-VM1-relay-bin.000002
                      Relay_Log_Pos: 261
              Relay_Master_Log_File: binlogs.000001
                   Slave_IO_Running: Yes
                  Slave_SQL_Running: Yes
                    Replicate_Do_DB: openldap
                Replicate_Ignore_DB: 
                 Replicate_Do_Table: 
             Replicate_Ignore_Table: 
            Replicate_Wild_Do_Table: 
        Replicate_Wild_Ignore_Table: 
                         Last_Errno: 0
                         Last_Error: 
                       Skip_Counter: 0
                Exec_Master_Log_Pos: 112
                    Relay_Log_Space: 427
                    Until_Condition: None
                     Until_Log_File: 
                      Until_Log_Pos: 0
                 Master_SSL_Allowed: No
                 Master_SSL_CA_File: 
                 Master_SSL_CA_Path: 
                    Master_SSL_Cert: 
                  Master_SSL_Cipher: 
                     Master_SSL_Key: 
              Seconds_Behind_Master: 0
      Master_SSL_Verify_Server_Cert: No
                      Last_IO_Errno: 0
                      Last_IO_Error: 
                     Last_SQL_Errno: 0
                     Last_SQL_Error: 
        Replicate_Ignore_Server_Ids: 
                   Master_Server_Id: 20001
                        Master_Bind: 
      1 row in set (0.00 sec)
  8. 启动Openldap Server
    • Schema 准备,这里不创建新的Schema文件,使用Openldap自带的Schema
    • 配置slapd.conf(Openldap Server 配置文件):
       1 root@Ubuntu-VM1:~/ws/ldap/test4# cat slapd.conf
       2 # slapd.conf - Configuration file for LDAP SLAPD
       3 ##########
       4 # Basics #
       5 ##########
       6 include /usr/local/openldap/etc/openldap/schema/core.schema
       7 include /usr/local/openldap/etc/openldap/schema/cosine.schema
       8 include /usr/local/openldap/etc/openldap/schema/inetorgperson.schema
       9 include /usr/local/openldap/etc/openldap/schema/nis.schema
      10 pidfile /usr/local/openldap/var/run/slapd.pid
      11 argsfile /usr/local/openldap/var/run/slapd.args
      12 loglevel 255 
      13 #modulepath /usr/local/openldap/lib 
      14 # modulepath /usr/local/libexec/openldap
      15 #moduleload back_hdb
      16 ##########################
      17 # Database Configuration #
      18 ##########################
      19 database ndb
      20 suffix "dc=example,dc=com"
      21 rootdn "cn=Manager,dc=example,dc=com"
      22 rootpw secret
      23 dbconnect localhost
      24 dbhost  127.0.0.1 
      25 dbname openldap
      26 #dbsocket /tmp/mysql.sock
      27 dbport 3306 
      28 dbuser root 
      29 dbpass "" 
      30 #dbflag 0 
      31 dbconnections 1
      32 directory /usr/local/openldap/var/openldap-data 
    • 初始数据规划
      ##共5条DN记录
      Initial Data
    • 数据文件 test.ldif
      ##共5条DN记录
      root@Ubuntu-VM1:~/ws/ldap/test4# cat test.ldif dn: dc=example,dc=com objectClass: dcObject objectClass: organizationalUnit dc: example ou: Example Dot Com dn: ou=people,dc=example,dc=com objectClass: organizationalUnit ou: people dn: ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: groups dn: cn=example,ou=groups,dc=example,dc=com objectClass: posixGroup cn: example gidNumber: 10000 dn: uid=lionel,ou=people,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: lionel sn: Porcheron givenName: Lionel cn: Lionel Porcheron displayName: Lionel Porcheron uidNumber: 1000 gidNumber: 10000 gecos: Lionel Porcheron loginShell: /bin/bash homeDirectory: /home/lionel shadowExpire: -1 shadowFlag: 0 shadowWarning: 7 shadowMin: 8 shadowMax: 999999 shadowLastChange: 10877 mail: lionel.porcheron@example.com postalCode: 31000 l: Toulouse o: Example mobile: +33 (0)6 xx xx xx xx homePhone: +33 (0)5 xx xx xx xx title: System Administrator postalAddress: initials: LP
    • 用Debug模式启动Openldap server(这里建议开始时启动Debug模式,配置一切OK以后再重新启动Daemon进程)
      # slapd -d 255 -f slapd.conf
      #以下为控制台输出,表示成功连接Master NDB
      518c9177 slapd startup: initiated.
      518c9177 backend_startup_one: starting "cn=config"
      518c9177 config_back_db_open
      Backend ACL: access to *
              by * none
      
      518c9177 config_back_db_open: line 0: warning: cannot assess the validity of the ACL scope within backend naming context
      518c9177 config_back_db_open: No explicit ACL for back-config configured. Using hardcoded default
      518c9177 config_build_entry: "cn=config"
      518c9177 config_build_entry: "cn=schema"
      518c9177 >>> dnNormalize: <cn={0}core>
      518c9177 <<< dnNormalize: <cn={0}core>
      518c9177 config_build_entry: "cn={0}core"
      518c9177 >>> dnNormalize: <cn={1}cosine>
      518c9177 <<< dnNormalize: <cn={1}cosine>
      518c9177 config_build_entry: "cn={1}cosine"
      518c9177 >>> dnNormalize: <cn={2}inetorgperson>
      518c9177 <<< dnNormalize: <cn={2}inetorgperson>
      518c9177 config_build_entry: "cn={2}inetorgperson"
      518c9177 >>> dnNormalize: <cn={3}nis>
      518c9177 <<< dnNormalize: <cn={3}nis>
      518c9177 config_build_entry: "cn={3}nis"
      518c9177 config_build_entry: "olcDatabase={-1}frontend"
      518c9177 config_build_entry: "olcDatabase={0}config"
      518c9177 config_build_entry: "olcDatabase={1}ndb"
      518c9177 backend_startup_one: starting "dc=example,dc=com"
      518c9177 ndb_db_open: "dc=example,dc=com"
      518c9178 slapd starting
      518c9178 daemon: added 4r listener=(nil)
      518c9178 daemon: added 7r listener=0x8396740
      518c9178 daemon: added 8r listener=0x83a0638
      518c9178 daemon: epoll: listen=7 active_threads=0 tvp=NULL
      518c9178 daemon: epoll: listen=8 active_threads=0 tvp=NULL
      518c9178 daemon: activity on 1 descriptor
      518c9178 daemon: activity on:518c9178 
      518c9178 daemon: epoll: listen=7 active_threads=0 tvp=NULL
      518c9178 daemon: epoll: listen=8 active_threads=0 tvp=NULL
      ##检查Master的状态
      #mysql -uroot -h 127.0.0.1 -P 3306
      mysql> show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | ndbinfo            |
      | openldap           |
      | performance_schema |
      | test               |
      +--------------------+
      6 rows in set (0.00 sec)
      
      mysql> show master status;
      +----------------+----------+--------------+------------------+
      | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
      +----------------+----------+--------------+------------------+
      | binlogs.000001 |     1708 | openldap     |                  |
      +----------------+----------+--------------+------------------+
      1 row in set (0.00 sec)
      
      mysql> use openldap;
      Reading table information for completion of table and column names
      You can turn off this feature to get a quicker startup with -A
      
      Database changed
      mysql> show tables;
      +--------------------+
      | Tables_in_openldap |
      +--------------------+
      | OL_dn2id           |
      | OL_nextid          |
      | OL_opattrs         |
      +--------------------+
      3 rows in set (0.00 sec)
      
      mysql> use openldap
      mysql> select count(*) from OL_dn2id, OL_nextid, OL_opattrs;
      +----------+
      | count(*) |
      +----------+
      |        0 |
      +----------+
      1 row in set (0.00 sec)
      ##检查Slave Cluster的状态
      #mysql -uroot -h 127.0.0.1 -P 3316 mysql
      > show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | ndbinfo | | openldap | | performance_schema | | test | +--------------------+ 6 rows in set (0.03 sec) mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: root Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlogs.000001 Read_Master_Log_Pos: 1708 Relay_Log_File: Ubuntu-VM1-relay-bin.000002 Relay_Log_Pos: 1857 Relay_Master_Log_File: binlogs.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: openldap Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1708 Relay_Log_Space: 2023 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 20001 Master_Bind: 1 row in set (0.00 sec) mysql> use openldap mysql> show tables; +--------------------+ | Tables_in_openldap | +--------------------+ | OL_dn2id | | OL_nextid | | OL_opattrs | +--------------------+ 3 rows in set (0.00 sec) mysql> select count(*) from OL_dn2id, OL_nextid, OL_opattrs; +----------+ | count(*) | +----------+ | 0 | +----------+ 1 row in set (0.01 sec) mysql> desc OL_dn2id; +----------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+---------------------+------+-----+---------+-------+ | eid | bigint(20) unsigned | NO | UNI | NULL | | | object_classes | varchar(1024) | NO | | NULL | | | a0 | varchar(128) | NO | PRI | | | | a1 | varchar(128) | NO | PRI | | | | a2 | varchar(128) | NO | PRI | | | | a3 | varchar(128) | NO | PRI | | | | a4 | varchar(128) | NO | PRI | | | | a5 | varchar(128) | NO | PRI | | | | a6 | varchar(128) | NO | PRI | | | | a7 | varchar(128) | NO | PRI | | | | a8 | varchar(128) | NO | PRI | | | | a9 | varchar(128) | NO | PRI | | | | a10 | varchar(128) | NO | PRI | | | | a11 | varchar(128) | NO | PRI | | | | a12 | varchar(128) | NO | PRI | | | | a13 | varchar(128) | NO | PRI | | | | a14 | varchar(128) | NO | PRI | | | | a15 | varchar(128) | NO | PRI | | | +----------------+---------------------+------+-----+---------+-------+ 18 rows in set (0.00 sec)
  9. Provision Data via LDAP client
    • Openldap提供了一些Tool来Provison 数据,例如ldapadd(运行它之前必须先启动Openldap Server的进程“slapd”),  slapadd(不需要启动slapd, 该工具将直接将数据导入NDB, 命令形式如slapadd -d 255 -f  slapd.conf -l test.ldif), 这里我们用ldapadd, 所以我们在前一步已经启动了slapd进程

      root@Ubuntu-VM1:~/ws/ldap/test4# ldapadd -x -D "cn=Manager,dc=example,dc=com" -w secret -d 256 -f test.ldif
      adding new entry "dc=example,dc=com"

      adding new entry "ou=people,dc=example,dc=com"

      adding new entry "ou=groups,dc=example,dc=com"

      adding new entry "cn=example,ou=groups,dc=example,dc=com"

      adding new entry "uid=lionel,ou=people,dc=example,dc=com"

    • 用ldapsearch查询我们插入的数据test.ldif是否成功
      root@Ubuntu-VM1:~/ws/ldap/test4# ldapsearch -xLLL -b "dc=example,dc=com"
      dn: dc=example,dc=com
      objectClass: dcObject
      objectClass: organizationalUnit
      dc: example
      ou: Example Dot Com
      
      dn: ou=groups,dc=example,dc=com
      objectClass: organizationalUnit
      ou: groups
      
      dn: cn=example,ou=groups,dc=example,dc=com
      objectClass: posixGroup
      cn: example
      gidNumber: 10000
      
      dn: ou=people,dc=example,dc=com
      objectClass: organizationalUnit
      ou: people
      
      dn: uid=lionel,ou=people,dc=example,dc=com
      objectClass: inetOrgPerson
      objectClass: posixAccount
      objectClass: shadowAccount
      postalCode: 31000
      l: Toulouse
      cn: Lionel Porcheron
      gidNumber: 10000
      sn: Porcheron
      title: System Administrator
      displayName: Lionel Porcheron
      givenName: Lionel
      homePhone: +33 (0)5 xx xx xx xx
      initials: LP
      mail: lionel.porcheron@example.com
      mobile: +33 (0)6 xx xx xx xx
      o: Example
      uid: lionel
      uidNumber: 1000
      homeDirectory: /home/lionel
      loginShell: /bin/bash
      gecos: Lionel Porcheron
      shadowLastChange: 10877
      shadowMin: 8
      shadowMax: 999999
      shadowWarning: 7
      shadowExpire: -1
      shadowFlag: 0
    • 查看后台Mysql Cluster变化:
      #检查Master的状态
      #mysql -uroot -h 127.0.0.1 -P 3306 
      mysql> show master status;
      +----------------+----------+--------------+------------------+
      | File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
      +----------------+----------+--------------+------------------+
      | binlogs.000001 |     9987 | openldap     |                  |
      +----------------+----------+--------------+------------------+
      1 row in set (0.00 sec)
      
      mysql> show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | ndbinfo            |
      | openldap           |
      | performance_schema |
      | test               |
      +--------------------+
      6 rows in set (0.00 sec)
      
      mysql> use openldap;
      Database changed
      mysql> show tables;
      +----------------------+
      | Tables_in_openldap   |
      +----------------------+
      | OL_dn2id             |
      | OL_nextid            |
      | OL_opattrs           |
      | dcObject             |
      | inetOrgPerson        |
      | organizationalPerson |
      | organizationalUnit   |
      | person               |
      | posixAccount         |
      | posixGroup           |
      | shadowAccount        |
      +----------------------+
      11 rows in set (0.02 sec)

      mysql> select count(*) from OL_dn2id; ##此处说明我们插入了5条数据,想想前面的初始数据规划,我们有5条DN记录
      +----------+
      | count(*) |
      +----------+
      | 5 |
      +----------+
      1 row in set (0.03 sec)

      #检查Slave的状态
      #mysql -uroot -h 127.0.0.1 -P 3316
      mysql> show slave status\G
      *************************** 1. row ***************************
                     Slave_IO_State: Waiting for master to send event
                        Master_Host: localhost
                        Master_User: root
                        Master_Port: 3306
                      Connect_Retry: 60
                    Master_Log_File: binlogs.000001
                Read_Master_Log_Pos: 9987
                     Relay_Log_File: Ubuntu-VM1-relay-bin.000002
                      Relay_Log_Pos: 10136
              Relay_Master_Log_File: binlogs.000001
                   Slave_IO_Running: Yes
                  Slave_SQL_Running: Yes
                    Replicate_Do_DB: openldap
                Replicate_Ignore_DB: 
                 Replicate_Do_Table: 
             Replicate_Ignore_Table: 
            Replicate_Wild_Do_Table: 
        Replicate_Wild_Ignore_Table: 
                         Last_Errno: 0
                         Last_Error: 
                       Skip_Counter: 0
                Exec_Master_Log_Pos: 9987
                    Relay_Log_Space: 10302
                    Until_Condition: None
                     Until_Log_File: 
                      Until_Log_Pos: 0
                 Master_SSL_Allowed: No
                 Master_SSL_CA_File: 
                 Master_SSL_CA_Path: 
                    Master_SSL_Cert: 
                  Master_SSL_Cipher: 
                     Master_SSL_Key: 
              Seconds_Behind_Master: 0
      Master_SSL_Verify_Server_Cert: No
                      Last_IO_Errno: 0
                      Last_IO_Error: 
                     Last_SQL_Errno: 0
                     Last_SQL_Error: 
        Replicate_Ignore_Server_Ids: 
                   Master_Server_Id: 20001
                        Master_Bind: 
      1 row in set (0.00 sec)
      
      mysql> show databases;
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | ndbinfo            |
      | openldap           |
      | performance_schema |
      | test               |
      +--------------------+
      6 rows in set (0.00 sec)
      
      mysql> use openldap;
      mysql> show tables;
      +----------------------+
      | Tables_in_openldap   |
      +----------------------+
      | OL_dn2id             |
      | OL_nextid            |
      | OL_opattrs           |
      | dcObject             |
      | inetOrgPerson        |
      | organizationalPerson |
      | organizationalUnit   |
      | person               |
      | posixAccount         |
      | posixGroup           |
      | shadowAccount        |
      +----------------------+
      11 rows in set (0.03 sec)
  10. 数据转换分析,对照NDB表和Provisioned test.ldif
    • DN 记录到DB表OL_dn2id的转换:
    • #mysql -uroot -h 127.0.0.1 -P 3306
      mysql>use openldap;
      mysql> select * from OL_dn2id;
      +------+------------------------------------------------------------------------------+--------+------------+-----------+------------+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+
      | eid  | object_classes                                                               | a0     | a1         | a2        | a3         | a4 | a5 | a6 | a7 | a8 | a9 | a10 | a11 | a12 | a13 | a14 | a15 |
      +------+------------------------------------------------------------------------------+--------+------------+-----------+------------+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+
      |    1 |  dcObject organizationalUnit @ top                                           | dc=com | dc=example |           |            |    |    |    |    |    |    |     |     |     |     |     |     |
      |    4 |  inetOrgPerson posixAccount shadowAccount @ top person organizationalPerson  | dc=com | dc=example | ou=people | uid=lionel |    |    |    |    |    |    |     |     |     |     |     |     |
      |    3 |  organizationalUnit @ top                                                    | dc=com | dc=example | ou=groups |            |    |    |    |    |    |    |     |     |     |     |     |     |
      |    2 |  organizationalUnit @ top                                                    | dc=com | dc=example | ou=people |            |    |    |    |    |    |    |     |     |     |     |     |     |
      | 1001 |  posixGroup @ top                                                            | dc=com | dc=example | ou=groups | cn=example |    |    |    |    |    |    |     |     |     |     |     |     |
      +------+------------------------------------------------------------------------------+--------+------------+-----------+------------+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+
      5 rows in set (0.07 sec)

      mysql> desc OL_dn2id;
      +----------------+---------------------+------+-----+---------+-------+
      | Field          | Type                | Null | Key | Default | Extra |
      +----------------+---------------------+------+-----+---------+-------+
      | eid            | bigint(20) unsigned | NO   | UNI | NULL    |       |
      | object_classes | varchar(1024)       | NO   |     | NULL    |       |
      | a0             | varchar(128)        | NO   | PRI |         |       |
      | a1             | varchar(128)        | NO   | PRI |         |       |
      | a2             | varchar(128)        | NO   | PRI |         |       |
      | a3             | varchar(128)        | NO   | PRI |         |       |
      | a4             | varchar(128)        | NO   | PRI |         |       |
      | a5             | varchar(128)        | NO   | PRI |         |       |
      | a6             | varchar(128)        | NO   | PRI |         |       |
      | a7             | varchar(128)        | NO   | PRI |         |       |
      | a8             | varchar(128)        | NO   | PRI |         |       |
      | a9             | varchar(128)        | NO   | PRI |         |       |
      | a10            | varchar(128)        | NO   | PRI |         |       |
      | a11            | varchar(128)        | NO   | PRI |         |       |
      | a12            | varchar(128)        | NO   | PRI |         |       |
      | a13            | varchar(128)        | NO   | PRI |         |       |
      | a14            | varchar(128)        | NO   | PRI |         |       |
      | a15            | varchar(128)        | NO   | PRI |         |       |
      +----------------+---------------------+------+-----+---------+-------+
      18 rows in set (0.00 sec)

      Openldap 将一条DN的信息例如dn: cn=example,ou=groups,dc=example,dc=com 作为一条记录插入DB 表OL_dn2id中

      #从客户端Provision时test.ldif 的部分数据
      dn: cn=example,ou=groups,dc=example,dc=com
      objectClass: posixGroup
      cn: example
      gidNumber: 10000

      #DN记录转换规则
      将DN的每个RDN从Root到Leaf转成OL_dn2id表中16个字段(a0,a1,a2,a3,....,a15),也就是说如果配置NDB作为LDAP的Backend,DIT(Data information Tree)的最大深度是16.

      #DN记录的ObjectClass及属性转换
      将DN关联的Objceclass作为字符串记录到OL_dn2id表中字段object_classes,此处DB表中存储的是"posixGroup @ top"(@表示ObjectClass的继承关系)
      进一步查看DB表posixGroup的数据:

        mysql> select * from posixGroup;
        +------+-----+------------------+-----------+-----------+
        | eid  | vid | cn               | gidNumber | memberUid |
        +------+-----+------------------+-----------+-----------+
        | 4    | 0   | Lionel Porcheron | 10000     | NULL      |
        | 1001 | 0   | example          | 10000     | NULL      |
        +------+-----+------------------+-----------+-----------+
        2 rows in set (0.02 sec)

       

        此处vid在的作用是防止LDAP中一个属性对应多个Value(例如cn的值可以有多个)

        mysql> desc posixGroup;
        +-----------+---------------------+------+-----+---------+-------+
        | Field     | Type                | Null | Key | Default | Extra |
        +-----------+---------------------+------+-----+---------+-------+
        | eid       | bigint(20) unsigned | NO   | PRI | NULL    |       |
        | vid       | int(10) unsigned    | NO   | PRI | NULL    |       |
        | cn        | varchar(128)        | YES  |     | NULL    |       |
        | gidNumber | varchar(128)        | YES  |     | NULL    |       |
        | memberUid | varchar(128)        | YES  |     | NULL    |       |
        +-----------+---------------------+------+-----+---------+-------+
        5 rows in set (0.04 sec)

       

    • 相关源码:在openldap-2.4.35/servers/slapd/back-ndb中有相关的转换代码 

      -rw-rw-r-- 1 2000 2000   12189 Mar 28 23:41 tools.cpp
      -rw-rw-r-- 1 2000 2000     100 Mar 28 23:41 TODO
      -rw-rw-r-- 1 2000 2000   21638 Mar 28 23:41 search.cpp
      -rw-rw-r-- 1 2000 2000    3481 Mar 28 23:41 proto-ndb.h
      -rw-rw-r-- 1 2000 2000   41251 Mar 28 23:41 ndbio.cpp
      -rw-rw-r-- 1 2000 2000   14667 Mar 28 23:41 modrdn.cpp
      -rw-rw-r-- 1 2000 2000   17815 Mar 28 23:41 modify.cpp
      -rw-rw-r-- 1 2000 2000    1643 Mar 28 23:41 Makefile.in
      -rw-rw-r-- 1 2000 2000   11441 Mar 28 23:41 init.cpp
      -rw-rw-r-- 1 2000 2000    8370 Mar 28 23:41 delete.cpp
      -rw-rw-r-- 1 2000 2000    9865 Mar 28 23:41 config.cpp
      -rw-rw-r-- 1 2000 2000    4212 Mar 28 23:41 compare.cpp
      -rw-rw-r-- 1 2000 2000    3884 Mar 28 23:41 bind.cpp
      -rw-rw-r-- 1 2000 2000    4186 Mar 28 23:41 back-ndb.h
      -rw-rw-r-- 1 2000 2000     772 Mar 28 23:41 attrsets.conf
      -rw-rw-r-- 1 2000 2000    9191 Mar 28 23:41 add.cpp
      
      # cat init.cpp
      static int
      ndb_db_open( BackendDB *be, ConfigReply *cr )
      {
              struct ndb_info *ni = (struct ndb_info *) be->be_private;
              char sqlbuf[BUFSIZ], *ptr;
              int rc, i;
      
              if ( be->be_suffix == NULL ) {
                      snprintf( cr->msg, sizeof( cr->msg ),
                              "ndb_db_open: need suffix" );
                      Debug( LDAP_DEBUG_ANY, "%s\n",
                              cr->msg, 0, 0 );
                      return -1;
              }
      
              Debug( LDAP_DEBUG_ARGS,
                      LDAP_XSTRING(ndb_db_open) ": \"%s\"\n",
                      be->be_suffix[0].bv_val, 0, 0 );
      
              if ( ni->ni_nconns < 1 )
                      ni->ni_nconns = 1;
      
              ni->ni_cluster = (Ndb_cluster_connection **)ch_calloc( ni->ni_nconns, sizeof( Ndb_cluster_connection *));
              for ( i=0; i<ni->ni_nconns; i++ ) {
                      ni->ni_cluster[i] = new Ndb_cluster_connection( ni->ni_connectstr );
                      rc = ni->ni_cluster[i]->connect( 20, 5, 1 );
                      if ( rc ) {
                              snprintf( cr->msg, sizeof( cr->msg ),
                                      "ndb_db_open: ni_cluster[%d]->connect failed (%d)",
                                      i, rc );
                              goto fail;
                      }
              }
              for ( i=0; i<ni->ni_nconns; i++ ) {
                      rc = ni->ni_cluster[i]->wait_until_ready( 30, 30 );
                      if ( rc ) {
                              snprintf( cr->msg, sizeof( cr->msg ),
                                      "ndb_db_open: ni_cluster[%d]->wait failed (%d)",
                                      i, rc );
                              goto fail;
                      }
              }
      
              mysql_init( &ni->ni_sql );
              if ( !mysql_real_connect( &ni->ni_sql, ni->ni_hostname, ni->ni_username, ni->ni_password,
                      "", ni->ni_port, ni->ni_socket, ni->ni_clflag )) {
                      snprintf( cr->msg, sizeof( cr->msg ),
                              "ndb_db_open: mysql_real_connect failed, %s (%d)",
                              mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
                      rc = -1;
                      goto fail;
              }
      
              sprintf( sqlbuf, "CREATE DATABASE IF NOT EXISTS %s", ni->ni_dbname );
              rc = mysql_query( &ni->ni_sql, sqlbuf );
              if ( rc ) {
                      snprintf( cr->msg, sizeof( cr->msg ),
                              "ndb_db_open: CREATE DATABASE %s failed, %s (%d)",
                              ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
                      goto fail;
              }
      
              sprintf( sqlbuf, "USE %s", ni->ni_dbname );
              rc = mysql_query( &ni->ni_sql, sqlbuf );
              if ( rc ) {
                      snprintf( cr->msg, sizeof( cr->msg ),
                              "ndb_db_open: USE DATABASE %s failed, %s (%d)",
                              ni->ni_dbname, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
                      goto fail;
              }
      
              ptr = sqlbuf;
              ptr += sprintf( ptr, "CREATE TABLE IF NOT EXISTS " DN2ID_TABLE " ("
                      "eid bigint unsigned NOT NULL, "
                      "object_classes VARCHAR(1024) NOT NULL, "
                      "a0 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a1 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a2 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a3 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a4 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a5 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a6 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a7 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a8 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a9 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a10 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a11 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a12 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a13 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a14 VARCHAR(128) NOT NULL DEFAULT '', "
                      "a15 VARCHAR(128) NOT NULL DEFAULT '', "
                      "PRIMARY KEY (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15), "
                      "UNIQUE KEY eid (eid) USING HASH" );
              /* Create index columns */
              if ( ni->ni_attridxs ) {
                      ListNode *ln;
                      int newcol = 0;
      
                      *ptr++ = ',';
                      *ptr++ = ' ';
                      for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
                              NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data;
                              ptr += sprintf( ptr, "`%s` VARCHAR(%d), ",
                                      ai->na_name.bv_val, ai->na_len );
                      }
                      ptr = lutil_strcopy(ptr, "KEY " INDEX_NAME " (" );
      
                      for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
                              NdbAttrInfo *ai = (NdbAttrInfo *)ln->ln_data;
                              if ( newcol ) *ptr++ = ',';
                              *ptr++ = '`';
                              ptr = lutil_strcopy( ptr, ai->na_name.bv_val );
                              *ptr++ = '`';
                              ai->na_ixcol = newcol + 18;
                              newcol++;
                      }
                      *ptr++ = ')';
              }
              strcpy( ptr, ") ENGINE=ndb" );
              rc = mysql_query( &ni->ni_sql, sqlbuf );
              if ( rc ) {
                      snprintf( cr->msg, sizeof( cr->msg ),
                              "ndb_db_open: CREATE TABLE " DN2ID_TABLE " failed, %s (%d)",
                              mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
                      goto fail;
              }
      
              rc = mysql_query( &ni->ni_sql, "CREATE TABLE IF NOT EXISTS " NEXTID_TABLE " ("
                      "a bigint unsigned AUTO_INCREMENT PRIMARY KEY ) ENGINE=ndb" );
              if ( rc ) {
                      snprintf( cr->msg, sizeof( cr->msg ),
                              "ndb_db_open: CREATE TABLE " NEXTID_TABLE " failed, %s (%d)",
                              mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
                      goto fail;
              }
      
              {
                      NdbOcInfo *oci;
      
                      rc = ndb_aset_get( ni, &ndb_optable, ndb_opattrs, &oci );
                      if ( rc ) {
                              snprintf( cr->msg, sizeof( cr->msg ),
                                      "ndb_db_open: ndb_aset_get( %s ) failed (%d)",
                                      ndb_optable.bv_val, rc );
                              goto fail;
                      }
                      for ( i=0; ndb_oplens[i] >= 0; i++ ) {
                              if ( ndb_oplens[i] )
                                      oci->no_attrs[i]->na_len = ndb_oplens[i];
                      }
                      rc = ndb_aset_create( ni, oci );
                      if ( rc ) {
                              snprintf( cr->msg, sizeof( cr->msg ),
                                      "ndb_db_open: ndb_aset_create( %s ) failed (%d)",
                                      ndb_optable.bv_val, rc );
                              goto fail;
                      }
                      ni->ni_opattrs = oci;
              }
              /* Create attribute sets */
              {
                      ListNode *ln;
      
                      for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
                              NdbOcInfo *oci = (NdbOcInfo *)ln->ln_data;
                              rc = ndb_aset_create( ni, oci );
                              if ( rc ) {
                                      snprintf( cr->msg, sizeof( cr->msg ),
                                              "ndb_db_open: ndb_aset_create( %s ) failed (%d)",
                                              oci->no_name.bv_val, rc );
                                      goto fail;
                              }
                      }
              }
              /* Initialize any currently used objectClasses */
              {
                      Ndb *ndb;
                      const NdbDictionary::Dictionary *myDict;
      
                      ndb = new Ndb( ni->ni_cluster[0], ni->ni_dbname );
                      ndb->init(1024);
      
                      myDict = ndb->getDictionary();
                      ndb_oc_read( ni, myDict );
                      delete ndb;
              }
      
      #ifdef DO_MONITORING
              /* monitor setup */
              rc = ndb_monitor_db_open( be );
              if ( rc != 0 ) {
                      goto fail;
              }
      #endif
      
              return 0;
      
      fail:
              Debug( LDAP_DEBUG_ANY, "%s\n",
                      cr->msg, 0, 0 );
              ndb_db_close( be, NULL );
              return rc;
      }
    • 最后推荐一款图形化的LDAP客户端http://jxplorer.org/index.html
posted on 2013-05-15 05:47  YHG  阅读(1713)  评论(0编辑  收藏  举报