วิธีที่ต้องการในการจัดเก็บการกำหนดค่าแอปพลิเคชันคืออะไร?


38

ส่วนใหญ่ฉันเก็บการกำหนดค่าแอปพลิเคชันการพัฒนาในไดเรกทอรีรากของโครงการเช่นนี้

app
|-- config.json

แต่นั่นไม่ได้เป็นวิธีที่ดีที่สุดเนื่องจากการกำหนดค่านี้จะถูกเก็บไว้ในระบบควบคุมเวอร์ชัน - อาจส่งผลให้เกิดการรั่วไหลของชื่อผู้ใช้รหัสผ่านและข้อมูลที่ละเอียดอ่อนอื่น ๆ

คู่มือแนะนำแอพ 12 Factorแนะนำให้วางไฟล์กำหนดค่าโดยรวมและใช้ตัวแปรสภาพแวดล้อมสำหรับการตั้งค่า:

... เก็บ config ในตัวแปรสภาพแวดล้อม Env vars สามารถเปลี่ยนแปลงได้ง่ายระหว่าง Deploys โดยไม่ต้องเปลี่ยนรหัสใด ๆ ต่างจากไฟล์ปรับแต่งมีโอกาสน้อยที่จะถูกตรวจสอบลงในรหัสซื้อคืนโดยไม่ได้ตั้งใจ และแตกต่างจากไฟล์ปรับแต่งที่กำหนดเองหรือกลไกการกำหนดค่าอื่น ๆ เช่นคุณสมบัติระบบ Java พวกเขาเป็นมาตรฐานภาษาและระบบปฏิบัติการไม่เชื่อเรื่องพระเจ้า

ฟังดูดีสำหรับฉันจริง ๆ แต่ร้านใดร้านหนึ่งพูดว่าตัวแปรสภาพแวดล้อมโดยไม่ตรวจสอบสิ่งเหล่านั้นลงในการควบคุมแหล่งที่มา? และเครื่องมือใดที่ฉันสามารถใช้เพื่อส่งตัวแปรเหล่านั้นไปยังแอป สามารถมีตัวเลือกการกำหนดค่าได้หลายสิบตัวและพิมพ์ด้วยมือทุกครั้งที่คุณเปิดแอปไม่ดี - ดังนั้นจึงต้องเก็บไว้ในไฟล์บางประเภท ไฟล์ดังกล่าวจะจบลงในการควบคุมแหล่งและเรากลับไปที่ที่เราเริ่ม

มีวิธีจัดการตัวเลือกการกำหนดค่าที่ยอมรับกันโดยทั่วไปหรือไม่ซึ่งไม่มีความเสี่ยงในการจัดเก็บการกำหนดค่าท้องถิ่นในการควบคุมแหล่งที่มา?


1
อย่างน้อย git ก็มีบางอย่าง.gitignoreที่ฉันสามารถกำหนดไฟล์หรือโฟลเดอร์ที่ไม่ควรถูกตรวจสอบในการควบคุมเวอร์ชัน อย่างที่คุณบอกว่าฉันไม่เห็นว่า Env vars ควรช่วยได้จริง ๆ คุณมีสคริปต์ที่จะตั้งค่าและควรเก็บไว้พร้อมกับโครงการหรือคุณมี 'ที่' ไว้ในระบบของคุณ (โฮมไดเร็กตอรี่ สคริปต์) ซึ่งดูเหมือนว่าจะสร้างปัญหามากมายด้วยตัวเองโดยเฉพาะอย่างยิ่งหากจำเป็นต้องกำหนดค่าจำนวนมาก ไม่ว่าในกรณีใดฉันจะแบ่งไฟล์กำหนดค่าเพื่อให้ข้อมูลที่เป็นความลับไปในไฟล์ต่าง
thorsten müller

