ข้ามไปที่เนื้อหาหลัก

Docker registry คือ ที่เก็บ image (image repository) ทำให้เราสามารถ push/pull image ผ่านทางเครือข่ายได้อย่างสะดวกรวดเร็ว

Docker #5 : Registry

Docker registry คือ ที่เก็บ image (image repository) ทำให้เราสามารถ push/pull image ผ่านทางเครือข่ายได้อย่างสะดวกรวดเร็ว เป็นการทำงานเหมือนกับ http://hub.docker.com นอกจากนี้ ยังเป็นส่วนหนึ่งที่ใช้ในการทำ distribution pipeline เวลาทำ continuous integration (ci) อีกด้วย
ไม่อย่างนั้นก็ต้องใช้ท่าพื้นฐานคือ
$ docker save -o <path to store image> <image name>
จากนั้ันก็ upload ผ่าน scp และเวลาจะใช้ก็ติดตั้งโดยใช้
$ docker load -i <image.tar.gz>
import เข้ามาในระบบ
ในกรณีที่มี client ใช้งานพร้อมกันหลายเครื่อง และอยากทำระบบการ push/pull แบบ local network เอง อย่างรวดเร็ว เราสามารถสร้างบริการ private docker registry มาได้ โดยมีการให้บริการ 2 แบบ คือ (อ้างอิง)
  1. แบบปลอดภัย เป็นค่า default ของ docker มีการใช้งาน SSL และ Certificate (ต้องมี verified https)
  2. แบบไม่ปลอดภัย เรียกว่าแบบ insecure-registry แบ่งเป็น
    2.1) plain http registry สามารถ push/pull ได้เลย
    2.2) self-signed ซึ่งจะต้อง copy certificate ไปยังเครื่องลูกด้วย
ในบทความนี้จะติดตั้งแบบ 2.1 plain http registry เนื่องจากเครื่องที่ใช้งานไม่มี SSL และ Certificate ซึ่งมี ขั้นตอนหลักอยู่ 4 ขั้นตอน คือ 1) start registry 2) tag image กับ url 3) push image ไป และ 4) pull image ลงมา จบ

ติดตั้ง Docker registry

เริ่มต้นด้วยการ pull registry image มาก่อน
$ docker pull registry:2
เนื่องจากการสั่งให้ทำงานแบบ insecure จะต้องไปกำหนด registry server ที่ /etc/systemd/system/docker.service (systemd ของ debian 8.6) /etc/default/docker (upstart ของ ubuntu)แต่ใน debian 8.6 ที่ผมใช้ดันมี /etc/default/docker แต่ไม่มี /etc/systemd/system/docker.service
ตอนแรกผมไปแก้ใน /lib/systemd/system/docker.service โดยเพิ่ม --insecure-registry yourRegistryServer:5000ใน DOCKER_OPTS ไม่เช่นนั้น เครื่อง client จะติดต่อผ่าน https ทำให้ไม่สามารถใช้งาน registry ได้ (ซึ่งก็ทำงานได้) แต่ได้คำแนะนำจาก อ.เอ็มว่า ควร override ใน /etc/systemd/system/docker.service มากกว่า ดังนี้
$ cat > /etc/systemd/system/docker.service.d/registry.conf << EOF
[Service]
ExecStart=
ExecStart=-/usr/bin/dockerd -H fd://--insecure-registry 172.x6.1x7.x1:5000
EOF
(มี ExecStart= อันแรก เป็นการล้างค่าเก่า แล้ว override ExecStart ใหม่ ด้วยอีกบรรทัด) หลังจากแก้ไขใน docker.service แล้ว จะต้องสั่ง เพื่อ update ค่าดังนี้
$ systemctl daemon-reload
$ systemctl show docker | grep ExecStart
$ systemctl restart docker
หมายเหตุ: ถ้ายังไม่มี directory /etc/systemd/system/docker.service.d ให้สร้างด้วยคำสั่ง
$ mkdir -pv /etc/systemd/system/docker.service.d/
ประเด็นเรื่องการ set ค่า insecure-registry นี้ มีพูดถึงพอสมควรใน #issue9889 และใน nknu.net
ตรวจสอบว่า registry server ถูกเพิ่มแบบ insecure ไปแล้ว โดยใช้ $ docker info
Insecure Registries:
 172.x6.1x7.x1:5000
 127.0.0.0/8
สั่งให้ registry เริ่มทำงาน
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2

Upload image ไปยัง registry

ทดลองติดตั้ง hello-world image โดย pull มาจาก docker hub ก่อน ดังนี้
$ docker pull hello-world
ติด tag เพื่อบอกว่า hello-world image ให้ link โดยใช้ url นี้
$ docker tag hello-world 172.x6.1x7.x1:5000/hello-world
ตรวจสอบผลการทำงาน จาก
$ docker images
ทำการ push hello-world image ลงไปใน registry server
$ docker push 172.x6.1x7.x1:5000/hello-world
เพียงเท่านี้ เป็นอันเสร็จพิธี ทางฝั่ง registry server หากต้องการแชร์ image อะไรเพิ่มเติม ก็ติด tag แล้ว push ไป ในทางปฏิบัติ อาจจะทำ volume ของ image ก่อนจะ start registry server เพื่อรับประกันได้ว่า image จะไม่หายไปไหน

