192.168.1.254 Вход в роутер. Настройка WI-FI роутера

Во многих современных Wi-Fi роутерах используется IP адрес http://192.168.1.254/ для входа в личный кабинет для управления настройками и совершения других действий, например усиления мощности интернет-сигнала.

Чаще всего вход в 192.168.1.254 подразумевает использование оборудования компании NETIS, роутеров компании MGTS (МГТС) работающих по технологии GPON.

192-168-1-254 Читать

Как хранить диаграммы Helm в реестре контейнеров Azure

В Helm есть много замечательных инструментов, но хранение диаграмм всегда было проблемой. Давайте посмотрим, как мы можем сделать этот процесс намного проще!

Одним из больших преимуществ понимания того, как работает экосистема контейнеров, является то, что вы можете использовать один и тот же шаблон для нескольких спецификаций.

Не так давно Helm объявил, что будет поддерживать артефакты OCI, которые представляют собой не что иное, как открытую спецификацию OCI для распространения образов контейнеров и других типов данных, называемых артефактами.

Эта спецификация, как и все другие спецификации OCI, не зависит от облака, что делает ее фантастическим инструментом для работы.

 

Контейнерные записи

Запись контейнера (CR) или реестр — это то, что приходилось использовать всем, кто когда-либо имел дело с контейнерами. CR — это место, где мы храним наши образы контейнеров, поэтому мы можем получать их из любого места и в любое время.

По сути, изображение — это набор файлов, которые имеют примерно такую ​​структуру:

 ├── blobs

       │   └── sha256

       │       ├── 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db3...

       │       ├── 31fb454efb3c69fafe53672598006790122269a1b3b458607dbe106...

       │       └── 8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690f...

       ├── index.json

       └── oci-layout


 

Файл index.json представляет собой список всех доступных манифестов, то есть это список всех изображений, доступных в определенном месте. В нашем случае это список всех карт руля.

Каждый файл внутри blobs/sha256 представляет собой JSON, который идентифицирует артефакт, будь то изображение или диаграмма. Этот JSON соответствует спецификации OCI для файлов SHA.

Если коротко, то это список настроек, описывающих характеристики BLOB, его настройки, свойства, слои файловой системы, а также начальные команды.

В случае Helm Chart у нас есть следующий файл:

{

  "schemaVersion": 2,

  "config": {

    "mediaType": "application/vnd.cncf.helm.config.v1+json",

    "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",

    "size": 117

  },

  "layers": [

    {

      "mediaType": "application/tar+gzip",

      "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",

      "size": 2487

    }

  ]

}


 

Обратите внимание, что у нас есть дифференциация mediaType, в то время как обычный образ Docker имеет тип application/vnd.oci.image.config.v1+json.

Здесь у нас тип   application/vnd.cncf.helm.config, то же самое и со слоями, каждый слой изображения OCI имеет тип application/vnd.oci.image.layer.v1.tar+gzip, а здесь у нас есть только формат .tar.gz.

 

Размещение диаграмм в Реестре контейнеров Azure

Размещение диаграмм Helm в Azure CR очень похоже на их локальное хранение. Вам необходимо иметь доступ к Azure через Azure CLI. Мы предполагаем, что у вас уже есть Azure CLI, поэтому давайте создадим наш ACR.

Сначала мы должны создать нашу группу ресурсов, а затем ACR с помощью команд:

az group create -n helm-reg -l eastus

az acr create -n chartregistry$RANDOM -g helm-reg --sku Basic -o tsv --query loginServer

 

Совет — сохранить имя репозитория в переменной:

export ACR=$(az acr create -n chartregistry$RANDOM -g helm-reg --sku Basic -o tsv --query loginServer)


 

Теперь мы собираемся войти в наш реестр, используя управляемые ключи Azure, но нам нужно включить административный контроль с помощью az acr update -n $ACR —admin-enabled true.

Затем выполните следующие две команды, чтобы получить учетные данные для входа и сохранить их в оболочке:

export ACRUSER=$(az acr credential show -n $ACR --query username -o tsv)

export ACRPASS=$(az acr credential show -n $ACR --query 'passwords[0].value' -o tsv)


 

Теперь мы можем войти в наш реестр с помощью Helm helm registry login $ACR —username $ACRUSER —password $ACRPASS, и отсюда у нас уже настроен наш реестр.

