Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชจเชฎเชธเซเชคเซ‡! เชคเชพเชœเซ‡เชคเชฐเชฎเชพเช‚, เชกเซ‹เช•เชฐ เชˆเชฎเซ‡เชœเซ€เชธ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เชœเชฎเชพเชตเชŸ เชฎเชพเชŸเซ‡ เชฌเช‚เชจเซ‡ เชฎเชพเชŸเซ‡ เช˜เชฃเชพ เชถเชพเชจเชฆเชพเชฐ เช“เชŸเซ‹เชฎเซ‡เชถเชจ เชŸเซ‚เชฒเซเชธ เชฌเชนเชพเชฐ เชชเชพเชกเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เช›เซ‡. เช† เชธเช‚เชฆเชฐเซเชญเซ‡, เชฎเซ‡เช‚ เช—เชฟเชŸเชฒเซ‡เชฌ เชธเชพเชฅเซ‡ เชฐเชฎเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚, เชคเซ‡เชจเซ€ เช•เซเชทเชฎเชคเชพเช“เชจเซ‹ เชธเช‚เชชเซ‚เชฐเซเชฃ เช…เชญเซเชฏเชพเชธ เช•เชฐเซเชฏเซ‹ เช…เชจเซ‡, เช…เชฒเชฌเชคเซเชค, เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชธเซ‡เชŸ เช•เชฐเซ€.

เช† เช•เชพเชฐเซเชฏ เชตเซ‡เชฌเชธเชพเช‡เชŸ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเซ‡เชฐเชฟเชค เชนเชคเซเช‚ kubernetes.io, เชœเซ‡เชฎเชพเช‚เชฅเซ€ เชชเซ‡เชฆเชพ เชฅเชพเชฏ เช›เซ‡ เชธเซเชคเซเชฐเซ‹เชค เช•เซ‹เชกเซเชธ เช†เชชเชฎเซ‡เชณเซ‡, เช…เชจเซ‡ เชฆเชฐเซ‡เช• เชชเซ‚เชฒ เชตเชฟเชจเช‚เชคเซ€ เชฎเซ‹เช•เชฒเชตเชพ เชฎเชพเชŸเซ‡, เชฐเซ‹เชฌเซ‹เชŸ เช†เชชเชฎเซ‡เชณเซ‡ เชคเชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเชพเชฅเซ‡ เชธเชพเช‡เชŸเชจเซเช‚ เชชเซ‚เชฐเซเชตเชพเชตเชฒเซ‹เช•เชจ เชธเช‚เชธเซเช•เชฐเชฃ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชเช• เชฒเชฟเช‚เช• เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡.

เชฎเซ‡เช‚ เชถเชฐเซ‚เช†เชคเชฅเซ€ เชธเชฎเชพเชจ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชฌเชจเชพเชตเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซเชฏเซ‹, เชชเชฐเช‚เชคเซ เชธเช‚เชชเซ‚เชฐเซเชฃ เชฐเซ€เชคเซ‡ Gitlab CI เช…เชจเซ‡ เชฎเชซเชค เชŸเซ‚เชฒเซเชธ เชชเชฐ เชฌเชจเซ‡เชฒ เช›เซ‡ เชœเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชนเซเช‚ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซเชธ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเช‚ เช›เซเช‚. เช†เชœเซ‡ เชนเซเช‚ เชคเชฎเชจเซ‡ เช†เช–เชฐเซ‡ เชคเซ‡เชฎเชจเชพ เชตเชฟเชถเซ‡ เชตเชงเซ เชœเชฃเชพเชตเซ€เชถ.

เช† เชฒเซ‡เช– เชธเชพเชงเชจเซ‹เชจเซ€ เชšเชฐเซเชšเชพ เช•เชฐเชถเซ‡ เชœเซ‡เชฎ เช•เซ‡:
เชนเซเชฏเซเช—เซ‹, qbec, เช•เชจเชฟเช•เซ‹, git-เช•เซเชฐเชฟเชชเซเชŸ ะธ เช—เชฟเชŸเชฒเซ‡เชฌ เชธเซ€.เช†เชˆ. เช—เชคเชฟเชถเซ€เชฒ เชตเชพเชคเชพเชตเชฐเชฃเชจเซ€ เชฐเชšเชจเชพ เชธเชพเชฅเซ‡.

เชธเชพเชฎเช—เซเชฐเซ€

  1. เชนเซเชฏเซเช—เซ‹เชจเซ‡ เชฎเชณเซ‹
  2. เชกเซ‹เช•เชฐเชซเชพเช‡เชฒ เชคเซˆเชฏเชพเชฐ เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช
  3. เช•เชจเชฟเช•เซ‹เชจเซ‡ เช“เชณเช–เชตเชพ
  4. qbec เชจเซ‡ เชœเชพเชฃเชตเซเช‚
  5. เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ-เชเช•เซเชเชฟเช•เซเชฏเซเชŸเชฐ เชธเชพเชฅเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช
  6. qbec เชธเชพเชฅเซ‡ เชนเซ‡เชฒเซเชฎ เชšเชพเชฐเซเชŸ เช—เซ‹เช เชตเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช
  7. เช—เชฟเชŸ-เช•เซเชฐเชฟเชชเซเชŸเชจเซ‹ เชชเชฐเชฟเชšเชฏ
  8. เชŸเซ‚เชฒเชฌเซ‹เช•เซเชธ เช‡เชฎเซ‡เชœ เชฌเชจเชพเชตเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช
  9. เช…เชฎเชพเชฐเซ€ เชชเซเชฐเชฅเชฎ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เช…เชจเซ‡ เชŸเซ…เช—เซเชธ เชฆเซเชตเชพเชฐเชพ เช›เชฌเซ€เช“เชจเซ€ เชเชธเซ‡เชฎเซเชฌเชฒเซ€
  10. เชœเชฎเชพเชตเชŸ เช“เชŸเซ‹เชฎเซ‡เชถเชจ
  11. เชฎเชพเชธเซเชŸเชฐ เชชเชฐ เชฆเชฌเชพเชฃ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เช•เชฒเชพเช•เซƒเชคเชฟเช“ เช…เชจเซ‡ เชเชธเซ‡เชฎเซเชฌเชฒเซ€
  12. เช—เชคเชฟเชถเซ€เชฒ เชตเชพเชคเชพเชตเชฐเชฃ
  13. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซ‹เชจเซ€ เชธเชฎเซ€เช•เซเชทเชพ เช•เชฐเซ‹

1. เชนเซเชฏเซเช—เซ‹เชจเซ‡ เชœเชพเชฃเชตเซเช‚

เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเชพ เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เช…เชฎเซ‡ เชนเซเชฏเซเช—เซ‹ เชชเชฐ เชฌเชจเซ‡เชฒ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เชชเซเชฐเช•เชพเชถเชจ เชธเชพเช‡เชŸ เชฌเชจเชพเชตเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เชถเซเช‚. เชนเซเชฏเซเช—เซ‹ เช เชธเซเชŸเซ‡เชŸเชฟเช• เช•เชจเซเชŸเซ‡เชจเซเชŸ เชœเชจเชฐเซ‡เชŸเชฐ เช›เซ‡.

เชœเซ‡เช“ เชธเซเชŸเซ‡เชŸเชฟเช• เชœเชจเชฐเซ‡เชŸเชฐเซเชธเชฅเซ€ เชชเชฐเชฟเชšเชฟเชค เชจเชฅเซ€, เชนเซเช‚ เชคเชฎเชจเซ‡ เชคเซ‡เชฎเชจเชพ เชตเชฟเชถเซ‡ เชฅเซ‹เชกเซเช‚ เชตเชงเซ เช•เชนเซ€เชถ. เชกเซ‡เชŸเชพเชฌเซ‡เช เช…เชจเซ‡ เช•เซ‡เชŸเชฒเชพเช• PHP เชธเชพเชฅเซ‡เชจเชพ เชชเชฐเช‚เชชเชฐเชพเช—เชค เชตเซ‡เชฌเชธเชพเช‡เชŸ เชเชจเซเชœเชฟเชจเชฅเซ€ เชตเชฟเชชเชฐเซ€เชค, เชœเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฆเซเชตเชพเชฐเชพ เชตเชฟเชจเช‚เชคเซ€ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เชคเซเชฏเชพเชฐเซ‡, เชซเซเชฒเชพเชฏ เชชเชฐ เชชเซƒเชทเซเช เซ‹ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡, เชธเซเชŸเซ‡เชŸเชฟเช• เชœเชจเชฐเซ‡เชŸเชฐเซเชธ เชฅเซ‹เชกเซ€ เช…เชฒเช— เชฐเซ€เชคเซ‡ เชกเชฟเชเชพเช‡เชจ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชคเซ‡เช“ เชคเชฎเชจเซ‡ เชธเซเชคเซเชฐเซ‹เชคเซ‹ เชฒเซ‡เชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡, เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เชฎเชพเชฐเซเช•เชกเชพเช‰เชจ เชฎเชพเชฐเซเช•เช…เชช เช…เชจเซ‡ เชฅเซ€เชฎ เชŸเซ‡เชฎเซเชชเชฒเซ‡เชŸเซเชธเชฎเชพเช‚ เชซเชพเช‡เชฒเซ‹เชจเซ‹ เชธเชฎเซ‚เชน, เชชเช›เซ€ เชคเซ‡เชฎเชจเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชฐเซ€เชคเซ‡ เชธเชฎเชพเชชเซเชค เชตเซ‡เชฌเชธเชพเช‡เชŸเชฎเชพเช‚ เช•เชฎเซเชชเชพเช‡เชฒ เช•เชฐเซ‹.

เชเชŸเชฒเซ‡ เช•เซ‡, เชชเชฐเชฟเชฃเชพเชฎเซ‡, เชคเชฎเชจเซ‡ เชเช• เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชฎเชพเชณเช–เซเช‚ เช…เชจเซ‡ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒเซ€ HTML เชซเชพเช‡เชฒเซ‹เชจเซ‹ เชธเชฎเซ‚เชน เชชเซเชฐเชพเชชเซเชค เชฅเชถเซ‡, เชœเซ‡เชจเซ‡ เชคเชฎเซ‡ เช•เซ‹เชˆเชชเชฃ เชธเชธเซเชคเชพ เชนเซ‹เชธเซเชŸเชฟเช‚เช— เชชเชฐ เช…เชชเชฒเซ‹เชก เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เช•เชพเชฐเซเชฏเช•เชพเชฐเซ€ เชตเซ‡เชฌเชธเชพเช‡เชŸ เชฎเซ‡เชณเชตเซ€ เชถเช•เซ‹ เช›เซ‹.

เชคเชฎเซ‡ เชนเซเชฏเซเช—เซ‹เชจเซ‡ เชธเซเชฅเชพเชจเชฟเช• เชฐเซ€เชคเซ‡ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เช…เชœเชฎเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹:

เชจเชตเซ€ เชธเชพเช‡เชŸ เชถเชฐเซ‚ เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช:

hugo new site docs.example.org

เช…เชจเซ‡ เชคเซ‡ เชœ เชธเชฎเชฏเซ‡ git เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€:

cd docs.example.org
git init

เช…เชคเซเชฏเชพเชฐ เชธเซเชงเซ€, เช…เชฎเชพเชฐเซ€ เชธเชพเช‡เชŸ เชจเซˆเชธเชฐเซเช—เชฟเช• เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเชพ เชชเชฐ เช•เช‚เชˆเช• เชฆเซ‡เช–เชพเชฏ เชคเซ‡ เชฎเชพเชŸเซ‡, เช†เชชเชฃเซ‡ เชธเซŒเชชเซเชฐเชฅเชฎ เชฅเซ€เชฎเชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡; เชฅเซ€เชฎ เช เชซเช•เซเชค เชจเชฎเซ‚เชจเชพเช“ เช…เชจเซ‡ เชธเซเชชเชทเซเชŸ เชจเชฟเชฏเชฎเซ‹เชจเซ‹ เชธเชฎเซ‚เชน เช›เซ‡ เชœเซ‡เชจเชพ เชฆเซเชตเชพเชฐเชพ เช…เชฎเชพเชฐเซ€ เชธเชพเช‡เชŸ เชœเชจเชฐเซ‡เชŸ เชฅเชพเชฏ เช›เซ‡.

เชฅเซ€เชฎ เชฎเชพเชŸเซ‡ เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚ เชœเชพเชฃเซ‹, เชœเซ‡, เชฎเชพเชฐเชพ เชฎเชคเซ‡, เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เชธเชพเช‡เชŸ เชฎเชพเชŸเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชฏเซ‹เช—เซเชฏ เช›เซ‡.

เชนเซเช‚ เช เชนเช•เซ€เช•เชค เชชเชฐ เชตเชฟเชถเซ‡เชท เชงเซเชฏเชพเชจ เช†เชชเชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚ เช•เซ‡ เช…เชฎเชพเชฐเซ‡ เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚ เชฅเซ€เชฎ เชซเชพเช‡เชฒเซ‹เชจเซ‡ เชธเชพเชšเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€; เชคเซ‡เชจเชพ เชฌเชฆเชฒเซ‡, เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชซเช•เซเชค เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช. git เชธเชฌเชฎเซ‹เชกเซเชฏเซเชฒ:

git submodule add https://github.com/matcornic/hugo-theme-learn themes/learn

เช†เชฎ, เช…เชฎเชพเชฐเซ€ เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚ เชซเช•เซเชค เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชธเชพเชฅเซ‡ เชธเซ€เชงเซ€ เชฐเซ€เชคเซ‡ เชธเช‚เชฌเช‚เชงเชฟเชค เชซเชพเช‡เชฒเซ‹ เชนเชถเซ‡, เช…เชจเซ‡ เช•เชจเซ‡เช•เซเชŸเซ‡เชก เชฅเซ€เชฎ เชšเซ‹เช•เซเช•เชธ เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€เชจเซ€ เชฒเชฟเช‚เช• เชคเชฐเซ€เช•เซ‡ เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚ เช•เชฎเชฟเชŸ เชคเชฐเซ€เช•เซ‡ เชฐเชนเซ‡เชถเซ‡, เชเชŸเชฒเซ‡ เช•เซ‡, เชคเซ‡เชจเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชฎเซ‚เชณ เชธเซเชคเซเชฐเซ‹เชคเชฎเชพเช‚เชฅเซ€ เช–เซ‡เช‚เชšเซ€ เชถเช•เชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเชพเชฅเซ€ เชกเชฐเชตเซเช‚ เชจเชนเซ€เช‚. เช…เชธเช‚เช—เชค เชซเซ‡เชฐเชซเชพเชฐเซ‹.

เชšเชพเชฒเซ‹ เชฐเซ‚เชชเชฐเซ‡เช–เชพเชจเซ‡ เช เซ€เช• เช•เชฐเซ€เช config.toml:

baseURL = "http://docs.example.org/"
languageCode = "en-us"
title = "My Docs Site"
theme = "learn"

เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เช† เชคเชฌเช•เซเช•เซ‡ เชคเชฎเซ‡ เชšเชฒเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹:

hugo server

เช…เชจเซ‡ เชธเชฐเชจเชพเชฎเซ‡ http://localhost:1313/ เช…เชฎเชพเชฐเซ€ เชจเชตเซ€ เชฌเชจเชพเชตเซ‡เชฒเซ€ เชตเซ‡เชฌเชธเชพเชˆเชŸ เชคเชชเชพเชธเซ‹, เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชฎเชพเช‚ เชฅเชฏเซ‡เชฒเชพ เชคเชฎเชพเชฎ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฌเซเชฐเชพเช‰เชเชฐเชฎเชพเช‚ เช–เซเชฒเซเชฒเชพ เชชเซ‡เชœเชจเซ‡ เช†เชชเชฎเซ‡เชณเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡, เช–เซ‚เชฌ เช…เชจเซเช•เซ‚เชณ!

