• Полезные уроки, которые помогут освоить K8s.
• Что такое Kubernetes? Запуск локального кластера Kubernetes. Minikube;
• Запуск Kubernetes кластера на AWS, используя eksctl;
• Запуск Kubernetes кластера на AWS, используя Terraform;
• Как использовать kubectl с несколькими Kubernetes кластерами;
• Как установить Kubernetes Dashboard;
• Создание объекта Pod. Запуск контейнеров в Kubernetes;
• Метки, аннотации и пространства имён в Kubernetes;
• ReplicationController и ReplicaSet в Kubernetes;
• Deployment в Kubernetes. Стратегии обновления приложений;
• Service в Kubernetes - Часть 1. Type: ClusterIP. Endpoints;
• Service в Kubernetes - Часть 2. Types: ExternalName, NodePort и LoadBalancer. Headless Service;
• Ingress в Kubernetes. Создание Ingress на Minikube;
• Liveness и Readiness Probes в Kubernetes;
• StartupProbe и httpHeaders для httpGet в Kubernetes;
• Переопределение CMD и ENTRYPOINT Docker иструкций, используя Kubernetes;
• Настройка HTTPS для web-app в Kubernetes. NGINX Ingress и cert manager. Let's Encrypt;
• Lens - IDE для Kubernetes;
• Использование объекта DaemonSet в Kubernetes;
• Использование Jobs в Kubernetes;
• Использование CronJobs в Kubernetes;
• Volumes в Kubernetes - Часть 1. Сравнение Docker storage driver: overlay2 и volume: emptyDir;
• Volumes в Kubernetes - Часть 2. Volumes типов hostPath и awsElasticBlockStore;
• Что такое PersistentVolume, PersistentVolumeClaim и StorageClass;
• Как настроить AWS IAM Roles для Service Accounts в Kubernetes;
• Cert-manager. Настройка HTTPS. Wildcard сертификаты. DNS01 Challenge. AWS Route53;
• Использование ConfigMap и переменных окружения в Kubernetes;
• Что такое Secrets в Kubernetes и как их использовать;
• Что такое Helm. Практический выпуск. Kubernetes;
• Что такое Helm Chart Repository. Установка ChartMuseum. Kubernetes;
• Что такое ArgoCD и как с ним работать в Kubernetes. GitOps;
• Сбор, анализ и отправка Pod логов в ElasticSearch, используя Fluentd. EFK Stack;
• AWS Load Balancer Controller в Kubernetes. Target type: IP vs Instance. Настройка HTTPS;
• Что такое ExternalDNS и как его настроить с использованием AWS Route53;
• Что такое ServiceAccount, Role, RoleBinding, ClusterRole и ClusterRoleBinding в Kubernetes;
• ArgoCD. Cluster Bootstrapping. App of Apps Pattern. Deploy Infrastructure в одну команду в K8s;
• Что такое External Secrets Operator в Kubernetes. AWS: Parameter Store и Secrets Manager;
• Установка и настройка Grafana Loki в Kubernetes, используя AWS S3 Bucket. Promtail;
• Node affinity и anti-affinity vs nodeSelector. podAffinity и podAntiAffinity в Kubernetes;
• Taints и Tolerations в Kubernetes. NoSchedule, PreferNoSchedule и NoExecute;
• Topology Spread Constraints. Запуск Pods в Highly Available. Local cluster, используя Kind;
• Установка Amazon EBS CSI Driver. Использование AWS KMS для EBS;
• Установка Amazon EFS CSI Driver. Dynamic volume provisioning, используя EFS Access points;
• Network Policies в Kubernetes. Установка Calico network policy engine в Amazon EKS.
#RU #Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
infosec
• Kubernetes — это ведущая система управления контейнерами в конвейерах разработки по всему миру, но это не освобождает её от вредоносных атак. Использование Kubernetes требует глубокого понимания среды, включая разные уязвимости, с которыми можно столкнуться при создании, развертывании или запуске приложений в кластере.
• Поскольку кластер Kubernetes один из самых ценных облачных ресурсов, он нуждается в защите. Его безопасность обеспечивает безопасность облака, кластеров приложений, контейнеров, приложений и кода. Хотя Kubernetes обеспечивает преимущества в области безопасности, укрепление способов защиты имеет решающее значение для обороны вашей системы от хакеров и других кибер-угроз.
• В этой статье рассматриваются семь основных способов, которые могут подвергнуть кластер атаке, с соответствующими мерами противодействия к каждому.
#Eng #Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
Шпаргалка по архитектуре k8s.jpg
998.1 KB
• Дополнительный материал:
- Полезные уроки, которые помогут освоить K8s;
- Kubernetes Goat;
- Взлом и защита Kubernetes.
#Kubernetes #DevOps
Please open Telegram to view this post
VIEW IN TELEGRAM
• Это отличный и, самое главное, бесплатный курс по куберу на русском языке. Подробное описание и разбор важных тем даст Вам ценные знания и навыки.
• Вводный вебинар. Зачем нужен Kubernetes?
• Что такое Docker?
• Docker Compose и Best Practice Docker, CI/CD и Gitlab CI;
• Первое практическое занятие;
• Введение в Kubernetes, Pod, Replicaset;
• Kubernetes: Deployment, Probes, Resources;
• Второе практическое занятие;
• Kubernetes: Ingress, Service, PV, PVC, ConfigMap, Secret;
• Компоненты кластера Kubernetes;
• Сеть Kubernetes, отказоустойчивый сетап кластера;
• Kubespray. Установка кластера;
• Продвинутые абстракции Kubernetes: Daemonset, Statefulset;
• Продвинутые абстракции Kubernetes: Job, CronJob, RBAC;
• DNS в Kubernetes. Способы публикации приложений;
• Helm. Темплейтирование приложений Kubernetes;
• Подключение СХД Ceph в Kubernetes с помощью CSI;
• Как сломать Кубернетес? Disaster Recovery;
• Обновление Kubernetes;
• Траблшутинг кластера. Решения проблем при эксплуатации;
• Мониторинг кластера Kubernetes;
• Логирование в Kubernetes. Сбор и анализ логов;
• Требования к разработке приложения в Kubernetes;
• Докеризация приложения и CI/CD в Kubernetes;
• Observability — принципы и техники наблюдения за системой.
#Kubernetes #RU
Please open Telegram to view this post
VIEW IN TELEGRAM
• ClusterIP — открывает доступ к сервису по внутреннему IP-адресу в кластере. Этот тип делает сервис доступным только внутри кластера;
• NodePort — открывает сервис на том же порту каждого выбранного узла в кластере с помощью NAT. Делает сервис доступным вне кластера через
<NodeIP>:<NodePort>
. Является надмножеством ClusterIP;• LoadBalancer — создает внешний балансировщик нагрузки в текущем облаке (если это поддерживается) и назначает фиксированный внешний IP-адрес для сервиса. Является надмножеством NodePort;
• ExternalName — открывает доступ к сервису по содержимому поля
externalName
(например, foo.bar.example.com
), возвращая запись CNAME
с его значением. При этом прокси не используется. Для этого типа требуется версия kube-dns
1.7+ или CoreDNS
0.0.8+.#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• Вопросы по Kubernetes достаточно часты на собеседованиях на инженерные вакансии, связанные с администрированием и эксплуатацией. Они могут варьироваться от базовых, рассчитанных на механическую проверку теоретических знаний («объясните, что такое service») до более сложных и комплексных, требующих глубинного понимания внутренних принципов Kubernetes и работы (каким образом опубликовать приложение, развёрнутое в Kubernetes). Давайте пойдём от базы в направлении возрастания сложности:
• Дополнительно:
- Обучающий курс по Kubernetes;
- Шпаргалка по архитектуре Kubernetes;
- Взлом и защита Kubernetes;
- Полезные уроки, которые помогут освоить K8s;
- Top 4 Kubernetes Service Types in one diagram;
- ТОП-8 книг по DevOps в 2023 году.
#Kubernetes #DevOps
Please open Telegram to view this post
VIEW IN TELEGRAM
• Kubernetes authentication principles;
• Internal Kubernetes authentication methods;
- Static token authentication;
- Bootstrap tokens;
- X.509 client certificates;
- Service account tokens;
• External authentication methods;
- OpenID Connect (OIDC);
- Webhook token authentication;
- Authenticating proxy;
- Impersonating proxy;
• Authentication for other Kubernetes components;
- Kubelet;
- Controller manager and scheduler;
- Kube-proxy;
- Etcd;
• Conclusion.
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• Коллекция полезных шпаргалок для DevOps и IT специалистов. Содержание следующее:
- #Nginx;
- #Docker;
- #Ansible;
- #Python;
- Go (Golang);
- #Git;
- Regular Expression (Regex);
- #PowerShell;
- #VIM;
- #Jenkins;
- Continuous Integration and Continuous Delivery (CI/CD);
- #Kubernetes;
- #Linux;
- Redis;
- Slack;
- Puppet;
- Google Cloud Developer;
- PostgreSQL;
- Ajax;
- Amazon Web Services (AWS).
#CheatSheet #DevOps
Please open Telegram to view this post
VIEW IN TELEGRAM
• Поделюсь с Вами очень интересным проектом, который описывает методы атак на Kubernetes. Проект сырой, но постоянно дополняется необходимой информацией. Особенно будет полезно изучить начинающим специалистам: https://kubenomicon.com/
• Другой полезный материал:
- Kubernetes: шпаргалка для собеседования;
- Обучающий курс по Kubernetes;
- Шпаргалка по архитектуре Kubernetes;
- Взлом и защита Kubernetes;
- Полезные уроки, которые помогут освоить K8s;
- Top 4 Kubernetes Service Types in one diagram;
- ТОП-8 книг по DevOps в 2023 году.
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• Самое известное средство контейнеризации и автоматизации развертывания приложений — #Docker. Известное, но не единственное: достойную конкуренцию ему составляет Kubernetes. Разумеется, он тоже представляет определенный интерес для злоумышленников. Как защитить Kubernetes от взлома? Об этом — сегодняшняя статья:
- Restrict Kubernetes API access to specific IP ranges;
- Use Role-Based Access Control (RBAC);
- Enable PodSecurityPolicy (PSP);
- Use Network Policies;
- Enable Audit Logging;
- Use Secure Service Endpoints;
- Use Pod Security Context;
- Use Kubernetes Secrets;
- Enable Container Runtime Protection;
- Enable Admission Controllers;
- Hardcoded Credential;
- Container Escape Attack;
- Kubernetes API Server Attack;
- Pod-to-Pod Network Attack;
- Privilege Escalation Attack;
- Denial-of-Service (DoS) Attack;
- Kubernetes Threat Matrix.
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• K8s LAN Party — это набор из пяти CTF-сценариев, в которых пользователю нужно найти уязвимости в кластере #Kubernetes. Каждый сценарий посвящен проблемам сети Kubernetes, с которыми сталкивались разработчики данного ресурса в реальной практике.
• Инструмент поможет участникам углубить свои знания в области безопасности кластера Kubernetes: у них будет возможность встать на место злоумышленников и изучить ошибки в конфигурациях, что пригодится в работе.
• В K8s LAN Party кластер уже развернут. Игроку нужно лишь выполнять команды в терминале прямо в браузере: https://www.k8slanparty.com
#CTF
Please open Telegram to view this post
VIEW IN TELEGRAM
K8Slanparty
K8s LAN Party
Kubernetes LAN Party - by Wiz
• PWK полностью повторяет идею (и даже интерфейс) своего «прародителя» Play with Docker (о котором я упоминал вчера): его основной сайт — это так называемая «игровая площадка» (playground), предоставляющая в веб-браузере доступ к виртуальной Linux-машине для возможности проведения экспериментов с кластерами Kubernetes. По сути это доступный бесплатно SaaS-аналог Minikube со своими удобствами (работа прямо в браузере) и ограничениями
• Предлагаемая в онлайн-сервисе лабораторная работа ориентирована на начинающих и посвящена основным концепциям и возможностям Kubernetes:
- Что вообще позволяет делать эта система: запуск контейнеров, балансировка нагрузки, выкатывание новых версий образов, автомасштабирование…;
- Архитектура Kubernetes;
- Ресурсы Kubernetes: узлы, поды, сервисы, пространства имён, секреты;
- Декларативный подход;
- Сетевая модель Kubernetes;
и т.п.
• Выглядит же прохождение лабораторной работы аналогично тому, как всё было в Play with Docker: слева у вас есть документ-инструкция (в том числе и команды для ввода), а справа — терминал (точнее, их два — для двух узлов Kubernetes), позволяющий «поиграть» в администратора K8s-кластера и видеть, что и как происходит на самом деле. Последнему, безусловно, способствует возможность выполнять произвольные уточняющие команды на любых этапах выполнения работы.
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• ПО для обеспечения безопасности Kubernetes… их так много, и у каждого свои цели, область применения и лицензии... Однако, хочу поведать Вам о некоторых интересных решениях с открытым исходным кодом, которые полностью бесплатны:
• Trivy — простой, но мощный сканер уязвимостей для контейнеров, легко интегрируемый в CI/CD-пайплайн. Его примечательная особенность — простота установки и работы: приложение состоит из единственного бинарника и не требует установки базы данных или дополнительных библиотек. Обратная сторона простоты Trivy состоит в том, что придется разбираться, как парсить и пересылать результаты в формате JSON, чтобы ими могли воспользоваться другие инструменты безопасности Kubernetes.
• Portieris — это admission controller для Kubernetes; применяется для принудительных проверок на доверие к контенту. Portieris использует сервер Notary в качестве источника истины для подтверждения доверенных и подписанных артефактов (то есть одобренных контейнерных образов). При создании или изменении рабочей нагрузки в Kubernetes Portieris загружает информацию о подписи и политику доверия к контенту для запрошенных образов контейнеров и при необходимости на лету вносит изменения в JSON-объект API для запуска подписанных версий этих образов.
• Kube-bench — приложение на Go, проверяющее, безопасно ли развернут Kubernetes. Ищет небезопасные параметры конфигурации среди компонентов кластера (etcd, API, controller manager и т.д.), сомнительные права на доступ к файлам, незащищенные учетные записи или открытые порты, квоты ресурсов, настройки ограничения числа обращений к API для защиты от DoS-атак и т.п.
• Kube-hunter — Kube-hunter «охотится» на потенциальные уязвимости (вроде удаленного выполнения кода или раскрытия данных) в кластерах Kubernetes. Kube-hunter можно запускать как удаленный сканер — в этом случае он оценит кластер с точки зрения стороннего злоумышленника — или как pod внутри кластера. Отличительной особенностью Kube-hunter'а является режим «активной охоты», во время которого он не только сообщает о проблемах, но и пытается воспользоваться уязвимостями, обнаруженными в целевом кластере, которые потенциально могут нанести вред его работе. Так что пользуйтесь с осторожностью!
• Kubeaudit — это консольный инструмент, изначально разработанный в Shopify для аудита конфигурации Kubernetes на предмет наличия различных проблем в области безопасности. Например, он помогает выявить контейнеры, работающие без ограничений, с правами суперпользователя, злоупотребляющие привилегиями или использующие ServiceAccount по умолчанию. У Kubeaudit есть и другие интересные возможности. К примеру, он умеет анализировать локальные файлы YAML, выявляя недостатки в конфигурации, способные привести к проблемам с безопасностью, и автоматически исправлять их.
• Kyverno — движок политик безопасности Kubernetes с открытым исходным кодом, который помогает вам определять политики с помощью простых манифестов Kubernetes. Он может проверять, изменять и генерировать ресурсы Kubernetes. Таким образом, это может позволить организациям определять и применять политики так, чтобы разработчики и администраторы придерживались определенного стандарта.
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• Nuclei — очень быстрый сканер уязвимостей с открытым исходным кодом, который можно настроить с помощью шаблонов. Может работать с различными протоколами, такими как: TCP, HTTP, DNS. А еще Nuclei можно настроить под свои нужды, так как сканирование основано на шаблонах, написанных в формате YAML.
• Так вот, в новой версии Nuclei (9.9.0) разработчики добавили темплейты для сканирования Kubernetes кластера и всё подробно описали в своем блоге:
- Deployment Configurations Review;
- Network Policies Enforcement;
- Pod Security Standards;
- Compliance and Configuration Management;
- Security Contexts and Roles;
- Logging and Monitoring;
- Secrets Management;
- Vulnerability Scanning and Patch Management.
#Kubernetes #Nuclei
Please open Telegram to view this post
VIEW IN TELEGRAM
• Если у вас есть желание и потребность в изучении Kubernetes, то этот курс как раз даст Вам всю необходимую базу и даже больше:
- Вводный вебинар. Зачем нужен Kubernetes?
- Что такое Docker?
- Docker Compose и Best Practice Docker, CI/CD и Gitlab CI;
- Введение в Kubernetes, Pod, Replicaset;
- Kubernetes: Deployment, Probes, Resources;
- Kubernetes: Ingress, Service, PV, PVC, ConfigMap, Secret;
- Компоненты кластера Kubernetes;
- Сеть Kubernetes, отказоустойчивый сетап кластера;
- Kubespray. Установка кластера;
- Продвинутые абстракции Kubernetes: Daemonset, Statefulset;
- Продвинутые абстракции Kubernetes: Job, CronJob, RBAC;
- DNS в Kubernetes. Способы публикации приложений;
- Helm. Темплейтирование приложений Kubernetes;
- Подключение СХД Ceph в Kubernetes с помощью CSI;
- Как сломать Кубернетес? Disaster Recovery;
- Обновление Kubernetes;
- Траблшутинг кластера. Решения проблем при эксплуатации;
- Мониторинг кластера Kubernetes;
- Логирование в Kubernetes. Сбор и анализ логов;
- Требования к разработке приложения в Kubernetes;
- Докеризация приложения и CI/CD в Kubernetes;
- Observability — принципы и техники наблюдения за системой.
#Kubernetes #Курс
Please open Telegram to view this post
VIEW IN TELEGRAM
• На YT появились доклады с DevOops 2023 - конференции по инженерным решениям и DevOps-культуре. Список докладов следующий:
• Security:
- GitOps с точки зрения безопасности;
- Как мы захотели автоматизировать Vault CE и во что его в итоге превратили;
- Безопасность контейнеров в 2023 году. Тренд или необходимость? (VK / VK Cloud);
- Токсичные репозитории. Что сейчас происходит с open source?
- Network Policy для разработчиков: как, зачем и почему;
- Прорастить или насадить? Руководство по выращиванию политик безопасной разработки;
- (Не)стандартный подход к моделированию Supply Chain Attack;
- Безопасность: консультативная vs запрещающая;
- Защищаем Kubernetes при помощи StackRox — дешево, сердито, эффективно?
- Security для бедных без ущерба для DevEx.
• K8s:
- Очумелые ручки: делаем свой Helm Chart Repository из подручных средств;
- Скрывая Kubernetes: подходы к конфигурированию;
- Stateful в K8s, которого мы боимся;
- Использование Helm без написания Helm-чартов;
- Сказка о рулевом и прорехах в пиджаке: как защитить K8s;
- Через тернии к Kubernetes operators;
- Побег из
- 7 раз отмерь, а потом переделай: как мы храним сетевые политики;
- Развертывание инфраструктуры в облаках с NOVA Container Platform.
#DevOps #Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
• Эта история от первого ведущего архитектора проекта, Брайана Гранта, который постил в Twitter серию тредов о технической истории проекта. Он рассказал о появлении разных фичей в K8s и логике, которая стояла за принятием отдельных решений.
• В честь юбилея оркестратора Брайан собрал все твиты в одну статью. Это её перевод, из которого вы узнаете, как появились контроллеры рабочих нагрузок, декларативная модель ресурсов, descheduler и многое другое:
• Дополнительно:
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM
📦 Первые контейнеры.
• Первые контейнеры, официально называвшиеся именно этим термином, появились в феврале 2004 года в операционной системе Solaris 10 от Sun Microsystems, они использовались на серверах с архитектурой x86 и SPARC. Solaris Containers включали в себя изолированные «песочницы» для запуска ОС (в терминологии разработчика они назывались «зонами»), а также инструменты управления системными ресурсами, допускавшими создание «моментальных снимков» отдельных зон и их клонирование. То есть, механизмы оркестрации.
• Зоны представляли собой полностью изолированные виртуальные серверы внутри хостовой операционной системы. Каждый такой экземпляр ОС имел собственное сетевое имя, использовал выделенные сетевые интерфейсы, собственную файловую систему, набор пользователей (включая root) и конфигурацию. При этом для работы виртуального сервера не требовалось жестко выделять память или процессор — аппаратные ресурсы использовались общие, однако при необходимости администратор имел возможность зарезервировать определенные серверные мощности для какой-то конкретной зоны. Процессы внутри контейнеров выполнялись изолированно, не имели доступа друг к другу и потому не могли конфликтовать.
• Основным отличием Solaris Containers от предшественников (Process Containers, LXC и Warden, #Docker и #Kubernetes) можно назвать то обстоятельство, что, как и ранее, виртуальные ОС использовали ядро хостовой системы, но при желании администратор мог запускать копии системы в контейнерах с собственным ядром. Это стало следующим важным шагом в эволюции технологий контейнеризации.
#Разное
• Первые контейнеры, официально называвшиеся именно этим термином, появились в феврале 2004 года в операционной системе Solaris 10 от Sun Microsystems, они использовались на серверах с архитектурой x86 и SPARC. Solaris Containers включали в себя изолированные «песочницы» для запуска ОС (в терминологии разработчика они назывались «зонами»), а также инструменты управления системными ресурсами, допускавшими создание «моментальных снимков» отдельных зон и их клонирование. То есть, механизмы оркестрации.
• Зоны представляли собой полностью изолированные виртуальные серверы внутри хостовой операционной системы. Каждый такой экземпляр ОС имел собственное сетевое имя, использовал выделенные сетевые интерфейсы, собственную файловую систему, набор пользователей (включая root) и конфигурацию. При этом для работы виртуального сервера не требовалось жестко выделять память или процессор — аппаратные ресурсы использовались общие, однако при необходимости администратор имел возможность зарезервировать определенные серверные мощности для какой-то конкретной зоны. Процессы внутри контейнеров выполнялись изолированно, не имели доступа друг к другу и потому не могли конфликтовать.
• Основным отличием Solaris Containers от предшественников (Process Containers, LXC и Warden, #Docker и #Kubernetes) можно назвать то обстоятельство, что, как и ранее, виртуальные ОС использовали ядро хостовой системы, но при желании администратор мог запускать копии системы в контейнерах с собственным ядром. Это стало следующим важным шагом в эволюции технологий контейнеризации.
#Разное
• Awesome Cloud Security Labs - объемный набор бесплатных лаб для самостоятельного изучения безопасности облачных сред и технологий:
➡ AWS;
➡ Azure;
➡ GCP;
➡ Kubernetes;
➡ Container;
➡ Terraform;
➡ Research Labs;
➡ CI/CD.
➡ https://github.com/iknowjason/Awesome-CloudSec-Labs
#Cloud #ИБ
#Cloud #ИБ
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - iknowjason/Awesome-CloudSec-Labs: Awesome free cloud native security learning labs. Includes CTF, self-hosted workshops…
Awesome free cloud native security learning labs. Includes CTF, self-hosted workshops, guided vulnerability labs, and research labs. - GitHub - iknowjason/Awesome-CloudSec-Labs: Awesome free clou...
• Сетевые политики — основополагающий аспект защиты кластеров Kubernetes. Политики L4 обеспечивают базовый контроль над трафиком на основе IP-адресов и портов, в то время как политики L7 позволяют гранулярно контролировать трафик на уровне приложений с помощью надёжной криптографической идентификации. Комбинируя оба типа политик и используя service mesh, можно реализовать модель «нулевого доверия», отвечающую современным вызовам в области безопасности.
• Это руководство для тех, кто хочет узнать больше об управлении сетевым трафиком Kubernetes на основе политик. Вы узнаете о разных типах политик и о том, почему они важны, о плюсах и минусах каждой из них и о том, как их определять и когда следует комбинировать.
• Дополнительно:
#Kubernetes
Please open Telegram to view this post
VIEW IN TELEGRAM