Решали с коллегами задачу по генерации манифестов Provisioner в цикле, при таком создании есть один деструктивный момент - нужно выбрать Container Runtime Interface (CRI), иначе provisioner.spec.kubeletConfiguration.containerRuntime в манифесте Provisioner в паре с AWSNodeTemplate karpenter по дефолту выставят нам containerd (подтверждение в тесте)
Собрали ряд требований:
CRI не указан в провиженере, значит выбираем дефолтный для нас (в нашем случае dockerd)
CRI указан в провиженере, выбираем его
CRI не указан в провиженере, но в provisioner.spec.kubeletConfiguration есть другие параметры
# Kubelet # If Provisioner.kubeletConfiguration is not empty {{- if .kubeletConfiguration }} kubeletConfiguration: # If containerRuntime has been configured in Provisioner.kubeletConfiguration {{- if hasKey .kubeletConfiguration "containerRuntime" -}} {{- toYaml .kubeletConfiguration | nindent 4 }} # ElseIf containerRuntime has not been configured in Provisioner.kubeletConfiguration {{- else }} # Pick default CRI from karpenter.default.kubeletConfiguration and add it to current .kubeletConfiguration {{- $CRI := dict "containerRuntime" $.Values.karpenter.default.kubeletConfiguration.containerRuntime -}} {{- $kubeletConfiguration := merge $CRI .kubeletConfiguration }} {{- toYaml $kubeletConfiguration | nindent 4 }} {{- end }} # ElseIf Provisioner.kubeletConfiguration is empty {{- else }} kubeletConfiguration: {{- toYaml $.Values.karpenter.default.kubeletConfiguration | nindent 4 }} {{- end }}
Тесты
Test cases:
1) CRI не указан в провиженере
values.yml
karpenter: payload: ahorbach: foo: bar
result:
spec: # Kubelet # If Provisioner.kubeletConfiguration is not empty kubeletConfiguration: containerRuntime: dockerd
2) CRI указан в провиженере
values.yml
karpenter: payload: ahorbach: kubeletConfiguration: bar: baz containerRuntime: rocket
result:
spec: # Kubelet # If Provisioner.kubeletConfiguration is not empty kubeletConfiguration: # If containerRuntime has been configured in Provisioner.kubeletConfiguration bar: baz containerRuntime: rocket # ElseIf containerRuntime has not been configured in Provisioner.kubeletConfiguration # ElseIf Provisioner.kubeletConfiguration is empty
spec: # Kubelet # If Provisioner.kubeletConfiguration is not empty kubeletConfiguration: # If containerRuntime has been configured in Provisioner.kubeletConfiguration # Pick default CRI from karpenter.default.kubeletConfiguration and add it to current .kubeletConfiguration containerRuntime: dockerd spam: eggs
from pydantic import BaseModel, validator DEFAULT_CRI ={"containerRuntime":"dockerd"} classkarpenterPayloadProvisioner(BaseModel): name:str kubelet_configuration:dict= DEFAULT_CRI @validator('kubelet_configuration') defkubelet_container_runtime(cls, v): cri = v.get("containerRuntime") # option two - Mutating if cri notin["dockerd","containerd"]: v.update(DEFAULT_CRI) return v
Тесты
import typing as t import pytest from karpenter import karpenterPayloadProvisioner # without selected CRI in Provisioner case1 =("foo",{},"dockerd") # with containerd as a CRI for Provisioner case2 =("bar",{"kubeReserved":"testMe","containerRuntime":"containerd"},"containerd") # with typo in CRI for Provisioner case3 =("baz",{"kubeReserved":"testMe","containerRuntime":"qwerty"},"dockerd") test_cases =[ case1, case2, case3, ] @pytest.mark.parametrize("name, kubelet_configuration, expected_CRI", test_cases) deftest_cri_provisioner(name:str, kubelet_configuration: t.Optional[dict], expected_CRI:str): provisioner = karpenterPayloadProvisioner(name=name, kubelet_configuration=kubelet_configuration) assert provisioner.kubelet_configuration["containerRuntime"]== expected_CRI
Terraformer - тулза преобразующая существующие облачные ресурсы в terraform код. Может быть полезна в различных кейсах, например: при обучении aws-у и terraform-у - создали ресурсы через console по курсу, а потом дампнули это в terraform код. Либо более классический кейс - описываете существующую инфраструктуру в IaC.
Нужно сделать кросс-аккаунт aws iam rbac роли, для того, чтобы kubed из mc-mgmt мог управлять секретами в k8s кластерах других aws аккаунтов, в данном случае mc-project.
В mc-mgmt кластере так же работает обычный интанс kubed-а, установленный helm чартом, из него мы и берем все необходимые k8s RBAC-и.
danger
Этот способ деструктивен, неверная конфигурация kubed-master может реверсировать синхронизацию секретов между namespace-ами. Рекомендация держать специальный кластер для kubed-master
ConfigMap
Deployment
--- apiVersion: v1 kind: ConfigMap metadata: name: kubed-master-aws namespace: kube-system data: credentials:|- [mc-mgmt] role_arn = arn:aws:iam::<mc-mgmt_id>:role/kubed-master web_identity_token_file = /var/run/secrets/eks.amazonaws.com/serviceaccount/token [mc-project] role_arn = arn:aws:iam::<mc-project_id>:role/kubed-follower source_profile = mc-mgmt role_session_name = mc-project generate-kubeconfig.sh:|- #!/bin/bash set -eux aws eks update-kubeconfig --name mc-project-k8s --alias mc-project-k8s --profile mc-project # NOTE: mc-mgmt-k8s should the last due to current-context aws eks update-kubeconfig --name mc-mgmt-k8s --alias mc-mgmt-k8s --profile mc-mgmt
Синхронизация возможно только из namespace-а указанного во флагах контроллера в namespace с таким же названием в follower кластерах. При это annotations и labels на конфигурациях в follower кластерах не сохраняется.
Поводом для синхронизации конфигураций является: перезапуск pod-а контроллера, обновление .data конфигурации. Т.е. если конфигурация будет удалена в follower кластере, она не синхронизуется автоматом.
Удаление конфигурации в master аккаунте, удалит конфигурацию во всех follower-ах.
В случае, если в follower кластере есть свой kubed для синхронизации между namespace-ами, то можно добавить annotation-ию вручную и конфигурация разбежится по namespace-ам. Причем обновление .data в master кластере синхронизирует секрет в follower, но не перетрет эту аннотацию.
Добавляем аннотацию в follower кластере
kubectl --context mc-project annotate cm cross-acc-sync-demo "kubed.appscode.com/sync=sync/kubed-master=true"
Добавляем label на другой namespace в follower кластере, чтобы местный kubed засинхронизировал cm между namespace-ами.
$ git clone https://github.com/lensapp/lens.git $ git checkout v5.5.4 # последний из стабильных релизов 5.x.x $ make build
Тут и начинаются грабли, в большей степени связанные с nodejs и несовместимостью версий самой ноды или пакетов.
Мне для корректировки версии помогла утилита nvm и эта статья
nvm ls-remote # смотрим какие варианты нам может предложить менеджер ноды nvm install lts/fermium # node 15.x nvm use lts/fermium # пиним версию ноды в системе
В моем случае пина версии ноды хватило, чтобы успешно собрать .dmg пакет.
Уже пару месяцев использую Notion для заметок, но делал все относительно топорно. У меня было много страничек древовидной структуры и канбан доска с тасками на неделю. Правда недавно взглянул в темплейты от самого Notin-а и скопировал оттуда engineering page (ниже пример под спойлером).
info
мой канбан борд
Посмотрел видео Владлена, нашел много полезного (ниже будет pdf с конспектом)
Относительно недавно заимел iPad + Pencil + Logitech Combo Touch для рисования рисунков, заметок и конспектов, легковесной замене ноута в случае инцидентов.
замена ноута -> в Logitech отвратный клик на тач и куча проблем самого iPad. Но используя проект code-server - я могу работать за iPad. Однако считаю, что поэтому пункту скорее неуд.
What if a pod is frequently restarting, and you need to figure out why?
What if all CPU resource is used up and you need to find out which pod consumes the most and why?
How to monitor certain resources?
How to troubleshoot a failed component?
info
For example, if you want to monitor the CPU resource each pod uses or each node uses, do you know what keyword to search in the official documentation?
Завел у себя дома кластер, мастер с одним воркером бегут поверх ubuntu-desktop моего старого ноутбука (4vcpu, 8gb ram), использую vagrant+virtualbox, containerd в качестве рантайма (CRI).
Мысль в том, что в любой момент могу с относительно минимальными телодвижениями докинуть воркеров с других компьютеров в домашней сети.
sequenceDiagram
participant Packer
participant Vagrant
participant Ansible
Packer->>Vagrant: Launch tmp VM
Note right of Vagrant: !NOTE: at low level Vagrant uses Virtualbox API
Vagrant->>Ansible: Configure tmp VM
Ansible-->>Vagrant: Done!
Vagrant-->>Packer: Done!
%% loop Artifact
%% Ansible->>Packer: Create Vagrant box from current VM state.
%% end
note over Packer: Creates Vagrant box from current VM state.
note over Packer: Releases the Vagrant box on Vagrant Cloud.
Это, пожалуй, самое больное в использовании virtualbox - открыть гую на весь экран. Тут я не буду вам давать никаких обещаний, могу лишь накинуть идеи как вам с этим справиться:
Когда я только знакомился с AWS по youtube плейлисту, я смастерил VPC в двух AZ с несколькими подсетями. Один из типов подсетей был private - с nat-gateway, в курсах забыли сказать, что они не входят во фритир. За пару дней за 2 гейта накапало около $6. Было обидно, я поставил биллинг аларм.
Совсем недавно я учился (на котиках) созданию артефактов с помощью packer. После тренировки в AWS я со спокойной душой в console нужного региона убил все AMI и пошел дальше.
Неделю спустя в почте заметил очередное письмо от AWS (мне иногда на личный gmail аккаунт приходят от них billing репорты, всегда пустые, и приглашения не re:invent).
Увидел что я потратил 85% "фри-тирного" места под снэпшоты ebs дисков.
info
AWS Free Tier - тут можно прочитать сколько вам в месяц выделяется того или иного ресурса бесплатно в рамках фри-тира.
Ага - из-за негодяя packer-а помимо AMI-шек создаются еще и такие сущности.
Мораль
пермым делом во фри-тире сделайте не рутового пользователя, вторым настройте биллинг алерты (я бы поставил трешхолд на 50% - в моем случае бюджет таял быстро).
Авторам видео / гайдлайнов, конечно, стоило бы указывать, что это не входит во фри-тир - или входит, но слабые лимиты.