ڈوکر اور سب کچھ، سب کچھ، سب کچھ

TL؛ DR: کنٹینرز میں ایپلی کیشنز چلانے کے لیے فریم ورک کا موازنہ کرنے کے لیے ایک جائزہ گائیڈ۔ ڈوکر اور اسی طرح کے دیگر سسٹمز کی صلاحیتوں پر غور کیا جائے گا۔

ڈوکر اور سب کچھ، سب کچھ، سب کچھ

یہ سب کہاں سے آیا اس کی ایک چھوٹی سی تاریخ

کہانی

ایپلیکیشن کو الگ کرنے کا پہلا معروف طریقہ chroot ہے۔ اسی نام کی سسٹم کال اس بات کو یقینی بناتی ہے کہ روٹ ڈائرکٹری کو تبدیل کر دیا گیا ہے - اس طرح اس بات کو یقینی بناتا ہے کہ جس پروگرام نے اسے بلایا ہے اسے صرف اس ڈائرکٹری میں موجود فائلوں تک رسائی حاصل ہے۔ لیکن اگر کسی پروگرام کو اندرونی طور پر روٹ مراعات دی جاتی ہیں، تو یہ ممکنہ طور پر کروٹ سے "فرار" ہو سکتا ہے اور مرکزی آپریٹنگ سسٹم تک رسائی حاصل کر سکتا ہے۔ اس کے علاوہ، روٹ ڈائرکٹری کو تبدیل کرنے کے علاوہ، دیگر وسائل (RAM، پروسیسر) کے ساتھ ساتھ نیٹ ورک تک رسائی محدود نہیں ہے.

اگلا طریقہ یہ ہے کہ آپریٹنگ سسٹم کرنل کے میکانزم کو استعمال کرتے ہوئے ایک کنٹینر کے اندر ایک مکمل آپریٹنگ سسٹم لانچ کیا جائے۔ اس طریقہ کو مختلف آپریٹنگ سسٹمز میں مختلف طریقے سے کہا جاتا ہے، لیکن جوہر ایک ہی ہے - کئی آزاد آپریٹنگ سسٹمز کو لانچ کرنا، جن میں سے ہر ایک وہی دانا چلاتا ہے جس پر مین آپریٹنگ سسٹم چلتا ہے۔ ان میں FreeBSD جیلیں، سولاریس زونز، OpenVZ اور LXC for Linux شامل ہیں۔ تنہائی کو نہ صرف ڈسک کی جگہ بلکہ دیگر وسائل سے بھی یقینی بنایا جاتا ہے؛ خاص طور پر، ہر کنٹینر میں پروسیسر کے وقت، RAM، اور نیٹ ورک بینڈوتھ کی حدود ہو سکتی ہیں۔ کروٹ کے مقابلے میں، کنٹینر کو چھوڑنا زیادہ مشکل ہے، کیونکہ کنٹینر میں سپر یوزر کو صرف کنٹینر کے مواد تک رسائی حاصل ہوتی ہے، تاہم، کنٹینر کے اندر موجود آپریٹنگ سسٹم کو اپ ٹو ڈیٹ رکھنے کی ضرورت اور پرانے ورژن کے استعمال کی وجہ سے۔ دانا (لینکس کے لیے ایک حد تک فری بی ایس ڈی سے متعلقہ)، دانا کے الگ تھلگ نظام کو "توڑنے" اور مرکزی آپریٹنگ سسٹم تک رسائی حاصل کرنے کا امکان غیر صفر ہے۔

کنٹینر میں ایک مکمل آپریٹنگ سسٹم (شروعاتی نظام، پیکیج مینیجر وغیرہ کے ساتھ) شروع کرنے کے بجائے، آپ فوری طور پر ایپلی کیشنز لانچ کر سکتے ہیں، سب سے اہم بات یہ ہے کہ ایپلی کیشنز کو ایسا موقع فراہم کیا جائے (ضروری لائبریریوں کی موجودگی۔ اور دیگر فائلیں)۔ اس خیال نے کنٹینرائزڈ ایپلیکیشن ورچوئلائزیشن کی بنیاد کے طور پر کام کیا، جس کا سب سے نمایاں اور معروف نمائندہ ڈوکر ہے۔ پچھلے نظاموں کے مقابلے میں، زیادہ لچکدار تنہائی کے طریقہ کار، کنٹینرز کے درمیان ورچوئل نیٹ ورکس اور کنٹینر کے اندر ایپلی کیشن اسٹیٹ ٹریکنگ کے لیے بلٹ ان سپورٹ کے ساتھ، کنٹینرز کو چلانے کے لیے بڑی تعداد میں فزیکل سرورز سے ایک ہی مربوط ماحول بنانے کی صلاحیت کے نتیجے میں۔ دستی وسائل کے انتظام کی ضرورت کے بغیر۔

میں Docker

ڈوکر سب سے مشہور ایپلی کیشن کنٹینرائزیشن سافٹ ویئر ہے۔ گو لینگویج میں لکھا گیا، یہ لینکس کرنل کی معیاری خصوصیات - cgroups، نام کی جگہیں، صلاحیتیں، وغیرہ کے ساتھ ساتھ Aufs فائل سسٹم اور اس طرح کے دیگر کو ڈسک کی جگہ بچانے کے لیے استعمال کرتا ہے۔

ڈوکر اور سب کچھ، سب کچھ، سب کچھ
ماخذ: ویکی میڈیا

فن تعمیر

ورژن 1.11 سے پہلے، ڈوکر نے ایک واحد سروس کے طور پر کام کیا جس نے کنٹینرز کے ساتھ تمام آپریشن کیے: کنٹینرز کے لیے تصاویر ڈاؤن لوڈ کرنا، کنٹینرز لانچ کرنا، API کی درخواستوں پر کارروائی کرنا۔ ورژن 1.11 سے شروع کرتے ہوئے، ڈوکر کو کئی حصوں میں تقسیم کیا گیا تھا جو ایک دوسرے کے ساتھ تعامل کرتے ہیں: کنٹینر، کنٹینرز کے پورے لائف سائیکل پر کارروائی کرنے کے لیے (ڈسک کی جگہ مختص کرنا، تصاویر ڈاؤن لوڈ کرنا، نیٹ ورک کے ساتھ کام کرنا، لانچنگ، انسٹال کرنا اور کنٹینرز کی حالت کی نگرانی) اور runC، کنٹینر پر عمل درآمد کا ماحول، جو cgroups کے استعمال اور لینکس کرنل کی دیگر خصوصیات پر مبنی ہے۔ ڈوکر سروس بذات خود باقی ہے، لیکن اب یہ صرف کنٹینرڈ میں ترجمہ شدہ API کی درخواستوں پر کارروائی کرتی ہے۔

