เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เบซเบกเบฒเบโ€‹เป€เบซเบ”โ€‹. เปเบ›.: เบชเปˆเบงเบ™ เบ—เบณ เบญเบดเบ” เบŠเบธเบ”เบ™เบตเป‰เป„เบ”เป‰เบ–เบทเบเบญเบธเบ—เบดเบ”เป€เบžเบทเปˆเบญเบฎเบนเป‰เบˆเบฑเบเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เบ‚เบญเบ‡ Istio เปเบฅเบฐเบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™เบžเบงเบเป€เบ‚เบปเบฒเปƒเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”, เบ„เบฑเป‰เบ‡เบ—เบตเบชเบญเบ‡ โ€” เบเบฒเบ™โ€‹เบ„เบธเป‰เบกโ€‹เบ„เบญเบ‡โ€‹เป€เบชเบฑเป‰เบ™โ€‹เบ—เบฒเบ‡โ€‹เปเบฅเบฐโ€‹เบเบฒเบ™โ€‹เบˆเบฐโ€‹เบฅเบฒโ€‹เบˆเบญเบ™โ€‹เป€เบ„เบทเบญโ€‹เบ‚เปˆเบฒเบโ€‹เบ›เบฑเบšโ€‹เบฅเบฐโ€‹เบญเบฝเบ”โ€‹. เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบชเบปเบ™เบ—เบฐเบ™เบฒเบเปˆเบฝเบงเบเบฑเบšเบ„เบงเบฒเบกเบ›เบญเบ”เป„เบž: เป€เบžเบทเปˆเบญเบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™เป€เบ–เบดเบ‡เบซเบ™เป‰เบฒเบ—เบตเปˆเบžเบทเป‰เบ™เบ–เบฒเบ™เบ—เบตเปˆเบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเบกเบฑเบ™, เบœเบนเป‰เบ‚เบฝเบ™เป„เบ”เป‰เปƒเบŠเป‰เบšเปเบฅเบดเบเบฒเบ™เบ•เบปเบงเบ•เบปเบ™ Auth0, เปเบ•เปˆเบœเบนเป‰เปƒเบซเป‰เบšเปเบฅเบดเบเบฒเบ™เบญเบทเปˆเบ™เป†เบชเบฒเบกเบฒเบ”เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเป„เบ”เป‰เปƒเบ™เบฅเบฑเบเบชเบฐเบ™เบฐเบ—เบตเปˆเบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™.

เบžเบงเบเป€เบฎเบปเบฒเบ•เบฑเป‰เบ‡เบเบธเปˆเบก Kubernetes เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบ™เบณเปƒเบŠเป‰ Istio เปเบฅเบฐเปเบญเบฑเบšเบžเบฅเบดเป€เบ„เบŠเบฑเบ™เบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบ•เบปเบงเบขเปˆเบฒเบ‡, เบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเบ„เบงเบฒเบกเบฎเบนเป‰เบชเบถเบ, เป€เบžเบทเปˆเบญเบชเบฐเปเบ”เบ‡เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เบ‚เบญเบ‡ Istio.

เบ”เป‰เบงเบ Istio, เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เบชเบฒโ€‹เบกเบฒเบ”โ€‹เบฎเบฑเบโ€‹เบชเบฒโ€‹เบเบฒเบ™โ€‹เบšเปโ€‹เบฅเบดโ€‹เบเบฒเบ™โ€‹เบ‚เบญเบ‡โ€‹เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เบ‚เบฐโ€‹เบซเบ™เบฒเบ”โ€‹เบ™เป‰เบญเบโ€‹เป€เบ™เบทเปˆเบญเบ‡โ€‹เบˆเบฒเบโ€‹เบงเปˆเบฒโ€‹เบžเบงเบโ€‹เป€เบ‚เบปเบฒโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบšเปเปˆโ€‹เบˆเปเบฒโ€‹เป€เบ›เบฑเบ™โ€‹เบ•เป‰เบญเบ‡โ€‹เบ›เบฐโ€‹เบ•เบดโ€‹เบšเบฑเบ”โ€‹เบŠเบฑเป‰เบ™โ€‹เบ•เปˆเบฒเบ‡เป†โ€‹เป€เบŠเบฑเปˆเบ™ Retryes, Timeouts, Circuit Breakers, Tracing, Monitoring. เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เปƒเบŠเป‰เป€เบ•เบฑเบเบ™เบดเบเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš เปเบฅเบฐเบเบฒเบ™เบ™เบณเปƒเบŠเป‰เปเบšเบšเบžเบดเป€เบชเบ”: เบเบฒเบ™เบ—เบปเบ”เบชเบญเบš A/B, เบเบฒเบ™เบชเบฐเบ—เป‰เบญเบ™เปเบชเบ‡ เปเบฅเบฐ เบกเป‰เบงเบ™ canary.

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เปƒเบ™เบงเบฑเบ”เบชเบฐเบ”เบธเปƒเบซเบกเปˆ, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบˆเบฑเบ”เบเบฒเบ™เบเบฑเบšเบ‚เบฑเป‰เบ™เบ•เบญเบ™เบชเบธเบ”เบ—เป‰เบฒเบเปƒเบ™เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เป„เบ›เบชเบนเปˆเบกเบนเบ™เบ„เปˆเบฒเบ—เบธเบฅเบฐเบเบดเบ”: เบเบฒเบ™เบฎเบฑเบšเบฎเบญเบ‡เปเบฅเบฐเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ” - เปเบฅเบฐเปƒเบ™ Istio เบกเบฑเบ™เป€เบ›เบฑเบ™เบ„เบงเบฒเบกเบชเบธเบเบ—เบตเปˆเปเบ—เป‰เบˆเบดเบ‡!

เบเบฒเบ™เบเบงเบ”เบชเบญเบšเปเบฅเบฐเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบ™ Istio

เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบšเปเปˆโ€‹เป€เบ„เบตเบโ€‹เบˆเบฐโ€‹เป€เบŠเบทเปˆเบญโ€‹เบงเปˆเบฒโ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบˆเบฐโ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบเบฒเบ™โ€‹เบ”เบปเบ™โ€‹เปƒเบˆโ€‹เป‚เบ”เบโ€‹เบเบฒเบ™โ€‹เบเบงเบ”โ€‹เบชเบญเบšโ€‹เปเบฅเบฐโ€‹เบเบฒเบ™โ€‹เบญเบฐโ€‹เบ™เบธโ€‹เบเบฒเบ”โ€‹. Istio เบชเบฒเบกเบฒเบ”เบชเบฐเป€เบซเบ™เบตเบซเบเบฑเบ‡เบˆเบฒเบเบ—เบฑเบ”เบชเบฐเบ™เบฐเป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบตเป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เปƒเบซเป‰เบซเบปเบงเบ‚เปเป‰เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบกเปˆเบงเบ™เปเบฅเบฐ, เบซเบผเบฒเบเบเบงเปˆเบฒเบ™เบฑเป‰เบ™, เป€เบ›เบฑเบ™เปเบฎเบ‡เบšเบฑเบ™เบ”เบฒเบ™เปƒเบˆเบชเปเบฒเบฅเบฑเบšเบ—เปˆเบฒเบ™?

เบ„เปเบฒเบ•เบญเบšเปเบกเปˆเบ™เบ‡เปˆเบฒเบเบ”เบฒเบ: Istio เบ›เปˆเบฝเบ™เบ„เบงเบฒเบกเบฎเบฑเบšเบœเบดเบ”เบŠเบญเบšเบชเปเบฒเบฅเบฑเบšเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบˆเบฒเบเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป„เบ›เบซเบฒเบ•เบปเบงเปเบ—เบ™ Envoy. เป€เบกเบทเปˆเบญเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเป„เบ›เป€เบ–เบดเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™, เบžเบงเบเบกเบฑเบ™เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบขเบฑเป‰เบ‡เบขเบทเบ™เปเบฅเบฐเบญเบฐเบ™เบธเบเบฒเบ”เปเบฅเป‰เบง, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เป€เบฎเบฑเบ”เปเบกเปˆเบ™เบ‚เบฝเบ™เบฅเบฐเบซเบฑเบ”เบ—เบตเปˆเบกเบตเบ›เบฐเป‚เบซเบเบ”เบ—เบฒเบ‡เบ—เบธเบฅเบฐเบเบดเบ”.

เบชเบฝเบ‡เบ”เบต? เบฅเบญเบ‡เป€เบšเบดเปˆเบ‡เบžเบฒเบเปƒเบ™!

เบเบฒเบ™เบขเบทเบ™เบขเบฑเบ™เบ”เป‰เบงเบ Auth0

เปƒเบ™เบ–เบฒเบ™เบฐเป€เบ›เบฑเบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ‚เปˆเบฒเบเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเปเบฒเบ™เบปเบ”เบ•เบปเบงเบ•เบปเบ™เปเบฅเบฐเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ™เปเบฒเปƒเบŠเป‰ Auth0, เบ—เบตเปˆเบกเบตเบชเบฐเบšเบฑเบšเบ—เบปเบ”เบฅเบญเบ‡, เปเบกเปˆเบ™ intuitive เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปเบฅเบฐเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบžเบฝเบ‡เปเบ•เปˆเบกเบฑเบเบกเบฑเบ™. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเปˆเบ•เบฒเบก, เบซเบผเบฑเบเบเบฒเบ™เบ”เบฝเบงเบเบฑเบ™เบชเบฒเบกเบฒเบ”เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เบเบฑเบšเบชเบดเปˆเบ‡เบญเบทเปˆเบ™เป† เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ” OpenID Connect: KeyCloak, IdentityServer เปเบฅเบฐเบญเบทเปˆเบ™เป†เบˆเปเบฒเบ™เบงเบ™เบซเบผเบฒเบ.

เป€เบžเบทเปˆเบญเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™, เป„เบ›เบ—เบตเปˆ Auth0 Portal เบ”เป‰เบงเบเบšเบฑเบ™เบŠเบตเบ‚เบญเบ‡เบ—เปˆเบฒเบ™, เบชเป‰เบฒเบ‡เบœเบนเป‰เป€เบŠเบปเปˆเบฒ (เบœเบนเป‰เป€เบŠเบปเปˆเบฒ - "เบœเบนเป‰เป€เบŠเบปเปˆเบฒ", เบซเบ™เปˆเบงเบเบ‡เบฒเบ™เบขเปˆเบฒเบ‡เบกเบตเป€เบซเบ”เบœเบปเบ™เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ”เบ”เบ”เปˆเบฝเบง, เบชเปเบฒเบฅเบฑเบšเบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเป€เบšเบดเปˆเบ‡ เป€เบญเบเบฐเบชเบฒเบ™ โ€” เบ›เบฐโ€‹เบกเบฒเบ™โ€‹. เปเบ›.) เปเบฅเบฐเป„เบ› เปเบญเบฑเบšเบžเบฅเบดเป€เบ„เบŠเบฑเปˆเบ™ > เปเบญเบฑเบšเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เป€เบฅเบทเบญเบ เป‚เบ”เป€เบกเบ™, เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบชเบฐเปเบ”เบ‡เบขเบนเปˆเปƒเบ™เบซเบ™เป‰เบฒเบˆเปเบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰:

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เบฅเบฐเบšเบธเป‚เบ”เป€เบกเบ™เบ™เบตเป‰เบขเบนเปˆเปƒเบ™เป„เบŸเบฅเปŒ resource-manifests/istio/security/auth-policy.yaml (เปเบซเบผเปˆเบ‡):

apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: auth-policy
spec:
  targets:
  - name: sa-web-app
  - name: sa-feedback
  origins:
  - jwt:
      issuer: "https://{YOUR_DOMAIN}/"
      jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
  principalBinding: USE_ORIGIN