Давайте создадим еще один артефакт с помощью helm chart save hrepo $ACR/hrepo:2.1.3(в качестве примера я буду использовать диаграмму из пустого репозитория с именем hrepo). Затем мы подтолкнем его с помощью helm chart push $ACR/hrepo:3.8.0.

Как только он будет там, мы сможем перечислить все в репозитории с помощью команды Azure CLI:

az acr repository show -n $ACR --repository hrepo


 

Обратите внимание, что у нас будет именно то, что мы отправили:

{

  "changeableAttributes": {

    "deleteEnabled": true,

    "listEnabled": true,

    "readEnabled": true,

    "writeEnabled": true

  },

  "createdTime": "2022-03-05T20:56:49.6118202Z",

  "imageName": "hrepo",

  "lastUpdateTime": "2022-03-05T20:56:49.7812323Z",

  "manifestCount": 1,

  "registry": "chartregistry23657.azurecr.io",

  "tagCount": 1

}


 

Мы также можем получить более подробную информацию с помощью команды show-manifests, добавив —detail:

az acr repository show-manifests -n $ACR --repository hrepo --detail


 

Это даст нам точное определение артефактов OCI:

[

  {

    "changeableAttributes": {

      "deleteEnabled": true,

      "listEnabled": true,

      "quarantineState": "Passed",

      "readEnabled": true,

      "writeEnabled": true

    },

    "configMediaType": "application/vnd.cncf.helm.config.v1+json",

    "createdTime": "2022-03-05T20:56:49.7213057Z",

    "digest": "sha256:4780713fa23d7144d356c353795b5b84e66ad2b8bbd47c7118b4b85435d50bbc",

    "imageSize": 1378,

    "lastUpdateTime": "2022-03-05T20:56:49.7213057Z",

    "mediaType": "application/vnd.oci.image.manifest.v1+json",

    "tags": [

      "2.1.3"

    ]

  }

]


 

Чтобы сохранить его, мы должны просто:

helm chart pull $ACR/hrepo:3.8.0

helm chart export $ACR/hrepo:3.8.0 -d ./destination

helm install hrepo-acr ./destination

 

Заключение

Хотя использовать Helm легко, все же не существует «простого» способа разместить диаграмму Helm как своего рода частную запись.

Хотя в Helm есть отличные инструменты, такие как Chart Museum, они все же не являются полностью стандартными, и для легкой распределенной разработки важно, чтобы у нас были открытые стандарты, которым может следовать каждый в целом.

Helm недавно перевел поддержку реестра OCI с экспериментальной на общую функцию, что является убедительным признаком того, что экосистема контейнеров становится все лучше.



2022-03-21T17:26:42
Microsoft

Windows 10 не требует ключа продукта для установки и использования

В отличие от более старых версий Windows, таких как Windows 7, Microsoft позволяет загружать и устанавливать Windows 10 без обязательного предоставления лицензионного ключа. Мало того, вы также можете использовать Windows 10 без ее активации навсегда. Тем не менее, есть некоторые ограничения, которые компания установила, что может немного раздражать. Хотите узнать больше о том, что значит использовать Windows 10 без ключа продукта? Читайте дальше, чтобы узнать, как установить Windows 10 без серийного ключа и что произойдет, если вы используете его без активации:

Нужен ли ключ продукта для загрузки Windows 10?

Нет, Microsoft не запрашивает у вас ключ продукта, чтобы вы могли загрузить установочный комплект Windows 10. На самом деле от вас не требуется абсолютно никаких подробностей. Вы можете загрузить Windows 10, ничего не сообщая Microsoft: ни ваша учетная запись Microsoft, ни серийный ключ Windows 10 не нужны.

Чтобы получить Windows 10, вы можете использовать любой веб-браузер для загрузки Media Creation Tool с веб-сайта Microsoft, здесь: Загрузите Windows 10. Когда вы попадете на страницу, нажмите или коснитесь кнопки «Загрузить инструмент сейчас» в разделе «Создать установочный носитель Windows 10». Затем сохраните и запустите исполняемый файл Media Creation Tool и используйте его для создания загрузочного USB-накопителя или DVD-диска с Windows 10.

Вам не нужен ключ продукта для загрузки Windows 10

