RHEL 8 Gweithdy Beta: Adeiladu Cymwysiadau Gwe Gweithio

Mae RHEL 8 Beta yn cynnig llawer o nodweddion newydd i ddatblygwyr, a gallai eu rhestru gymryd tudalennau, fodd bynnag, mae dysgu pethau newydd bob amser yn well yn ymarferol, felly isod rydym yn cynnig gweithdy ar greu seilwaith cais mewn gwirionedd yn seiliedig ar Red Hat Enterprise Linux 8 Beta.

RHEL 8 Gweithdy Beta: Adeiladu Cymwysiadau Gwe Gweithio

Gadewch i ni gymryd Python, iaith raglennu boblogaidd ymhlith datblygwyr, fel sail, cyfuniad o Django a PostgreSQL, cyfuniad eithaf cyffredin ar gyfer creu cymwysiadau, a ffurfweddu RHEL 8 Beta i weithio gyda nhw. Yna byddwn yn ychwanegu cwpl mwy o gynhwysion (annosbarthedig).

Bydd yr amgylchedd prawf yn newid, oherwydd mae'n ddiddorol archwilio posibiliadau awtomeiddio, gweithio gyda chynwysyddion a rhoi cynnig ar amgylcheddau gyda gweinyddwyr lluosog. I ddechrau gyda phrosiect newydd, gallwch ddechrau trwy greu prototeip bach, syml â llaw fel y gallwch weld yn union beth sydd angen digwydd a sut mae'n rhyngweithio, ac yna symud ymlaen i awtomeiddio a chreu ffurfweddiadau mwy cymhleth. Heddiw rydym yn sôn am greu prototeip o'r fath.

Gadewch i ni ddechrau trwy ddefnyddio delwedd RHEL 8 Beta VM. Gallwch osod peiriant rhithwir o'r dechrau, neu ddefnyddio'r ddelwedd westai KVM sydd ar gael gyda'ch tanysgrifiad Beta. Wrth ddefnyddio delwedd westai, bydd angen i chi ffurfweddu CD rhithwir a fydd yn cynnwys metadata a data defnyddwyr ar gyfer cychwyn cwmwl (cloud-init). Nid oes angen i chi wneud unrhyw beth arbennig gyda strwythur y ddisg na'r pecynnau sydd ar gael; bydd unrhyw ffurfweddiad yn gwneud hynny.

Gadewch i ni edrych yn agosach ar y broses gyfan.

Gosod Django

Gyda'r fersiwn diweddaraf o Django, bydd angen amgylchedd rhithwir (rhithwir) arnoch chi gyda Python 3.5 neu'n hwyrach. Yn y nodiadau Beta gallwch weld bod Python 3.6 ar gael, gadewch i ni wirio a yw hyn yn wir:

[cloud-user@8beta1 ~]$ python
-bash: python: command not found
[cloud-user@8beta1 ~]$ python3
-bash: python3: command not found

Mae Red Hat yn defnyddio Python yn weithredol fel pecyn cymorth system yn RHEL, felly pam mae hyn yn ganlyniad?

Y ffaith yw bod llawer o ddatblygwyr Python yn dal i ystyried y newid o Python 2 i Python 2, tra bod Python 3 ei hun yn cael ei ddatblygu'n weithredol, ac mae mwy a mwy o fersiynau newydd yn ymddangos yn gyson. Felly, i gwrdd â'r angen am offer system sefydlog wrth gynnig mynediad i ddefnyddwyr i wahanol fersiynau newydd o Python, symudwyd system Python i becyn newydd a darparodd y gallu i osod Python 2.7 a 3.6. Ceir rhagor o wybodaeth am y newidiadau a pham y cawsant eu gwneud yn y cyhoeddiad yn Blog Langdon White (Gwyn Langdon).

Felly, i ddechrau gweithio Python, dim ond dau becyn sydd angen i chi eu gosod, gyda python3-pip wedi'u cynnwys fel dibyniaeth.

sudo yum install python36 python3-virtualenv

Beth am ddefnyddio galwadau modiwl uniongyrchol fel mae Langdon yn ei awgrymu a gosod pip3? Gan gadw'r awtomeiddio sydd i ddod mewn cof, mae'n hysbys y bydd Ansible angen gosod pip i redeg, gan nad yw'r modiwl pip yn cefnogi virtualenvs gyda gweithredadwy pip arferol.