เบ”เป‰เบงเบเบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™เบ”เบฑเปˆเบ‡เบเปˆเบฒเบง, เบ™เบฑเบเบšเบดเบ™ (เบซเบ™เบถเปˆเบ‡เปƒเบ™เบชเบฒเบกเบญเบปเบ‡เบ›เบฐเบเบญเบšเบ‚เบญเบ‡เบเบปเบ™เบ„เบงเบšเบ„เบธเบกเบžเบทเป‰เบ™เบ–เบฒเบ™เปƒเบ™ Istio - เบ›เบฐเบกเบฒเบ™. เบเบณเบ™เบปเบ”เบ„เปˆเบฒ Envoys เป€เบžเบทเปˆเบญเบเบงเบ”เบชเบญเบšเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบชเบปเปˆเบ‡เบ•เปเปˆเป„เบ›เบซเบฒเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™: sa-web-app ะธ sa-feedback. เปƒเบ™เป€เบงเบฅเบฒเบ”เบฝเบงเบเบฑเบ™, เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบšเปเปˆเป„เบ”เป‰เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เบเบฑเบš Envoys เบšเปเบฅเบดเบเบฒเบ™ sa-frontend, เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบญเบญเบเบˆเบฒเบ frontend เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบขเบฑเป‰เบ‡เบขเบทเบ™. เป€เบžเบทเปˆเบญเบ™เปเบฒเปƒเบŠเป‰เบ™เบฐเป‚เบเบšเบฒเบ, เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io โ€œauth-policyโ€ created

เบเบฑเบšเบ„เบทเบ™เป„เบ›เบซเบฒเบซเบ™เป‰เบฒเปเบฅเบฐเป€เบฎเบฑเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เป - เบ—เปˆเบฒเบ™เบˆเบฐเป€เบซเบฑเบ™เบงเปˆเบฒเบกเบฑเบ™เบชเบดเป‰เบ™เบชเบธเบ”เบฅเบปเบ‡เบ”เป‰เบงเบเบชเบฐเบ–เบฒเบ™เบฐเบžเบฒเบš 401 เบšเปเปˆเป„เบ”เป‰เบฎเบฑเบšเบญเบฐเบ™เบธเบเบฒเบ”. เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบ›เปˆเบฝเบ™เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบœเบนเป‰เปƒเบŠเป‰ frontend เป€เบžเบทเปˆเบญเบžเบดเบชเบนเบ”เบขเบทเบ™เบขเบฑเบ™เบ”เป‰เบงเบ Auth0.

เบเบฒเบ™เบขเบทเบ™เบขเบฑเบ™เบ„เบณเบฎเป‰เบญเบ‡เบ‚เปเบ”เป‰เบงเบ Auth0

เป€เบžเบทเปˆเบญเบžเบดเบชเบนเบ”เบขเบทเบ™เบขเบฑเบ™เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เปเบ‚เบญเบ‡เบœเบนเป‰เปƒเบŠเป‰เบชเบธเบ”เบ—เป‰เบฒเบ, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบชเป‰เบฒเบ‡ API เปƒเบ™ Auth0 เบ—เบตเปˆเบˆเบฐเป€เบ›เบฑเบ™เบ•เบปเบงเปเบ—เบ™เบ‚เบญเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบตเปˆเบขเบทเบ™เบขเบฑเบ™ (เบเบฒเบ™เบ—เบปเบšเบ—เบงเบ™เบ„เบทเบ™, เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เปเบฅเบฐเบเบฒเบ™เบˆเบฑเบ”เบญเบฑเบ™เบ”เบฑเบš). เป€เบžเบทเปˆเบญเบชเป‰เบฒเบ‡ API, เปƒเบซเป‰เป„เบ›เบ—เบตเปˆ Auth0 Portal > APIs > เบชเป‰เบฒเบ‡ API เปเบฅเบฐเบ•เบทเปˆเบกเปเบšเบšเบŸเบญเบก:

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบขเบนเปˆเบ—เบตเปˆเบ™เบตเป‰เปเบกเปˆเบ™ เบ•เบปเบงเบŠเบตเป‰เบงเบฑเบ”, เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเปƒเบŠเป‰เบ•เปเปˆเบกเบฒเปƒเบ™เบชเบฐเบ„เบดเบš. เบ‚เปโ€‹เปƒเบซเป‰โ€‹เบ‚เบฝเบ™โ€‹เป„เบงเป‰โ€‹เบ”เบฑเปˆเบ‡โ€‹เบ™เบตเป‰:

  • Audience: {YOUR_AUDIENCE}

เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบ—เบตเปˆเบเบฑเบ‡เป€เบซเบผเบทเบญเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เปเบกเปˆเบ™เบ•เบฑเป‰เบ‡เบขเบนเปˆเปƒเบ™ Auth0 Portal เปƒเบ™เบžเบฒเบ เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบ - เป€เบฅเบทเบญเบ เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบ (เบชเป‰เบฒเบ‡เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เบžเป‰เบญเบกเบเบฑเบš API).

เปƒเบ™เบ—เบตเปˆเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ‚เบฝเบ™:

  • เป‚เบ”เป€เบกเบ™: {YOUR_DOMAIN}
  • ID เบฅเบนเบเบ„เป‰เบฒ: {YOUR_CLIENT_ID}

เป€เบฅเบทเปˆเบญเบ™เป„เบ›เบซเบฒ เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบ เป„เบ›เบ—เบตเปˆเบŠเปˆเบญเบ‡เบ‚เปเป‰เบ„เบงเบฒเบก เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เป€เบญเบตเป‰เบ™เบ„เบทเบ™ URLs (เปเบเป‰เป„เบ‚ URLs เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป‚เบ—เบ„เบทเบ™), เปƒเบ™เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบ™เบปเบ” URL เบ—เบตเปˆเบเบฒเบ™เป‚เบ—เบ„เบงเบ™เบˆเบฐเบ–เบทเบเบชเบปเปˆเบ‡เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบเบงเบ”เบชเบญเบšเบชเปเบฒเป€เบฅเบฑเบ”. เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบกเบฑเบ™เปเบกเปˆเบ™:

http://{EXTERNAL_IP}/callback

เปเบฅเบฐ เบชเบณ เบฅเบฑเบš URL เบญเบญเบเบˆเบฒเบเบฅเบฐเบšเบปเบšเบ—เบตเปˆเป„เบ”เป‰เบฎเบฑเบšเบญเบฐเบ™เบธเบเบฒเบ” (เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰ URLs เบญเบญเบเบˆเบฒเบเบฅเบฐเบšเบปเบš) เป€เบžเบตเปˆเบก:

http://{EXTERNAL_IP}/logout

เบ‚เปเปƒเบซเป‰เบเป‰เบฒเบงเป„เบ›เบชเบนเปˆเป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบซเบ™เป‰เบฒ.

เบญเบฑเบšเป€เบ”เบ” Frontend

เบ›เปˆเบฝเบ™เป€เบ›เบฑเบ™เบชเบฒเบ‚เบฒ auth0 เบ„เบฑเบ‡เป€เบเบฑเบšเบกเป‰เบฝเบ™ [istio-mastery]. เปƒเบ™เบชเบฒเบ‚เบฒเบ™เบตเป‰, เบฅเบฐเบซเบฑเบ” frontend เบ–เบทเบเบ›เปˆเบฝเบ™เป€เบžเบทเปˆเบญเบ›เปˆเบฝเบ™เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบœเบนเป‰เปƒเบŠเป‰เป„เบ›เบซเบฒ Auth0 เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบžเบดเบชเบนเบ”เบขเบทเบ™เบขเบฑเบ™เปเบฅเบฐเบ™เปเบฒเปƒเบŠเป‰ JWT token เปƒเบ™เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฑเบšเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบญเบทเปˆเบ™เป†. เบชเบธเบ”เบ—เป‰เบฒเบเปเบกเปˆเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ”เบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰ (.App.js):

analyzeSentence() {
    fetch('/sentiment', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
        },
        body: JSON.stringify({ sentence: this.textField.getValue() })
    })
        .then(response => response.json())
        .then(data => this.setState(data));
}