@ thorstenmüller - ปัญหาเฉพาะกับ. gitignore ที่การตั้งค่าฐาน / แม่แบบยังคงต้องถูกจัดเก็บซึ่งหมายความว่าแอปต้องอ่านการกำหนดค่าสองแบบ - ฐานหนึ่งที่มีตัวเลือกเริ่มต้น (เก็บไว้ใน scm) และท้องถิ่นที่แทนที่ฐาน (และ ไม่ได้เก็บไว้ใน scm) ด้วย env vars ฉันคิดว่าการปรับใช้จำนวนมากทำได้ง่ายขึ้น - การระบุตัวแปรสภาพแวดล้อมสำหรับการตั้งค่าเครื่องเสมือนใหม่ง่ายกว่าการเขียนบางอย่างลงในไฟล์ที่ไม่ได้มาตรฐาน
Rogach

เป็นคำถามที่ดีหลังจากที่ฉันเริ่มใช้แหล่งข้อมูลแอปพลิเคชันเฉพาะสำหรับผู้ใช้ทั่วไปสิ่งนี้กลายเป็นชีวิตง่ายขึ้น ;-)
Wolf

1
คุณลอง "Redis" redis.ioแล้วหรือยัง มันมีความหมายเป็นพิเศษสำหรับการจัดเก็บโครงสร้างค่าคีย์เท่านั้น
Karan

2
@ jporcenaluk - ฉันชอบที่เก็บคีย์ - ค่า แต่เพิ่ม redis แบบเต็มไปยังแอปพลิเคชันเพียงเพื่อจัดการการจัดการการตั้งค่ารู้สึกเหมือน overkill เล็กน้อย ในทางกลับกันบางทีฉันอาจไม่เคยทำงานในโครงการที่ใหญ่พอ
Rogach

คำตอบ:


16

อาจเป็นไปได้ว่าไม่มีคำตอบที่ดีสำหรับเรื่องนี้ ดูเหมือนว่าคุณจะต้องเก็บข้อมูลนี้ไว้ในที่ปลอดภัยเนื่องจากจะต้องใช้เพื่อวัตถุประสงค์ในการกู้คืนจากความเสียหายในหนึ่งวัน สิ่งนี้ใช้ได้กับไฟล์คุณสมบัติและสคริปต์ที่ตั้งค่าตัวแปรสภาพแวดล้อม

  • ด้วยซอร์สโค้ด (ใน SVN / GIT ฯลฯ ) เป็นความคิดที่ไม่ดีจริงๆเนื่องจากข้อมูลนี้จะมีรหัสผ่านฐานข้อมูลการผลิตและอื่น ๆ
  • การสำรองข้อมูลรายคืนขององค์กรของคุณอาจเพียงพอ แต่ก็ไม่น่าจะทำให้มีการเปลี่ยนแปลงที่เข้าถึงได้ง่าย
  • ข้อมูลจะต้องมีการแยกรุ่นเป็นซอฟต์แวร์ที่ใช้งานแยกต่างหาก ในระบบปัจจุบันของเราการเปลี่ยนแปลงการกำหนดค่านำไปสู่การสร้างแอปพลิเคชันใหม่และนี่เป็นเพียงความผิดปกติ

ขณะนี้เรากำลังค้นหาวิธีแก้ไขปัญหานี้และกำลังโน้มตัวไปยังที่เก็บรหัสที่มีการ จำกัด การเข้าถึง ที่เก็บนี้จะมีข้อมูลการกำหนดค่าเท่านั้น คนอื่นมีประสบการณ์แบ่งปันหรือไม่


2
การมีที่เก็บสองแห่งแยกกันสำหรับโครงการหนึ่งดูเหมือนว่าไม่ใช่ความคิดที่ดี - คุณไม่สามารถทำความสะอาดการย้อนกลับหรือทำงานกับสาขาได้เพราะจากนั้นคุณจะต้องจัดการกับที่เก็บสองแห่งพร้อมกัน (เช่นสาขาอื่น ๆ ต้องการตัวเลือกการกำหนดค่าใหม่ สลับไปที่สาขาใหม่นั้นโดยไม่ต้องสลับในที่เก็บการตั้งค่าสิ่งที่แตกในรูปแบบแปลก ๆ )
Rogach

