ProHoster > وبلاگ > اداره > تجربه ما با داده ها در etcd خوشه Kubernetes به طور مستقیم (بدون K8s API)
تجربه ما با داده ها در etcd خوشه Kubernetes به طور مستقیم (بدون K8s API)
مشتریان به طور فزاینده ای از ما می خواهند که دسترسی به خوشه Kubernetes را فراهم کنیم تا بتوانند به خدمات درون خوشه دسترسی داشته باشند: به طوری که آنها بتوانند مستقیماً به پایگاه داده یا سرویس متصل شوند تا یک برنامه محلی را با برنامه های درون خوشه متصل کنند.
به عنوان مثال، نیاز به اتصال از دستگاه محلی خود به یک سرویس وجود دارد memcached.staging.svc.cluster.local. ما این قابلیت را با استفاده از VPN در خوشه ای که مشتری به آن متصل می شود، ارائه می دهیم. برای انجام این کار، ما زیرشبکههای پادها، سرویسها و push Cluster DNS را به مشتری اعلام میکنیم. بنابراین، هنگامی که یک مشتری سعی می کند به سرویس متصل شود memcached.staging.svc.cluster.local، درخواست به DNS خوشه می رود و در پاسخ آدرس این سرویس را از شبکه سرویس کلاستر یا آدرس پاد دریافت می کند.
ما خوشههای K8s را با استفاده از kubeadm پیکربندی میکنیم، جایی که زیرشبکه سرویس پیشفرض است 192.168.0.0/16، و شبکه غلاف ها است 10.244.0.0/16. معمولا همه چیز خوب کار می کند، اما چند نکته وجود دارد:
زیر شبکه 192.168.*.* اغلب در شبکه های اداری مشتری و حتی بیشتر در شبکه های خانگی توسعه دهندگان استفاده می شود. و سپس با تداخل مواجه میشویم: روترهای خانگی روی این زیرشبکه کار میکنند و VPN این زیرشبکهها را از خوشه به مشتری هل میدهد.
ما چندین خوشه داریم (تولید، مرحله و/یا چندین خوشه توسعه دهنده). سپس به صورت پیشفرض، همه آنها زیرشبکههای یکسانی برای پادها و سرویسها خواهند داشت که مشکلات زیادی را برای کار همزمان با سرویسها در چندین کلاستر ایجاد میکند.
ما مدت ها پیش روش استفاده از زیرشبکه های مختلف برای سرویس ها و پادها در یک پروژه را اتخاذ کرده ایم - به طور کلی، به طوری که همه خوشه ها دارای شبکه های مختلف هستند. با این حال، تعداد زیادی خوشه در حال کار هستند که من نمیخواهم از ابتدا آنها را تغییر دهم، زیرا آنها بسیاری از خدمات، برنامههای دولتی و غیره را اجرا میکنند.
و سپس از خود پرسیدیم: چگونه می توان زیر شبکه را در یک خوشه موجود تغییر داد؟
جستجوی تصمیمات
متداول ترین روش بازآفرینی است همه خدمات با نوع ClusterIP. به عنوان یک گزینه، می تواند مشاوره دهد و این:
فرآیند زیر یک مشکل دارد: پس از پیکربندی همه چیز، پادها با IP قدیمی به عنوان سرور نام DNS در /etc/resolv.conf می آیند.
از آنجایی که هنوز راه حل را پیدا نکردم، مجبور شدم کل کلاستر را با reset kubeadm بازنشانی کنم و دوباره آن را راه اندازی کنم.
اما این برای همه مناسب نیست... در اینجا مقدمه های دقیق تری برای مورد ما وجود دارد:
فلانل استفاده می شود؛
هم در ابرها و هم روی سخت افزار خوشه هایی وجود دارد.
من می خواهم از استقرار مجدد همه سرویس ها در خوشه اجتناب کنم.
به طور کلی نیاز به انجام هر کاری با حداقل تعداد مشکلات وجود دارد.
نسخه Kubernetes 1.16.6 است (البته مراحل بعدی برای نسخه های دیگر مشابه خواهد بود).
وظیفه اصلی این است که اطمینان حاصل شود که در یک خوشه با استفاده از kubeadm با یک زیرشبکه سرویس مستقر شده است 192.168.0.0/16، آن را جایگزین کنید 172.24.0.0/16.
و اتفاقاً ما مدتها بود که علاقه مند بودیم ببینیم در Kubernetes چه چیزی و چگونه در etcd ذخیره می شود ، چه کاری می توان با آن انجام داد ... بنابراین فکر کردیم:چرا فقط داده ها را در etcd به روز نمی کنیم و آدرس های IP قدیمی (زیر شبکه) را با آدرس های جدید جایگزین نمی کنیم؟؟ "
با جستجوی ابزارهای آماده برای کار با داده ها در etcd، چیزی پیدا نکردیم که مشکل را به طور کامل حل کند. (به هر حال، اگر در مورد برنامه های کاربردی برای کار با داده ها به طور مستقیم در etcd اطلاع دارید، از پیوندها سپاسگزاریم.) با این حال، یک نقطه شروع خوب است etcdhelper از OpenShift(با تشکر از نویسندگان آن!).
این ابزار می تواند با استفاده از گواهی ها به etcd متصل شود و داده ها را از آنجا با استفاده از دستورات بخواند ls, get, dump.
etcdhelper را اضافه کنید
فکر بعدی منطقی است: "چه چیزی شما را از اضافه کردن این ابزار با افزودن قابلیت نوشتن داده به etcd باز می دارد؟"
این یک نسخه اصلاح شده از etcdhelper با دو عملکرد جدید شد changeServiceCIDR и changePodCIDR. روی او می توانید کد را ببینید اینجا.
ویژگی های جدید چه می کنند؟ الگوریتم changeServiceCIDR:
ایجاد یک deserializer؛
کامپایل یک عبارت منظم برای جایگزینی CIDR.
ما تمام خدمات را با نوع ClusterIP در خوشه انجام می دهیم:
رمزگشایی مقدار از etcd به یک شی Go.
با استفاده از یک عبارت منظم، دو بایت اول آدرس را جایگزین می کنیم.
به سرویس یک آدرس IP از زیر شبکه جدید اختصاص دهید.
یک سریال ساز ایجاد کنید، شی Go را به protobuf تبدیل کنید، داده های جدید را در etcd بنویسید.
تابع changePodCIDR اساسا مشابه changeServiceCIDR - فقط به جای ویرایش مشخصات سرویس، این کار را برای گره انجام می دهیم و تغییر می دهیم .spec.PodCIDR به یک زیر شبکه جدید
عمل
سرویس CIDR را تغییر دهید
طرح اجرای کار بسیار ساده است، اما شامل زمان از کار افتادن در زمان ایجاد مجدد همه غلاف ها در خوشه است. پس از تشریح مراحل اصلی، همچنین نظراتی را در مورد اینکه چگونه از نظر تئوری می توان این زمان از کار افتادگی را به حداقل رساند، به اشتراک خواهیم گذاشت.
مراحل مقدماتی:
نصب نرم افزار لازم و مونتاژ etcdhelper پچ شده.
پشتیبان گیری etcd و /etc/kubernetes.
برنامه اقدام مختصر برای تغییر سرویسCIDR:
تغییر مانیفست apiserver و controller-manager.
صدور مجدد گواهینامه؛
تغییر خدمات ClusterIP در etcd.
راه اندازی مجدد همه غلاف ها در خوشه.
در ادامه یک توالی کامل از اقدامات به تفصیل آمده است.
ما برای خودمان پس انداز می کنیم etcdhelper.go، دانلود وابستگی ها، جمع آوری:
wget https://raw.githubusercontent.com/flant/examples/master/2020/04-etcdhelper/etcdhelper.go
go get go.etcd.io/etcd/clientv3 k8s.io/kubectl/pkg/scheme k8s.io/apimachinery/pkg/runtime
go build -o etcdhelper etcdhelper.go
4. زیرشبکه سرویس را در نمایشگرهای صفحه کنترل Kubernetes تغییر دهید. در فایل ها /etc/kubernetes/manifests/kube-apiserver.yaml и /etc/kubernetes/manifests/kube-controller-manager.yaml پارامتر را تغییر دهید --service-cluster-ip-range به یک زیر شبکه جدید: 172.24.0.0/16 به جای 192.168.0.0/16.
5. از آنجایی که ما در حال تغییر زیرشبکه سرویسی هستیم که kubeadm برای apiserver گواهینامه صادر می کند (از جمله)، آنها باید دوباره صادر شوند:
بیایید ببینیم گواهینامه فعلی برای کدام دامنه ها و آدرس های IP صادر شده است:
openssl x509 -noout -ext subjectAltName </etc/kubernetes/pki/apiserver.crt
X509v3 Subject Alternative Name:
DNS:dev-1-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:apiserver, IP Address:192.168.0.1, IP Address:10.0.0.163, IP Address:192.168.199.100
بیایید یک پیکربندی حداقلی برای kubeadm آماده کنیم:
اخطار! در این لحظه، وضوح دامنه کار در خوشه را متوقف می کند، زیرا در پادهای موجود /etc/resolv.conf آدرس قدیمی CoreDNS (kube-dns) ثبت شده است و kube-proxy قوانین iptables را از زیر شبکه قدیمی به زیر شبکه جدید تغییر می دهد. در ادامه مقاله در مورد گزینه های احتمالی برای به حداقل رساندن زمان خرابی نوشته شده است.
بیایید ConfigMap را در فضای نام رفع کنیم kube-system:
kubectl -n kube-system edit cm kubelet-config-1.16
- اینجا جایگزین کنید clusterDNS به آدرس IP جدید سرویس kube-dns: kubectl -n kube-system get svc kube-dns.
kubectl -n kube-system edit cm kubeadm-config
- درستش می کنیم data.ClusterConfiguration.networking.serviceSubnet به یک زیر شبکه جدید
از آنجایی که آدرس kube-dns تغییر کرده است، لازم است پیکربندی kubelet را در همه گره ها به روز کنید:
6. بیایید همه گره های کلاستر را یکی یکی ریبوت کنیم.
7. اگر حداقل یک گره را ترک کنید podCIDR قدیمی، سپس kube-controller-manager قادر به شروع نخواهد بود و پادهای موجود در خوشه برنامه ریزی نمی شوند.
در واقع، تغییر podCIDR می تواند حتی ساده تر انجام شود (به عنوان مثال، پس). اما ما می خواستیم نحوه کار با etcd را به طور مستقیم یاد بگیریم، زیرا مواردی وجود دارد که اشیاء Kubernetes را در etcd ویرایش می کنیم - تک تک نوع ممکن (به عنوان مثال، شما نمی توانید فقط قسمت Service را بدون خرابی تغییر دهید spec.clusterIP.)
مجموع
این مقاله امکان کار با داده ها در etcd را به طور مستقیم مورد بحث قرار می دهد. دور زدن Kubernetes API. گاهی اوقات این رویکرد به شما امکان می دهد "کارهای پیچیده" را انجام دهید. ما عملیات داده شده در متن را روی خوشه های واقعی K8 آزمایش کردیم. با این حال، وضعیت آمادگی آنها برای استفاده گسترده است PoC (اثبات مفهوم). بنابراین، اگر می خواهید از نسخه اصلاح شده ابزار etcdhelper در خوشه های خود استفاده کنید، این کار را با مسئولیت خود انجام دهید.