samba 4で構築したドメインにNetApp 9.5が登録できない


テスト環境作成のためNetAppシミュレータの9.5P6を作ってsamba 4で構築したActive Directory環境に登録しようとした・・・

netapp95sim::*> vserver cifs create -cifs-server netappcifs -domain ad.osakana.net -ou CN=Computers -vserver netappcifs -netbios-aliases netappcifs

In order to create an Active Directory machine account for the CIFS server, you must supply the name and password of a
Windows account with sufficient privileges to add computers to the "CN=Computers" container within the "AD.OSAKANA.NET"
domain.

Enter the user name: administrator

Enter the password:

Error: Machine account creation procedure failed
  [   215] Loaded the preliminary configuration.
  [   267] Successfully connected to ip 172.17.44.49, port 88 using
           TCP
  [   342] Successfully connected to ip 172.17.44.49, port 636 using
           TCP
  [   379] Required certificate with CA ADSERVER.ad.osakana.net is
           not installed
  [   381] Unable to start LDAPS: Can't contact LDAP server
  [   381] Additional info: error:14090086:SSL
           routines:ssl3_get_server_certificate:certificate verify
           failed
  [   381] Unable to connect to LDAP (Active Directory) service on
           todoroki49.vm2.dtc.co.jp (Error: Can't contact LDAP
           server)
**[   381] FAILURE: Unable to make a connection (LDAP (Active
**         Directory):AD.OSAKANA.NET), result: 7642

Error: command failed: Failed to create the Active Directory machine account "netappcifs". Reason: LDAP Error: Cannot
       contact the LDAP server.

netapp95sim::*>

エラー発生。

なんか調べたところ、active-directoryというコマンドでも登録できるらしいのでそれでもテストしてみる。


netapp95sim::*> active-directory create -vserver netappcifs -account-name adserver -domain ad.osakana.net
  (vserver active-directory create)

In order to create an Active Directory machine account, you must supply the name and password of a Windows account with
sufficient privileges to add computers to the "CN=Computers" container within the "AD.OSAKANA.NET" domain.

Enter the user name: administrator

Enter the password:

Error: Machine account creation procedure failed
  [   179] Loaded the preliminary configuration.
  [   230] Successfully connected to ip 172.17.44.49, port 88 using
           TCP
  [   298] Successfully connected to ip 172.17.44.49, port 636 using
           TCP
  [   333] Required certificate with CA ADSERVER.ad.osakana.net is
           not installed
  [   335] Unable to start LDAPS: Can't contact LDAP server
  [   335] Additional info: error:14090086:SSL
           routines:ssl3_get_server_certificate:certificate verify
           failed
  [   336] Unable to connect to LDAP (Active Directory) service on
           adserver.ad.osakana.net (Error: Can't contact LDAP
           server)
**[   336] FAILURE: Unable to make a connection (LDAP (Active
**         Directory):AD.OSAKANA.NET), result: 7642

Error: command failed: Failed to create the Active Directory machine account "ADSERVER". Reason: LDAP Error: Cannot
       contact the LDAP server.

netapp95sim::*>

同じようにエラー。

この後いろいろ試行錯誤した結果、自己証明CAをNetAppに入れればいいのでは?とやってみた。(「クラスタまたはSVMがクライアントであるSSLサーバを認証するためのサーバCA証明書のインストール」)

netapp95sim::*> security certificate install -vserver netappcifs -type server-ca

Please enter Certificate: Press <Enter> when done
-----BEGIN CERTIFICATE-----
<sambaの/usr/local/samba/private/tls/ca.pemの内容を張り付け>
-----END CERTIFICATE-----


Error: command failed: The certificate has expired.

netapp95sim::*>

ん?「The certificate has expired.」???

samba公式「Configuring LDAP over SSL (LDAPS) on a Samba AD DC」の「Verifying the certificate」に書いてある手法で確認してみます。