2
@Rogach ฉันจะใช้จุดของคุณ มีเหตุผลที่ถูกต้องในการเก็บการกำหนดค่าด้วยรหัส แต่ตามที่คุณพูดในคำถามของคุณสิ่งที่ละเอียดอ่อนต้องไปที่อื่น ดังนั้นที่เก็บสองแห่งจึงดูเหมือนหลีกเลี่ยงไม่ได้ นอกจากนี้ฉันไม่ได้พูดถึงว่าแอพเซิร์ฟเวอร์มักจะช่วยเหลือที่นี่ ผู้ดูแลระบบสามารถตั้งค่าแหล่งข้อมูลและตัวแปร JNDI และจะไม่เปิดเผยต่อสาธารณะ
kiwiron

ร้านค้าที่สองทำให้รู้สึก อาจมีข้อมูลประเภทอื่น ๆ ที่เป็นความลับซึ่งอาจถูกจัดเก็บพร้อมกับการกำหนดค่า (เช่นข้อมูลการผลิตที่อยู่ระหว่างการวิเคราะห์เพื่อแก้ไขปัญหาของลูกค้า)
Wolf

1
@Rogach ดูเหมือนว่าพวกเขาจะดึงดูดความเกลียดชังได้มาก แต่ submodules คอมไพล์จะจัดการเรื่องนี้ได้ดีฉันคิดว่า - หากมีการตั้งค่าหลักที่เหมาะสมและ repo access ที่ จำกัด สามารถอยู่ข้างในได้
SeldomNeedy

9

ในการตรวจสอบปัญหาและแนวทางแก้ไขที่เป็นไปได้มันช่วยให้ฉันใช้วิธีที่นิยมโดย Jeff Atwood : ถ้าพระเจ้าต้องสร้างวิธีเก็บข้อมูลการกำหนดค่าที่ละเอียดอ่อนเขาจะทำอย่างไร

เขาจะรู้ว่าใครต้องการข้อมูลการกำหนดค่าและให้เฉพาะกับคนเหล่านั้นเท่านั้นและคนอื่น ๆ จะไม่สามารถเข้าถึงข้อมูลได้

ส่วนแรกควรได้รับการดูแล: ระบบควบคุมแหล่งข้อมูลของคุณควรตรวจสอบสิทธิ์ผู้ใช้ และวิธีการนี้ได้รับความถูกต้องตาม # 10 ในบัญญัติ 10 ประการของการควบคุมแหล่งที่มาของ Troy Hunt "การพึ่งพาต้องอยู่ในการควบคุมแหล่งที่มา"

แต่จะรักษาความปลอดภัยอย่างไรถ้ามันรั่ว? ไม่จำเป็นต้องเก็บไว้ในรูปแบบข้อความธรรมดา! ใช้การเข้ารหัส ใน. NET มีขั้นตอนที่คุณสามารถใช้เพื่อเข้ารหัสข้อมูลสตริงการเชื่อมต่อในไฟล์ปรับแต่งของคุณ คุณจะต้องหาวิธีการที่เทียบเท่ากับเทคโนโลยีที่คุณเลือก


3
แค่ต้องการชี้แจง - การกำหนดค่าการเข้ารหัสจะช่วยได้อย่างไร ตามที่ฉันเข้าใจคุณจะต้องเปิดเผยรหัสผ่านการถอดรหัสลับเดียวกันระหว่างนักพัฒนาทั้งหมดและฟังดูเหมือนเป็นการเรียกร้องให้เกิดปัญหา
Rogach

หากมีบุคคลภายนอก บริษัท ของคุณเข้าถึงที่เก็บของคุณรหัสผ่านของคุณจะสับสน หากมีคนคัดลอกไฟล์จากโครงการไปยังไดรฟ์ USB และปล่อยไว้ที่อื่นสิ่งเดียวกัน แน่นอนว่าจะต้องมีการบำรุงรักษามากขึ้น การรักษาความปลอดภัยมักจะมาในราคาที่สะดวก วิธีแก้ปัญหานี้ค่อนข้างไม่แน่นอนฉันจะให้คุณ ฉันเปิดให้วิธีที่ดีกว่าในการแก้ปัญหาของ OP!
jporcenaluk

5

