We are not waiting for future, We create the future

Tags


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

14th April 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 นะครับ

IT manager & DevOps @Twin Synergy Co.,Ltd

View Comments