เชฎเชพเช‚ เช•เชตเชฐ เชชเซ‡เชœ เชฌเชจเชพเชตเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เช content/_index.md:

# My docs site

## Welcome to the docs!

You will be very smart :-)

เชจเชตเชพ เชฌเชจเชพเชตเซ‡เชฒเชพ เชชเซƒเชทเซเช เชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชธเชพเช‡เชŸ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชซเช•เซเชค เชšเชฒเชพเชตเซ‹:

hugo

เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชธเชพเชฎเช—เซเชฐเซ€เช“ เชœเชพเชนเซ‡เชฐ/ เช…เชจเซ‡ เชคเชฎเชพเชฐเซ€ เชตเซ‡เชฌเชธเชพเช‡เชŸ เชนเชถเซ‡.
เชนเชพ, เชฎเชพเชฐเซเช— เชฆเซเชตเชพเชฐเชพ, เชšเชพเชฒเซ‹ เชคเชฐเชค เชœ เชคเซ‡เชจเซ‡ เช‰เชฎเซ‡เชฐเซ€เช .gitignore:

echo /public > .gitignore

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .
git commit -m "New site created"

2. เชกเซ‹เช•เชฐเชซเชพเชˆเชฒ เชคเซˆเชฏเชพเชฐ เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช

เช…เชฎเชพเชฐเชพ เชญเช‚เชกเชพเชฐเชจเซ€ เชฐเชšเชจเชพเชจเซ‡ เชตเซเชฏเชพเช–เซเชฏเชพเชฏเชฟเชค เช•เชฐเชตเชพเชจเซ‹ เชธเชฎเชฏ เช›เซ‡. เชนเซเช‚ เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เช†เชจเชพ เชœเซ‡เชตเซ€ เชตเชธเซเชคเซเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเช‚ เช›เซเช‚:

.
โ”œโ”€โ”€ deploy
โ”‚   โ”œโ”€โ”€ app1
โ”‚   โ””โ”€โ”€ app2
โ””โ”€โ”€ dockerfiles
    โ”œโ”€โ”€ image1
    โ””โ”€โ”€ image2

  • เชกเซ‹เช•เชฐเชซเชพเชˆเชฒเซเชธ/ - เชกเซ‹เช•เชฐเชซเชพเชˆเชฒเซเชธ เชธเชพเชฅเซ‡เชจเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เช“ เช…เชจเซ‡ เช…เชฎเชพเชฐเซ€ เชกเซ‹เช•เชฐ เชˆเชฎเซ‡เชœเซ€เชธ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชœเชฐเซ‚เชฐเซ€ เชฌเชงเซเช‚ เชธเชฎเชพเชตเซ‡ เช›เซ‡.
  • เชœเชฎเชพเชตเชตเซเช‚/ โ€” เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซ‹ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡เชจเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เช“ เชงเชฐเชพเชตเซ‡ เช›เซ‡

เช†เชฎ, เช…เชฎเซ‡ เชชเชพเชฅ เชธเชพเชฅเซ‡ เช…เชฎเชพเชฐเซ€ เชชเซเชฐเชฅเชฎ เชกเซ‹เช•เชฐเชซเชพเช‡เชฒ เชฌเชจเชพเชตเซ€เชถเซเช‚ เชกเซ‹เช•เชฐเชซเชพเชˆเชฒเซเชธ/เชตเซ‡เชฌเชธเชพเชˆเชŸ/เชกเซ‹เช•เชฐเชซเชพเชˆเชฒ

FROM alpine:3.11 as builder
ARG HUGO_VERSION=0.62.0
RUN wget -O- https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-64bit.tar.gz | tar -xz -C /usr/local/bin
ADD . /src
RUN hugo -s /src

FROM alpine:3.11
RUN apk add --no-cache darkhttpd
COPY --from=builder /src/public /var/www
ENTRYPOINT [ "/usr/bin/darkhttpd" ]
CMD [ "/var/www" ]

เชœเซ‡เชฎ เชคเชฎเซ‡ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, เชกเซ‹เช•เชฐเชซเชพเชˆเชฒเชฎเชพเช‚ เชฌเซ‡ เช›เซ‡ เชฅเซ€, เช† เชฒเช•เซเชทเชฃ เช•เชนเซ‡เชตเชพเชฏ เช›เซ‡ เชฎเชฒเซเชŸเชฟ-เชธเซเชŸเซ‡เชœ เชฌเชฟเชฒเซเชก เช…เชจเซ‡ เชคเชฎเชจเซ‡ เช…เช‚เชคเชฟเชฎ เชกเซ‹เช•เชฐ เชˆเชฎเซ‡เชœเชฎเชพเช‚เชฅเซ€ เชฌเชฟเชจเชœเชฐเซ‚เชฐเซ€ เชฆเชฐเซ‡เช• เชตเชธเซเชคเซเชจเซ‡ เชฌเชพเช•เชพเชค เชฐเชพเช–เชตเชพ เชฆเซ‡ เช›เซ‡.
เช†เชฎ, เช…เช‚เชคเชฟเชฎ เช›เชฌเซ€ เชซเช•เซเชค เชธเชฎเชพเชตเชถเซ‡ เชถเซเชฏเชพเชฎhttpd (เชนเชณเชตเชพ HTTP เชธเชฐเซเชตเชฐ) เช…เชจเซ‡ เชœเชพเชนเซ‡เชฐ/ - เช…เชฎเชพเชฐเซ€ เชธเซเชŸเซ‡เชŸเชฟเช•เชฒเซ€ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒเซ€ เชตเซ‡เชฌเชธเชพเช‡เชŸเชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€.

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add dockerfiles/website
git commit -m "Add Dockerfile for website"

3. เช•เชจเชฟเช•เซ‹เชจเซ‡ เชœเชพเชฃเชตเซเช‚

เชกเซ‹เช•เชฐ เช‡เชฎเซ‡เชœ เชฌเชฟเชฒเซเชกเชฐ เชคเชฐเซ€เช•เซ‡, เชฎเซ‡เช‚ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚ เช•เชจเชฟเช•เซ‹, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡เชจเชพ เช“เชชเชฐเซ‡เชถเชจ เชฎเชพเชŸเซ‡ เชกเซ‹เช•เชฐ เชกเชฟเชฎเชจเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€, เช…เชจเซ‡ เชฌเชฟเชฒเซเชก เชชเซ‹เชคเซ‡ เช•เซ‹เชˆเชชเชฃ เชฎเชถเซ€เชจ เชชเชฐ เชนเชพเชฅ เชงเชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เชถเช•เซ‡ เช›เซ‡ เช…เชจเซ‡ เช•เซ‡เชถเชจเซ‡ เชธเซ€เชงเซ€ เชฐเชœเชฟเชธเซเชŸเซเชฐเซ€เชฎเชพเช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡, เชคเซเชฏเชพเช‚ เชธเช‚เชชเซ‚เชฐเซเชฃ เชธเซเชตเชฟเชงเชพเชฏเซเช•เซเชค เชธเชคเชค เชธเซเชŸเซ‹เชฐเซ‡เชœเชจเซ€ เชœเชฐเซ‚เชฐเชฟเชฏเชพเชคเชจเซ‡ เชฆเซ‚เชฐ เช•เชฐเซ‡ เช›เซ‡.

เช›เชฌเซ€ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡, เชซเช•เซเชค เช•เชจเซเชŸเซ‡เชจเชฐ เชธเชพเชฅเซ‡ เชšเชฒเชพเชตเซ‹ kaniko เชตเชนเซ€เชตเชŸเช•เชฐเซเชคเชพ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชตเชฐเซเชคเชฎเชพเชจ เชฌเชฟเชฒเซเชก เชธเช‚เชฆเชฐเซเชญเชฎเชพเช‚ เชชเชธเชพเชฐ เช•เชฐเซ‹; เช† เชกเซ‹เช•เชฐ เชฆเซเชตเชพเชฐเชพ เชธเซเชฅเชพเชจเชฟเช• เชฐเซ€เชคเซ‡ เชชเชฃ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡:

docker run -ti --rm 
  -v $PWD:/workspace 
  -v ~/.docker/config.json:/kaniko/.docker/config.json:ro 
  gcr.io/kaniko-project/executor:v0.15.0 
  --cache 
  --dockerfile=dockerfiles/website/Dockerfile 
  --destination=registry.gitlab.com/kvaps/docs.example.org/website:v0.0.1

เช•เซเชฏเชพเช‚ registry.gitlab.com/kvaps/docs.example.org/website - เชคเชฎเชพเชฐเซ€ เชกเซ‹เช•เชฐ เช‡เชฎเซ‡เชœเชจเซเช‚ เชจเชพเชฎ; เชฌเชจเชพเชตเซเชฏเชพ เชชเช›เซ€, เชคเซ‡ เช†เชชเชฎเซ‡เชณเซ‡ เชกเซ‹เช•เชฐ เชฐเชœเชฟเชธเซเชŸเซเชฐเซ€เชฎเชพเช‚ เชฒเซ‹เช‚เชš เชฅเชถเซ‡.

เชชเซ‡เชฐเชพเชฎเซ€เชŸเชฐ --เช•เซ‡เชถ เชคเชฎเชจเซ‡ เชกเซ‹เช•เชฐ เชฐเชœเชฟเชธเซเชŸเซเชฐเซ€เชฎเชพเช‚ เชธเซเชคเชฐเซ‹ เช•เซ‡เชถ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡; เช†เชชเซ‡เชฒ เช‰เชฆเชพเชนเชฐเชฃ เชฎเชพเชŸเซ‡, เชคเซ‡เช“ เช†เชฎเชพเช‚ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ registry.gitlab.com/kvaps/docs.example.org/website/cache, เชชเชฐเช‚เชคเซ เชคเชฎเซ‡ เชชเซ‡เชฐเชพเชฎเซ€เชŸเชฐเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช…เชจเซเชฏ เชชเชพเชฅเชจเซ‹ เช‰เชฒเซเชฒเซ‡เช– เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ --cache-repo.

เชกเซ‹เช•เชฐ-เชฐเชœเชฟเชธเซเชŸเซเชฐเซ€เชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

4. qbec เชจเซ‡ เชœเชพเชฃเชตเซเช‚

Qbec เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ เชŸเซ‚เชฒ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ เชคเชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฎเซ‡เชจเชฟเชซเซ‡เชธเซเชŸเชจเซ‡ เช˜เซ‹เชทเชฃเชพเชคเซเชฎเช• เชฐเซ€เชคเซ‡ เชตเชฐเซเชฃเชตเชตเชพ เช…เชจเซ‡ เชคเซ‡เชฎเชจเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เชœเชฎเชพเชตเชŸ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เชฎเซเช–เซเชฏ เชตเชพเช•เซเชฏเชฐเชšเชจเชพ เชคเชฐเซ€เช•เซ‡ Jsonnet เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชฅเซ€ เชคเชฎเซ‡ เชฌเชนเซเชตเชฟเชง เชตเชพเชคเชพเชตเชฐเชฃเชฎเชพเช‚ เชคเชซเชพเชตเชคเซ‹เชจเชพ เชตเชฐเซเชฃเชจเชจเซ‡ เชฎเซ‹เชŸเชพ เชชเซเชฐเชฎเชพเชฃเชฎเชพเช‚ เชธเชฐเชณ เชฌเชจเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹, เช…เชจเซ‡ เช•เซ‹เชก เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจเชจเซ‡ เชฒเช—เชญเช— เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชฆเซ‚เชฐ เช•เชฐเซ‡ เช›เซ‡.

เช† เช–เชพเชธ เช•เชฐเซ€เชจเซ‡ เชเชตเชพ เช•เชฟเชธเซเชธเชพเช“เชฎเชพเช‚ เชธเชพเชšเซเช‚ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡ เช•เซ‡ เชœเซเชฏเชพเช‚ เชคเชฎเชพเชฐเซ‡ เชตเชฟเชตเชฟเชง เชชเชฐเชฟเชฎเชพเชฃเซ‹ เชธเชพเชฅเซ‡ เช•เซ‡เชŸเชฒเชพเช• เช•เซเชฒเชธเซเชŸเชฐเซ‹เชฎเชพเช‚ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชœเชฎเชพเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ เช…เชจเซ‡ เช—เชฟเชŸเชฎเชพเช‚ เช˜เซ‹เชทเชฃเชพเชคเซเชฎเช• เชฐเซ€เชคเซ‡ เชคเซ‡เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเชตเชพ เชฎเชพเช‚เช—เชคเชพ เชนเซ‹.

Qbec เชคเชฎเชจเซ‡ เชœเชฐเซ‚เชฐเซ€ เชชเชฐเชฟเชฎเชพเชฃเซ‹ เชชเชธเชพเชฐ เช•เชฐเซ€เชจเซ‡ เชนเซ‡เชฒเซเชฎ เชšเชพเชฐเซเชŸเชจเซ‡ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเชตเชพเชจเซ€ เชชเชฃ เชชเชฐเชตเชพเชจเช—เซ€ เช†เชชเซ‡ เช›เซ‡ เช…เชจเซ‡ เชชเช›เซ€ เชคเซ‡เชจเซ‡ เชจเชฟเชฏเชฎเชฟเชค เชฎเซ‡เชจเชฟเชซเซ‡เชธเซเชŸเชจเซ€ เชœเซ‡เชฎ เชธเช‚เชšเชพเชฒเชฟเชค เช•เชฐเซ‡ เช›เซ‡, เชœเซ‡เชฎเชพเช‚ เชคเชฎเซ‡ เชคเซ‡เชจเชพ เชชเชฐ เชตเชฟเชตเชฟเชง เชชเชฐเชฟเชตเชฐเซเชคเชจเซ‹ เชฒเชพเช—เซ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เช…เชจเซ‡ เช† เชฌเชฆเชฒเชพเชฎเชพเช‚, เชคเชฎเชจเซ‡ เชœเชฐเซ‚เชฐเชฟเชฏเชพเชคเชฅเซ€ เช›เซเชŸเช•เชพเชฐเซ‹ เชฎเซ‡เชณเชตเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เชšเชพเชฐเซเชŸ เชฎเซเชฏเซเชเชฟเชฏเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹. เชเชŸเชฒเซ‡ เช•เซ‡, เชคเชฎเซ‡ เชšเชพเชฐเซเชŸเซเชธเชจเซ‡ เชธเซ€เชงเชพ เชœ เช—เชฟเชŸเชฎเชพเช‚เชฅเซ€ เชธเซเชŸเซ‹เชฐ เช…เชจเซ‡ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เชœเซเชฏเชพเช‚ เชคเซ‡เช“ เชธเช‚เชฌเช‚เชงเชฟเชค เช›เซ‡.

เชฎเซ‡เช‚ เช…เช—เชพเช‰ เช•เชนเซเชฏเซเช‚ เชคเซ‡เชฎ, เช…เชฎเซ‡ เชคเชฎเชพเชฎ เชœเชฎเชพเชตเชŸเชจเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชฎเชพเช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเซ€เชถเซเช‚ เชœเชฎเชพเชตเชตเซเช‚/:

mkdir deploy
cd deploy

เชšเชพเชฒเซ‹ เช…เชฎเชพเชฐเซ€ เชชเซเชฐเชฅเชฎ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชถเชฐเซ‚ เช•เชฐเซ€เช:

qbec init website
cd website

เชนเชตเซ‡ เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ เชฐเชšเชจเชพ เช†เชจเชพ เชœเซ‡เชตเซ€ เชฆเซ‡เช–เชพเชฏ เช›เซ‡:

.
โ”œโ”€โ”€ components
โ”œโ”€โ”€ environments
โ”‚   โ”œโ”€โ”€ base.libsonnet
โ”‚   โ””โ”€โ”€ default.libsonnet
โ”œโ”€โ”€ params.libsonnet
โ””โ”€โ”€ qbec.yaml

เชšเชพเชฒเซ‹ เชซเชพเชˆเชฒ เชœเซ‹เชˆเช qbec.yaml:

