راه اندازی کلاستر Kubernetes
کلاستر های Kubernetes رو میشه به روش های مختلف با توجه پلتفرم ، پیاده سازی کرد. برخی سامانه های رایانش ابری مانند GCP، Azure و AWS کلاسترهای آماده رو در اختیار شما قرار میدن که در واقع هر کدوم از این کمپانی ها نسخه مخصوص خودشون از Kubernetes ارائه داده و اونو تو پلتفرم خودشون قرار دادن.
از اونجایی که توی ایران استفاده از چنین پلتفرم هایی خیلی سخته و در صورت امکان ، هزینه های دلاری سنگینی هم ایجاد میکنه ، میتونیم کلاستر K8S رو خودمون به صورت Bare-Metal پیاده سازی کنیم. به این صورت که روی ماشین های مجازی یا سرور های مختلف کلاستر شخصی درست کرده و ازش استفاده می کنیم.
وقتی صحبت از کلاستر میشه ، مسلما شرایط همیشگی پابرجاست! یعنی چی ؟
هر کلاستر از یکسری Node تشکیل میشه که وظایف مربوط به خودشون رو انجام میدن. در این بین یک یا چند Node به عنوان مدیر کلاستر انتخاب میشن و وظیفه مدیریت کلاستر رو به عهده میگیرن. اینجا هم ما همین شرایط رو داریم و Node های ما شامل Master و Worker میشن.
پیش نیاز ها
برای تهییه این مطلب از چنین کانفیگی استفاده شده :
- سرور G8 DL360
- 3 ماشین مجازی ( 1 ماشین به عنوان Master و 2 ماشین به عنوان Worker )
- ماشین Master با 32 گیگ رم و 4 هسته
- ماشین های Worker با 16 گیگ رم و 2 هسته
- سیستم عامل Ubuntu Server نسخه 18.04
- ابزار Ansible برای Automation و استقرار کلاستر
توجه داشته باشید که اختصاص منابع برای زیرساخت و یا تعیین تعداد Node ها با توجه به نیاز خودتون انجام میشه
آماده سازی
قبل از اینکه شروع به پیاده سازی کلاستر کنیم ، لازمه تا یکسری کارها انجام بدیم :
- برای هر ماشین hostname مناسب تنظیم کنید. در اینجا به این صورت ماشین ها رو ساختم
K8s-manager
K8s-node-1
K8s-node-2 - روی هر ماشین timezone ایران رو تنظیم کنید تا ساعت به درستی نشون داده بشه
- از اونجایی که تمامی مخازن مورد نیاز برای دریافت Image های داکر و منابع مورد نیاز K8S تحریمه ، حتما Proxy مناسب روی ماشین ها تنظیم کنید
- برای داشتن سرعت بهتر موقع نصب پکیج ها ، میتونید از Mirror های دیگه ای استفاده کنید. برای مثال این مخزن مربوط به ابر XaaS که سرعت خوبی هم داره : http://ubuntu.xaas.ir/ubuntu
تنظیم Ansible
برای ساده شدن روند پیاده سازی از Ansible استفاده می کنیم و نیازه تا فایل hosts رو به این صورت تنظیم کنیم :
[all:vars]
ansible_user=kube
ansible_password=changeme
ansible_sudo_pass=changeme
ansible_python_interpreter=/usr/bin/python3
[managers]
manager ansible_host=192.168.1.14
[nodes]
node1 ansible_host=192.168.1.16
node2 ansible_host=192.168.1.17
تو این قسمت آدرس آی پی ماشین ها ، نام کاربری و کلمه عبور مناسب باید قرار داده بشه. موقع نصب نام کاربری و کلمه عبور یکسانی برای ماشین ها استفاده کنید تا اینجا به مشکل نخورید. همچنین نسخه پیشفرض پایتون هم برای Ansible مشخص میکنیم. قبل از تنظیم این گزینه از آدرس صحیح پایتون مطمئن بشید ( میتونید از دستور which python
یا which python3
استفاده کنید ).
در صورتی که تازه ماشین ها رو ساختید حتما یکبار از طریق SSH به اون ها متصل بشید تا fingerprint ها هم تنظیم بشه
برای اینکه مطمئن بشید همه چیز درست تنظیم شده و آماده است دستور زیر رو اجرا کنید :
ansible all -m ping
چنین خروجی باید داشته باشید :
راه اندازی کلاستر
در اینجا چند فایل Playbook داریم که مرحله به مرحله اون ها رو اجرا می کنیم. اولین مرحله راه اندازی ، نصب Docker بوده که باید روی تمام ماشین ها انجام بشه.
نصب داکر
یک فایل playbook با نام docker_tasks.yml
به اینصورت بسازید :
- name: Install docker packages
apt:
name: "{{ item }}"
state: present
update_cache: yes
retries: 3
delay: 10
register: result
until: result is succeeded
with_items:
- apt-transport-https
- ca-certificates
- curl
- software-properties-common
tags:
- docker
- name: Add GPG key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
retries: 3
delay: 10
register: result
until: result is succeeded
tags:
- docker
- name: Verify that we have the key with the fingerprint
apt_key:
id: 0EBFCD88
state: present
retries: 3
delay: 10
register: result
until: result is succeeded
tags:
- docker
- name: Set up the stable repository
apt_repository:
repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable
state: present
retries: 3
delay: 10
register: result
until: result is succeeded
tags:
- docker
- name: Update apt packages
apt:
update_cache: yes
retries: 3
delay: 10
register: result
until: result is succeeded
tags:
- docker
- name: Install docker
apt:
name: "{{ item }}"
state: present
update_cache: yes
retries: 3
delay: 10
register: result
until: result is succeeded
with_items:
- docker-ce
- docker-ce-cli
- containerd.io
tags:
- docker
- name: Add "kube" user to "docker" group
user:
name: "kube"
group: "docker"
append: yes
retries: 3
delay: 10
register: result
until: result is succeeded
tags:
- docker
وظایف قرار داده شده در این فایل به ترتیب شامل این موارد میشه :
- نصب پکیج های مورد نیاز
- اضافه کردن کلید GPG داکر
- بررسی صحت کلید اضافه شده
- اضافه کردن مخزن داکر ( توجه کنید که اینجا از مخزن مربوط به ابونتو 18.04 استفاده شده )
- آپدیت کردن مخزن ها
- نصب داکر
- اضافه کردن کاربر پیشفرض ماشین ها به گروه داکر
توجه داشته باشید که لازم نیست این فایل جداگانه اجرا بشه. برای همین فقط شامل لیست Task های مورد نیازه و بعدا داخل فایل اصلی Include میشه.
نصب K8S
فایلی با نام dependencies.yml
بسازید. این فایل شامل Task های مورد نیاز برای نصب کلیه پیش نیاز های کلاسترمون میشه و باید به این صورت باشه :
--- # Install Kubernetes
- hosts: all
remote_user: kube
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- include_tasks: docker_tasks.yml
- name: Disabling Swap on all nodes
shell: swapoff -a
- name: Commenting Swap entries in /etc/fstab
replace:
path: /etc/fstab
regexp: "(.*swap*)"
replace: '#\1'
- name: Add Kubernetes apt-key
apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
state: present
retries: 3
delay: 10
register: result
until: result is succeeded
- name: Add Kubernetes APT repository
apt_repository:
repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
state: present
filename: "kubernetes"
retries: 3
delay: 10
register: result
until: result is succeeded
- name: Install kubelet
apt:
name: kubelet
state: present
update_cache: true
retries: 3
delay: 10
register: result
until: result is succeeded
- name: Install kubeadm
apt:
name: kubeadm
state: present
retries: 3
delay: 10
register: result
until: result is succeeded
- hosts: managers
remote_user: kube
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: Install kubectl
apt:
name: kubectl
state: present
retries: 3
delay: 10
register: result
until: result is succeeded
وظایف قرار داده شده در این فایل به ترتیب شامل این موارد میشه :
- وظایف مربوط به نصب داکر که در مرحله قبل نوشتیم Include میشه
- برای کار با kubelet نیاز داریم تا swap روی کلیه ماشین ها غیرفعال بشه پس با این دستور این کار رو انجام میدیم
- از اونجایی که دستور بالا به صورت موقت Swap رو غیرفعال میکنه ، با ویرایش فایل fstab برای اجراهای بعدی هم مطمئن میشیم Swap غیرفعال باقی بمونه
- اضافه کردن کلید GPG مربوط به K8S
- اضافه کردن مخزن K8S
- نصب kubelet
- نصب kubeadm
این موارد روی تمام Node ها نصب میشه و در انتها فقط روی نود Manager نصب kubectl رو انجام میدیم. این فایل رو با استفاده از دستور زیر اجرا می کنیم :
ansible-playbook dependencies.yml
ور در پایان چنین خروجی مد نظر ماست :
تا اینجا همه چیز آماده شده و میتونیم کلاستر خودمون رو تشکیل بدیم. مدیر کلاستر یا همون Manager/Master خودش رو معرفی میکنه و با ارائه Token به Worker ها اجازه میده بهش بپیوندند. پس ابتدا نیازه تا Manager خودمون رو تنظیم کنیم.
پیکربندی Manager
برای این کار فایلی با نام manager.yml
به این صورت تنظیم کنید :
--- # Setup master node
- hosts: managers
remote_user: kube
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: Remove debug file
file:
path: $HOME/cluster_init.txt
state: absent
- name: Initialize the cluster
shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_init.txt
args:
chdir: $HOME
creates: cluster_init.txt
- name: Create .kube directory
file:
path: $HOME/.kube
state: directory
mode: 0755
- name: Copy admin.conf to user's kube config
copy:
src: /etc/kubernetes/admin.conf
dest: $HOME/.kube/config
remote_src: yes
owner: kube
- name: Remove debug file
file:
path: $HOME/pod_network.txt
state: absent
- name: Install Pod network
shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml >> pod_network.txt
args:
chdir: $HOME
creates: pod_network.txt
retries: 3
delay: 10
register: result
until: result is succeeded
برای این مرحله از فایل هایی جهت debug هم استفاده میشه تا درصورت بروز مشکل از علتش آگاه بشید. وظایف قرار داده شده در این فایل به ترتیب شامل این موارد میشه :
- حذف فایل debug مربوط به تنظیم Manager ( در صورت وجود )
- تنظیم نود Manager با استفاده از kubeadm و ذخیره نتایج در فایل debug. در اینجا بازه آی پی مورد نظر برای شبکه کلاستر رو هم تعریف می کنیم.
- ساخت دایرکتوری برای قرار دادن فایل تنظیمات
- کپی کردن فایل تنظیمات پیشفرض K8S به دایرکتوری که در مرحله قبل ساختیم
- حذف فایل debug مربوط به تنظیم شبکه کلاستر ( در صورت وجود )
- تنظیم شبکه کلاستر. برای این مورد از Flannel استفاده می کنیم. ابزاری بسیار ساده است که شبکه لایه 3 برامون درست میکنه. جهت اطلاعات بیشتر به ریپازیتوری پروژه در این آدرس مراجعه کنید. در این حین وضعیت و اطلاعات دستور ، در فایل debug مربوطه ذخیره میشه.
با اجرای این فایل نود مدیریتی کلاستر به تدریج آماده میشه. از اونجا که برای راحتی مشاهده وضعیت از فایل debug استفاده کردیم می تونید با مشاهده محتوای اون از وضعیت نصب آگاه بشید.
این فایل رو هم اجرا می کنیم :
ansible-playbook manager.yml
tail -f $HOME/cluster_init.txt
این مرحله تقریبا باید بین 2 تا 5 دقیقه طول بکشه ( مسلما به سرعت اینترنت بستگی داره ).
پیکربندی Worker ها
این مرحله بسیار ساده است. همه چیز آمده است و مدیر کلاستر هم اطلاعات مورد نیاز رو محیا کرده تا همه Worker ها به مجموعه متصل بشن. برای تنظیم این نود ها فایلی با نام nodes.yml
با محتوای زیر آماده کنید :
--- # Setup worker nodes
- hosts: managers
remote_user: kube
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: Get join command
shell: kubeadm token create --print-join-command
register: join_command_raw
- name: Set join command
set_fact:
join_command: "{{ join_command_raw.stdout_lines[0] }}"
- hosts: nodes
remote_user: kube
become: yes
become_method: sudo
connection: ssh
gather_facts: yes
tasks:
- name: Remove debug file
file:
path: $HOME/joined.txt
state: absent
- name: Join cluster
shell: "{{ hostvars['manager'].join_command }} >> joined.txt"
args:
chdir: $HOME
creates: joined.txt
register: node
در ابتدا نیازه تا دو مورد در نود Manager اجرا بشه :
- از اونجایی که Token مورد نظر برای اتصال ، در مرحله قبل ( موقع تنظیم کلاستر با kubeadm ) ساخته شده و بهمون نمایش داده میشه لازمه تا دوباره یکی بسازیم و اون رو در خروجی نمایش بدیم. در این Task از یک متغییر برای ذخیره کردن مقادیر خروجی استفاده می کنیم تا بعدا Token ساخته شده رو استفاده کنیم. با اجرای این دستور یک Command در اختیار ما قرار داده میشه که با اجرای اون هر Worker میتونه به مجموعه اضافه بشه.
- در این قسمت Command ساخته شده رو به صورت fact ذخیره میکنیم چون باید در Task های بعدی که مربوط به Worker هاست ازش استفاده کنیم.
حالا نوبت به تنظیم Worker هاست و دستور ساده ای هم داره :
- حذف فایل debug مربوط به اضافه شدن Worker به مجموعه ( در صورت وجود )
- مقدار Command مورد نظر برای اتصال رو که در مرحله قبلی به صورت fact ذخیره کردیم باید از hostvars دریافت کنیم. این دستور مستقیم اجرا میشه و در نهایت Worker به مجموعه اضافه میشه
یه نکته خیلی مهم !!
برای دریافت fact از اجراهای قبلی باید از نام host استفاده کنیم و نه نام گروه اون !!!! اگه دوباره به فایل hosts مربوط به Ansible مراجعه کنید ، چنین کانفیگی داریم :
[managers]
manager ansible_host=192.168.1.14
در اینجا managers
نام گروه و manager
نام host ماست که باید از اون برای استخراج fact استفاده بشه به این صورت :
hostvars['manager'].join_command
حالا با اجرای این فایل آخرین مرحله از ساخت کلاستر هم انجام میشه و همه چیز تکمیل میشه :
ansible-playbook nodes.yml
برای مشاهده وضعیت کلاستر با SSH به نود مدیریتی متصل بشید و دستور زیر رو اجرا کنید
تقریبا چند دقیقه طول میکشه تا نود های Worker آماده بشن. حالا کلاستر آماده است و میتونید سرویس های خودتون رو روی اون مستقر کنید.
فایل های کامل این آموزش در آدرس زیر موجوده :
https://github.com/hatamiarash7/MyWebSite_Projects/tree/master/kubernetes-cluster
هر سوالی در مورد پیاده سازی و تنظیم کلاستر های K8S داشتید در کامنت ها بپرسید یا ایمیل بفرستید :))