mình vẫn chưa động vào Kubernetes. Vậy nên viết nhanh phần đến đít, không mai kia rơi vãi hết.
Bài này KHÔNG PHẢI HƯỚNG DẪN DÙNG K8s, ai cần hướng dẫn thì vào trang chủ xem.
Bài này tổng kết về kinh nghiệm sử dụng K8s: Khái niệm, kiến trúc, troubleshoot, ...
dựa trên trí nhớ mong manh còn sót lại chút ít sau những cơn lụt ở Sài Gòn...
Kubernetes |
Các khái niệm trong K8s
K8s đưa ra một lô 1 lốc các khái niệm. Vậy nên muốn dùng k8s, phải nắm chắc các khái niệm.Xem thì có vẻ nhiều, nhưng đó là những thứ mà nếu như k8s không đưa ra, thì một ngày nào đó, bạn cũng lại tự "phát minh" ra (và 99,96 % là tệ / tạm bợ hơn nhiều).
Pod
Pod là một khái niệm rộng hơn container, nhưng đa số trường hợp thì đánh đồng nó với container cũng không sao. Pod là 1 nhóm (1 trở lên) các container thực hiện một mục đích nào đó (chạy software nào đó - pod có nhiều container là khi các app có quan hệ rất chặt chẽ - theo ví dụ K8s đưa ra là trang upload ảnh và trang hiển thị ảnh.)Nếu k8s chỉ có mỗi khái niệm pod, thì dùng k8s giống như dùng docker bình thường. Tức
muốn thêm tính năng gì thì ta phải tự kiến trúc/ thiết kế/ thực hiện.
96% thông tin bạn cần về pod, nằm trong output của lệnh : describe pod PODNAME
$ kubectl get pods --selector='app=audit'
NAME READY STATUS RESTARTS AGE
audit-deployment-3585156150-mlcv3 1/1 Running 0 14d
$ kubectl describe pod audit-deployment-3585156150-mlcv3
Name: audit-deployment-3585156150-mlcv3
Namespace: default
...
Service (svc)
Service đưa ra khái niệm về - service 😂Nếu như khi làm docker, bạn sẽ quá tập trung vào container, thì ở k8s, ta tập trung vào service.
Một service sẽ cung cấp một "dịch vụ" gì đó, có giá trị, và ta cố không tập trung vào chuyện bên dưới nó chạy thế nào, chỉ quan tâm rằng có một dịch vụ đang được cung cấp ở địa chỉ xyz.com port 2369...
Service là khái niệm được thực hiện bởi : domain name, và port. Service sẽ tự động "tìm" các pod được đánh label phù hợp (trùng với label của service), rồi chuyển các connection tới đó.
Nếu tìm được 5 pods thoả mã label, service sẽ thực hiện load-balancing: chia connection tới từng pod theo chiến lược được chọn (VD: round-robin: lần lượt vòng tròn).
Mỗi service sẽ được gán 1 domain do người dùng lựa chọn, khi ứng dụng cần kết nối đến service, ta chỉ cần dùng domain là xong. Domain được quản lý bởi hệ thống name server SkyDNS nội bộ của k8s - một thành phần sẽ được cài khi ta cài k8s.
$ kubectl get svc --namespace=kube-system | grep dnsNếu đã có kinh nghiệm sysadmin, ta sẽ thấy k8s service giải quyết rất nhiều bài toán mà khi hệ thống/dịch vụ của bạn to ra, bạn sẽ phải làm: service discovery, load balancing.
kube-dns 10.3.240.10 <none> 53/UDP,53/TCP 38d
Tất nhiên, nếu chỉ có 1 máy chạy 1 dịch vụ, thì service chả có nghĩa lý gì. Vậy nên khi dùng k8s, hãy nhớ rằng nó được thiết kế và đưa vào các khái niệm để phục vụ cho hàng trăm, ngàn service/container, chứ không phải 1 cái. Nó phức tạp vì nó có lý do để phức tạp. Và bạn/công ty của bạn không phải Google (ở đây không hạ thấp bạn hay công ty của bạn), không phải công ty nào cũng chạy dịch vụ software cung cấp cho cả thế giới.
Namespace (ns)
Nếu tôi đặt service này là "web" lúc chạy production, còn lúc dev thì tôi chạy nó ở đâu? không nhẽ phải đổi tên service?Namespace giải quyết vấn đề này. Mặc định các dịch vụ sẽ sử đụng namespace "default", nhưng ta muốn tạo namespace nào thì tuỳ ý. K8s sử dụng 1 namespace riêng : kube-system, vì vậy nhớ đừng quên namespace khi gọi câu lệnh: VD:
$ kubectl get svc --namespace=kube-systemnamespace - luôn là một ý tưởng tuyệt vời, Python cũng nói vậy:
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default-http-backend 10.3.246.86 <nodes> 80:31031/TCP 38d
elasticsearch-logging 10.3.251.158 <none> 9200/TCP 33d
heapster 10.3.242.120 <none> 80/TCP 33d
kibana-logging 10.3.245.215 <none> 5601/TCP 33d
kube-dns 10.3.240.10 <none> 53/UDP,53/TCP 38d
kubernetes-dashboard 10.3.243.251 <none> 80/TCP 38d
monitoring-grafana 10.3.243.34 <none> 80/TCP 33d
monitoring-influxdb 10.3.253.47 <none> 8086/TCP 33d
tiller-deploy 10.3.240.33 <none> 44134/TCP 38d
$ python -c 'import this' | grep -i namespace
Namespaces are one honking great idea -- let's do more of those!
Port-forward
Không phải dịch vụ nào cũng cần show ra cho cả thế giới xem, ví dụ như hệ thống logging hay monitoring thì chỉ cần "người nhà mình" biết là đủ. Hoặc khi dev, chưa có domain để expose ra ngoài, ta sẽ truy cập các service bằng port-forward khi đã biết tên pod (get pods):$ kubectl port-forward monitoring-grafana-3730655072-sbcst 3000:3000 --namespace=kube-systemVà ta có thể truy cập vào pod này qua port 3000 mà nó đang listen thông qua localhost:3000
Forwarding from 127.0.0.1:3000 -> 3000
Forwarding from [::1]:3000 -> 3000
Handling connection for 3000
Handling connection for 3000
...
Dashboard
Dashboard cho phép xem tổng quan về cluster k8s đang dùng, nó được cài vào k8s như một add-on https://github.com/kubernetes/dashboard Nói chung là để xem thôi, còn tương tác gì thì cứ câu lệnh kubectl mà chọc.Kiểm tra xem đã cài dashboard chưa:
$ kubectl get svc --namespace=kube-system | grep -i dashboardTruy cập:
kubernetes-dashboard 10.3.243.251 <none> 80/TCP 38d
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
Vào trình duyệt qua 127.0.0.1:8001/ui/
K8s dashboard |
Persistent volume (PV) - Persistent volume claim (PVC)
Bất kỳ ai làm container cũng cần hiểu rằng, ta không lưu dữ liệu trên container mà phải lưu nó vào một chỗ nào đó. Bởi khi container restart / bị die thì dữ liệu cũng sẽ mất theo nó. Đây là chuyện dù dùng docker trực tiếp hay giải pháp khác K8s thì bạn vẫn phải tính. Việc lưu dữ liệu của app trên container trực tiếp trên máy host là một giải pháp nhỏ lẻ. Vì nếu ta cho dữ liệu của pod của app A vào /var/lib/app/A, mà có 2 pod cho app A cùng được chạy trên máy đó thì chuyện gì xảy ra?Giải pháp k8s sử dụng là các hệ thống lưu trữ "network". Tức lưu vào một hệ thống storage khác. Như NFS, GlusterFS, Ceph ...
PV, là khái niệm để đưa ra một dung lượng lưu trữ THỰC TẾ 1GB, 10GB ...
PVC là khái niệm ảo, đưa ra một dung lượng CẦN THIẾT, mà ứng dụng yêu cầu.
Khi 1 PV thoả mãn yêu cầu của 1 PVC thì chúng "match" nhau, rồi "bound" (buộc / kết nối) lại với nhạu. Nếu tự cài K8s, hãy chuẩn bị sẵn giải pháp lưu trữ của bạn. Nếu dùng sẵn Google cloud hay AWS, sẵn sàng để trả tiền.
ConfigMap (cm) - Secret
Một software ít khi chạy luôn mà không cần config.ConfigMap là giải pháp để nhét 1 file config / đặt các ENVironment var hay set các argument khi gọi câu lệnh. ConfigMap là một cục config, mà pod nào cần, thì chỉ định là nó cần - giúp dễ dàng chia sẻ file cấu hình.
Ít ai muốn đặt mật khẩu vào file cấu hình, và chỉ có lập trình viên "tồi" mới hardcode mật khẩu vào code. Vậy nên K8s có "secret", để lưu trữ các mật khẩu, token, ... hay những gì cần giữ bí mật.
Nodes
là các máy trong k8s cluster.$ kubectl get nodes
NAME STATUS AGE
gke-cluster-1-default-pool-xxx-7f9v Ready 23d
gke-cluster-1-default-pool-xxx-8k6t Ready 39d
gke-cluster-1-default-pool-xxx-hc0d Ready 39d
gke-cluster-1-default-pool-xxx-xpcc Ready 39d
Deployment/ StatefulSets / DaemonSet / Static Pod
Các "khái niệm" khác nhau cho các loại dịch vụ khác nhau.Deployment là loại chung nhất, khi ta muốn "deploy" một dịch vụ nào đó. Ta tạo ra pod bằng cách tạo ra một deployment (hoặc statefulSets, hoặc các khái niệm tương đương).
StatefulSets được dùng khi ta cần các service bật lên theo tứ tự nhất định.
DaemonSets thường dành cho các dịch vụ cần chạy trên tất cả các node. Ví dụ như fluentd để collect log trên tất cả các node.
Static Pod là 1 file "manifest" đặt trong thư mục chỉ định bởi kubelet, các pod này sẽ được chạy khi kubelet chạy. Không thể điều khiển chúng bằng kubectl. Đây là một khái niệm đang dần bị xa lánh bởi sự thiếu linh động và khó kiểm soát.
Gõ kubectl get để xem tất cả những khái niệm resource mà k8s sử dụng, và cách gọi ngắn gọn cho từng khái niệm (svc cho service, deploy cho deployment, cm cho configmap ...).
Helm - K8s package manager
Trên Ubuntu, ta dùng APT để cài package, thì trên K8s, Helm dùng để cài các "chart", muốn chạy một hệ thống CI ?Install ngay bằng câu lệnh của helm.
helm install something
VD:
$ helm install stable/concourse # cài concourse CI
Monitoring
Monitoring trên K8s rất dễ dàng, chỉ cần cài 1 phần mềm có khả năng tích hợp với k8s, nó sẽ hỏiK8s để lấy thông tin về tất cả các pod trong hệ thống.Hãy tưởng tượng ta có hệ thống monitoring tự động cho mọi pod được tạo - mà không cần làm gì :3
Xem thêm tại https://kubernetes.io/docs/concepts/cluster-administration/resource-usage-monitoring/
Create
Mọi file cấu hình cho pod/svc/cm/ ... đều là file ở định dạng YAML.Chỉ cần chạy
kubectl create -f filename # hoặc . để cài hết các file trong thư mục hiện tạiđể "deploy" chúng.
Kiến trúc
K8s cluster bao gồm nhiều node, trên mỗi node sẽ cần chạy một "kubelet", đây là chương trìnhđể chạy k8s. Cần một máy để làm "chủ" cluster, trên đó sẽ cài API server, scheduler ...
Các máy còn lại sẽ chạy kubelet để sinh ra các container.
Network
Có nhiều loại phần mềm để triển khai container network, như Flannel, Weaver ...nếu bạn dùng Google Cloud, vấn đề này không cần quan tâm.
Tổng kết
- Nếu bạn sẵn sàng chi tiền để mua K8s chạy trên một hệ thống dựng sẵn nào đó: như GCE hay OpenShift, thì mọi vấn đề liên quan đến cài đặt k8s cùng các thành phần khác sẽ được bỏ qua, bạn chỉ cần quan tâm tới việc vận hành các pod/service của mình, và trả tiền.- CoreOS có nhiều đóng góp và doc khá tốt để giới thiệu và tự cài 1 hệ thống K8s: https://coreos.com/kubernetes/docs/latest/
Đến đây, tình nghĩa với K8s chấm dứt... cho tới khi nào ta lại cần.
PS: hoá đơn dùng k8s 1 tháng để test (GKE 4 vCPU), không phải trả đồng nào vì GCE khuyến mãi 300$ mỗi user.
Hết.
HVN at http://www.familug.org/ and http://pymi.vn
Đăng ký học #Python , lớp tại chi nhánh #HàNội khai giảng giữa tháng 4, 2017: https://pymi.vn/
Nhập email vào http://invite.pymi.vn/ để nhận thư mời tham gia forum hỏi đáp Python, Django, Golang, Linux ...
No comments:
Post a Comment