ڈوکر اور سب کچھ، سب کچھ، سب کچھ

تنصیب اور ترتیب

ڈوکر انسٹال کرنے کا میرا پسندیدہ طریقہ ڈوکر مشین ہے، جو ریموٹ سرورز (مختلف کلاؤڈز سمیت) پر ڈوکر کو براہ راست انسٹال اور کنفیگر کرنے کے علاوہ ریموٹ سرورز کے فائل سسٹم کے ساتھ کام کرنا ممکن بناتی ہے اور مختلف کمانڈز بھی چلا سکتی ہے۔

تاہم، 2018 کے بعد سے، پروجیکٹ کو مشکل سے تیار کیا گیا ہے، اس لیے ہم اسے زیادہ تر لینکس ڈسٹری بیوشنز کے لیے معیاری طریقے سے انسٹال کریں گے - ایک ریپوزٹری شامل کرنا اور ضروری پیکجز کو انسٹال کرنا۔

یہ طریقہ خودکار تنصیب کے لیے بھی استعمال ہوتا ہے، مثال کے طور پر Ansible یا اس سے ملتے جلتے دوسرے سسٹمز کا استعمال، لیکن میں اس مضمون میں اس پر غور نہیں کروں گا۔

تنصیب Centos 7 پر کی جائے گی، میں ایک ورچوئل مشین کو بطور سرور استعمال کروں گا، انسٹال کرنے کے لیے صرف نیچے دیے گئے کمانڈز کو چلائیں:

# yum install -y yum-utils
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install docker-ce docker-ce-cli containerd.io

انسٹالیشن کے بعد، آپ کو سروس شروع کرنے اور اسے اسٹارٹ اپ میں ڈالنے کی ضرورت ہے:

# systemctl enable docker
# systemctl start docker
# firewall-cmd --zone=public --add-port=2377/tcp --permanent

مزید برآں، آپ ایک ڈوکر گروپ بنا سکتے ہیں، جس کے صارفین سوڈو کے بغیر ڈوکر کے ساتھ کام کر سکیں گے، لاگنگ ترتیب دے سکیں گے، باہر سے API تک رسائی کو فعال کر سکیں گے، اور فائر وال کو زیادہ درست طریقے سے ترتیب دینا نہ بھولیں (ہر وہ چیز جس کی اجازت نہیں ہے۔ اوپر اور نیچے کی مثالوں میں ممنوع ہے - میں نے اسے سادگی اور وضاحت کے لیے چھوڑ دیا)، لیکن میں یہاں مزید تفصیل میں نہیں جاؤں گا۔

دوسرے امکانات

مذکورہ ڈوکر مشین کے علاوہ، ڈوکر رجسٹری بھی ہے، کنٹینرز کے لیے امیجز کو اسٹور کرنے کا ایک ٹول، نیز ڈوکر کمپوز، کنٹینرز میں ایپلی کیشنز کی تعیناتی کو خودکار کرنے کا ایک ٹول، YAML فائلوں کو کنٹینرز کی تعمیر اور ترتیب دینے کے لیے استعمال کیا جاتا ہے۔ اور دیگر متعلقہ چیزیں (مثال کے طور پر، نیٹ ورکس، ڈیٹا کو ذخیرہ کرنے کے لیے مستقل فائل سسٹم)۔

اسے CICD کے لیے کنویرز کو منظم کرنے کے لیے بھی استعمال کیا جا سکتا ہے۔ ایک اور دلچسپ خصوصیت کلسٹر موڈ میں کام کر رہی ہے، نام نہاد سوارم موڈ (ورژن 1.12 سے پہلے اسے ڈوکر سوارم کہا جاتا تھا)، جو آپ کو کنٹینرز چلانے کے لیے کئی سرورز سے ایک ہی انفراسٹرکچر کو جمع کرنے کی اجازت دیتا ہے۔ تمام سرورز کے اوپر ایک ورچوئل نیٹ ورک کے لیے سپورٹ موجود ہے، ایک بلٹ ان لوڈ بیلنسر ہے، نیز کنٹینرز کے راز کے لیے سپورٹ ہے۔

ڈاکر کمپوز سے YAML فائلیں، معمولی ترمیم کے ساتھ، ایسے کلسٹرز کے لیے استعمال کی جا سکتی ہیں، جو مختلف مقاصد کے لیے چھوٹے اور درمیانے درجے کے کلسٹروں کی دیکھ بھال کو مکمل طور پر خودکار کرتی ہیں۔ بڑے کلسٹرز کے لیے، Kubernetes افضل ہے کیونکہ بھیڑ کے موڈ کی دیکھ بھال کے اخراجات Kubernetes کے اخراجات سے زیادہ ہو سکتے ہیں۔ runC کے علاوہ، آپ انسٹال کر سکتے ہیں، مثال کے طور پر، کنٹینر پر عملدرآمد کے ماحول کے طور پر کاتا کنٹینر

ڈوکر کے ساتھ کام کرنا

تنصیب اور ترتیب کے بعد، ہم ایک کلسٹر کو جمع کرنے کی کوشش کریں گے جس میں ہم ترقیاتی ٹیم کے لیے GitLab اور Docker رجسٹری کو تعینات کریں گے۔ میں سرور کے طور پر تین ورچوئل مشینیں استعمال کروں گا، جس پر میں تقسیم شدہ FS GlusterFS کو اضافی طور پر تعینات کروں گا؛ میں اسے ڈوکر والیوم اسٹوریج کے طور پر استعمال کروں گا، مثال کے طور پر، docker رجسٹری کا ایک غلطی برداشت کرنے والا ورژن چلانے کے لیے۔ چلانے کے لیے کلیدی اجزاء: Docker Registry, Postgresql, Redis, GitLab جس میں سوارم کے اوپر گٹ لیب رنر کے لیے تعاون ہے۔ ہم کلسٹرنگ کے ساتھ Postgresql شروع کریں گے۔ سٹولن۔، لہذا آپ کو Postgresql ڈیٹا کو ذخیرہ کرنے کے لیے GlusterFS استعمال کرنے کی ضرورت نہیں ہے۔ باقی اہم ڈیٹا GlusterFS پر محفوظ کیا جائے گا۔