apiVersion: qbec.io/v1alpha1
kind: App
metadata:
  name: website
spec:
  environments:
    default:
      defaultNamespace: docs
      server: https://kubernetes.example.org:8443
  vars: {}

เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เชฎเซเช–เซเชฏเชคเซเชตเซ‡ เชฐเชธ เชงเชฐเชพเชตเซ€เช เช›เซ€เช spec.Environments, qbec เช เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เช…เชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เชกเชฟเชซเซ‹เชฒเซเชŸ เชเชจเซเชตเชพเชฏเชฐเซเชจเชฎเซ‡เชจเซเชŸ เชฌเชจเชพเชตเซเชฏเซเช‚ เช›เซ‡ เช…เชจเซ‡ เชธเชฐเซเชตเชฐ เชธเชฐเชจเชพเชฎเซเช‚, เชคเซ‡เชฎเชœ เช…เชฎเชพเชฐเซ€ เชตเชฐเซเชคเชฎเชพเชจ kubeconfig เชฎเชพเช‚เชฅเซ€ เชจเซ‡เชฎเชธเซเชชเซ‡เชธ เชฒเซ€เชงเซเช‚ เช›เซ‡.
เชนเชตเซ‡ เชœเซเชฏเชพเชฐเซ‡ เชคเซˆเชจเชพเชค เชฎเซ‚เชณเชญเซ‚เชค เชชเชฐเซเชฏเชพเชตเชฐเชฃ, qbec เชนเช‚เชฎเซ‡เชถเชพ เชฎเชพเชคเซเชฐ เช‰เชฒเซเชฒเซ‡เช–เชฟเชค Kubernetes เช•เซเชฒเชธเซเชŸเชฐ เช…เชจเซ‡ เช‰เชฒเซเชฒเซ‡เช–เชฟเชค เชจเซ‡เชฎเชธเซเชชเซ‡เชธเชฎเชพเช‚ เชœ เชœเชฎเชพเชตเชŸ เช•เชฐเชถเซ‡, เชเชŸเชฒเซ‡ เช•เซ‡, เชœเชฎเชพเชตเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเซ‡ เชธเช‚เชฆเชฐเซเชญเซ‹ เช…เชจเซ‡ เชจเซ‡เชฎเชธเซเชชเซ‡เชธ เชตเชšเซเชšเซ‡ เชธเซเชตเชฟเชš เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€.
เชœเซ‹ เชœเชฐเซ‚เชฐเซ€ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เช† เชซเชพเช‡เชฒเชฎเชพเช‚ เชธเซ‡เชŸเชฟเช‚เช—เซเชธ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เชคเชฎเชพเชฐเชพ เชฌเชงเชพ เชตเชพเชคเชพเชตเชฐเชฃเชฎเชพเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ เช›เซ‡ qbec.yaml, เช…เชจเซ‡ เชซเชพเช‡เชฒเชฎเชพเช‚ params.libsonnet, เชœเซเชฏเชพเช‚ เชคเซ‡ เช•เชนเซ‡ เช›เซ‡ เช•เซ‡ เชคเซ‡เชฎเชจเชพ เชฎเชพเชŸเซ‡ เชชเชฐเชฟเชฎเชพเชฃเซ‹ เช•เซเชฏเชพเช‚เชฅเซ€ เชฎเซ‡เชณเชตเชตเซเช‚.

เช†เช—เชณ เช†เชชเชฃเซ‡ เชฌเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เช“ เชœเซ‹เชˆเช เช›เซ€เช:

  • เช˜เชŸเช•เซ‹/ - เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฎเชพเชŸเซ‡เชจเชพ เชคเชฎเชพเชฎ เชฎเซ‡เชจเชฟเชซเซ‡เชธเซเชŸเซเชธ เช…เชนเซ€เช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡; เชคเซ‡เชจเซเช‚ เชตเชฐเซเชฃเชจ jsonnet เช…เชจเซ‡ เชจเชฟเชฏเชฎเชฟเชค yaml เชซเชพเช‡เชฒเซ‹ เชฌเช‚เชจเซ‡เชฎเชพเช‚ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡
  • เชตเชพเชคเชพเชตเชฐเชฃ/ โ€” เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เช†เชชเชฃเชพ เชตเชพเชคเชพเชตเชฐเชฃ เชฎเชพเชŸเซ‡เชจเชพ เชคเชฎเชพเชฎ เชšเชฒ (เชชเซ‡เชฐเชพเชฎเซ€เชŸเชฐเซเชธ)เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เชถเซเช‚.

เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชฌเซ‡ เชซเชพเช‡เชฒเซ‹ เช›เซ‡:

  • Environments/base.libsonnet - เชคเซ‡เชฎเชพเช‚ เชคเชฎเชพเชฎ เชตเชพเชคเชพเชตเชฐเชฃ เชฎเชพเชŸเซ‡ เชธเชพเชฎเชพเชจเซเชฏ เชชเชฐเชฟเชฎเชพเชฃเซ‹ เชนเชถเซ‡
  • Environments/default.libsonnet โ€” เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชฎเชพเชŸเซ‡ เช“เชตเชฐเชฐเชพเช‡เชก เช•เชฐเซ‡เชฒเชพ เชชเชฐเชฟเชฎเชพเชฃเซ‹ เชธเชฎเชพเชตเซ‡ เช›เซ‡ เชฎเซ‚เชณเชญเซ‚เชค

เชšเชพเชฒเซ‹ เช–เซ‹เชฒเซ€เช Environments/base.libsonnet เช…เชจเซ‡ เชคเซเชฏเชพเช‚ เช…เชฎเชพเชฐเชพ เชชเซเชฐเชฅเชฎ เช˜เชŸเช• เชฎเชพเชŸเซ‡ เชชเชฐเชฟเชฎเชพเชฃเซ‹ เช‰เชฎเซ‡เชฐเซ‹:

{
  components: {
    website: {
      name: 'example-docs',
      image: 'registry.gitlab.com/kvaps/docs.example.org/website:v0.0.1',
      replicas: 1,
      containerPort: 80,
      servicePort: 80,
      nodeSelector: {},
      tolerations: [],
      ingressClass: 'nginx',
      domain: 'docs.example.org',
    },
  },
}

เชšเชพเชฒเซ‹ เช†เชชเชฃเซ‹ เชชเซเชฐเชฅเชฎ เช˜เชŸเช• เชชเชฃ เชฌเชจเชพเชตเซ€เช components/website.jsonnet:

local env = {
  name: std.extVar('qbec.io/env'),
  namespace: std.extVar('qbec.io/defaultNs'),
};
local p = import '../params.libsonnet';
local params = p.components.website;

[
  {
    apiVersion: 'apps/v1',
    kind: 'Deployment',
    metadata: {
      labels: { app: params.name },
      name: params.name,
    },
    spec: {
      replicas: params.replicas,
      selector: {
        matchLabels: {
          app: params.name,
        },
      },
      template: {
        metadata: {
          labels: { app: params.name },
        },
        spec: {
          containers: [
            {
              name: 'darkhttpd',
              image: params.image,
              ports: [
                {
                  containerPort: params.containerPort,
                },
              ],
            },
          ],
          nodeSelector: params.nodeSelector,
          tolerations: params.tolerations,
          imagePullSecrets: [{ name: 'regsecret' }],
        },
      },
    },
  },
  {
    apiVersion: 'v1',
    kind: 'Service',
    metadata: {
      labels: { app: params.name },
      name: params.name,
    },
    spec: {
      selector: {
        app: params.name,
      },
      ports: [
        {
          port: params.servicePort,
          targetPort: params.containerPort,
        },
      ],
    },
  },
  {
    apiVersion: 'extensions/v1beta1',
    kind: 'Ingress',
    metadata: {
      annotations: {
        'kubernetes.io/ingress.class': params.ingressClass,
      },
      labels: { app: params.name },
      name: params.name,
    },
    spec: {
      rules: [
        {
          host: params.domain,
          http: {
            paths: [
              {
                backend: {
                  serviceName: params.name,
                  servicePort: params.servicePort,
                },
              },
            ],
          },
        },
      ],
    },
  },
]

เช† เชซเชพเช‡เชฒเชฎเชพเช‚ เช…เชฎเซ‡ เชเช• เชธเชพเชฅเซ‡ เชคเซเชฐเชฃ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชเชจเซเชŸเชฟเชŸเซ€เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซเชฏเซเช‚ เช›เซ‡, เช† เช›เซ‡: เชกเชฟเชชเซเชฒเซ‹เชฏเชฎเซ‡เชจเซเชŸ, เชธเซ‡เชตเชพ ะธ เชชเซเชฐเชตเซ‡เชถ. เชœเซ‹ เช†เชชเชฃเซ‡ เช‡เชšเซเช›เซ€เช เชคเซ‹, เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชตเชฟเชตเชฟเชง เช˜เชŸเช•เซ‹เชฎเชพเช‚ เชฎเซ‚เช•เซ€ เชถเช•เซ€เช เช›เซ€เช, เชชเชฐเช‚เชคเซ เช† เชคเชฌเช•เซเช•เซ‡ เช…เชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เชเช• เชชเซ‚เชฐเชคเซเช‚ เชนเชถเซ‡.

เชตเชพเช•เซเชฏเชฐเชšเชจเชพ jsonnet เชจเชฟเชฏเชฎเชฟเชค json เชœเซ‡เชตเซเช‚ เชœ เช›เซ‡, เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชฐเซ€เชคเซ‡, เชจเชฟเชฏเชฎเชฟเชค json เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เชฎเชพเชจเซเชฏ jsonnet เช›เซ‡, เชคเซ‡เชฅเซ€ เชถเชฐเซ‚เช†เชคเชฎเชพเช‚ เชคเชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เช‘เชจเชฒเชพเช‡เชจ เชธเซ‡เชตเชพเช“เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชตเชงเซ เชธเชฐเชณ เชฌเชจเซ€ เชถเช•เซ‡ เช›เซ‡ เชœเซ‡เชฎ เช•เซ‡ yaml2json เชคเชฎเชพเชฐเชพ เชธเชพเชฎเชพเชจเซเชฏ yaml เชจเซ‡ json เชฎเชพเช‚ เชฐเซ‚เชชเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฅเชตเชพ, เชœเซ‹ เชคเชฎเชพเชฐเชพ เช˜เชŸเช•เซ‹เชฎเชพเช‚ เช•เซ‹เชˆ เชšเชฒ เชจ เชนเซ‹เชฏ, เชคเซ‹ เชคเซ‡เชจเซเช‚ เชตเชฐเซเชฃเชจ เชจเชฟเชฏเชฎเชฟเชค yaml เชจเชพ เชฐเซ‚เชชเชฎเชพเช‚ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡.

เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ jsonnet เชนเซเช‚ เชคเชฎเชพเชฐเชพ เชธเช‚เชชเชพเชฆเช• เชฎเชพเชŸเซ‡ เชชเซเชฒเช—เช‡เชจ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเชตเชพเชจเซ€ เช–เซ‚เชฌ เชญเชฒเชพเชฎเชฃ เช•เชฐเซเช‚ เช›เซเช‚

เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชตเชฟเชฎ เชฎเชพเชŸเซ‡ เชชเซเชฒเช—เช‡เชจ เช›เซ‡ vim-jsonnet, เชœเซ‡ เชธเชฟเชจเซเชŸเซ‡เช•เซเชธ เชนเชพเช‡เชฒเชพเช‡เชŸเชฟเช‚เช— เชšเชพเชฒเซ เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เช†เชชเชฎเซ‡เชณเซ‡ เชเช•เซเชเชฟเช•เซเชฏเซเชŸ เชฅเชพเชฏ เช›เซ‡ jsonnet fmt เชœเซเชฏเชพเชฐเซ‡ เชชเชฃ เชคเชฎเซ‡ เชธเชพเชšเชตเซ‹ เช›เซ‹ (เชœเซ‡เชธเซ‹เชจเซ‡เชŸ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเชตเซเช‚ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡).

เชฌเชงเซเช‚ เชคเซˆเชฏเชพเชฐ เช›เซ‡, เชนเชตเซ‡ เช…เชฎเซ‡ เชœเชฎเชพเชตเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช:

เช…เชฎเชจเซ‡ เชถเซเช‚ เชฎเชณเซเชฏเซเช‚ เชคเซ‡ เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡, เชšเชพเชฒเซ‹ เชšเชฒเชพเชตเซ€เช:

qbec show default

เช†เช‰เชŸเชชเซเชŸ เชชเชฐ, เชคเชฎเซ‡ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเซ‡เชฒ yaml เชฎเซ‡เชจเชฟเชซเซ‡เชธเซเชŸ เชœเซ‹เชถเซ‹ เชœเซ‡ เชกเชฟเชซเซ‹เชฒเซเชŸ เช•เซเชฒเชธเซเชŸเชฐ เชชเชฐ เชฒเชพเช—เซ เชฅเชถเซ‡.

เชธเชฐเชธ, เชนเชตเซ‡ เช…เชฐเชœเซ€ เช•เชฐเซ‹:

qbec apply default

เช†เช‰เชŸเชชเซเชŸ เชชเชฐ เชคเชฎเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชœเซ‹เชถเซ‹ เช•เซ‡ เชคเชฎเชพเชฐเชพ เช•เซเชฒเชธเซเชŸเชฐเชฎเชพเช‚ เชถเซเช‚ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡, qbec เชคเชฎเชจเซ‡ เชŸเชพเชˆเชช เช•เชฐเซ€เชจเซ‡ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเชพเชฅเซ‡ เชธเช‚เชฎเชค เชฅเชตเชพ เชฎเชพเชŸเซ‡ เช•เชนเซ‡เชถเซ‡. y เชคเชฎเซ‡ เชคเชฎเชพเชฐเชพ เช‡เชฐเชพเชฆเชพเชจเซ€ เชชเซเชทเซเชŸเชฟ เช•เชฐเซ€ เชถเช•เชถเซ‹.

เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชคเซˆเชฏเชพเชฐ เช…เชจเซ‡ เชคเซˆเชจเชพเชค เช›เซ‡!

เชœเซ‹ เชคเชฎเซ‡ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเซ‹ เช›เซ‹, เชคเซ‹ เชคเชฎเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เช† เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹:

qbec diff default

เช† เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชตเชฐเซเชคเชฎเชพเชจ เชœเชฎเชพเชตเชŸเชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช…เชธเชฐ เช•เชฐเชถเซ‡ เชคเซ‡ เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

cd ../..
git add deploy/website
git commit -m "Add deploy for website"

5. เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ-เชเช•เซเชเชฟเช•เซเชฏเซเชŸเชฐ เชธเชพเชฅเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชคเชพเชœเซ‡เชคเชฐเชฎเชพเช‚ เชธเซเชงเซ€ เชนเซเช‚ เชซเช•เซเชค เชจเชฟเชฏเชฎเชฟเชค เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ‹ เชนเชคเซ‹ gitlab-เชฐเชจเชฐ เชถเซ‡เชฒ เช…เชฅเชตเชพ เชกเซ‹เช•เชฐ-เชเช•เซเชเชฟเช•เซเชฏเซเชŸเชฐ เชธเชพเชฅเซ‡ เชชเซ‚เชฐเซเชต-เชคเซˆเชฏเชพเชฐ เชฎเชถเซ€เชจ (LXC เช•เชจเซเชŸเซ‡เชจเชฐ) เชชเชฐ. เชถเชฐเซ‚เช†เชคเชฎเชพเช‚, เช…เชฎเชพเชฐเซ€ เช—เชฟเชŸเชฒเซ‡เชฌเชฎเชพเช‚ เชตเซˆเชถเซเชตเชฟเช• เชธเซเชคเชฐเซ‡ เชตเซเชฏเชพเช–เซเชฏเชพเชฏเชฟเชค เชเชตเชพ เช˜เชฃเชพ เชฆเซ‹เชกเชตเซ€เชฐเซ‹ เชนเชคเชพ. เชคเซ‡เช“เช เชคเชฎเชพเชฎ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ เชฎเชพเชŸเซ‡ เชกเซ‹เช•เชฐ เช›เชฌเซ€เช“ เชเช•เชคเซเชฐเชฟเชค เช•เชฐเซ€.