กำหนด insecure mode ในเครื่อง client

ในเครื่อง client จำเป็นต้องบอกว่า registry server แบบ insecure อยู่ที่ไหน ถ้าเป็น linux debian 8.6 ก็กำหนดได้เหมือนข้างบน แต่ถ้าเป็น Docker Toolbox v1.12.x จะกำหนดที่ /var/lib/boot2docker/profile ซึ่งไฟล์ profile จะอยู่ข้างในเครื่อง default จะต้อง $ docker-machine ssh default ก่อน จึงจะสามารถเปิดไฟล์นี้ได้ จากนั้นเปลี่ยนสิทธิ์เป็น root และ เข้าไปเพิ่ม — insecure-registry ตามภาพ
แต่ปัญหาอย่างหนึ่งคือ ข้างใน VM ที่มากับ Docker Toolbox 1.12.x จะไม่มี editor ใด ๆ เลย vim, vi, nano, pico (น่าเศร้าจริง ๆ) ไม่มี apt-get ข้างในให้ลงโปรแกรมเพิ่มด้วย ดังนั้นเราต้อง copy ไฟล์ออกมาข้างนอกเครื่อง default (boot2docker) ก่อน แล้วค่อย copy กลับเข้าไปข้างใน
$ docker-machine.exe scp default:/var/lib/boot2docker/profile .
เนื่องจากต้องใช้สิทธิ์ root ของ container ในการ copy ไฟล์ profile กลับเข้าไปที่เดิม ดังนั้นเราจึงต้อง copy ไปใส่ใน /tmp ก่อน
$ docker-machine.exe scp profile default:/tmp/profile 
จากนั้นค่อย ssh เข้าไปใน default เปลี่ยนสิทธิ์เป็น root ($sudo su) แล้ว copy ไปวางใน path ให้ถูกต้องอีกที (#cp /tmp/profile /var/lib/boot2docker/) เมื่อเสร็จเรียบร้อยแล้ว ให้ reload configure โดย /etc/init.d/docker restart
สั่ง $ docker info เพื่อตรวจสอบสถานะ insecure อีกรอบ ถ้า service ยังค้าง IP หรือ domain ที่ใส่เพิ่มใน insecure registry ยังไม่แสดง อาจจะต้อง restart ตัว VM แต่ถ้า restart VM เมื่อไหร่ สิ่งที่เราแก้ใน container ก็จะหายไป ซึ่งต้องใช้ท่านี้แทน คือ การไปแก้ที่ไฟล์ C:\Program Files\Docker Toolbox\start.sh ก่อนที่จะ start VM เลย (แต่ไม่แนะนำ)
“${DOCKER_MACHINE}” create -d virtualbox --engine-insecure-registry 172.x6.1x7.x1:5000 $PROXY_ENV “${VM}”
แล้วก็สั่ง start VM ใหม่ คราวนี้ สั่ง $ docker info น่าจะหมดปัญหาแล้ว

Download image จาก registry

สั่ง pull เหมือนกับดึงจาก hub.docker.com เพียงแต่จำเป็นต้องใส่ domain name หรือ IP ของ registry server ให้ด้วยดังนี้
$ docker pull 172.x6.1x7.x1:5000/hello-world
ทดลองสั่ง $docker images เพื่อตรวจสอบดูว่า hello-world ถูก download มาติดตั้งเรียบร้อยแล้ว เป็นอันเสร็จงาน
ปิดท้าย: วิธีการนี้ ง่าย สะดวก รวดเร็ว แต่ก็มีโอกาสโดน Man In The Middle (MITM) เพราะไม่ได้เป็นการเชื่อมต่อแบบ https อย่างไรก็ดี หาก set เพื่อใช้งานส่วนตัว และมี firewall กั้น ไม่ให้คนนอก เข้าถึงระบบเครือข่ายก็ไม่เป็นไรครับ

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

Docker ทำอะไรได้มากกว่า run container มาหาคำตอบกัน — Part 2

Homepage Upgrade จริงๆ แล้ว Docker ทำอะไรได้มากกว่า run container มาหาคำตอบกัน — Part 2 Apipol Sukgler Aug 11, 2018 8.อยาก Persist Data ต้องทำอย่างไร อย่าง redis ที่ถ้าไม่ทำ persist data ข้อมูลที่อยู่ด้านในก็จะหายไปทันที ถ้าเกิด redis ดับไป โดยการทำ persist ข้อมูลเก็บไว้ได้โดยใช้ option -v ในการ mount volume ออกมาภายนอก docker run -v /docker/redis-data:/data --name redis -d redis redis-server --appendonly yes redis-server — appendonly yes — เป็น Mode ที่จะทำ persist data ลงในไฟล์ appendonly.aof ทุกครั้งที่มีการเปลี่ยนแปลงข้อมูลใน redis เอาข้อมูลใน appendonly.aof ที่อยู่ใน /data ออกมานอก container ใน directory /docker/redis-data From now on, every time Redis receives a command that changes the dataset (e.g.  SET ) it will append it to the AOF. When you restart Redis it will re-play the AOF to rebuild the state ( Ref ) จากนั้นเราลอง set ค่าเข้า redis โดยใช้ redis-cli docker exec -i redis redis-cli > set data "hello world" หรืออ...