หลายคนวิพากษ์วิจารณ์การจัดเก็บการกำหนดค่าในไฟล์ปกติพร้อมกับซอร์สโค้ดของคุณ แต่จากประสบการณ์ของฉันนี่เป็นทางออกที่ดีจริงๆ:

  • ง่ายต่อการใช้งานในภาษาใด ๆ ในหลาย ๆ คุณได้รับการสนับสนุนสำหรับไฟล์การกำหนดค่าที่ซับซ้อนนอกกรอบ เช่นในกรณีของ Java ที่มี Spring Boot คุณจะได้รับการสนับสนุนจาก YAML ซึ่งสามารถแสดงโครงสร้างแบบต้นไม้และเป็นเรื่องง่ายที่จะมีไฟล์กำหนดค่าแยกต่างหากสำหรับสภาพแวดล้อมที่แตกต่างกันรวมถึงการกำหนดค่าพื้นฐานซึ่งไฟล์เฉพาะสภาพแวดล้อมสามารถสืบทอดได้
  • จำเป็นต้องใช้การกำหนดค่าเพื่อเรียกใช้ซอฟต์แวร์ของคุณและการเปลี่ยนแปลงรหัสมักจะต้องมีการเพิ่ม / แก้ไขการตั้งค่าการกำหนดค่าดังนั้นจึงเป็นเรื่องปกติที่จะต้องมีการกำหนดค่าและรหัสไว้ด้วยกัน
  • การจัดเก็บการกำหนดค่าด้วยซอร์สจะให้ประโยชน์ทั้งหมดของการควบคุมซอร์สเช่นการรู้ว่าใครแก้ไขการตั้งค่าใดและเมื่อใดหรือสามารถตรวจสอบการกำหนดค่าระหว่างการตรวจสอบรหัสปกติ
  • ถ้าคุณไม่ทำงานให้กับ CIA ข้อโต้แย้งเรื่องความปลอดภัยก็ดูเหมือนจะคลุมเครือกับฉัน ดังนั้นรหัสผ่านฐานข้อมูลของคุณจะถูกเก็บไว้ในไฟล์บนเครื่องที่แอพของคุณทำงาน ถ้ามีคนเข้าถึงเครื่องด้วยแอพของคุณคุณอาจมีปัญหามากมายแล้ว - พวกเขาสามารถลบแอพของคุณและเริ่มแอพของตัวเองในพอร์ตเดียวกัน ในสถานการณ์ดังกล่าวการเข้าถึงรหัสผ่านฐานข้อมูลอาจไม่ใช่ปัญหาใหญ่ เว้นแต่ว่าการเชื่อมต่อทั้งหมดของคุณจะถูกเข้ารหัสอย่างสมบูรณ์มีการเข้าถึงเครื่องของคุณพวกเขาสามารถดมกลิ่นข้อมูลที่น่าสนใจจากอินเทอร์เฟซเครือข่ายได้
  • คุณสามารถใช้เครื่องมือเช่นHieraเพื่อมีไฟล์การกำหนดค่าที่เป็นข้อความ แต่ไม่สามารถจัดเก็บรหัสผ่านหรือข้อมูลที่สำคัญอื่น ๆ ไว้ภายใน

ดังนั้นในหลายกรณีการกำหนดค่าที่เป็นข้อความที่เก็บไว้ในการควบคุมแหล่งที่มาพร้อมกับรหัสเป็นการเริ่มต้นที่ดี