Gyda dehonglydd python3 gweithio ar gael ichi, gallwch barhau â'r broses osod Django a chael system weithio ynghyd â'n cydrannau eraill. Mae yna lawer o opsiynau gweithredu ar gael ar y Rhyngrwyd. Mae un fersiwn yn cael ei chyflwyno yma, ond gall defnyddwyr ddefnyddio eu prosesau eu hunain.

Byddwn yn gosod y fersiynau PostgreSQL a Nginx sydd ar gael yn RHEL 8 yn ddiofyn gan ddefnyddio Yum.

sudo yum install nginx postgresql-server

Bydd angen psycopg2 ar PostgreSQL, ond mae angen iddo fod ar gael mewn amgylchedd virtualenv yn unig, felly byddwn yn ei osod gan ddefnyddio pip3 ynghyd â Django a Gunicorn. Ond yn gyntaf mae angen i ni sefydlu virtualenv.

Mae yna lawer o ddadlau bob amser ar y pwnc o ddewis y lle iawn i osod prosiectau Django, ond pan fyddwch chi'n ansicr, gallwch chi bob amser droi at Safon Hierarchaeth Linux Filesystem. Yn benodol, mae'r FHS yn dweud bod / srv yn cael ei ddefnyddio i: “storio data gwesteiwr-benodol - data y mae'r system yn ei gynhyrchu, megis data gweinydd gwe a sgriptiau, data sy'n cael ei storio ar weinyddion FTP, a storfeydd system reoli.” fersiynau (yn ymddangos yn FHS -2.3 yn 2004)."

Dyma'n union achos ni, felly rydyn ni'n rhoi popeth sydd ei angen arnom yn / srv, sy'n eiddo i ddefnyddiwr ein rhaglen (defnyddiwr cwmwl).

sudo mkdir /srv/djangoapp
sudo chown cloud-user:cloud-user /srv/djangoapp
cd /srv/djangoapp
virtualenv django
source django/bin/activate
pip3 install django gunicorn psycopg2
./django-admin startproject djangoapp /srv/djangoapp

Mae sefydlu PostgreSQL a Django yn hawdd: creu cronfa ddata, creu defnyddiwr, ffurfweddu caniatâd. Un peth i'w gadw mewn cof wrth osod PostgreSQL i ddechrau yw'r sgript gosod postgresql sydd wedi'i osod gyda'r pecyn postgresql-server. Mae'r sgript hon yn eich helpu i gyflawni tasgau sylfaenol sy'n gysylltiedig â gweinyddu clwstwr cronfa ddata, megis cychwyn clwstwr neu'r broses uwchraddio. I ffurfweddu enghraifft PostgreSQL newydd ar system RHEL, mae angen i ni redeg y gorchymyn:

sudo /usr/bin/postgresql-setup -initdb

Yna gallwch chi ddechrau PostgreSQL gan ddefnyddio systemd, creu cronfa ddata, a sefydlu prosiect yn Django. Cofiwch ailgychwyn PostgreSQL ar ôl gwneud newidiadau i ffeil ffurfweddu dilysu'r cleient (pg_hba.conf fel arfer) i ffurfweddu storfa cyfrinair ar gyfer defnyddiwr y cais. Os byddwch chi'n dod ar draws anawsterau eraill, gwnewch yn siŵr eich bod chi'n newid y gosodiadau IPv4 a IPv6 yn y ffeil pg_hba.conf.

systemctl enable -now postgresql

sudo -u postgres psql
postgres=# create database djangoapp;
postgres=# create user djangouser with password 'qwer4321';
postgres=# alter role djangouser set client_encoding to 'utf8';
postgres=# alter role djangouser set default_transaction_isolation to 'read committed';
postgres=# alter role djangouser set timezone to 'utc';
postgres=# grant all on DATABASE djangoapp to djangouser;
postgres=# q

Yn y ffeil /var/lib/pgsql/data/pg_hba.conf:

# IPv4 local connections:
host    all        all 0.0.0.0/0                md5
# IPv6 local connections:
host    all        all ::1/128                 md5

Yn y ffeil /srv/djangoapp/settings.py:

# Database
DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql_psycopg2',
       'NAME': '{{ db_name }}',
       'USER': '{{ db_user }}',
       'PASSWORD': '{{ db_password }}',
       'HOST': '{{ db_host }}',
   }
}

Ar ôl ffurfweddu'r ffeil settings.py yn y prosiect a sefydlu cyfluniad y gronfa ddata, gallwch chi gychwyn y gweinydd datblygu i sicrhau bod popeth yn gweithio. Ar ôl dechrau'r gweinydd datblygu, mae'n syniad da creu defnyddiwr gweinyddol er mwyn profi'r cysylltiad â'r gronfa ddata.