Если вам нужно подробное руководство по загрузке и созданию установочного носителя с помощью Media Creation Tool, в этом руководстве показаны все шаги: Windows 10 Media Creation Tool — создание установочного USB-накопителя или ISO-образа.

Как установить Windows 10 без ключа продукта

После создания установочного носителя Windows 10 используйте его для загрузки компьютера, устройства или виртуальной машины. Затем запустите процесс установки Windows 10, как обычно.

Начните установку Windows 10, как обычно.

Когда вы дойдете до шага, на котором мастер установки Windows 10 попросит вас активировать Windows, нажмите или коснитесь «У меня нет ключа продукта».

Выберите У меня нет ключа продукта

Затем продолжите процесс установки Windows 10 в обычном режиме: мастер установки больше не будет запрашивать ключ продукта.

Что произойдет, если я установлю Windows 10 без ключа продукта?

При установке Windows 10 без предоставления серийного ключа могут возникнуть два сценария:

  • Это не первый раз, когда вы устанавливаете Windows 10 на свой компьютер или устройство, и предыдущая установка Windows 10 была активирована либо путем покупки нового лицензионного ключа Windows 10, либо с помощью предложения бесплатного обновления с Windows 7 или Windows 8.1, сделанная Microsoft в прошлом. В этом случае ваша новая Windows 10 будет автоматически бесплатно активирована, даже если на этот раз вы не ввели ключ продукта.
  • Это первый раз, когда вы устанавливаете Windows 10 на свой компьютер или устройство, и в этом случае на нем никогда не работала активированная операционная система Windows 10. В этом случае Microsoft не активирует Windows 10, пока вы не предоставите ключ продукта. Пока вы этого не сделаете, операционная система будет работать, но с рядом ограничений, которые мы перечислим в следующем разделе этой статьи.

Каковы ограничения нелицензионной копии Windows 10?

Если вы устанавливаете Windows 10 без ключа продукта и Microsoft не активирует его, вы сможете использовать его неограниченное время, но с парой ограничений. Наиболее важные из них следующие:

  • Windows 10 покажет водяной знак «Активировать Windows» в правом нижнем углу экрана.
  • Вы не сможете персонализировать свою Windows 10 из приложения «Настройки». К сожалению, это означает, что вы не можете изменить такие вещи, как фоновое изображение, цвета и темы, или настроить внешний вид меню «Пуск» или панели задач.
  • Приложение «Настройки» покажет уведомления о том, что ваша Windows 10 не активирована, и порекомендует вам приобрести ключ продукта Windows 10.

Вы можете использовать Windows 10 без ключа продукта навсегда, с некоторыми ограничениями.

Это основные недостатки использования Windows 10 без ключа продукта. В остальном нелицензионная копия Windows 10 работает так же, как и активированная. Вы можете использовать его так долго, как хотите.

Вы используете Windows 10 без ключа продукта?

Таким образом, Microsoft позволяет загружать и устанавливать Windows 10 без лицензионного ключа. Он даже позволяет вам использовать его столько, сколько вы хотите, даже не активируя его. Тем не менее, есть некоторые ограничения, если вы это сделаете. Достаточно ли их, чтобы заставить вас купить ключ продукта Windows 10? Или вы собираетесь использовать Windows 10 без ее активации? Дайте нам знать в комментариях ниже.



2022-03-21T16:08:38
Вопросы читателей

Docker Tips: Очистите свою машину от хлама /Как удалить старые и не используемые образы Docker

Сегодня мы поговорим о том, как Docker использует дисковое пространство хостовой машины, а также разберемся в том, как это пространство освободить от ошметков неиспользуемых образов и контейнеров.







Общее потребление




Docker – крутая штука, наверное сегодня мало кто в этом сомневается. Всего несколько лет назад этот продукт предоставил нам совершенно новый способ построения, доставки и запуска любого окружения, позволяя значительно сэкономить ресурсы процессора и оперативной памяти. В дополнение к этому (а для кого-то это будет даже самым важным) Docker позволил нам невероятно упростить и унифицировать управление жизненным циклом используемых рабочих сред.




Однако, за все эти прелести современной жизни приходится платить. Когда мы запускаем контейнеры, скачиваем или создаем собственные образы, разворачиваем сложные экосистемы, нам приходится платить. И платим мы, в том числе, дисковым пространством.




