Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

دليل تهيئة ClickHouse Operator

يوضح هذا الدليل كيفية تهيئة مجموعات ClickHouse وKeeper باستخدام المشغّل.

إعداد ClickHouseCluster

الإعداد الأساسي

apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: my-cluster
spec:
  replicas: 3           # Number of replicas per shard
  shards: 2             # Number of shards
  keeperClusterRef:
    name: my-keeper     # Reference to KeeperCluster
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 10Gi

النسخ المتماثلة والشظايا

  • النسخ المتماثلة: عدد مثيلات ClickHouse لكل شظية (لتحقيق التوفّر العالي)
  • الشظايا: عدد التقسيمات الأفقية (لأغراض التوسّع)
spec:
  replicas: 3  # Default: 3
  shards: 2    # Default: 1

سيُنشئ عنقود يحتوي على replicas: 3 وshards: 2 ما مجموعه 6 كبسولات لـ ClickHouse.

تكامل Keeper

يجب أن يشير كل عنقود ClickHouse إلى KeeperCluster من أجل التنسيق:

spec:
  keeperClusterRef:
    name: my-keeper
    # namespace: keeper-system  # Optional, defaults to the ClickHouseCluster namespace

عند تعيين keeperClusterRef.namespace، يجب على المشغِّل مراقبة مساحتي الاسم كلتيهما. وإذا كان WATCH_NAMESPACE مُعدًّا، فأدرِج مساحتي الاسم الخاصتين بـ ClickHouse وKeeper في تلك القائمة.

إعداد KeeperCluster

apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
  name: my-keeper
spec:
  replicas: 3  # Must be odd: 1, 3, 5, 7, 9, 11, 13, or 15
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 5Gi

تهيئة التخزين

قم بتهيئة التخزين الدائم باستخدام dataVolumeClaimSpec، وهو PersistentVolumeClaimSpec قياسي في Kubernetes. يحوّله المُشغِّل إلى PersistentVolumeClaim لكل نسخة متماثلة يتم ربطه على مسار البيانات /var/lib/clickhouse:

spec:
  dataVolumeClaimSpec:
    storageClassName: fast-ssd  # Optional: consider your storage class based on the installed CSI
    resources:
      requests:
        storage: 100Gi

يغطي الدليل المخصّص للتخزين ووحدات التخزين إرفاق أقراص إضافية ضمن تهيئة متعددة الأقراص (JBOD)، والتشغيل من دون وحدة تخزين دائمة، وتوسيع السعة، وسياسات التخزين المخصّصة، وتشفير البيانات المخزّنة، والقواعد التي تحدد ما لا يمكن تغييره بعد الإنشاء.

نطاق العنقود

يحدِّد spec.clusterDomain لاحقة DNS في Kubernetes التي يستخدمها المشغِّل عند إنشاء أسماء المضيفين المؤهلة بالكامل للكبسولات التي يكتبها في إعدادات خادم ClickHouse. وتكون القيمة الافتراضية هي cluster.local، وهو موجود في كلٍّ من ClickHouseCluster وKeeperCluster.

spec:
  clusterDomain: cluster.local   # default; override only for a custom domain

بالنسبة إلى النسخ المتماثلة في ClickHouse، ينشئ المشغِّل خدمة عديمة الرأس حاكمة باسم <cluster-name>-clickhouse-headless لتخدم حركة مرور العملاء. كما ينشئ خدمات لكل نسخة متماثلة باسم <cluster-name>-clickhouse-internal-<shard>-<index> تنشر الكبسولات غير الجاهزة لحركة المرور الداخلية وطلبات الإدارة من المشغِّل. يمكن استخدامها لاستعادة النسخة المتماثلة إذا لم تتمكن من أن تصبح جاهزة بنفسها.

تستخدم عقد Keeper أسماء الكبسولات عبر خدمتها عديمة الرأس: <pod>.<headless-service>.<namespace>.svc.<clusterDomain>.

إعدادات الكبسولة

التوزيع الطوبولوجي والتقارب التلقائيان

وزّع الكبسولات عبر مناطق التوافر:

spec:
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname

الإعداد اليدوي

يمكن تحديد قواعد مخصّصة لتقارب/تنافر الجرابات وقيود توزيع الطوبولوجيا.

spec:
  podTemplate:
    affinity:
      <your-affinity-rules-here>
    topologySpreadConstraints:
      <your-topology-spread-constraints-here>

راجع مرجع واجهة برمجة التطبيقات للاطلاع على جميع الخيارات المدعومة لقوالب الـ Pod.

ميزانيات تعطيل الكبسولات

ينشئ المشغّل مورد PodDisruptionBudget ‏(PDB) لكل عنقود، بحيث لا تتسبب الاضطرابات الطوعية — مثل تفريغ العقد، وعمليات الترقية المتدرجة، وعمليات الإخلاء التي ينفذها المُوسّع التلقائي — في إسقاط عدد كافٍ من الكبسولات بما يؤدي إلى فقدان quorum أو الإخلال بالتوافر.

