يشرح هذا الدليل كيفية تشفير عنقود ClickHouse بالكامل: إصدار شهادة باستخدام cert-manager، وتمكين TLS على العنقود، وتوصيل عميل عبر المنافذ الآمنة، وتوسيع نطاق التشفير ليشمل حركة تنسيق Keeper.
وهو دليل عملي موجّه للمهام. للاطلاع على مرجع تفصيلي لكل حقل في spec.settings.tls، راجع
Configuration → TLS/SSL configuration
ومرجع واجهة برمجة التطبيقات.
المتطلبات الأساسية
- عنقود ClickHouse قيد التشغيل ويديره المشغِّل (راجع المقدمة).
- تثبيت cert-manager في العنقود.
- امتلاك صلاحية وصول
kubectlإلى حيّز اسم العنقود.
لا يُنشئ المشغِّل الشهادات بنفسه، بل يستخدم مورد Kubernetes من نوع
Secret توفّره أنت. ويُعد cert-manager الطريقة الموصى بها لإنشاء هذا
الـ Secret وتدويره، لكن أي أداة تكتب Secret بالتنسيق المتوقع ستفي بالغرض.
كيف يتوقع المُشغِّل الشهادات
يُفعَّل TLS من خلال توجيه spec.settings.tls.serverCertSecret إلى Secret يحتوي على
زوج مفاتيح الخادم:
| مفتاح الـ Secret | المحتويات | مطلوب |
|---|---|---|
tls.crt |
شهادة الخادم المرمّزة بتنسيق PEM | نعم |
tls.key |
المفتاح الخاص المرمّز بتنسيق PEM | نعم |
وهذا هو نفس التنسيق الذي يكتبه cert-manager تمامًا لمورد Certificate، لذلك لا
تحتاج إلى أي تحويل. ويقوم المُشغِّل بربط زوج المفاتيح داخل كل كبسولة عند
/etc/clickhouse-server/tls/ وتهيئته ضمن إعداد openSSL في ClickHouse.
الخطوة 1 — التهيئة الأولية لـ CA باستخدام cert-manager
أكثر إعدادات التهيئة قابليةً للتكرار هو استخدام CA موقَّعة ذاتيًا لتوقيع شهادة
الخادم لاحقًا. يوفّر لك ذلك ملف ca.crt مستقرًا يمكن للعملاء الوثوق به.
# A self-signed issuer used only to mint the CA certificate
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-bootstrap
namespace: <namespace>
spec:
selfSigned: {}
---
# The CA certificate itself
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: clickhouse-ca
namespace: <namespace>
spec:
isCA: true
commonName: clickhouse-ca
secretName: clickhouse-ca
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-bootstrap
kind: Issuer
---
# A CA issuer that signs leaf certificates from the CA above
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: clickhouse-ca-issuer
namespace: <namespace>
spec:
ca:
secretName: clickhouse-caفي بيئة الإنتاج، استبدل Bootstrap الموقَّع ذاتيًا بجهة الإصدار الفعلية لديك (مثل CA مؤسسية، أو Vault، أو ACME، وما إلى ذلك). لا تتغير سوى الخطوة 2 — أما ربط العنقود فمتطابق.
الخطوة 2 — إصدار شهادة الخادم
اطلب شهادة طرفية من الجهة المُصدِرة لـ CA. يجب أن تغطي dnsNames عناوين
الوصول التي يستخدمها العملاء للكبسولات. ينشئ المشغّل خدمة headless واحدة باسم
<cluster-name>-clickhouse-headless، ويمكن الوصول إلى كل كبسولة نسخة متماثلة عبر
<cluster-name>-clickhouse-<shard>-<index>-0.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local.
ويغطي استخدام wildcard على نطاق خدمة headless جميع النسخ المتماثلة:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: clickhouse-server
namespace: <namespace>
spec:
secretName: clickhouse-cert # <-- the Secret the operator will read
duration: 8760h # 1 year
renewBefore: 720h # rotate 30 days early
issuerRef:
name: clickhouse-ca-issuer
kind: Issuer
dnsNames:
- "*.<cluster-name>-clickhouse-headless.<namespace>.svc"
- "*.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local"
- "localhost"ينشئ cert-manager مورد Secret باسم clickhouse-cert ويضم tls.crt وtls.key و
ca.crt، ويحدّثه قبل انتهاء صلاحيته. تحقّق من وجوده:
kubectl -n <namespace> get secret clickhouse-cert -o jsonpath='{.data}' | jq 'keys'
# ["ca.crt","tls.crt","tls.key"]الخطوة 3 — تمكين TLS على العنقود
وجّه العنقود إلى كائن Secret:
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
name: <cluster-name>
namespace: <namespace>
spec:
settings:
tls:
enabled: true
required: true # disable the insecure ports entirely
serverCertSecret:
name: clickhouse-certما الذي يفعله المشغّل
عندما تكون tls.enabled: true، فإن المشغّل:
- يفتح المنافذ الآمنة على كل كبسولة وعلى خدمة headless:
9440(TLS أصلي) و8443(HTTPS). وتُضاف هذه المنافذ إلى جانب المنافذ الحالية. - يربط كائن Secret عند
/etc/clickhouse-server/tls/ويُنشئ مقطعopenSSLفي ClickHouse معverificationMode: relaxed، وdisableProtocols: sslv2,sslv3، وpreferServerCiphers: true. وهذه هي القيم الافتراضية — راجع تخصيص إعدادات TLS لتجاوزها.
وعندما تضبط أيضًا required: true، فإن المشغّل يقوم بالإضافة إلى ذلك بما يلي:
- يزيل المنافذ غير الآمنة
9000(native) و8123(HTTP) — ولا تبقى إلا النسخ العاملة عبر TLS، لذا لن يعود بإمكان العملاء غير المشفّرين الاتصال. - يحوّل مسبار الحيوية للكبسولة إلى المنفذ الآمن
9440الخاص بـ native، بحيث يستمر فحص الحالة في العمل من دون مستمع غير مشفّر.
الخطوة 4 — الاتصال عبر TLS
مع required: true، يجب على برامج العميل استخدام المنافذ الآمنة والوثوق بـ CA. وجّه
الاتصال إلى كبسولة نسخة متماثلة محددة عبر خدمة headless (أو خدمة ClusterIP
الخاصة بك إذا كنت قد أنشأت واحدة).
البروتوكول الأصلي (clickhouse-client, المنفذ 9440):
clickhouse-client --secure \
--host <cluster-name>-clickhouse-0-0-0.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local \
--port 9440 \
--ca-certificate /path/to/ca.crt \
--query "SELECT 1"HTTPS (المنفذ 8443):
curl --cacert /path/to/ca.crt \
"https://<cluster-name>-clickhouse-0-0-0.<cluster-name>-clickhouse-headless.<namespace>.svc.cluster.local:8443/?query=SELECT%201"استخرج ca.crt مباشرةً من الـ Secret للاختبار المحلي:
kubectl -n <namespace> get secret clickhouse-cert \
-o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crtتشفير حركة المرور إلى Keeper
إن تفعيل TLS على عنقود ClickHouse لا يشفّر الاتصال بـ Keeper.
فعِّل ذلك على KeeperCluster بشكل مستقل — أصدر شهادة لخدمة Keeper
(الخطوتان 1–2 مع dnsNames الخاصة بخدمة Keeper) وأشِر إليها:
apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
name: <keeper-name>
namespace: <namespace>
spec:
settings:
tls:
enabled: true
required: true
serverCertSecret:
name: keeper-certيكشف Keeper عن منفذ العميل الآمن على 2281. وبمجرد تفعيل TLS في Keeper، يتصل
عنقود ClickHouse به عبر TLS تلقائيًا — من دون أي إعداد إضافي على جانب
ClickHouseCluster. ويتحقق ClickHouse من شهادة Keeper بالاستناد إلى
مخزن الثقة الخاص بالنظام، بالإضافة إلى أي caBundle تقوم بتهيئته.
حزمة CA مخصصة
يتحقق ClickHouse افتراضيًا من الجهات النظيرة التي يتصل بها (النسخ المتماثلة الأخرى، وKeeper، ومصادر القواميس عبر HTTPS،
وS3، …) بالرجوع إلى مخزن الثقة في النظام. ولإضافة الثقة أيضًا إلى
CA خاصة — سواء كانت موقَّعة ذاتيًا أو داخلية ولا تكون شهادتها الجذرية موجودة في مخزن النظام —
وفّر caBundle:
spec:
settings:
tls:
enabled: true
serverCertSecret:
name: clickhouse-cert
caBundle:
name: <ca-secret-name>
key: ca.crtيقوم المشغِّل بربط هذه الحزمة وإضافتها إلى مخزن الثقة الخاص بعميل openSSL
(caConfig). يظل مخزن الثقة الخاص بالنظام ساريًا — وتصبح CA الخاصة بك موثوقًا بها بالإضافة
إلى الجذور العامة، لذلك تظل الاتصالات بنقاط النهاية العامة تعمل. وفي
إعداد موقَّع ذاتيًا، وجّه caBundle إلى المفتاح ca.crt في كائن Secret نفسه الذي أنشأه cert-manager
(كما في المثال cluster_with_ssl).
تخصيص إعدادات TLS
إن مقطع openSSL الذي يُنشئه المشغّل هو إعداد افتراضي، وليس حدًا أقصى. ويُكتب
في تهيئة الخادم الرئيسية؛ وأي شيء ضمن spec.settings.extraConfig يُضاف إلى
config.d/99-extra-config.yaml، ثم يدمجه ClickHouse أخيرًا — لذلك يتجاوز
القيم المُولَّدة.
لتشديد الإعدادات الافتراضية — على سبيل المثال، فرض تحقّق صارم من النظير ورفع
الحد الأدنى للبروتوكول إلى TLS 1.2 — عيّن مفاتيح openSSL.server التي تريد تغييرها:
spec:
settings:
extraConfig:
openSSL:
server:
verificationMode: strict
disableProtocols: "sslv2,sslv3,tlsv1,tlsv1_1"يتم الدمج على مستوى كل مفتاح: لا تُستبدل إلا القيم التي تضبطها، بينما تُحفَظ المفاتيح المُنشأة التي
لا تذكرها (مسارات الشهادات، إعدادات CA). راجع
إعدادات خادم openSSL
للاطلاع على الخيارات المتاحة، و
التهيئة → التهيئة الإضافية المضمّنة
لمعرفة كيفية دمج extraConfig.
التحقق واستكشاف الأخطاء وإصلاحها
تأكد من أن المنافذ الآمنة مفعّلة على خدمة headless:
kubectl -n <namespace> get svc <cluster-name>-clickhouse-headless \
-o jsonpath='{.spec.ports[*].name}'
# expect: ... tcp-secure http-secure (and NO tcp/http when required: true)تأكد من أن الشهادة مربوطة داخل الكبسولة:
kubectl -n <namespace> exec <pod> -- ls /etc/clickhouse-server/tls/
# clickhouse-server.crt clickhouse-server.key (plus custom-ca.crt when caBundle is set)| العَرَض | السبب المُرجَّح |
|---|---|
| تفشل الكبسولات في التشغيل / خطأ في ربط وحدة التخزين بعد تمكين TLS | مورد Secret المشار إليه مفقود أو يفتقر إلى tls.crt/tls.key (أو، عند ضبط caBundle، إلى الـ Secret/المفتاح الذي يشير إليه). لا يتحقق المشغّل من محتويات الـ Secret — وتظهر المفاتيح المفقودة على شكل فشل في ربط وحدة تخزين الكبسولة، وليس كحالة status مخصّصة. افحص الكبسولة باستخدام kubectl describe pod. |
| يرفض الـ webhook العنقود | تم تعيين required: true بدون enabled: true، أو enabled: true بدون serverCertSecret. |
certificate verify failed لدى العميل |
العميل لا يثق في CA. مرّر ca.crt من الـ Secret، أو تحقّق من أن dnsNames في الشهادة تغطي المضيف الذي تتصل به. |
| يتعذّر فجأة على عميل plaintext الاتصال | أدّت required: true إلى إزالة المنفذين 9000/8123. بدّل العميل إلى 9440/8443، أو عيّن required: false للإبقاء على المنافذ غير الآمنة مفتوحة أثناء الترحيل. |
انظر أيضًا
- التهيئة → تهيئة TLS/SSL — مرجع الحقول
- التهيئة →
additionalPorts— المنافذ المحجوزة - مرجع واجهة برمجة التطبيقات → ClusterTLSSpec
- إعدادات الخادم
openSSL— خيارات TLS التي يمكنك تجاوزها عبرextraConfig