Krijimi i librit të gatimit
Hapat e fundit
Ka shumë mënyra për të automatizuar procesin e konfigurimit dhe konfigurimit të një kutie. Për çfarëdo arsye, nëse i gjithë sistemi ynë në këtë pikë përbëhet nga vetëm një kuti e vetme, vendosja e një infrastrukture të plotë SCM (Menaxhimi i konfigurimit të softuerit) është i tepërt. Skriptet Shell janë një opsion, por ne mund të përdorim gjithashtu një version të zhveshur të SCM i cili është i disponueshëm në disa nga mjetet atje. Chef është një nga opsionet e njohura dhe "chef-solo" është mënyra e pavarur e konfigurimit të Chef-it ku nuk kërkojmë një nyje shtesë për të vepruar si "chef-server". Gjithçka që i nevojitet është një URL ose një shteg drejt një pakete tarball që përmban libra gatimi për kuzhinierët. Krahasuar me skriptet e guaskës, kjo lloj qasjeje është më deklarative dhe efikase jashtë kutisë dhe është gjithashtu një hyrje e mirë për të filluar me proceset SCM ose IaC (Infrastruktura si kod).
Disa përfitime të tjera nga përdorimi i chef-solo:
- Kompozueshmëria: Përdorni librat e gatimit të komunitetit nga supermarketi i kuzhinierëve ose vende të tjera.
- Pa pagesë dhe me burim të hapur; licencuar sipas licencës lejuese Apache 2.0.
- Qasje në pjesën tjetër të ekosistemit të Chef-it (InSpec, ChefSpec, Cookstyle, Foodcritic, Chef-Shell etj)
- Librat e gatimit dhe recetat mund të përshtaten më vonë në modalitetin klient/server.
Dhe disa dobësi:
- Disa libra gatimi të komunitetit në supermarketin Chef janë të vjetëruar, të prishur dhe të pa mirëmbajtur.
- kuzhinier-solo nuk mund t'i zgjidhë vetë varësitë.
'Recetat' brenda një 'libër gatimi' të kuzhinierit kanë një DSL të bazuar në rubin që përshkruan 'burimet' që janë në një gjendje të veçantë në një nyje. Le të vazhdojmë me një përmbledhje për t'u njohur me disa koncepte Chef që janë gjithashtu të zbatueshme për chef-solo. Qëllimi ynë është të konfigurojmë një nyje Ubuntu që drejton një aplikacion ueb Python/Django duke përdorur Gunicorn dhe NGINX.
Note: We do not necessarily require ChefDK to be installed on our "Chef workstation" (our machine), although with it, we can use 'chef generate' commands to start-off with a directory structure for creating cookbooks, recipes and more. In this article, we will assume ChefDK is installed on our workstation. Commands were run using the version 4.7.26-1 of ChefDK.
(Gjithçka që nga kjo pikë e tutje, përveç rasteve kur specifikohet ndryshe, do të ekzekutohet në makinën tonë, të referuar edhe si 'Stacioni i punës së shefit')
Krijimi i librit të gatimit
Librat e gatimit në kuzhinier janë njësi të ripërdorshme që përmbajnë gjithçka që nevojitet për të mbështetur një skenar konfigurimi. Librat e gatimit mund të përmbajnë "receta" të shumta dhe "recetat" kryesisht përbëhen nga modele burimesh. default.rbështë receta e paracaktuar që do të ekzekutohet kur libri i gatimit të referohet në një listë të ekzekutimit . Receta të ndryshme lejojnë ndarjen e shqetësimeve. Për këtë tutorial, sidoqoftë, ne do të shtojmë të gjitha deklaratat e burimeve në një skedar të recetës kryesore, që është default.rb.
Krijoni një dosje të quajtur "my-chef-project" dhe krijoni një dosje brenda saj të quajtur "cookbooks". Nga ./my-chef-project/cookbooks/, vraponi:
$ chef generate cookbook my-cookbook
Struktura jonë e drejtorisë tani do të duket kështu:
.
└── my-chef-project
└── cookbooks
└── my-cookbook
├── CHANGELOG.md
├── LICENSE
├── Policyfile.rb
├── README.md
├── chefignore
├── kitchen.yml
├── metadata.rb
├── recipes
│ └── default.rb
├── spec
│ ├── spec_helper.rb
│ └── unit
│ └── recipes
│ └── default_spec.rb
└── test
└── integration
└── default
└── default_test.rb
Shtimi i paketave
Hapi i parë për të konfiguruar nyjen tonë është të identifikojmë se cilat paketa kërkohen nga aplikacioni ynë. Nyja jonë është zgjedhur të jetë Ubuntu, kështu që ne mund të mbështetemi te menaxheri i paketave APT për të mbledhur varësitë. Instalimi i paketave të ofruara nga shpërndarja e OS është atëherë një copë tortë:
apt_update
package 'python3'
package 'python3-pip'
package 'nginx'
package 'pkg-config'
package 'libcairo2-dev'
package 'libjpeg-dev'
package 'libgif-dev'
package 'libgirepository1.0-dev'
Këto janë pak a shumë vetë-shpjeguese. Rreshti i parë do të përditësojë depon e apt dhe rreshtat e mëposhtëm do t'i instalojnë ato paketa.
Note: The packages following 'nginx' are needed for compiling some of the python dependencies through pip. These may differ based on your python/django project dependencies specified in requirements.txt. You can use a trial and error method to determine these packages that you need to include in your cookbook. To do that, perform a manual sudo pip install -r requirements.txt (Note: This installs packages system wide!) on a freshly instantiated ubuntu machine to see if it runs successfully. If not, the stderr should give you hints on what packages are missing.
Krijimi i përdoruesve të Linux
Pasi të kemi përfunduar me shtimin e paketave të kërkuara, duhet të krijojmë një përdorues jo të privilegjuar Linux që do të zotërojë kodin burimor të aplikacionit.
user 'bob' do
uid 1212
gid 'users'
home '/home/bob'
shell '/bin/bash'
password '$1$alilbito$C83FsODuq0A1pUMeFPeR10'
end
Vini re se fjalëkalimi është një format hash shadow i përdorur në Linux. Mund të nxirret duke përdorur OpenSSL:
$ openssl passwd -1 -salt alilbitof mypassword
Përfshirë burimin e aplikacionit
Tani le të përfshijmë kodin burimor të aplikacionit Django në librin tonë të gatimit. Vendos kodin burim brenda ./my-chef-project/cookbooks/my-cookbook/files/default/myapp/
Krijo ./my-chef-project/cookbooks/my-cookbook/files/defaultdrejtorinë nëse nuk ekziston.
Udhëzimi për kopjimin e këtyre skedarëve në një vendndodhje të largët në nyjen tonë përshkruhet duke përdorur burimin remote_directory :
remote_directory '/home/bob/myapp' do
source 'myapp' # This is the name of the folder containing our source code that we kept in ./my-cookbook/files/default/
owner 'bob'
group 'users'
mode '0755'
action :create
end
Tërheqja e varësive të pitonit
Për të instaluar paketat python në requirements.txt, ne mund të përdorim burimin e ekzekutimit për të ekzekutuar një komandë arbitrare. Në këtë rast, ne duhet të ekzekutojmë komandën e instalimit të pip mbi të:
execute 'install python dependencies' do
command 'pip3 install -r requirements.txt'
cwd '/home/bob/myapp'
end
Note: Bear in mind that this is going to execute as the root user and the python libraries will be installed system-wide. If our node is designated to exclusively run this one single python app, then it isn't much of a problem. Despite that, a better option to keep things clean and sane is to find and use a community cookbook that manages python installations or 'virtualenvs'. (or at the very least, write a series of execute blocks to replicate this). Using virtualenvs in python ensures that any python based system tools or other python projects will not be affected
Konfigurimi i Gunicorn & NGINX
Tani është koha për të përgatitur Serverin HTTP Gunicorn WSGI me NGINX si përfaqësuesin tonë të kundërt. Nginx përdoret gjithashtu për të trajtuar të gjitha asetet statike nga Django.
Për të lidhur Gunicorn si një shërbim në Ubuntu, mund të përdoret Systemd. Burimi systemd_unit është përfshirë në Chef që nga versioni 12.11.
systemd_unit 'gunicorn.service' do
content({
Unit: {
Description: 'Django on Gunicorn',
After: 'network.target',
},
Service: {
ExecStart: '/usr/local/bin/gunicorn --workers 3 --bind localhost:8080 myapp.wsgi:application',
User: 'bob',
Group: 'www-data',
WorkingDirectory: '/home/bob/myapp'
Restart: 'always',
},
Install: {
WantedBy: 'multi-user.target',
}
})
action [:create, :enable, :start]
end
Tani duhet të përfshijmë një konfigurim standard proxy NGINX në këtë server Gunicorn siç tregohet më poshtë. Ky fragment mund të hyjë në ./my-cookbook/templates/nginx.conf.erb. Krijo direktoriumin e shablloneve nëse nuk ekziston.
Note: Chef's templates support embedded ruby files that can contain variables, ruby expressions and statements. Although this file has the 'erb' extension, we did not use any of the ruby statements or expressions. Also, for the sake of simplicity, we only have a non HTTPS nginx config here (gentle reminder; please do not do this in production!)
server {
listen 80;
server_name http://example.com/;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/bob/myapp/myapp/static;
}
location / {
include proxy_params;
proxy_pass http://localhost:8080/;
}
}
Note: There is also an alternative and a better config, where, for instance the Gunicorn server is bound to a unix domain socket instead of a TCP loopback connection. It's worth exploring that for performance reasons.
Për të kopjuar mbi këtë konfigurim në dosjen e aktivizuar për faqet në nyje, përdorni burimin e shabllonit nga Chef.
template '/etc/nginx/sites-available/example.com.conf' do
source 'nginx.conf.erb'
owner 'root'
group 'root'
mode '0744'
end
Aktivizimi i konfigurimeve në nginx zakonisht bëhet duke krijuar një lidhje simbolike që tregon konfigurimin në dosjen sites-availablee nginx sites-enabled. Lidhjet simbolike mund të deklarohen në librat e kuzhinierëve me burimin e lidhjes siç tregohet më poshtë:
link '/etc/nginx/sites-enabled/example.com.conf' do
to '/etc/nginx/sites-available/example.com.conf'
end
dhe për të fshirë lidhjen simbolike të konfigurimit të paracaktuar:
link '/etc/nginx/sites-enabled/default' do
action :delete
end
Nisja e NGINX
Dhe së fundi, për të ndezur shërbimin nginx:
service 'nginx' do
action :enable
action :start
end
Listat e kandidatëve
Listat e ekzekutimit në kuzhinier janë një listë e renditur rolesh ose recetash në një libër gatimi që do të ekzekutohen në sekuencë në nyje. Ne kemi një libër gatimi "my-cookbook" dhe recetën "default" brenda tij që duhet të ekzekutojmë në kutinë e Ubuntu, kështu që runlist.json në drejtorinë tonë të projektit ( ./my-chef-project/runlist.json) duhet të duket kështu:
{
"run_list": [
"recipe[my-cookbook::default]"
]
}
Hapat e fundit
Libri ynë i gatimit për Chef Solo është gati për t'u shërbyer. Është koha për të siguruar një makinë Ubuntu 18.04 dhe për të instaluar ChefDK në të:
$ ssh root@example.com 'apt-get update && yes | apt-get install curl && curl https://packages.chef.io/files/current/chefdk/4.7.45/ubuntu/18.04/chefdk_4.7.45-1_amd64.deb -o chefdk.deb && yes | dpkg -i chefdk.deb && rm chefdk.deb'
Duke u rikthyer në stacionin tonë të punës të Chef , gjithçka që duhet të bëjmë është të vendosim dosjen e librave të gatimit brenda një tarball, ta transferojmë atë tarball së bashku me atë runlist.jsonnë nyjen e largët që kemi dhënë më lart dhe të ekzekutojmë komandën chef-solo:
(Komanda e mëposhtme duhet të ekzekutohet brenda nyjes ose 'klientit të kuzhinierit' dhe jo në stacionin e punës të Chef)
$ chef-solo --recipe-url $(pwd)/chef-solo.tar.gz -j $(pwd)/runlist.json --chef-license=accept
Ose këtu është një linjë me një linjë (Për t'u drejtuar nga ./my-chef-project/CWD në Stacionin e Punës së Chef):
tar zvcf chef-solo.tar.gz ./cookbooks &&\
scp chef-solo.tar.gz runlist.json root@example.com:~/ &&\
ssh root@example.com 'chef-solo --recipe-url $(pwd)/chef-solo.tar.gz -j $(pwd)/runlist.json --chef-license=accept'
Kjo eshte! Shikoni daljen standarde të mbushur me aktivitetin e shefit duke u përpjekur të konvergojë nyjen tuaj me atë që keni specifikuar në librat e gatimit. Chef-solo do të instalojë të gjithë gurët e çmuar të kërkuar për të gjithë librat e gatimit. Nëse komanda chef-solo është e suksesshme, do të kemi një aplikacion Django që funksionon pas nginx në kutinë e Ubuntu. Navigoni te domeni/IP për ta testuar atë.
Note: Remember that in django you may need to set this domain/ip in the ALLOWED_HOSTS list in settings.py.
Duke iu përgjigjur ndryshimeve
Kurdoherë që bëjmë një ndryshim në përmbajtjen e drejtorisë së projektit tonë (receta, shabllone ose kodi burimor i aplikacionit, etj.), thjesht ekzekutoni një rreshtim të mësipërm nga drejtoria e projektit.
Tip: If the cookbook is version controlled with git (as it should), one good recommendation is to set git hooks to run this one-liner.
Pritja e tarball (opsionale)
Nëse shikoni nga afër komandën e fundit të kuzhinierit, vini re se ajo --recipe-urlka për qëllim të marrë një URL. Kjo do të thotë që ju mund të keni një rrjedhë pune ku një CI do të ndërtojë tarballin tuaj të vetëm kuzhinier, do ta ngarkojë diku dhe do të konfigurojë nyjen tuaj që të tërhiqet prej saj në mënyrë periodike.
Tip: Use curl to pull the changed tarball periodically as a cronjob. curl -z $file will honor If-Modified-Since headers and will only download the tar ball if the remote file has been changed since the timestamp on the existing local $file.