เป€เบžเบทเปˆเบญเบ›เปˆเบฝเบ™เบชเปˆเบงเบ™เปœเป‰เบฒเป€เบžเบทเปˆเบญเปƒเบŠเป‰เบ‚เปเป‰เบกเบนเบ™เบœเบนเป‰เป€เบŠเบปเปˆเบฒเปƒเบ™ Auth0, เบเบฐเบฅเบธเบ™เบฒเป€เบ›เบตเบ” sa-frontend/src/services/Auth.js เปเบฅเบฐเปเบ—เบ™เบ—เบตเปˆเบ„เปˆเบฒเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ‚เบฝเบ™เบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡ (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // ะ˜ัะฟะพะปัŒะทัƒะตั‚ัั ะดะปั ั€ะตะดะธั€ะตะบั‚ะฐ ะฟะพัะปะต ะฐัƒั‚ะตะฝั‚ะธั„ะธะบะฐั†ะธะธ
}

เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเปเบกเปˆเบ™เบเบฝเบกเบžเป‰เบญเบก. เบฅเบฐเบšเบธ Docker ID เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เปƒเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เป€เบกเบทเปˆเบญเบชเป‰เบฒเบ‡เปเบฅเบฐเบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ—เบตเปˆเป€เบฎเบฑเบ”:

$ docker build -f sa-frontend/Dockerfile 
 -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 
 sa-frontend

$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

$ kubectl set image deployment/sa-frontend 
 sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

เบฅเบญเบ‡เปƒเบŠเป‰เปเบญเบฑเบš! เบ—เปˆเบฒเบ™เบˆเบฐเบ–เบทเบเป‚เบญเบ™เป„เบ›เบซเบฒ Auth0, เบšเปˆเบญเบ™เบ—เบตเปˆเบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบ‚เบปเป‰เบฒเบชเบนเปˆเบฅเบฐเบšเบปเบš (เบซเบผเบทเบฅเบปเบ‡เบ—เบฐเบšเบฝเบ™), เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ—เปˆเบฒเบ™เบˆเบฐเบ–เบทเบเบชเบปเปˆเบ‡เบเบฑเบšเบ„เบทเบ™เป„เบ›เบซเบฒเบซเบ™เป‰เบฒเบ—เบตเปˆเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบขเบทเบ™เบขเบฑเบ™เปเบฅเป‰เบงเบˆเบฐเบ–เบทเบเป€เบฎเบฑเบ”. เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบžเบฐเบเบฒเบเบฒเบกเบ„เปเบฒเบชเบฑเปˆเบ‡เบ—เบตเปˆเป„เบ”เป‰เบเปˆเบฒเบงเบกเบฒเปƒเบ™เบชเปˆเบงเบ™เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเบ—เบตเปˆเบกเบต curl, เบ—เปˆเบฒเบ™เบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเบฅเบฐเบซเบฑเบ” 401 เบฅเบฐเบซเบฑเบ”เบชเบฐเบ–เบฒเบ™เบฐ, เบชเบฑเบ™เบเบฒเบ™เบงเปˆเบฒเบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เปเบšเปเปˆเป„เบ”เป‰เบฎเบฑเบšเบญเบฐเบ™เบธเบเบฒเบ”.

เปƒเบซเป‰เบ‚เบฑเป‰เบ™เบ•เบญเบ™เบ•เปเปˆเป„เบ› - เบญเบฐเบ™เบธเบเบฒเบ”เบเบฒเบ™เบฎเป‰เบญเบ‡เบ‚เป.

เบเบฒเบ™เบญเบฐเบ™เบธเบกเบฑเบ”เบ”เป‰เบงเบ Auth0

เบเบฒเบ™เบเบงเบ”เบชเบญเบšเบ„เบงเบฒเบกเบ–เบทเบเบ•เป‰เบญเบ‡เป€เบฎเบฑเบ”เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเป€เบ‚เบปเป‰เบฒเปƒเบˆเบงเปˆเบฒเบœเบนเป‰เปƒเบŠเป‰เปเบกเปˆเบ™เปƒเบœ, เปเบ•เปˆเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปเบกเปˆเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เป€เบžเบทเปˆเบญเบฎเบนเป‰เบงเปˆเบฒเบžเบงเบเป€เบ‚เบปเบฒเป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบซเบเบฑเบ‡. Istio เบชเบฐเป€เบซเบ™เบตเป€เบ„เบทเปˆเบญเบ‡เบกเบทเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ™เบตเป‰เป€เบŠเบฑเปˆเบ™เบ”เบฝเบงเบเบฑเบ™.

เบ•เบปเบงเบขเปˆเบฒเบ‡, เปƒเบซเป‰เบชเป‰เบฒเบ‡เบชเบญเบ‡เบเบธเปˆเบกเบœเบนเป‰เปƒเบŠเป‰ (เป€เบšเบดเปˆเบ‡เปเบœเบ™เบงเบฒเบ”เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰):

  • เบœเบนเป‰เปƒเบŠเป‰ (เบœเบนเป‰เปƒเบŠเป‰) โ€” เบกเบตเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบžเบฝเบ‡เปเบ•เปˆเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™ SA-WebApp เปเบฅเบฐ SA-Frontend;
  • เบœเบนเป‰เบ„เบงเบšเบ„เบธเบก (เบœเบนเป‰เบ„เบงเบšเบ„เบธเบก) โ€” เบกเบตโ€‹เบเบฒเบ™โ€‹เป€เบ‚เบปเป‰เบฒโ€‹เป€เบ–เบดเบ‡โ€‹เบ—เบฑเบ‡โ€‹เบชเบฒเบกโ€‹เบเบฒเบ™โ€‹เบšเปโ€‹เบฅเบดโ€‹เบเบฒเบ™โ€‹.

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3
เปเบ™เบงเบ„เบงเบฒเบกเบ„เบดเบ”เบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”

