Uso di Systemd per gestire i gruppi di controllo

Presenta i concetti sui cgroup in Oracle Linux e mostra come systemd organizza e gestisce il controllo delle risorse.

I gruppi di controllo, definiti cgroups, sono una funzione kernel Oracle Linux che organizza i servizi systemd e, se necessario, i singoli processi (PIDs) in gruppi gerarchici per l'allocazione delle risorse di sistema, ad esempio CPU, memoria e I/O.

Ad esempio, se è necessario dividere la risorsa CPU tra tre servizi systemd, myservice1.service, myservice2.service e myservice3.service, in un rapporto di 150:100:50, è possibile utilizzare gli strumenti systemd per assegnare a ciascun servizio cgroup corrispondente un peso CPU corrispondente alla propria condivisione di destinazione.

Nota

systemd è responsabile della creazione e della gestione di cgroups nel file system virtuale /sys/fs/cgroup/.

La suite systemd offre modalità sicure e di alto livello per configurare le risorse cgroup, come l'utilizzo di file drop-in o il comando systemctl set-property. La modifica diretta degli oggetti systemd nel file system virtuale /sys/fs/cgroup/ non è consigliata.

Per impostazione predefinita, systemd crea un cgroup per i seguenti elementi:

  • Ogni servizio systemd impostato sull'host.

    Ad esempio, un server potrebbe avere il gruppo di controllo NetworkManager.service per raggruppare i processi di proprietà del servizio NetworkManager e il gruppo di controllo firewalld.service per raggruppare i processi di proprietà del servizio firewalld e così via.

  • Ogni utente (UID) sull'host.

La funzionalità cgroup viene attivata come file system virtuale in /sys/fs/cgroup.

Ogni cgroup ha una cartella corrispondente all'interno del file system /sys/fs/cgroup. Ad esempio, il comando cgroups creato da systemd per i servizi che gestisce può essere visualizzato eseguendo il comando ls -l /sys/fs/cgroup/system.slice | grep ".service" come mostrato nel seguente blocco di codice di esempio:

ls -l /sys/fs/cgroup/system.slice | grep ".service"
...root root 0 Mar 22 10:47 atd.service
...root root 0 Mar 22 10:47 auditd.service
...root root 0 Mar 22 10:47 chronyd.service
...root root 0 Mar 22 10:47 crond.service
...root root 0 Mar 22 10:47 dbus-broker.service
...root root 0 Mar 22 10:47 dtprobed.service
...root root 0 Mar 22 10:47 firewalld.service
...root root 0 Mar 22 10:47 httpd.service
...

È inoltre possibile creare cgroups personalizzato al di fuori dei rami systemd, ad esempio in una posizione come /sys/fs/cgroup/MyGroups/, e assegnare ID processo (PIDs) a cgroups diversi in base alle esigenze del sistema. Tuttavia, questo approccio dovrebbe essere utilizzato solo per scenari specifici, come il debug temporaneo o i test. Per la maggior parte dei casi d'uso, si consiglia di utilizzare systemd per configurare cgroups per garantire una gestione delle risorse corretta e persistente.

Oracle Linux fornisce due tipi di gruppi di controllo:

Gruppi di controllo versione 1 (cgroups v1)

Questi gruppi forniscono una gerarchia di controller per risorsa.

Ogni risorsa, ad esempio CPU, memoria, I/O e così via, ha la propria gerarchia di gruppi di controllo. Uno svantaggio di questo gruppo è la difficoltà di stabilire un corretto coordinamento dell'uso delle risorse tra gruppi che potrebbero appartenere a diverse gerarchie di processi.

Gruppi di controllo versione 2 (cgroups v2)

Questi gruppi forniscono un'unica gerarchia di gruppi di controllo su cui vengono eseguiti il MOUNT di tutti i controller delle risorse. In questa gerarchia è possibile ottenere un migliore coordinamento degli usi delle risorse tra diversi controller delle risorse. Questa versione è un miglioramento rispetto a cgroups v1 la cui eccessiva flessibilità ha impedito un corretto coordinamento dell'uso delle risorse tra i consumatori del sistema.

