Thực hành tốt nhất Kubernetes

Tôi đã trò chuyện với một SRE Googler trước đây, người (chính xác) đã chỉ ra rằng Kubernetes tiến hóa rất nhanh (quá nhanh để duy trì tiền tệ), sử dụng (nhiều) khái niệm mới lạ và có (cũng) nhiều cách để giải quyết vấn đề tương tự.

Phần lớn điều này là đúng và không nhất thiết là điều xấu cũng không nhất thiết phải khác biệt so với bất kỳ công nghệ nào khác. Trường hợp tôi không đồng ý là những yếu tố này đã làm nản lòng việc áp dụng Kubernetes của anh ấy. Tôi sẽ khuyến khích bạn đi sâu vào. Kubernetes là thành công của nó * mặc dù * những mối quan tâm (hợp lý) này bởi vì nó rất tốt.

Trong bài đăng này, tôi sẽ cung cấp cho bạn một số thực tiễn tốt nhất thô sơ mà tôi hy vọng sẽ giúp bạn nắm bắt công nghệ này bằng các thùng chứa của nó và lao vào.

Không theo thứ tự đặc biệt:

  1. Hãy để người khác làm toil!

Sử dụng dịch vụ Kubernetes như Kubernetes Engine. Trừ khi bạn tò mò về trí tuệ, một nhà phát triển làm việc trên Kubernetes hoặc bạn là nhà cung cấp nền tảng có khách hàng yêu cầu dịch vụ Kubernetes, hãy lưu lại rắc rối và sử dụng dịch vụ Kubernetes. Bạn đã xây dựng nhà riêng của bạn và chiếc xe của bạn? Hay bạn có thích ngủ ở một nơi mà Sói có thể thổi bay và lái một chiếc xe đáng tin cậy đưa bạn từ A đến B không?

Vì vậy, nếu bạn đã đọc bất kỳ bài đăng nào khác của tôi, tôi cũng khuyên bạn nên đánh giá các cụm khu vực và do đó, bạn đang xem xét một cái gì đó dọc theo dòng:

cụm container gcloud beta tạo $ {CLUSTER} ...
cụm container gcloud beta có được thông tin đăng nhập $ {CLUSTER} ...

Và sau đó, bạn đã sẵn sàng để đi với:

áp dụng kubectl --filename = marvels.yaml

2. Cố gắng nghĩ về Kub Kubetes

Điều này * có thể * là một thách thức với Kubernetes Engine hơn là trong các nền tảng khác, nhưng trên Google Cloud Platform, bạn buộc phải duy trì sự hiểu biết về trạng thái tài nguyên của mình trong Kubernetes (ví dụ: Nút, Ingresses) và đồng thời , các tài nguyên cơ bản trong Compute Engine (ví dụ: VM, Bộ cân bằng tải HTTP / S). Vấn đề đối ngẫu sóng hạt này là không may. Cảm ơn Dale H. vì lần đầu tiên nói rõ điều này cho tôi.

Nếu có thể, hãy cố gắng suy nghĩ về các tài nguyên của Kubernetes và bỏ qua các tài nguyên GCE cơ bản. Bây giờ đã dành hơn một năm để thiên vị công việc của tôi với Kubernetes, nó trở nên dễ dàng hơn để suy nghĩ đơn thuần về khía cạnh của một số số lượng Pod Pod được dịch vụ (và Ingresses) tiết lộ.

3. Không gian tên, Không gian tên, Không gian tên

Cập nhật: Cảm ơn Michael Hausenblas đã hướng dẫn tôi cách thực hành tốt nhất về * không * tham chiếu các không gian tên từ trong các tệp YAML của Kubernetes. Mặc dù bạn phải luôn sử dụng các không gian tên, việc chỉ định các không gian này khi bạn áp dụng tệp cung cấp tính linh hoạt cao hơn và khả năng sử dụng cùng các tệp YAML chống lại, ví dụ: cảnh quan khác nhau. Xem bài viết Michael Michael tại đây.

Mike Altarace và tôi đã viết các mặt trăng trước đây về Không gian tên trong Kubernetes và nơi bạn nên sử dụng chúng. Kể từ đó, tôi đã bỏ qua khá nhiều lời khuyên của riêng mình vì nghĩ rằng các trường hợp sử dụng của tôi rất nhỏ đến mức sử dụng Không gian tên sẽ bị quá tải. Tôi đã sai. Sử dụng không gian tên, luôn luôn.