เชชเชฐเช‚เชคเซ เชชเซเชฐเซ‡เช•เซเชŸเชฟเชธ เชฌเชคเชพเชตเซ‡ เช›เซ‡ เชคเซ‡เชฎ, เช† เชตเชฟเช•เชฒเซเชช เชตเซเชฏเชตเชนเชพเชฐเชฟเช•เชคเชพ เช…เชจเซ‡ เชธเชฒเชพเชฎเชคเซ€ เชฌเช‚เชจเซ‡เชจเซ€ เชฆเซเชฐเชทเซเชŸเชฟเช เชธเซŒเชฅเซ€ เช†เชฆเชฐเซเชถ เชจเชฅเซ€. เชฆเชฐเซ‡เช• เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฎเชพเชŸเซ‡ เช…เชฅเชตเชพ เชคเซ‹ เชฆเชฐเซ‡เช• เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชฎเชพเชŸเซ‡ เช…เชฒเช— เชฆเซ‹เชกเชตเซ€เชฐเซ‹ เชคเซˆเชจเชพเชค เช•เชฐเชตเชพ เชคเซ‡ เชตเชงเซ เชธเชพเชฐเซเช‚ เช…เชจเซ‡ เชตเซˆเชšเชพเชฐเชฟเช• เชฐเซ€เชคเซ‡ เชตเชงเซ เชฏเซ‹เช—เซเชฏ เช›เซ‡.

เชธเชฆเชจเชธเซ€เชฌเซ‡, เช† เช•เซ‹เชˆ เชธเชฎเชธเซเชฏเชพ เชจเชฅเซ€, เช•เชพเชฐเชฃ เช•เซ‡ เชนเชตเซ‡ เช…เชฎเซ‡ เชœเชฎเชพเชตเชถเซเช‚ gitlab-เชฐเชจเชฐ เชธเซ€เชงเชพ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธเชฎเชพเช‚ เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเชพ เชญเชพเช— เชฐเซ‚เชชเซ‡.

เช—เชฟเชŸเชฒเซ‡เชฌ เช•เซเชฌเชฐเชจเซ‡เชŸเซ€เชธเชจเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐเชจเซ‡ เชคเซˆเชจเชพเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชคเซˆเชฏเชพเชฐ เชนเซ‡เชฒเซเชฎ เชšเชพเชฐเซเชŸ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡. เชคเซ‡เชฅเซ€ เชคเชฎเชพเชฐเซ‡ เชซเช•เซเชค เชถเซ‹เชงเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เชจเซ‹เช‚เชงเชฃเซ€ เชŸเซ‹เช•เชจ เชฎเชพเช‚ เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฎเชพเชŸเซ‡ เชธเซ‡เชŸเชฟเช‚เช—เซเชธ -> CI / CD -> เชฐเชจเชฐเซเชธ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชธเซเช•เชพเชจ เชธเซ‹เช‚เชชเซ‹:

helm repo add gitlab https://charts.gitlab.io

helm install gitlab-runner 
  --set gitlabUrl=https://gitlab.com 
  --set runnerRegistrationToken=yga8y-jdCusVDn_t4Wxc 
  --set rbac.create=true 
  gitlab/gitlab-runner

เช•เซเชฏเชพเช‚:

  • https://gitlab.com - เชคเชฎเชพเชฐเชพ เช—เชฟเชŸเชฒเซ‡เชฌ เชธเชฐเซเชตเชฐเชจเซเช‚ เชธเชฐเชจเชพเชฎเซเช‚.
  • yga8y-jdCusVDn_t4Wxc - เชคเชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฎเชพเชŸเซ‡ เชจเซ‹เช‚เชงเชฃเซ€ เชŸเซ‹เช•เชจ.
  • rbac.create=true โ€” kubernetes-executor เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช…เชฎเชพเชฐเชพ เช•เชพเชฐเซเชฏเซ‹ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชชเซ‹เชกเซเชธ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชธเช•เซเชทเชฎ เชฅเชตเชพ เชฎเชพเชŸเซ‡ เชฐเชจเชฐเชจเซ‡ เชœเชฐเซ‚เชฐเซ€ เชตเชฟเชถเซ‡เชทเชพเชงเชฟเช•เชพเชฐเซ‹ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡.

เชœเซ‹ เชฌเชงเซเช‚ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเชพเชฐเซ‡ เชตเชฟเชญเชพเช—เชฎเชพเช‚ เชจเซ‹เช‚เชงเชพเชฏเซ‡เชฒ เชฐเชจเชฐ เชœเซ‹เชตเซ‹ เชœเซ‹เชˆเช เชฆเซ‹เชกเชตเซ€เชฐเซ‹, เชคเชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชธเซ‡เชŸเชฟเช‚เช—เซเชธเชฎเชพเช‚.

เช‰เชฎเซ‡เชฐเชพเชฏเซ‡เชฒ เชฐเชจเชฐเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชคเซ‡ เชธเชฐเชณ เช›เซ‡? - เชนเชพ, เชคเซ‡ เช–เซ‚เชฌ เชธเชฐเชณ เช›เซ‡! เชฎเซ‡เชจเซเชฏเซเช…เชฒเซ€ เชฆเซ‹เชกเชตเซ€เชฐเซ‹เชจเซ€ เชจเซ‹เช‚เชงเชฃเซ€ เช•เชฐเชตเชพเชฎเชพเช‚ เชนเชตเซ‡ เช•เซ‹เชˆ เชคเช•เชฒเซ€เชซ เชจเชนเซ€เช‚ เชชเชกเซ‡, เชนเชตเซ‡เชฅเซ€ เชฆเซ‹เชกเชตเซ€เชฐเซ‹ เช†เชชเซ‹เช†เชช เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เช…เชจเซ‡ เชจเชพเชถ เชชเชพเชฎเชถเซ‡.

6. QBEC เชธเชพเชฅเซ‡ เชนเซ‡เชฒเซเชฎ เชšเชพเชฐเซเชŸ เช—เซ‹เช เชตเซ‹

เช•เชพเชฐเชฃ เช•เซ‡ เช…เชฎเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‡เชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚ gitlab-เชฐเชจเชฐ เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเซ‹ เชเช• เชญเชพเช— เช›เซ‡, เชคเซ‡ เช…เชฎเชพเชฐเชพ เช—เชฟเชŸ เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚ เชคเซ‡เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเชตเชพเชจเซ‹ เชธเชฎเชฏ เช›เซ‡.

เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชเช• เช…เชฒเช— เช˜เชŸเช• เชคเชฐเซ€เช•เซ‡ เชตเชฐเซเชฃเชตเซ€ เชถเช•เซ€เช เช›เซ€เช เชตเซ‡เชฌเชธเชพเช‡เชŸ, เชชเชฐเช‚เชคเซ เชญเชตเชฟเชทเซเชฏเชฎเชพเช‚ เช…เชฎเซ‡ เชตเชฟเชตเชฟเชง เชจเช•เชฒเซ‹ เชœเชฎเชพเชตเชตเชพเชจเซ€ เชฏเซ‹เชœเชจเชพ เชฌเชจเชพเชตเซ€เช เช›เซ€เช เชตเซ‡เชฌเชธเชพเช‡เชŸ เช˜เชฃเซ€ เชตเชพเชฐ, เชตเชฟเชชเชฐเซ€เชค gitlab-เชฐเชจเชฐ, เชœเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เช•เซเชฒเชธเซเชŸเชฐ เชฆเซ€เช  เชฎเชพเชคเซเชฐ เชเช• เชœ เชตเชพเชฐ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชคเซ‹ เชšเชพเชฒเซ‹ เชคเซ‡เชจเชพ เชฎเชพเชŸเซ‡ เชเช• เช…เชฒเช— เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชถเชฐเซ‚ เช•เชฐเซ€เช:

cd deploy
qbec init gitlab-runner
cd gitlab-runner

เช† เชตเช–เชคเซ‡ เช…เชฎเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชเชจเซเชŸเชฟเชŸเซ€เชจเซเช‚ เชฎเซ‡เชจเซเชฏเซเช…เชฒเซ€ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เชถเซเช‚ เชจเชนเซ€เช‚, เชชเชฐเช‚เชคเซ เชคเซˆเชฏเชพเชฐ เชนเซ‡เชฒเซเชฎ เชšเชพเชฐเซเชŸ เชฒเชˆเชถเซเช‚. qbec เชจเซ‹ เชเช• เชซเชพเชฏเชฆเซ‹ เช เช›เซ‡ เช•เซ‡ Git เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚เชฅเซ€ เชธเซ€เชงเชพ เชนเซ‡เชฒเซเชฎ เชšเชพเชฐเซเชŸเซเชธ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ.

เชšเชพเชฒเซ‹ เชคเซ‡เชจเซ‡ เช—เชฟเชŸ เชธเชฌเชฎเซ‹เชกเซเชฏเซเชฒเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเซ€เช:

git submodule add https://gitlab.com/gitlab-org/charts/gitlab-runner vendor/gitlab-runner

เชนเชตเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชตเชฟเช•เซเชฐเซ‡เชคเชพ/เช—เซ€เชŸเชฒเซ‡เชฌ-เชฐเชจเชฐ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐ เชฎเชพเชŸเซ‡ เชšเชพเชฐเซเชŸ เชธเชพเชฅเซ‡เชจเซ‹ เชญเช‚เชกเชพเชฐ เช›เซ‡.

เชคเซ‡เชตเซ€ เชœ เชฐเซ€เชคเซ‡, เชคเชฎเซ‡ เช…เชจเซเชฏ เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€เชเชจเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชธเช‚เชชเซ‚เชฐเซเชฃ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชจเซ‡ เชธเชคเซเชคเชพเชตเชพเชฐ เชšเชพเชฐเซเชŸ เชธเชพเชฅเซ‡ https://github.com/helm/charts

เชšเชพเชฒเซ‹ เช˜เชŸเช•เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เช components/gitlab-runner.jsonnet:

local env = {
  name: std.extVar('qbec.io/env'),
  namespace: std.extVar('qbec.io/defaultNs'),
};
local p = import '../params.libsonnet';
local params = p.components.gitlabRunner;

std.native('expandHelmTemplate')(
  '../vendor/gitlab-runner',
  params.values,
  {
    nameTemplate: params.name,
    namespace: env.namespace,
    thisFile: std.thisFile,
    verbose: true,
  }
)

เชฎเชพเชŸเซ‡ เชชเซเชฐเชฅเชฎ เชฆเชฒเซ€เชฒ expandHelmTemplate เช…เชฎเซ‡ เชšเชพเชฐเซเชŸ เชชเชฐ เชชเชพเชฅ เชชเชธเชพเชฐ เช•เชฐเซ€เช เช›เซ€เช, เชชเช›เซ€ params.values, เชœเซ‡ เช†เชชเชฃเซ‡ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชชเชฐเชฟเชฎเชพเชฃเซ‹เชฎเชพเช‚เชฅเซ€ เชฒเชˆเช เช›เซ€เช, เชคเซ‡ เชชเช›เซ€ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เช†เชตเซ‡ เช›เซ‡

  • เชจเชพเชฎเชจเซ‹ เชขเชพเช‚เชšเซ‹ - เชชเซเชฐเช•เชพเชถเชจ เชจเชพเชฎ
  • เชจเชพเชฎเชธเซเชฅเชณ - เชจเซ‡เชฎเชธเซเชชเซ‡เชธ เชธเซเช•เชพเชจ เชชเชฐ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค
  • เช† เชซเชพเช‡เชฒ โ€” เชœเชฐเซ‚เชฐเซ€ เชชเชฐเชฟเชฎเชพเชฃ เช•เซ‡ เชœเซ‡ เชตเชฐเซเชคเชฎเชพเชจ เชซเชพเช‡เชฒเชจเซ‹ เชชเชพเชฅ เชชเชธเชพเชฐ เช•เชฐเซ‡ เช›เซ‡
  • เชตเชฐเซเชฌเซ‹เช - เช†เชฆเซ‡เชถ เชฌเชคเชพเชตเซ‡ เช›เซ‡ เชธเซเช•เชพเชจ เชจเชฎเซ‚เชจเซ‹ เชšเชพเชฐเซเชŸ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เชคเชฎเชพเชฎ เชฆเชฒเซ€เชฒเซ‹ เชธเชพเชฅเซ‡

เชนเชตเซ‡ เชšเชพเชฒเซ‹ เชฎเชพเช‚ เช†เชชเชฃเชพ เช˜เชŸเช• เชฎเชพเชŸเซ‡เชจเชพ เชชเชฐเชฟเชฎเชพเชฃเซ‹เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เช Environments/base.libsonnet:

local secrets = import '../secrets/base.libsonnet';

{
  components: {
    gitlabRunner: {
      name: 'gitlab-runner',
      values: {
        gitlabUrl: 'https://gitlab.com/',
        rbac: {
          create: true,
        },
        runnerRegistrationToken: secrets.runnerRegistrationToken,
      },
    },
  },
}

เชงเซเชฏเชพเชจ เช†เชชเซ‹ เชฆเซ‹เชกเชตเซ€เชฐ เชจเซ‹เช‚เชงเชฃเซ€ เชŸเซ‹เช•เชจ เช…เชฎเซ‡ เชฌเชพเชนเซเชฏ เชซเชพเช‡เชฒเชฎเชพเช‚เชฅเซ€ เชฒเชˆเช เช›เซ€เช secrets/base.libsonnet, เชšเชพเชฒเซ‹ เชคเซ‡เชจเซ‡ เชฌเชจเชพเชตเซ€เช:

{
  runnerRegistrationToken: 'yga8y-jdCusVDn_t4Wxc',
}

เชšเชพเชฒเซ‹ เชคเชชเชพเชธเซ€เช เช•เซ‡ เชฌเชงเซเช‚ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡ เช•เซ‡ เชจเชนเซ€เช‚:

qbec show default

เชœเซ‹ เชฌเชงเซเช‚ เชตเซเชฏเชตเชธเซเชฅเชฟเชค เชนเซ‹เชฏ, เชคเซ‹ เช…เชฎเซ‡ เชนเซ‡เชฒเซเชฎ เชฆเซเชตเชพเชฐเชพ เช…เชฎเชพเชฐเซ€ เช…เช—เชพเช‰ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡เชฒ เชชเซเชฐเช•เชพเชถเชจ เช•เชพเชขเซ€ เชจเชพเช–เซ€ เชถเช•เซ€เช เช›เซ€เช:

helm uninstall gitlab-runner

เช…เชจเซ‡ เชคเซ‡ เชœ เชฐเซ€เชคเซ‡ เชœเชฎเชพเชตเชตเชพ, เชชเชฐเช‚เชคเซ qbec เชฆเซเชตเชพเชฐเชพ:

qbec apply default

7. เช—เชฟเชŸ-เช•เซเชฐเชฟเชชเซเชŸเชจเซ‹ เชชเชฐเชฟเชšเชฏ

เช—เชฟเชŸ-เช•เซเชฐเชฟเชชเซเชŸ เชเช• เชธเชพเชงเชจ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ เชคเชฎเชพเชฐเซ€ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€ เชฎเชพเชŸเซ‡ เชชเชพเชฐเชฆเชฐเซเชถเช• เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชธเซ‡เชŸ เช•เชฐเชตเชพ เชฆเซ‡ เช›เซ‡.

เช† เช•เซเชทเชฃเซ‡, เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐ เชฎเชพเชŸเซ‡เชจเซ€ เช…เชฎเชพเชฐเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชฎเชพเชณเช–เซเช‚ เช†เชจเชพ เชœเซ‡เชตเซเช‚ เชฆเซ‡เช–เชพเชฏ เช›เซ‡:

.
โ”œโ”€โ”€ components
โ”‚   โ”œโ”€โ”€ gitlab-runner.jsonnet
โ”œโ”€โ”€ environments
โ”‚   โ”œโ”€โ”€ base.libsonnet
โ”‚   โ””โ”€โ”€ default.libsonnet
โ”œโ”€โ”€ params.libsonnet
โ”œโ”€โ”€ qbec.yaml
โ”œโ”€โ”€ secrets
โ”‚   โ””โ”€โ”€ base.libsonnet
โ””โ”€โ”€ vendor
    โ””โ”€โ”€ gitlab-runner (submodule)

เชชเชฐเช‚เชคเซ เช—เชฟเชŸเชฎเชพเช‚ เชฐเชนเชธเซเชฏเซ‹ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเซเช‚ เชธเชฒเชพเชฎเชค เชจเชฅเซ€, เชถเซเช‚ เชคเซ‡ เช›เซ‡? เชคเซ‡เชฅเซ€ เช†เชชเชฃเซ‡ เชคเซ‡เชฎเชจเซ‡ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เชเช• เชšเชฒ เช–เชพเชคเชฐ, เช† เชนเช‚เชฎเซ‡เชถเชพ เช…เชฐเซเชฅเชฎเชพเช‚ เชจเชฅเซ€. เชคเชฎเซ‡ เชฐเชนเชธเซเชฏเซ‹ เชŸเซเชฐเชพเชจเซเชธเชซเชฐ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ qbec เช…เชจเซ‡ เชคเชฎเชพเชฐเซ€ CI เชธเชฟเชธเซเชŸเชฎเชจเชพ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชšเชฒเซ‹ เชฆเซเชตเชพเชฐเชพ.
เชชเชฐเช‚เชคเซ เชคเซ‡ เชจเซ‹เช‚เชงเชตเซเช‚ เชฏเซ‹เช—เซเชฏ เช›เซ‡ เช•เซ‡ เชคเซเชฏเชพเช‚ เชตเชงเซ เชœเชŸเชฟเชฒ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ เชชเชฃ เช›เซ‡ เชœเซ‡เชฎเชพเช‚ เช˜เชฃเชพ เชตเชงเซ เชฐเชนเชธเซเชฏเซ‹ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡; เชคเซ‡ เชฌเชงเชพเชจเซ‡ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชšเชฒ เชฆเซเชตเชพเชฐเชพ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เช•เชฐเชตเซเช‚ เช…เชคเซเชฏเช‚เชค เชฎเซเชถเซเช•เซ‡เชฒ เชนเชถเซ‡.

เชคเชฆเซเชชเชฐเชพเช‚เชค, เช† เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เชนเซเช‚ เชคเชฎเชจเซ‡ เช†เชตเชพ เช…เชฆเซเชญเซเชค เชธเชพเชงเชจ เชตเชฟเชถเซ‡ เช•เชนเซ€ เชถเช•เชคเซ‹ เชจเชฅเซ€ git-เช•เซเชฐเชฟเชชเซเชŸ.

git-เช•เซเชฐเชฟเชชเซเชŸ เชคเซ‡ เชชเชฃ เช…เชจเซเช•เซ‚เชณ เช›เซ‡ เช•เซ‡ เชคเซ‡ เชคเชฎเชจเซ‡ เชฐเชนเชธเซเชฏเซ‹เชจเชพ เชธเชฎเช—เซเชฐ เช‡เชคเชฟเชนเชพเชธเชจเซ‡ เชธเชพเชšเชตเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡, เชธเชพเชฅเซ‡ เชธเชพเชฅเซ‡ เชธเชฐเช–เชพเชฎเชฃเซ€, เชฎเชฐเซเชœ เช…เชจเซ‡ เชคเช•เชฐเชพเชฐเชจเซ‡ เชคเซ‡ เชœ เชฐเซ€เชคเซ‡ เช‰เช•เซ‡เชฒเชตเชพ เชฆเซ‡ เช›เซ‡ เชœเซ‡ เชฐเซ€เชคเซ‡ เช†เชชเชฃเซ‡ เช—เชฟเชŸเชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชŸเซ‡เชตเชพเชฏเซ‡เชฒเชพ เช›เซ€เช.

เชธเซเชฅเชพเชชเชจ เชชเช›เซ€ เชชเซเชฐเชฅเชฎ เชตเชธเซเชคเซ git-เช•เซเชฐเชฟเชชเซเชŸ เช†เชชเชฃเซ‡ เช†เชชเชฃเซ€ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€ เชฎเชพเชŸเซ‡ เช•เซ€ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡:

git crypt init

เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ PGP เช•เซ€ เช›เซ‡, เชคเซ‹ เชคเชฎเซ‡ เชคเชฐเชค เชœ เช† เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฎเชพเชŸเซ‡ เชธเชนเชฏเซ‹เช—เซ€ เชคเชฐเซ€เช•เซ‡ เชคเชฎเชพเชฐเซ€ เชœเชพเชคเชจเซ‡ เช‰เชฎเซ‡เชฐเซ€ เชถเช•เซ‹ เช›เซ‹:

git-crypt add-gpg-user [email protected]

เช† เชฐเซ€เชคเซ‡ เชคเชฎเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชคเชฎเชพเชฐเซ€ เช–เชพเชจเช—เซ€ เช•เซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช† เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชจเซ‡ เชกเชฟเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เชœเซ‹ เชคเชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ PGP เช•เซ€ เชจเชฅเซ€ เช…เชจเซ‡ เชคเซ‡เชจเซ€ เช…เชชเซ‡เช•เซเชทเชพ เชจเชฅเซ€, เชคเซ‹ เชคเชฎเซ‡ เชฌเซ€เชœเซ€ เชฐเซ€เชคเซ‡ เชœเชˆเชจเซ‡ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เช•เซ€ เชจเชฟเช•เชพเชธ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹:

git crypt export-key /path/to/keyfile

เช†เชฎ, เชœเซ‡ เช•เซ‹เชˆ เชจเชฟเช•เชพเชธ เช•เชฐเซ‡ เช›เซ‡ เช•เซ€เชซเชพเชˆเชฒ เชคเชฎเชพเชฐเชพ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชจเซ‡ เชกเชฟเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เชธเช•เซเชทเชฎ เชนเชถเซ‡.

เช† เช…เชฎเชพเชฐเซเช‚ เชชเซเชฐเชฅเชฎ เชฐเชนเชธเซเชฏ เชธเซ‡เชŸ เช•เชฐเชตเชพเชจเซ‹ เชธเชฎเชฏ เช›เซ‡.
เชšเชพเชฒเซ‹ เชนเซเช‚ เชคเชฎเชจเซ‡ เชฏเชพเชฆ เช•เชฐเชพเชตเซเช‚ เช•เซ‡ เช…เชฎเซ‡ เชนเชœเซ€ เชชเชฃ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชฎเชพเช‚ เช›เซ€เช เชœเชฎเชพเชตเชŸ/gitlab-runner/, เชœเซเชฏเชพเช‚ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เช›เซ‡ เชฐเชนเชธเซเชฏเซ‹/, เชšเชพเชฒเซ‹ เชคเซ‡เชฎเชพเช‚เชจเซ€ เชฌเชงเซ€ เชซเชพเชˆเชฒเซ‹เชจเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเซ€เช, เช† เชฎเชพเชŸเซ‡ เช†เชชเชฃเซ‡ เชเช• เชซเชพเชˆเชฒ เชฌเชจเชพเชตเซ€เชถเซเช‚ เชฐเชนเชธเซเชฏเซ‹/.gitattributes เชจเซ€เชšเซ‡เชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชธเชพเชฅเซ‡:

* filter=git-crypt diff=git-crypt
.gitattributes !filter !diff

เชธเชพเชฎเช—เซเชฐเซ€เชฎเชพเช‚เชฅเซ€ เชœเซ‹เชˆ เชถเช•เชพเชฏ เช›เซ‡ เชคเซ‡เชฎ, เชฌเชงเซ€ เชซเชพเช‡เชฒเซ‹ เชฎเชพเชธเซเช• เช•เชฐเซ‡เชฒเซ€ เช›เซ‡ * เชฆเซเชตเชพเชฐเชพ เชšเชฒเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ git-เช•เซเชฐเชฟเชชเซเชŸ, เชธเซŒเชฅเซ€ เชธเชฟเชตเชพเชฏ .gitaattributes

เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชšเชฒเชพเชตเซ€เชจเซ‡ เชšเช•เชพเชธเซ€ เชถเช•เซ€เช เช›เซ€เช:

git crypt status -e

เช†เช‰เชŸเชชเซเชŸ เช เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚เชจเซ€ เชฌเชงเซ€ เชซเชพเชˆเชฒเซ‹เชจเซ€ เชฏเชพเชฆเซ€ เชนเชถเซ‡ เชœเซ‡เชจเชพ เชฎเชพเชŸเซ‡ เชเชจเซเช•เซเชฐเชฟเชชเซเชถเชจ เชธเช•เซเชทเชฎ เช›เซ‡

เชฌเชธ, เชนเชตเซ‡ เช…เชฎเซ‡ เชธเซเชฐเช•เซเชทเชฟเชค เชฐเซ€เชคเซ‡ เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช:

cd ../..
git add .
git commit -m "Add deploy for gitlab-runner"

เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชซเช•เซเชค เชšเชฒเชพเชตเซ‹:

git crypt lock

เช…เชจเซ‡ เชคเชฐเชค เชœ เชฌเชงเซ€ เชเชจเซเช•เซเชฐเชฟเชชเซเชŸเซ‡เชก เชซเชพเช‡เชฒเซ‹ เชฌเชพเชˆเชจเชฐเซ€ เช•เช‚เชˆเช•เชฎเชพเช‚ เชซเซ‡เชฐเชตเชพเชˆ เชœเชถเซ‡, เชคเซ‡เชฎเชจเซ‡ เชตเชพเช‚เชšเชตเซเช‚ เช…เชถเช•เซเชฏ เชนเชถเซ‡.
เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชจเซ‡ เชกเชฟเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชšเชฒเชพเชตเซ‹:

git crypt unlock

8. เชŸเซ‚เชฒเชฌเซ‹เช•เซเชธ เชˆเชฎเซ‡เชœ เชฌเชจเชพเชตเซ‹

เชŸเซ‚เชฒเชฌเซ‹เช•เซเชธ เช‡เชฎเซ‡เชœ เช เชคเชฎเชพเชฎ เชธเชพเชงเชจเซ‹ เชธเชพเชฅเซ‡เชจเซ€ เชเช• เช‡เชฎเซ‡เชœ เช›เซ‡ เชœเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช…เชฎเซ‡ เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเซ‡ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เช•เชฐเซ€เชถเซเช‚. เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช—เชฟเชŸเชฒเซ‡เชฌ เชฐเชจเชฐ เชฆเซเชตเชพเชฐเชพ เชฒเชพเช•เซเชทเชฃเชฟเช• เชœเชฎเชพเชตเชŸ เช•เชพเชฐเซเชฏเซ‹ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡.

เช…เชนเซ€เช‚ เชฌเชงเซเช‚ เชธเชฐเชณ เช›เซ‡, เชšเชพเชฒเซ‹ เชเช• เชจเชตเซเช‚ เชฌเชจเชพเชตเซ€เช เชกเซ‹เช•เชฐเชซเชพเชˆเชฒเซเชธ/เชŸเซ‚เชฒเชฌเซ‹เช•เซเชธ/เชกเซ‹เช•เชฐเชซเชพเชˆเชฒ เชจเซ€เชšเซ‡เชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชธเชพเชฅเซ‡:

FROM alpine:3.11

RUN apk add --no-cache git git-crypt

RUN QBEC_VER=0.10.3 
 && wget -O- https://github.com/splunk/qbec/releases/download/v${QBEC_VER}/qbec-linux-amd64.tar.gz 
     | tar -C /tmp -xzf - 
 && mv /tmp/qbec /tmp/jsonnet-qbec /usr/local/bin/

RUN KUBECTL_VER=1.17.0 
 && wget -O /usr/local/bin/kubectl 
      https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/linux/amd64/kubectl 
 && chmod +x /usr/local/bin/kubectl

RUN HELM_VER=3.0.2 
 && wget -O- https://get.helm.sh/helm-v${HELM_VER}-linux-amd64.tar.gz 
     | tar -C /tmp -zxf - 
 && mv /tmp/linux-amd64/helm /usr/local/bin/helm

เชœเซ‡เชฎ เชคเชฎเซ‡ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, เช† เชˆเชฎเซ‡เชœเชฎเชพเช‚ เช…เชฎเซ‡ เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเซ€เช•เซ‡เชถเชจ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช—เชฎเชพเช‚ เชฒเซ‡เชตเชพเชคเซ€ เชคเชฎเชพเชฎ เช‰เชชเชฏเซ‹เช—เชฟเชคเชพเช“เชจเซ‡ เชˆเชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ€เช เช›เซ€เช. เช…เชฎเชพเชฐเซ‡ เช…เชนเซ€เช‚ เชคเซ‡เชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€ เชธเชฟเชตเชพเชฏ เช•เซ‡ kubectl, เชชเชฐเช‚เชคเซ เชคเชฎเซ‡ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชธเซ‡เชŸเช…เชช เชคเชฌเช•เซเช•เชพ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชคเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เชฐเชฎเชตเชพ เชฎเชพเช—เซ€ เชถเช•เซ‹ เช›เซ‹.

เช‰เชชเชฐเชพเช‚เชค, เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชธเชพเชฅเซ‡ เชตเชพเชคเชšเซ€เชค เช•เชฐเชตเชพ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เชธเช•เซเชทเชฎ เชฅเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเชพเชฐเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐ เชฆเซเชตเชพเชฐเชพ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡เชฒเชพ เชชเซ‹เชกเซเชธ เชฎเชพเชŸเซ‡ เชญเซ‚เชฎเชฟเช•เชพ เช—เซ‹เช เชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชšเชพเชฒเซ‹ gitlab-runner เชธเชพเชฅเซ‡ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€เชฎเชพเช‚ เชœเชˆเช:

cd deploy/gitlab-runner

เช…เชจเซ‡ เชเช• เชจเชตเซ‹ เช˜เชŸเช• เช‰เชฎเซ‡เชฐเซ‹ เช˜เชŸเช•เซ‹/rbac.jsonnet:

local env = {
  name: std.extVar('qbec.io/env'),
  namespace: std.extVar('qbec.io/defaultNs'),
};
local p = import '../params.libsonnet';
local params = p.components.rbac;

[
  {
    apiVersion: 'v1',
    kind: 'ServiceAccount',
    metadata: {
      labels: {
        app: params.name,
      },
      name: params.name,
    },
  },
  {
    apiVersion: 'rbac.authorization.k8s.io/v1',
    kind: 'Role',
    metadata: {
      labels: {
        app: params.name,
      },
      name: params.name,
    },
    rules: [
      {
        apiGroups: [
          '*',
        ],
        resources: [
          '*',
        ],
        verbs: [
          '*',
        ],
      },
    ],
  },
  {
    apiVersion: 'rbac.authorization.k8s.io/v1',
    kind: 'RoleBinding',
    metadata: {
      labels: {
        app: params.name,
      },
      name: params.name,
    },
    roleRef: {
      apiGroup: 'rbac.authorization.k8s.io',
      kind: 'Role',
      name: params.name,
    },
    subjects: [
      {
        kind: 'ServiceAccount',
        name: params.name,
        namespace: env.namespace,
      },
    ],
  },
]

เช…เชฎเซ‡ เชจเชตเชพ เชชเชฐเชฟเชฎเชพเชฃเซ‹เชจเซเช‚ เชชเชฃ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เชถเซเช‚ Environments/base.libsonnet, เชœเซ‡ เชนเชตเซ‡ เช†เชจเชพ เชœเซ‡เชตเซ‹ เชฆเซ‡เช–เชพเชฏ เช›เซ‡:

local secrets = import '../secrets/base.libsonnet';

{
  components: {
    gitlabRunner: {
      name: 'gitlab-runner',
      values: {
        gitlabUrl: 'https://gitlab.com/',
        rbac: {
          create: true,
        },
        runnerRegistrationToken: secrets.runnerRegistrationToken,
        runners: {
          serviceAccountName: $.components.rbac.name,
          image: 'registry.gitlab.com/kvaps/docs.example.org/toolbox:v0.0.1',
        },
      },
    },
    rbac: {
      name: 'gitlab-runner-deploy',
    },
  },
}

เชงเซเชฏเชพเชจ เช†เชชเซ‹ $.components.rbac.name เช‰เชฒเซเชฒเซ‡เช– เช•เชฐเซ‡ เชจเชพเชฎ เช˜เชŸเช• เชฎเชพเชŸเซ‡ เช†เชฐเชฌเซ€เชเชธเซ€

เชšเชพเชฒเซ‹ เชคเชชเชพเชธเซ€เช เช•เซ‡ เชถเซเช‚ เชฌเชฆเชฒเชพเชฏเซเช‚ เช›เซ‡:

qbec diff default

เช…เชจเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฒเชพเช—เซ เช•เชฐเซ‹:

qbec apply default

เช‰เชชเชฐเชพเช‚เชค, เช—เชฟเชŸเชฎเชพเช‚ เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

cd ../..
git add dockerfiles/toolbox
git commit -m "Add Dockerfile for toolbox"
git add deploy/gitlab-runner
git commit -m "Configure gitlab-runner to use toolbox"

9. เช…เชฎเชพเชฐเซ€ เชชเซเชฐเชฅเชฎ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เช…เชจเซ‡ เชŸเซ…เช—เซเชธ เชฆเซเชตเชพเชฐเชพ เช›เชฌเซ€เช“เชจเซ€ เชเชธเซ‡เชฎเซเชฌเชฒเซ€

เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเชพ เชฎเซ‚เชณเชฎเชพเช‚ เช†เชชเชฃเซ‡ เชฌเชจเชพเชตเซ€เชถเซเช‚ .gitlab-ci.yml เชจเซ€เชšเซ‡เชจเซ€ เชธเชพเชฎเช—เซเชฐเซ€ เชธเชพเชฅเซ‡:

.build_docker_image:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug-v0.15.0
    entrypoint: [""]
  before_script:
    - echo "{"auths":{"$CI_REGISTRY":{"username":"$CI_REGISTRY_USER","password":"$CI_REGISTRY_PASSWORD"}}}" > /kaniko/.docker/config.json

build_toolbox:
  extends: .build_docker_image
  script:
    - /kaniko/executor --cache --context $CI_PROJECT_DIR/dockerfiles/toolbox --dockerfile $CI_PROJECT_DIR/dockerfiles/toolbox/Dockerfile --destination $CI_REGISTRY_IMAGE/toolbox:$CI_COMMIT_TAG
  only:
    refs:
      - tags

build_website:
  extends: .build_docker_image
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  script:
    - /kaniko/executor --cache --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/dockerfiles/website/Dockerfile --destination $CI_REGISTRY_IMAGE/website:$CI_COMMIT_TAG
  only:
    refs:
      - tags

เช•เซƒเชชเชพ เช•เชฐเซ€เชจเซ‡ เชจเซ‹เช‚เชงเซ‹ เช•เซ‡ เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช GIT_SUBMODULE_STRATEGY: เชธเชพเชฎเชพเชจเซเชฏ เชคเซ‡ เชจเซ‹เช•เชฐเซ€เช“ เชฎเชพเชŸเซ‡ เชœเซเชฏเชพเช‚ เชคเชฎเชพเชฐเซ‡ เช…เชฎเชฒ เชชเชนเซ‡เชฒเชพ เชธเชฌเชฎเซ‹เชกเซเชฏเซเชฒเซเชธเชจเซ‡ เชธเซเชชเชทเซเชŸเชชเชฃเซ‡ เชถเชฐเซ‚ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .gitlab-ci.yml
git commit -m "Automate docker build"

เชฎเชจเซ‡ เชฒเชพเช—เซ‡ เช›เซ‡ เช•เซ‡ เช…เชฎเซ‡ เช†เชจเซ‡ เชธเซเชฐเช•เซเชทเชฟเชค เชฐเซ€เชคเซ‡ เชตเชฐเซเชเชจ เช•เชนเซ€ เชถเช•เซ€เช เช›เซ€เช v0.0.1 เช…เชจเซ‡ เชŸเซ‡เช— เช‰เชฎเซ‡เชฐเซ‹:

git tag v0.0.1

เชœเซเชฏเชพเชฐเซ‡ เชชเชฃ เช…เชฎเชจเซ‡ เชจเชตเซเช‚ เชธเช‚เชธเซเช•เชฐเชฃ เชฐเชฟเชฒเซ€เช เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชชเชกเชถเซ‡ เชคเซเชฏเชพเชฐเซ‡ เช…เชฎเซ‡ เชŸเซ…เช—เซเชธ เช‰เชฎเซ‡เชฐเซ€เชถเซเช‚. เชกเซ‹เช•เชฐ เช‡เชฎเซ‡เชœเชฎเชพเช‚ เชŸเซ…เช—เซเชธ เช—เชฟเชŸ เชŸเซ…เช—เซเชธ เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชฏเซ‡เชฒเชพ เชนเชถเซ‡. เชจเชตเชพ เชŸเซ‡เช— เชธเชพเชฅเซ‡เชจเซ‹ เชฆเชฐเซ‡เช• เชชเซเชถ เช† เชŸเซ‡เช— เชธเชพเชฅเซ‡ เชˆเชฎเซ‡เชœเซ€เชธเชจเชพ เชจเชฟเชฐเซเชฎเชพเชฃเชจเซ‡ เช†เชฐเช‚เชญ เช•เชฐเชถเซ‡.

เชšเชพเชฒเซ‹ เชคเซ‡ เช•เชฐเซ€เช git push --tags, เช…เชจเซ‡ เชšเชพเชฒเซ‹ เช…เชฎเชพเชฐเซ€ เชชเซเชฐเชฅเชฎ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชœเซ‹เชˆเช:

เชชเซเชฐเชฅเชฎ เชชเชพเช‡เชชเชฒเชพเช‡เชจเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชคเซ‡ เชนเช•เซ€เช•เชค เชคเชฐเชซ เชคเชฎเชพเชฐเซเช‚ เชงเซเชฏเชพเชจ เชฆเซ‹เชฐเชตเชพ เชฏเซ‹เช—เซเชฏ เช›เซ‡ เช•เซ‡ เชŸเซ‡เช—เซเชธ เชฆเซเชตเชพเชฐเชพ เชเชธเซ‡เชฎเซเชฌเชฒเซ€ เชกเซ‹เช•เชฐ เชˆเชฎเซ‡เชœเซ‹ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชฏเซ‹เช—เซเชฏ เช›เซ‡, เชชเชฐเช‚เชคเซ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชฏเซ‹เช—เซเชฏ เชจเชฅเซ€. เชœเซ‚เชจเชพ เช•เชฎเชฟเชŸเซเชธเชจเซ‡ เชจเชตเชพ เชŸเซ…เช—เซเชธ เช…เชธเชพเช‡เชจ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡, เช† เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เชคเซ‡เชฎเชจเชพ เชฎเชพเชŸเซ‡ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชถเชฐเซ‚ เช•เชฐเชตเชพเชฅเซ€ เชœเซ‚เชจเชพ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ€ เชœเชฎเชพเชตเชŸ เชฅเชถเซ‡.

เช† เชธเชฎเชธเซเชฏเชพเชจเซ‡ เช‰เช•เซ‡เชฒเชตเชพ เชฎเชพเชŸเซ‡, เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เชกเซ‹เช•เชฐ เชˆเชฎเซ‡เชœเซ€เชธเชจเซเช‚ เชฌเชฟเชฒเซเชก เชŸเซ‡เช— เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชฏเซ‡เชฒเซเช‚ เชนเซ‹เชฏ เช›เซ‡, เช…เชจเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชถเชพเช–เชพเชฎเชพเช‚ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชฎเชพเชธเซเชŸเชฐ, เชœเซ‡เชฎเชพเช‚ เชเช•เชคเซเชฐเชฟเชค เช•เชฐเซ‡เชฒเซ€ เช›เชฌเซ€เช“เชจเซ€ เช†เชตเซƒเชคเซเชคเชฟเช“ เชนเชพเชฐเซเชกเช•เซ‹เชก เช•เชฐเซ‡เชฒเซ€ เช›เซ‡. เช† เชคเซ‡ เช›เซ‡ เชœเซเชฏเชพเช‚ เชคเชฎเซ‡ เชเช• เชธเชฐเชณ เชฐเชฟเชตเชฐเซเชŸ เชธเชพเชฅเซ‡ เชฐเซ‹เชฒเชฌเซ‡เช• เชถเชฐเซ‚ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เชฎเชพเชธเซเชŸเชฐ-เชถเชพเช–เชพเช“.

10. เชœเชฎเชพเชตเชŸเชจเซเช‚ เช“เชŸเซ‹เชฎเซ‡เชถเชจ

เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐ เช…เชฎเชพเชฐเชพ เชฐเชนเชธเซเชฏเซ‹เชจเซ‡ เชกเชฟเช•เซเชฐเชฟเชชเซเชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเชพเชฐเซ‡ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€ เช•เซ€ เชจเชฟเช•เชพเชธ เช•เชฐเชตเชพเชจเซ€ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เช…เชฎเชพเชฐเชพ CI เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชšเชฒเซ‹เชฎเชพเช‚ เช‰เชฎเซ‡เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชชเชกเชถเซ‡:

git crypt export-key /tmp/docs-repo.key
base64 -w0 /tmp/docs-repo.key; echo

เช…เชฎเซ‡ เชชเชฐเชฟเชฃเชพเชฎเซ€ เชฒเชพเช‡เชจเชจเซ‡ Gitlab เชฎเชพเช‚ เชธเชพเชšเชตเซ€เชถเซเช‚; เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชšเชพเชฒเซ‹ เช…เชฎเชพเชฐเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชธเซ‡เชŸเชฟเช‚เช—เซเชธ เชชเชฐ เชœเชˆเช:
เชธเซ‡เชŸเชฟเช‚เช—เซเชธ -> CI / CD -> เชตเซ‡เชฐเซ€เชเชฌเชฒเซเชธ

เช…เชจเซ‡ เชšเชพเชฒเซ‹ เชเช• เชจเชตเซเช‚ เชšเชฒ เชฌเชจเชพเชตเซ€เช:

เชชเซเชฐเช•เชพเชฐ
เช•เซ€
เชญเชพเชต
เชธเซเชฐเช•เซเชทเชฟเชค
เชฎเชนเซ‹เชฐเซเช‚
เช…เชตเช•เชพเชถ

File
GITCRYPT_KEY
<your string>
true (เชคเชพเชฒเซ€เชฎ เชฆเชฐเชฎเชฟเชฏเชพเชจ เชคเชฎเซ‡ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ false)
true
All environments

เช‰เชฎเซ‡เชฐเชพเชฏเซ‡เชฒ เชšเชฒเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชนเชตเซ‡ เชšเชพเชฒเซ‹ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ€เช .gitlab-ci.yml เชคเซ‡เชฎเชพเช‚ เช‰เชฎเซ‡เชฐเซ‹:

.deploy_qbec_app:
  stage: deploy
  only:
    refs:
      - master

deploy_gitlab_runner:
  extends: .deploy_qbec_app
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  before_script:
    - base64 -d "$GITCRYPT_KEY" | git-crypt unlock -
  script:
    - qbec apply default --root deploy/gitlab-runner --force:k8s-context __incluster__ --wait --yes

deploy_website:
  extends: .deploy_qbec_app
  script:
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes

เช…เชนเซ€เช‚ เช…เชฎเซ‡ qbec เชฎเชพเชŸเซ‡ เช˜เชฃเชพ เชจเชตเชพ เชตเชฟเช•เชฒเซเชชเซ‹ เชธเช•เซเชฐเชฟเชฏ เช•เชฐเซเชฏเชพ เช›เซ‡:

  • --root some/app โ€” เชคเชฎเชจเซ‡ เชšเซ‹เช•เซเช•เชธ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ เชกเชฟเชฐเซ‡เช•เซเชŸเชฐเซ€ เชจเช•เซเช•เซ€ เช•เชฐเชตเชพ เชฆเซ‡ เช›เซ‡
  • --เชซเซ‹เชฐเซเชธ:k8s-เชธเช‚เชฆเชฐเซเชญ __ เชธเชฎเชพเชตเซ‡เชถ__ - เช† เชเช• เชœเชพเชฆเซเชˆ เชšเชฒ เช›เซ‡ เชœเซ‡ เช•เชนเซ‡ เช›เซ‡ เช•เซ‡ เชœเชฎเชพเชตเชŸ เช เชœ เช•เซเชฒเชธเซเชŸเชฐเชฎเชพเช‚ เชฅเชถเซ‡ เชœเซ‡เชฎเชพเช‚ gtilab-runner เชšเชพเชฒเซ€ เชฐเชนเซเชฏเซเช‚ เช›เซ‡. เช† เชœเชฐเซ‚เชฐเซ€ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ เช…เชจเซเชฏเชฅเชพ qbec เชคเชฎเชพเชฐเชพ kubeconfig เชฎเชพเช‚ เชฏเซ‹เช—เซเชฏ Kubernetes เชธเชฐเซเชตเชฐ เชถเซ‹เชงเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชคเซเชจ เช•เชฐเชถเซ‡.
  • -- เชฐเชพเชน เชœเซเช“ โ€” qbec เชจเซ‡ เชคเซเชฏเชพเช‚ เชธเซเชงเซ€ เชฐเชพเชน เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชฆเชฌเชพเชฃ เช•เชฐเซ‡ เช›เซ‡ เชœเซเชฏเชพเช‚ เชธเซเชงเซ€ เชคเซ‡ เชฌเชจเชพเชตเซ‡เชฒ เชธเช‚เชธเชพเชงเชจเซ‹ เชคเซˆเชฏเชพเชฐ เชธเซเชฅเชฟเชคเชฟเชฎเชพเช‚ เชจ เชœเชพเชฏ เช…เชจเซ‡ เชฎเชพเชคเซเชฐ เชคเซเชฏเชพเชฐเซ‡ เชœ เชธเชซเชณ เชเช•เซเชเชฟเชŸ-เช•เซ‹เชก เชธเชพเชฅเซ‡ เชฌเชนเชพเชฐ เชจเซ€เช•เชณเซ‹.
  • -เชนเชพ - เชซเช•เซเชค เช‡เชจเซเชŸเชฐเซ‡เช•เซเชŸเชฟเชต เชถเซ‡เชฒเชจเซ‡ เช…เช•เซเชทเชฎ เช•เชฐเซ‡ เช›เซ‡ เชถเซเช‚ เชคเชฎเชจเซ‡ เช–เชพเชคเชฐเซ€ เช›เซ‡? เชœเซเชฏเชพเชฐเซ‡ เชคเซˆเชจเชพเชค.

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .gitlab-ci.yml
git commit -m "Automate deploy"

เช…เชจเซ‡ เชชเช›เซ€ เช—เซ€เชŸ เชฆเชฌเชพเชฃ เช…เชฎเซ‡ เชœเซ‹เชˆเชถเซเช‚ เช•เซ‡ เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซ‹ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชœเชฎเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เช›เซ‡:

เชฌเซ€เชœเซ€ เชชเชพเช‡เชชเชฒเชพเช‡เชจเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

11. เชฎเชพเชธเซเชŸเชฐ เชชเชฐ เชฆเชฌเชพเชฃ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เช•เชฒเชพเช•เซƒเชคเชฟเช“ เช…เชจเซ‡ เชเชธเซ‡เชฎเซเชฌเชฒเซ€

เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เช‰เชชเชฐ เชตเชฐเซเชฃเชตเซ‡เชฒ เชชเช—เชฒเชพเช‚ เชฒเช—เชญเช— เช•เซ‹เชˆเชชเชฃ เชฎเชพเช‡เช•เซเชฐเซ‹เชธเชฐเซเชตเชฟเชธ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชตเชฟเชคเชฐเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชชเซ‚เชฐเชคเชพ เช›เซ‡, เชชเชฐเช‚เชคเซ เช…เชฎเซ‡ เชฆเชฐ เชตเช–เชคเซ‡ เชธเชพเช‡เชŸเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ เชคเซเชฏเชพเชฐเซ‡ เชŸเซ‡เช— เช‰เชฎเซ‡เชฐเชตเชพ เชฎเชพเช‚เช—เชคเชพ เชจเชฅเซ€. เชคเซ‡เชฅเซ€, เช…เชฎเซ‡ เชตเชงเซ เช—เชคเชฟเชถเซ€เชฒ เชฎเชพเชฐเซเช— เช…เชชเชจเชพเชตเซ€เชถเซเช‚ เช…เชจเซ‡ เชฎเซเช–เซเชฏ เชถเชพเช–เชพเชฎเชพเช‚ เชกเชพเชฏเชœเซ‡เชธเซเชŸ เชœเชฎเชพเชตเชŸ เช—เซ‹เช เชตเซ€เชถเซเช‚.

เชตเชฟเชšเชพเชฐ เชธเชฐเชณ เช›เซ‡: เชนเชตเซ‡ เช…เชฎเชพเชฐเซ€ เช›เชฌเซ€ เชตเซ‡เชฌเชธเชพเช‡เชŸ เชœเซเชฏเชพเชฐเซ‡ เชชเชฃ เชคเชฎเซ‡ เชฆเชฌเชพเชฃ เช•เชฐเชถเซ‹ เชคเซเชฏเชพเชฐเซ‡ เชซเชฐเซ€เชฅเซ€ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เชฎเชพเชธเซเชŸเชฐ, เช…เชจเซ‡ เชชเช›เซ€ เช†เชชเชฎเซ‡เชณเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เชœเชฎเชพเชตเชŸ เช•เชฐเซ‹.

เชšเชพเชฒเซ‹ เช†เชชเชฃเชพเชฎเชพเช‚ เช† เชฌเซ‡ เชจเซ‹เช•เชฐเซ€เช“ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ€เช .gitlab-ci.yml:

build_website:
  extends: .build_docker_image
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  script:
    - mkdir -p $CI_PROJECT_DIR/artifacts
    - /kaniko/executor --cache --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/dockerfiles/website/Dockerfile --destination $CI_REGISTRY_IMAGE/website:$CI_COMMIT_REF_NAME --digest-file $CI_PROJECT_DIR/artifacts/website.digest
  artifacts:
    paths:
      - artifacts/
  only:
    refs:
      - master
      - tags

deploy_website:
  extends: .deploy_qbec_app
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST"

เชฎเชนเซ‡เชฐเชฌเชพเชจเซ€ เช•เชฐเซ€เชจเซ‡ เชจเซ‹เช‚เชง เช•เชฐเซ‹ เช•เซ‡ เช…เชฎเซ‡ เชเช• เชฅเซเชฐเซ‡เชก เช‰เชฎเซ‡เชฐเซเชฏเซ‹ เช›เซ‡ เชฎเชพเชธเซเชŸเชฐ ะบ ref. เชจเซ‹เช•เชฐเซ€เช“ เชฎเชพเชŸเซ‡ เชฌเชฟเชฒเซเชก_เชตเซ‡เชฌเชธเชพเช‡เชŸ เช…เชจเซ‡ เช…เชฎเซ‡ เชนเชตเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช $CI_COMMIT_REF_NAME ะฒะผะตัั‚ะพ $CI_COMMIT_TAG, เชเชŸเชฒเซ‡ เช•เซ‡, เช…เชฎเซ‡ Git เชฎเชพเช‚ เชŸเซ…เช—เซเชธเชฅเซ€ เช›เซ‚เชŸเซ€ เช—เชฏเชพ เช›เซ€เช เช…เชจเซ‡ เชนเชตเซ‡ เช…เชฎเซ‡ เช•เชฎเชฟเชŸ เชฌเซเชฐเชพเชจเซเชšเชจเชพ เชจเชพเชฎ เชธเชพเชฅเซ‡ เชเช• เช‡เชฎเซ‡เชœเชจเซ‡ เชฆเชฌเชพเชฃ เช•เชฐเซ€เชถเซเช‚ เชœเซ‡เชฃเซ‡ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชถเชฐเซ‚ เช•เชฐเซ€ เช›เซ‡. เชคเซ‡ เชจเซ‹เช‚เชงเชตเซเช‚ เชฏเซ‹เช—เซเชฏ เช›เซ‡ เช•เซ‡ เช† เชŸเซ…เช—เซเชธ เชธเชพเชฅเซ‡ เชชเชฃ เช•เชพเชฎ เช•เชฐเชถเซ‡, เชœเซ‡ เช…เชฎเชจเซ‡ เชกเซ‹เช•เชฐ-เชฐเชœเชฟเชธเซเชŸเซเชฐเซ€เชฎเชพเช‚ เชšเซ‹เช•เซเช•เชธ เชธเช‚เชธเซเช•เชฐเชฃ เชธเชพเชฅเซ‡ เชธเชพเช‡เชŸเชจเชพ เชธเซเชจเซ‡เชชเชถเซ‹เชŸเชจเซ‡ เชธเชพเชšเชตเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชถเซ‡.

เชœเซเชฏเชพเชฐเซ‡ เชธเชพเช‡เชŸเชจเชพ เชจเชตเชพ เชธเช‚เชธเซเช•เชฐเชฃ เชฎเชพเชŸเซ‡ เชกเซ‹เช•เชฐ เชŸเซ‡เช—เชจเซเช‚ เชจเชพเชฎ เช…เชชเชฐเชฟเชตเชฐเซเชคเชฟเชค เชฅเชˆ เชถเช•เซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เช…เชฎเชพเชฐเซ‡ เชนเชœเซ€ เชชเชฃ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธเชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเชตเซเช‚ เชชเชกเชถเซ‡, เช…เชจเซเชฏเชฅเชพ เชคเซ‡ เชซเช•เซเชค เชจเชตเซ€ เช›เชฌเซ€เชฎเชพเช‚เชฅเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ‡ เชซเชฐเซ€เชฅเซ€ เช—เซ‹เช เชตเชถเซ‡ เชจเชนเซ€เช‚, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เช•เซ‹เชˆเชชเชฃ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซ€ เชจเซ‹เช‚เชง เชฒเซ‡เชถเซ‡ เชจเชนเซ€เช‚. เชœเชฎเชพเชตเชŸ เชฎเซ‡เชจเชฟเชซเซ‡เชธเซเชŸ.

เชตเชฟเช•เชฒเซเชช โ€”vm:ext-str digest="$DIGEST" qbec เชฎเชพเชŸเซ‡ - เชคเชฎเชจเซ‡ jsonnet เชฎเชพเช‚ เชฌเชพเชนเซเชฏ เชšเชฒ เชชเชธเชพเชฐ เช•เชฐเชตเชพเชจเซ€ เชชเชฐเชตเชพเชจเช—เซ€ เช†เชชเซ‡ เช›เซ‡. เช…เชฎเซ‡ เชˆเชšเซเช›เซ€เช เช›เซ€เช เช•เซ‡ เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชฆเชฐเซ‡เช• เชชเซเชฐเช•เชพเชถเชจ เชธเชพเชฅเซ‡ เชคเซ‡เชจเซ‡ เช•เซเชฒเชธเซเชŸเชฐเชฎเชพเช‚ เชซเชฐเซ€เชฅเซ€ เช—เซ‹เช เชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡. เช…เชฎเซ‡ เชนเชตเซ‡ เชŸเซ…เช— เชจเชพเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เชคเชพ เชจเชฅเซ€, เชœเซ‡ เชนเชตเซ‡ เชฌเชฆเชฒเซ€ เชจ เชถเช•เชพเชฏ เชคเซ‡เชตเซเช‚ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เช…เชฎเชพเชฐเซ‡ เช‡เชฎเซ‡เชœเชจเชพ เชšเซ‹เช•เซเช•เชธ เชธเช‚เชธเซเช•เชฐเชฃ เชธเชพเชฅเซ‡ เชœเซ‹เชกเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เช…เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เชคเซ‡ เชฌเชฆเชฒเชพเชฏ เช›เซ‡ เชคเซเชฏเชพเชฐเซ‡ เชœเชฎเชพเชตเชŸเชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เช…เชนเซ€เช‚ เช…เชฎเชจเซ‡ เชซเชพเช‡เชฒเชฎเชพเช‚ เชกเชพเชฏเชœเซ‡เชธเซเชŸ เช‡เชฎเซ‡เชœ เชธเชพเชšเชตเชตเชพเชจเซ€ เช•เชจเชฟเช•เซ‹เชจเซ€ เช•เซเชทเชฎเชคเชพ เชฆเซเชตเชพเชฐเชพ เชฎเชฆเชฆ เชฎเชณเชถเซ‡ (เชตเชฟเช•เชฒเซเชช --เชกเชพเช‡เชœเซ‡เชธเซเชŸ-เชซเชพเช‡เชฒ)
เชชเช›เซ€ เช…เชฎเซ‡ เช† เชซเชพเช‡เชฒเชจเซ‡ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เช•เชฐเซ€เชถเซเช‚ เช…เชจเซ‡ เชœเชฎเชพเชตเชŸ เชธเชฎเชฏเซ‡ เชคเซ‡เชจเซ‡ เชตเชพเช‚เชšเซ€เชถเซเช‚.

เชšเชพเชฒเซ‹ เช†เชชเชฃเชพ เชฎเชพเชŸเซ‡เชจเชพ เชชเชฐเชฟเชฎเชพเชฃเซ‹เชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ€เช deploy/website/environments/base.libsonnet เชœเซ‡ เชนเชตเซ‡ เช†เชจเชพ เชœเซ‡เชตเซ‹ เชฆเซ‡เช–เชพเชถเซ‡:

{
  components: {
    website: {
      name: 'example-docs',
      image: 'registry.gitlab.com/kvaps/docs.example.org/website@' + std.extVar('digest'),
      replicas: 1,
      containerPort: 80,
      servicePort: 80,
      nodeSelector: {},
      tolerations: [],
      ingressClass: 'nginx',
      domain: 'docs.example.org',
    },
  },
}

เชฅเชˆ เช—เชฏเซเช‚, เชนเชตเซ‡ เช•เซ‹เชˆเชชเชฃ เช•เชฎเชฟเชŸ เช‡เชจ เช•เชฐเซ‹ เชฎเชพเชธเซเชŸเชฐ เชฎเชพเชŸเซ‡ เชกเซ‹เช•เชฐ เชˆเชฎเซ‡เชœเชจเซเช‚ เชฌเชฟเชฒเซเชก เช†เชฐเช‚เชญ เช•เชฐเซ‡ เช›เซ‡ เชตเซ‡เชฌเชธเชพเช‡เชŸ, เช…เชจเซ‡ เชชเช›เซ€ เชคเซ‡เชจเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธ เชชเชฐ เชœเชฎเชพเชตเซ‹.

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .
git commit -m "Configure dynamic build"

เช…เชฎเซ‡ เชชเช›เซ€เชฅเซ€ เชคเชชเชพเชธ เช•เชฐเซ€เชถเซเช‚ เช—เซ€เชŸ เชฆเชฌเชพเชฃ เช†เชชเชฃเซ‡ เช†เชจเชพ เชœเซ‡เชตเซเช‚ เช•เช‚เชˆเช• เชœเซ‹เชตเซเช‚ เชœเซ‹เชˆเช:

เชฎเชพเชธเซเชŸเชฐ เชฎเชพเชŸเซ‡ เชชเชพเช‡เชชเชฒเชพเช‡เชจเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชฐเซ€เชคเซ‡, เช†เชชเชฃเซ‡ เชฆเชฐเซ‡เช• เชชเซเชถ เชธเชพเชฅเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌ-เชฐเชจเชฐเชจเซ‡ เชซเชฐเซ€เชฅเซ€ เช—เซ‹เช เชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€, เชธเชฟเชตเชพเชฏ เช•เซ‡, เช…เชฒเชฌเชคเซเชค, เชคเซ‡เชจเชพ เชฐเซ‚เชชเชฐเซ‡เช–เชพเช‚เช•เชจเชฎเชพเช‚ เช•เช‚เชˆ เชฌเชฆเชฒเชพเชฏเซเช‚ เชจเชฅเซ€, เชšเชพเชฒเซ‹ เชคเซ‡เชจเซ‡ เช เซ€เช• เช•เชฐเซ€เช. .gitlab-ci.yml:

deploy_gitlab_runner:
  extends: .deploy_qbec_app
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  before_script:
    - base64 -d "$GITCRYPT_KEY" | git-crypt unlock -
  script:
    - qbec apply default --root deploy/gitlab-runner --force:k8s-context __incluster__ --wait --yes
  only:
    changes:
      - deploy/gitlab-runner/**/*

เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซเช‚ เชจเชฟเชฐเซ€เช•เซเชทเชฃ เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชถเซ‡ เชœเชฎเชพเชตเชŸ/gitlab-runner/ เช…เชจเซ‡ เชœเซ‹ เช•เซ‹เชˆ เชนเซ‹เชฏ เชคเซ‹ เชœ เช…เชฎเชพเชฐเซ€ เชจเซ‹เช•เชฐเซ€เชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเชถเซ‡

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .gitlab-ci.yml
git commit -m "Reduce gitlab-runner deploy"

เช—เซ€เชŸ เชฆเชฌเชพเชฃ, เชธเชฐเชธ:

เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‡เชฒ เชชเชพเช‡เชชเชฒเชพเช‡เชจเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

12. เช—เชคเชฟเชถเซ€เชฒ เชตเชพเชคเชพเชตเชฐเชฃ

เช—เชคเชฟเชถเซ€เชฒ เชตเชพเชคเชพเชตเชฐเชฃ เชธเชพเชฅเซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเช‡เชชเชฒเชพเช‡เชจเชฎเชพเช‚ เชตเชฟเชตเชฟเชงเชคเชพ เชฒเชพเชตเชตเชพเชจเซ‹ เช† เชธเชฎเชฏ เช›เซ‡.

เชชเซเชฐเชฅเชฎ, เชšเชพเชฒเซ‹ เชœเซ‹เชฌ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ€เช เชฌเชฟเชฒเซเชก_เชตเซ‡เชฌเชธเชพเช‡เชŸ เช…เชฎเชพเชฐเชพ เชฎเชพเช‚ .gitlab-ci.yml, เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชฌเซเชฒเซ‹เช• เชฆเซ‚เชฐ เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช เชฎเชพเชคเซเชฐ, เชœเซ‡ เช—เชฟเชŸเชฒเซ‡เชฌเชจเซ‡ เช•เซ‹เชˆเชชเชฃ เชถเชพเช–เชพเชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เชชเซเชฐเชคเชฟเชฌเชฆเซเชงเชคเชพ เชชเชฐ เชคเซ‡เชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเชตเชพ เชฆเชฌเชพเชฃ เช•เชฐเชถเซ‡:

build_website:
  extends: .build_docker_image
  variables:
    GIT_SUBMODULE_STRATEGY: normal
  script:
    - mkdir -p $CI_PROJECT_DIR/artifacts
    - /kaniko/executor --cache --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/dockerfiles/website/Dockerfile --destination $CI_REGISTRY_IMAGE/website:$CI_COMMIT_REF_NAME --digest-file $CI_PROJECT_DIR/artifacts/website.digest
  artifacts:
    paths:
      - artifacts/