بالنسبة إلى عناقيد ClickHouse التي تضم أكثر من شظية واحدة، يتم إنشاء PDB واحدة لكل شظية حتى لا يُحتسب الاضطراب في شظية واحدة ضمن شظية أخرى.

القيم الافتراضية

يحدّد المشغّل قيماً افتراضية آمنة بناءً على حجم العنقود، بحيث توفّر عملية apply الجديدة بالفعل حماية من فقدان النصاب بالخطأ.

المورد البنية قيمة PDB الافتراضية
ClickHouseCluster replicas: 1 (شظية أحادية النسخة المتماثلة) maxUnavailable: 1 — يُسمح بالتعطيل في عنقود أحادي العقدة حتى لا يتم حظر تفريغ العقدة
ClickHouseCluster replicas: 2+ (شظية متعددة النسخ المتماثلة) minAvailable: 1 — يجب أن تظل نسخة متماثلة واحدة على الأقل لكل شظية قيد التشغيل
KeeperCluster replicas: 1 maxUnavailable: 1 — يُسمح بالتعطيل في عنقود أحادي العقدة حتى لا يتم حظر تفريغ العقدة
KeeperCluster replicas: 3+ maxUnavailable: replicas/2 — يحافظ على quorum الخاص بـ RAFT في عنقود 2F+1 (يمكن لـ 3 نسخ متماثلة تحمّل تعطل نسخة واحدة، ويمكن لـ 5 نسخ متماثلة تحمّل تعطل نسختين)

بالنسبة إلى ClickHouseCluster مكوّن من 3 شظايا مع replicas: 3، ينشئ المشغّل ثلاثة PDBs، واحداً لكل شظية، بحيث يكون لكل منها minAvailable: 1.

تجاوز القيم الافتراضية

استخدم spec.podDisruptionBudget لتجاوز minAvailable أو maxUnavailable (واحد منهما فقط):

spec:
  replicas: 3
  shards: 2
  podDisruptionBudget:
    minAvailable: 2   # keep at least 2 of 3 replicas in every shard up during a disruption

أو بصيغة maxUnavailable، مع نسبة مئوية:

spec:
  replicas: 5
  podDisruptionBudget:
    maxUnavailable: 40%

يمكنك أيضًا تمرير الحقل unhealthyPodEvictionPolicy إلى PDB الذي يتم إنشاؤه — ويكون ذلك مفيدًا عندما تحتاج إلى السماح بإخلاء الكبسولات التي لا تزال في حالة NotReady:

spec:
  podDisruptionBudget:
    minAvailable: 2
    unhealthyPodEvictionPolicy: AlwaysAllow

السياسات

يتيح لك spec.podDisruptionBudget.policy اختيار مدى صرامة إدارة المشغّل لـ PDBs:

Policy Behavior
Enabled (default) ينشئ المشغّل PDB ويحدّثه في كل عملية مواءمة. هذا هو الإعداد الافتراضي الآمن لبيئات الإنتاج.
Disabled لا ينشئ المشغّل أي PDBs، ويقوم بحذف أي PDBs موجودة تحمل labels مطابقة. يفيد ذلك في عناقيد التطوير التي ينبغي فيها السماح بكل تعطيل طوعي.
Ignored لا ينشئ المشغّل PDBs ولا يحذفها. وتُترك PDBs الموجودة كما هي. استخدم هذا الخيار عندما يتولى نظام آخر (مثل policy admission أو أداة GitOps) إدارة PDBs نيابةً عنك.

مثال — عطّل إدارة PDB بالكامل على عنقود تطوير:

spec:
  podDisruptionBudget:
    policy: Disabled

مثال — احتفِظ بـ PDB الذي أنشأته يدويًا بجوار العنقود وامنع المشغّل من التعامل معه:

spec:
  podDisruptionBudget:
    policy: Ignored

التعطيل على مستوى العنقود بالكامل

يمكن أيضًا تعطيل إدارة PDB على مستوى العنقود بالكامل عبر متغير البيئة ENABLE_PDB الخاص بالمشغّل. عند ضبط ENABLE_PDB=false، يتجاوز المشغّل خطوة التسوية الخاصة بـ PDB لكل ClickHouseCluster وKeeperCluster، بغض النظر عن spec.podDisruptionBudget.policy الخاصة بهما، ولا يراقب موارد PodDisruptionBudget مطلقًا. لذلك، لا يحتاج ServiceAccount الخاص بالمشغّل إلى أذونات RBAC على poddisruptionbudgets.policy/v1، وهو ما يفيد عند تشغيل المشغّل باستخدام ServiceAccount مقيّد يستبعد تلك الأذونات عمدًا.

# in the operator Deployment spec
env:
- name: ENABLE_PDB
  value: "false"

هذا مخصّص للبيئات التي تعتمد سياسات التعطيل الخاصة بها (مثلًا عبر Gatekeeper / Kyverno) ولا تريد أي تدخّل من المشغّل على الإطلاق.