./manage.py runserver 0.0.0.0:8000
./manage.py createsuperuser

WSGI? Wai?

Mae'r gweinydd datblygu yn ddefnyddiol ar gyfer profi, ond i redeg y rhaglen mae'n rhaid i chi ffurfweddu'r gweinydd a'r dirprwy priodol ar gyfer Rhyngwyneb Porth Gweinydd Gwe (WSGI). Mae yna sawl cyfuniad cyffredin, er enghraifft, Apache HTTPD gyda uWSGI neu Nginx gyda Gunicorn.

Gwaith Rhyngwyneb Porth Gweinydd Gwe yw anfon ceisiadau o'r gweinydd gwe i fframwaith gwe Python. Mae WSGI yn grair o'r gorffennol ofnadwy pan oedd peiriannau CGI o gwmpas, a heddiw WSGI yw'r safon de facto, waeth beth fo'r gweinydd gwe neu'r fframwaith Python a ddefnyddir. Ond er gwaethaf ei ddefnydd eang, mae yna lawer o arlliwiau o hyd wrth weithio gyda'r fframweithiau hyn, a llawer o ddewisiadau. Yn yr achos hwn, byddwn yn ceisio sefydlu rhyngweithio rhwng Gunicorn a Nginx trwy soced.

Gan fod y ddau gydran hyn wedi'u gosod ar yr un gweinydd, gadewch i ni geisio defnyddio soced UNIX yn lle soced rhwydwaith. Gan fod cyfathrebu yn gofyn am soced beth bynnag, gadewch i ni geisio cymryd un cam arall a ffurfweddu actifadu soced ar gyfer Gunicorn trwy systemd.

Mae'r broses o greu gwasanaethau wedi'u hysgogi â soced yn eithaf syml. Yn gyntaf, mae ffeil uned yn cael ei chreu sy'n cynnwys cyfarwyddeb ListenStream sy'n pwyntio at y pwynt y bydd y soced UNIX yn cael ei greu, yna ffeil uned ar gyfer y gwasanaeth lle bydd y gyfarwyddeb Gofynion yn pwyntio at y ffeil uned soced. Yna, yn y ffeil uned gwasanaeth, y cyfan sy'n weddill yw galw Gunicorn o'r amgylchedd rhithwir a chreu rhwymiad WSGI ar gyfer soced UNIX a chymhwysiad Django.

Dyma rai enghreifftiau o ffeiliau uned y gallwch eu defnyddio fel sail. Yn gyntaf rydym yn gosod y soced.

[Unit]
Description=Gunicorn WSGI socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Nawr mae angen i chi ffurfweddu'r daemon Gunicorn.

[Unit]
Description=Gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=cloud-user
Group=cloud-user
WorkingDirectory=/srv/djangoapp

ExecStart=/srv/djangoapp/django/bin/gunicorn 
         —access-logfile - 
         —workers 3 
         —bind unix:gunicorn.sock djangoapp.wsgi

[Install]
WantedBy=multi-user.target

Ar gyfer Nginx, mae'n fater syml o greu ffeiliau cyfluniad dirprwy a sefydlu cyfeiriadur i storio cynnwys statig os ydych chi'n defnyddio un. Yn RHEL, mae ffeiliau cyfluniad Nginx wedi'u lleoli yn /etc/nginx/conf.d. Gallwch gopïo'r enghraifft ganlynol i'r ffeil /etc/nginx/conf.d/default.conf a chychwyn y gwasanaeth. Gwnewch yn siŵr eich bod chi'n gosod yr enw gweinydd_ i gyd-fynd â'ch enw gwesteiwr.

server {
   listen 80;
   server_name 8beta1.example.com;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /srv/djangoapp;
   }

   location / {
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_pass http://unix:/run/gunicorn.sock;
   }
}

Dechreuwch y soced Gunicorn a Nginx gan ddefnyddio systemd ac rydych chi'n barod i ddechrau profi.

Gwall Porth Drwg?

Os rhowch y cyfeiriad yn eich porwr, mae'n debyg y byddwch chi'n derbyn gwall 502 Bad Gateway. Gall gael ei achosi gan ganiatâd soced UNIX sydd wedi'i ffurfweddu'n anghywir, neu gall fod oherwydd materion mwy cymhleth yn ymwneud â rheoli mynediad yn SELinux.