GlusterFS کو تمام سرورز پر تعینات کرنے کے لیے (انہیں node1، node2، node3 کہا جاتا ہے)، آپ کو پیکیجز انسٹال کرنے، فائر وال کو فعال کرنے، اور ضروری ڈائریکٹریز بنانے کی ضرورت ہے:

# yum -y install centos-release-gluster7
# yum -y install glusterfs-server
# systemctl enable glusterd
# systemctl start glusterd
# firewall-cmd --add-service=glusterfs --permanent
# firewall-cmd --reload
# mkdir -p /srv/gluster
# mkdir -p /srv/docker
# echo "$(hostname):/docker /srv/docker glusterfs defaults,_netdev 0 0" >> /etc/fstab

تنصیب کے بعد، GlusterFS کو ترتیب دینے کا کام ایک نوڈ سے جاری رکھنا چاہیے، مثال کے طور پر node1:

# gluster peer probe node2
# gluster peer probe node3
# gluster volume create docker replica 3 node1:/srv/gluster node2:/srv/gluster node3:/srv/gluster force
# gluster volume start docker

پھر آپ کو نتیجے میں والیوم کو ماؤنٹ کرنے کی ضرورت ہے (کمانڈ کو تمام سرورز پر عمل میں لانا ہوگا):

# mount /srv/docker

سوارم موڈ کو سرورز میں سے ایک پر کنفیگر کیا گیا ہے، جو لیڈر ہوگا، باقی کو کلسٹر میں شامل ہونا پڑے گا، اس لیے پہلے سرور پر کمانڈ پر عمل کرنے کے نتیجے کو دوسرے سرور پر کاپی کرکے اس پر عمل درآمد کرنے کی ضرورت ہوگی۔

ابتدائی کلسٹر سیٹ اپ، میں node1 پر کمانڈ چلاتا ہوں:

# docker swarm init
Swarm initialized: current node (a5jpfrh5uvo7svzz1ajduokyq) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-0c5mf7mvzc7o7vjk0wngno2dy70xs95tovfxbv4tqt9280toku-863hyosdlzvd76trfptd4xnzd xx.xx.xx.xx:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
# docker swarm join-token manager

ہم دوسری کمانڈ کا نتیجہ کاپی کرتے ہیں اور اسے node2 اور node3 پر عمل کرتے ہیں:

# docker swarm join --token SWMTKN-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxx xx.xx.xx.xx:2377
This node joined a swarm as a manager.

اس مقام پر، سرورز کی ابتدائی ترتیب مکمل ہو گئی ہے، آئیے خدمات کو ترتیب دینے کے لیے آگے بڑھتے ہیں؛ عمل درآمد کے لیے کمانڈز node1 سے شروع کیے جائیں گے، جب تک کہ دوسری صورت میں اس کی وضاحت نہ کی جائے۔

سب سے پہلے، آئیے کنٹینرز کے لیے نیٹ ورک بنائیں:

# docker network create --driver=overlay etcd
# docker network create --driver=overlay pgsql
# docker network create --driver=overlay redis
# docker network create --driver=overlay traefik
# docker network create --driver=overlay gitlab

پھر ہم سرورز کو نشان زد کرتے ہیں، کچھ خدمات کو سرورز سے منسلک کرنے کے لیے یہ ضروری ہے:

# docker node update --label-add nodename=node1 node1
# docker node update --label-add nodename=node2 node2
# docker node update --label-add nodename=node3 node3

اس کے بعد، ہم etcd ڈیٹا، KV اسٹوریج کو ذخیرہ کرنے کے لیے ڈائریکٹریز بناتے ہیں، جو Traefik اور Stolon کے لیے ضروری ہے۔ Postgresql کی طرح، یہ سرورز کے ساتھ بندھے ہوئے کنٹینرز ہوں گے، لہذا ہم یہ کمانڈ تمام سرورز پر چلاتے ہیں:

# mkdir -p /srv/etcd

اگلا، etcd کو ترتیب دینے کے لیے ایک فائل بنائیں اور اسے استعمال کریں:

00etcd.yml

version: '3.7'

services:
  etcd1:
    image: quay.io/coreos/etcd:latest
    hostname: etcd1
    command:
      - etcd
      - --name=etcd1
      - --data-dir=/data.etcd
      - --advertise-client-urls=http://etcd1:2379
      - --listen-client-urls=http://0.0.0.0:2379
      - --initial-advertise-peer-urls=http://etcd1:2380
      - --listen-peer-urls=http://0.0.0.0:2380
      - --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
      - --initial-cluster-state=new
      - --initial-cluster-token=etcd-cluster
    networks:
      - etcd
    volumes:
      - etcd1vol:/data.etcd
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.nodename == node1]
  etcd2:
    image: quay.io/coreos/etcd:latest
    hostname: etcd2
    command:
      - etcd
      - --name=etcd2
      - --data-dir=/data.etcd
      - --advertise-client-urls=http://etcd2:2379
      - --listen-client-urls=http://0.0.0.0:2379
      - --initial-advertise-peer-urls=http://etcd2:2380
      - --listen-peer-urls=http://0.0.0.0:2380
      - --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
      - --initial-cluster-state=new
      - --initial-cluster-token=etcd-cluster
    networks:
      - etcd
    volumes:
      - etcd2vol:/data.etcd
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.nodename == node2]
  etcd3:
    image: quay.io/coreos/etcd:latest
    hostname: etcd3
    command:
      - etcd
      - --name=etcd3
      - --data-dir=/data.etcd
      - --advertise-client-urls=http://etcd3:2379
      - --listen-client-urls=http://0.0.0.0:2379
      - --initial-advertise-peer-urls=http://etcd3:2380
      - --listen-peer-urls=http://0.0.0.0:2380
      - --initial-cluster=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
      - --initial-cluster-state=new
      - --initial-cluster-token=etcd-cluster
    networks:
      - etcd
    volumes:
      - etcd3vol:/data.etcd
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.nodename == node3]

volumes:
  etcd1vol:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/etcd"
  etcd2vol:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/etcd"
  etcd3vol:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/etcd"