Если вы никогда не задумывались о том, сколько же места реально занято на вашей машине Docker’ом, то можете быть неприятно удивлены выводом этой команды:




$ docker system df







Здесь отображено использование диска Docker’ом в различных разрезах:







Готов поспорить, что уже после этого простого перечисления вы горите желанием почистить диск от мусора и вернуть к жизни драгоценные гигабайты (прим. перев.: особенно, если за эти гигабайты вы ежемесячно перечисляете арендную плату).




Использование диска контейнерами




Каждый раз при создании контейнера на хостовой машине в каталоге /var/lib/docker создается несколько файлов и каталогов, среди которых стоит отметить следующие:







Давайте представим себе систему, на которой установлен девственно чистый Docker, ни разу не участвовавший в запуске контейнеров и сборке образов. Его отчет об использовании дискового пространства будет выглядеть так:




$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         0          0          0B         0B
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B




Запустим какой-нибудь контейнер, например, NGINX:




$ docker container run --name www -d -p 8000:80 nginx:1.16




Что происходит с диском:







$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          1          126M       0B (0%)
Containers     1          1          2B         0B (0%)
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B




Судя по выводу, у нас еще нет пространства, которое мы могли бы высвободить. Так как 2 байта это совершенно несерьезно, давайте представим, что наш NGINX неожиданно для всех написал куда-то 100 Мегабайт данных и создал внутри себя файл test.img именно такого размера.




$ docker exec -ti www 
  dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]




Снова исследуем использование дискового пространства на хосте. Мы увидим, что контейнер (containers) занимает там 100 Мегабайт.




$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          1          126M       0B (0%)
Containers     1          1          104.9MB    0B (0%)
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B




Думаю, ваш пытливый мозг уже задается вопросом, где же находится наш файл test.img. Давайте его поищем:




$ find /var/lib/docker -type f -name test.img
/var/lib/docker/overlay2/83f177...630078/merged/test.img
/var/lib/docker/overlay2/83f177...630078/diff/test.img




Не вдаваясь в подробности можно отметить, что файл test.img удобно расположился на уровне чтения-записи, управляемом драйвером overlay2. Если же мы остановим наш контейнер, то хост подскажет нам, что это место, в принципе, можно высвободить:




# Stopping the www container
$ docker stop www

# Visualizing the impact on the disk usage
$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          1          126M       0B (0%)
Containers     1          0          104.9MB    104.9MB (100%)
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B




Как мы можем это сделать? Удалением контейнера, которое повлечет за собой очистку соответствующего пространства на уровне чтения-записи.




С помощью следующей команды вы можете удалить все установленные контейнеры одним махом и очистить ваш диск от всех созданных ими на уровне чтения-записи файлов:




$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2

Total reclaimed space: 104.9MB




Итак, мы высвободили 104,9 Мегабайта удалением контейнера. Но так как мы уже не используем скачанный ранее образ, то он тоже становится кандидатом на удаление и высвобождение наших ресурсов:




$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         1          0          126M       126M (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B




Внимание: до тех пор, пока образ используется хотя бы одним контейнером, вы не сможете использовать этот трюк.




Субкоманда prune, которую мы использовали выше, дает эффект только на остановленных контейнерах. Если мы хотим удалить не только остановленные, но и запущенные контейнеры, следует использовать одну из этих команд:




# Historical command
$ docker rm -f $(docker ps –aq)

# More recent command
$ docker container rm -f $(docker container ls -aq)




Заметки на полях: если при запуске контейнера использовать параметр —rm, то при его остановке будут высвобождено все дисковое пространство, которое он занимал.




Использование диска образами




Несколько лет назад размер образа в несколько сотен мегабайт был совершенно нормальным: образ Ubuntu весил 600 Мегабайт, а образ Microsoft .Net – несколько Гигабайт. В те лохматые времена скачивание одного только образа могло нанести большой урон вашему свободному месту на диске, даже если вы расшаривали уровни между образами. Сегодня – хвала великим – образы весят намного меньше, но даже в этом случае можно быстро забить имеющиеся ресурсы, если не принимать некоторых мер предосторожности.




Есть несколько типов образов, которые напрямую не видны конечному пользователю:







$ docker image ls -f dangling=true
REPOSITORY  TAG      IMAGE ID         CREATED             SIZE
none      none   21e658fe5351     12 minutes ago      71.3MB




Удалить их можно следующим способом:




$ docker image rm $(docker image ls -f dangling=true -q)




Мы можем использовать также субкоманду prune:




$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
deleted: sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
deleted: sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
deleted: sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
deleted: sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f

Total reclaimed space: 12.9kB




Если мы вдруг захотим удалить вообще все образы (а не только dangling) одной командой, то можно сделать так:




$ docker image rm $(docker image ls -q)




Использование диска томами




Тома (volumes) применяются для хранения данных за пределами файловой системы контейнера. Например, если мы хотим сохранить результаты работы какого-либо приложения, чтобы использовать их как-то еще. Частым примером являются базы данных.




Давайте запустим контейнер MongoDB, примонтируем к нему внешний по отношению к контейнеру том, и восстановим из него бэкап базы данных (у нас он доступен в файле bck.json):




# Running a mongo container
$ docker run --name db -v $PWD:/tmp -p 27017:27017 -d mongo:4.0

# Importing an existing backup (from a huge bck.json file)
$ docker exec -ti db mongoimport 
  --db 'test' 
  --collection 'demo' 
  --file /tmp/bck.json 
  --jsonArray




Данные будут находиться на хостовой машине в каталоге /var/lib/docker/volumes. Но почему не на уровне чтения-записи контейнера? Потому что в Dockerfile образа MongoDB каталог /data/db (в котором MongoDB по умолчанию хранит свои данные) определен как том (volume).







Заметки на полях: многие образы, в результате работы которых должны создаваться данные, используют тома (volumes) для сохранения этих самых данных.




Когда мы наиграемся с MongoDB и остановим (а может даже и удалим) контейнер, том не будет удален. Он продолжит занимать наше драгоценное дисковое пространство до тех пор, пока мы явно не удалим его такой командой:




$ docker volume rm $(docker volume ls -q)




Ну или мы можем использовать уже знакомую нам субкоманду prune:




$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da

Total reclaimed space: 25.82GB
luc@saturn:~$




Использование диска для кэша сборки образов




В Docker 18.09 процесс создания образов претерпел некоторые изменения благодаря инструменту BuildKit. С помощью этой штуки увеличивается скорость процесса, оптимизируется управление хранением данных и безопасностью. Здесь мы не будем рассматривать все детали этого замечательного инструмента, остановимся лишь нам том, как он затрагивает вопросы использования дискового пространства.




Предположим, что у нас есть совершенно простое приложение Node.Js:







$ cat index.js
var express = require('express');
var util    = require('util');
var app = express();
app.get('/', function(req, res) {
  res.setHeader('Content-Type', 'text/plain');
  res.end(util.format("%s - %s", new Date(), 'Got Request'));
});
app.listen(process.env.PORT || 80);




$ cat package.json
    {
      "name": "testnode",
      "version": "0.0.1",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "express": "^4.14.0"
      }
    }




Dockerfile для сборки образа выглядит так:




FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]




Давайте соберем образ обычным способом, без использования BuildKit:




$ docker build -t app:1.0 .




Если мы проверим использование дискового пространства, то увидим, что место занимают только базовый образ (node:13-alpine) и конечный образ (app:1.0):




TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         2          0          109.3MB    109.3MB (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    0          0          0B         0B




Давайте соберем вторую версию нашего приложения, уже с использованием BuildKit. Для этого нам лишь необходимо установить переменную DOCKER_BUILDKIT в значение 1:




$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .




Если мы сейчас проверим использование диска, то увидим, что теперь там участвует кэш сборки (buid-cache):




$ docker system df
TYPE           TOTAL      ACTIVE     SIZE       RECLAIMABLE
Images         2          0          109.3MB    109.3MB (100%)
Containers     0          0          0B         0B
Local Volumes  0          0          0B         0B
Build Cache    11         0          8.949kB    8.949kB




Для его очистки воспользуемся следующей командой:




$ docker builder prune
WARNING! This will remove all dangling build cache.
Are you sure you want to continue? [y/N] y
Deleted build cache objects:
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi

Total reclaimed space: 8.949kB




Очистить все!




Итак, мы рассмотрели очистку дискового пространства, занятого контейнерами, образами и томами. В этом нам помогает субкоманда prune. Но ее можно использовать и на системном уровне docker, и она очистит все, что только сможет:




$ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N]