تكوين الحاوية

صورة حاوية مخصّصة

استخدم صورة حاوية محددة لـ ClickHouse:

spec:
  containerTemplate:
    image:
      repository: clickhouse/clickhouse-server
      tag: "25.12"
    imagePullPolicy: IfNotPresent

موارد الحاويات

اضبط CPU والذاكرة لحاويات ClickHouse:

# default values
spec:
  containerTemplate:
    resources:
      requests:
        cpu: "250m"
        memory: "512Mi"
      limits:
        cpu: "1"
        memory: "512Mi"

متغيرات البيئة

أضِف متغيرات بيئة مخصّصة:

spec:
  containerTemplate:
    env:
    - name: CUSTOM_ENV_VAR
      value: "1"

ربط وحدات التخزين

أضف عمليات ربط إضافية لوحدات التخزين:

spec:
  containerTemplate:
    volumeMounts:
    - name: custom-config
      mountPath: /etc/clickhouse-server/config.d/custom.xml
      subPath: custom.xml

راجع مرجع واجهة برمجة التطبيقات للاطلاع على جميع خيارات قوالب الحاويات المدعومة.

إعدادات TLS/SSL

تهيئة نقاط نهاية آمنة

مرّر مرجعًا إلى Kubernetes Secret يحتوي على شهادات TLS لتمكين نقاط النهاية الآمنة

spec:
  settings:
    tls:
      enabled: true
      required: true # Insecure ports are disabled if set
      serverCertSecret:
        name: <certificate-secret-name>

تنسيق Secret الخاص بشهادة SSL

من المتوقع أن يحتوي Secret على زوج الشهادة والمفتاح الخاص بالخادم:

  • tls.crt - شهادة الخادم بترميز PEM
  • tls.key - المفتاح الخاص بترميز PEM

اتصال ClickHouse-Keeper عبر TLS

إذا كان TLS مفعّلًا في KeeperCluster، فسيستخدم ClickHouseCluster اتصالًا آمنًا بعُقد Keeper تلقائيًا.

يتحقق ClickHouseCluster من شهادات عُقد Keeper باستخدام مخزن الثقة في النظام، بالإضافة إلى أي caBundle تقوم بتهيئته.

للثقة في CA خاصة (على سبيل المثال، CA موقعة ذاتيًا أو داخلية)، قدّم مرجعًا إلى حزمة CA مخصصة:

spec:
    settings:
        tls:
          caBundle:
            name: <ca-certificate-secret-name>
            key: <ca-certificate-key>

External Secret

ينشئ المشغّل افتراضيًا مورد Secret ويتولى إدارته، ويحتوي هذا المورد على بيانات الاعتماد الداخلية للعنقود (كلمة مرور الاتصال بين الخوادم، وكلمة مرور الإدارة، وهوية Keeper، وسرّ العنقود، ومفتاح named-collections). ويحمل هذا الـ Secret اسم العنقود ويقع ضمن مساحة اسم العنقود.

إذا كنت تريد إدارة بيانات الاعتماد هذه بنفسك — على سبيل المثال، بتوفيرها من HashiCorp Vault أو AWS Secrets Manager أو External Secrets Operator — فاجعل المشغّل يشير إلى Secret موجود مسبقًا باستخدام spec.externalSecret:

apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: sample
spec:
  replicas: 2
  keeperClusterRef:
    name: sample
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 10Gi
  externalSecret:
    name: my-clickhouse-credentials
    policy: Observe

المفاتيح المطلوبة

يجب أن يحتوي Secret على المفاتيح التالية:

المفتاح التنسيق متى يكون مطلوبًا
interserver-password كلمة مرور بنص صريح دائمًا
management-password كلمة مرور بنص صريح دائمًا
keeper-identity clickhouse:<password> دائمًا
cluster-secret كلمة مرور بنص صريح دائمًا
named-collections-key مفتاح AES بترميز سداسي عشري بطول 16 بايت (32 محرفًا سداسيًا عشريًا) فقط في ClickHouse >= 25.12
disk-encryption-key مفتاح AES بترميز سداسي عشري بطول 16 بايت (32 محرفًا سداسيًا عشريًا) فقط عند تعيين settings.encryption

يكون Secret الكامل كما يلي:

apiVersion: v1
kind: Secret
metadata:
  name: my-clickhouse-credentials
  namespace: sample
type: Opaque
stringData:
  interserver-password: "a-strong-random-password"
  management-password: "another-strong-password"
  keeper-identity: "clickhouse:keeper-auth-password"
  cluster-secret: "cluster-internal-secret"
  named-collections-key: "0123456789abcdef0123456789abcdef"   # 32 hex chars = 16 bytes
  disk-encryption-key: "00112233445566778899aabbccddeeff"     # only when settings.encryption is set

السياسة: المراقبة مقابل الإدارة