networks:
  etcd:
    external: true

# docker stack deploy --compose-file 00etcd.yml etcd

کچھ وقت کے بعد، ہم چیک کرتے ہیں کہ etcd کلسٹر اوپر ہے:

# docker exec $(docker ps | awk '/etcd/ {print $1}')  etcdctl member list
ade526d28b1f92f7: name=etcd1 peerURLs=http://etcd1:2380 clientURLs=http://etcd1:2379 isLeader=false
bd388e7810915853: name=etcd3 peerURLs=http://etcd3:2380 clientURLs=http://etcd3:2379 isLeader=false
d282ac2ce600c1ce: name=etcd2 peerURLs=http://etcd2:2380 clientURLs=http://etcd2:2379 isLeader=true
# docker exec $(docker ps | awk '/etcd/ {print $1}')  etcdctl cluster-health
member ade526d28b1f92f7 is healthy: got healthy result from http://etcd1:2379
member bd388e7810915853 is healthy: got healthy result from http://etcd3:2379
member d282ac2ce600c1ce is healthy: got healthy result from http://etcd2:2379
cluster is healthy

ہم Postgresql کے لیے ڈائریکٹریز بناتے ہیں، تمام سرورز پر کمانڈ پر عمل کرتے ہیں:

# mkdir -p /srv/pgsql

اگلا، Postgresql کو ترتیب دینے کے لیے ایک فائل بنائیں:

01pgsql.yml

version: '3.7'

services:
  pgsentinel:
    image: sorintlab/stolon:master-pg10
    command:
      - gosu
      - stolon
      - stolon-sentinel
      - --cluster-name=stolon-cluster
      - --store-backend=etcdv3
      - --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
      - --log-level=debug
    networks:
      - etcd
      - pgsql
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 30s
        order: stop-first
        failure_action: pause
  pgkeeper1:
    image: sorintlab/stolon:master-pg10
    hostname: pgkeeper1
    command:
      - gosu
      - stolon
      - stolon-keeper
      - --pg-listen-address=pgkeeper1
      - --pg-repl-username=replica
      - --uid=pgkeeper1
      - --pg-su-username=postgres
      - --pg-su-passwordfile=/run/secrets/pgsql
      - --pg-repl-passwordfile=/run/secrets/pgsql_repl
      - --data-dir=/var/lib/postgresql/data
      - --cluster-name=stolon-cluster
      - --store-backend=etcdv3
      - --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
    networks:
      - etcd
      - pgsql
    environment:
      - PGDATA=/var/lib/postgresql/data
    volumes:
      - pgkeeper1:/var/lib/postgresql/data
    secrets:
      - pgsql
      - pgsql_repl
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.nodename == node1]
  pgkeeper2:
    image: sorintlab/stolon:master-pg10
    hostname: pgkeeper2
    command:
      - gosu
      - stolon 
      - stolon-keeper
      - --pg-listen-address=pgkeeper2
      - --pg-repl-username=replica
      - --uid=pgkeeper2
      - --pg-su-username=postgres
      - --pg-su-passwordfile=/run/secrets/pgsql
      - --pg-repl-passwordfile=/run/secrets/pgsql_repl
      - --data-dir=/var/lib/postgresql/data
      - --cluster-name=stolon-cluster
      - --store-backend=etcdv3
      - --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
    networks:
      - etcd
      - pgsql
    environment:
      - PGDATA=/var/lib/postgresql/data
    volumes:
      - pgkeeper2:/var/lib/postgresql/data
    secrets:
      - pgsql
      - pgsql_repl
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.nodename == node2]
  pgkeeper3:
    image: sorintlab/stolon:master-pg10
    hostname: pgkeeper3
    command:
      - gosu
      - stolon 
      - stolon-keeper
      - --pg-listen-address=pgkeeper3
      - --pg-repl-username=replica
      - --uid=pgkeeper3
      - --pg-su-username=postgres
      - --pg-su-passwordfile=/run/secrets/pgsql
      - --pg-repl-passwordfile=/run/secrets/pgsql_repl
      - --data-dir=/var/lib/postgresql/data
      - --cluster-name=stolon-cluster
      - --store-backend=etcdv3
      - --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
    networks:
      - etcd
      - pgsql
    environment:
      - PGDATA=/var/lib/postgresql/data
    volumes:
      - pgkeeper3:/var/lib/postgresql/data
    secrets:
      - pgsql
      - pgsql_repl
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.nodename == node3]
  postgresql:
    image: sorintlab/stolon:master-pg10
    command: gosu stolon stolon-proxy --listen-address 0.0.0.0 --cluster-name stolon-cluster --store-backend=etcdv3 --store-endpoints http://etcd1:2379,http://etcd2:2379,http://etcd3:2379
    networks:
      - etcd
      - pgsql
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 30s
        order: stop-first
        failure_action: rollback

volumes:
  pgkeeper1:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/pgsql"
  pgkeeper2:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/pgsql"
  pgkeeper3:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/pgsql"

secrets:
  pgsql:
    file: "/srv/docker/postgres"
  pgsql_repl:
    file: "/srv/docker/replica"

networks:
  etcd:
    external: true
  pgsql:
    external: true

ہم راز تیار کرتے ہیں اور فائل کا استعمال کرتے ہیں:

# </dev/urandom tr -dc 234567890qwertyuopasdfghjkzxcvbnmQWERTYUPASDFGHKLZXCVBNM | head -c $(((RANDOM%3)+15)) > /srv/docker/replica
# </dev/urandom tr -dc 234567890qwertyuopasdfghjkzxcvbnmQWERTYUPASDFGHKLZXCVBNM | head -c $(((RANDOM%3)+15)) > /srv/docker/postgres
# docker stack deploy --compose-file 01pgsql.yml pgsql

کچھ دیر بعد (کمانڈ کی آؤٹ پٹ دیکھیں ڈاکر سروس lsکہ تمام خدمات ختم ہیں) ہم Postgresql کلسٹر شروع کرتے ہیں:

# docker exec $(docker ps | awk '/pgkeeper/ {print $1}') stolonctl --cluster-name=stolon-cluster --store-backend=etcdv3 --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379 init

Postgresql کلسٹر کی تیاری کی جانچ کرنا:

# docker exec $(docker ps | awk '/pgkeeper/ {print $1}') stolonctl --cluster-name=stolon-cluster --store-backend=etcdv3 --store-endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379 status
=== Active sentinels ===

ID      LEADER
26baa11d    false
74e98768    false
a8cb002b    true

=== Active proxies ===

ID
4d233826
9f562f3b
b0c79ff1

=== Keepers ===

UID     HEALTHY PG LISTENADDRESS    PG HEALTHY  PG WANTEDGENERATION PG CURRENTGENERATION
pgkeeper1   true    pgkeeper1:5432         true     2           2
pgkeeper2   true    pgkeeper2:5432          true            2                   2
pgkeeper3   true    pgkeeper3:5432          true            3                   3

=== Cluster Info ===

Master Keeper: pgkeeper3

===== Keepers/DB tree =====

pgkeeper3 (master)
├─pgkeeper2
└─pgkeeper1

ہم باہر سے کنٹینرز تک رسائی کھولنے کے لیے ٹریفک کو ترتیب دیتے ہیں:

03traefik.yml

version: '3.7'

services:
  traefik:
    image: traefik:latest
    command: >
      --log.level=INFO
      --providers.docker=true
      --entryPoints.web.address=:80
      --providers.providersThrottleDuration=2
      --providers.docker.watch=true
      --providers.docker.swarmMode=true
      --providers.docker.swarmModeRefreshSeconds=15s
      --providers.docker.exposedbydefault=false
      --accessLog.bufferingSize=0
      --api=true
      --api.dashboard=true
      --api.insecure=true
    networks:
      - traefik
    ports:
      - 80:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == manager
        preferences:
          - spread: node.id
      labels:
        - traefik.enable=true
        - traefik.http.routers.traefik.rule=Host(`traefik.example.com`)
        - traefik.http.services.traefik.loadbalancer.server.port=8080
        - traefik.docker.network=traefik

networks:
  traefik:
    external: true

# docker stack deploy --compose-file 03traefik.yml traefik

ہم Redis کلسٹر لانچ کرتے ہیں، ایسا کرنے کے لیے ہم تمام نوڈس پر ایک اسٹوریج ڈائرکٹری بناتے ہیں۔

# mkdir -p /srv/redis

05redis.yml

version: '3.7'

services:
  redis-master:
    image: 'bitnami/redis:latest'
    networks:
      - redis
    ports:
      - '6379:6379'
    environment:
      - REDIS_REPLICATION_MODE=master
      - REDIS_PASSWORD=xxxxxxxxxxx
    deploy:
      mode: global
      restart_policy:
        condition: any
    volumes:
      - 'redis:/opt/bitnami/redis/etc/'

  redis-replica:
    image: 'bitnami/redis:latest'
    networks:
      - redis
    ports:
      - '6379'
    depends_on:
      - redis-master
    environment:
      - REDIS_REPLICATION_MODE=slave
      - REDIS_MASTER_HOST=redis-master
      - REDIS_MASTER_PORT_NUMBER=6379
      - REDIS_MASTER_PASSWORD=xxxxxxxxxxx
      - REDIS_PASSWORD=xxxxxxxxxxx
    deploy:
      mode: replicated
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: any

  redis-sentinel:
    image: 'bitnami/redis:latest'
    networks:
      - redis
    ports:
      - '16379'
    depends_on:
      - redis-master
      - redis-replica
    entrypoint: |
      bash -c 'bash -s <<EOF
      "/bin/bash" -c "cat <<EOF > /opt/bitnami/redis/etc/sentinel.conf
      port 16379
      dir /tmp
      sentinel monitor master-node redis-master 6379 2
      sentinel down-after-milliseconds master-node 5000
      sentinel parallel-syncs master-node 1
      sentinel failover-timeout master-node 5000
      sentinel auth-pass master-node xxxxxxxxxxx
      sentinel announce-ip redis-sentinel
      sentinel announce-port 16379
      EOF"
      "/bin/bash" -c "redis-sentinel /opt/bitnami/redis/etc/sentinel.conf"
      EOF'
    deploy:
      mode: global
      restart_policy:
        condition: any

volumes:
  redis:
    driver: local
    driver_opts:
      type: 'none'
      o: 'bind'
      device: "/srv/redis"

networks:
  redis:
    external: true

# docker stack deploy --compose-file 05redis.yml redis

ڈوکر رجسٹری شامل کریں:

06registry.yml

version: '3.7'

services:
  registry:
    image: registry:2.6
    networks:
      - traefik
    volumes:
      - registry_data:/var/lib/registry
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
      labels:
        - traefik.enable=true
        - traefik.http.routers.registry.rule=Host(`registry.example.com`)
        - traefik.http.services.registry.loadbalancer.server.port=5000
        - traefik.docker.network=traefik

volumes:
  registry_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/docker/registry"

networks:
  traefik:
    external: true

# mkdir /srv/docker/registry
# docker stack deploy --compose-file 06registry.yml registry

اور آخر میں - GitLab:

08gitlab-runner.yml

version: '3.7'

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    networks:
      - pgsql
      - redis
      - traefik
      - gitlab
    ports:
      - 22222:22
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        postgresql['enable'] = false
        redis['enable'] = false
        gitlab_rails['registry_enabled'] = false
        gitlab_rails['db_username'] = "gitlab"
        gitlab_rails['db_password'] = "XXXXXXXXXXX"
        gitlab_rails['db_host'] = "postgresql"
        gitlab_rails['db_port'] = "5432"
        gitlab_rails['db_database'] = "gitlab"
        gitlab_rails['db_adapter'] = 'postgresql'
        gitlab_rails['db_encoding'] = 'utf8'
        gitlab_rails['redis_host'] = 'redis-master'
        gitlab_rails['redis_port'] = '6379'
        gitlab_rails['redis_password'] = 'xxxxxxxxxxx'
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "smtp.yandex.ru"
        gitlab_rails['smtp_port'] = 465
        gitlab_rails['smtp_user_name'] = "[email protected]"
        gitlab_rails['smtp_password'] = "xxxxxxxxx"
        gitlab_rails['smtp_domain'] = "example.com"
        gitlab_rails['gitlab_email_from'] = '[email protected]'
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['smtp_tls'] = true
        gitlab_rails['smtp_enable_starttls_auto'] = true
        gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
        external_url 'http://gitlab.example.com/'
        gitlab_rails['gitlab_shell_ssh_port'] = 22222
    volumes:
      - gitlab_conf:/etc/gitlab
      - gitlab_logs:/var/log/gitlab
      - gitlab_data:/var/opt/gitlab
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
        - node.role == manager
      labels:
        - traefik.enable=true
        - traefik.http.routers.gitlab.rule=Host(`gitlab.example.com`)
        - traefik.http.services.gitlab.loadbalancer.server.port=80
        - traefik.docker.network=traefik
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    networks:
      - gitlab
    volumes:
      - gitlab_runner_conf:/etc/gitlab
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
        - node.role == manager