เป€เบžเบทเปˆเบญเบชเป‰เบฒเบ‡เบเบธเปˆเบกเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ‚เบฐเบซเบเบฒเบเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ” Auth0 เปเบฅเบฐเบ™เปเบฒเปƒเบŠเป‰ Istio เป€เบžเบทเปˆเบญเปƒเบซเป‰เบžเบงเบเป€เบ‚เบปเบฒเบกเบตเบฅเบฐเบ”เบฑเบšเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™.

เบเบฒเบ™เบ•เบดเบ”เบ•เบฑเป‰เบ‡เปเบฅเบฐเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ” Auth0

เปƒเบ™เบ›เบฐเบ•เบน Auth0, เป„เบ›เบ—เบตเปˆเบชเปˆเบงเบ™เบ‚เบฐเบซเบเบฒเบ (เบเบฒเบ™โ€‹เบ‚เบฐโ€‹เบซเบเบฒเบ) เปเบฅเบฐโ€‹เบ•เบดเบ”โ€‹เบ•เบฑเป‰เบ‡โ€‹ Auth0 เบเบฒเบ™โ€‹เบญเบฐโ€‹เบ™เบธโ€‹เบเบฒเบ”โ€‹. เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบ•เบดเบ”เบ•เบฑเป‰เบ‡, เป„เบ›เบ—เบตเปˆ เบเบฒเบ™เบ‚เบฐเบซเบเบฒเบเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”, เปเบฅเบฐเบขเบนเปˆเบ—เบตเปˆเบ™เบฑเป‰เบ™ - เบเบฑเบšเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ‚เบญเบ‡เบœเบนเป‰เป€เบŠเบปเปˆเบฒเป‚เบ”เบเบเบฒเบ™เบ„เบฅเบดเบเปƒเบชเปˆเบ‚เบงเบฒเป€เบ—เบดเบ‡เปเบฅเบฐเป€เบฅเบทเบญเบเบ•เบปเบงเป€เบฅเบทเบญเบเป€เบกเบ™เบนเบ—เบตเปˆเป€เบซเบกเบฒเบฐเบชเบปเบก. (เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ). เป€เบ›เบตเบ”เปƒเบŠเป‰เบเบธเปˆเบก (เบเบธเปˆเบก) เปเบฅเบฐโ€‹เปƒเบซเป‰โ€‹เบ„เบฅเบดเบโ€‹เปƒเบชเปˆโ€‹เบ›เบธเปˆเบกโ€‹เบเบปเบ”โ€‹เบฅเบฐโ€‹เบšเบฝเบšโ€‹เบเบฒเบ™โ€‹เป€เบœเบตเบโ€‹เปเบœเปˆโ€‹ (เบเบปเบ”โ€‹เบฅเบฐโ€‹เบšเบฝเบšโ€‹เบเบฒเบ™โ€‹เป€เบœเบตเบโ€‹เปเบœเปˆโ€‹).

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เบชเป‰เบฒเบ‡เบเบธเปˆเบก

เปƒเบ™โ€‹เบเบฒเบ™โ€‹เบ‚เบฐโ€‹เบซเบเบฒเบโ€‹เบเบฒเบ™โ€‹เบญเบฐโ€‹เบ™เบธโ€‹เบเบฒเบ”โ€‹เป„เบ›โ€‹เบ—เบตเปˆ Groups เปเบฅเบฐเบชเป‰เบฒเบ‡เบเบธเปˆเบก Moderators. เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เปเปˆเบœเบนเป‰เปƒเบŠเป‰เบ—เบตเปˆเบกเบตเบ„เบงเบฒเบกเบ–เบทเบเบ•เป‰เบญเบ‡เบ—เบฑเบ‡เบซเบกเบปเบ”เป€เบ›เบฑเบ™เบœเบนเป‰เปƒเบŠเป‰เบ›เบปเบเบเบฐเบ•เบด, เบกเบฑเบ™เบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบชเป‰เบฒเบ‡เบเบธเปˆเบกเป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบชเปเบฒเบฅเบฑเบšเบžเบงเบเป€เบ‚เบปเบฒ.

เป€เบฅเบทเบญเบเบเบธเปˆเบก Moderators, เบเบปเบ”เบ›เบธเปˆเบก เป€เบžเบตเปˆเบกเบชเบฐเบกเบฒเบŠเบดเบ, เป€เบžเบตเปˆเบกเบšเบฑเบ™เบŠเบตเบ•เบปเป‰เบ™เบ•เปเบ‚เบญเบ‡เบ—เปˆเบฒเบ™. เบ›เปˆเบญเบเปƒเบซเป‰เบœเบนเป‰เปƒเบŠเป‰เบšเบฒเบ‡เบ„เบปเบ™เป‚เบ”เบเบšเปเปˆเบกเบตเบเบธเปˆเบกเป€เบžเบทเปˆเบญเปƒเบซเป‰เปเบ™เปˆเปƒเบˆเบงเปˆเบฒเบžเบงเบเป€เบ‚เบปเบฒเบ–เบทเบเบ›เบฐเบ•เบดเป€เบชเบ”เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡. (เบœเบนเป‰เปƒเบŠเป‰เปƒเบซเบกเปˆเบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เบ”เป‰เบงเบเบ•เบปเบ™เป€เบญเบ‡เป‚เบ”เบเบœเปˆเบฒเบ™ Auth0 Portal > เบœเบนเป‰เปƒเบŠเป‰ > เบชเป‰เบฒเบ‡เบœเบนเป‰เปƒเบŠเป‰.)

เป€เบžเบตเปˆเบกเบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡เบเบธเปˆเบกเป€เบžเบทเปˆเบญเป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡ Token