يتحكم spec.externalSecret.policy في كيفية تعامل المشغّل مع المفاتيح المطلوبة الناقصة:

السياسة السلوك عند غياب المفاتيح
Observe (الافتراضي) تُعلَّق التسوية حتى يصبح كل مفتاح مطلوب موجودًا. ويُبلّغ المشغّل عن كل مفتاح ناقص — وتلميح التنسيق الخاص به — عبر الحالة ExternalSecretValid (بالسبب ExternalSecretInvalid) وحدث Warning.
Manage يُولِّد المشغّل أي مفاتيح مطلوبة ناقصة ويكتبها مجددًا إلى كائن Secret نفسه. وهذا مفيد للتهيئة الأولية: أنشئ كائن Secret فارغًا، ودَع المشغّل يملؤه، ثم شدِّد الوصول اختياريًا. ومع ذلك، لا يحذف المشغّل كائن Secret مطلقًا.

اختر Observe عندما يكون النظام الخارجي (Vault أو ESO أو sealed-secrets أو GitOps) هو مصدر الحقيقة وتريد أن يُخفق المشغّل بوضوح عند وجود خطأ في الإعداد. واختر Manage عندما تريد تهيئة أولية مكتفية ذاتيًا، مع الاحتفاظ بملكية كائن Secret نفسه (على سبيل المثال، لأخذ نسخة احتياطية منه).

شرط الحالة واستكشاف الأخطاء وإصلاحها

يعرض المشغِّل شرط ExternalSecretValid ضمن ClickHouseCluster.status.conditions. افحصه عندما يبدو أن عملية التسوية عالقة:

# Plain kubectl — works out of the box
kubectl describe clickhousecluster sample | sed -n '/Conditions:/,$p'

# Same data as YAML
kubectl get clickhousecluster sample -o yaml | sed -n '/conditions:/,/^[^ ]/p'

# Pretty-printed JSON (requires jq)
kubectl get clickhousecluster sample -o jsonpath='{.status.conditions}' | jq

الأسباب المحتملة:

reason المعنى الإصلاح
ExternalSecretNotFound كائن Secret المشار إليه غير موجود في مساحة الاسم. أنشئ كائن Secret، أو صحّح spec.externalSecret.name.
ExternalSecretInvalid كائن Secret موجود، لكنه يفتقر إلى المفاتيح المطلوبة (فقط مع Observe). تسرد الرسالة كل مفتاح مفقود مع التنسيق المتوقع له. أضف المفاتيح المفقودة، أو بدّل إلى policy: Manage.
ExternalSecretValid جميع المفاتيح المطلوبة موجودة، والمشغّل يستخدم كائن Secret.

يعيد المشغّل إدراج عملية التسوية في قائمة الانتظار ما دام كائن Secret غير صالح، لذا بمجرد إضافة المفاتيح المفقودة ستلتقطها عملية التسوية التالية تلقائيًا — ولا حاجة إلى إعادة تشغيل الـ pods.

منافذ إضافية

يكشف المشغّل مجموعة ثابتة من المنافذ على كل Pod لـ ClickHouse وعلى الخدمة عديمة الرأس العامة الخاصة به: 8123 لـ HTTP، و9000 لـ أصلي، و9009 للاتصال بين الخوادم، و9001/9002 للإدارة، و9363 لمقاييس Prometheus، بالإضافة إلى منافذ TLS البديلة 8443/9440 عند تمكين TLS. كما تُكشف منافذ interserver والإدارة عبر الخدمات الداخلية لكل نسخة متماثلة، بحيث تتمكن النسخ المتماثلة والمشغّل من التواصل قبل أن تصبح النسخة المتماثلة جاهزة. لجعل ClickHouse يستمع إلى بروتوكولات إضافية — مثل MySQL أو PostgreSQL أو gRPC أو أي منفذ مخصّص — عرِّفها في spec.additionalPorts:

spec:
  additionalPorts:
    - name: mysql
      port: 9004
    - name: postgres
      port: 9005
    - name: grpc
      port: 9100

يضيف المشغّل هذه المنافذ إلى containerPorts الخاصة بالـ Pod وإلى الخدمة عديمة الرأس العامة. ويمكن العثور على المثال الكامل في examples/custom_protocols.yaml.

مثال متكامل: MySQL wire protocol

لإتاحة ClickHouse عبر MySQL wire protocol على المنفذ 9004:

apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: sample
spec:
  replicas: 1
  keeperClusterRef:
    name: sample
  dataVolumeClaimSpec:
    resources:
      requests:
        storage: 2Gi

  # 1) Open the port on the Pod and the public headless Service.
  additionalPorts:
    - name: mysql
      port: 9004

  # 2) Tell ClickHouse server to actually listen on it.
  settings:
    extraConfig:
      protocols:
        mysql:
          type: mysql
          port: 9004
          description: "MySQL wire protocol"

بعد تطبيق ذلك، تحقّق من داخل الكتلة:

kubectl exec sample-clickhouse-0-0-0 -- \
  clickhouse-client --port 9004 --query "SELECT 1"

قيود الحقول

الحقل القاعدة
name يجب أن يطابق النمط DNS_LABEL^[a-z]([-a-z0-9]*[a-z0-9])?$، على ألا يتجاوز 63 حرفًا. ويُفرض التفرد بواسطة CRD باستخدام مفتاح list-map.
port عدد صحيح ضمن [1, 65535]. يرفض webhook أرقام المنافذ المكررة داخل القائمة.

المنافذ والأسماء المحجوزة

يرفض الـ webhook الخاص بالتحقق إدخالات additionalPorts التي قد تتعارض مع المنافذ التي يستخدمها المشغّل نفسه. جميع المنافذ المرتبطة بـ TLS محجوزة دون قيد أو شرط حتى لا يؤدي تبديل spec.settings.tls.enabled لاحقًا إلى تعطيل عنقود كان صالحًا سابقًا.

المنفذ محجوز لـ
8123 HTTP
8443 HTTPS
9000 TCP الأصلي
9440 TLS الأصلي
9009 بين الخوادم
9001 الإدارة
9363 مقاييس Prometheus

تُرفض أيضًا الأسماء التالية — فهي معرّفات المشغّل الداخلية لأنواع البروتوكولات (وليست الأسماء المستعارة المفهومة للبشر):

الاسم
http
http-secure
tcp
tcp-secure
interserver
management
prometheus

ينتج عن الطلب المرفوض خطأ مثل:

spec.additionalPorts[0].port: 8123 is reserved for the operator-managed HTTP port
spec.additionalPorts[0].name: "http" is reserved by the operator

فحص الإصدار وقناة الترقية