Yn y log gwall nginx gallwch weld llinell fel hyn:

2018/12/18 15:38:03 [crit] 12734#0: *3 connect() to unix:/run/gunicorn.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.122.1, server: 8beta1.example.com, request: "GET / HTTP/1.1", upstream: "http://unix:/run/gunicorn.sock:/", host: "8beta1.example.com"

Os byddwn yn profi Gunicorn yn uniongyrchol, byddwn yn cael ateb gwag.

curl —unix-socket /run/gunicorn.sock 8beta1.example.com

Gadewch i ni ddarganfod pam mae hyn yn digwydd. Os byddwch chi'n agor y log, mae'n debyg y byddwch chi'n gweld bod y broblem yn gysylltiedig â SELinux. Gan ein bod yn rhedeg daemon nad oes polisi wedi'i greu ar ei gyfer, mae wedi'i nodi fel init_t. Gadewch i ni brofi'r ddamcaniaeth hon yn ymarferol.

sudo setenforce 0

Gall hyn i gyd achosi beirniadaeth a dagrau o waed, ond dim ond dadfygio'r prototeip yw hyn. Gadewch i ni analluogi'r siec dim ond i wneud yn siŵr mai dyma'r broblem, ac ar ôl hynny byddwn yn dychwelyd popeth yn ôl i'w le.

Trwy adnewyddu'r dudalen yn y porwr neu ail-redeg ein gorchymyn cyrl, gallwch weld tudalen prawf Django.

Felly, ar ôl gwneud yn siŵr bod popeth yn gweithio ac nad oes mwy o broblemau caniatâd, rydym yn galluogi SELinux eto.

sudo setenforce 1

Ni fyddaf yn siarad am audit2allow na chreu polisïau sy'n seiliedig ar rybudd gyda sepolgen yma, gan nad oes unrhyw gais Django mewn gwirionedd ar hyn o bryd, felly nid oes map cyflawn o'r hyn y gallai Gunicorn fod eisiau ei gyrchu a'r hyn y dylai wrthod mynediad iddo. Felly, mae angen cadw SELinux yn rhedeg i amddiffyn y system, tra ar yr un pryd yn caniatáu i'r cais redeg a gadael negeseuon yn y log archwilio fel y gellir creu'r polisi gwirioneddol oddi wrthynt.

Pennu parthau caniataol

Nid yw pawb wedi clywed am barthau a ganiateir yn SELinux, ond nid ydynt yn ddim byd newydd. Roedd llawer hyd yn oed yn gweithio gyda nhw heb hyd yn oed sylweddoli hynny. Pan grëir polisi yn seiliedig ar negeseuon archwilio, mae'r polisi a grëwyd yn cynrychioli'r parth a ddatryswyd. Gadewch i ni geisio creu polisi trwyddedu syml.

I greu parth penodol a ganiateir ar gyfer Gunicorn, mae angen rhyw fath o bolisi arnoch chi, ac mae angen i chi hefyd farcio'r ffeiliau priodol. Yn ogystal, mae angen offer i lunio polisïau newydd.

sudo yum install selinux-policy-devel

Mae'r mecanwaith parthau a ganiateir yn arf gwych ar gyfer nodi problemau, yn enwedig o ran cymhwysiad arferol neu gymwysiadau sy'n llongio heb bolisïau a grëwyd eisoes. Yn yr achos hwn, bydd y polisi parth a ganiateir ar gyfer Gunicorn mor syml â phosibl - datgan prif fath (gunicorn_t), datgan math y byddwn yn ei ddefnyddio i farcio gweithredadwy lluosog (gunicorn_exec_t), ac yna sefydlu trosglwyddiad ar gyfer system i farcio'n gywir prosesau rhedeg. Mae'r llinell olaf yn gosod y polisi wedi'i alluogi yn ddiofyn ar yr adeg y caiff ei lwytho.

gunicorn.te:

policy_module(gunicorn, 1.0)

type gunicorn_t;
type gunicorn_exec_t;
init_daemon_domain(gunicorn_t, gunicorn_exec_t)
permissive gunicorn_t;

Gallwch chi lunio'r ffeil bolisi hon a'i hychwanegu at eich system.

make -f /usr/share/selinux/devel/Makefile
sudo semodule -i gunicorn.pp

sudo semanage permissive -a gunicorn_t
sudo semodule -l | grep permissive