volumes:
  gitlab_conf:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/docker/gitlab/conf"
  gitlab_logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/docker/gitlab/logs"
  gitlab_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/docker/gitlab/data"
  gitlab_runner_conf:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: "/srv/docker/gitlab/runner"

networks:
  pgsql:
    external: true
  redis:
    external: true
  traefik:
    external: true
  gitlab:
    external: true

# mkdir -p /srv/docker/gitlab/conf
# mkdir -p /srv/docker/gitlab/logs
# mkdir -p /srv/docker/gitlab/data
# mkdir -p /srv/docker/gitlab/runner
# docker stack deploy --compose-file 08gitlab-runner.yml gitlab

کلسٹر اور خدمات کی آخری حالت:

# docker service ls
ID                  NAME                   MODE                REPLICAS            IMAGE                          PORTS
lef9n3m92buq        etcd_etcd1             replicated          1/1                 quay.io/coreos/etcd:latest
ij6uyyo792x5        etcd_etcd2             replicated          1/1                 quay.io/coreos/etcd:latest
fqttqpjgp6pp        etcd_etcd3             replicated          1/1                 quay.io/coreos/etcd:latest
hq5iyga28w33        gitlab_gitlab          replicated          1/1                 gitlab/gitlab-ce:latest        *:22222->22/tcp
dt7s6vs0q4qc        gitlab_gitlab-runner   replicated          1/1                 gitlab/gitlab-runner:latest
k7uoezno0h9n        pgsql_pgkeeper1        replicated          1/1                 sorintlab/stolon:master-pg10
cnrwul4r4nse        pgsql_pgkeeper2        replicated          1/1                 sorintlab/stolon:master-pg10
frflfnpty7tr        pgsql_pgkeeper3        replicated          1/1                 sorintlab/stolon:master-pg10
x7pqqchi52kq        pgsql_pgsentinel       replicated          3/3                 sorintlab/stolon:master-pg10
mwu2wl8fti4r        pgsql_postgresql       replicated          3/3                 sorintlab/stolon:master-pg10
9hkbe2vksbzb        redis_redis-master     global              3/3                 bitnami/redis:latest           *:6379->6379/tcp
l88zn8cla7dc        redis_redis-replica    replicated          3/3                 bitnami/redis:latest           *:30003->6379/tcp
1utp309xfmsy        redis_redis-sentinel   global              3/3                 bitnami/redis:latest           *:30002->16379/tcp
oteb824ylhyp        registry_registry      replicated          1/1                 registry:2.6
qovrah8nzzu8        traefik_traefik        replicated          3/3                 traefik:latest                 *:80->80/tcp, *:443->443/tcp

اور کیا بہتر کیا جا سکتا ہے؟ https پر کنٹینرز چلانے کے لیے Traefik کو ترتیب دینا یقینی بنائیں، Postgresql اور Redis کے لیے tls انکرپشن شامل کریں۔ لیکن عام طور پر، یہ پہلے سے ہی ڈویلپرز کو پی او سی کے طور پر دیا جا سکتا ہے۔ آئیے اب ڈوکر کے متبادل کو دیکھتے ہیں۔

پوڈ مین

پوڈز کے گروپ والے کنٹینرز کو چلانے کے لیے ایک اور کافی معروف انجن (پڈز، کنٹینرز کے گروپس ایک ساتھ تعینات)۔ Docker کے برعکس، اسے کنٹینرز چلانے کے لیے کسی سروس کی ضرورت نہیں ہے؛ تمام کام libpod لائبریری کے ذریعے کیا جاتا ہے۔ گو میں بھی لکھا ہوا ہے، کنٹینرز کو چلانے کے لیے OCI کے موافق رن ٹائم کی ضرورت ہوتی ہے، جیسے runC۔

ڈوکر اور سب کچھ، سب کچھ، سب کچھ

پوڈ مین کے ساتھ کام کرنا عام طور پر ڈوکر کے لیے اس کی یاد دلاتا ہے، یہاں تک کہ آپ اسے اس طرح کر سکتے ہیں (جیسا کہ بہت سے لوگوں نے کہا ہے جنہوں نے اسے آزمایا ہے، بشمول اس مضمون کے مصنف):

$ alias docker=podman

اور آپ کام جاری رکھ سکتے ہیں۔ عام طور پر، پوڈ مین کے ساتھ صورت حال بہت دلچسپ ہے، کیونکہ اگر کبرنیٹس کے ابتدائی ورژن ڈوکر کے ساتھ کام کرتے ہیں، تو 2015 کے آس پاس، کنٹینرز کی دنیا (OCI - اوپن کنٹینر انیشی ایٹو) کو معیاری بنانے اور ڈوکر کو کنٹینر اور runC میں تقسیم کرنے کے بعد، Kubernetes میں چلانے کے لیے Docker کا متبادل تیار ہو رہا ہے: CRI-O۔ اس سلسلے میں پوڈ مین ڈوکر کا متبادل ہے، جسے Kubernetes کے اصولوں پر بنایا گیا ہے، جس میں کنٹینرز کی گروپ بندی بھی شامل ہے، لیکن اس منصوبے کا بنیادی مقصد اضافی خدمات کے بغیر Docker طرز کے کنٹینرز کو لانچ کرنا ہے۔ واضح وجوہات کی بناء پر، کوئی بھیڑ موڈ نہیں ہے، کیونکہ ڈویلپر واضح طور پر کہتے ہیں کہ اگر آپ کو کلسٹر کی ضرورت ہے، تو Kubernetes لیں۔

تنصیب

Centos 7 پر انسٹال کرنے کے لیے، صرف Extras repository کو چالو کریں، اور پھر کمانڈ کے ساتھ سب کچھ انسٹال کریں:

# yum -y install podman