เบœเบนเป‰โ€‹เปƒเบŠเป‰โ€‹เป„เบ”เป‰โ€‹เบ–เบทเบโ€‹เป€เบžเบตเปˆเบกโ€‹เป€เบ‚เบปเป‰เบฒโ€‹เป„เบ›โ€‹เปƒเบ™โ€‹เบเบธเปˆเบกโ€‹, เปเบ•เปˆโ€‹เบ‚เปเป‰โ€‹เบกเบนเบ™โ€‹เบ™เบตเป‰โ€‹เบเบฑเบ‡โ€‹เบ•เป‰เบญเบ‡โ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบเบฒเบ™โ€‹เบชเบฐโ€‹เบ—เป‰เบญเบ™โ€‹เปƒเบซเป‰โ€‹เป€เบซเบฑเบ™โ€‹เปƒเบ™ tokens เบเบฒเบ™โ€‹เป€เบ‚เบปเป‰เบฒโ€‹เป€เบ–เบดเบ‡โ€‹. เป€เบžเบทเปˆเบญเบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เบฒเบก OpenID Connect เปเบฅเบฐเปƒเบ™เป€เบงเบฅเบฒเบ”เบฝเบงเบเบฑเบ™เบชเบปเปˆเบ‡เบ„เบทเบ™เบเบธเปˆเบกเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™, token เบˆเบฐเบ•เป‰เบญเบ‡เป€เบžเบตเปˆเบกเบ‚เบญเบ‡เบกเบฑเบ™เป€เบญเบ‡. เบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡เปเบšเบšเบเบณเบ™เบปเบ”เป€เบญเบ‡. เบ›เบฐเบ•เบดเบšเบฑเบ”เบœเปˆเบฒเบ™เบเบปเบ”เบฅเบฐเบšเบฝเบš Auth0.

เป€เบžเบทเปˆเบญเบชเป‰เบฒเบ‡เบเบปเบ”เบฅเบฐเบšเบฝเบš, เป„เบ›เบ—เบตเปˆ Auth0 Portal to เบเบปเบ”เบฅเบฐเบšเบฝเบš, เบเบปเบ”เบ›เบธเปˆเบก เบชเป‰เบฒเบ‡เบเบปเบ”เบฅเบฐเบšเบฝเบš เปเบฅเบฐเป€เบฅเบทเบญเบเบเบปเบ”เบฅเบฐเบšเบฝเบšเบซเบงเปˆเบฒเบ‡เป€เบ›เบปเปˆเบฒเบˆเบฒเบเปเบกเปˆเปเบšเบš.

เบเบฑเบšเป„เบ›เบซเบฒเบšเปเบฅเบดเบเบฒเบ™เบˆเบธเบฅเบฐเบžเบฒเบเบเบฑเบš Istio. เบžเบฒเบเบ—เบต 3

เบ„เบฑเบ”เบฅเบญเบเบฅเบฐเบซเบฑเบ”เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เปเบฅเบฐเบšเบฑเบ™เบ—เบถเบเบกเบฑเบ™เป€เบ›เบฑเบ™เบเบปเบ”เบฅเบฐเบšเบฝเบšเปƒเบซเบกเปˆ เป€เบžเบตเปˆเบกเบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡เบเบธเปˆเบก (namespacedGroup.js):

function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}

ะŸั€ะธะผะตั‡ะฐะฝะธะต: เบฅเบฐเบซเบฑเบ”เบ™เบตเป‰เป€เบญเบปเบฒเบเบธเปˆเบกเบœเบนเป‰เปƒเบŠเป‰เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเบเปเบฒเบ™เบปเบ”เบขเบนเปˆเปƒเบ™เบเบฒเบ™เบ‚เบฐเบซเบเบฒเบเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปเบฅเบฐเป€เบžเบตเปˆเบกเบกเบฑเบ™เปƒเบชเปˆ token เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เป€เบ›เบฑเบ™เบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡เปเบšเบšเบเปเบฒเบ™เบปเบ”เป€เบญเบ‡ (เบžเบฒเบเปƒเบ•เป‰ namespace เบ‚เบญเบ‡เบกเบฑเบ™, เบ•เบฒเบกเบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™เบ‚เบญเบ‡ Auth0).

เบเบฑเบšเป„เบ›เบ—เบตเปˆเปœเป‰เบฒ เบเบปเบ”เบฅเบฐเบšเบฝเบš เปเบฅเบฐเบเบงเบ”เป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบ—เปˆเบฒเบ™เบกเบตเบชเบญเบ‡เบเบปเบ”เบฅเบฐเบšเบฝเบšเบ‚เบฝเบ™เบขเบนเปˆเปƒเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

  • auth0-authorization-extension
  • เป€เบžเบตเปˆเบกเบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡เบเบธเปˆเบก

เบ„เปเบฒเบชเบฑเปˆเบ‡เปเบกเปˆเบ™เบชเปเบฒเบ„เบฑเบ™เป€เบžเบฒเบฐเบงเปˆเบฒเบžเบฒเบเบชเบฐเบซเบ™เบฒเบกเบ‚เบญเบ‡เบเบธเปˆเบกเป„เบ”เป‰เบฎเบฑเบšเบเบปเบ”เบฅเบฐเบšเบฝเบš asynchronously auth0-authorization-extension เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบกเบฑเบ™เบ–เบทเบเป€เบžเบตเปˆเบกเป€เบ›เบฑเบ™เบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡เป‚เบ”เบเบเบปเบ”เบฅเบฐเบšเบฝเบšเบ—เบตเบชเบญเบ‡. เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเปเบกเปˆเบ™ token เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เป€เบŠเบฑเปˆเบ™เบ™เบตเป‰:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [ัะพะบั€ะฐั‰ะตะฝะพ ะดะปั ะฝะฐะณะปัะดะฝะพัั‚ะธ]
}