# ls -l  /usr/local/samba/private/tls
合計 12
-rw-r--r--. 1 root root 2041  3月 27  2018 ca.pem
-rw-r--r--. 1 root root 2045  3月 27  2018 cert.pem
-rw-------. 1 root root 3243  3月 27  2018 key.pem
#

# openssl verify /usr/local/samba/private/tls/cert.pem -CApath /usr/local/samba/private/tls/ca.pem
/usr/local/samba/private/tls/cert.pem: O = Samba Administration, OU = Samba - temporary autogenerated HOST certificate, CN = ADSERVER.AD.OSAKANA.NET
error 20 at 0 depth lookup:unable to get local issuer certificate
Error opening certificate file -CApath
140285523859344:error:02001002:system library:fopen:No such file or directory:bss_file.c:402:fopen('-CApath','r')
140285523859344:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:404:
unable to load certificate
/usr/local/samba/private/tls/ca.pem: O = Samba Administration, OU = Samba - temporary autogenerated CA certificate, CN = ADSERVER.AD.OSAKANA.NET
error 18 at 0 depth lookup:self signed certificate
O = Samba Administration, OU = Samba - temporary autogenerated CA certificate, CN = ADSERVER.AD.OSAKANA.NET
error 10 at 0 depth lookup:certificate has expired
OK
#

はい。証明書の有効期限切れでした。

手順がめんどいので、/usr/local/samba/private/tlsにあるファイルをリネームしてから「systemctl stop samba-ad-dc.service」「systemctl start samba-ad-dc.service」で強制再作成させました。

rsyncによるディレクトリ同期を行う際、並列実行により高速化する手法


rsyncを高速化するために、分散して実行することにした。

全部を1つのスクリプトとしてもいいのだが、デバグがしやすいように分割して作業を行えるようにしている。

また、下記の記述はLinuxの/usrをコピーすることを想定している。環境に応じて書き換えること。

まず、/usr/xxx以下にあるファイルまでをコピーするために以下を実行する。

# rsync --archive -v --exclude="*/*/" /usr/ /mnt/vol/voltest

このexcludeオプションをつけている場合、「/usr/xxx/yyy」のファイルとシンボリックリンクはコピーされる。しかし「/usr/xxx/zzz/」のディレクトリはコピーされない。

次に、「/usr/xxx/zzz/」のディレクトリ一覧を取得する。

# find /usr -mindepth 2 -maxdepth 2 -type d -print

このディレクトリ一覧を下記のperlスクリプトに食わせる。(下記スクリプトは” find /usr -mindepth 2 -maxdepth 2 -type d -print > list.txt”で取得したlist.txtを使う想定)

#!/usr/bin/perl

use threads;
use Thread::Queue;

my $LOGDIR="/root/test";
my $MAXSESSION=5;

my $sourcepathbase="/usr";
my $destpathbase="/mnt/vol/voltest";

my $stream = Thread::Queue->new;

open(FILE,"list.txt");
while(my $tmp=<FILE>){
        $stream->enqueue("$tmp");

}
close(FILE);

sub SyncExecute{
        while(my $str = $stream->dequeue){
                # 改行削除
                $str =~ s/\n//ig;
                $str =~ s/\r//ig;
                # ログ出力用ファイル名
                my $filename=$str;
                $filename =~ s/\//-/ig;
                $filename =~ s/\.//ig;
                $filename =~ s/-$//ig;
                $filename =~ s/#//ig;
                $filename =~ s/^-//ig;
                $filename =~ s/ //ig;
                my $logfile="$LOGDIR/test-$filename.log";
                # rsync元と先の処理
                my $tmp,$st,$ed;
                my $sourcepath,$destpath;
                $tmp=substr($str,0,1);
                if($tmp eq "/"){
                        $sourcepath=$sourcepathbase.$str."/";
                        $destpath=$destpathbase.$str;
                }else{
                        $sourcepath=$sourcepathbase."/".$str."/";
                        $destpath=$destpathbase."/".$str;
                }
                `date >> $logfile`;
                print "rsync -v --archive $sourcepath $destpath >> $logfile 2>&amp;1 \n";
                `rsync -v --archive $sourcepath $destpath >> $logfile 2>&amp;1 `;
                `date >> $logfile`;
                #`sleep 5`;
        }
}