دوسرے امکانات

پوڈ مین سسٹمڈ کے لیے یونٹ تیار کر سکتا ہے، اس طرح سرور ریبوٹ کے بعد کنٹینرز شروع کرنے کا مسئلہ حل ہو جاتا ہے۔ مزید برآں، systemd کو کنٹینر میں pid 1 کے طور پر صحیح طریقے سے کام کرنے کا اعلان کیا گیا ہے۔ کنٹینرز کی تعمیر کے لیے ایک علیحدہ بلڈہ ٹول ہے، تھرڈ پارٹی ٹولز بھی ہیں - ڈوکر کمپوز کے اینالاگ، جو Kubernetes کے ساتھ مطابقت پذیر کنفیگریشن فائلیں بھی تیار کرتے ہیں، اس لیے Podman سے Kubernetes میں منتقلی کو جتنا ممکن ہو آسان بنایا جاتا ہے۔

پوڈ مین کے ساتھ کام کرنا

چونکہ کوئی بھیڑ موڈ نہیں ہے (اگر کسی کلسٹر کی ضرورت ہو تو ہمیں Kubernetes پر جانا چاہیے)، ہم اسے الگ کنٹینرز میں جمع کریں گے۔

پوڈ مین کمپوز انسٹال کریں:

# yum -y install python3-pip
# pip3 install podman-compose

پوڈ مین کے لیے نتیجے میں کنفیگریشن فائل قدرے مختلف ہے، اس لیے مثال کے طور پر ہمیں ایک علیحدہ والیوم سیکشن کو براہ راست سروسز کے ساتھ سیکشن میں منتقل کرنا پڑا۔

gitlab-podman.yml

version: '3.7'

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    hostname: gitlab.example.com
    restart: unless-stopped
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        gitlab_rails['gitlab_shell_ssh_port'] = 22222
    ports:
      - "80:80"
      - "22222:22"
    volumes:
      - /srv/podman/gitlab/conf:/etc/gitlab
      - /srv/podman/gitlab/data:/var/opt/gitlab
      - /srv/podman/gitlab/logs:/var/log/gitlab
    networks:
      - gitlab

  gitlab-runner:
    image: gitlab/gitlab-runner:alpine
    restart: unless-stopped
    depends_on:
      - gitlab
    volumes:
      - /srv/podman/gitlab/runner:/etc/gitlab-runner
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - gitlab

networks:
  gitlab:

# podman-compose -f gitlab-runner.yml -d up

نتیجہ:

# podman ps
CONTAINER ID  IMAGE                                  COMMAND               CREATED             STATUS                 PORTS                                      NAMES
da53da946c01  docker.io/gitlab/gitlab-runner:alpine  run --user=gitlab...  About a minute ago  Up About a minute ago  0.0.0.0:22222->22/tcp, 0.0.0.0:80->80/tcp  root_gitlab-runner_1
781c0103c94a  docker.io/gitlab/gitlab-ce:latest      /assets/wrapper       About a minute ago  Up About a minute ago  0.0.0.0:22222->22/tcp, 0.0.0.0:80->80/tcp  root_gitlab_1

آئیے دیکھتے ہیں کہ یہ systemd اور kubernetes کے لیے کیا پیدا کرتا ہے، اس کے لیے ہمیں پوڈ کا نام یا شناخت معلوم کرنے کی ضرورت ہے:

# podman pod ls
POD ID         NAME   STATUS    CREATED          # OF CONTAINERS   INFRA ID
71fc2b2a5c63   root   Running   11 minutes ago   3                 db40ab8bf84b

Kubernetes:

# podman generate kube 71fc2b2a5c63
# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-1.6.4
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2020-07-29T19:22:40Z"
  labels:
    app: root
  name: root
spec:
  containers:
  - command:
    - /assets/wrapper
    env:
    - name: PATH
      value: /opt/gitlab/embedded/bin:/opt/gitlab/bin:/assets:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: HOSTNAME
      value: gitlab.example.com
    - name: container
      value: podman
    - name: GITLAB_OMNIBUS_CONFIG
      value: |
        gitlab_rails['gitlab_shell_ssh_port'] = 22222
    - name: LANG
      value: C.UTF-8
    image: docker.io/gitlab/gitlab-ce:latest
    name: rootgitlab1
    ports:
    - containerPort: 22
      hostPort: 22222
      protocol: TCP
    - containerPort: 80
      hostPort: 80
      protocol: TCP
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
    volumeMounts:
    - mountPath: /var/opt/gitlab
      name: srv-podman-gitlab-data
    - mountPath: /var/log/gitlab
      name: srv-podman-gitlab-logs
    - mountPath: /etc/gitlab
      name: srv-podman-gitlab-conf
    workingDir: /
  - command:
    - run
    - --user=gitlab-runner
    - --working-directory=/home/gitlab-runner
    env:
    - name: PATH
      value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: HOSTNAME
    - name: container
      value: podman
    image: docker.io/gitlab/gitlab-runner:alpine
    name: rootgitlab-runner1
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
    volumeMounts:
    - mountPath: /etc/gitlab-runner
      name: srv-podman-gitlab-runner
    - mountPath: /var/run/docker.sock
      name: var-run-docker.sock
    workingDir: /
  volumes:
  - hostPath:
      path: /srv/podman/gitlab/runner
      type: Directory
    name: srv-podman-gitlab-runner
  - hostPath:
      path: /var/run/docker.sock
      type: File
    name: var-run-docker.sock
  - hostPath:
      path: /srv/podman/gitlab/data
      type: Directory
    name: srv-podman-gitlab-data
  - hostPath:
      path: /srv/podman/gitlab/logs
      type: Directory
    name: srv-podman-gitlab-logs
  - hostPath:
      path: /srv/podman/gitlab/conf
      type: Directory
    name: srv-podman-gitlab-conf
status: {}

سسٹمڈ:

# podman generate systemd 71fc2b2a5c63
# pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020

[Unit]
Description=Podman pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
Documentation=man:podman-generate-systemd(1)
Requires=container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
Before=container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service

