
Jis dènyèman, yon konpayi byen li te ye te anonse ke li te transfere liy li nan laptops nan achitekti ARM. Lè m 'tande nouvèl sa a, mwen sonje: pandan yon lòt fwa ankò gade nan pri yo pou EC2 nan AWS, mwen remake Gravitons ak yon pri trè bon gou. Trape an, nan kou, te ke li te ARM. Lè sa a, li pa janm rive m 'ke ARM se byen grav ...
Pou mwen, achitekti sa a te toujou domèn mobil ak lòt bagay IoT. Sèvè "reyèl" sou ARM yo se yon jan kanmenm etranj, nan kèk fason menm sovaj ... Sepandan, yon nouvo panse kole nan tèt mwen, se konsa yon wikenn mwen deside tcheke sa ki ta ka kouri sou ARM jodi a. Se pou sa mwen deside kòmanse ak yon bagay tou pre ak mwen renmen anpil - gwoup la Kubernetes. Epi se pa sèlman kèk kalite konvansyonèl "gwoup", men tout bagay "nan yon fason granmoun", pou ke li se otank posib menm jan mwen abitye wè li nan pwodiksyon an.
Dapre lide mwen, gwoup la ta dwe aksesib nan Entènèt la, kèk aplikasyon entènèt ta dwe kouri nan li, epi ta dwe gen omwen siveyans. Pou aplike lide sa a, w ap bezwen yon pè (oswa plis) nan Franbwaz Pi omwen modèl 3B +. AWS te kapab vin tounen yon platfòm pou eksperyans, men mwen te enterese nan "franbwazye yo" (ki te toujou kanpe san fè anyen konsa). Se konsa, nou pral deplwaye yon gwoup Kubernetes ak Ingress, Prometheus ak Grafana sou yo.
Prepare "franbwazye"
Enstale OS ak SSH
Mwen pa t deranje twòp ak chwazi yon OS pou enstale: mwen jis pran dènye Raspberry Pi OS Lite ak . Disponib la , tout aksyon ki soti nan ki dwe fèt sou tout nœuds nan gwoup la nan lavni. Apre sa, w ap bezwen fè manipilasyon sa yo (tou sou tout nœuds).
Apre konekte monitè a ak klavye, ou dwe premye konfigirasyon rezo a ak SSH:
- Pou gwoup la fonksyone, mèt la dwe gen yon adrès IP estatik, ak nœuds travayè yo dwe gen yon adrès IP estatik. Mwen pi pito adrès estatik nan tout pou fasilite nan konfigirasyon.
- Ka adrès estatik la dwe configuré nan eksplwatasyon an (nan fichye a
/etc/dhcpcd.confgen yon egzanp apwopriye) oswa pa fikse yon kontra-lwaye nan sèvè a DHCP nan itilize a (nan ka mwen an, lakay ou) routeur. - ssh-server tou senpleman enkli nan raspi-config (opsyon entèfas → ssh).
Apre sa, ou ka konekte via SSH (konekte default la se pi, ak modpas la se raspberry oswa youn nan ou chanje a) epi kontinye ak anviwònman yo.
Lòt paramèt
- Ann mete non host la. Nan egzanp mwen an yo pral itilize
pi-controlиpi-worker. - Ann tcheke si sistèm fichye a pwolonje pou kouvri tout disk la (
df -h /). Si sa nesesè, li ka elaji lè l sèvi avèk raspi-config. - Ann chanje modpas itilizatè default la nan raspi-config.
- Ann fèmen fichye swap la (sa a se yon kondisyon pou Kubernetes; si w enterese nan detay sou sijè sa a, gade ):
dphys-swapfile swapoff systemctl disable dphys-swapfile - Ann mete ajou pakè yo nan dènye vèsyon yo:
apt-get update && apt-get dist-upgrade -y - Ann enstale Docker ak pakè adisyonèl:
apt-get install -y docker docker.io apt-transport-https curl bridge-utils iptables-persistentLè w ap enstale
iptables-persistentw ap bezwen sove paramèt iptables yo pou ipv4, ak nan fichye a/etc/iptables/rules.v4- ajoute règ nan chèn lanFORWARD, tankou sa a:# Generated by xtables-save v1.8.2 on Sun Jul 19 00:27:43 2020 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A FORWARD -s 10.1.0.0/16 -j ACCEPT -A FORWARD -d 10.1.0.0/16 -j ACCEPT COMMIT - Tout sa ki rete se rdemare.
Koulye a, ou pare pou enstale gwoup Kubernetes ou a.
Enstale Kubernetes
Nan etap sa a, mwen fè espre mete sou kote tout devlopman antrepriz mwen yo ak nou yo pou otomatize enstalasyon ak konfigirasyon gwoup K8s la. Olye de sa, se pou yo sèvi ak dokiman ofisyèl la ak (yon ti kras konplete ak kòmantè ak abrevyasyon).
Ann ajoute depo Kubernetes la:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get updatePli lwen nan dokiman an li sijere enstale CRI (koòdone ègzekutabl veso). Depi Docker deja enstale, ann kontinye epi enstale eleman prensipal yo:
sudo apt-get install -y kubelet kubeadm kubectl kubernetes-cni Nan etap la nan enstale eleman prensipal yo, mwen imedyatman te ajoute kubernetes-cni, ki nesesè pou gwoup la fonksyone. Ak isit la gen yon pwen enpòtan: pake a kubernetes-cni pou kèk rezon li pa kreye yon anyè default pou anviwònman koòdone CNI, kidonk mwen te oblije kreye li manyèlman:
mkdir -p /etc/cni/net.dPou backend rezo a travay, ki pral diskite anba a, ou bezwen enstale Plugin la pou CNI. Mwen te chwazi plugin portmap ki abitye ak konprann pou mwen (pou yon lis konplè, gade ):
curl -sL https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-arm-v0.7.5.tgz | tar zxvf - -C /opt/cni/bin/ ./portmapKonfigirasyon Kubernetes
Ne ak avyon kontwòl
Enstale gwoup la tèt li se byen senp. Ak akselere pwosesis sa a ak verifye ke imaj yo Kubernetes yo disponib, ou ka premye kouri:
kubeadm config images pullKoulye a, nou fè enstalasyon an tèt li - inisyalize plan kontwòl gwoup la:
kubeadm init --pod-network-cidr=10.1.0.0/16 --service-cidr=10.2.0.0/16 --upload-certsTanpri sonje ke sous-rezo pou sèvis ak gous pa ta dwe sipèpoze youn ak lòt oswa ak rezo ki egziste deja.
Nan fen a, yo pral montre nou yon mesaj ke tout bagay anfòm, epi an menm tan an yo pral di nou ki jan yo tache nœuds travayè yo nan avyon kontwòl la:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of the control-plane node running the following command on each as root:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4
--discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050
--contrl-plane --certificate-key 72a3c0a14c627d6d7fdade1f4c8d7a41b0fac31b1faf0d8fdf9678d74d7d2403
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4
--discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050Ann swiv rekòmandasyon yo pou ajoute yon konfigirasyon pou itilizatè a. An menm tan an, mwen rekòmande imedyatman ajoute autocompletion pou kubectl:
kubectl completion bash > ~/.kube/completion.bash.inc
printf "
# Kubectl shell completion
source '$HOME/.kube/completion.bash.inc'
" >> $HOME/.bash_profile
source $HOME/.bash_profileNan etap sa a, ou ka deja wè premye ne nan gwoup la (byenke li poko pare):
root@pi-control:~# kubectl get no
NAME STATUS ROLES AGE VERSION
pi-control NotReady master 29s v1.18.6Konfigirasyon rezo a
Apre sa, jan sa di nan mesaj la apre enstalasyon, w ap bezwen enstale rezo a nan gwoup la. Dokimantasyon an ofri yon chwa nan Calico, Cilium, contiv-vpp, Kube-routeur ak Weave Net... Isit la mwen devye de enstriksyon ofisyèl yo epi chwazi yon opsyon ki pi abitye ak konprann pou mwen: nan mòd host-gw (pou plis enfòmasyon sou backend ki disponib, gade ).
Enstale li nan yon gwoup se byen senp. Premyèman, telechaje manifest yo:
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml Lè sa a, chanje kalite a ak nan anviwònman yo vxlan sou host-gw:
sed -i 's/vxlan/host-gw/' kube-flannel.yml... ak sous-rezo gous yo - soti nan valè default la rive nan youn ki espesifye pandan inisyalizasyon gwoup la:
sed -i 's#10.244.0.0/16#10.1.0.0/16#' kube-flannel.ymlApre sa, nou kreye resous:
kubectl create -f kube-flannel.yml Pare! Apre kèk tan, premye ne K8s la pral chanje nan estati a Ready:
NAME STATUS ROLES AGE VERSION
pi-control Ready master 2m v1.18.6Ajoute yon Ne travayè
Koulye a, ou ka ajoute yon travayè. Pou fè sa sou li - apre enstale Kubernetes tèt li dapre senaryo ki dekri pi wo a - ou jis bezwen kouri lòd la te deja resevwa:
kubeadm join 192.168.88.30:6443 --token a485vl.xjgvzzr2g0xbtbs4
--discovery-token-ca-cert-hash sha256:9da6b05aaa5364a9ec59adcc67b3988b9c1b94c15e81300560220acb1779b050Nan pwen sa a nou ka asime ke gwoup la pare:
root@pi-control:~# kubectl get no
NAME STATUS ROLES AGE VERSION
pi-control Ready master 28m v1.18.6
pi-worker Ready <none> 2m8s v1.18.6Mwen sèlman te gen de Franbwaz Pis nan men, se konsa bay lwen youn nan yo sèlman Mwen pa t 'vle li anba avyon an kontwòl. Se konsa, mwen retire tach la otomatikman enstale nan ne pi-kontwòl nan kouri:
root@pi-control:~# kubectl edit node pi-control... ak retire liy yo:
- effect: NoSchedule
key: node-role.kubernetes.io/masterRanpli gwoup la ak minimòm ki nesesè yo
Premyerman nou bezwen Helm. Natirèlman, ou ka fè tout bagay san li, men Helm pèmèt ou literalman Customize kèk eleman nan diskresyon ou san yo pa koreksyon dosye. Epi an reyalite, li se jis yon dosye binè ki "pa mande pou pen."
Se konsa, ann ale nan nan seksyon dokiman/enstalasyon an epi egzekite kòmandman an soti nan la:
curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bashApre sa, ajoute repozitwa tablo yo:
helm repo add stable https://kubernetes-charts.storage.googleapis.com/Koulye a, ann enstale eleman enfrastrikti yo jan li te planifye:
- Kontwolè Ingress;
- Prometheus;
- Grafana;
- cert-manadjè.
Kontwolè Ingress
Premye eleman se Kontwolè Ingress - Enstalasyon se byen senp epi pare pou itilize soti nan bwat la. Pou fè sa, jis ale nan epi kouri lòd la enstale soti nan la:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/baremetal/deploy.yamlSepandan, nan moman sa a "franbwaz la" te kòmanse souch ak kouri nan IOPS ki gen kapasite. Reyalite a se ke ansanm ak kontwolè Ingress la, yon gwo kantite resous yo enstale, anpil demann nan API a yo fè epi, kòmsadwa, yon anpil nan done yo ekri nan elatriye. An jeneral, swa yon kat memwa klas 10 pa trè pwodiktif, oswa yon kat SD se fondamantalman pa ase pou yon chaj konsa. Sepandan, apre apeprè 5 minit tout bagay te kòmanse.
Yo te kreye yon espas non ak yon kontwolè ak tout sa li te bezwen parèt ladan l:
root@pi-control:~# kubectl -n ingress-nginx get pod
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-2hwdx 0/1 Completed 0 31s
ingress-nginx-admission-patch-cp55c 0/1 Completed 0 31s
ingress-nginx-controller-7fd7d8df56-68qp5 1/1 Running 0 48sPrometheus
De pwochen konpozan yo byen fasil pou enstale atravè Helm nan repo tablo a.
Jwenn Prometheus, kreye yon espas non epi mete l sou:
helm search repo stable | grep prometheus
kubectl create ns monitoring
helm install prometheus --namespace monitoring stable/prometheus --set server.ingress.enabled=True --set server.ingress.hosts={"prometheus.home.pi"}Pa default, Prometheus kòmande 2 disk: pou done Prometheus tèt li ak pou done AlertManager. Depi yon klas depo pa te kreye nan gwoup la, disk yo pa pral kòmande epi gous pa pral kòmanse. Pou enstalasyon Kubernetes metal fè, anjeneral nou itilize Ceph rbd, men nan ka Franbwaz Pi a sa a se klèman twòp.
Se poutèt sa, an n kreye yon senp depo lokal sou hostpath la. PV (volim pèsistan) manifeste pou prometheus-server ak prometheus-alertmanager yo konbine nan yon dosye. prometheus-pv.yaml в . Anyè a pou PV obligatwa nan davans kreye sou disk la nan ne nan ki nou vle mare Prometheus: nan egzanp lan li ekri nodeAffinity pa non host pi-worker ak repèrtwar yo kreye sou li /data/localstorage/prometheus-server и /data/localstorage/prometheus-alertmanager.
Telechaje (klonaj) manifest la epi ajoute li nan Kubernetes:
kubectl create -f prometheus-pv.yamlNan etap sa a, mwen te rankontre premye pwoblèm achitekti ARM. Kube-state-metrics, ki enstale pa default nan tablo Prometheus la, te refize kòmanse. Li te bay yon erè:
root@pi-control:~# kubectl -n monitoring logs prometheus-kube-state-metrics-c65b87574-l66d8
standard_init_linux.go:207: exec user process caused "exec format error"Reyalite a se ke kube-state-metrics sèvi ak yon imaj nan pwojè a CoreOS, ki pa konpile pou ARM:
kubectl -n monitoring get deployments.apps prometheus-kube-state-metrics -o=jsonpath={.spec.template.spec.containers[].image}
quay.io/coreos/kube-state-metrics:v1.9.7Mwen te oblije fè yon ti kras google epi jwenn, pou egzanp, . Pou itilize li, ann mete ajou lage a pou endike ki imaj pou itilize pou kube-state-metrics:
helm upgrade prometheus --namespace monitoring stable/prometheus --set server.ingress.enabled=True --set server.ingress.hosts={"prometheus.home.pi"} --set kube-state-metrics.image.repository=carlosedp/kube-state-metrics --set kube-state-metrics.image.tag=v1.9.6Ann tcheke si tout bagay te kòmanse:
root@pi-control:~# kubectl -n monitoring get po
NAME READY STATUS RESTARTS AGE
prometheus-alertmanager-df65d99d4-6d27g 2/2 Running 0 5m56s
prometheus-kube-state-metrics-5dc5fd89c6-ztmqr 1/1 Running 0 5m56s
prometheus-node-exporter-49zll 1/1 Running 0 5m51s
prometheus-node-exporter-vwl44 1/1 Running 0 4m20s
prometheus-pushgateway-c547cfc87-k28qx 1/1 Running 0 5m56s
prometheus-server-85666fd794-z9qnc 2/2 Running 0 4m52sGrafana ak cert-manadjè
Pou tablo ak tablodbò nou mete grafana:
helm install grafana --namespace monitoring stable/grafana --set ingress.enabled=true --set ingress.hosts={"grafana.home.pi"}Nan fen pwodiksyon an, nou pral montre kijan pou jwenn modpas aksè a:
kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echoPou kòmande sètifika nou pral enstale sèt-manadjè. Pou enstale li, tanpri al gade , ki ofri kòmandman korespondan yo pou Helm:
helm repo add jetstack https://charts.jetstack.io
helm install
cert-manager jetstack/cert-manager
--namespace cert-manager
--version v0.16.0
--set installCRDs=truePou sètifika oto-siyen pou itilize lakay, sa a se byen ase. Si ou bezwen jwenn menm bagay la Se pou yo ankripte, Lè sa a, ou bezwen tou konfigirasyon emeteur cluster. Ou ka jwenn detay sou sa nan atik nou an "'.
Mwen menm mwen te etabli sou opsyon ki soti nan , deside ke opsyon nan etap nan LE ta ase. Nou chanje imèl la nan egzanp lan, sove li nan yon dosye epi ajoute li nan gwoup la ():
kubectl create -f cert-manager-cluster-issuer.yamlKoulye a, ou ka bay lòd pou yon sètifika, pou egzanp, pou Grafana. Sa a pral mande pou yon domèn ak aksè nan gwoup la soti deyò. Mwen gen yon domèn, epi mwen konfigirasyon trafik la pa voye pò 80 ak 443 sou routeur lakay mwen an akò ak sèvis ingress-controller kreye:
kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.2.206.61 <none> 80:31303/TCP,443:30498/TCP 23d80yèm pò a nan ka sa a se tradui nan 31303, ak 443 nan 30498. (Pò yo pwodwi owaza, kidonk pa w la pral diferan.)
Men yon egzanp sètifika ():
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: grafana
namespace: monitoring
spec:
dnsNames:
- grafana.home.pi
secretName: grafana-tls
issuerRef:
kind: ClusterIssuer
name: letsencrypt-stagingAjoute li nan gwoup la:
kubectl create -f cert-manager-grafana-certificate.yamlApre sa, resous Ingress la ap parèt, atravè ki validation Ann Cripte pral pran plas:
root@pi-control:~# kubectl -n monitoring get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
cm-acme-http-solver-rkf8l <none> grafana.home.pi 192.168.88.31 80 72s
grafana <none> grafana.home.pi 192.168.88.31 80 6d17h
prometheus-server <none> prometheus.home.pi 192.168.88.31 80 8d Apre validasyon an pase, nou pral wè ke resous la certificate pare, ak nan sekrè ki anwo a grafana-tls - sètifika ak kle. Ou ka tcheke imedyatman ki moun ki bay sètifika a:
root@pi-control:~# kubectl -n monitoring get certificate
NAME READY SECRET AGE
grafana True grafana-tls 13m
root@pi-control:~# kubectl -n monitoring get secrets grafana-tls -ojsonpath="{.data['tls.crt']}" | base64 -d | openssl x509 -issuer -noout
issuer=CN = Fake LE Intermediate X1Ann tounen nan Grafana. Nou pral bezwen ranje yon ti kras lage Helm li yo pa chanje anviwònman yo pou TLS matche ak sètifika pwodwi a.
Pou fè sa, telechaje tablo a, modifye ak mete ajou li nan anyè lokal la:
helm pull --untar stable/grafana Edit nan yon fichye grafana/values.yaml Paramèt TLS:
tls:
- secretName: grafana-tls
hosts:
- grafana.home.pi Isit la ou ka imedyatman konfigirasyon enstale Prometheus kòm datasource:
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus-server:80
access: proxy
isDefault: trueKoulye a, nou mete ajou tablo Grafana nan anyè lokal la:
helm upgrade grafana --namespace monitoring ./grafana --set ingress.enabled=true --set ingress.hosts={"grafana.home.pi"} Tcheke sa ki nan Ingress grafana Yo te ajoute pò 443 epi gen aksè atravè HTTPS:
root@pi-control:~# kubectl -n monitoring get ing grafana
NAME CLASS HOSTS ADDRESS PORTS AGE
grafana <none> grafana.home.pi 192.168.88.31 80, 443 63m
root@pi-control:~# curl -kI https://grafana.home.pi
HTTP/2 302
server: nginx/1.19.1
date: Tue, 28 Jul 2020 19:01:31 GMT
content-type: text/html; charset=utf-8
cache-control: no-cache
expires: -1
location: /login
pragma: no-cache
set-cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
x-frame-options: deny
strict-transport-security: max-age=15724800; includeSubDomainsPou demontre Grafana an aksyon, ou ka telechaje epi ajoute . Men sa li sanble:

Mwen rekòmande tou pou ajoute yon tablodbò pou ekspòtatè ne: li pral montre an detay sa k ap pase ak "franbwazye yo" (chaj CPU, memwa, rezo, itilizasyon disk, elatriye).
Apre sa mwen panse sa gwoup la pare pou aksepte epi kouri aplikasyon yo!
Remak sou asanble
Gen omwen de opsyon pou bati aplikasyon pou achitekti ARM. Premyèman, ou ka bati sou yon aparèy ARM. Sepandan, apre yo fin gade jete aktyèl la nan de Franbwaz Pis, mwen reyalize ke yo pa ta siviv asanble tou. Se poutèt sa, mwen te bay tèt mwen lòd yon nouvo Franbwaz Pi 4 (li gen plis pouvwa anpil e li gen otan ke 4 GB memwa) - Mwen planifye bati sou li.
Dezyèm opsyon an se bati yon imaj Docker milti-ark sou yon machin ki pi pwisan. Pou sa gen . Si aplikasyon an se nan yon lang konpile, Lè sa a, kwa-konpilasyon pou ARM yo pral obligatwa. Mwen pa pral dekri tout paramèt pou chemen sa a, paske... Sa a pral mande pou yon atik separe. Lè w aplike apwòch sa a, li posib pou reyalize imaj "inivèsèl": Docker kouri sou yon machin ARM pral otomatikman telechaje imaj ki koresponn ak achitekti a.
Konklizyon
Eksperyans lan depase tout atant mwen yo: [omwen] "vaniy" Kubernetes ak baz ki nesesè yo santi l byen sou ARM, epi sèlman yon koup nan nuans leve ak konfigirasyon li yo.
Franbwaz Pi 3B + yo kenbe chay la sou CPU a, men kat SD yo se yon bouche klè. Kòlèg yo sijere ke nan kèk vèsyon li posib bòt soti nan USB, kote ou ka konekte yon SSD: Lè sa a, gen plis chans sitiyasyon an ap vin pi bon.
Men yon egzanp chaj CPU lè w ap enstale Grafana:

Pou eksperyans ak "eseye li soti", nan opinyon mwen, yon gwoup Kubernetes sou "franbwazye" transmèt santi a nan operasyon pi bon pase menm Minikube a, paske tout eleman yo nan gwoup la enstale ak travay "tankou yon granmoun".
Nan lavni an, gen yon lide ajoute nan gwoup la tout sik CI/CD, aplike antyèman sou Franbwaz Pi a. Mwen pral kontan tou si yon moun pataje eksperyans yo nan mete kanpe K8s sou AWS Gravitons.
PS Wi, "pwodiksyon" ka pi pre pase sa mwen te panse:

P
Li tou sou blog nou an:
- «'.
Sous: www.habr.com
