Biorąc pod uwagę popularność naszego postu na temat łączenia MongoDB SSL z samopodpisanymi certyfikatami w Node.js, postanowiliśmy napisać samouczek dotyczący łączenia MongoDB z Ruby. W tym blogu pokażemy, jak połączyć się z serwerem MongoDB skonfigurowanym z samopodpisanymi certyfikatami dla SSL przy użyciu zarówno sterownika Ruby MongoDB, jak i popularnego mongoidu Object-Document-Mapper (ODM).
ScaleGrid obecnie używa certyfikatów z podpisem własnym dla SSL podczas tworzenia węzłów dla nowego klastra. Dodatkowo zapewniamy również możliwość zakupu własnych certyfikatów SSL i skonfigurowania ich na serwerze MongoDB, a także możesz wysłać e-mail na adres [email protected], aby dowiedzieć się więcej o tej ofercie.
Podłączanie do zestawu replik przy użyciu sterownika Ruby MongoDB
W tym przykładzie użyjemy najnowszego stabilnego sterownika Ruby MongoDB w wersji 2.8. Wersje sterownika 2.5.x mają znany błąd, który uniemożliwia im pracę z wdrożeniami ScaleGrid. Wersja Ruby użyta w obu poniższych przykładach to 2.6.3.
Opcje połączenia dostępne dla sterownika są udokumentowane tutaj, a opcje, których będziemy potrzebować, to:
- :ssl
- :ssl_verify
- :ssl_ca_cert .
Najpierw znajdź i skopiuj parametry połączenia MongoDB ze strony szczegółów klastra w konsoli ScaleGrid:
Plik certyfikatu CA jest również dostępny do pobrania ze strony szczegółów klastra. Pobierz i zapisz plik certyfikatu w lokalizacji dostępnej dla aplikacji:
Oto fragment pokazujący, jak połączyć się z zestawem replik MongoDB z Ruby:
require 'mongo'Mongo::Logger.logger.level =::Logger::DEBUGMONGODB_CA_CERT ="/ścieżka/do/ca_cert.pem"MONGODB_CONN_URL ="mongodb://testuser:@SG-przykład- 17026.servers.mongodirector.com:27017,SG-example-17027.servers.mongodirector.com:27017,SG-example-17028.servers.mongodirector.com:27017/test?replicaSet=RS-example-0&ssl=true" options ={ ssl:true, ssl_verify:true, :ssl_ca_cert => MONGODB_CA_CERT }client =Mongo::Client.new(MONGODB_CONN_URL, options)db =client.databasecollections =db.collection_namesputs "db ma #{#.name} {kolekcje}"klient.zamknij
Aby zachować prostotę przykładu, określiliśmy parametry połączenia i ścieżkę do pliku certyfikatu bezpośrednio we fragmencie kodu — zazwyczaj umieszczasz je w pliku yaml lub podajesz jako Zmienne środowiska. Ponadto przykład ustawia poziom dziennika na DEBUG
aby można było debugować wszelkie problemy z łącznością. Po rozwiązaniu problemów z łącznością należy go zmienić na mniej gadatliwy.
Jak połączyć MongoDB z aplikacją Ruby za pomocą SSLClick To Tweet
Łączenie za pomocą Mongoid
Wersja mongoid, której użyjemy w naszym przykładzie, to najnowsza stabilna wersja – 7.0.2. Użyjemy pliku yaml, aby dostarczyć konfigurację do mongoid, a szczegóły takiego pliku konfiguracyjnego są udokumentowane tutaj. Opcje konfiguracji specyficzne dla SSL, które będziemy musieli połączyć z naszym zestawem replik, to:
- ssl
- ssl_verify
- ssl_ca_cert
Nasz plik yml:
development:# Konfiguracja dostępnych klientów bazy danych. (wymagane) klienci:# Zdefiniuj klienta domyślnego. (wymagane) default:# Można zdefiniować uri dla klienta:# uri:'mongodb://użytkownik:hasł[email protected]:27017/my_db' # Szczegóły można znaleźć w dokumentacji sterownika. Alternatywnie możesz zdefiniować:# # Zdefiniuj nazwę domyślnej bazy danych, z którą Mongoid może się połączyć. # (wymagany). database:test # Podaj hosty, z którymi domyślny klient może się połączyć. Musi być tablicą # par host:port. (wymagane) hosty:- SG-example-17026.servers.mongodirector.com:27017 - SG-example-17027.servers.mongodirector.com:27017 - SG-example-17028.servers.mongodirector.com:47100 opcje:# Nazwa użytkownika do uwierzytelnienia. użytkownik:„użytkownik testowy” # Hasło użytkownika do uwierzytelnienia. hasło:„hasło” # Role bazy danych użytkownika. role:- 'readWrite' # Zmiana domyślnego mechanizmu uwierzytelniania. Prawidłowe opcje to::scram, # :mongodb_cr, :mongodb_x509 i :plain. (domyślnie w 3.0 jest :scram, domyślnie w 2.4 i 2.6 jest :plain) auth_mech::scram # Baza danych lub źródło do uwierzytelnienia użytkownika. (domyślnie:admin) źródło_uwierzytelniania:test # Wymuś na sterowniku połączenie w określony sposób zamiast auto- # wykrywania. Może być jednym z::direct, :replica_set, :sharded. Ustaw na :direct # podczas łączenia się z ukrytymi członkami zestawu replik. connect::replica_set ... ... # Nazwa zestawu replik do połączenia. Serwery dostarczone jako seedy, które nie należą # do tego zestawu replik, zostaną zignorowane. zestaw_replik:RS-przykład-0 # Czy łączyć się z serwerami przez ssl. (domyślnie:false) ssl:prawda # Czy przeprowadzać walidację certyfikacji równorzędnej. (domyślnie:prawda) ssl_verify:prawda # Plik zawierający zestaw połączonych certyfikatów urzędu certyfikacji # używany do sprawdzania poprawności certyfikatów przekazanych z drugiego końca połączenia. ssl_ca_cert:/ścieżka/do/ca_cert.pem # Skonfiguruj konkretne opcje Mongoid. (opcjonalne) opcje:# Ustaw poziomy dziennika sterownika Mongoid i Ruby. (domyślnie::info) log_level::debug
Przykład połączenia:
gem 'mongoid', '7.0.2'require 'mongoid'Mongoid.load!("/path/to/mongoid.yml", :development)# Nie używam żadnej z funkcji ODM - po prostu pobierz podstawowe mongo klient i próba połączeniaclient =Mongoid::Clients.defaultdb =client.databasecollections =db.collection_namesputs "db #{db.name} ma kolekcje #{collections}"Mongoid::Clients.disconnect
Ponownie, w produkcyjnych aplikacjach Ruby on Rails ścieżka do pliku yaml zostałaby pobrana ze zmiennych środowiskowych.
Testowanie zachowania awaryjnego
Podobnie jak inne sterowniki MongoDB, sterownik Ruby MongoDB jest również zaprojektowany do wewnętrznego rozpoznawania zmian w topologii spowodowanych zdarzeniami, takimi jak przełączanie awaryjne. Jednak dobrze jest przetestować i zweryfikować zachowanie sterownika podczas przełączania awaryjnego, aby uniknąć niespodzianek w środowisku produkcyjnym.
Podobnie jak mój poprzedni post na MongoDB PyMongo, możemy napisać program do ciągłego testowania zapisu, aby obserwować zachowanie awaryjne sterownika.
Najłatwiejszym sposobem wywołania przełączenia awaryjnego jest uruchomienie polecenia rs.stepDown():
RS-example-0:PRIMARY> rs.stepDown()2019-04-18T19:44:42.257+0530 E QUERY [wątek1] Błąd:błąd podczas wykonywania zapytania:nie powiodło się:błąd sieci podczas próby uruchomienia polecenia „replSetStepDown” na hoście „SG-example-1.servers.mongodirector.com:27017” :DB.prototype.runCommand@src/mongo/shell/db.js:168:1DB.prototype.adminCommand@src/mongo/shell/db. js:185:1rs.stepDown@src/mongo/shell/utils.js:1305:12@(shell)::12019-04-18T19:44:42.261+0530 I SIEĆ [thread1] próbuję ponownie połączyć się z przykładem SG -1.servers.mongodirector.com:27017 (X.X.X.X) nie powiodło się2019-04-18T19:44:43.267+0530 I SIEĆ [wątek1] ponownie połącz SG-przykład-1.servers.mongodirector.com:27017 (X.X.X.X) okRS-przykład- 0:DRUGORZĘDNY>
Oto odpowiednie części naszego kodu testowego:
wymagaj 'mongo'...logger =Logger.new(STDOUT)logger.level =Logger::INFOMONGODB_CA_CERT ="/ścieżka/do/ca_cert.pem"MONGODB_CONN_URL ="mongodb://testuser:@ SG-example-17026.servers.mongodirector.com:27017,SG-example-17027.servers.mongodirector.com:27017,SG-example-17028.servers.mongodirector.com:27017/test?replicaSet=RS-example- 0&ssl=true"options ={ ssl:true, ssl_verify:true, :ssl_ca_cert => MONGODB_CA_CERT }begin logger.info("Próba połączenia...") client =Mongo::Client.new(MONGODB_CONN_URL, options) i =0 pętli do db =client.database collection =db[:test] begin doc ={"idx":i, "date":DateTime.now, "text":SecureRandom.base64(3) } wynik =collection.insert_one( doc) logger.info("Rekord wstawiony - id:#{result.inserted_id}") i +=1 sleep(3) rescue Mongo::Error => e logger.error("Mong Error seen:#{e.message }") logger.error(e.backtrace) logger.i nfo("Retrying...") end end logger.info("Done")rescue => err logger.error("Wyjątek:#{err.message}") logger.error(err.backtrace)ensure client. zamknij, chyba że client.nil?end
To stale zapisuje takie wpisy w kolekcji testów w testowej bazie danych:
RS-test-0:PRIMARY> db.test.find(){ "_id" :ObjectId("5cf50ff1896cd172a4f7c6ee"), "idx" :0, "data" :ISODate("2019-06-03T12:17 :53.008Z"), "text" :"HTvd" }{ "_id" :ObjectId("5cf50ff6896cd172a4f7c6ef"), "idx" :1, "data" :ISODate("2019-06-03T12:17:58.697Z" ), "text" :"/e5Z" }{ "_id" :ObjectId("5cf50ff9896cd172a4f7c6f0"), "idx" :2, "data" :ISODate("2019-06-03T12:18:01.940Z"), " text" :"quuw" }{ "_id" :ObjectId("5cf50ffd896cd172a4f7c6f1"), "idx" :3, "data" :ISODate("2019-06-03T12:18:05.194Z"), "text" :" gTyY" }{"_id" :ObjectId("5cf51000896cd172a4f7c6f2"), "idx" :4, "data" :ISODate("2019-06-03T12:18:08.442Z"), "tekst" :"VDXX" }{ "_id" :ObjectId("5cf51003896cd172a4f7c6f3"), "idx" :5, "data" :ISODate("2019-06-03T12:18:11.691Z"), "text" :"UY87" }...
Zobaczmy zachowanie podczas przełączania awaryjnego:
Ja, [2019-06-03T17:53:25.079829 #9464] INFO -- :Próba połączenia...I, [2019-06-03T17:53:30.577099 #9464] INFO -- :Wstawiono rekord - id:5cf5113f896cd124f8f31062I, [2019-06-03T17:53:33.816528 #9464] INFO -- :Rekord wstawiony - id:5cf51145896cd124f8f31063I, [2019-06-03T17:53:37.047043 #9464] INFO -- :Rekord wstawiony - id:5cf51148896cd124f8f31064I, [2019-06-03T17:53:40.281537 #9464] INFO -- :Rekord wstawiony - id:5cf5114c896cd124f8f31065I, [2019-06-03T17:53:43.520010 #9464] INFO -- :Rekord wstawiony - id:5cf51148114f8963 [2019-06-03T17:53:46.747080 #9464] INFO -- :Wstawiony rekord - id:5cf51152896cd124f8f31067I, [2019-06-03T17:53:49.978077 #9464] INFO -- :Wstawiony rekord - id:5cf51155896cd124f8f31068 <<Oczywiste jest, że jeśli zostaną wykryte poprawne błędy i ponowna próba odczytu/zapisu, sterownik automatycznie wykryje zmianę topologii i ponownie połączy się z nowym masterem. W przypadku zapisów opcja :retry_writes upewnij się, że sterownik sam spróbuje jeszcze raz, zanim powiadomi aplikację o błędzie.
Istnieje również wiele limitów czasu dla sterowników, które można dostosować w oparciu o dokładne zachowanie i opóźnienie widoczne w konfiguracji. Są one udokumentowane tutaj.
Rozwiązywanie problemów
Jeśli masz problemy z połączeniem z wdrożeniem MongoDB z obsługą SSL, oto kilka wskazówek dotyczących debugowania:
- Najpierw sprawdź, czy rzeczywiście możesz połączyć się z serwerem MongoDB z serwera, na którym działa Twoja aplikacja. Najprostszym sposobem na to jest zainstalowanie powłoki mongo na komputerze klienta. W systemie Linux nie musisz instalować całego serwera MongoDB — możesz po prostu zainstalować powłokę osobno. Gdy powłoka będzie dostępna, spróbuj użyć „Składni wiersza poleceń”, którą udostępniamy, aby spróbować połączyć się z serwerem.
- Jeśli nie możesz połączyć się przez powłokę mongo, oznacza to, że maszyna klienta nie może połączyć się z portem 27017 serwerów MongoDB. Sprawdź ustawienia swojej grupy bezpieczeństwa, VPC i zapory ScaleGrid, aby upewnić się, że istnieje łączność między komputerami klienckimi i serwerowymi.
- Jeśli łączność sieciowa jest prawidłowa, następną rzeczą do sprawdzenia jest to, że używasz wersji Ruby, mongoid i mongo gem, które są kompatybilne z tą wersją Twojego serwera MongoDB.
- Jeśli potwierdziłeś, że wersje sterowników są poprawne, spróbuj uruchomić przykładowy skrypt Ruby, podobny do przykładu, który podaliśmy powyżej, na IRB. Wykonanie krok po kroku może wskazać, gdzie jest problem.
- Jeśli skrypt testowy działa poprawnie, ale nadal nie możesz połączyć się z mongoid, spróbuj uruchomić prosty skrypt testowy, taki jak podany powyżej przykład .
- Jeśli nadal masz problemy z połączeniem ze swoją instancją, napisz do nas na adres [email protected] ze szczegółowymi wynikami powyższych kroków rozwiązywania problemów oraz z dokładne wersje sterowników Ruby, mongoid i mongo, których używasz. Gemfile.lock zapewni ci dokładne wersje.
Jeśli jesteś nowy w ScaleGrid i chcesz wypróbować ten samouczek, zarejestruj się, aby uzyskać bezpłatną 30-dniową wersję próbną, aby poznać platformę i przetestować podłączenie MongoDB do aplikacji Ruby.