در این مقاله، به معرفی و نصب سرور Kubernetes Cluster، Haproxy، Nfs با استفاده از Vagrant خواهیم پرداخت.
سایر مقالات در مورد ادغام Hyperledger Fabric با Spring Boot از لینک های زیر قابل دسترسی هستند.
قسمت 2 – راه اندازی خوشه Kubernetes
بخش 4 – تولید گواهینامه ها و مصنوعات
Kubernetes چیست؟
Kubernetes یک ابزار هماهنگسازی کانتینر متن باز است که توسط Google توسعه یافته است تا به شما کمک کند برنامههای کانتینری شده/dockerized را مدیریت کنید که از محیطهای استقرار چندگانه مانند On-premise، cloud یا ماشینهای مجازی پشتیبانی میکنند.
نام Kubernetes از یونانی به معنای سکان دار یا خلبان گرفته شده است. K8 به عنوان مخفف از شمردن هشت حرف بین “K” و “s” حاصل می شود. گوگل پروژه Kubernetes را در سال 2014 منبع باز کرد.
Vagrant چیست؟
Vagrant ابزاری است که به ما امکان می دهد ماشین های مجازی توسعه یافته توسط HashiCorp را ایجاد و مدیریت کنیم. با Vagrant به راحتی می توانیم ماشین مجازی را پیکربندی کنیم و بسیاری از ماشین ها را به راحتی مدیریت کنیم.
Vagrant زیرساخت ماشین های مجازی شما را با استفاده از یک فایل Vagrantfile خودکار می کند.
نصب Vagrant
برای نصب Vagrant ،virtualbox یا hyperv باید بر روی رایانه محلی شما نصب شود. ما از ارائه دهنده VirtualBox استفاده خواهیم کرد که ارائه دهنده پیش فرض Vagrant است. Vagranfile که من ایجاد کردم از ارائه دهندگان hyperv و virtualbox پشتیبانی می کند.
میتوانید Vagrant را از https://www.vagrantup.com/ و VirtualBox را از https://www.virtualbox.org/wiki/Downloads دانلود و نصب کنید.
پس از نصب می توانید نسخه Vagrant را با نصب تایید کنید.
نصب افزونه Guest Addition برای Vagrant
Guest Addition اساساً برای این است که بتوانید پتانسیل کامل Vagrant را آزاد کنید، به این معنی که نصب و به روز نگه داشتن آن مهم است. با این حال، اطمینان از اینکه جعبههای Vagrant شما همیشه آخرین نسخه Guest Additions را اجرا میکنند، میتواند کاری زمانبر باشد و چرخههای مهمی را که میتوان از آنها بهتر استفاده کرد، ربود.
با دستور زیر می توانیم این افزونه را نصب کنیم.
vagrant plugin install vagrant-vbguest
Vagrantfile
Vagrantfile فایلی است که در آن اطلاعات لازم (ram, cpu, vm_provider) برای پیکربندی و هماهنگی ماشین های مجازی نوشته شده است. برای ایجاد این پیکربندی از زبان روبی استفاده می شود.
نصب ماشین مجازی با استفاده از Vagrant
بیایید پروژه ای را که دانلود کرده ایم از این لینک باز کنیم و به فهرستی که Vagrantfile در آن قرار دارد برویم.
$ cd deploy
ما 3 ماشین مجازی را برای سرور nfs، پراکسی ha و خوشه kubernetes با استفاده از vagrant راه اندازی خواهیم کرد.
الزامات سخت افزاری و IP ماشین مجازی در جدول زیر نشان داده شده است.
توزیع Vagrant برنامه Asset Transfer، حداقل 10 گیگابایت رم و 8 هسته CPU مورد نیاز است.
$script = <<-SCRIPT
# echo "Preparing local node_modules folder…"
# mkdir -p /home/vagrant/app/sdk/vagrant_node_modules
# chown vagrant:vagrant /home/vagrant/app/sdk/vagrant_node_modules
echo "cd $1" >> /home/vagrant/.profile
echo "cd $1" >> /home/vagrant/.bashrc
echo "All good!!"
SCRIPT
VAGRANTFILE_API_VERSION = "2"
VM_SYNCED_FOLDER_PATH = "/vagrant"
# Vagrant base box to use
BOX_BASE = "ubuntu/focal64"
# set servers list and their parameters
NODES = [
{ :hostname => "nfsserver", :ip => "192.168.12.9", :cpus => 1, :mem => 512, :type => "nfs" },
{ :hostname => "haproxy", :ip => "192.168.12.10", :cpus => 1, :mem => 512, :type => "haproxy" },
{ :hostname => "k8smaster", :ip => "192.168.12.11", :cpus => 6, :mem => 9728, :type => "k8s" }
# { :hostname => "k8snode1", :ip => "192.168.12.12", :cpus => 2, :mem => 2048, :type => "k8s" }
]
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# 1. Use this for "Standard setup"
etcHosts = ""
config.vm.box = BOX_BASE
config.vm.synced_folder ".", VM_SYNCED_FOLDER_PATH
# Uncomment the lines below if you would like to protect the VM
# config.ssh.username = 'vagrant'
# config.ssh.password = 'vagrant'
# config.ssh.insert_key = 'true'
nfs_enabled = NODES.select { |node| node[:type] == "nfs"}
NODES.each do |node|
if node[:type] == "haproxy"
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + " elb.kub ' >> /etc/hosts" + "\n"
elsif node[:type] == "nfs"
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + " nfs.kub ' >> /etc/hosts" + "\n"
else
if node[:hostname] == "k8smaster" && nfs_enabled.empty?()
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + " nfs.kub ' >> /etc/hosts" + "\n"
else
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + "' >> /etc/hosts" + "\n"
end
end
end #end NODES
NODES.each do |node|
config.vm.define node[:hostname] do |cfg|
cfg.vm.hostname = node[:hostname]
cfg.vm.network "private_network", ip: node[:ip]
cfg.vm.provider :virtualbox do |vb|
vb.customize [ "modifyvm", :id, "--cpus", node[:cpus] ]
vb.customize [ "modifyvm", :id, "--memory", node[:mem] ]
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
vb.customize ["modifyvm", :id, "--name", node[:hostname] ]
vb.gui = false
end #end provider
cfg.vm.provider :hyperv do |hv|
hv.customize [ "modifyvm", :id, "--cpus", node[:cpus] ]
hv.customize [ "modifyvm", :id, "--memory", node[:mem] ]
hv.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
hv.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
hv.customize ["modifyvm", :id, "--name", node[:hostname] ]
hv.gui = false
end #end provider
cfg.vm.provision :shell, inline: $script, args: "#{VM_SYNCED_FOLDER_PATH}"
cfg.vm.provision :shell, :inline => etcHosts
end
end
end
متغیر BOX_BASE در Vagrantfile سیستم عامل vms را مشخص می کند. برای سرور اوبونتو 20.04 LTS، مقدار این متغیر ubuntu/focal64 است.
BOX_BASE = “ubuntu/focal64”
متغیر NODES در Vagrantfile لیست vms و پارامترهای آنها (رم، cpu، ip، نام میزبان) را تنظیم می کند. پارامتر نوع می تواند هاپروکسی، nfs و k8s باشد. خوشه Kubernetes در حال حاضر در حال راه اندازی یک گره است. اگر خوشه Kubernetes از چندین گره اصلی و کارگر تشکیل شده باشد، این متغیر NODES را می توان به صورت زیر اختصاص داد.
برای 3 Master، 3 Worker Node Setup
$script = <<-SCRIPT
# echo "Preparing local node_modules folder…"
# mkdir -p /home/vagrant/app/sdk/vagrant_node_modules
# chown vagrant:vagrant /home/vagrant/app/sdk/vagrant_node_modules
echo "cd $1" >> /home/vagrant/.profile
echo "cd $1" >> /home/vagrant/.bashrc
echo "All good!!"
SCRIPT
VAGRANTFILE_API_VERSION = "2"
VM_SYNCED_FOLDER_PATH = "/vagrant"
# Vagrant base box to use
BOX_BASE = "ubuntu/focal64"
# set servers list and their parameters
NODES = [
{ :hostname => "nfsserver", :ip => "192.168.12.9", :cpus => 1, :mem => 512, :type => "nfs" },
{ :hostname => "haproxy", :ip => "192.168.12.10", :cpus => 1, :mem => 512, :type => "haproxy" },
{ :hostname => "k8smaster1", :ip => "192.168.12.11", :cpus => 6, :mem => 9728, :type => "k8s" },
{ :hostname => "k8smaster2", :ip => "192.168.12.12", :cpus => 6, :mem => 9728, :type => "k8s" },
{ :hostname => "k8smaster3", :ip => "192.168.12.13", :cpus => 6, :mem => 9728, :type => "k8s" },
{ :hostname => "k8snode1", :ip => "192.168.12.14", :cpus => 2, :mem => 2048, :type => "k8s" },
{ :hostname => "k8snode2", :ip => "192.168.12.15", :cpus => 2, :mem => 2048, :type => "k8s" },
{ :hostname => "k8snode3", :ip => "192.168.12.16", :cpus => 2, :mem => 2048, :type => "k8s" }
]
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# 1. Use this for "Standard setup"
etcHosts = ""
config.vm.box = BOX_BASE
config.vm.synced_folder ".", VM_SYNCED_FOLDER_PATH
# Uncomment the lines below if you would like to protect the VM
# config.ssh.username = 'vagrant'
# config.ssh.password = 'vagrant'
# config.ssh.insert_key = 'true'
nfs_enabled = NODES.select { |node| node[:type] == "nfs"}
NODES.each do |node|
if node[:type] == "haproxy"
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + " elb.kub ' >> /etc/hosts" + "\n"
elsif node[:type] == "nfs"
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + " nfs.kub ' >> /etc/hosts" + "\n"
else
if node[:hostname] == "k8smaster" && nfs_enabled.empty?()
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + " nfs.kub ' >> /etc/hosts" + "\n"
else
etcHosts += "echo '" + node[:ip] + " " + node[:hostname] + "' >> /etc/hosts" + "\n"
end
end
end #end NODES
NODES.each do |node|
config.vm.define node[:hostname] do |cfg|
cfg.vm.hostname = node[:hostname]
cfg.vm.network "private_network", ip: node[:ip]
cfg.vm.provider :virtualbox do |vb|
vb.customize [ "modifyvm", :id, "--cpus", node[:cpus] ]
vb.customize [ "modifyvm", :id, "--memory", node[:mem] ]
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
vb.customize ["modifyvm", :id, "--name", node[:hostname] ]
vb.gui = false
end #end provider
cfg.vm.provider :hyperv do |hv|
hv.customize [ "modifyvm", :id, "--cpus", node[:cpus] ]
hv.customize [ "modifyvm", :id, "--memory", node[:mem] ]
hv.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
hv.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
hv.customize ["modifyvm", :id, "--name", node[:hostname] ]
hv.gui = false
end #end provider
cfg.vm.provision :shell, inline: $script, args: "#{VM_SYNCED_FOLDER_PATH}"
cfg.vm.provision :shell, :inline => etcHosts
end
end
end
Vagrantfile از نصب چند حالت Master و Worker پشتیبانی می کند. همچنین از virtualbox و hyperv به عنوان ارائه دهنده ماشین مجازی پشتیبانی می کند.
2. حالا اجازه می دهد ماشین های مجازی ایجاد کنیم.
$ vagrant up
پس از اتمام نصب Vagrant یعنی ماشین های مجازی ایجاد شد و تنظیماتی که در Vagrantfile مشخص کرده ایم انجام شد، می توانیم با دستور vagrant ssh به ماشین مجازی که نصب کرده ایم متصل شویم.
ارائه پویا NFS در Kubernetes
ذخیره سازی کانتینری Kubernetes به افراد اجازه می دهد تا ظروف داده را بر اساس تقاضا توسعه دهند. محرمانه بودن داده های موجود با ارائه تهیه خودکار حفظ می شود.
روش ذخیره سازی با تقاضای بسیار بالا است که در میان عمودهای مختلف گسترده و گسترده است. برنامه های کاربردی متعددی برای ارائه دسترسی رضایت بخش به مردم در راه است.
یکی از راه هایی که Kubernetes به برنامه ها اجازه دسترسی به فضای ذخیره سازی را می دهد، پروتکل استاندارد Network File Service (NFS) است.
نصب سرور NFS با استفاده از Vagrant
بیایید با دستور vagrant ssh به ماشین مجازی سرور nfs متصل شویم.
$ vagrant ssh nfsserver
بیایید به دایرکتوری برویم که اسکریپت های نصب سرور nfs در آن قرار دارند. این دایرکتوری همان پوشه deploy/setup/nfs-server-setup در پروژه است. با Vagrant، این دایرکتوری با ماشین مجازی همگام سازی می شود.
$ cd /vagrant/setup/nfs-server-setup
اجازه اجرا را بدهیم.
$ sudo chmod u+x *.sh
بیایید سرور Nfs را نصب کنیم.
$ sudo ./install_nfs.sh
پس از اتمام نصب سرور nfs، بیایید اسکریپتی را اجرا کنیم که دایرکتوری های لازم را برای فایل های فابریک ایجاد می کند.
$ ./create_fabric_dir.sh
پس از ایجاد دایرکتوری ها، اجازه دهید فایل های فابریک را در این دایرکتوری ها کپی کنیم.
$ ./copy_fabricfiles.sh
مسیر سرور nfs به صورت پیش فرض روی /srv/kubedata تنظیم شده است. اگر می خواهید این مسیر را تغییر دهید، باید متغیر NFS_PATH را در install_nfs.sh، متغیر NFS_DIR را در copy_fabricfiles.sh و متغیر NFS_DIR را در create_fabric_dir.sh تغییر دهید. در پروژه، این اسکریپت ها در deploy/setup/nfs-server هستند. پوشه راه اندازی
#!/bin/bash
NFS_DIR=/srv/kubedata
TARGET_PATH=$NFS_DIR/fabricfiles
FABRIC_FILES_PATH=/vagrant/k8s/fabricfiles
# Functions #########################################################################
function copy_fabricfiles(){
echo "## Copied fabric files"
echo
sudo cp -a $FABRIC_FILES_PATH/. $TARGET_PATH/
sudo chmod -R 777 $TARGET_PATH/
}
# Let's go ###################################################################################
copy_fabricfiles
#!/bin/bash
NFS_DIR=/srv/kubedata
FABRIC_FILES_PATH=$NFS_DIR/fabricfiles
BROKER_PATH=$NFS_DIR/fabricfiles/broker
# Functions #########################################################################
function create_fabricfiles_dir(){
echo "## Created fabric files path"
echo
sudo mkdir $FABRIC_FILES_PATH
sudo chown -R nobody:nogroup $FABRIC_FILES_PATH
sudo chmod -R 777 $FABRIC_FILES_PATH
}
function create_broker_dir(){
echo "## Created broker path"
echo
sudo mkdir -p $BROKER_PATH
sudo mkdir $BROKER_PATH/zookeeper0
sudo mkdir $BROKER_PATH/zookeeper1
sudo mkdir $BROKER_PATH/kafka0
sudo mkdir $BROKER_PATH/kafka1
sudo chmod -R 777 $BROKER_PATH
}
# Let's go ###################################################################################
create_fabricfiles_dir
create_broker_dir
#!/bin/bash
# install nfs server
# get some variables #####################################################################
IP_RANGE=$(dig +short k8smaster | grep -v 127.0 | sed s/".[0-9]*$"/.0/g)
NFS_PATH=/srv/kubedata
# Functions #####################################################################
prepare_directories(){
sudo mkdir -p ${NFS_PATH}
sudo chmod 777 -R ${NFS_PATH}
}
install_nfs(){
sudo apt-get install -y nfs-kernel-server 2>&1 > /dev/null
}
set_nfs(){
sudo echo "${NFS_PATH} ${IP_RANGE}/24(rw,sync,no_root_squash,no_subtree_check)">/etc/exports
}
run_nfs(){
sudo systemctl restart nfs-server rpcbind
sudo exportfs -a
}
# Let's go #######################################################################
prepare_directories
install_nfs
set_nfs
run_nfs
Fabric dosyaları srv/kubedata/fabricfiles patihne kopyalanmıştır.Aşağı komut ile kontrol edelim.
$ ls /srv/kubedata/fabricfiles/
نصب سرور Nfs با موفقیت انجام شد. بیایید از ترمینال ماشین مجازی خارج شویم.
$ exit
Load Balancer خارجی در Kubernetes
HAProxy یک راه حل رایگان، بسیار سریع و قابل اعتماد است که دسترسی بالا، متعادل کننده بار و پروکسی را برای برنامه های کاربردی مبتنی بر TCP و HTTP ارائه می دهد. این به ویژه برای وب سایت های با ترافیک بسیار بالا مناسب است و تعداد زیادی از پربازدیدترین وب سایت های جهان را قدرتمند می کند.
در طول سالها، به یک متعادلکننده بار منبع باز استاندارد تبدیل شده است و اکنون با اکثر توزیعهای اصلی لینوکس عرضه میشود.
ما از HAProxy به عنوان یک loadbalancer خارجی Kubernetes استفاده خواهیم کرد. درخواست هاپروکسی از پورت 80 به کنترل کننده ورودی nginx در گره های کارگر متعادل می شود. علاوه بر این، درخواست هاپروکسی از پورت 6443 بین گره های اصلی kubernetes متعادل می شود.
نصب HAProxy با استفاده از Vagrant
بیایید با دستور vagrant ssh به ماشین مجازی هاپروکسی متصل شویم.
$ vagrant ssh haproxy
بیایید به دایرکتوری برویم که اسکریپت های نصب هاپروکسی در آن قرار دارند. این دایرکتوری همان پوشه deploy/setup/haproxy-setup در پروژه است. با Vagrant، این دایرکتوری با ماشین مجازی همگام سازی می شود.
$ cd /vagrant/setup/haproxy-setup
اجازه اجرا را بدهیم.
$ sudo chmod u+x *.sh
بیایید هاپروکسی را نصب کنیم
$ sudo ./install_haproxy.sh
نصب هاپروکسی با موفقیت انجام شد. بیایید از ترمینال ماشین مجازی خارج شویم.
$ exit
نصب Kubernetes با استفاده از Vagrant
ما با استفاده از Kubespray، یک خوشه فلزی خالی از Kubernetes را نصب خواهیم کرد. Kubespray ترکیبی از کتاب های بازی Ansible، موجودی، ابزارهای تهیه و دانش دامنه برای وظایف مدیریت پیکربندی کلاسترهای OS/Kubernetes عمومی است.
بیایید با دستور Vagrant ssh به ماشین مجازی kubernetes master node متصل شویم.
$ vagrant ssh k8smaster
بیایید به دایرکتوری برویم که اسکریپت های نصب kubernetes در آن قرار دارند. این دایرکتوری همان پوشه deploy/setup/kubernetes-setup در پروژه است. با Vagrant، این دایرکتوری با ماشین مجازی همگام سازی می شود.
$ cd /vagrant/setup/kubernetes-setup
اجازه اجرا را بدهیم.
$ sudo chmod u+x *.sh
به طور پیش فرض، kubernetes با گزینه metallb، سرور متریک، هلم، weavenet، nfs ارائه دهنده، گزینه مدیریت گواهی نصب می شود.
اگر می خواهید این گزینه را تغییر دهید، باید متغیرها (METALLB_ENABLED، METRIC_SERVER_ENABLED، و غیره) را در install_kubespray.sh و متغیرها (CERT_MANAGER_ENABLED،ISTIO_ENABLED و غیره) در install-prereqs.sh. در پروژه، این اسکریپت ها در پوشه deploy/setup/kubernetes-setup هستند.
#!/bin/bash
# Variables ########################################
KUBERNETES_DASHBOARD_ENABLED=false
CERT_MANAGER_ENABLED=true
JENKINS_ENABLED=false
SONARQUBE_ENABLED=false
ISTIO_ENABLED=false
RANCHER_ENABLED=false
#!/bin/bash
# Variables ########################################
IP_HAPROXY=$(dig +short elb.kub)
KUBESPRAY_VERSION=2.15
KUBESPRAY_PATH=${HOME}/kubespray
SSH_PASSWORD=vagrant
HELM_ENABLED=true
METRIC_SERVER_ENABLED=true
METALLB_ENABLED=true
METALLB_IP_RANGE=192.168.12.240-192.168.12.250
NGINX_INGRESS_ENABLED=true
HAPROXY_ENABLED=true
WEAVE_ENABLED=true
AUTH_ENABLED=true
MetalLB چیست؟
MetalLB یک اجرای متعادل کننده بار برای خوشه های فلزی خالی Kubernetes است که از پروتکل های مسیریابی استاندارد استفاده می کند. به طور پیش فرض نصب شده است.
Helm چیست؟
Helm ابزاری برای مدیریت نمودارها است. نمودارها بسته هایی از منابع Kubernetes از پیش پیکربندی شده هستند. به طور پیش فرض نصب شده است.
Nginx Ingress Controller چیست؟
Ingress Nginx یک کنترلر Ingress برای Kubernetes است که از NGINX به عنوان یک پروکسی معکوس و متعادل کننده بار استفاده می کند. به طور پیش فرض نصب شده است.
Istio چیست؟
Istio محبوب ترین اجرای مش سرویس، در بالای Kubernetes توسعه یافته است و دارای جایگاه متفاوتی در اکوسیستم برنامه بومی ابری نسبت به Kubernetes است. به طور پیش فرض نصب نشده است. اگر می خواهید این گزینه را تغییر دهید، باید ISTIO_ENABLED را تغییر دهید. متغیر در install-prereqs.sh.
بیایید kubernetes را نصب کنیم
$ ./install-prereqs.sh
نصب Kubernetes با موفقیت انجام شد. در نهایت، بیایید خوشه kubernetes را به Lens IDE اضافه کنیم.
Lens چیست؟
Lens-Kubernetes IDE (“Lens IDE”) توزیعی از مخزن OpenLens با سفارشی سازی های خاص Team Lens است که تحت یک EULA سنتی منتشر شده است.
Lens IDE آگاهی کامل از موقعیت را برای هر چیزی که در Kubernetes اجرا می شود فراهم می کند. این مانع ورود افرادی است که تازه شروع به کار کرده اند و بهره وری را برای افراد با تجربه بیشتر بهبود می بخشد.
Lens IDE یک برنامه مستقل برای سیستم عامل های MacOS، Windows و Linux. می توانید آن را به صورت رایگان برای Windows، MacOS و Linux از وب سایت Lens IDE دانلود کنید.
خوشه Kubernetes را به Lens IDE اضافه کنید
بیایید محتویات فایل پیکربندی kubectl را کپی کنیم. فایل پیکربندی پیش فرض kubectl در ~/ قرار دارد. kube/config و به عنوان فایل kubeconfig نامیده می شود.
$ cat ${HOME}/.kube/config
بیایید Lens IDE را باز کنیم، بیایید از کاتالوگ به Cluster برویم. بیایید Add را از kubeconfig انتخاب کنیم.
بیایید محتویات فایل پیکربندی kubectl را در پنجره باز شده جایگذاری کنیم. https://elb.kub:6443 را با https://192.168.12.10:6443 جایگزین کنیم. در نهایت روی Add Cluster کلیک کنید.
خوشه Kubernetes با موفقیت اضافه شد. بیایید از کاتالوگ به کلاسترها برویم. بیایید kubernetes-admin@cluster.local را انتخاب کرده و روی اتصال کلیک کنید.
Kubernetes با موفقیت به خوشه متصل شد. وقتی Storage Class را در Storage انتخاب می کنیم، یک کلاس ذخیره سازی به نام nfs-client وجود دارد.
به طور کلی معرفی و نصب ابزارهای kubernetes cluster و kubernetes، سرور nfs و هاپروکسی را با استفاده از vagrant توضیح داده شد.