Khi các container được xử lý, các không gian tên cho các dự án Kubernetes. Ngoài ranh giới bảo mật mà Namespaces truyền tải, họ là một cách tuyệt vời để phân vùng công việc của bạn và họ mang lại một cách tuyệt vời để đặt lại hoặc xóa nó:

kubectl xóa không gian tên / $ WORKING_PRO DỰ ÁN

Nhược điểm duy nhất là, khi sử dụng không gian tên không mặc định, bạn sẽ cần chỉ định không gian tên làm việc của mình --namespace = $ WORKING_PRO DỰ ÁN trên các lệnh kubectl, theo tôi, có thể là một cách thực hành bảo vệ tốt. Tuy nhiên, bạn luôn có thể - không gian tên hoặc đặt một không gian tên khác làm mặc định (liên kết).

4. Quá nhiều cách để giải quyết vấn đề

Đây là một mối quan tâm nản lòng. Tôi nghĩ rằng nó có lẽ không đúng sự thật, nhưng không có hướng dẫn tốt và thực hành tốt nhất, có lẽ có quá nhiều cách tương tự để giải quyết vấn đề tương tự. Tôi có một mô hình phổ biến mà tôi sử dụng mà tôi sẽ tóm tắt ở đây để khuyến khích thảo luận:

  • Các tệp YAML là kiến ​​thức trong kho lạnh (xem # 5)
  • Các thùng chứa của bạn sẽ làm tốt một việc (xem phần phân phối trực tuyến)
  • Luôn triển khai Triển khai (xem # 6)
  • Nếu bạn muốn L7 aka HTTP / S Cân bằng tải hãy sử dụng Ingress (xem # 7 - ha!)
  • Quản lý thông tin đăng nhập an toàn bằng cách sử dụng Bí mật (liên kết)

5. Xu hướng áp dụng cho kubectl --filename trên các lựa chọn thay thế

Thật dễ dàng để có được một cú đánh nhanh với kubectl tạo không gian tên / $ {WORKING_DIR}, nhưng sau vài lệnh như vậy, bạn có thể tự hỏi làm thế nào bạn đạt được trạng thái hiện tại và - quan trọng hơn - làm thế nào để tạo lại trạng thái này. Tôi khuyến khích bạn tạo các tệp YAML để mô tả tài nguyên của bạn thay vì lệnh tạo kub ectl tương đương.

Tôi khuyến khích bạn làm quen với tài liệu API * tuyệt vời * Kubernetes (liên kết, liên kết và 1.10) đầy đủ, chính xác và dễ điều hướng (có lẽ là tài liệu hoàn hảo!?). Nhưng, ngay cả với công cụ mạnh mẽ này, đôi khi nó gặp một chút khó khăn khi sử dụng lệnh kubectl phù hợp với bạn và chuyển đổi nó thành YAML. Không phải vậy:

kubectl được triển khai / $ {MY_DEPLOYMENT} --output = yaml
kubectl nhận dịch vụ / $ {MY_SERVICE} --output = yaml
kubectl nhận bất cứ điều gì / $ {MY_ANYTHING} --output = yaml

Đưa kết quả vào một tệp nếu bạn thích, nhưng sử dụng chúng làm cơ sở cho tệp YAML tương đương (!). Bạn sẽ cần phải bỏ bất kỳ tài liệu tham khảo ví dụ.

Khi bạn đã tạo ra kiệt tác.yaml, tôi khuyến khích bạn luôn luôn áp dụng để thực hiện việc tạo ban đầu, áp dụng để thực hiện bất kỳ cập nhật tiếp theo nào và, nếu bạn phải xóa. Đó là nó!

áp dụng kubectl --filename = masterstick.yaml
xóa kubectl --filename = masterstick.yaml

Thông tin chi tiết nhỏ: bạn không cần phải kéo các tệp YAML cục bộ để triển khai. Bạn cũng có thể cung cấp kubectl áp dụng --filename với các URL và, miễn là mọi tệp phụ thuộc là tham chiếu cục bộ, việc triển khai sẽ hoạt động.

Thông tin chi tiết nhỏ: nơi duy nhất tôi thấy điều này được sử dụng là ở vùng đất Kubernetes nhưng đó là một thông lệ hợp pháp, bạn có thể kết hợp nhiều tệp YAML vào một tệp YAML với --- và ... tách tệp. Vì vậy, thay vì một không gian tên YAML, YAML triển khai và YAML dịch vụ, bạn có thể có một YAML cực lớn hợp nhất cả ba tệp thành một.

Đây là YAML hợp lệ (sao chép và dán nó vào ví dụ YAML Lint). Đó là * không hợp lệ * Thông số Kubernetes | YAML vì mỗi thông số không đầy đủ nhưng, nếu từng được hoàn thành, điều này là YAML hoàn toàn tốt và là một cách tốt để giữ tài nguyên liên quan.

Xem #B (Xsonnet) cho một lời chỉ trích.

6. Sử dụng triển khai

Có một nhóm quyền lực trong Triển khai, đủ để tôi hướng dẫn: hãy sử dụng Triển khai mọi lúc, mọi nơi. Ngay cả khi bạn đang triển khai podnginx đơn đầu tiên của mình. Các triển khai là du lịch hạng nhất trên thế giới với giá của Coach, bạn có thể rơi vào triển khai, bạn mắc lỗi, áp dụng lại và Kubernetes chăm sóc tiêu diệt những quả đậu nghịch ngợm và thay thế chúng bằng những con có hành vi tốt.

7. LoadBalancer và Ingress

Những điều này gây ra nhầm lẫn. Trong tâm trí của tôi (và tôi có thể sai), khi tôi tạo Dịch vụ bằng cách sử dụng --type = LoadBalancer, tôi muốn | lấy LB mạng. Nếu tôi muốn Cân bằng tải HTTP / S (Cấp 7), tôi cần tạo một Ingress. Ingress là một tài nguyên Kubernetes khó hiểu. Có thể nói, L7 == Ingress (và kết quả là có rất nhiều sức mạnh cấu hình).

Kubernetes Engine biểu hiện các tài nguyên Nhập vào dưới dạng GCE HTTP / S Load-Balancer. Christopher Grant làm rất tốt công việc làm sáng tỏ Ingress trong các bài đăng của mình (ở đây và ở đây).

8. Cổng Node

Tôi thiên đường (bao giờ?) Trực tiếp tạo ra một ClusterIP. Tôi đã thực hiện mọi thứ với Kubernetes dẫn đến các dịch vụ bị lộ bởi ClusterIP. Chủ yếu (!) Tôi đã tạo NodePorts hoặc tôi làm mọi thứ (ví dụ: tạo tài nguyên Ingress) sử dụng NodePorts.

Các nút Node được liên kết với Nút Kubernetes và chúng Cổng Cổng. Công cụ mạnh mẽ mà họ cung cấp là * mỗi * nút trong cụm (hoặc đây có phải là NodePool không? [[TODO]]) phơi bày cùng một dịch vụ trên cùng một cổng (nút).

Nếu tôi tạo một dịch vụ mà lộ ra trên NodePort X, tôi có thể yên tâm rằng, nếu tôi truy cập vào cổng đó trên nút * any * trong cụm, tôi sẽ truy cập dịch vụ. Điều này tạo thành cơ sở cho khả năng cân bằng tải của Kubernetes vì ​​cụm có thể định tuyến các yêu cầu đến của dịch vụ tới cổng này trên bất kỳ nút nào.

Google Cloud SDK (hay còn gọi là gcloud) bao gồm một ứng dụng khách ssh khiến việc kết nối với máy tính Compute Engine trở nên tầm thường (mà bạn nhớ lại là Nút cụm Kubernetes). ssh client bao gồm khả năng chuyển tiếp cổng. Vì vậy, nếu chúng tôi muốn kết nối với Dịch vụ Kubernetes và chúng tôi có thể tra cứu NodePort của dịch vụ, thì chúng tôi có thể chuyển tiếp một cách tầm thường đến dịch vụ đó bằng cách chuyển tiếp cổng (sử dụng gcloud hoặc bất kỳ ứng dụng khách ssh nào) đến cổng trên bất kỳ Nút.

Ví dụ sau sử dụng kubectl để lấy nút 0 trong cụm. Tên Nút động cơ Kubernetes giống với tên máy tính Compute Engine VM. Đưa ra một dịch vụ có tên $ {MY_SERVICE} trong một không gian tên gọi là $ {MY_NAMESPACE}, chúng tôi xác định dịch vụ NodePort. Sau đó, chúng tôi chuyển sang gcloud và sử dụng ssh tích hợp của nó để chuyển tiếp cổng (sử dụng --ssh-flag = "- L XXXX: localhost: XXXX).

NODE_HOST = $ (\
  kubectl nhận nút \
  --output = jsonpath = "{. items [0] .metadata.name}")
NODE_PORT = $ (\
  kubectl nhận dịch vụ / $ {MY_SERVICE} \
  --namespace = $ {MY_NAMESPACE} \
  --output = jsonpath = "{. spec.ports [0] .nodePort}")
tiếng vang $ {NODE_PORT}
tính toán gcloud ssh $ {NODE_HOST} \
--ssh-flag = "- L $ {NODE_PORT}: localhost: $ {NODE_PORT}" \
--project = $ {YOU_PRO DỰ ÁN}

Điều gì mạnh mẽ về điều này? Bây giờ, bạn có thể truy cập dịch vụ như thể nó là cục bộ và không phải đục lỗ trên tường lửa.

Các nút Node là các cổng được đánh số cao (~ 30.00030323267).

9. Hack kubectl sử dụng JSON

Google Cloud Cloud SDK (hay còn gọi là gcloud) thực sự xuất sắc nhưng kubectl (Kubernetes CLI) tốt hơn (sic). Một tính năng mạnh mẽ là định dạng và lọc đầu ra. Điều này cho phép các cách không mã hóa (không sử dụng API) để mở rộng tập lệnh và các công cụ khác với thông tin từ các cụm Kubernetes.

Tất cả trạng thái tài nguyên Kubernetes có thể truy cập thông qua ví dụ: kubectl get (theo kinh nghiệm của tôi hữu ích hơn cho mục đích này hơn các lệnh kubectl mô tả). Sau đó, tất cả những gì còn lại là tìm kim trong cái có thể là một đống cỏ khô của JSON.

Bí quyết là:

kubectl get [resource] / [resource-name] --output = JSON

Và sau đó cầu mắt kết quả để bắt đầu xây dựng chuỗi truy vấn:

kubectl nhận [resource] / [resource-name] --output = jsonpath = ". items [*]"

và lặp lại tinh chỉnh kết quả được đặt xuống cho đến khi bạn có (các) mục mà bạn tìm kiếm. Dưới đây, một ví dụ nên làm việc với bất kỳ cụm nào:

kubectl nhận nút --output = json
kubectl nhận các nút --output = jsonpath = "{. items [*]}
kubectl nhận các nút --output = jsonpath = "{. items [0]}
kubectl nhận các nút --output = jsonpath = "{. items [0] .metadata.name}

Cuối cùng, có một đối số hợp lý (và một nguyên lý trong * nix) để tìm hiểu một công cụ phân tích cú pháp JSON và áp dụng công cụ đó cho tất cả các nhu cầu phân tích cú pháp JSON. Trong trường hợp này, có bất kỳ đối thủ cạnh tranh hợp lý để jq? Tôi nghi ngờ là không.

Plus jq có một sân chơi tuyệt vời (jqplay.org).

A. Sử dụng nhãn

Nó là một dịch vụ phần mềm sắp ra mắt từ lâu nhưng hiện tại đã hỗ trợ khái niệm ghi nhãn tài nguyên tùy ý (thường là các cặp giá trị khóa). Lý do mạnh mẽ là vì siêu dữ liệu này cung cấp một cách kết thúc mở, hoàn toàn do người dùng xác định để truy vấn tài nguyên. Kubernetes sử dụng nguyên tắc này vốn có; Nó có một khả năng nội tại và không phải là suy nghĩ sau khi bắt đầu.

Dịch vụ Kubernetes hiển thị số lượng Kubernetes Pod tùy ý. Một Dịch vụ * không * phơi bày các Pod được gọi là Henry Henry hay Pods bao gồm một Bản sao. Thay vào đó, một Dịch vụ hiển thị các Pod có nhãn đáp ứng các tiêu chí được xác định trong thông số kỹ thuật Service Service và các nhãn này, tất nhiên, do người dùng xác định.

NB Trong ví dụ trên, chúng tôi sử dụng một không gian tên gọi là project-x và thông số không gian tên này xuất hiện trong Không gian tên (khi nó được tạo ra), Triển khai để xác định nơi Triển khai tồn tại và trong Dịch vụ. Deployment (được gọi là microservice-y) sẽ tạo một Bản sao (được chỉ định ngầm định ở đây; nó có những gì Triển khai tạo ra) sẽ duy trì 100 Pods. Mỗi Pod sẽ có một ứng dụng nhãn: publicname-a và chứa một thùng chứa được gọi là grpc-proxy dựa trên một hình ảnh gọi là image-grpc-proxy. Dịch vụ được gọi là dịch vụ-p. Điều quan trọng, Dịch vụ chọn Pods (!) (Chỉ trong không gian tên dự án-x) có ứng dụng nhãn: publicname-a. Dịch vụ sẽ chọn bất kỳ Pod nào (trong không gian tên dự án-x) có cặp nhãn (khóa: value) này * không * chỉ những Pod được tạo trong triển khai này. Dịch vụ không tham chiếu các Pod theo tên của chúng (dựa trên tên Triển khai), tên container của chúng cũng như tên hình ảnh của container, chỉ các nhãn được liên kết với nhóm.

NB Đây là * không * một thực hành tốt nhưng nó chứng minh quan điểm. Nếu bạn đã chạy một cấu hình tương tự như trên và sau đó tạo riêng, ví dụ: một Pod chạy Nginx (trong không gian tên dự án-x) và sau đó bạn đã thêm ứng dụng nhãn: publicname-a vào nó, nó sẽ nhanh chóng được kết hợp trong tập hợp các Pod được dịch vụ tổng hợp bởi Dịch vụ-p. Nếu bạn xóa nhãn khỏi bất kỳ Pod nào được Dịch vụ tổng hợp, Pod sẽ ngừng được đưa vào.

Tính năng này được minh họa bằng cách cập nhật các bản cập nhật trong đó Deployment tạo ra một Bản sao mới bao gồm các Pod mới cho phiên bản X ', khác với các Bản sao và Pod cho phiên bản X. Dịch vụ có thể được xác định để hiển thị giao điểm của các Pod chạy trên cả hai phiên bản này bởi vì nó không được xác định theo thuật ngữ của các bản sao hoặc các Pod cụ thể mà bởi các nhãn do người dùng xác định (bộ chọn lọc của bộ lọc) được áp dụng bởi bạn khi các Pod được tạo.

Điều đó rất mạnh mẽ!

B. Sử dụng Jsonnet, có thể là Ksonnet

Hai thách thức với tất cả các định dạng có cấu trúc (!?) (YAML, JSON, XML, CSV ;-) là tự tham chiếu và biến. Khi bạn tạo các thông số kỹ thuật marvellous.yaml cho việc triển khai Kubernetes của mình, bạn sẽ gặp phải vấn đề này một cách dễ dàng. Bạn sẽ thấy mình sử dụng chữ (ví dụ: đối với tên hình ảnh và thông báo) và, ngay cả với các Triển khai được tôn trọng, lặp lại tên và bộ chọn.

Không có giải pháp nào cho những vấn đề này nếu bạn giới hạn bản thân với YAML và JSON. Google đã tạo ra Jsonnet một phần để giải quyết những vấn đề này. Những người Heptio thông minh đã mở rộng Jsonnet thành Kubernetes với chanh Ksonnet.

Cả hai đều là ngôn ngữ tạo khuôn mẫu giải quyết các vấn đề được nêu ở trên (và hơn thế nữa). Tôi khuyến khích bạn xem xét Jsonnet. Như với khuyến nghị của tôi để xem xét sử dụng jq, hãy tìm hiểu Jsonnet một lần và áp dụng nó ở mọi nơi bạn sử dụng JSON. Ksonnet đặc trưng cho Kubernetes và - theo kinh nghiệm hạn chế (!) Của tôi - tôi đã tìm thấy những lợi ích thu được từ tính đặc hiệu này để không bị vượt trội bởi đường cong học tập.

C. YAML hoặc JSON

Kubernetes đối xử với YAML và JSON gần như bằng nhau. Cá nhân tôi thấy YAML thích hợp hơn cho các tệp cấu hình mà tôi kubectl --apply vì YAML ngắn gọn hơn JSON. Mặc dù tôi thấy YAML khó viết hơn.

Tuy nhiên, khi hiểu về cấu trúc và phân tích cú pháp, tôi thích --output = JSON và cũng bởi vì - output = JSONPATH. Tôi là một người hâm mộ Golang khổng lồ nhưng các mẫu Go không phải là trực quan và tôi không sử dụng chúng.

cái nhìn sâu sắc nhỏ: YAML là một siêu bộ của JSON (liên kết) chờ đợi! gì?

D. API chó xuống và cấu hình

API Downward của API để đặt cho nó tên chính xác mặc dù không có gì khó hiểu, là một cơ sở trong Kubernetes mà Pods có thể hiểu được cụm xung quanh chúng. Tôi giả sử, dòng chảy bình thường là từ thế giới bên ngoài vào Pod và các thùng chứa của nó * nhưng * có những lúc nó có ích cho một container (!) Để lấy thông tin về môi trường của nó, ví dụ: Tên nút của nó | IP, tên Pod ấp (dấu cách) | IP.

Các giá trị API hướng xuống được trình bày cho vùng chứa thông qua các biến môi trường. Các biến môi trường được sử dụng (như các nơi khác) để cung cấp cấu hình hoặc trạng thái khác cho các thùng chứa. Một kết quả rất hay của việc sử dụng các biến môi trường và việc triển khai API hướng xuống (với một cảnh báo nhỏ) là thùng chứa vẫn được tách rời khỏi Kubernetes.

Dưới đây, một ví dụ từ bạn thân của tôi - Sal Rashid - sử dụng API hướng xuống để thu thập trạng thái Node và Pod và trình bày chúng cho người dùng:

https://github.com/salrashid123/istio_helloworld/blob/master/all-istio.yaml

NB Xem các phần bắt đầu tại các dòng 76, 80, 84, 88 trong đó tên Pod, không gian tên, tên IP và tên nút được cung cấp trong thời gian chạy bởi API hướng xuống tới bộ chứa có tên myapp-container.

API hướng xuống là cách duy nhất, thiết thực để thu thập dữ liệu này cho một container. Vì vậy, nó nhiều hơn một người khác chỉ thực hành trên phạm vi tình dục, chứ không phải là người thực hành tốt nhất.

Trong nhiều bài viết của tôi, khi tôi xây dựng các giải pháp cho Kubernetes, tôi đã kiểm tra quy trình cục bộ và bên ngoài của một container, sau đó trong một container (chỉ định các biến môi trường), sau đó trên cụm Kubernetes. Các cơ chế được đóng gói là nhất quán (xem bên dưới) mặc dù một cơ chế thường chạy trên Docker và một trên Kubernetes.

Trong một bài đăng tôi đã viết gần đây trên Hệ điều hành Tối ưu hóa Container của Google, tôi chứng minh một container chạy cục bộ trong Docker, từ xa trong Hệ điều hành Tối ưu hóa Container và sau đó trên Kubernetes.

Ở đây, nhánh chạy dưới Docker cục bộ. Lưu ý cách các biến môi trường (--env) được sử dụng để cung cấp cấu hình cho gcr.io/$ nbPRO DỰA / hành động.

docker chạy \
- tương tác \
--tty \
--publish = 127.0.0.1: 8080: 8080 \
--env = GCLOUD_DATASET_ID = $ {DỰ ÁN} \
--env = GOOGLE_APPLICATION_CREDENTIALS = / tmp / $ {ROBOT} .key.json \
--volume = $ PWD / $ {ROBOT} .key.json: / tmp / $ {ROBOT} .key.json \
gcr.io/$ nbPRO DỰ ÁN / dastastore

Ở đây, kết quả tương tự bao gồm việc triển khai vào việc tạo ra một VM tối ưu hóa vùng chứa. Lần này hãy kiểm tra các giá trị được cung cấp cho cờ container-env:

Các trường hợp tính toán gcloud beta tạo với thùng chứa $ {INSTANCE} \
--zone = $ {KHU}
--image-family = cos-ổn định \
--image-project = cos-cloud \
--container-image=gcr.io/$ nbPRO DỰ ÁN / $ nbIMAGE Bolog@$ nbDIGEST} \
--container-restart-chính sách = luôn \
--container-env = \
GCLOUD_DATASET_ID = $ {DỰ ÁN}, \
GOOGLE_APPLICATION_CREDENTIALS = / tmp / $ {ROBOT} .key.json \
--container-mount-host-path = \
gắn kết đường dẫn = / tmp, \
đường dẫn máy chủ = / tmp, \
chế độ = rw \
--project = $ {DỰ ÁN}

Và cuối cùng, ở đây, đoạn trích YAML của Triển khai cho Kubernetes:

hộp đựng:
      - tên: kho dữ liệu
        hình ảnh: gcr.io/$ đũaPRO DỰ ÁN
        imagePullPolicy: Luôn luôn
        VolumeMounts:
          - tên: kho dữ liệu
            mountPath: / var / secret / google
        env:
        - tên: GOOGLE_APPLICATION_CREDENTIALS
          giá trị: /var/secrets/google/datastore.key.json
        - tên: GCLOUD_DATASET_ID
          giá trị: $ {DỰ ÁN}
        cổng:
        - tên: http
          containerPort: 8080

Do đó, tôi thấy việc sử dụng các biến môi trường để cấu hình khá vụng về. Ở đó, không có sự ràng buộc rõ ràng nào về các biến môi trường cụ thể với các quy trình cụ thể và bạn chỉ nhận ra rằng chúng không được cấu hình đúng khi mọi thứ bị hỏng. Nó dễ dàng tưởng tượng các biến môi trường xung đột trong một môi trường không chứa container mặc dù đây là một vấn đề ít hơn với các container bởi vì, như trên, chúng tôi đã cài đặt rõ ràng các giá trị cho một container cụ thể.

Tất cả những gì đã nói, sử dụng các biến môi trường theo cách này là cách thực hành tốt nhất.

E. Sidecars và tại sao Pods aren luôn luôn đồng nghĩa với container

5 co cognac
2 cl ba giây
Nước chanh 2 cl
Chuẩn bị Đổ tất cả các thành phần vào bình lắc cocktail chứa đầy đá. Lắc đều và lọc vào ly cocktail.

Phần lớn thời gian, bạn sẽ tạo ra các Podern Kubernetes có chứa các container đơn lẻ và bạn sẽ tự hỏi tại sao lại có tất cả các chi phí hoạt động của một Pod khi bạn chỉ cần một container. Pods tương tự như một môi trường máy chủ có thể chạy nhiều container. Sau đó, nhiều lần bạn sẽ xem xét việc chạy nhiều container trong một Pod Trứng

Chỉ và một lần duy nhất mà bạn nên :-)

Có lẽ nhiều hơn một, nhưng hãy để dính vào chỉ một lần.

Mô hình chống (don lồng làm điều này) là để dự tính cấu hình hiện tại của bạn (hãy giả sử một máy chủ web và một phụ trợ cơ sở dữ liệu) và đưa cả hai vào một Pod. Đây không phải là * một ý tưởng hay * trừ khi * mỗi phiên bản máy chủ web phải được gắn kết chặt chẽ và mãi mãi với một thể hiện cơ sở dữ liệu cụ thể. Điều này là không thể.

Điều mà nhiều khả năng là các phiên bản máy chủ web của bạn sẽ mở rộng theo tải tổng hợp và các trường hợp cơ sở dữ liệu của bạn sẽ mở rộng (độc lập với điều này và) dựa trên khả năng tổng hợp của chúng để xử lý tải trước. Khi bạn thấy tổng hợp, hãy nghĩ đến Dịch vụ và khi bạn nghĩ Dịch vụ, vui lòng thử dự tính một số lượng Pod tùy ý (vì nó quan trọng đối với hóa đơn của bạn, nhưng đối với hầu hết các mục đích khác, không quan trọng là cần bao nhiêu Pod miễn là số là vừa phải để phục vụ khối lượng công việc).

Khi nào bạn nên xem xét nhiều container trên mỗi Pod? Một lần khi điều này * luôn * có ý nghĩa là khi bạn muốn bổ sung, mở rộng hoặc làm phong phú hành vi của Pod chính trong một thùng chứa. Hãy để xem lại ví dụ về máy chủ web và cơ sở dữ liệu từ trên xuống. Trong kịch bản này, hy vọng rằng bạn hiện đang thuyết phục rằng bạn sẽ triển khai hai Dịch vụ (và hai Triển khai), một cho giao diện và một cho phụ trợ.

Đó là một cách thực hành tốt và phổ biến để đặt chính cá thể máy chủ web của bạn với proxy ngược. Thông thường, đây sẽ là Nginx hoặc HAProxy và ngày càng trở nên phổ biến khi sử dụng Envoy (Tôi khuyên bạn, nếu bạn đang nhìn vào proxy, hãy xem xét Envoy; xem #F Istio). Một proxy ngược cung cấp tính nhất quán (chúng tôi chỉ sử dụng ví dụ như Envoy) ngay cả khi bạn sử dụng các máy chủ web khác nhau (ví dụ: Apache, Tomcat w / Java, v.v.), ngay cả khi bạn có lưu lượng truy cập HTTP, gRPC, Web Sockets, v.v. , ngay cả khi bạn muốn hướng một số lưu lượng truy cập đến máy chủ web của mình và một số lưu lượng truy cập vào bộ đệm (ví dụ Varnish).

Trong tất cả các kịch bản trước đây, sẽ rất hợp lý khi sử dụng mô hình bên sidecar. Trong mô hình này, bộ chứa chính (máy chủ web của bạn) có các bộ chứa phụ trợ, bổ sung (Envoy proxy, bộ đệm Varnish, v.v.). Chúng phải được kết hợp chặt chẽ với một thể hiện của máy chủ web cụ thể * và * về mặt chức năng, sự kết hợp đó là đơn vị Kiêu.

Nó là rất phổ biến để xem đăng nhập, giám sát, theo dõi và các thành phần cơ sở hạ tầng khác được phân phối như sidecar quá. Một động lực ở đây là để tách mối quan tâm. Để cung cấp cho các nhà phát triển một yêu cầu nhất quán tạo ra mã có thể quản lý được và cung cấp cho SRE tính linh hoạt để chọn các công cụ ưa thích biết rằng tất cả mã trên toàn đội sẽ ghi nhật ký, phát ra số liệu, có thể theo dõi, áp dụng xác thực nhất quán, v.v. tạo thành nền tảng của các lưới dịch vụ (xem #F Istio). Đây là tốt nhất cuối cùng, mặc dù thực hành non trẻ.

F. Sử dụng Istio

Sử dụng Istio cẩn thận.

Istio (và các lưới dịch vụ khác) là những công nghệ tương đối mới ra đời từ các công ty (bao gồm cả Google) đã chạy các container ở quy mô lớn. Các dịch vụ chia lưới một cách tầm thường một proxy phổ biến (trong trường hợp Istio, Envoy) trong mỗi Pod trong mỗi Triển khai trong mọi Không gian trong mỗi cụm.

Kết quả là một chất nền quản lý nhất quán cho phép kết hợp quản lý lỏng lẻo (chúng tôi sẽ sử dụng Stackdo Trace ngay hôm nay nhưng có kế hoạch chuyển sang Jaeger, chúng tôi đã triển khai giám sát Prometheus) và chúng tôi biết tất cả các dịch vụ của chúng tôi đều an toàn, chúng tôi biết Đang định tuyến 10% lưu lượng truy cập đến các bản dựng canary của các dịch vụ A, B và C).

Tôi khuyên rằng cẩn thận, vì các công nghệ này là mới, có các cạnh thô và đang phát triển nhanh chóng. Nhưng, những lợi thế (linh hoạt, nhanh nhẹn, chứng minh trong tương lai) phương pháp này cung cấp cho bạn khả năng vượt xa chi phí. Quan trọng nhất, hãy sử dụng lưới dịch vụ làm mô hình của bạn với Kubernetes ngay cả khi bạn chưa muốn áp dụng một trong những công nghệ lưới dịch vụ.

Đó là tất cả, folks!