Π ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΠ΅ ΡΡΠ·Π΄Π°ΠΌ ΡΠ°Π±ΠΎΡΠ½Π° ΡΡΠ΅Π΄Π° Π·Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ²Π°Π½Π΅ Π½Π° ΠΈΠ³ΡΠ°ΡΠ° "Epics", Π° ΡΡΡΠΎ ΡΠ°ΠΊΠ° ΡΠ΅ ΡΠ°Π·Π΄Π΅Π»Ρ ΡΠ°ΠΌΠ°ΡΠ° ΠΈΠ³ΡΠ° Π½Π° ΡΠ°ΡΡΠΈ, ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π² OpenFaaS. Π©Π΅ Π½Π°ΠΏΡΠ°Π²Ρ Π²ΡΠΈΡΠΊΠΈ ΠΌΠ°Π½ΠΈΠΏΡΠ»Π°ΡΠΈΠΈ Π½Π° Linux, ΡΠ΅ ΡΠ°Π·ΠΏΠΎΠ»ΠΎΠΆΠ° Kubernetes Π² minikube Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° VirtualBox. Π Π°Π±ΠΎΡΠ½Π°ΡΠ° ΠΌΠΈ ΠΌΠ°ΡΠΈΠ½Π° ΠΈΠΌΠ° 2 ΠΏΡΠΎΡΠ΅ΡΠΎΡΠ½ΠΈ ΡΠ΄ΡΠ° ΠΈ 12 GB RAM; ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ SSD ΠΊΠ°ΡΠΎ ΡΠΈΡΡΠ΅ΠΌΠ΅Π½ Π΄ΠΈΡΠΊ. Π©Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ debian 8 ΠΊΠ°ΡΠΎ ΠΌΠΎΡ ΠΎΡΠ½ΠΎΠ²Π½Π° ΡΠΈΡΡΠ΅ΠΌΠ° Π·Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°, Ρ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΈ emacs, sudo, git ΠΈ virtualbox, Π²ΡΠΈΡΠΊΠΎ ΠΎΡΡΠ°Π½Π°Π»ΠΎ ΡΠ΅ ΡΠ΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ° ΡΡΠ΅Π· ΠΈΠ·ΡΠ΅Π³Π»ΡΠ½Π΅ ΠΎΡ GitHub ΠΈ Π΄ΡΡΠ³ΠΈ ΠΈΠ·ΡΠΎΡΠ½ΠΈΡΠΈ. ΠΠΈΠ΅ ΡΠ΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ ΡΠ΅Π·ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π² /usr/local/bin, ΠΎΡΠ²Π΅Π½ Π°ΠΊΠΎ Π½Π΅ Π΅ ΠΏΠΎΡΠΎΡΠ΅Π½ΠΎ Π΄ΡΡΠ³ΠΎ. ΠΠ° Π·Π°ΠΏΠΎΡΠ²Π°ΠΌΠ΅!
ΠΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ° Π½Π° ΡΠ°Π±ΠΎΡΠ½Π°ΡΠ° ΡΡΠ΅Π΄Π°
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° Go
Π‘Π»Π΅Π΄Π²Π°ΠΌΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ ΠΎΡ ΠΎΡΠΈΡΠΈΠ°Π»Π½ΠΈΡ ΡΠ°ΠΉΡ:
$ curl -L0 https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz -o go.tar.gz
$ sudo tar -C /usr/local -xzf go.tar.gz
$ echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡΡΠ°:
$ mkdir -p ~/go/src/hello && cd ~/go/src/hello
$ echo 'package main
import "fmt"
func main() {
fmt.Printf("hello, worldn")
}' > hello.go
$ go build
$ ./hello
hello, world
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° faas-cli
Π‘Π»Π΅Π΄Π²Π°ΠΌΠ΅ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ ΠΎΡ ΠΎΡΠΈΡΠΈΠ°Π»Π½ΠΈΡ ΡΠ°ΠΉΡ:
$ curl -sSL https://cli.openfaas.com | sudo -E sh
x86_64
Downloading package https://github.com/openfaas/faas-cli/releases/download/0.11.3/faas-cli as /tmp/faas-cli
Download complete.
Running with sufficient permissions to attempt to move faas-cli to /usr/local/bin
New version of faas-cli installed to /usr/local/bin
Creating alias 'faas' for 'faas-cli'.
___ _____ ____
/ _ _ __ ___ _ __ | ___|_ _ __ _/ ___|
| | | | '_ / _ '_ | |_ / _` |/ _` ___
| |_| | |_) | __/ | | | _| (_| | (_| |___) |
___/| .__/ ___|_| |_|_| __,_|__,_|____/
|_|
CLI:
commit: 73004c23e5a4d3fdb7352f953247473477477a64
version: 0.11.3
ΠΡΠ²Π΅Π½ ΡΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΡΠ΅ bash-Π·Π°Π²ΡΡΡΠ²Π°Π½Π΅:
faas-cli completion --shell bash | sudo tee /etc/bash_completion.d/faas-cli
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½Π΅ Π½Π° Kubernetes
ΠΠ° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°, minikube Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ΅Π½, ΡΠ°ΠΊΠ° ΡΠ΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΉΡΠ΅ Π³ΠΎ ΠΈ kubelet Π² /usr/local/bin ΠΈ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΉΡΠ΅ helm Π·Π° ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
$ curl https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 -o minikube && chmod +x minikube && sudo mv minikube /usr/local/bin/
$ curl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -o kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
$ curl https://get.helm.sh/helm-v3.0.2-linux-amd64.tar.gz | tar -xzvf - linux-amd64/helm --strip-components=1; sudo mv helm /usr/local/bin
Π‘ΡΠ°ΡΡΠΈΡΠ°ΠΉΡΠ΅ minikube:
$ minikube start
minikube v1.6.2 on Debian 8.11
Automatically selected the 'virtualbox' driver (alternates: [])
Downloading VM boot image ...
> minikube-v1.6.0.iso.sha256: 65 B / 65 B [--------------] 100.00% ? p/s 0s
> minikube-v1.6.0.iso: 150.93 MiB / 150.93 MiB [-] 100.00% 5.67 MiB p/s 27s
Creating virtualbox VM (CPUs=2, Memory=8192MB, Disk=20000MB) ...
Preparing Kubernetes v1.17.0 on Docker '19.03.5' ...
Downloading kubeadm v1.17.0
Downloading kubelet v1.17.0
Pulling images ...
Launching Kubernetes ... Waiting for cluster to come online ...
Done! kubectl is now configured to use "minikube"
ΠΏΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅:
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6955765f44-knlcb 1/1 Running 0 29m
kube-system coredns-6955765f44-t9cpn 1/1 Running 0 29m
kube-system etcd-minikube 1/1 Running 0 28m
kube-system kube-addon-manager-minikube 1/1 Running 0 28m
kube-system kube-apiserver-minikube 1/1 Running 0 28m
kube-system kube-controller-manager-minikube 1/1 Running 0 28m
kube-system kube-proxy-hv2wc 1/1 Running 0 29m
kube-system kube-scheduler-minikube 1/1 Running 0 28m
kube-system storage-provisioner 1/1 Running 1 29m
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° OpenFaaS
Π Π°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈΡΠ΅ ΠΏΡΠ΅ΠΏΠΎΡΡΡΠ²Π°Ρ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° 2 ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π° ΠΎΡ ΠΈΠΌΠ΅Π½Π°, Ρ ΠΊΠΎΠΈΡΠΎ Π΄Π° ΡΠ°Π±ΠΎΡΠΈΡΠ΅:
$ kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
namespace/openfaas created
namespace/openfaas-fn created
ΠΠΎΠ±Π°Π²ΡΠ½Π΅ Π½Π° Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π·Π° ΠΊΠΎΡΠΌΠΈΠ»ΠΎ:
$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" has been added to your repositories
ΠΠΈΠ°Π³ΡΠ°ΠΌΠ°ΡΠ° ΠΈΠΌΠ° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ Π·Π° Π·Π°Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΏΠ°ΡΠΎΠ»Π° ΠΏΡΠ΅Π΄ΠΈ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅, Π½Π΅ΠΊΠ° Ρ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΈ Π·Π°ΠΏΠ°Π·ΠΈΠΌ Π΄Π°Π½Π½ΠΈΡΠ΅ Π·Π° Π΄ΠΎΡΡΡΠΏ ΠΊΠ°ΡΠΎ k8s ΡΠ°ΠΉΠ½Π°:
$ PASSWORD=verysecurerandompasswordstring
$ kubectl -n openfaas create secret generic basic-auth --from-literal=basic-auth-user=admin --from-literal=basic-auth-password="$PASSWORD"
secret/basic-auth created
ΠΠ° Π²Π½Π΅Π΄ΡΠΈΠΌ:
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "openfaas" chart repository
Update Complete. Happy Helming!
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
Release "openfaas" does not exist. Installing it now.
NAME: openfaas
LAST DEPLOYED: Fri Dec 25 10:28:22 2019
NAMESPACE: openfaas
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
To verify that openfaas has started, run:
kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
Π‘Π»Π΅Π΄ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π°ΠΌΠ΅ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½Π°ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π°:
$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NAME READY UP-TO-DATE AVAILABLE AGE
alertmanager 1/1 1 1 114s
basic-auth-plugin 1/1 1 1 114s
faas-idler 1/1 1 1 114s
gateway 1/1 1 1 114s
nats 1/1 1 1 114s
prometheus 1/1 1 1 114s
queue-worker 1/1 1 1 114s
ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π½Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π½ΠΎΡΡΡΠ°:
$ kubectl rollout status -n openfaas deploy/gateway
deployment "gateway" successfully rolled out
$ kubectl port-forward -n openfaas svc/gateway 8080:8080 &
[1] 6985
Forwarding from 127.0.0.1:8080 -> 8080
$ echo -n $PASSWORD | faas-cli login --username admin --password-stdin
Calling the OpenFaaS server to validate the credentials...
Handling connection for 8080
WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates.
credentials saved for admin http://127.0.0.1:8080
$ faas-cli list
Function Invocations Replicas
ΠΠ½ΡΡΠ°Π»ΠΈΡΠ°Π½Π΅ Π½Π° Mongodb
ΠΠΈΠ΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°ΠΌΠ΅ Π²ΡΠΈΡΠΊΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΠ° Π½Π° helm:
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
"stable" has been added to your repositories
$ helm install stable/mongodb --generate-name
NAME: mongodb-1577466908
LAST DEPLOYED: Fri Dec 25 11:15:11 2019
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **
MongoDB can be accessed via port 27017 on the following DNS name from within your cluster:
mongodb-1577466908.default.svc.cluster.local
To get the root password run:
export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace default mongodb-1577466908 -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)
To connect to your database run the following command:
kubectl run --namespace default mongodb-1577466908-client --rm --tty -i --restart='Never' --image bitnami/mongodb --command -- mongo admin --host mongodb-1577466908 --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD
To connect to your database from outside the cluster execute the following commands:
kubectl port-forward --namespace default svc/mongodb-1577466908 27017:27017 &
mongo --host 127.0.0.1 --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORD
ΠΏΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅:
kubectl run --namespace default mongodb-1577466908-client --rm --tty -i --restart='Never' --image bitnami/mongodb --command -- mongo admin --host mongodb-1577466908 --authenticationDatabase admin -u root -p $(kubectl get secret --namespace default mongodb-1577466908 -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)
If you don't see a command prompt, try pressing enter.
> db.version();
4.0.14
ΠΠ°ΡΠΈΡΠ½Π΅ΡΠ΅ ctrl+D, Π·Π° Π΄Π° ΠΈΠ·Π»Π΅Π·Π΅ΡΠ΅ ΠΎΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°.
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° emacs
ΠΠΎ ΠΏΡΠΈΠ½ΡΠΈΠΏ Π²ΡΠΈΡΠΊΠΎ Π²Π΅ΡΠ΅ Π±Π΅ΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠ°Π½ΠΎ ΡΠΏΠΎΡΠ΅Π΄
Π Π°Π·Π±ΠΈΠ²Π°Π½Π΅ Π½Π° ΠΈΠ³ΡΠ°ΡΠ° Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ
ΠΠ·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ΡΠΎ Ρ ΡΡΠ½ΠΊΡΠΈΠΈΡΠ΅ ΡΠ΅ ΠΎΡΡΡΠ΅ΡΡΠ²ΡΠ²Π° ΡΡΠ΅Π· http ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°, ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ²Π°Π½Π΅ΡΠΎ ΠΎΡ ΠΊΡΠ°ΠΉ Π΄ΠΎ ΠΊΡΠ°ΠΉ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΠ΅ ΠΎΡΠΈΠ³ΡΡΡΠ²Π° ΠΎΡ JWT. Mongodb ΡΠ΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π·Π° ΡΡΡ ΡΠ°Π½ΡΠ²Π°Π½Π΅ Π½Π° ΡΠΎΠΊΠ΅Π½ΠΈ, ΠΊΠ°ΠΊΡΠΎ ΠΈ ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ Π½Π° ΠΈΠ³ΡΠ°ΡΠ°, Π΄Π°Π½Π½ΠΈ Π·Π° ΠΈΠ³ΡΠ°ΡΠΈ, ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎΡΡΠΈ ΠΎΡ Ρ ΠΎΠ΄ΠΎΠ²Π΅ Π½Π° Π²ΡΠΈΡΠΊΠΈ ΠΈΠ³ΡΠΈ ΠΈ Π΄ΡΡΠ³Π° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ. ΠΠ΅ΠΊΠ° ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎ-ΠΎΡΠ±Π»ΠΈΠ·ΠΎ Π½Π°ΠΉ-ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ.
ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ
ΠΡ ΠΎΠ΄ΡΡ Π½Π° ΡΠ°Π·ΠΈ ΡΡΠ½ΠΊΡΠΈΡ Π΅ JSON Ρ ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌΠ° ΠΈ ΠΏΠ°ΡΠΎΠ»Π°ΡΠ° Π½Π° ΠΈΠ³ΡΠ°ΡΠ°. ΠΠΎΠ³Π°ΡΠΎ ΡΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ° ΡΠ°Π·ΠΈ ΡΡΠ½ΠΊΡΠΈΡ, ΡΠ΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π° Π΄Π°Π»ΠΈ ΡΠΎΠ·ΠΈ ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌ Π½Π΅ Π΅ Π² Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ; Π°ΠΊΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°ΡΠ° Π΅ ΡΡΠΏΠ΅ΡΠ½Π°, ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌΡΡ ΠΈ Ρ Π΅ΡΡΡ Π½Π° ΠΏΠ°ΡΠΎΠ»Π°ΡΠ° ΡΠ΅ Π²ΠΌΡΠΊΠ²Π°Ρ Π² Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ. ΠΠ° Π°ΠΊΡΠΈΠ²Π½ΠΎ ΡΡΠ°ΡΡΠΈΠ΅ Π² ΠΈΠ³ΡΠ°ΡΠ° Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ° ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ.
ΠΡ ΠΎΠ΄
ΠΡ ΠΎΠ΄ΡΡ Π½Π° ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π΅ JSON Ρ ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌ ΠΈ ΠΏΠ°ΡΠΎΠ»Π° Π·Π° ΠΈΠ³ΡΠ°; Π°ΠΊΠΎ ΠΈΠΌΠ° ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌ Π² Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ ΠΈ ΠΏΠ°ΡΠΎΠ»Π°ΡΠ° Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΏΠΎΡΠ²ΡΡΠ΄Π΅Π½Π° Ρ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»Π½ΠΎ Π·Π°ΠΏΠ°Π·Π΅Π½Π°ΡΠ° Π² Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ, ΡΠ΅ Π²ΡΡΡΠ° JWT, ΠΊΠΎΠΉΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΠ΅Π΄Π°Π΄Π΅Π½ Π½Π° Π΄ΡΡΠ³ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΊΠΎΠ³Π°ΡΠΎ ΡΠ° ΠΠ°ΡΠ΅ΡΠ΅Π½. Π Π°Π·Π»ΠΈΡΠ½ΠΈ ΡΠ»ΡΠΆΠ΅Π±Π½ΠΈ Π·Π°ΠΏΠΈΡΠΈ ΡΡΡΠΎ ΡΠ΅ Π²ΠΌΡΠΊΠ²Π°Ρ Π² Π±Π°Π·Π°ΡΠ° Π΄Π°Π½Π½ΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π²ΡΠ΅ΠΌΠ΅ Π·Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΎ Π²Π»ΠΈΠ·Π°Π½Π΅ ΠΈ Π΄Ρ.
ΠΠΈΠΆΡΠ΅ ΡΠΏΠΈΡΡΠΊ Ρ ΠΈΠ³ΡΠΈ
ΠΡΠ΅ΠΊΠΈ Π½Π΅ΠΎΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΠΈΡΠΊΠ° ΡΠΏΠΈΡΡΠΊ Ρ Π²ΡΠΈΡΠΊΠΈ ΠΈΠ³ΡΠΈ, Ρ ΠΈΠ·ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π½Π° Π°ΠΊΡΠΈΠ²Π½ΠΈΡΠ΅. ΠΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ΠΈΡΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» ΡΡΡΠΎ Π²ΠΈΠΆΠ΄Π° ΡΠΏΠΈΡΡΠΊ Ρ Π°ΠΊΡΠΈΠ²Π½ΠΈ ΠΈΠ³ΡΠΈ. Π Π΅Π·ΡΠ»ΡΠ°ΡΡΡ ΠΎΡ ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π΅ JSON, ΡΡΠ΄ΡΡΠΆΠ°Ρ ΡΠΏΠΈΡΡΡΠΈ Ρ ΠΈΠ³ΡΠΈ (ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° ΠΈΠ³ΡΠ°, ΡΠ΅ΡΠΈΠΌΠΎ Π·Π° ΡΠΎΠ²Π΅ΠΊΠ° ΠΈΠΌΠ΅ ΠΈ Ρ.Π½.).
Π‘ΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° ΠΈΠ³ΡΠ°
Π€ΡΠ½ΠΊΡΠΈΡΡΠ° ΡΠ°Π±ΠΎΡΠΈ ΡΠ°ΠΌΠΎ Ρ ΠΎΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ; Π½Π° Π²Ρ ΠΎΠ΄Π° ΡΠ΅ ΠΏΡΠΈΠ΅ΠΌΠ° ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π΅Π½ Π±ΡΠΎΠΉ ΠΈΠ³ΡΠ°ΡΠΈ, ΠΊΠ°ΠΊΡΠΎ ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π½Π° ΠΈΠ³ΡΠ°ΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠΈ Π³Π΅ΡΠΎΠΈ Π΄Π° ΡΠ΅ Π°ΠΊΡΠΈΠ²ΠΈΡΠ°Ρ Π² ΡΠ°Π·ΠΈ ΠΈΠ³ΡΠ°, ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π΅Π½ Π±ΡΠΎΠΉ ΠΈΠ³ΡΠ°ΡΠΈ ΠΈ Ρ.Π½.). ΠΡΠ΄Π΅Π»Π΅Π½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π½Π° ΠΈΠ³ΡΠ°ΡΠ° Π΅ Π½Π°Π»ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° ΠΏΠ°ΡΠΎΠ»Π° Π·Π° ΠΏΡΠΈΡΡΠ΅Π΄ΠΈΠ½ΡΠ²Π°Π½Π΅, ΠΊΠΎΡΡΠΎ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΡΡΠ·Π΄Π°Π²Π°ΡΠ΅ Π½Π΅ΠΏΡΠ±Π»ΠΈΡΠ½ΠΈ ΠΈΠ³ΡΠΈ. ΠΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΡΠ΅ ΡΡΠ·Π΄Π°Π²Π° ΠΏΡΠ±Π»ΠΈΡΠ½Π° ΠΈΠ³ΡΠ°. Π Π΅Π·ΡΠ»ΡΠ°ΡΡΡ ΠΎΡ ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π΅ JSON, ΠΊΠΎΠΉΡΠΎ ΡΡΠ΄ΡΡΠΆΠ° ΠΏΠΎΠ»Π΅ Π·Π° ΡΡΠΏΠ΅ΡΠ½ΠΎ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅, ΡΠ½ΠΈΠΊΠ°Π»Π΅Π½ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π° ΠΈΠ³ΡΠ°ΡΠ° ΠΈ Π΄ΡΡΠ³ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ.
ΠΡΠΈΡΡΠ΅Π΄ΠΈΠ½ΡΠ²Π°Π½Π΅ ΠΊΡΠΌ ΠΈΠ³ΡΠ°
Π€ΡΠ½ΠΊΡΠΈΡΡΠ° ΡΠ°Π±ΠΎΡΠΈ ΡΠ°ΠΌΠΎ Ρ ΠΎΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΠΈ, Π²Ρ ΠΎΠ΄ΡΡ Π΅ ID Π½Π° ΠΈΠ³ΡΠ°ΡΠ° ΠΈ Π½Π΅ΠΉΠ½Π°ΡΠ° ΠΏΠ°ΡΠΎΠ»Π°, Π°ΠΊΠΎ ΡΠΎΠ²Π° Π΅ Π½Π΅ΠΏΡΠ±Π»ΠΈΡΠ½Π° ΠΈΠ³ΡΠ°, ΠΈΠ·Ρ ΠΎΠ΄ΡΡ Π΅ JSON Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΡΠ΅ Π½Π° ΠΈΠ³ΡΠ°ΡΠ°. Π£ΠΏΡΠ»Π½ΠΎΠΌΠΎΡΠ΅Π½ΠΈΡΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π», Π²ΠΊΠ»ΡΡΠΈΠ» ΡΠ΅ Π² ΠΈΠ³ΡΠ°ΡΠ°, ΠΊΠ°ΠΊΡΠΎ ΠΈ ΡΡΠ·Π΄Π°ΡΠ΅Π»ΡΡ Π½Π° ΠΈΠ³ΡΠ°ΡΠ°, ΡΠ΅ Π½Π°ΡΠΈΡΠ°Ρ ββΠΏΠΎ-Π½Π°ΡΠ°ΡΡΠΊ ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ Π² ΠΈΠ³ΡΠ°ΡΠ°.
ΠΡΠ΅Π³Π»Π΅Π΄ Π½Π° ΡΡΠ±ΠΈΡΠΈΡ Π² ΠΈΠ³ΡΠ°ΡΠ°
ΠΡΠ΅ΠΊΠΈ Π½Π΅ΠΎΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΠΈΡΠΊΠ° ΡΠΏΠΈΡΡΠΊ ΡΡΡ ΡΡΠ±ΠΈΡΠΈΡ Π·Π° Π½Π΅Π°ΠΊΡΠΈΠ²Π½ΠΈ ΠΈΠ³ΡΠΈ, Π° ΡΠΏΡΠ»Π½ΠΎΠΌΠΎΡΠ΅Π½ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈ ΡΠΏΠΈΡΡΠΊ ΡΡΡ ΡΡΠ±ΠΈΡΠΈΡ Π·Π° Π²ΡΡΠΊΠ° Π°ΠΊΡΠΈΠ²Π½Π° ΠΈΠ³ΡΠ°. ΠΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π΅Π½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊΡΠΌ ΡΡΠ½ΠΊΡΠΈΡΡΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ Π½ΠΎΠΌΠ΅ΡΡΡ Π½Π° ΡΡΠ±ΠΈΡΠΈΠ΅ΡΠΎ, ΠΊΠΎΠΉΡΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ Π²Π΅ΡΠ΅ ΠΈΠΌΠ°. Π ΡΠΎΠ·ΠΈ ΡΠ»ΡΡΠ°ΠΉ ΡΠ°ΠΌΠΎ ΠΎΠ½Π΅Π·ΠΈ ΡΡΠ±ΠΈΡΠΈΡ, ΠΊΠΎΠΈΡΠΎ ΡΠ° Π½Π°ΡΡΡΠΏΠΈΠ»ΠΈ ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ, ΡΠ΅ Π±ΡΠ΄Π°Ρ Π²ΡΡΠ½Π°ΡΠΈ Π² ΡΠΏΠΈΡΡΠΊΠ°. Π§ΡΠ΅Π· ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ½ΠΎΡΠΎ ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ°Π·ΠΈ ΡΡΠ½ΠΊΡΠΈΡ, ΠΎΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π» Π½Π°Π±Π»ΡΠ΄Π°Π²Π° ΠΊΠ°ΠΊΠ²ΠΎ ΡΠ΅ ΡΠ»ΡΡΠ²Π° Π² ΠΈΠ³ΡΠ°ΡΠ°. Π’Π°Π·ΠΈ ΡΡΠ½ΠΊΡΠΈΡ ΡΡΡΠΎ Π²ΡΡΡΠ° ΠΈΡΠΊΠ°Π½Π΅ Π·Π° Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, Π½Π° ΠΊΠΎΠ΅ΡΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΡΠ³ΠΎΠ²ΠΎΡΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π·Π° ΠΈΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΡΡΠ±ΠΈΡΠΈΡ Π½Π° ΠΈΠ³ΡΠ°ΡΠ°.
ΠΠ·ΠΏΡΠ°ΡΠ°Π½Π΅ Π½Π° ΡΡΠ±ΠΈΡΠΈΠ΅ Π·Π° ΠΈΠ³ΡΠ°
Π€ΡΠ½ΠΊΡΠΈΡΡΠ° ΡΠ°Π±ΠΎΡΠΈ ΡΠ°ΠΌΠΎ Π·Π° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ Π² ΠΈΠ³ΡΠ°ΡΠ°: Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΅ Π΄Π° ΡΡΠ°ΡΡΠΈΡΠ°ΡΠ΅ ΠΈΠ³ΡΠ°ΡΠ°, Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΡΠ΅ Ρ
ΠΎΠ΄, Π΄Π° Π³Π»Π°ΡΡΠ²Π°ΡΠ΅, Π΄Π° Π½Π°ΠΏΠΈΡΠ΅ΡΠ΅ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅ΡΠΎ ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π²Π° Π² ΡΠΏΠΈΡΡΠΊΠ° ΡΡΡ ΡΡΠ±ΠΈΡΠΈΡ Π² ΠΈΠ³ΡΠ°ΡΠ° ΠΈ Ρ.Π½.
ΠΡΠΎΡΠΈΠ·ΠΈΡΠ°Π½ΠΈΡΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π», ΠΊΠΎΠΉΡΠΎ Π΅ ΡΡΠ·Π΄Π°Π» ΠΈΠ³ΡΠ°ΡΠ°, Π·Π°ΠΏΠΎΡΠ²Π° Π΄Π° ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Ρ ΡΠΎΠ»ΠΈ Π½Π° Π²ΡΠΈΡΠΊΠΈ ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ Π² ΠΈΠ³ΡΠ°ΡΠ°, Π²ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ ΡΠ΅Π±Π΅ ΡΠΈ, ΡΠ΅ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΠΎΡΠ²ΡΡΠ΄ΡΡ ΡΠΎΠ»ΡΡΠ° ΡΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΡΡΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ. Π‘Π»Π΅Π΄ ΠΊΠ°ΡΠΎ Π²ΡΠΈΡΠΊΠΈ ΡΠΎΠ»ΠΈ ΡΠ° ΠΏΠΎΡΠ²ΡΡΠ΄Π΅Π½ΠΈ, ΠΈΠ³ΡΠ°ΡΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΠΏΡΠ΅Π²ΠΊΠ»ΡΡΠ²Π° Π½Π° Π½ΠΎΡΠ΅Π½ ΡΠ΅ΠΆΠΈΠΌ.
Π‘ΡΠ°ΡΠΈΡΡΠΈΠΊΠ° Π½Π° ΠΈΠ³ΡΠ°ΡΠ°
Π€ΡΠ½ΠΊΡΠΈΡΡΠ° ΡΠ°Π±ΠΎΡΠΈ ΡΠ°ΠΌΠΎ Π·Π° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈ Π² ΠΈΠ³ΡΠ°ΡΠ°, ΠΏΠΎΠΊΠ°Π·Π²Π° ΡΡΡΡΠΎΡΠ½ΠΈΠ΅ΡΠΎ Π½Π° ΠΈΠ³ΡΠ°ΡΠ°, ΡΠΏΠΈΡΡΠΊΠ° ΠΈ Π±ΡΠΎΡ Π½Π° ΠΈΠ³ΡΠ°ΡΠΈΡΠ΅ (Π½ΠΈΠΊΠ½Π΅ΠΉΠΌΠΈ), ΡΠΎΠ»ΠΈΡΠ΅ ΠΈ ΡΠ΅Ρ Π½ΠΈΡ ΡΡΠ°ΡΡΡ (Π½Π°ΠΏΡΠ°Π²Π΅Π½ Ρ ΠΎΠ΄ ΠΈΠ»ΠΈ Π½Π΅), ΠΊΠ°ΠΊΡΠΎ ΠΈ Π΄ΡΡΠ³Π° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ. ΠΠ°ΠΊΡΠΎ ΠΏΡΠΈ ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ, Π²ΡΠΈΡΠΊΠΎ ΡΠ°Π±ΠΎΡΠΈ ΡΠ°ΠΌΠΎ Π·Π° ΡΡΠ°ΡΡΠ½ΠΈΡΠΈΡΠ΅ Π² ΠΈΠ³ΡΠ°ΡΠ°.
ΠΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ½ΠΎ ΡΡΠ°ΡΡΠΈΡΠ°Π½ΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ
ΠΠΊΠΎ ΠΈΠ³ΡΠ°ΡΠ° Π½Π΅ Π΅ Π±ΠΈΠ»Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π° ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅, ΠΏΠΎΡΠΎΡΠ΅Π½ΠΎ ΠΏΡΠΈ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΈΠ³ΡΠ°ΡΠ°, ΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ½ΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ ΠΏΡΠ΅ΠΌΠ°Ρ Π½Π°ΡΠ° ΠΎΡ ΡΠΏΠΈΡΡΠΊΠ° Ρ Π°ΠΊΡΠΈΠ²Π½ΠΈ ΠΈΠ³ΡΠΈ ΡΡΠ΅Π· ΡΡΠ½ΠΊΡΠΈΡΡΠ° Π·Π° ΠΈΠ·ΡΠΈΡΡΠ²Π°Π½Π΅.
ΠΡΡΠ³Π° ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ½Π° Π·Π°Π΄Π°ΡΠ° Π΅ ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»Π½ΠΎΡΠΎ ΠΏΡΠ΅Π²ΠΊΠ»ΡΡΠ²Π°Π½Π΅ Π½Π° ΡΠ΅ΠΆΠΈΠΌΠ° Π½Π° ΠΈΠ³ΡΠ° ΠΎΡ Π½ΠΎΡΠ΅Π½ ΠΊΡΠΌ Π΄Π½Π΅Π²Π΅Π½ ΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π·Π° ΠΈΠ³ΡΠΈ, Π·Π° ΠΊΠΎΠΈΡΠΎ ΡΠΎΠ²Π° Π½Π΅ ΡΠ΅ Π΅ ΡΠ»ΡΡΠΈΠ»ΠΎ ΠΏΠΎ Π²ΡΠ΅ΠΌΠ΅ Π½Π° Ρ ΠΎΠ΄Π° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΠ³ΡΠ°Ρ, ΠΊΠΎΠΉΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΡΠ΅Π°Π³ΠΈΡΠ° Π½Π° ΠΈΠ³ΡΠΎΠ²ΠΎ ΡΡΠ±ΠΈΡΠΈΠ΅, Π½Π΅ Π΅ ΠΈΠ·ΠΏΡΠ°ΡΠΈΠ» ΡΠ²ΠΎΠ΅ΡΠΎ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ Π½ΡΠΊΠ°ΠΊΠ²Π° ΠΏΡΠΈΡΠΈΠ½Π° ).
Π‘ΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅
Π²ΡΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ - ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΡΡΠ΅Π΄Π°ΡΠ° Π·Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°, ΡΠ°Π·Π±ΠΈΠ²Π°Π½Π΅ Π½Π° Π·Π°Π΄Π°ΡΠ°ΡΠ° Π½Π° ΡΡΠ½ΠΊΡΠΈΠΈ
- ΠΠ΅ΠΊΠ΅Π½Π΄ ΡΠ°Π±ΠΎΡΠ°
- Frontend ΡΠ°Π±ΠΎΡΠ°
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° CICD, ΠΎΡΠ³Π°Π½ΠΈΠ·ΠΈΡΠ°Π½Π΅ Π½Π° ΡΠ΅ΡΡΠ²Π°Π½Π΅
- ΠΠ°ΠΏΠΎΡΠ½Π΅ΡΠ΅ ΠΏΡΠΎΠ±Π½Π° ΠΈΠ³ΡΠΎΠ²Π° ΡΠ΅ΡΠΈΡ
- Π Π΅Π·ΡΠ»ΡΠ°ΡΠΈ ΠΎΡ
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com