[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa
ExecStop=/usr/bin/podman stop -t 10 db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/db40ab8bf84bf35141159c26cb6e256b889c7a98c0418eee3c4aa683c14fccaa/userdata/conmon.pid

[Install]
WantedBy=multi-user.target
# container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020

[Unit]
Description=Podman container-da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864.service
Documentation=man:podman-generate-systemd(1)
RefuseManualStart=yes
RefuseManualStop=yes
BindsTo=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
After=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service

[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864
ExecStop=/usr/bin/podman stop -t 10 da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/da53da946c01449f500aa5296d9ea6376f751948b17ca164df438b7df6607864/userdata/conmon.pid

[Install]
WantedBy=multi-user.target
# container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service
# autogenerated by Podman 1.6.4
# Thu Jul 29 15:23:28 EDT 2020

[Unit]
Description=Podman container-781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3.service
Documentation=man:podman-generate-systemd(1)
RefuseManualStart=yes
RefuseManualStop=yes
BindsTo=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service
After=pod-71fc2b2a5c6346f0c1c86a2dc45dbe78fa192ea02aac001eb8347ccb8c043c26.service

[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start 781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3
ExecStop=/usr/bin/podman stop -t 10 781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3
KillMode=none
Type=forking
PIDFile=/var/run/containers/storage/overlay-containers/781c0103c94aaa113c17c58d05ddabf8df4bf39707b664abcf17ed2ceff467d3/userdata/conmon.pid

[Install]
WantedBy=multi-user.target

بدقسمتی سے، کنٹینرز کو لانچ کرنے کے علاوہ، سسٹمڈ کے لیے تیار کردہ یونٹ کچھ اور نہیں کرتا ہے (مثال کے طور پر، پرانے کنٹینرز کی صفائی جب ایسی سروس دوبارہ شروع ہوتی ہے)، اس لیے آپ کو ایسی چیزیں خود لکھنی ہوں گی۔

اصولی طور پر، Podman یہ آزمانے کے لیے کافی ہے کہ کنٹینرز کیا ہیں، docker-compose کے لیے پرانی کنفیگریشنز کو منتقل کریں، اور پھر Kubernetes کی طرف بڑھیں، اگر آپ کو کلسٹر کی ضرورت ہو، یا Docker کا استعمال میں آسان متبادل حاصل کریں۔

Rkt

پروجیکٹ آرکائیوز میں چلا گیا تقریبا چھ ماہ قبل اس حقیقت کی وجہ سے کہ RedHat نے اسے خریدا تھا، لہذا میں اس پر مزید تفصیل سے غور نہیں کروں گا۔ مجموعی طور پر، اس نے بہت اچھا تاثر چھوڑا، لیکن Docker اور خاص طور پر Podman کے مقابلے میں، یہ ایک کمبائن کی طرح لگتا ہے۔ rkt کے اوپر ایک CoreOS ڈسٹری بیوشن بھی بنایا گیا تھا (حالانکہ ان کے پاس اصل میں Docker تھا)، لیکن یہ بھی RedHat خریداری کے بعد سپورٹ میں ختم ہو گیا۔

پلاش

مزید ایک منصوبہ، جس کا مصنف صرف کنٹینرز بنانا اور چلانا چاہتا تھا۔ دستاویزات اور کوڈ کے مطابق، مصنف نے معیارات کی پیروی نہیں کی، لیکن صرف اپنے عمل کو لکھنے کا فیصلہ کیا، جو اصولی طور پر، اس نے کیا.

نتائج

Kubernetes کے ساتھ صورتحال بہت دلچسپ ہے: ایک طرف، Docker کے ساتھ آپ ایک کلسٹر (swarm mode میں) بنا سکتے ہیں، جس کے ساتھ آپ کلائنٹس کے لیے پروڈکٹ ماحول بھی چلا سکتے ہیں، یہ خاص طور پر چھوٹی ٹیموں کے لیے درست ہے (3-5 افراد) ، یا ایک چھوٹے مجموعی بوجھ کے ساتھ، یا کبرنیٹس کے قیام کی پیچیدگیوں کو سمجھنے کی خواہش کی کمی، بشمول زیادہ بوجھ کے لیے۔

پوڈ مین مکمل مطابقت فراہم نہیں کرتا، لیکن اس کا ایک اہم فائدہ ہے - Kubernetes کے ساتھ مطابقت، بشمول اضافی ٹولز (buildah اور دیگر)۔ لہذا، میں کام کے لیے ایک ٹول کے انتخاب کے لیے مندرجہ ذیل طریقے سے رجوع کروں گا: چھوٹی ٹیموں کے لیے، یا محدود بجٹ کے ساتھ - ڈوکر (ممکنہ سوارم موڈ کے ساتھ)، ذاتی لوکل ہوسٹ پر اپنے لیے تیار کرنے کے لیے - پوڈ مین کامریڈز، اور باقی سب کے لیے۔ - Kubernetes.

مجھے یقین نہیں ہے کہ مستقبل میں ڈوکر کے ساتھ صورتحال نہیں بدلے گی، آخر کار، وہ علمبردار ہیں، اور مرحلہ وار معیاری بھی ہو رہے ہیں، لیکن پوڈ مین، اپنی تمام خامیوں کے لیے (صرف لینکس پر کام کرتا ہے، کوئی کلسٹرنگ نہیں، اسمبلی اور دیگر اعمال تیسرے فریق کے حل ہیں) مستقبل واضح ہے، لہذا میں تبصروں میں ان نتائج پر بحث کرنے کے لیے سب کو دعوت دیتا ہوں۔

PS 3 اگست کو ہم لانچ کرتے ہیں "ڈوکر ویڈیو کورس"، جہاں آپ اس کے کام کے بارے میں مزید جان سکتے ہیں۔ ہم اس کے تمام ٹولز کا تجزیہ کریں گے: بنیادی تجرید سے لے کر نیٹ ورک کے پیرامیٹرز تک، مختلف آپریٹنگ سسٹمز اور پروگرامنگ زبانوں کے ساتھ کام کرنے کی باریکیاں۔ آپ ٹیکنالوجی سے واقف ہو جائیں گے اور سمجھ جائیں گے کہ Docker کو کہاں اور کس طرح استعمال کرنا ہے۔ ہم بہترین پریکٹس کیسز بھی شیئر کریں گے۔

ریلیز سے پہلے پری آرڈر کی قیمت: RUB 5000۔ آپ ڈوکر ویڈیو کورس پروگرام دیکھ سکتے ہیں۔ کورس کے صفحے پر.

ماخذ: www.habr.com

نیا تبصرہ شامل کریں