หากคุณเข้าสู่ระบบแบบกระจายหรือต้องการให้สามารถกำหนดค่า hot-swap ได้โดยไม่ต้องปรับใช้แอปพลิเคชันของคุณใหม่คุณอาจพบโซลูชันที่ใช้เซิร์ฟเวอร์การกำหนดค่าที่ดีกว่า ฤดูใบไม้ผลิเมฆมีการสนับสนุนสำหรับกลไกดังกล่าวและแบ็กเอนด์ที่ให้บริการในการกำหนดค่าอาจจะเป็นที่เก็บคอมไพล์หรือยูเรก้า นอกจากนี้คุณยังสามารถม้วนของคุณเองโดยใช้เช่นZookeeper วิธีใด ๆ เหล่านี้จะทำให้ง่ายต่อการจัดการการกำหนดค่าที่สอดคล้องกันบนเซิร์ฟเวอร์จำนวนมากเพื่ออัปเดตการกำหนดค่าโดยไม่ต้องสร้างและปรับใช้ซอฟต์แวร์ของคุณอีกครั้ง สิ่งนี้มีค่าใช้จ่ายแน่นอนซึ่งเป็นการเรียนรู้เซิร์ฟเวอร์การกำหนดค่าและวิธีการใช้งานจากแอปพลิเคชันของคุณรวมถึงระบบอื่นในการปรับใช้และบำรุงรักษา


แต่รหัสจะเปลี่ยนมือให้คนที่ไม่ได้เป็นเจ้าของความลับในไฟล์ปรับแต่งนั่นจะเป็นเรื่องยุ่งเหยิงจริง
Tim Ludwinski

@TimLudwinski คีย์ / ความลับเป็นของ บริษัท ไม่ใช่นักพัฒนารายบุคคลดังนั้นพวกเขาจึงควรได้รับการดูแลในลักษณะที่พวกเขาจะไม่หลงทางหากบุคคลใด ๆ ออกไป พวกเขาอาจมีปัญหาและดูแลโดยผู้ดูแลระบบ / ทีมรักษาความปลอดภัยเพื่อให้มีรีจิสทรีกลาง
Michał Kosmulski

5

เรากำลังต่อสู้กับปัญหาเดียวกันกับที่ฉันทำงาน ตอนนี้การกำหนดค่าทั้งหมดของเรานั้นใช้ไฟล์และแหล่งควบคุมด้วยแอพพลิเคชั่นแต่ละตัวที่ใช้ สิ่งนี้นำไปสู่การทำซ้ำและเพื่อนักพัฒนาที่สามารถเข้าถึงรหัสผ่านการใช้งานจริง / qa แทนที่จะเป็นเพียงการพัฒนา

ที่กล่าวว่าฉันคิดว่าเราได้มาด้วยทางออกที่ดีในอนาคต เรากำลังย้ายไฟล์ปรับแต่งของเราไปยัง repo git แยกกัน (ชื่อ repo config) จากนั้นเราตั้งค่าเซิร์ฟเวอร์ spring-cloud-config (java) ซึ่งจะให้บริการไฟล์จาก repo config ตามโปรไฟล์ที่ส่งผ่านไป เหมาะสำหรับแอปพลิเคชัน Java ซึ่งสามารถใช้ไคลเอนต์และดาวน์โหลดได้ในเวลาเริ่มต้น สำหรับแอพ PHP / ที่ไม่ใช่จาวาเราจะดึงไฟล์ลงมาโดยตรง (ไม่เหมาะ) ในอนาคตเราอาจจะเขียนบางสิ่งที่ช่วยให้แอปพลิเคชั่น PHP ดาวน์โหลดการกำหนดค่าด้วยตัวเองและทำการแคชไว้ที่ใดที่หนึ่ง ฉันคิดว่าโซลูชันนี้เป็น config-as-a-service ซึ่งไม่ได้ละเมิดคำแนะนำของแอพ 12 ปัจจัยอย่างชัดเจน

ฉันเชื่อว่า zookeeper สามารถใช้กับสิ่งเดียวกันได้ (ฉันเห็นการตั้งค่าด้วย kubernetes + zookeeper) ดังนั้นฉันจึงไม่แน่ใจว่าทำไมคำตอบนั้นถึง -1 ข้างต้น

ลิงค์:

https://spring.io/guides/gs/centralized-configuration/

https://cloud.spring.io/spring-cloud-config/


3