Если вы по каким-либо причинам экономите дисковое пространство на машине с Docker, то периодический запуск этой команды стоит ввести в привычку.




====================================================================




Так как в Docker более менее адекватный механизм удаления старых образов и контейнеров появился в версии 1.13: PR 26108 (за счет параметра prune который удаляет все старые контейнеры volume без контейнеров и образа без контейнеров), но зная что с каждой новой версией кол-во багов и проблем ростет, я лично не рискую обновляться, потому использую такие механизмы:




Удаление всех не используемых images




docker rmi $(docker images --filter "dangling=true" -q --no-trunc)




Удаление контейнеров в статусе “exited




docker rm $(docker ps -qa --no-trunc --filter "status=exited")




Удаление не используемых volume




docker volume ls -qf "dangling=true" | xargs docker volume rm




Все это можно совместить в один алиас для bash окружения:




alias docker-clean=' 
  docker ps --no-trunc -aqf "status=exited" | xargs docker rm ; 
  docker images --no-trunc -aqf "dangling=true" | xargs docker rmi ; 
  docker volume ls -qf "dangling=true" | xargs docker volume rm'




Источник:









Алгоритм топологической сортировки

Алгоритм топологической сортировки работает с DAG (прямой ациклический граф). Смысл топологической сортировки в том, что если какой-либо узел указывает на другой узел, то после него будет идти узел, указывающий на другой узел. Таким образом, в этом случае, если у нас есть циклический граф, мы не можем предсказать, какой узел после какого узла. Вот почему алгоритм топологической сортировки работает только с ациклическим графом, а не с циклическим графом.

Каждый граф имеет более одной топологической последовательности сортировки, поскольку она зависит от степени вхождения ребер узлов. Первый начальный узел, который мы выбираем с числом узлов в степени, равен 0.

Давайте разберемся с алгоритмом топологической сортировки на примере.

Алгоритм топологической сортировки

 

Шаг 1: мы вставляем те узлы, количество входящих ребер которых равно 0. Таким образом, эти узлы являются узлами 1 и 4.

Алгоритм топологической сортировки

 

Шаг 2:

а. Начнем с узла 1. Мы можем выбрать любой узел между узлами 1 и 4.

б. Мы уменьшаем каждое ребро узла на 1, которое связано с узлом 1. Мы уменьшаем ребро узлов (0, 2 и 3).

в. Мы перемещаем узел 1 из списка в топологически отсортированный список, как показано ниже.

Алгоритм топологической сортировки

 

Шаг 3:

а. Теперь мы исходим из списка, который является Node 4.

б. Мы уменьшаем все исходящие ребра узлов, соединенных с узлом 4, которые являются узлами (0 и 3).

в. Теперь узел 3 не имеет входящих ребер, поэтому мы помещаем его в список, а узел 4 переходит в топологически отсортированный список.

Алгоритм топологической сортировки

 

Шаг 4:

а. Теперь мы исходим из списка, который является узлом 3.

б. Мы уменьшаем все исходящие ребра узлов, соединенных с узлом 3, которые являются узлами (0 и 2).

в. Теперь узлы 0 и 2 не имеют входящих ребер, поэтому мы помещаем их в список, а узел 3 переходит в топологически отсортированный список.

Алгоритм топологической сортировки

 

Шаг 5:

а. Теперь мы исходим из списка, который является Node 0.

б. Поскольку исходящих ребер из Node 0 нет, мы просто добавляем их в список топологической сортировки.

Алгоритм топологической сортировки

 

Шаг 6:

а. Теперь мы исходим из списка, который является узлом 2.

б. Поскольку исходящих ребер из узла 2 нет, мы просто добавляем их в список топологической сортировки.

Алгоритм топологической сортировки

 

Шаг 7:

Наконец, мы отсортировали список здесь.

Алгоритм топологической сортировки

 

Алгоритм топологической сортировки

Ниже приведены шаги алгоритма топологической сортировки, которым мы должны следовать.

Шаг 0: Рассчитайте степень вхождения каждого узла графа.

Шаг 1: Сначала нам нужно найти узел, у которого входящие ребра равны нулю.

Шаг 2: мы удаляем этот узел из графа и добавляем его в список топологических порядков сортировки.

Шаг 3: Удалите те узлы, у которых есть исходящие ребра.

