การ deploy ไปยัง server ที่ต้องการด้วย ssh บน Gitlab CI

DevOps Apr 14, 2019

ในการทำเขียน gitlab-ci.yml นั้นเราสามารถกำหนดได้หลาย stage โดยปกติที่ผมใช้จะเป็น build > test > release > deploy

Build ผมจะเอาไว้ติดตั้ง packet ต่างๆ ของแอพพลิเคชั่น เช่น node_modules/ หรือ vendor/

Release ผมจะเอาไว้ทำ docker image แล้ว push เก็บขึ้นไปยัง private docker registry ที่ต้องการ

Test ไว้เรียกคำสั่ง unittest

Deploy ก็คือขั้นตอนที่เราจะเอาแอพพลิเคชั่นของเราไปใช้งานบน server จริง โดยปกติถ้าทำเองก็จะต้องเปิด Terminal ขึ้นมาแล้วก็ ssh เข้าไปยัง server ที่ต้องการจากนั้นก็ docker pull เอง แล้วจากนั้นก็กำหนดคำสั่งที่ต้องการไป

ผมเลยจะมาแนะนำวิธีการให้ gitlab-ci นั้นสามารถ ssh ไปยัง server ของเราได้ แล้วจากนั้นจะให้มันใช้คำสั่งอะไรต่อก็แล้วแต่เราจะกำหนดละ

สร้าง ssh-key บน server

ขั้นแรกให้เรา ssh เข้าไปยัง server ที่จะทำการ deploy จากนั้นใช้คำสั่ง ssh-keygen จากนั้นกด enter ไปเลยไม่ต้องใส่อะไร

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx root@ichamp
The key's randomart image is:
+---[RSA 2048]----+
| .=+o            |
| o=+.            |
| B+o  .          |
|=.+oo. .         |
|o=+*.E. S        |
|oo*.*oo=         |
|++ oo...o        |
|o.  o.+  .       |
|   .+* oo        |
+----[SHA256]-----+

เราก็จะได้ id_rsa กับ id_rsa.pub มาโดยดูได้จาก ls ~/.ssh

$ ls ~/.ssh/
authorized_keys  id_rsa  id_rsa.pub

ให้ทำการนำค่าจาก id_rsa.pub มาใส่ไว้ใน authorized_keys ใครไม่มีไฟล์นี้ก็สร้างเพิ่มเอาได้

$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

จากนั้น copy ข้อมูลใน id_rsa ออกมาจะได้ประมาณนี้ ซึ่งมันคือ private key

$ cat ~/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
xxxxx
xxxxx
xxxxx
-----END RSA PRIVATE KEY-----

นำค่า private key มาเก็บไว้ใน variable ของ gitlab ในโปรเจ็คเรา ใครไม่รู้สร้างยังไงสามารถดูได้จาก วิธีใช้งาน variable ใน gitlab

เก็บ private key ไว้ใน variable

โค็ดตัวอย่างไฟล์ .gitlab.yml

variables:
  DEV_SSH: "ssh root@12.345.678.9"

dev-deploy:
  stage: deploy
  image: twinsynergy/deploy
  environment:
    name: Development
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - mkdir -p ~/.ssh
    - eval $(ssh-agent -s)
    - echo "$DEV_PRIVATE_KEY" > ./key.file
    - chmod 400 ./key.file
    - ssh-add ./key.file
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
  script:
    - $DEV_SSH "docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY"
    - $DEV_SSH "docker pull $CI_REGISTRY_IMAGE:$DEV_BRANCH"
    - $DEV_SSH "git -C /root/example-app/ reset --hard HEAD"
    - $DEV_SSH "git -C /root/example-app/ pull"
    - $DEV_SSH "docker-compose -f /root/example-app/dev.yml down"
    - $DEV_SSH "docker-compose -f /root/example-app/dev.yml up -d"
    - $DEV_SSH "docker image prune -f"
  only:
    - dev-release

หลังจากเราเตรียม ssh-key บน server เรียบร้อยแล้วเรามาดูในส่วนของไฟล์ .gitlab-ci.yml บ้างจากโค็ดด้านบนในส่วนของ before_script: จะเป็นการเตรียม ssh-key ที่ได้จาก server ของเรามาใส่ไว้เพื่อให้สามารถ ssh เข้าไปได้

สังเกตุว่าจะมี echo "$DEV_PRIVATE_KEY" > ./key.file ซึ่งค่า $DEV_PRIVATE_KEY ก็คือ private key ที่ถูกกำหนดมาจากด้านบน

จากนั้นใน script: เราก็จะสามารถ ssh เข้าไปยัง server เราได้แล้วโดยคำสั่งจะเป็นแบบนี้

ssh root@xxx.xxx.xxx.xx "echo hello world"

เพียงเท่านี้ตัว gitlab-ci ของเราก็สามารถ ssh ไปยัง server ของเราได้แล้ว

ขอให้สนุกกับการเขียน gitlab-ci นะครับ

Arnon Kijlerdphon

IT manager & DevOps @Twin Synergy Co.,Ltd

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.