Gadewch i ni wirio i weld a yw SELinux yn rhwystro rhywbeth arall heblaw'r hyn y mae ein daemon anhysbys yn ei gyrchu.

sudo ausearch -m AVC

type=AVC msg=audit(1545315977.237:1273): avc:  denied { write } for pid=19400 comm="nginx" name="gunicorn.sock" dev="tmpfs" ino=52977 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_run_t:s0 tclass=sock_file permissive=0

Mae SELinux yn atal Nginx rhag ysgrifennu data i'r soced UNIX a ddefnyddir gan Gunicorn. Yn nodweddiadol, mewn achosion o'r fath, mae polisïau'n dechrau newid, ond mae heriau eraill o'n blaenau. Gallwch hefyd newid y gosodiadau parth o barth cyfyngiad i barth caniatâd. Nawr, gadewch i ni symud httpd_t i'r parth caniatâd. Bydd hyn yn rhoi'r mynediad angenrheidiol i Nginx a gallwn barhau â gwaith dadfygio pellach.

sudo semanage permissive -a httpd_t

Felly, unwaith y byddwch wedi llwyddo i ddiogelu SELinux (ni ddylech adael prosiect SELinux mewn modd cyfyngedig) a bod y parthau caniatâd wedi'u llwytho, mae angen i chi ddarganfod beth yn union sydd angen ei farcio fel gunicorn_exec_t i gael popeth i weithio'n iawn eto. Gadewch i ni geisio ymweld â'r wefan i weld negeseuon newydd am gyfyngiadau mynediad.

sudo ausearch -m AVC -c gunicorn

Fe welwch lawer o negeseuon yn cynnwys 'comm="gunicorn"' sy'n gwneud pethau amrywiol ar ffeiliau yn / srv/djangoapp, felly mae hwn yn amlwg yn un o'r gorchmynion sy'n werth ei nodi.

Ond yn ogystal, mae neges fel hon yn ymddangos:

type=AVC msg=audit(1545320700.070:1542): avc:  denied { execute } for pid=20704 comm="(gunicorn)" name="python3.6" dev="vda3" ino=8515706 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0

Os edrychwch ar statws y gwasanaeth gunicorn neu redeg y gorchymyn ps, ni welwch unrhyw brosesau rhedeg. Mae'n edrych fel bod gunicorn yn ceisio cyrchu'r dehonglydd Python yn ein hamgylchedd rhithwir, o bosibl i redeg sgriptiau gweithwyr. Felly nawr gadewch i ni farcio'r ddwy ffeil weithredadwy hyn a gwirio a allwn agor ein tudalen prawf Django.

chcon -t gunicorn_exec_t /srv/djangoapp/django/bin/gunicorn /srv/djangoapp/django/bin/python3.6

Bydd angen ailgychwyn y gwasanaeth gunicorn cyn y gellir dewis y tag newydd. Gallwch ei ailgychwyn ar unwaith neu atal y gwasanaeth a gadael i'r soced ei gychwyn pan fyddwch chi'n agor y safle yn y porwr. Gwiriwch fod prosesau wedi derbyn y labeli cywir gan ddefnyddio ps.

ps -efZ | grep gunicorn

Peidiwch ag anghofio creu polisi SELinux arferol yn nes ymlaen!

Os edrychwch ar y negeseuon AVC nawr, mae'r neges olaf yn cynnwys caniataol = 1 ar gyfer popeth sy'n ymwneud â'r cais, a caniataol = 0 ar gyfer gweddill y system. Os ydych chi'n deall pa fath o fynediad sydd ei angen ar raglen go iawn, gallwch chi ddod o hyd i'r ffordd orau i ddatrys problemau o'r fath yn gyflym. Ond tan hynny, mae'n well cadw'r system yn ddiogel a chael archwiliad clir y gellir ei ddefnyddio o brosiect Django.

sudo ausearch -m AVC

Digwyddodd!

Mae prosiect Django gweithredol wedi ymddangos gyda frontend yn seiliedig ar Nginx a Gunicorn WSGI. Fe wnaethom ffurfweddu Python 3 a PostgreSQL 10 o ystorfeydd RHEL 8 Beta. Nawr gallwch chi symud ymlaen a chreu (neu ddefnyddio) cymwysiadau Django neu archwilio offer eraill sydd ar gael yn RHEL 8 Beta i awtomeiddio'r broses ffurfweddu, gwella perfformiad, neu hyd yn oed gynhwyso'r cyfluniad hwn.

Ffynhonnell: hab.com

Ychwanegu sylw