แทนที่จะเก็บการกำหนดค่าทั้งหมดไว้ในไฟล์เดียวให้เก็บไว้ในหลายไฟล์

  • มีการกำหนดค่าไดเรกทอรี README*ไฟล์ทั้งหมดที่มีจะถูกตีความเป็นแฟ้มการกำหนดค่าอาจจะยกเว้น
  • ชื่อไฟล์ทั้งหมดจะถูกจัดเรียงตามตัวอักษรและไฟล์จะถูกโหลดตามลำดับ 01-logging.jsonนี่คือเหตุผลที่ไฟล์ในกรณีดังกล่าวมักจะเริ่มต้นด้วยหลักหรือสอง: 02-database.jsonฯลฯ
  • ข้อมูลจากไฟล์ทั้งหมดจะถูกโหลดลงในโครงสร้างการกำหนดค่าเดียวกันกับแอปพลิเคชัน นี่คือจำนวนไฟล์ที่สามารถเสริมการตั้งค่าของกันและกันและยังแทนที่ไฟล์เหล่านั้นด้วยวิธีที่คาดการณ์ได้
  • เก็บเฉพาะไฟล์ VCS ที่มีค่า safe-to-see หรือค่าเริ่มต้นใน VCS เท่านั้น เพิ่มไฟล์ปรับแต่งด้วยความลับระหว่างการปรับใช้หรือดีกว่าใช้บริการเก็บข้อมูลความลับที่ผ่านการตรวจสอบแล้ว

บนกล่องลินุกซ์ใกล้ที่สุดของคุณจะดูที่หรือ/etc/sudoers.d /etc/nginx/conf.dมันแสดงให้เห็นรูปแบบเดียวกัน

การจัดการความลับเป็นสัตว์ร้ายที่แตกต่างกัน คุณสามารถจัดการพวกเขาเป็นขั้นตอนด้วยตนเองในขณะที่คุณยังเล็ก คุณสามารถใช้สิ่งต่าง ๆ เช่นผู้ดูแลสัตว์ คุณสามารถตรวจสอบความลับลงใน VCS ในรูปแบบที่เข้ารหัสและถอดรหัสพวกเขาเป็นขั้นตอนการปรับใช้ มีตัวเลือกอื่น ๆ อีกจำนวนหนึ่ง

(นอกจากนี้ชิ้นความคิดเห็น: JSON ไม่ใช่รูปแบบไฟล์กำหนดค่าที่ดีเพราะไม่อนุญาตให้แสดงความคิดเห็นความคิดเห็นมีความสำคัญ TOML, YAML และแม้กระทั่งรูปแบบ INI จะใช้งานได้ดีกว่า)


2

ฉันคิดว่าตัวเลือกของคุณจะถูกกำหนดโดยระบบปฏิบัติการที่คุณกำลังปรับใช้

ฉันอยากจะแนะนำใช่ใส่ค่าในการควบคุมแหล่งที่มา แต่เฉพาะรุ่น 'dev' คุณต้องการให้ซอร์สโค้ดรวบรวมและทำงาน! ไม่รวมขั้นตอนลับพิเศษ

กระบวนการสร้างและปรับใช้ของคุณควรสลับค่าเหล่านี้ตามสภาพแวดล้อมในระหว่างการปรับใช้ (ปลาหมึกยักษ์มีรูปแบบนี้)


0

Apache zookeeper มีตัวเลือกที่ยอดเยี่ยมในการจัดเก็บการกำหนดค่าแอปพลิเคชันสำหรับระบบกระจาย การเปลี่ยนแปลงที่ทำกับผู้ดูแลระบบสามารถบันทึกและประมวลผลได้โดยมีภัณฑารักษ์หรือผู้ดูแลผู้ดูแลในตอนท้ายของแอปพลิเคชัน


6
ตัวเลือกคืออะไร? มันทำงานยังไง? มันเก็บไว้ที่ไหน เป็นที่ต้องการมากกว่าอีกไหม ข้อดีและข้อเสียต่าง ๆ ของแต่ละตัวเลือกมีอะไรบ้าง? สิ่งนี้จะทำงานกับระบบปฏิบัติการที่แตกต่างกันอย่างไร

3
@Gangz - ฉันจะสนใจคำตอบที่ละเอียดกว่านี้โปรดอย่าท้อแท้จาก downvotes และปรับปรุงคำตอบของคุณเพื่อให้สามารถช่วยเหลือได้
Jay Elston
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.