my @kids;
foreach(1..$MAXSESSION){
        my $kid = threads->new(\&amp;SyncExecute,$stream);
        push(@kids,$kid);
        $stream->enqueue(undef);
}


print "wait\n";

foreach(@kids){
        my ($return) =$_ -> join;
}

このスクリプトは、rsyncの同時実行数5で、並列にrsyncを実行していくものになっている。

実行したサーバの負荷状況に応じて「my $MAXSESSION=5;」で設定している 同時実行数 を調整する。あまり大きくしすぎるとサーバからの応答が遅くなりすぎるのでほどほどに・・・


2020/03/10追記

上記で実行するrsyncコマンドはハードリンクの処理を行わないものとなっている。

このため、ハードリンクされているファイルがある場合、コピー先のファイルが1つではなく複数別個のものとしてコピーされる。

ハードリンクをそのままコピーしたい場合は「–hard-links」オプションを追加する必要があるのだが、ハードリンク処理の効力範囲は同一プロセス内で処理すること、という条件があるため、今回のような分割処理して高速化する、という場合には不適切となっている。

このため、ハードリンクファイルがある場合は、初回同期は分割処理で行い、2回目はディレクトリ全体を–hard-linksオプションをつけて1プロセスで処理してハードリンク処理を行わせる、という手法をとる必要がある。

なお、ハードリンク処理が完了したあと、分割処理の対象となった場合、すでにファイルが存在しているので再コピーされる、ということは発生しない。

ONTAP9でボリューム削除して再作成しようとしたら空き容量がないと言われる


NetApp ONTAP8 7-modeで使用中のボリュームがあり、それをNetApp ONTAP9.5環境に対してtransitionのsnapmirrorを行った。

が・・・元ボリュームがqtree snapmirror中であったため、最後の処理で失敗した。(event log showの結果より)

1/14/2020 05:52:49  netapp95         ERROR         smc.snapmir.init.fail: Initialize from source volume 'netapp7mode:vol211' to destination volume 'netapp95svm:vol211' failed with error 'Transfer failed.'. Relationship UUID 'a3555a83-3360-11ea-a0b6-00a098f844df'.
1/14/2020 05:52:49  netapp95         ERROR         replication.dst.err: SnapMirror: destination transfer from netapp7mode:vol211 to vol211 : replication transfer failed to complete.
1/14/2020 05:52:49  netapp95         ERROR         snapmirror.dst.OnlineErr: SnapMirror not able to bring destination volume vol211 online, CR_TRANS_QTREE_REPLICA.
1/14/2020 05:52:46  netapp95         ERROR         wafl.voltrans.qtree.replica: The source of volume vol211 is a qtree replica. It cannot be transitioned to clustered Data ONTAP.

これについては、元のボリューム(netapp7mode:vol211)が受け側となっているqtree snapmirror全てに対して、「snapmirror quiesce netapp7mode:/vol/vol211/~」 と「snapmirror break netapp7mode:/vol/vol211/~」 を実行し、snapmirrorのステータスが「Broken-off」であれば7mode→ONTAP9へのtransition snapmirrorが成功することを確認。

で、snapmirrorの初期化(snapmirror initialize)にした場合、受け側のボリューム(今回はnetapp95svm:vol211)を削除して、再作成する必要がある。

netapp95上で「snapmirror delete -destination-path netapp95svm:vol211」でsnapmirror登録を消した後、ボリュームを「volume offline -vserver netapp95svm -volume vol211」でオフラインにしてから「volume delete -vserver netapp95svm -volume vol211」 で削除。