Oracle Linux 8 include entrambe le versioni, con cgroups v1 abilitato e attivato per impostazione predefinita. Oracle Linux 9 fornisce anche entrambe le versioni, ma abilita e installa cgroups v2 per impostazione predefinita.

Oracle Linux 10 offre solo l'implementazione dei gruppi di controllo versione 2. cgroups v1 non è più valido e non è disponibile. cgroups v2 è abilitato e attivato per impostazione predefinita.

Per ulteriori informazioni sui gruppi di controllo, vedere le pagine del manuale cgroups(7) e sysfs(5).

Informazioni sui gruppi di controllo e systemd

I gruppi di controllo possono essere utilizzati dal System Manager systemd e dal Service Manager per la gestione delle risorse. systemd utilizza questi gruppi per organizzare le unità e i servizi che utilizzano risorse. Per maggiori informazioni su systemd, vedere Gestione del sistema con systemd.

systemd fornisce diversi tipi di unità, tre dei quali a scopo di controllo delle risorse:

  • Servizio: processo o gruppo di processi le cui impostazioni si basano su un file di configurazione dell'unità. I servizi comprendono i processi specificati in una "raccolta" in modo che systemd possa avviare o arrestare i processi come un unico set. I nomi dei servizi seguono il formato name.service.

  • Ambito: un gruppo di processi creati esternamente, ad esempio sessioni utente, container, virtual machine e così via.

    Analogamente ai servizi, gli ambiti incapsulano questi processi creati e vengono avviati o arrestati dai processi arbitrari e quindi registrati da systemd in runtime. I nomi degli ambiti seguono il formato name.scope.

  • Slice: gruppo di unità organizzate in modo gerarchico in cui si trovano i servizi e gli ambiti.

    Pertanto, le fette stesse non contengono processi. Piuttosto, gli ambiti e i servizi in una sezione definiscono i processi. Ogni nome di un'unità di slice corrisponde al percorso di una posizione nella gerarchia. Le slice root, in genere user.slice per tutti i processi basati sull'utente e system.slice per i processi basati sul sistema, vengono create automaticamente nella gerarchia. Le slice padre esistono immediatamente sotto la slice root e seguono il formato parent-name.slice. Queste slice root possono quindi avere sotto-slice su più livelli.

Il servizio, l'ambito e le unità di sezione vengono mappati direttamente agli oggetti nella gerarchia dei gruppi di controllo. Quando queste unità vengono attivate, vengono mappate direttamente ai percorsi dei gruppi di controllo creati dai nomi delle unità. Per visualizzare il mapping tra i tipi di unità risorsa systemd e i gruppi di controllo, digitare:

sudo systemd-cgls
Working directory /sys/fs/cgroup:
├─user.slice (#1243)
│ → trusted.invocation_id: 50ce3909b2644f919ee420adc39edb4b
│ ├─user-1001.slice (#4167)
│ │ → trusted.invocation_id: 02e80a960d4549a7a9c69ce0fb546c26
│ │ ├─session-2.scope (#4405)
│ │ │ ├─2417 sshd: alice [priv]
│ │ │ ├─2430 sshd: alice@pts/0
│ │ │ ├─2431 -bash
│ │ │ ├─2689 sudo systemd-cgls
│ │ │ ├─2691 systemd-cgls
│ │ │ └─2692 less
...
│   └─user@984.service … (#3827)
│     → trusted.delegate: 1
│     → trusted.invocation_id: 09b47ce9f3124239b75814114353f3f2
│     └─init.scope (#3861)
│       ├─2058 /usr/lib/systemd/systemd --user
│       └─2099 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
└─system.slice (#53)
...
  ├─chronyd.service (#2467)
  │ → trusted.invocation_id: c0f77aaa9c7844e6bef6a6898ae4dd56
  │ └─1358 /usr/sbin/chronyd -F 2
  ├─auditd.service (#2331)
  │ → trusted.invocation_id: 756808add6a348609316c9e8c1801846
  │ └─1310 /sbin/auditd
  ├─tuned.service (#3079)
  │ → trusted.invocation_id: 2c358135fc46464d862b05550338d4f4
  │ └─1415 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
  ├─systemd-journald.service (#1651)
  │ → trusted.invocation_id: 7cb7ccb14e044a899aadf47bbb583ada
  │ └─977 /usr/lib/systemd/systemd-journald
  ├─atd.service (#3623)
  │ → trusted.invocation_id: 597a7a4e5646468db407801b8562d869
  │ └─1915 /usr/sbin/atd -f
  ├─sshd.service (#3419)
  │ → trusted.invocation_id: 490504a683fc4311ab0fbeb0864a1a34
  │ └─1871 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
...

Per un esempio di utilizzo dei comandi systemd, ad esempio systemctl, per la gestione delle risorse, vedere Controllo dell'accesso alle risorse di sistema. Per ulteriori dettagli tecnici, consultare le pagine del manuale systemctl(1), systemd-cgls(1) e systemd.resource-control(5).

Uso di systemd per gestire cgroups v2

Mostra come systemd strutture cgroups v2 per servizi e utenti e come ispezionare la gerarchia.

Il metodo preferito per gestire l'allocazione delle risorse con cgroups v2 consiste nell'utilizzare la funzionalità del gruppo di controllo fornita da systemd.

Nota

Per informazioni sull'abilitazione della funzionalità cgroups v2 nel sistema, vedere Gestione delle risorse mediante i gruppi di controllo

Per impostazione predefinita, systemd crea una cartella cgroup per ogni servizio systemd impostato sull'host. systemd assegna un nome a queste cartelle utilizzando il formato servicename.service, dove servicename è il nome del servizio associato alla cartella.

Per visualizzare un elenco delle cartelle cgroup create da systemd per i servizi, eseguire il comando ls nel ramo system.slice del file system cgroup come mostrato nel blocco di codice di esempio seguente:

ls /sys/fs/cgroup/system.slice/
...                     ...                           ...
app_service1.service    cgroup.subtree_control        httpd.service
app_service2.service    chronyd.service               ...  
...                     crond.service                 ...
cgroup.controllers      dbus-broker.service           ...
cgroup.events           dtprobed.service              ...
cgroup.freeze           firewalld.service             ...
...                     gssproxy.service              ...
...                     ...                           ...

Nel blocco di comandi precedente:

  • Le cartelle app_service1.service e app_service2.service rappresentano servizi applicativi personalizzati che possono essere eseguiti sul sistema.

Oltre ai gruppi di controllo del servizio, systemd crea anche una cartella cgroup per ogni utente sull'host.

Per visualizzare il file cgroups creato per ciascun utente, è possibile eseguire il comando ls nel ramo user.slice del file system cgroup come mostrato nel seguente blocco di codice di esempio:

ls /sys/fs/cgroup/user.slice/
cgroup.controllers      cgroup.subtree_control        user-1001.slice
cgroup.events           cgroup.threads                user-982.slice
cgroup.freeze           cgroup.type                   ...
...                     ...                           ...
...                     ...                           ...
...                     ...                           ...

Nel blocco di codice precedente:

  • Ogni cartella cgroup utente viene denominata utilizzando il formato user-UID.slice. Pertanto, il gruppo di controllo user-1001.slice si riferisce ad un utente il cui UID è 1001, ad esempio.

systemd fornisce l'accesso di alto livello alle funzioni cgroups e del controller delle risorse del kernel in modo da non dover accedere direttamente al file system.

Ad esempio, per impostare il peso della CPU di un servizio denominato app_service1.service, eseguire il comando systemctl set-property come indicato di seguito.

sudo systemctl set-property app_service1.service CPUWeight=150

Pertanto, systemd consente di gestire la distribuzione delle risorse a livello di applicazione anziché il livello PID del processo utilizzato durante la configurazione di cgroups senza utilizzare la funzionalità systemd.

Informazioni sulle slice e sull'allocazione delle risorse in systemd

Questa sezione esamina il modo in cui systemd divide inizialmente ciascuno dei controller kernel predefiniti, ad esempio CPU, memory e blkio, in porzioni denominate "slice" come illustrato dal seguente grafico a torta di esempio:

Nota

È inoltre possibile creare slice personalizzate per la distribuzione delle risorse, come illustrato nella sezione Impostazione delle opzioni di Resource Controller e creazione di slice personalizzate.

Grafico a torta con 3 fette di dimensioni uguali, etichettate System, Machine e User. Utente e sistema sono ulteriormente suddivisi in sotto-slice.

Come mostra il grafico a torta precedente, per impostazione predefinita ogni controller delle risorse è diviso equamente tra le 3 sezioni seguenti:

  • Sistema (system.slice).

  • Utente (user.slice).

  • Macchina (machine.slice).

L'elenco seguente esamina più da vicino ciascuna slice. Ai fini della discussione, gli esempi nell'elenco si concentrano sul controller CPU.

Sistema (system.slice)

Questa slice di risorsa viene utilizzata per gestire l'allocazione delle risorse tra daemon e unità di servizio.

Come mostrato nel grafico a torta dell'esempio precedente, la slice del sistema è divisa in altre sotto-slice. Ad esempio, nel caso delle risorse della CPU, è possibile che siano presenti allocazioni di sottoslice all'interno della slice del sistema che includono quanto segue:
  • httpd.service (CPUWeight=100)

  • sshd.service (CPUWeight =100)

  • crond.service (CPUWeight =100)

  • app1.service (CPUWeight =100)

  • app2.service (CPUWeight =100)

Nell'elenco precedente, app1.service e app2.service rappresentano i servizi applicativi personalizzati che possono essere eseguiti sul sistema.
Utente (user.slice)
Questa sezione risorsa viene utilizzata per gestire l'allocazione delle risorse tra le sessioni utente. Viene creata una singola slice per ogni UID, indipendentemente dal numero di login che l'utente associato ha attivo sul server. Continuando con l'esempio del grafico a torta, le sezioni secondarie potrebbero essere le seguenti:
  • user1 (CPUWeight=100, UID=982)

  • user2 (CPUWeight=100, UID=1001)

Macchina (machine.slice)
Questa porzione della risorsa viene utilizzata per gestire l'allocazione delle risorse tra macchine virtuali in hosting, come guest KVM e container Linux. La slice del computer è presente su un server solo se il server ospita macchine virtuali o contenitori Linux.
Nota

Le allocazioni di condivisione non impostano un limite massimo per una risorsa.

Negli esempi precedenti la slice user.slice dispone di 2 utenti: user1 e user2. A ogni utente viene allocata una condivisione uguale della risorsa CPU disponibile per l'elemento padre user.slice. Tuttavia, se i processi associati a user1 sono inattivi e non richiedono alcuna risorsa CPU, la relativa condivisione CPU è disponibile per l'allocazione a user2, se necessario. In tal caso, user2 potrebbe anche essere allocata l'intera risorsa CPU ripartita all'elemento padre user.slice se richiesto da altri utenti.

Per limitare la risorsa CPU, è necessario impostare la proprietà CPUQuota sulla percentuale richiesta.

Slice, servizi e ambiti nella gerarchia cgroup

L'analogia del grafico a torta utilizzata nelle sezioni precedenti è un modo utile per concettualizzare la divisione delle risorse in fette. Tuttavia, in termini di organizzazione strutturale, i gruppi di controllo sono disposti in una gerarchia. È possibile visualizzare la gerarchia dei gruppi di controllo systemd nel sistema eseguendo il comando systemd-cgls come indicato di seguito.

Suggerimento

Per visualizzare l'intera struttura gerarchica cgroup, a partire dalla slice root -.slice, come nell'esempio seguente, assicurarsi di eseguire systemd-cgls dall'esterno del punto di attivazione del gruppo di controllo /sys/fs/cgroup/.

Altrimenti, se si esegue il comando dall'interno di /sys/fs/cgroup/, l'output inizia dalla posizione cgroup da cui è stato eseguito il comando. Per ulteriori informazioni, vedere systemd-cgls(1).

systemd-cgls
Control group /:
-.slice
...
├─user.slice (#1429)
│ → user.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
│ ├─user-982.slice (#4131)
│ │ → user.invocation_id: 9d0d94d7b8a54bcea2498048911136c8
│ │ ├─session-c1.scope (#4437)
│ │ │ ├─2416 /usr/bin/sudo -u ocarun /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
│ │ │ └─2494 /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
│ │ └─user@982.service … (#4199)
│ │   → user.delegate: 1
│ │   → user.invocation_id: 37c7aed7aa6e4874980b79616acf0c82
│ │   └─init.scope (#4233)
│ │     ├─2437 /usr/lib/systemd/systemd --user
│ │     └─2445 (sd-pam)
│ └─user-1001.slice (#7225)
│   → user.invocation_id: ce93ad5f5299407e9477964494df63b7
│   ├─session-2.scope (#7463)
│   │ ├─20304 sshd: oracle [priv]
│   │ ├─20404 sshd: oracle@pts/0
│   │ ├─20405 -bash
│   │ ├─20441 systemd-cgls
│   │ └─20442 less
│   └─user@1001.service … (#7293)
│     → user.delegate: 1
│     → user.invocation_id: 70284db060c1476db5f3633e5fda7fba
│     └─init.scope (#7327)
│       ├─20395 /usr/lib/systemd/systemd --user
│       └─20397 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 28
└─system.slice (#53)
 ...
  ├─dbus-broker.service (#2737)
  │ → user.invocation_id: 2bbe054a2c4d49809b16cb9c6552d5a6
  │ ├─1450 /usr/bin/dbus-broker-launch --scope system --audit
  │ └─1457 dbus-broker --log 4 --controller 9 --machine-id 852951209c274cfea35a953ad2964622 --max-bytes 536870912 --max-fds 4096 --max-matches 131072 --audit
 ...
  ├─chronyd.service (#2805)
  │ → user.invocation_id: e264f67ad6114ad5afbe7929142faa4b
  │ └─1482 /usr/sbin/chronyd -F 2
  ├─auditd.service (#2601)
  │ → user.invocation_id: f7a8286921734949b73849b4642e3277
  │ ├─1421 /sbin/auditd
  │ └─1423 /usr/sbin/sedispatch
  ├─tuned.service (#3349)
  │ → user.invocation_id: fec7f73678754ed687e3910017886c5e
  │ └─1564 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
  ├─systemd-journald.service (#1837)
  │ → user.invocation_id: bf7fb22ba12f44afab3054aab661aedb
  │ └─1068 /usr/lib/systemd/systemd-journald
  ├─atd.service (#3961)
  │ → user.invocation_id: 1c59679265ab492482bfdc9c02f5eec5
  │ └─2146 /usr/sbin/atd -f
  ├─sshd.service (#3757)
  │ → user.invocation_id: 57e195491341431298db233e998fb180
  │ └─2097 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
  ├─crond.service (#3995)
  │ → user.invocation_id: 4f5b380a53db4de5adcf23f35d638ff5
  │ └─2150 /usr/sbin/crond -n
  ...

L'output dell'esempio precedente mostra come risiedono tutti i gruppi di controllo "*.slice" nella slice root -.slice. Sotto la slice root è possibile vedere i gruppi di controllo user.slice e system.slice, ognuno con le proprie slice secondarie cgroup figlio.

Esaminando l'output del comando systemd-cgls è possibile vedere come, ad eccezione di root -.slice, tutti i processi si trovano sui nodi foglia. Questa disposizione viene applicata da cgroups v2, in una regola denominata "nessun processo interno". Per ulteriori informazioni sulla regola "nessun processo interno", vedere cgroups (7).

L'output nell'esempio di comando systemd-cgls precedente mostra anche come le slice possono avere gruppi di controllo figlio discendenti che sono ambiti systemd. Gli ambiti systemd vengono rivisti nella sezione seguente.

ambiti di sistema

L'ambito systemd è un tipo di unità systemd che raggruppa i processi del service worker di sistema avviati indipendentemente da systemd. Le unità di scope sono transitorie cgroups create a livello di programmazione utilizzando le interfacce bus di systemd.

Ad esempio, nel seguente codice di esempio, l'utente con UID 1001 ha eseguito il comando systemd-cgls e l'output mostra che session-2.scope è stato creato per i processi generati dall'utente indipendentemente da systemd (incluso il processo per il comando stesso, 21380 sudo systemd-cgls):

Nota

Nell'esempio seguente, il comando è stato eseguito dall'interno del punto di attivazione del gruppo di controllo /sys/fs/cgroup/. Quindi, al posto della slice root, l'output inizia dalla posizione cgroup da cui è stato eseguito il comando.
sudo systemd-cgls
Working directory /sys/fs/cgroup:
...
├─user.slice (#1429)
│ → user.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
│ → trusted.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
...
│ └─user-1001.slice (#7225)
│   → user.invocation_id: ce93ad5f5299407e9477964494df63b7
│   → trusted.invocation_id: ce93ad5f5299407e9477964494df63b7
│   ├─session-2.scope (#7463)
│   │ ├─20304 sshd: oracle [priv]
│   │ ├─20404 sshd: oracle@pts/0
│   │ ├─20405 -bash
│   │ ├─21380 sudo systemd-cgls
│   │ ├─21382 systemd-cgls
│   │ └─21383 less
│   └─user@1001.service … (#7293)
│     → user.delegate: 1
│     → trusted.delegate: 1
│     → user.invocation_id: 70284db060c1476db5f3633e5fda7fba
│     → trusted.invocation_id: 70284db060c1476db5f3633e5fda7fba
│     └─init.scope (#7327)
│       ├─20395 /usr/lib/systemd/systemd --user
│       └─20397 (sd-pam)

Impostazione delle opzioni di Resource Controller e creazione di slice personalizzate

Dimostra tre approcci (unit file, drop-in e systemctl set-property) per perfezionare i controller delle risorse e i layout delle slice.

systemd fornisce i seguenti metodi per l'impostazione delle opzioni del controller delle risorse, ad esempio CPUWeight, CPUQuota e così via, per personalizzare l'allocazione delle risorse nel sistema:

  • Uso dei file delle unità di servizio.

  • Utilizzo di file drop-in.

  • Uso del comando systemctl set-property.

Le sezioni seguenti forniscono esempi di procedure per l'uso di ciascuno di questi metodi per configurare risorse e slice nel sistema.

Uso dei file delle unità di servizio

Per impostare le opzioni in un file di unità di servizio, effettuare le operazioni riportate di seguito.

  1. Creare il file /etc/systemd/system/myservice1.service con il contenuto seguente:
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
  2. Il servizio creato nel passo precedente richiede uno script bash /usr/lib/systemd/generate_load.sh. Creare il file con il seguente contenuto:
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  3. Rendere eseguibile lo script:
    sudo chmod +x /usr/lib/systemd/generate_load.sh
  4. Abilita e avvia il servizio:
    sudo systemctl enable myservice1 --now
  5. Eseguire il comando systemd-cgls e confermare che il servizio myservice1 è in esecuzione in system.slice:
    systemd-cgls
    Control group /:
    -.slice
    ...
    ├─user.slice (#1429)
    ...
    └─system.slice (#53)
      ...
      ├─myservice1.service (#7939)
      │ → user.invocation_id: e227f8f288444fed92a976d391e6a897
      │ ├─22325 /bin/bash /usr/lib/systemd/generate_load.sh
      │ ├─22326 /bin/bash /usr/lib/systemd/generate_load.sh
      │ ├─22327 /bin/bash /usr/lib/systemd/generate_load.sh
      │ └─22328 /bin/bash /usr/lib/systemd/generate_load.sh
      ├─pmie.service (#4369)
      │ → user.invocation_id: 68fcd40071594481936edf0f1d7a8e12
       ...
  6. Creare una slice personalizzata per il servizio.

    Aggiungere la riga Slice=my_custom_slice.slice alla sezione [Service] nel file myservice1.service, creato in un passo precedente, come mostrato nel blocco di codice seguente:

    [Service]
    Slice=my_custom_slice.slice
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
    
    Attenzione

    Usare i caratteri di sottolineatura anziché i trattini per separare i termini nei nomi delle slice.

    In systemd, un trattino nel nome di una slice è un carattere speciale: in systemd, i trattini nei nomi delle slice vengono utilizzati per descrivere il percorso completo cgroup della slice (a partire dalla slice root).

    Ad esempio, se si specifica il nome di una slice come "my-custom-slice.slice", anziché crearne una, systemd crea il percorso cgroups seguente sotto la slice root: my.slice/my-custom.slice/my-custom-slice.slice.

  7. Dopo aver modificato il file, assicurarsi che systemd ricarichi i file di configurazione e quindi riavviare il servizio:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
  8. Eseguire il comando systemd-cgls e confermare che il servizio myservice1 è ora in esecuzione nella slice personalizzata my_custom_slice:
    systemd-cgls
    Control group /:
    -.slice
    ...
    ├─user.slice (#1429)
    ...
    ├─my_custom_slice.slice (#7973)
    │ → user.invocation_id: a8a493a8db1342be85e2cdf1e80255f8
    │ └─myservice1.service (#8007)
    │   → user.invocation_id: 9a4a6171f2844e479d4a0f347aac38ce
    │   ├─22385 /bin/bash /usr/lib/systemd/generate_load.sh
    │   ├─22386 /bin/bash /usr/lib/systemd/generate_load.sh
    │   ├─22387 /bin/bash /usr/lib/systemd/generate_load.sh
    │   └─22388 /bin/bash /usr/lib/systemd/generate_load.sh
    ├─init.scope (#19)
    │ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 28
    └─system.slice (#53)
      ├─irqbalance.service (#2907)
      │ → user.invocation_id: 00d64c9b9d224f179496a83536dd60bb
      │ └─1464 /usr/sbin/irqbalance --foreground
     ...
    

Uso dei file drop-in

Per utilizzare un file drop-in per configurare le risorse, effettuare le operazioni riportate di seguito.

  1. Creare la directory per il file di rilascio del servizio.
    Suggerimento

    La directory "drop-in" per i file drop-in per un servizio si trova in /etc/systemd/system/service_name.service.d, dove service_name è il nome del servizio.

    Continuando con il nostro esempio con il servizio myservice1, eseguiremo il seguente comando:

    sudo mkdir -p /etc/systemd/system/myservice1.service.d/
  2. Creare 2 file drop-in denominati 00-slice.conf e 10-CPUSettings.conf nella directory myservice1.service.d creata nel passo precedente.
    Nota

    • Più file drop-in con nomi diversi vengono applicati in ordine lexicografico.

    • Questi file drop-in hanno la precedenza sul file dell'unità di servizio.

  3. Aggiungere i seguenti contenuti a 00-slice.conf
    [Service]
    Slice=my_custom_slice2.slice
    MemoryAccounting=yes
    CPUAccounting=yes
    

    L'impostazione della slice Slice=my_custom_slice2.slice nel file di rilascio ha la precedenza sulla voce Slice=my_custom_slice.slice aggiunta al file dell'unità di servizio in un passo precedente.

  4. E aggiungere i seguenti contenuti a 10-CPUSettings.conf
    [Service]
    CPUWeight=200
    
  5. Creare un secondo servizio (myservice2) e assegnargli un CPUWeight diverso da quello assegnato a myservice1:
    1. Creare il file /etc/systemd/system/myservice2.service con i seguenti contenuti:
      [Service]
      Slice=my_custom_slice2.slice
      Type=oneshot
      ExecStart=/usr/lib/systemd/generate_load2.sh
      TimeoutSec=0
      StandardOutput=tty
      RemainAfterExit=yes
      
      [Install]
      WantedBy=multi-user.target
    2. Il servizio creato nel passo precedente richiede uno script bash /usr/lib/systemd/generate_load2.sh. Creare il file con il seguente contenuto:
      #!/bin/bash
      for i in {1..4};do while : ; do : ; done & done
    3. Rendere eseguibile lo script:
      sudo chmod +x /usr/lib/systemd/generate_load2.sh
    4. Creare un drop in file /etc/systemd/system/myservice2.service.d/10-CPUSettings.conf per myservice2 con i seguenti contenuti:
      [Service]
      CPUWeight=400
      
  6. Assicurarsi che systemd ricarichi i propri file di configurazione, riavvii myservice1, abiliti e avvii anche myservices2:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl enable myservice2 --now
  7. Eseguire il comando systemd-cgtop per visualizzare i gruppi di controllo ordinati in base all'uso delle risorse. Nell'output di esempio seguente è possibile vedere come, oltre all'uso delle risorse di ogni slice, il comando systemd-cgtop visualizza l'uso delle risorse all'interno di ogni slice, in modo da poterlo utilizzare per confermare che il peso della CPU è stato diviso come previsto.
    systemd-cgtop
    Control Group                                     Tasks   %CPU   Memory  Input/s Output/s
    /                                                   228  198.8   712.5M        -        -
    my_custom_slice2.slice                                8  198.5     1.8M        -        -
    my_custom_slice2.slice/myservice2.service             4  132.8   944.0K        -        -
    my_custom_slice2.slice/myservice1.service             4   65.6   976.0K        -        -
    user.slice                                           18    0.9    43.9M        -        -
    user.slice/user-1001.slice                            6    0.9    13.7M        -        -
    user.slice/user-1001.slice/session-2.scope            4    0.9     9.4M        -        -
    system.slice                                         60    0.0   690.8M        -        -
    

Uso di systemctl set-property

Il comando systemctl set-property posiziona i file di configurazione nella seguente posizione:

/etc/systemd/system.control
Attenzione

Non è necessario modificare manualmente i file creati dal comando set-property systemctl.

Nota

Il comando systemctl set-property non riconosce tutte le proprietà resource-control utilizzate nei file system-unit e drop-in trattati in precedenza in questo argomento.

La procedura riportata di seguito mostra come utilizzare il comando systemctl set-property per configurare l'allocazione delle risorse.

  1. Continuando con il nostro esempio, creare un altro file di servizio nella posizione /etc/systemd/system/myservice3.service con il seguente contenuto:
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load3.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    [Install]
    WantedBy=multi-user.target
  2. Impostare la slice del servizio su my_custom_slice2 (la stessa slice utilizzata dai servizi creati ai passi precedenti) aggiungendo la riga seguente alla sezione [Service] nel file myservice3.service:
    Slice=my_custom_slice2.slice
    Nota

    La slice deve essere impostata nel file service-unit perché il comando systemctl set-property non riconosce la proprietà Slice.

  3. Il servizio creato nel passo precedente richiede uno script bash /usr/lib/systemd/generate_load3.sh. Creare il file con il seguente contenuto:
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  4. Rendere eseguibile lo script:
    sudo chmod +x /usr/lib/systemd/generate_load3.sh
  5. Assicurarsi che systemd ricarichi i file di configurazione, quindi abilitare e avviare il servizio:
    sudo systemctl daemon-reload
    sudo systemctl enable myservice3 --now
  6. Eseguire systemd-cgtop per confermare che tutti i 3 servizi, myservice1, myservice2 e myservice3, sono tutti in esecuzione nella stessa slice.
  7. Utilizzare il comando systemctl set-property per impostare CPUWeight per myservice3 su 800:
    sudo systemctl set-property myservice3.service CPUWeight=800
  8. Confermare la creazione automatica di un file drop-in in /etc/systemd/system.control/myservice3.service.d. Non è tuttavia necessario modificare il file:
    cat /etc/systemd/system.control/myservice3.service.d/50-CPUWeight.conf
    # This is a drop-in unit file extension, created via "systemctl set-property"
    # or an equivalent operation. Do not edit.
    [Service]
    CPUWeight=800
    
  9. Assicurarsi che systemd ricarichi i file di configurazione e riavviare tutti i servizi:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl restart myservice2
    sudo systemctl restart myservice3
  10. Eseguire il comando systemd-cgtop per verificare che il peso della CPU sia stato diviso come previsto:
    systemd-cgtop
    Control Group                                         Tasks   %CPU   Memory  Input/s Output/s
    /                                                       235  200.0   706.1M        -        -
    my_custom_slice2.slice                                   12  198.4     2.9M        -        -
    my_custom_slice2.slice/myservice3.service                 4  112.7   976.0K        -        -
    my_custom_slice2.slice/myservice2.service                 4   56.9   996.0K        -        -
    my_custom_slice2.slice/myservice1.service                 4   28.8   988.0K        -        -
    user.slice                                               18    0.9    44.1M        -        -
    user.slice/user-1001.slice                                6    0.9    13.9M        -        -
    user.slice/user-1001.slice/session-2.scope                4    0.9     9.5M        -        -