เบ•เบญเบ™เบ™เบตเป‰เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบ›เบฑเบšเบ„เปˆเบฒเบ•เบปเบงเปเบ—เบ™ Envoy เป€เบžเบทเปˆเบญเบเบงเบ”เบชเบญเบšเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบ‚เบญเบ‡เบœเบนเป‰เปƒเบŠเป‰, เป€เบŠเบดเปˆเบ‡เบเบธเปˆเบกเบˆเบฐเบ–เบทเบเบ”เบถเบ‡เบญเบญเบเบˆเบฒเบเบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡ (https://sa.io/group) เปƒเบ™ token เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฑเบšเบ„เบทเบ™. เบ™เบตเป‰เปเบกเปˆเบ™เบซเบปเบงเบ‚เปเป‰เบชเปเบฒเบฅเบฑเบšเบžเบฒเบเบ•เปเปˆเป„เบ›เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบก.

เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบ™ Istio

เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เป€เบฎเบฑเบ”เบงเบฝเบ, เบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เป€เบ›เบตเบ”เปƒเบŠเป‰ RBAC เบชเปเบฒเบฅเบฑเบš Istio. เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ•เปเปˆเป„เบ›เบ™เบตเป‰:

apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'                     # 1
  inclusion:
    services:                                   # 2
    - "sa-frontend.default.svc.cluster.local"
    - "sa-web-app.default.svc.cluster.local"
    - "sa-feedback.default.svc.cluster.local" 

เบ„เบณ เบญเบฐเบ—เบดเบšเบฒเบ:

  • 1 โ€” เป€เบ›เบตเบ”เปƒเบŠเป‰ RBAC เบžเบฝเบ‡เปเบ•เปˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เปเบฅเบฐ namespaces เบ—เบตเปˆเบฅเบฐเบšเบธเป„เบงเป‰เปƒเบ™เบžเบฒเบเบชเบฐเบซเบ™เบฒเบก Inclusion;
  • 2 โ€” เบžเบงเบเป€เบฎเบปเบฒเบฅเบฒเบเบŠเบทเปˆเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ.

เปƒเบซเป‰เปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ”เป‰เบงเบเบ„เปเบฒเบชเบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created

เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบฑเบ‡เปเบปเบ”เบ•เบญเบ™เบ™เบตเป‰เบ•เป‰เบญเบ‡เบเบฒเบ™เบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบ—เบตเปˆเบญเบตเบ‡เปƒเบชเปˆเบšเบปเบ”เบšเบฒเบ”. เปƒเบ™เบ„เปเบฒเบชเบฑเบšเบ•เปˆเบฒเบ‡เป†เบญเบทเปˆเบ™เป†, เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เปเบกเปˆเบ™เบ–เบทเบเบซเป‰เบฒเบกเปเบฅเบฐเบˆเบฐเบชเบปเปˆเบ‡เบœเบปเบ™เบ•เบญเบšเปเบ—เบ™ RBAC: access denied. เบ”เบฝเบงเบ™เบตเป‰เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบœเบนเป‰เปƒเบŠเป‰เบ—เบตเปˆเป„เบ”เป‰เบฎเบฑเบšเบญเบฐเบ™เบธเบเบฒเบ”.

เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เปƒเบŠเป‰เบ›เบปเบเบเบฐเบ•เบด

เบœเบนเป‰เปƒเบŠเป‰เบ—เบฑเบ‡เปเบปเบ”เบ•เป‰เบญเบ‡เบกเบตเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™ SA-Frontend เปเบฅเบฐ SA-WebApp. เบ›เบฐเบ•เบดเบšเบฑเบ”เป‚เบ”เบเปƒเบŠเป‰เบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™ Istio เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

  • เบšเบปเบ”เบšเบฒเบ”เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™ - เบเปเบฒเบ™เบปเบ”เบชเบดเบ”เบ—เบดเบ—เบตเปˆเบœเบนเป‰เปƒเบŠเป‰เบกเบต;
  • ServiceRoleBinding โ€” เบเปเบฒเบ™เบปเบ”เบงเปˆเบฒ ServiceRole เบ™เบตเป‰เบ‚เบถเป‰เบ™เบเบฑเบšเปƒเบœ.

เบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เปƒเบŠเป‰เบ—เบปเปˆเบงเป„เบ›เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบชเบฐเป€เบžเบฒเบฐเปƒเบ”เบซเบ™เบถเปˆเบ‡ (servicerole.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: regular-user
  namespace: default
spec:
  rules:
  - services: 
    - "sa-frontend.default.svc.cluster.local" 
    - "sa-web-app.default.svc.cluster.local"
    paths: ["*"]
    methods: ["*"]

เปเบฅเบฐเบœเปˆเบฒเบ™ regular-user-binding เบ™เบณเปƒเบŠเป‰ ServiceRole เบเบฑเบšเบœเบนเป‰เป€เบ‚เบปเป‰เบฒเบŠเบปเบกเปœเป‰เบฒเบ—เบฑเบ‡เปเบปเบ” (normal-user-service-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: regular-user-binding
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "regular-user"

"เบœเบนเป‰เปƒเบŠเป‰เบ—เบฑเบ‡เบซเบกเบปเบ”" เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบœเบนเป‰เปƒเบŠเป‰เบ—เบตเปˆเบšเปเปˆเป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบขเบทเบ™เบขเบฑเบ™เบˆเบฐเบกเบตเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡ SA WebApp เบšเป? เบšเปเปˆ, เบ™เบฐเป‚เบเบšเบฒเบเบˆเบฐเบเบงเบ”เบชเบญเบšเบ„เบงเบฒเบกเบ–เบทเบเบ•เป‰เบญเบ‡เบ‚เบญเบ‡ JWT token.

เปƒเบซเป‰เปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ:

$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding created

เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบชเบณเบฅเบฑเบšเบœเบนเป‰เบ„เบงเบšเบ„เบธเบก

เบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เบ„เบงเบšเบ„เบธเบก, เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบ›เบตเบ”เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ” (mod-service-role.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: mod-user
  namespace: default
spec:
  rules:
  - services: ["*"]
    paths: ["*"]
    methods: ["*"]

เปเบ•เปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบชเบดเบ”เบ—เบดเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบชเปเบฒเบฅเบฑเบšเบœเบนเป‰เปƒเบŠเป‰เบ—เบตเปˆ token เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบกเบตเบเบฒเบ™เบฎเบฝเบเบฎเป‰เบญเบ‡ https://sa.io/group เบ—เบตเปˆโ€‹เบกเบตโ€‹เบ„เบงเบฒเบกโ€‹เบซเบกเบฒเบโ€‹ Moderators (mod-service-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: mod-user-binding
  namespace: default
spec:
  subjects:
  - properties:
      request.auth.claims[https://sa.io/group]: "Moderators"
  roleRef:
    kind: ServiceRole
name: "mod-user" 

เปƒเบซเป‰เปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ:

$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding created

เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบเบฒเบ™เป€เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™เป„เบงเป‰เบขเบนเปˆเปƒเบ™เบ—เบนเบ”, เบกเบฑเบ™เบญเบฒเบ”เบˆเบฐเปƒเบŠเป‰เป€เบงเบฅเบฒเบชเบญเบ‡เบชเบฒเบกเบ™เบฒเบ—เบตเป€เบžเบทเปˆเบญเปƒเบซเป‰เบเบปเบ”เบฅเบฐเบšเบฝเบšเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เบกเบตเบœเบปเบ™เบšเบฑเบ‡เบ„เบฑเบšเปƒเบŠเป‰. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบฎเบฑเบšเบ›เบฐเบเบฑเบ™เบงเปˆเบฒเบœเบนเป‰เปƒเบŠเป‰เปเบฅเบฐเบœเบนเป‰เบ„เบงเบšเบ„เบธเบกเบกเบตเบฅเบฐเบ”เบฑเบšเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™.

เบชเบฐเบซเบผเบธเบšเปƒเบ™เบชเปˆเบงเบ™เบ™เบตเป‰

เบขเปˆเบฒเบ‡เบˆเบดเบ‡เบˆเบฑเบ‡, เป€เบˆเบปเป‰เบฒเป€เบ„เบตเบเป€เบซเบฑเบ™เบงเบดเบ—เบตเบเบฒเบ™เบ—เบตเปˆเบ‡เปˆเบฒเบเบเบงเปˆเบฒ, เบšเปเปˆเบ•เป‰เบญเบ‡เบžเบฐเบเบฒเบเบฒเบก, เบ‚เบฐเบซเบเบฒเบเป„เบ”เป‰ เปเบฅเบฐเบ›เบญเบ”เป„เบžเบ•เปเปˆเบเบฑเบšเบเบฒเบ™เบขเบฑเป‰เบ‡เบขเบทเบ™ เปเบฅเบฐ เบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เบšเป?

เบกเบตเบžเบฝเบ‡เปเบ•เปˆเบชเบฒเบกเบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™ Istio (RbacConfig, ServiceRole, เปเบฅเบฐ ServiceRoleBinding) เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™เบ—เบตเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบžเบทเปˆเบญเบšเบฑเบ™เบฅเบธเบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเบ—เบตเปˆเบฅเบฐเบญเบฝเบ”เบญเปˆเบญเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบžเบดเบชเบนเบ”เบขเบทเบ™เบขเบฑเบ™เปเบฅเบฐเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบœเบนเป‰เปƒเบŠเป‰เบชเบธเบ”เบ—เป‰เบฒเบเป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™.

เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบ”เบนเปเบฅเบšเบฑเบ™เบซเบฒเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบญเบญเบเบˆเบฒเบเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบนเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ, เบšเบฑเบ™เบฅเบธเป„เบ”เป‰:

  • เบเบฒเบ™เบซเบผเบธเบ”เบœเปˆเบญเบ™เบˆเปเบฒเบ™เบงเบ™เบฅเบฐเบซเบฑเบ”เบ—เบปเปˆเบงเป„เบ›เบ—เบตเปˆเบญเบฒเบ”เบˆเบฐเบกเบตเบšเบฑเบ™เบซเบฒเบ„เบงเบฒเบกเบ›เบญเบ”เป„เบžเปเบฅเบฐเบ‚เปเป‰เบšเบปเบเบžเปˆเบญเบ‡;
  • เบเบฒเบ™เบซเบผเบธเบ”เบœเปˆเบญเบ™เบˆเปเบฒเบ™เบงเบ™เบ‚เบญเบ‡เบชเบฐเบ–เบฒเบ™เบฐเบเบฒเบ™ stupid เปƒเบ™เบซเบ™เบถเปˆเบ‡ endpoint เบซเบฑเบ™เบญเบญเบเป€เบžเบทเปˆเบญเปƒเบซเป‰เบชเบฒเบกเบฒเบ”เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เป„เบ”เป‰เบˆเบฒเบเบžเบฒเบเบ™เบญเบเปเบฅเบฐเบฅเบทเบกเบ—เบตเปˆเบˆเบฐเบฅเบฒเบเบ‡เบฒเบ™เบกเบฑเบ™;
  • เบเบฒเบ™เบฅเบปเบšเบฅเป‰เบฒเบ‡เบ„เบงเบฒเบกเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบ›เบฑเบšเบ›เบธเบ‡เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบธเบเบ„เบฑเป‰เบ‡เบ—เบตเปˆเบกเบตเบเบฒเบ™เป€เบžเบตเปˆเบกเบšเบปเบ”เบšเบฒเบ”เบซเบผเบทเบชเบดเบ”เปƒเบซเบกเปˆ;
  • เบงเปˆเบฒเบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™เปƒเบซเบกเปˆเบเบฑเบ‡เบ„เบปเบ‡เบ‡เปˆเบฒเบเบ”เบฒเบ, เบ›เบญเบ”เป„เบžเปเบฅเบฐเป„เบง.

เบชเบฐเบซเบฅเบธเบš

Istio เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เบตเบกเบ‡เบฒเบ™เบชเบธเบกเปƒเบชเปˆเบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™เบ‚เบญเบ‡เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบงเบฝเบเบ‡เบฒเบ™เบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบ‚เบญเบ‡เบ—เบธเบฅเบฐเบเบดเบ”เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เป€เบžเบตเปˆเบกเบ„เปˆเบฒเปƒเบŠเป‰เบˆเปˆเบฒเบเปƒเบ™เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™, เปƒเบซเป‰เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบเบฑเบšเบ„เบทเบ™เบชเบนเปˆเบชเบฐเบ–เบฒเบ™เบฐเบžเบฒเบšเบˆเบธเบ™เบฅเบฐเบžเบฒเบ.

เบšเบปเบ”เบ„เบงเบฒเบก (เปƒเบ™เบชเบฒเบกเบชเปˆเบงเบ™) เป„เบ”เป‰เปƒเบซเป‰เบ„เบงเบฒเบกเบฎเบนเป‰เบžเบทเป‰เบ™เบ–เบฒเบ™เปเบฅเบฐเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบžเบฒเบเบ›เบฐเบ•เบดเบšเบฑเบ”เบ—เบตเปˆเบเบฝเบกเบžเป‰เบญเบกเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบเบฑเบš Istio เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเปเบ—เป‰เบˆเบดเบ‡.

PS เบˆเบฒเบเบ™เบฑเบเปเบ›

เบญเปˆเบฒเบ™เบเบฑเบ‡เบขเบนเปˆเปƒเบ™ blog เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ:

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™