そして、「volume create -vserver netapp95svm -volume vol211 -aggregate aggr名 -size 22t -state online -type DP」で作成!

netapp95::> volume create -vserver netapp95svm -volume vol211 -aggregate aggr名 -size 22t -state online -type DP
[Job 351] Job is queued: Create vol211.                                        

Error: command failed: [Job 351] Job failed: Failed to create the volume on
       node "netapp95svm". Reason: Request to create volume "vol211" failed
       because there is not enough space in aggregate "aggr名". Either
       create 10.9TB of free space in the aggregate or select a size of at most
       11.2TB for the new volume. 
netapp95::>

おや?

netapp95::> storage aggregate show
Aggregate     Size Available Used% State   #Vols  Nodes            RAID Status
--------- -------- --------- ----- ------- ------ ---------------- ------------
<略>
aggr名 
           29.41TB   11.29TB   62% online       2 netapp95svm      raid_dp,
                                                                   normal
<略>
netapp95::>

まだ使用中という認識になっている???

いろいろ調べた結果、ONTAP 8.3より導入されたVolume Recovery Queueにより、削除したボリュームは12時間残しておく、という機能によるものだった。

How to use the Volume Recovery Queue feature in clustered Data ONTAP 8.3
How to enable the volume recovery queue in clustered Data ONTAP 8.3
After deleting a volume, the volume is brought offline with type DEL

強制的に削除するにはdiagモードにあるvolume recovery-queue purgeを使用する。

netapp95::> set diag 
Warning: These diagnostic commands are for use by NetApp personnel only.
Do you want to continue? {y|n}: y

netapp95::*> volume recovery-queue show
Vserver   Volume      Deletion Request Time     Retention Hours
--------- ----------- ------------------------  ---------------
netapp95svm vol211_1032_1032 
                      Thu Jan 16 14:33:18 2020               12

netapp95::*> 

上記の「volume recovery-queue show」で現在保持している削除したボリュームを確認できる。

削除は「volume recovery-queue purge -vserver netapp95svm -volume vol211_1032_1032」というような感じで実行する。

netapp95::*> volume recovery-queue purge -vserver netapp95svm -volume vol211_1032_1032 
Queued private job: 251                                                        

netapp95::*> volume recovery-queue show
This table is currently empty.

netapp95::*> 

消えたのでaggregateは復活したはず!!!

netapp95::*> df -A -h
Aggregate                total       used      avail capacity
<略>
aggr名                    29TB       18TB       11TB      61%
aggr名/.snapshot            0B         0B         0B       0%
<略>
netapp95::*>

あれ????

なぜだろー??

なぜだろー???としばらく検索してから、再度実行

netapp95::*> df -A -h
Aggregate                total       used      avail capacity
<略>
aggr名                    29TB       16TB       12TB      57%
aggr名/.snapshot            0B         0B         0B       0%
<略>
netapp95::*> 

おや?空き容量が少し増えてる?

「df -A」の実行に切り替えてみると、徐々に空き容量が増えていっていることが判明。

どうやら内部処理に時間がかかっているだけのようでした。

cluster ONTAP/ONTAP9のNFS exports設定にNISホスト名が使えないのでdnsmasqでごまかすことにした


NetAppのcluster ONTAP8.x/ONTAP9はNISを使える、と書いてあるものの、詳細を確認すると、NISホスト名は使用できず、NISユーザとパスワード、NISグループ、NIS netgroup(ホスト名用のグループ)しか使えないとのこと。

NIS netgroup対応といっても、netgroupに含まれるホスト名にNIS ホスト名が許されるわけではなく、DNS起因のホスト名の使用が許される、というものでした。(ONTAPシミュレータで確認)