ينفّذ المشغّل مهمتين مستقلتين تتعلقان بإصدارات العنقود:

  1. الإبلاغ عن الإصدار — بالنسبة إلى ClickHouseCluster، يشغّل مورد Kubernetes Job صورة الحاوية مرة واحدة لاكتشاف إصدار ClickHouse قيد التشغيل؛ وبالنسبة إلى KeeperCluster، يقرأ المشغّل الإصدار الذي يبلّغ به الخادم من النسخ المتماثلة قيد التشغيل. ويُسجَّل الإصدار المكتشف في .status.version وتستخدمه خطوات التسوية الأخرى (على سبيل المثال، لا يكون مفتاح named-collections الخاص بـ External Secret مطلوبًا إلا بدءًا من ClickHouse 25.12).
  2. قناة الترقية — تحقّق دوري من موجز إصدارات ClickHouse العام (https://clickhouse.com/data/version_date.tsv). ويبلّغ المشغغّل عمّا إذا كان إصدار أحدث متاحًا عبر شرط الحالة VersionUpgraded. وهو لا يرقّي العنقود من تلقاء نفسه مطلقًا — فالمستخدم هو من يتحكّم في وسم الصورة.

اختيار قناة الترقية

يحدِّد spec.upgradeChannel مجموعة الإصدارات الصادرة من المشروع الأصلي التي يقارن بها المشغّل. ويوجد الحقل نفسه في كلٍّ من ClickHouseCluster وKeeperCluster.

spec:
  upgradeChannel: lts   # or "stable", or "25.8", or omitted

القيم المسموح بها (التي يتحقق منها CRD باستخدام النمط ^(lts|stable|\d+\.\d+)?$):

القيمة السلوك
empty (default) لا يقترح المُشغِّل إلا التحديثات الثانوية ضمن خط major.minor الرئيسي/الثانوي الجاري تشغيله حاليًا. وسيُبلَّغ العنقود الذي يعمل على 25.8.3.1 بوجود 25.8.4.x، ولكن ليس 25.9.x.
stable يتتبع قناة stable في المصدر الأصلي — أي أحدث إصدار تضع عليه ClickHouse Inc. علامة الاستقرار ضمن خط الإصدار الرئيسي. ويتلقى ترقيات رئيسية في وقت أبكر من قناة lts.
lts يتتبع قناة lts في المصدر الأصلي — أي إصدارات الدعم طويل الأمد. ويتلقى ترقيات رئيسية بوتيرة أقل، مع فترات دعم أطول.
25.8 (or any <major>.<minor>) يثبّت القناة على خط major.minor محدد. ولا تُقترح ترقيات رئيسية تتجاوزه حتى إذا كان هناك إصدار أحدث متاح في المصدر الأصلي.

في بيئات الإنتاج، يُفضَّل عمومًا تثبيت القناة على قيمة <major>.<minor> صريحة (مثل 25.8). فهذا يقيّد العنقود بخط الإصدار الرئيسي المقصود، ويتيح للمُشغِّل إظهار تحذير WrongReleaseChannel إذا انجرفت أي نسخة متماثلة، لسبب ما، إلى إصدار رئيسي مختلف — وهو أمر يكتسب أهمية خاصة عندما يُشار إلى الصورة بواسطة digest (@sha256:...) بدلًا من tag مقروء بشريًا. أما القيمة الافتراضية الفارغة فهي مناسبة لعناقيد التطوير حيث لا تكون القفزات بين الإصدارات الرئيسية مصدر قلق.

شروط الحالة

يكشف الشرطان التاليان نتيجة الـ فحص وفحص الترقية:

الشرط السبب المعنى
VersionInSync VersionMatch تُبلّغ جميع النسخ المتماثلة عن الإصدار نفسه
VersionInSync VersionMismatch تعمل النسخ المتماثلة بإصدارات مختلفة. يُحجب هذا السبب أثناء ترقية متدرجة مخططة. ويظهر عادةً عند تثبيت وسم صورة قابل للتغيير (مثل latest أو إصدار رئيسي/فرعي مجرد مثل 26.3) بينما يكون الـ registry الأساسي قد تغيّر بين عمليات السحب، فتستقر نسخ متماثلة مختلفة على إصدارات فرعية مختلفة ضمن الوسم نفسه.
VersionInSync VersionPending لم تكتمل بعد مهمة فحص الإصدار، أو لم يُرصَد بعد إصدار أي نسخة متماثلة من Keeper
VersionInSync VersionProbeFailed فشلت مهمة فحص الخاصة بـ ClickHouse؛ لذلك لا يستطيع المشغّل تحديد الإصدار قيد التشغيل
VersionUpgraded UpToDate يعمل العنقود بأحدث إصدار متاح في القناة المحددة
VersionUpgraded MinorUpdateAvailable يتوفر إصدار فرعي أحدث ضمن خط major.minor نفسه
VersionUpgraded MajorUpdateAvailable يتوفر major.minor أحدث ضمن القناة المختارة
VersionUpgraded VersionOutdated الإصدار قيد التشغيل قديم ولم يعد يتلقى إصلاحات من القناة المحددة — ويحدث ذلك عادةً لأن الخط الرئيسي أُزيل من lts أو stable في المصدر الرئيسي
VersionUpgraded WrongReleaseChannel الصورة قيد التشغيل لا تنتمي إلى upgradeChannel المحدد. Example: عنقود يعمل بالإصدار 26.5 مع upgradeChannel: lts، لأن 26.5 ليس جزءًا من خط lts في المصدر الرئيسي.
VersionUpgraded UpgradeCheckFailed تعذّر على المشغّل الوصول إلى موجز الإصدارات من المصدر الرئيسي

افحصها باستخدام:

kubectl get clickhousecluster sample -o yaml | sed -n '/conditions:/,/^[^ ]/p'

تجاوز Job فحص الإصدار

ينطبق هذا على ClickHouseCluster فقط. لم يعد KeeperCluster يشغّل Job لفحص الإصدار — إذ تُقرأ نسخته مباشرةً من نسخ Keeper المتماثلة العاملة — لذلك فإن spec.versionProbeTemplate مهمل ولا يكون له أي تأثير هناك.

يُنَفَّذ الفحص باعتباره Job عاديًا في Kubernetes. إذا كانت في عنقودك سياسات قبول تتطلب قيم Tolerations محددة، أو محددات عُقد، أو سياقات أمان، أو إذا كنت تريد تقييد مدة بقاء مهام الفحص المكتملة، فتجاوز القالب عبر spec.versionProbeTemplate:

spec:
  versionProbeTemplate:
    spec:
      ttlSecondsAfterFinished: 600   # delete completed probe Jobs 10 minutes after completion
      template:
        spec:
          nodeSelector:
            kubernetes.io/arch: amd64
          tolerations:
            - key: dedicated
              operator: Equal
              value: clickhouse
              effect: NoSchedule
          containers:
            - name: version-probe
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi

اسم الحاوية version-probe هو الاسم الافتراضي للمشغّل — إذ إن الإدخال ضمن containers: يطابقه بالاسم، لذا يُجري المشغّل دمجًا عميقًا للحقول التي يوفّرها المستخدم فوق القيم الافتراضية.

عناصر تحكم على مستوى المشغّل

يتحكم خياران في مدير المشغّل بحلقة التحقق من الترقية على مستوى عام:

Flag Default Effect
--version-update-interval 24h عدد المرات التي يعيد فيها المشغّل جلب قائمة الإصدارات من المصدر الأصلي
--disable-version-update-checks false يعطّل أداة التحقق من الترقية بالكامل. ولا يتم تعيين الحالة VersionUpgraded، كما لا يُنشأ أي مرور HTTP صادر إلى clickhouse.com

اضبط --disable-version-update-checks=true في البيئات المعزولة عن الشبكة أو عندما لا يكون مسموحًا بخروج الحركة إلى clickhouse.com.

إعدادات ClickHouse

كلمة مرور المستخدم default

يضبط spec.settings.defaultUserPassword كلمة مرور المستخدم المضمّن default. وفّر القيمة من مفتاح في Secret (مستحسن) أو في ConfigMap تنشئه، بدلًا من تضمينها مباشرةً داخل CR:

spec:
  settings:
    defaultUserPassword:
      passwordType: password   # default; see "Password types" below
      secret:                  # exactly one of secret or configMap
        name: clickhouse-password   # name of the Secret/ConfigMap
        key: password               # the key inside it, not the password value

حدِّد واحدًا فقط من secret أو configMap، على أن يشتمل أيٌّ منهما على كلٍّ من name (الكائن) وkey (الإدخال الذي يحتوي على كلمة المرور).

أنواع كلمات المرور

يُحدِّد passwordType كيفية تفسير ClickHouse للقيمة. وتكون قيمته الافتراضية password (نص صريح)؛ أما البدائل فهي صيغ مُجزَّأة مثل password_sha256_hex و password_double_sha1_hex. ويُفضَّل استخدام نوع مُجزَّأ حتى لا يُخزَّن النص الصريح مطلقًا. راجع إعدادات مستخدمي ClickHouse للاطلاع على القائمة الكاملة.

مثال كامل باستخدام Secret

أنشئ Secret، ثم أشِر إلى مفتاحه:

kubectl create secret generic clickhouse-password \
  --from-literal=password='your-secure-password'
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: my-cluster
spec:
  settings:
    defaultUserPassword:
      passwordType: password
      secret:
        name: clickhouse-password
        key: password

بالنسبة إلى كلمة مرور مُجزّأة، خزّن قيمة التجزئة بدلًا من النص غير المشفّر:

echo -n 'your-secure-password' | sha256sum   # use the hex digest as the value
kubectl create secret generic clickhouse-password \
  --from-literal=password='<sha256-hex-digest>'
spec:
  settings:
    defaultUserPassword:
      passwordType: password_sha256_hex
      secret:
        name: clickhouse-password
        key: password

استخدام ConfigMap

يعمل ConfigMap بالطريقة نفسها، لكن محتوياته ليست محمية كما في Secret. استخدمه فقط للقيم غير الحساسة أو للقيم التي جرى تجزئتها بالفعل، مثل بصمة password_sha256_hex:

spec:
  settings:
    defaultUserPassword:
      passwordType: password_sha256_hex
      configMap:
        name: clickhouse-config
        key: default_password

مستخدمون مخصّصون في التهيئة

قم بتهيئة مستخدمين إضافيين في ملفات التهيئة.

أنشئ ConfigMap وSecret للمستخدم:

apiVersion: v1
kind: ConfigMap
metadata:
  name: user-config
data:
  reader.yaml: |
    users:
      reader:
        password:
          - '@from_env': READER_PASSWORD
        profile: default
        grants:
          query:
            - "GRANT SELECT ON *.*"
---
apiVersion: v1
kind: Secret
metadata:
  name: reader-password
data:
  password: "c2VjcmV0LXBhc3N3b3Jk"  # base64("secret-password")

أضِف تهيئة مخصّصة إلى ClickHouseCluster:

spec:
  podTemplate:
    volumes:
      - name: reader-user
        configMap:
          name: user-config
  containerTemplate:
    env:
      - name: READER_PASSWORD
        valueFrom:
          secretKeyRef:
            name: reader-password
            key: password
    volumeMounts:
      - mountPath: /etc/clickhouse-server/users.d/
        name: reader-user
        readOnly: true

مزامنة قاعدة البيانات

فعِّل المزامنة التلقائية لقاعدة البيانات للنسخ المتماثلة الجديدة:

spec:
  settings:
    enableDatabaseSync: true  # Default: true

عند التفعيل، يزامن المُشغِّل جداول Replicated وجداول التكامل مع النسخ المتماثلة الجديدة.

تحمل كل Pod للنسخة المتماثلة بوابة الجاهزية clickhouse.com/ReplicaInitialized، لذلك لا تُنشر النسخة المتماثلة الجديدة عبر الخدمة عديمة الرأس العامة إلا بعد أن يُكمل المُشغِّل تهيئتها: إذ تُحوَّل قاعدة البيانات default إلى محرك Replicated ويُزامَن المخطط. وحتى ذلك الحين، يصل إليها المُشغِّل والنسخ المتماثلة الأخرى عبر خدمتها الداخلية. عند استخدام enableDatabaseSync: false، يضع المُشغِّل علامة التهيئة على النسخ المتماثلة فورًا، لذا تعتمد الجاهزية على فحوصات الحاوية وحدها.

لا يحذف المُشغِّل مطلقًا قاعدة بيانات default غير Replicated والمملوءة بالبيانات. تبدأ هذه النسخة المتماثلة مع ذلك في خدمة حركة مرور العملاء بعد إعداد المخطط، لكن العنقود يبلّغ عن SchemaInSync=False بالسبب DefaultDatabaseNotReplicated إلى أن تعالج قاعدة البيانات تلك بنفسك.

قبل إزالة نسخة متماثلة عند التخفيض التدريجي، يُفرِّغ المُشغِّل أولًا حركة مرور العملاء منها، وينتظر حتى تتوقف عن النشر، ويُكرِّر بياناتها المتبقية إلى النسخ المتماثلة الباقية، ثم يحذفها فقط بعد ذلك.

تسجيل الخادم

اضبط سجل خادم ClickHouse عبر spec.settings.logger. كل حقل اختياري وله قيمة افتراضية آمنة، لذا فإن أي عنقود لا تُجري عليه أي تعديل يسجّل بالفعل عند مستوى trace في كلٍّ من وحدة تحكم الحاوية وملف سجل خاضع للتدوير على القرص.

spec:
  settings:
    logger:
      logToFile: true   # Default: true. Set false to log only to the console
      jsonLogs: false   # Default: false. Set true for structured JSON log lines
      level: trace      # Default: trace
      size: 1000M       # Default: 1000M. Rotate a log file once it reaches this size
      count: 50         # Default: 50. Number of rotated files to keep
الحقل الافتراضي الوصف
logToFile true عندما تكون القيمة false، يزيل المشغّل أهداف الملفات، ولا يرسل الخادم السجلات إلا إلى وحدة تحكم الحاوية.
jsonLogs false عندما تكون القيمة true، يضيف المشغّل formatting.type: json بحيث يكون كل سطر كائن JSON.
level trace مستوى تفصيل السجلات. إحدى القيم التالية: test، trace، debug، information، notice، warning، error، critical، fatal.
size 1000M الحجم الأقصى لملف سجل واحد قبل التدوير.
count 50 عدد ملفات السجل المُدوَّرة التي يحتفظ بها الخادم.

يُبقي المشغّل التسجيل إلى وحدة التحكم مفعّلًا دائمًا لكي يعمل kubectl logs، ويضيف التسجيل إلى الملف فوق ذلك عندما تكون logToFile بقيمة true. وينتج عن عنقود بالإعدادات الافتراضية كتلة logger التالية:

logger:
  console: true
  level: trace
  log: /var/log/clickhouse-server/clickhouse-server.log
  errorlog: /var/log/clickhouse-server/clickhouse-server.err.log
  size: 1000M
  count: 50

ينطبق مقطع spec.settings.logger نفسه على KeeperCluster؛ لكن المشغّل يكتب ملفاته في هذه الحالة ضمن /var/log/clickhouse-keeper/.

إعداد مخصص

تهيئة إضافية مضمنة

بدلًا من ربط ملفات تهيئة مخصّصة، يمكنك تحديد خيارات تهيئة إضافية لـ ClickHouse مباشرةً.

أضف تهيئة مخصّصة لـ ClickHouse باستخدام extraConfig:

spec:
  settings:
    extraConfig:
      background_pool_size: 20

إعدادات المستخدمين الإضافيين المضمّنة

يمكنك أيضًا تحديد إعدادات إضافية لمستخدمي ClickHouse باستخدام extraUsersConfig. ويُفيد ذلك في تعريف المستخدمين وملفات التعريف والحصص والامتيازات مباشرةً ضمن مواصفات العنقود.

spec:
  settings:
    extraUsersConfig:
      users:
        analyst:
          password:
            - '@from_env': ANALYST_PASSWORD
          profile: "readonly"
          quota: "default"
      profiles:
        readonly:
          readonly: 1
          max_memory_usage: 10000000000
      quotas:
        default:
          interval:
            duration: 3600
            queries: 1000
            errors: 100

راجع الوثائق للاطلاع على جميع خيارات إعداد مستخدمي ClickHouse المدعومة.

مثال على التهيئة

مثال كامل للتهيئة:

apiVersion: clickhouse.com/v1alpha1
kind: KeeperCluster
metadata:
  name: sample
spec:
  replicas: 3
  dataVolumeClaimSpec:
    storageClassName: <storage-class-name>
    resources:
      requests:
        storage: 10Gi
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname
  containerTemplate:
    resources:
      requests:
        cpu: "2"
        memory: "4Gi"
      limits:
        cpu: "4"
        memory: "8Gi"
  settings:
    tls:
      enabled: true
      required: true
      serverCertSecret:
        name: <keeper-certificate-secret>
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: default-user-password
data:
  # secret-password
  password: "..." # sha256 hex of the password
---
apiVersion: clickhouse.com/v1alpha1
kind: ClickHouseCluster
metadata:
  name: sample
spec:
  replicas: 2
  dataVolumeClaimSpec:
    storageClassName: <storage-class-name>
    resources:
      requests:
        storage: 200Gi
  keeperClusterRef:
    name: sample
  podTemplate:
    topologyZoneKey: topology.kubernetes.io/zone
    nodeHostnameKey: kubernetes.io/hostname
  settings:
    tls:
      enabled: true
      required: true
      serverCertSecret:
        name: clickhouse-cert
    defaultUserPassword:
      passwordType: password_sha256_hex
      configMap:
        key: password
        name: default-password
Navigation