Шаг 4: Уменьшите степень вхождения на количество связанных ребер, которые были удалены.

Шаг 5: Повторяйте шаги 1–4, пока не останется узлов с нулевой степенью вхождения.

Шаг 6: Убедитесь, что все элементы расположены в правильной последовательности.

Шаг 7: Теперь мы отсортировали заказ из шага 6.

Шаг 8: Положите конец алгоритму.

 

Код Python : ниже приведена реализация приведенного выше примера на Python.

 

fromcollectionsimportdefaultdict



classbuildGraph :



def__init__(self, nodes : int) :

self.nodes= nodes



# Теперь мы сохраняем граф в формате смежного списка

self.adjListDetails=defaultdict(list)



# Он будет хранить информацию о входящих

ребрах определенного узла 



# в самом

self.count_numbers_of_incoming_edge_of_a_node= []



# Мы сохраняем отсортированные узлы в топологическом порядке

self.topological_sorted_order= []



# Мы храним информацию обо всех тех узлах, которые

# не имеют входящих ребер в графе

self.nodes_have_zero_incoming_edges= []



# Теперь мы создаем смежный список всех графов для сортировки

defAddGraphEdge (self, source :int, destination : int) :

self.adjListDetails[source].append(destination)

self.count_numbers_of_incoming_edge_of_a_node[destination] +=1



defTopologicalSortAlgorithm (self) :



for node inrange(self.nodes) :

ifself.count_numbers_of_incoming_edge_of_a_node[node] ==0 :

self.nodes_have_zero_incoming_edges.append(node)



whileself.nodes_have_zero_incoming_edges :

self.nodes_have_zero_incoming_edges.sort()

            source =self.nodes_have_zero_incoming_edges.pop(0)



# итерация по соседнему списку

if source inself.adjListDetails :

for node inself.adjListDetails[source] :

self.count_numbers_of_incoming_edge_of_a_node[node] -=1

ifself.count_numbers_of_incoming_edge_of_a_node[node] ==0 :

self.nodes_have_zero_incoming_edges.append(node)



self.topological_sorted_order.append(source)



print("Топологический порядок сортировки: "+str(self.topological_sorted_order))



defmain() :



number_of_nodes=7

    graph =buildGraph(number_of_nodes)

graph.count_numbers_of_incoming_edge_of_a_node= [0] *number_of_nodes



graph.AddGraphEdge(0,2)

graph.AddGraphEdge(0,5)

graph.AddGraphEdge(1,3)

graph.AddGraphEdge(1,6)

graph.AddGraphEdge(2,4)

graph.AddGraphEdge(3,5)

graph.AddGraphEdge(5,2)

graph.AddGraphEdge(5,4)

graph.AddGraphEdge(6,2)



graph.TopologicalSortAlgorithm()



if __name__ =="__main__" :

main()

 

 

Выход:

Топологический порядок сортировки: [0, 1, 3, 5, 6, 2, 4]

 

Временная сложность алгоритма топологической сортировки:

Общее время обработки алгоритма равно O (E + N), где E представляет количество ребер, а N представляет количество узлов в графе. Затем, на следующем шаге, мы должны вычислить степень входа каждого узла, что обычно занимает O(E) раз, а затем поместить все эти узлы в отсортированный список, где их степень входа равна нулю, что занимает O(N) раз. раз. Таким образом, общая временная сложность алгоритма топологической сортировки составляет O (E+N).

Но пространственная сложность алгоритма топологической сортировки составляет O (N), что равно общему количеству узлов в графе.

 

Применение:

  1. Топологическая сортировка очень полезна для нахождения цикла графа.
  2. Алгоритм топологической сортировки используется для определения условий взаимоблокировки в операционной системе.
  3. Алгоритм топологической сортировки используется для поиска кратчайшего пути во взвешенном ациклическом графе.

 

Вывод :

В этой статье мы узнали еще об одном важном алгоритме — топологической сортировке. Мы видели, что этот алгоритм работает только с ациклическими графами. Алгоритм топологической сортировки также помогает определить порядок составления задачи. Алгоритм топологической сортировки имеет много преимуществ в реальном времени, например поиск кратчайшего пути. Поскольку топологическая сортировка чрезвычайно полезна, каждый программист и студент должен хорошо понимать этот алгоритм.



2022-03-19T18:03:01
Программирование