เชชเช›เซ€ เชœเซ‹เชฌ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‹ เชกเชฟเชชเซเชฒเซ‹เชฏ_เชตเซ‡เชฌเชธเชพเช‡เชŸ, เชคเซเชฏเชพเช‚ เชเช• เชฌเซเชฒเซ‹เช• เช‰เชฎเซ‡เชฐเซ‹ เชชเชฐเซเชฏเชพเชตเชฐเชฃ:

deploy_website:
  extends: .deploy_qbec_app
  environment:
    name: prod
    url: https://docs.example.org
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST"

เช† Gitlab เชจเซ‡ เชœเซ‹เชฌ เชธเชพเชฅเซ‡ เชธเชพเช‚เช•เชณเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชถเซ‡ เชชเซเชฐเซ‹เชช เชชเชฐเซเชฏเชพเชตเชฐเชฃ เช…เชจเซ‡ เชคเซ‡เชจเซ€ เชธเชพเชšเซ€ เชฒเชฟเช‚เช• เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เช•เชฐเซ‹.

เชšเชพเชฒเซ‹ เชนเชตเซ‡ เชตเชงเซ เชฌเซ‡ เชœเซ‹เชฌ เช‰เชฎเซ‡เชฐเซ€เช:

deploy_website:
  extends: .deploy_qbec_app
  environment:
    name: prod
    url: https://docs.example.org
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply default --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST"

deploy_review:
  extends: .deploy_qbec_app
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: http://$CI_ENVIRONMENT_SLUG.docs.example.org
    on_stop: stop_review
  script:
    - DIGEST="$(cat artifacts/website.digest)"
    - qbec apply review --root deploy/website --force:k8s-context __incluster__ --wait --yes --vm:ext-str digest="$DIGEST" --vm:ext-str subdomain="$CI_ENVIRONMENT_SLUG" --app-tag "$CI_ENVIRONMENT_SLUG"
  only:
    refs:
    - branches
  except:
    refs:
      - master

stop_review:
  extends: .deploy_qbec_app
  environment:
    name: review/$CI_COMMIT_REF_NAME
    action: stop
  stage: deploy
  before_script:
    - git clone "$CI_REPOSITORY_URL" master
    - cd master
  script:
    - qbec delete review --root deploy/website --force:k8s-context __incluster__ --yes --vm:ext-str digest="$DIGEST" --vm:ext-str subdomain="$CI_ENVIRONMENT_SLUG" --app-tag "$CI_ENVIRONMENT_SLUG"
  variables:
    GIT_STRATEGY: none
  only:
    refs:
    - branches
  except:
    refs:
      - master
  when: manual

เชคเซ‡เช“ เชฎเชพเชธเซเชŸเชฐ เชธเชฟเชตเชพเชฏเชจเซ€ เช•เซ‹เชˆเชชเชฃ เชถเชพเช–เชพเช“เชฎเชพเช‚ เชงเช•เซ‡เชฒเชตเชพ เชชเชฐ เชฒเซ‹เชจเซเชš เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เช…เชจเซ‡ เชธเชพเช‡เชŸเชจเชพ เชชเซ‚เชฐเซเชตเชพเชตเชฒเซ‹เช•เชจ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เชœเชฎเชพเชตเชถเซ‡.

เช…เชฎเซ‡ qbec เชฎเชพเชŸเซ‡ เชจเชตเซ‹ เชตเชฟเช•เชฒเซเชช เชœเซ‹เชˆเช เช›เซ€เช: --เชเชช-เชŸเซ‡เช— โ€” เชคเซ‡ เชคเชฎเชจเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเชพ เชคเซˆเชจเชพเชค เชตเชฐเซเชเชจเชจเซ‡ เชŸเซ‡เช— เช•เชฐเชตเชพเชจเซ€ เชชเชฐเชตเชพเชจเช—เซ€ เช†เชชเซ‡ เช›เซ‡ เช…เชจเซ‡ เชซเช•เซเชค เช† เชŸเซ‡เช—เชจเซ€ เช…เช‚เชฆเชฐ เชœ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡; เชœเซเชฏเชพเชฐเซ‡ เช•เซเชฌเชฐเชจเซ‡เชŸเซเชธเชฎเชพเช‚ เชธเช‚เชธเชพเชงเชจเซ‹ เชฌเชจเชพเชตเชคเซ€ เช…เชจเซ‡ เชจเชพเชถ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡, qbec เชคเซ‡เชฎเชจเซ€ เชธเชพเชฅเซ‡ เชœ เช•เชพเชฐเซเชฏ เช•เชฐเชถเซ‡.
เช† เชฐเซ€เชคเซ‡ เช…เชฎเซ‡ เชฆเชฐเซ‡เช• เชธเชฎเซ€เช•เซเชทเชพ เชฎเชพเชŸเซ‡ เช…เชฒเช— เชตเชพเชคเชพเชตเชฐเชฃ เชฌเชจเชพเชตเซ€ เชถเช•เชคเชพ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เชคเซ‡ เชœ เชเช•เชจเซ‹ เชซเชฐเซ€เชฅเซ€ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช.

เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เชชเชฃ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช qbec เชธเชฎเซ€เช•เซเชทเชพ เชฒเชพเช—เซ เช•เชฐเซ‹, เชจเซ€ เชฌเชฆเชฒเซ‡ qbec เชกเชฟเชซเซ‹เชฒเซเชŸ เชฒเชพเช—เซ เช•เชฐเซ‹ - เช† เชคเซ‡ เชœ เช•เซเชทเชฃ เช›เซ‡ เชœเซเชฏเชพเชฐเซ‡ เช†เชชเชฃเซ‡ เช†เชชเชฃเชพ เชชเชฐเซเชฏเชพเชตเชฐเชฃเซ‹ (เชธเชฎเซ€เช•เซเชทเชพ เช…เชจเซ‡ เชกเชฟเชซเซ‹เชฒเซเชŸ) เชฎเชพเชŸเซ‡เชจเชพ เชคเชซเชพเชตเชคเซ‹เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เชถเซเช‚:

เชšเชพเชฒเซ‹ เช‰เชฎเซ‡เชฐเซ€เช เชธเชฎเซ€เช•เซเชทเชพ เชฎเชพเช‚ เชชเชฐเซเชฏเชพเชตเชฐเชฃ deploy/website/qbec.yaml

spec:
  environments:
    review:
      defaultNamespace: docs
      server: https://kubernetes.example.org:8443

เชชเช›เซ€ เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชœเชพเชนเซ‡เชฐ เช•เชฐเซ€เชถเซเช‚ deploy/website/params.libsonnet:

local env = std.extVar('qbec.io/env');
local paramsMap = {
  _: import './environments/base.libsonnet',
  default: import './environments/default.libsonnet',
  review: import './environments/review.libsonnet',
};

if std.objectHas(paramsMap, env) then paramsMap[env] else error 'environment ' + env + ' not defined in ' + std.thisFile

เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚ เชคเซ‡เชจเชพ เชฎเชพเชŸเซ‡เชจเชพ เช•เชธเซเชŸเชฎ เชชเซ‡เชฐเชพเชฎเซ€เชŸเชฐเซเชธ เชฒเช–เซ‹ deploy/website/environments/review.libsonnet:

// this file has the param overrides for the default environment
local base = import './base.libsonnet';
local slug = std.extVar('qbec.io/tag');
local subdomain = std.extVar('subdomain');

base {
  components+: {
    website+: {
      name: 'example-docs-' + slug,
      domain: subdomain + '.docs.example.org',
    },
  },
}

เชšเชพเชฒเซ‹ เชœเซ‹เชฌเซเชฏเซ เชชเชฐ เชชเชฃ เชจเชœเซ€เช•เชฅเซ€ เชจเชœเชฐ เช•เชฐเซ€เช เชฐเซ‹เช•เซ‹_เชธเชฎเซ€เช•เซเชทเชพ, เชœเซเชฏเชพเชฐเซ‡ เชถเชพเช–เชพ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เชคเซเชฏเชพเชฐเซ‡ เชคเซ‡ เชŸเซเชฐเชฟเช—เชฐ เชฅเชถเซ‡ เช…เชจเซ‡ เชœเซ‡เชฅเซ€ เช—เชฟเชŸเชฒเซ‡เชฌ เชšเซ‡เช•เช†เช‰เชŸ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เชจ เช•เชฐเซ‡ เชคเซ‡ เชฎเชพเชŸเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ GIT_STRATEGY: เช•เซ‹เชˆ เชจเชนเซ€เช‚, เชชเช›เซ€เชฅเซ€ เช…เชฎเซ‡ เช•เซเชฒเซ‹เชจ เช•เชฐเซ€เช เช›เซ€เช เชฎเชพเชธเซเชŸเชฐ- เชคเซ‡เชจเชพ เชฆเซเชตเชพเชฐเชพ เชฐเชฟเชตเซเชฏเซเชจเซ‡ เชถเชพเช–เชพ เช…เชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เซ‹.
เชคเซ‡ เชฅเซ‹เชกเซเช‚ เช—เซ‚เช‚เชšเชตเชฃเชญเชฐเซเชฏเซเช‚ เช›เซ‡, เชชเชฐเช‚เชคเซ เชฎเชจเซ‡ เชนเชœเซ€ เชธเซเชงเซ€ เชตเชงเซ เชธเซเช‚เชฆเชฐ เชฐเชธเซเชคเซ‹ เชฎเชณเซเชฏเซ‹ เชจเชฅเซ€.
เชเช• เชตเซˆเช•เชฒเซเชชเชฟเช• เชตเชฟเช•เชฒเซเชช เชฆเชฐเซ‡เช• เชธเชฎเซ€เช•เซเชทเชพเชจเซ‡ เชนเซ‹เชŸเซ‡เชฒ เชจเซ‡เชฎเชธเซเชชเซ‡เชธเชฎเชพเช‚ เชœเชฎเชพเชตเชตเชพเชจเซ‹ เชนเชถเซ‡, เชœเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชคเซ‹เชกเซ€ เชถเช•เชพเชฏ เช›เซ‡.

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .
git commit -m "Enable automatic review"

เช—เซ€เชŸ เชฆเชฌเชพเชฃ, git Checkout -b เชŸเซ‡เชธเซเชŸ, git เชชเซเชถ เช“เชฐเชฟเชœเชฟเชจ เชŸเซ‡เชธเซเชŸ, เชคเชชเชพเชธเซ‹:

เช—เชฟเชŸเชฒเซ‡เชฌเชฎเชพเช‚ เชฌเชจเชพเชตเซ‡เชฒเชพ เชตเชพเชคเชพเชตเชฐเชฃเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชฌเชงเซเช‚ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡? - เชธเชฐเชธ, เช…เชฎเชพเชฐเซ€ เชชเชฐเซ€เช•เซเชทเชฃ เชถเชพเช–เชพ เช•เชพเชขเซ€ เชจเชพเช–เซ‹: เชœเซ€เชŸ เชšเซ‡เช•เช†เช‰เชŸ เชฎเชพเชธเซเชŸเชฐ, git เชชเซเชถ เชฎเซ‚เชณ: เชชเชฐเซ€เช•เซเชทเชฃ, เช…เชฎเซ‡ เชคเชชเชพเชธเซ€เช เช›เซ€เช เช•เซ‡ เชชเชฐเซเชฏเชพเชตเชฐเชฃ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชจเซ€ เชœเซ‹เชฌเซเชธ เชญเซ‚เชฒเซ‹ เชตเชฟเชจเชพ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡.

เช…เชนเซ€เช‚ เชนเซเช‚ เชคเชฐเชค เชœ เชธเซเชชเชทเซเชŸ เช•เชฐเชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚ เช•เซ‡ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพ เชถเชพเช–เชพเช“ เชฌเชจเชพเชตเซ€ เชถเช•เซ‡ เช›เซ‡, เชคเซ‡ เชฌเชฆเชฒเซ€ เชชเชฃ เชถเช•เซ‡ เช›เซ‡ .gitlab-ci.yml เชซเชพเช‡เชฒ เช…เชจเซ‡ เชเช•เซเชธเซ‡เชธ เช—เซเชชเซเชค เชšเชฒเซ‹.
เชคเซ‡เชฅเซ€, เชซเช•เซเชค เชธเช‚เชฐเช•เซเชทเชฟเชค เชถเชพเช–เชพเช“ เชฎเชพเชŸเซ‡ เชœ เชคเซ‡เชฎเชจเชพ เช‰เชชเชฏเซ‹เช—เชจเซ‡ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเชตเชพเชจเซ€ เชญเชพเชฐเชชเซ‚เชฐเซเชตเช• เชญเชฒเชพเชฎเชฃ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡ เชฎเชพเช‚ เชฎเชพเชธเซเชŸเชฐ, เช…เชฅเชตเชพ เชฆเชฐเซ‡เช• เชชเชฐเซเชฏเชพเชตเชฐเชฃ เชฎเชพเชŸเซ‡ เชšเชฒเซ‹เชจเซ‹ เชเช• เช…เชฒเช— เชธเซ‡เชŸ เชฌเชจเชพเชตเซ‹.

13. เชเชชเซเชธเชจเซ€ เชธเชฎเซ€เช•เซเชทเชพ เช•เชฐเซ‹

เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเซ‹เชจเซ€ เชธเชฎเซ€เช•เซเชทเชพ เช•เชฐเซ‹ เช† เชเช• GitLab เชธเซเชตเชฟเชงเชพ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ เชคเซˆเชจเชพเชค เชตเชพเชคเชพเชตเชฐเชฃเชฎเชพเช‚ เชเชกเชชเชฅเซ€ เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚ เชฆเชฐเซ‡เช• เชซเชพเช‡เชฒ เชฎเชพเชŸเซ‡ เชเช• เชฌเชŸเชจ เช‰เชฎเซ‡เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡.

เช† เชฌเชŸเชจเซ‹ เชฆเซ‡เช–เชพเชตเชพ เชฎเชพเชŸเซ‡, เชคเชฎเชพเชฐเซ‡ เชซเชพเช‡เชฒ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ .gitlab/route-map.yml เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚เชจเชพ เชคเชฎเชพเชฎ เชชเชพเชฅ เชชเชฐเชฟเชตเชฐเซเชคเชจเซ‹เชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ‹; เช…เชฎเชพเชฐเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เชคเซ‡ เช–เซ‚เชฌ เชœ เชธเชฐเชณ เชนเชถเซ‡:

# Indices
- source: /content/(.+?)_index.(md|html)/ 
  public: '1'

# Pages
- source: /content/(.+?).(md|html)/ 
  public: '1/'

เช…เชฎเชพเชฐเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพเชจเซเช‚ เชญเซ‚เชฒเชถเซ‹ เชจเชนเซ€เช‚:

git add .gitlab/
git commit -m "Enable review apps"

เช—เซ€เชŸ เชฆเชฌเชพเชฃ, เช…เชจเซ‡ เชคเชชเชพเชธเซ‹:

เชธเชฎเซ€เช•เซเชทเชพ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฌเชŸเชจเชจเซ‹ เชธเซเช•เซเชฐเซ€เชจเชถเซ‹เชŸ

Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เช•เชพเชฎ เชฅเชˆ เช—เชฏเซเช‚!

เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชธเซเชคเซเชฐเซ‹เชคเซ‹:

เชคเชฎเชพเชฐเชพ เชงเซเชฏเชพเชจ เชฌเชฆเชฒ เช†เชญเชพเชฐ, เชฎเชจเซ‡ เช†เชถเชพ เช›เซ‡ เช•เซ‡ เชคเชฎเชจเซ‡ เชคเซ‡ เช—เชฎเซเชฏเซเช‚ เชนเชถเซ‡ Kubernetes เชฎเชพเช‚ เชœเชฎเชพเชตเชŸ เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชจเชตเชพ เชธเชพเชงเชจเซ‹ เช…เชœเชฎเชพเชตเซ€ เชฐเชนเซเชฏเชพเช‚ เช›เซ€เช

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