既存のDNSサーバにエントリを追加してもらえれば解決ではありますが、できるかどうかわからないので、お手軽にできる回避策として、RHEL6/RHEL7などの標準パッケージ群に含まれているdnsmasqを使用した簡易DNSサーバを立ててみることにした。

dnsmasqは/etc/hostsもしくはhostsフォーマットに準じたファイルを指定して、そこのエントリを元にDNS応答を返すことができる。

NISホスト名を「ypcat hosts」で一括出力するとhostsフォーマットでエントリが取得できるので、crontabで定期的に「ypcat hosts」を実行して情報更新を行い、dnsmasqでDNSで応答を返せるようにした。

まずは、DNSサーバのインストール。

[root@nisclient ~]# yum install dnsmasq
読み込んだプラグイン:fastestmirror
インストール処理の設定をしています
Loading mirror speeds from cached hostfile
 * base: ftp.nara.wide.ad.jp
 * extras: ftp.nara.wide.ad.jp
 * updates: ftp.nara.wide.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> Package dnsmasq.x86_64 0:2.48-18.el6_9 will be インストール
--> 依存性解決を終了しました。

依存性を解決しました

================================================================================
 パッケージ       アーキテクチャ  バージョン                リポジトリー   容量
================================================================================
インストールしています:
 dnsmasq          x86_64          2.48-18.el6_9             base          150 k

トランザクションの要約
================================================================================
インストール         1 パッケージ

総ダウンロード容量: 150 k
インストール済み容量: 294 k
これでいいですか? [y/N]y
パッケージをダウンロードしています:
dnsmasq-2.48-18.el6_9.x86_64.rpm                         | 150 kB     00:00
rpm_check_debug を実行しています
トランザクションのテストを実行しています
トランザクションのテストを成功しました
トランザクションを実行しています
  インストールしています  : dnsmasq-2.48-18.el6_9.x86_64                    1/1
  Verifying               : dnsmasq-2.48-18.el6_9.x86_64                    1/1

インストール:
  dnsmasq.x86_64 0:2.48-18.el6_9

完了しました!
[root@nisclient ~]#

/etc に配置された設定ファイルを確認。

[root@nisclient ~]# ls -l /etc/dnsmasq.*
-rw-r--r--. 1 root root 21214 10月  3 08:18 2017 /etc/dnsmasq.conf

/etc/dnsmasq.d:
合計 0
[root@nisclient ~]#

NISで配布されたhostsを/etc/hosts-from-nisに保存するということにして、/etc/hosts は使用しない、ということにして、/etc/dnsmasq.conf の以下を変更

変更前
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
#no-hosts
# or if you want it to read another file, as well as /etc/hosts, use
# this.
#addn-hosts=/etc/banner_add_hosts
変更後
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
no-hosts
# or if you want it to read another file, as well as /etc/hosts, use
# this.
addn-hosts=/etc/hosts-from-nis

上記以外のエントリは標準設定のままです。NISから配布されたhostsを/etc/hosts-from-nisに保存

[root@nisclient ~]# ypcat hosts > /etc/hosts-from-nis
[root@nisclient ~]# cat /etc/hosts-from-nis
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
172.17.44.100   nfstest
172.17.44.49    server49      server49.vm2.example.com
172.17.44.49    server49      server49.vm2.example.com
172.17.44.87    server87
172.17.44.88    server88
172.17.44.89    server89
[root@nisclient ~]#

続いてfirewalld/iptablesの設定変更して、ポート53のtcp/udpを許可。

[root@nisclient ~]# cat /etc/sysconfig/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
[root@nisclient ~]# service iptables restart
iptables: チェインをポリシー ACCEPT へ設定中filter         [  OK  ]
iptables: ファイアウォールルールを消去中:                  [  OK  ]
iptables: モジュールを取り外し中:                          [  OK  ]
iptables: ファイアウォールルールを適用中:                  [  OK  ]
[root@nisclient ~]#

firewalldの場合は以下

-bash-4.2# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources:
  services: dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

-bash-4.2# firewall-cmd --permanent --zone=public --add-service=dns
success
-bash-4.2# firewall-cmd --reload
success
-bash-4.2# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources:
  services: dhcpv6-client dns ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

-bash-4.2#

で、dnsmasqを起動して、DNSにより名前解決ができるか確認してみます。

[root@nisclient ~]# service dnsmasq status
dnsmasq は停止しています
[root@nisclient ~]# service dnsmasq start
Starting dnsmasq:                                          [  OK  ]
[root@nisclient ~]# service dnsmasq status
dnsmasq (pid  1556) を実行中...
[root@nisclient ~]#

[root@nisclient ~]# nslookup nfstest 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

Name:   nfstest
Address: 172.17.44.100

[root@nisclient ~]#

NetAppのperfstatデータ収集ツールで取得したファイルを分解する


現用のNetAppの状況確認をするために「perfstatデータ収集ツール」というのが配布されている。

rsh/sshで対象のNetAppにログインして、いろんなコマンドを実行して、1つのテキストファイルとして出力をする。

この「1つのテキストファイル」というのがくせ者で、200MBぐらいのファイルができたりする。

これだとエディタで取り扱いづらいので細かく分割することにした。

中をみてみると「=-=-=-=-=-= CONFIG IPアドレス PRESTATS =-=-=-=-=-= aggr status -v」という感じで「 =-=-=-=-=-= 」区切りでファイルが出力されている。

それを元にファイルを分割したのが下記スクリプト。

$inputfile="x:\tmp\source\perfstat7_20191122_1400.txt"
$outdir="x:\tmp\output"

$filename=""

Get-Content $inputfile -Encoding UTF8 | ForEach-Object {
    $line=$_
    if( $line.Contains("=-=-=-=-=-=") ){
        $filename=$line
        $filename=$filename.Replace("=-=-=-=-=-= ","")
        $filename=$filename.Replace("/","-")
        $filename=$filename.Replace(":","")
        $filename=$outdir+"\"+$filename+".txt"
        New-Item $filename
    }
    if($filename -ne ""){
        $line | Add-Content $filename
    }
}

今回は1回しか実行しないので速度を気にする必要がないので簡単さを優先している。

もし、出力速度を気にするのであれば1行毎にAdd-Contentするのは非常に効率が悪いので工夫が必要となる。

参考例:「PowerShellで巨大なファイルをGet-Contentし、Export-Csvするのを省メモリで行う


2019/11/25 追記

上記のスクリプトだと遅すぎで、約200MBのファイル処理に5時間かかりました。

やはり改行のみ行が数万行ある、というのが悪かったようです。

また、同じヘッダ行が何回か登場するようで単純に「New-Item」としているとファイル名が重複しているというエラーがでてしまっていました。

さすがに5時間はないなーということで、高速化処理をしたのが下記となります。

実行にかかる時間は2分と大幅短縮となりました。

$inputfile="x:\tmp\source\perfstat7_20191122_1400.txt"
$outdir="x:\tmp\output2"

$filename=""

$results=@()
$linecount=0

Get-Content $inputfile -Encoding UTF8 | ForEach-Object {
    $line=$_
    if( $line.Contains("=-=-=-=-=-=") ){
        if($filename -ne ""){
            $results | Add-Content $filename
            $results=@()
            $linecount=0
        }
        $filename=$line
        $filename=$filename.Replace("=-=-=-=-=-= ","")
        $filename=$filename.Replace("/","-")
        $filename=$filename.Replace(":","")
        $filename=$outdir+"\"+$filename+".txt"
        if ( !(Test-Path $filename) ){
            New-Item $filename
        }
    }

    if($filename -ne ""){
        $results += $line
        $linecount++
        if(($linecount % 1000) -eq 0 ){
            $results | Add-Content $filename
            $results=@()
        }
    }
}