Bulutta Java: Sürekli Entegrasyon Kurulum Eğitimi
Yayınlanan: 2022-03-11Her yıl, BT endüstrisinin giderek daha hızlı evrimine tanık oluyoruz. Çığır açan “Bir kez yaz, her yerde çalıştır” sloganının yazılım geliştirme topluluğu için yepyeni bir beklenti düzeyi belirlemesinin üzerinden yirmi yıldan fazla zaman geçti. Ve bugün, özellikle Java geliştirmeyi ve genel olarak yazılım geliştirmeyi topluca yepyeni bir olasılık evrenine taşıyan, sonuçta ortaya çıkan, sürekli genişleyen bir araç seti ile buradayız.
Çevik, DevOps ve Sürekli Entegrasyon ve Dağıtım gibi metodolojiler - mikro hizmetlerin evrimi ile birlikte - toplu olarak yazılım geliştirme süreci üretkenliğini, yazılım geliştirmenin her zamankinden daha fazla zevk olduğu bir noktaya kadar artırdı. Otomasyonu kullanmak ve doğru araç setini kurmak, yazılım ürünlerinin geliştirilmesini ve sunulmasını şaşırtıcı derecede ağrısız hale getirebilir.
Bu makale, bu yeni evrene, DevOps'a geçen ve ürün geliştirme ve teslimatını en üst düzeye çıkarmak için arama yapan bir Java geliştiricisinin bakış açısıyla bakacaktır.
Günümüzde Spring Boot, Docker, Cloud, Amazon Web Services, Sürekli Teslimat gibi terimler yaygın olarak kullanılmaktadır ancak daha az anlaşılmıştır. Bu makale, tüm bu teknolojileri sunmak ve bu terimleri açıklamak için mümkün olan en kolay yolu izleyecek ve küçük bir yazılım parçası geliştireceğimiz ve belirtilen tüm araçları kullanarak üretim teslimatına hazırlayacağımız bir eğitim şeklinde tamamlayacaktır.
Neden Bu Araçlar?
Docker ile Dağıtımları Basitleştirin
"Bir kez yaz, her yerde çalıştır", kodunuzun her yerde çalışmasını sağlayan Java Sanal Makinesi (JVM) gibi teknolojilerin ortaya çıkmasını sağlayan kavramsal atılımdı. Ve şimdi, birkaç on yıl sonra, BT topluluğuna Docker adı verilen bir şeyin sunulmasıyla karşınızdayız. Docker, yazılımınızı yerleştirebileceğiniz ve neredeyse istediğiniz her yerde zahmetsizce çalıştırabileceğiniz bir sınırlama aracıdır.
Ancak, bir Java geliştiricisi Docker'a bakıp "Buna neden ihtiyacımız olsun ki, ana taşınabilir çözüm olarak iyi tanınan JVM'ye zaten sahibiz" diyebilir. Ama öyle mi?
"Bir kez yaz, her yerde koş" kulağa hoş geliyor ve iyi gidiyor… en azından çoğu zaman. Birden çok JVM satıcısıyla, birden çok Java sürümüyle, birden çok işletim sistemiyle ve yukarıdakilerin çeşitli permütasyonları ve kombinasyonlarıyla karşılaşana kadar. Daha sonra kendinizi zarif "Bir kez yaz, her yerde çalıştır" paradigmasından verimsiz "Bir kez yaz, her yerde hata ayıkla " tuzağına geçiş yaparken buluyorsunuz.
İşte tam da bu noktada Docker günü kurtarmaya yardım ediyor.
Docker, yazılımın geliştirilmesini, test edilmesini ve gönderilmesini basitleştirir. Test etmek istediğiniz yazılıma sahipseniz, onu Docker kapsayıcısına koyun; çalışacak ve ilgili tüm taraflar için kurulumu zahmetsiz olacaktır.
Spring Boot ile Geliştirmeyi Hızlandırın
“Her yere koş” sloganının ortaya çıkmasından on yıldan kısa bir süre sonra, Bahar çerçevesi sahneye çıktı. Bugün, Spring ekosistemi gelişmeye devam ediyor ve belki de en önemlisi Spring Boot olmak üzere çok sayıda Spring tabanlı proje üretti. Spring Boot web sitesinde belirtildiği gibi:
Spring Boot, yalnızca çalıştırabileceğiniz bağımsız, üretim düzeyinde Spring tabanlı Uygulamalar oluşturmayı kolaylaştırır.
Spring Boot, uygulamayı birkaç dakika içinde çalışır duruma getirmenizi sağlar. Yazılım geliştiriciler, yazılım geliştirmeye odaklanabilir ve daha sonra onlar için tüm yapılandırmayı yapan bir araçtan yararlanabilir.
Bu eğitimde, mikro hizmetimizi geliştirmek için Spring Boot kullanacağız.
Jenkins ile Sürekli Entegrasyon (CI)
DevOps, yazılım geliştirme ve teslim yaşam döngüsünü ilgili tüm taraflar için mümkün olduğunca sorunsuz, sorunsuz ve üretken kılmak amacıyla yazılım geliştirme ve sistem yönetimi ekiplerini sıkı bir şekilde entegre eden, hızla büyüyen bir harekettir: geliştiriciler, sistem yöneticileri, test uzmanları ve nihayetinde , son kullanıcılar.
Sürekli entegrasyon (CI), DevOps devriminin temel taşlarından biridir. Buradaki fikir, bir geliştirici kod deposuna kod eklediğinde, bunun otomatik olarak test edilmesi ve üretime teslim (dağıtım) için paketlenmesidir.
CI, aşağıdakilerle el ele gider:
- Sürekli Teslimat – Son kullanıcı iş testi için hazırlanan paketin, üretim dağıtımına manuel tetikleme ile otomatik teslimatı.
- Sürekli Dağıtım – Paketlenmiş ürünün doğrudan üretime otomatik dağıtımı.
CI sürecini uygulamak için kullanılabilecek birkaç araçtan daha fazlası mevcuttur. En popüler olanlardan biri, açık kaynaklı bir CI aracı olan Jenkins'tir. Arkasında binden fazla eklenti ve devasa bir topluluk bulunan Jenkins, sürekli entegrasyon, teslimat veya dağıtım yapmayı düşünmeye başlarken kolay bir seçimdir.
Eğitimimizde Jenkins, ürünümüzü buluta, daha spesifik olarak Amazon (AWS) bulutuna teslim etmek için kullanılacaktır.
AWS ile Bulut Bilişim
Biraz sysadmin deneyiminiz varsa, sistem yönetiminin bazı endişelerini omuzlarınızdan kaldırdığınızı hayal edin. Birkaç uygulamanız var; ne kadar kaynağa ihtiyaç duyacakları hakkında bir fikriniz var, ancak tam olarak ihtiyaç duyacağınız donanım boyutunu bilmiyorsunuz. Tahmin yaparsınız, kaynaklar alınır ve sistem üretime geçer. Şanslıysanız, fazla tahmin ettiğinizi ve ihtiyacınız olandan daha fazla kaynağa sahip olduğunuzu göreceksiniz. Ancak Murphy Yasası göz önüne alındığında, kaynak gereksinimlerini hafife aldığınızı ve muazzam zaman baskısı altında biraz daha fazla bellek veya işlem gücü elde etmek için çabaladığınızı fark edeceksiniz. Buna karşılık, buluta dağıtım yapıyorsanız, sisteminizi oraya koymanız ve bulut sağlayıcılarının sunduğu esneklikle gerektiği gibi boyutlandırmanız yeterlidir. Bulut sayesinde, ne sistem kaynaklarının tükenmesi konusunda endişelenmenize gerek yok, ne de belleğinizin yüzde 90'ının veya CPU'nuzun boşta kalması konusunda endişelenmenize gerek yok.
Tabii ki, hangi sağlayıcıyı seçeceğinize karar vermenin zorluğu var. Bulut savaşları hala devam ediyor. Bilgisayarın geleceği için Microsoft, Amazon ve Google'ın Clash, son zamanlarda teknoloji dünyası haberlerinde bulabileceğiniz örnek bir başlık. Bu blog için, büyük ölçüde mevcut popülaritesine ve pazar payına dayalı olarak Amazon Web Servislerini (AWS) seçtim.
AWS'nin avantajlarından biri, kaydolduktan sonra Amazon'un birçok hizmet sunmasıdır:
Bu öğreticide şu iki AWS hizmetini kullanacağız: Elastic Compute Cloud EC2 (daha spesifik olarak, Amazon EC2 Container Registry veya Amazon ECR) ve Amazon S3 (Simple Storage Services).
Amazon ECR'si
Docker görüntülerimizi bir yerde saklamamız gerekecek. Amazon ECR, yönetilen bir AWS Docker kayıt hizmetidir. Amazon ECR web sitesinde belirtildiği gibi:
…geliştiricilerin Docker kapsayıcı görüntülerini depolamasını, yönetmesini ve dağıtmasını kolaylaştırır. Amazon ECR, Amazon EC2 Container Service (ECS) ile entegredir ve geliştirmeden üretime iş akışınızı kolaylaştırır. Amazon ECR, kendi kapsayıcı havuzlarınızı çalıştırma gereksinimini veya temel alınan altyapıyı ölçeklendirme endişesini ortadan kaldırır.
Amazon S3
Belirtildiği gibi, geliştirdiğimiz uygulama, dosyaları Amazon S3'e yükleyecek bir Spring Boot mikro hizmeti olacak. Amazon S3 web sitesinde belirtildiği gibi:
…geliştiricilere ve BT ekiplerine güvenli, dayanıklı, yüksek düzeyde ölçeklenebilir bulut depolama sağlar. Amazon S3, web'deki herhangi bir yerden herhangi bir miktarda veriyi depolamak ve almak için basit bir web hizmeti arayüzü ile kullanımı kolay nesne depolamadır.
Pratik Bir "Nasıl Yapılır" Eğitimi
Amaç, dosyaları Amazon S3'e yükleyecek bir Spring Boot mikro hizmetini dağıtıma hazırlamaktır. Adımlar şunlardır:
- Mikro hizmeti geliştirin
- Hizmetin yerleştirileceği oluşturma sürecini tanımlayın
- Git kod deposunu barındırmak için Bitbucket kullanın
- Uygulamayı Gradle kullanarak paketlemek için Bitbucket'i Jenkins ile entegre edin
- Uzak bir Amazon ECR'ye aktarın
Aşağıda, gerekli tüm bileşenleri ayarlamak için bir eğitim verilmiştir:
- Spring Boot örnek uygulaması - Gradle kullanılarak paketlenmiş ve sabitlenmiş mikro hizmet
- Yeni bir Ubuntu sunucusunda Jenkins kurulumu
- Webhook aracılığıyla Jenkins ile Bitbucket entegrasyonu
- Jenkins iş yapılandırması
- Uygulamamızı içeren Docker görüntülerini depolamak için Amazon ECR
Önkoşullar
AWS bulut kaynaklarını kullanabilmek için önce Amazon'a kaydolmamız gerekiyor. Kaydolarak, kaydı takip eden 12 ay boyunca uygulamalı deneyim sağlamak amacıyla anında Ücretsiz Kullanım kullanım avantajlarına sahip bir hesap alacağız.
Belirtildiği gibi, bu eğitimde Amazon S3 ve Amazon ECR'yi kullanacağız. Her ikisi için de hizmetlere bağlanmak için erişim anahtarlarına ihtiyacımız olacak.
AWS'ye kaydolduktan sonra hesabımıza gidiyoruz Güvenlik kimlik bilgileri , burada Erişim anahtarlarını seçiyoruz ve “Yeni Erişim Anahtarı Oluştur” a tıklıyoruz. Tıkladıktan sonra, kimliğiyle birlikte bir anahtar oluşturulur. Bunu daha sonra AWS Jenkins entegrasyonunu yapılandırırken ve S3 dosya yüklememizi geliştirirken kullanacağımız için güvenli bir yerde saklamanız gerekir.
Bir sonraki ön koşul, bir Amazon S3 kovasına (depolama kapsayıcısı) ihtiyacımız olmasıdır. Spring Boot Service, Amazon S3 depolama alanına dosya yükleyecek ve buradan dosya indirecektir. Kova oluşturma yeterince basittir ve yalnızca birkaç tıklama gerektirir. Bunun nasıl yapılacağına ilişkin tam açıklama Bir Kova Oluşturma belgelerinde verilmiştir.
Kodumuzu barındırmak ve Jenkins'e istekleri tetiklemek için Bitbucket'i de kullanacağız, bu nedenle bir Bitbucket hesabına da ihtiyaç var. Bitbucket, geliştiriciler için harika bir seçenektir ve ana avantajlarından biri oluşturabileceğiniz sınırsız sayıda özel depodur.
Uygulama geliştirme
Spring ek açıklamalarının tüm ayrıntılarına ve nasıl çalıştıklarına girmek yerine, bunun yerine saf geliştirici perspektifinden tüm kurulumun daha zorlu kısmına odaklanacağım; yani, CI için gereken Linux, Jenkins ve diğer araçları kurmak ve yapılandırmak. Spring Boot mikro hizmet uygulaması da dahil olmak üzere bu öğreticide kullanılan tüm kod örnekleri, proje için Bickbucket deposunda mevcuttur.
Uygulama kompozisyonumuz basittir. StorageWebserviceApplication.java
dosyamızda Spring Boot uygulama giriş noktamız var. Dosya yükleme ve indirme mantığı StorageService.java
. StorageController.java
, dosya yükleme ve indirme için kullanılan API uç noktalarını içeren bir Rest denetleyicisidir. İşte proje hiyerarşisi:
Bir derleme aracı olarak Gradle'ı seçtik ve bu, uygulamamızı paketleyecek ve Docker görüntüsünü oluşturacak. Şimdi, Gradle derleme dosyasını, hizmet bileşenini ve Dockerfile'ı tartışacağız.
AWS API'yi kullanabilmek için, AWS belgelerinde Gradle'ı kullanmaya yönelik tanımlandığı gibi, derleme dosyamıza bağımlılıkları dahil etmemiz gerekir.
Özetle, Gradle betiğimizin AWS bağımlılık yapılandırma kısmı aşağıdaki gibi görünecektir:
buildscript { ... repositories { mavenCentral() } dependencies { ... classpath("io.spring.gradle:dependency-management-plugin:0.5.4.RELEASE") } } .. apply plugin: "io.spring.dependency-management" dependencyManagement { imports { mavenBom ('com.amazonaws:aws-java-sdk-bom:1.10.47') } } dependencies { .. compile ('com.amazonaws:aws-java-sdk-s3') }
Daha önce belirtildiği gibi, Amazon S3'e dosya yüklerken bunu dosyaları bir S3 kovasına yükleyerek yaparız.
Pakete bağlanmak için Amazon S3 istemcimizin kimlik bilgilerinin sağlanmış olması gerekir. Kimlik bilgileri, daha önce oluşturduğumuz erişim anahtarlarıdır. application.properties
dosyasında erişim anahtarı kimliğini ve değerini tanımlarız; toptal-s3-example
olarak adlandırdık.
Ana hizmet bileşenimiz artık aşağıdaki gibidir:
@Service public class StorageService { @Value("${aws.accesKeyId}") private String awsAccessKeyId; @Value("${aws.secretKey}") private String awsSecretKey; @Value("${aws.bucketName}") private String awsBucketName; private AWSCredentials credentials; private AmazonS3 s3client;; @PostConstruct public void init(){ credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretKey); s3client = new AmazonS3Client(credentials); } public void uploadFile(MultipartFile file) throws IOException { File fileForUpload = transformMultipartToFile(file); s3client.putObject(new PutObjectRequest(awsBucketName, file.getOriginalFilename(), fileForUpload)); } public InputStream downloadFile(String amazonFileKey) throws IOException { S3Object fetchFile = s3client.getObject(new GetObjectRequest(awsBucketName, amazonFileKey)); InputStream objectData = fetchFile.getObjectContent(); return objectData; } …
StorageService
, application.properties
dosyasından kimlik bilgilerini okur ve bunları BasicAWSCredentials
nesnesini ve ardından AmazonS3Client
nesnesini başlatmak için kullanır. Aşağıda, Amazon S3 istemci nesnesinde dosya yükleme için getObject
ve dosya indirme için putObject
çağırmak basit bir meseledir.
Hizmeti bir Docker kapsayıcısında çalıştıracağız ve Gradle oluşturma işlemi sırasında Docker görüntüsünü oluşturacağız. Bunu ayrıca build.gradle
dosyasını aşağıdaki gibi yapılandırarak yapacağız:
buildscript { ... dependencies { ... classpath('se.transmode.gradle:gradle-docker:1.2') } } ..... apply plugin: 'docker' ... task buildDocker(type: Docker, dependsOn: build) { push = false applicationName = "storageservice" dockerfile = file('src/main/docker/Dockerfile') doFirst { copy { from jar into stageDir } } }
Buildscript
bölümü ve apply plugin
oldukça standarttır. Ayrıca src/main/docker/Dockerfile
içinde depolanan Docker yapılandırmasını okuyan ve JAR dosyasını Docker derlemesine kopyalayan bir buildDocker
görevi tanımladık.
Dockerfile, imajımızı hazırlayacağımız saf Docker komutlarının bir listesini içerir:
FROM frolvlad/alpine-oraclejdk8 ADD storageWebService-0.0.1-SNAPSHOT.jar storageService.jar EXPOSE 8080 CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/storageService.jar"]
Uygulamamızı çalıştırmak için bir ön koşul, bir Java Sanal Makinesi (JVM) kurmuş olmaktır. Docker, Java yüklü görüntülerin bir listesini sağlar ve minimum 5MB Alpine Linux'a dayalı olarak en küçüklerinden birini seçeceğiz. frolvlad/alpine-oraclejdk8
image ihtiyacımız olan her şeye sahip ve oldukça küçük (sadece 170 MB).
FROM
komutu, bahsi geçen görüntüyü, kendi görüntümüzün oluşturulacağı temel olarak ayarlar. Yerleşik JAR dosyasını, ADD
adı altında kapsayıcı dosya sistemine storageService.jar
. Daha sonra, EXPOSE
komutu ile Docker konteynerinin 8080
portunu çalışma zamanında dinlemesini tanımlıyoruz. Ancak bu, ana bilgisayardan 8080
ile iletişimi etkinleştirmeyecektir. Görüntü tamamlandığında ve onu çalıştırmak istediğimizde, aşağıdaki komutla docker run -p 8080:8080 amazonRepository/storageservice
ile kapsayıcıdaki bağlantı noktasını yayınlamamız gerekecek, burada amazonRepository
bir depodur, bu daha sonra yapılandıracağız öğretici. CMD
ile konteyneri çalıştırdığımızda hangi komutların çalıştırılacağını tanımlıyoruz. CMD
komutunun parantez içindeki değerler, kapsayıcıyı çalıştırdığımızda aşağıdakilerin yürütüleceği anlamına gelir:
java -Djava.security.egd=file:/dev/./urandom -jar /storageService.jar
-Djava.security.egd=file:/dev/./urandom
seçeneği, başlatma sırasında JVM gecikmelerini azaltmaya yardımcı olmak için gereklidir. Atlanırsa, önyükleme işlemi sırasında ihtiyaç duyulan rasgele sayı oluşturma işlemi nedeniyle uygulamanın başlatılmasını son derece yavaşlatacaktır.
Bu, "Uygulama geliştirme" bölümünü özetler. Bu yapıldığında daha sonra bir Docker konteynerini çalıştırdığımızda burada oluşturduğumuz servis otomatik olarak başlayacaktır. O halde, sürekli entegrasyon sürecini kurmak için gereken diğer araçların kurulumuna ve konfigürasyonuna başlayalım.
Uygulama ve Sistem İşlemleri
Öncelikle, Jenkins CI aracını kuracağımız temiz bir Linux sunucusuna ihtiyacımız var. Aşağıdaki talimatların özellikle Ubuntu 14.04 için olduğunu unutmayın. Talimatların diğer Linux dağıtımları için biraz farklı olabileceğini unutmayın. Kullanılan Jenkins sürümü 2.7.1'dir ve ekranlar ve talimatlar, kullanılan Jenkins sürümüne bağlı olarak biraz farklılık gösterebilir.
Böylece, Linux sunucu konsolumuza gidiyoruz ve önkoşulları yüklemeye başlıyoruz.
JDK Önkoşul
Bir JDK'nın kurulu olması gerekiyor. JDK8'i yüklemek için talimatlar aşağıdadır.

sudo add-apt-repository ppa:webupd8team/java sudo apt-get install python-software-properties sudo apt-get update sudo apt-get install oracle-java8-installer java -version
Docker'ı yükleyin
Jenkins'in Docker yapılarını tetikleyebilmesi için docker-engine
aşağıdaki gibi kurmamız gerekiyor:
sudo apt-get install apt-transport-https ca-certificates sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D #create a docker list file sudo vi /etc/apt/sources.list.d/docker.list #add the following entry in the docker.list file (change trusty to #the release you are running on if you are running on different, ie. #xenial, precise...): deb https://apt.dockerproject.org/repo ubuntu-trusty main #save and exit the file sudo apt-get update apt-cache policy docker-engine sudo apt-get install docker-engine
Docker motorunu kurduğumuz için, aşağıdaki komutla Docker'ın doğru çalıştığını doğrulamak için bir hello-world
Docker görüntüsü başlatacağız.
sudo docker run hello-world
Hello-world
görüntü çıktısı aşağıdaki gibi görünecek ve bununla motorun iyi çalıştığını onaylayabiliriz.
AWS Komut Satırı Arayüzünü (CLI) yükleyin
Ardından, AWS CLI'yi yükleyeceğiz. Daha sonra, Jenkins iş yapılandırmasında, AWS kimlik doğrulaması ve Docker görüntüsünü Amazon EC2 kapsayıcı kayıt defterine gönderme komutlarını yürütmek için CLI'yi kullanacağız.
AWS CLI'yi yüklemek için Amazon CLI belgelerinde ayrıntılı olarak açıklanan yönergeleri izleriz.
İki kurulum seçeneğinden Python programlarını kurmak ve yönetmek için kullanılan bir paket yönetim sistemi olan Pip kullanarak kurulumu seçeceğiz. Aşağıdaki üç komutu çalıştırarak Pip ve AWS CLI'yi kuracağız:
#install Python version 2.7 if it was not already installed during the JDK #prerequisite installation sudo apt-get install python2.7 #install Pip package management for python sudo apt-get install python-pip #install AWS CLI sudo pip install awscli
AWS ECR'si
Oluşturma sürecinin son adımı olarak, Docker imajımızı Amazon konteyner kayıt defterine göndereceğiz. Amazon web hizmetleri konsolunda AWS EC2 Container Service'i buluyoruz.
Soldaki Depolar alt menüsünü seçiyoruz ve Başla'ya tıklıyoruz.
Ardından, depo adını girdiğimiz ve Sonraki Adım düğmesine tıkladığımız depoyu yapılandırmak için ilk ekran karşımıza çıkıyor.
Sonraki Adım'a tıklamak, görüntüleri depoya nasıl göndereceğimize ilişkin talimatları içeren bir ekran gösterir.
Bir Docker görüntüsünün nasıl oluşturulacağına ve kayıt defterine nasıl gönderileceğine dair bir örnekle karşı karşıyayız, ancak şimdi bununla ilgilenmemize gerek yok. Bununla bir depo oluşturduk.
Jenkins'i kurun ve yapılandırın
Jenkins'i kurmak için kabuğa aşağıdaki komutları giriyoruz:
#Download Jenkins key and pipe it to apt-key tool, apt-key command #add will read from input stream, as defined by „–„. When added #apt will be able to authenticate package to be installed. wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - #create a sources list for jenkins sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' #update your local package list sudo apt-get update #install jenkins sudo apt-get install jenkins
Kurulum bittiğinde Jenkins otomatik olarak başlar. Aşağıdaki komutla hizmet durumunu kontrol edin:
sudo service jenkins status
Jenkins, Bitbucket Git deposuna bağlanacak ve bunu yapmak için Git'i kurmamız gerekiyor.
#install Git sudo apt-get install git
Jenkins, bir Docker görüntüsünün oluşturulacağı Gradle oluşturma sürecini tetikleyecek. Bunu yapabilmek için Jenkins kullanıcısının docker
kullanıcı grubuna eklenmesi gerekir:
#add Jenkins user to docker user group sudo usermod -aG docker jenkins
Oluşturma işlemi sırasında Jenkins, Docker görüntülerini Amazon ECR'ye aktaracak. Bunu etkinleştirmek için Jenkins kullanıcısı için AWS'yi yapılandırmamız gerekiyor.
Öncelikle jenkins
kullanıcısına geçmemiz gerekiyor. Bunun için bir şifre belirlememiz gerekiyor.
#change Jenkins password sudo passwd jenkins #switch to Jenkins user su – jenkins #configure AWS aws configure
aws configure
komutunu girdikten sonra, oluşturulan gizli erişim anahtarını ve anahtar kimliğini (bunlar, süreçte daha önce oluşturduğumuz kimlik bilgileridir) girmeye başlarız. Benim durumumda, hesabın bölgesi us-west-2
ve ben de bunu giriyorum. Ayrıca AWS komutları için varsayılan çıktı biçimini JSON olarak ayarladık.
Artık Jenkins'i 8080 numaralı bağlantı noktasından erişilebilen web konsolu aracılığıyla yapılandırmaya geçebiliriz.
URL'ye eriştiğimizde aşağıdaki Başlarken ekranı ile karşılaşıyoruz.
Ekranda belirtildiği gibi şifreyi girmemiz gerekiyor. Bunu yaptıktan sonra kurulum sihirbazı aşağıdakileri yapmamızı ister:
- Hangi eklentilerin yükleneceğini seçin - Önerilen eklentileri yükle'yi seçeceğiz.
- Kullanıcı kimlik bilgilerini girerek ilk yönetici kullanıcıyı oluşturun
Bittiğinde, Kaydet ve Bitir'i tıklayın . Bununla Jenkins kurulum konfigürasyonunu bitirdik.
Oluşturma işini tanımlamaya başlamadan önce, birkaç ek eklenti eklememiz gerekiyor. Jenkins'i Yönet'e gideceğiz ve Eklentileri yönet 'e tıklayacağız. Kullanılabilir sekmesinde önce Bitbucket eklentisini buluyoruz, kutuyu işaretliyoruz ve yeniden başlattıktan sonra İndir ve yükle'ye tıklıyoruz.
Daha sonra aşağıdaki ekran gibi bir şeyle karşılaşacaksınız.
Eklenti yüklendikten sonra, işi kurmak için gerekli olacak aşağıdaki ek eklentiler için işlemi tekrarlıyoruz:
- Gradle eklentisi
- Docker inşa adım eklentisi
- Cloudbees Docker özel yapı ortamı eklentisi
- Amazon ECR eklentisi
Kullandığımız Docker derleme adımı eklentisi, Docker arka plan programına istek gönderecektir. Bunun için 2375 numaralı bağlantı noktasındaki TCP soketini etkinleştirmemiz gerekiyor. Bunun için etc/default/docker
konumunda bulunan Docker yapılandırma dosyasına giriyoruz.
sudo vi /etc/default/docker
Burada konfigürasyona aşağıdaki satırı ekliyoruz:
DOCKER_OPTS='-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock'
Dosyayı kaydedip çıkıyoruz ve hem Docker hem de Jenkins servisini yeniden başlatıyoruz.
sudo service docker restart sudo service jenkins restart
Jenkins yeniden başlatıldıktan sonra Jenkins konsoluna gidiyoruz ve Manage Jenkins'den Configure System'ı seçiyoruz.
Docker oluşturucu bölümünü buluyoruz ve REST API URL'si için http://localhost:2375
giriyoruz, değişikliği onaylamak için Apply'a tıklıyoruz. Ardından, her şeyin yolunda olduğunu umarak doğrulamak için Test Bağlantısını tıklıyoruz.
Yapılandırmayı kaydedip Jenkins iş yapılandırmasına geçiyoruz.
İş Yapılandırması
Jenkins ana sayfasına gidiyoruz ve New Item oluşturuyoruz.
Bir Freestyle projesi seçiyoruz ve aşağıdaki ekranda gösterildiği gibi proje adını giriyoruz:
Tamam'a tıklayarak, iş yapılandırma sayfası ile karşı karşıyayız. Bitbucket Git depomuza yapılan her gönderimde projenin oluşturulmasını istiyoruz. Bunu başarmak için öncelikle bağlandığımız depoyu tanımlamamız gerekiyor.
Adım 1: Kaynak Kodu Yönetimi
Kaynak kod yönetimi altında Git'i seçiyoruz ve Bitbucket depomuzun URL'sini giriyoruz. URL, https://bitbucket.org/bitbucketUsername/repositoryName
biçimindedir.
URL'yi girdikten sonra Jenkins, bağlantıyı otomatik olarak test etmeye çalışacaktır. Henüz kimlik bilgilerini girmediğimiz için bağlanamadığını belirten bir hata gösterecektir.
Add açılır listesini açın ve Credentials Jenkins sağlayıcısına tıklayın.
Bitbucket hesabımız için kullanıcı adı ve şifreyi girdiğimiz aşağıdaki ekran karşımıza çıkıyor.
Yeni kimlik bilgilerini ekledikten sonra, kimlik bilgileri açılır menüsünden onu seçtiğinizden emin oluyoruz ve bu, Kaynak kod yönetimi kurulumunu tamamlıyor.
2. Adım: Tetikleyiciler Oluşturun
Tetikleyici derlemelerini uzaktan kontrol edin ve bir kimlik doğrulama belirteci tanımlayın. Rastgele ve güvenli bir belirteç tanımladığınızdan emin olun.
3. Adım: Bitbucket Web kancası
Jenkins, Bitbucket'te kullanacağımız URL'yi zaten sağladı. Bitbucket veri havuzu sayfamıza gidiyoruz ve ayarlar menüsünde Web kancaları üzerine tıklayın. Daha sonra Web kancası ekle'ye tıklamak bize aşağıdaki gibi doldurduğumuz aşağıdaki ekranı sunar:
URL şu yapıya sahiptir: http://JENKINS_URL _HOST:PORT/job/JOB_NAME/build?token=TOKEN
.
Yukarıdaki değerleri sırasıyla Jenkins URL'si, çalıştığı bağlantı noktası, oluşturduğunuz işin adı ve daha önce tanımladığınız jeton ile girin.
Webhook'u kaydettikten sonra, gerekirse düzenleyebileceğiniz veya her yeni kod bastığımızda oluşturulan istekleri görüntüleyebileceğiniz aşağıdaki ekran ile karşılaşacaksınız.
Bu yapılandırmayla, daldan bağımsız olarak web kancası her depo gönderiminde tetiklenir. Jenkins tarafında, hangi dal itme işleminin yapıyı tetikleyeceğini tanımlayabiliriz.
Bitbucket'in Jenkins'e kod gönderebilmesi için, anonim okuma erişimine izin vermek için Jenkins global güvenliğini yeniden yapılandırmamız gerekiyor. Ek olarak, kurulumumuz için, siteler arası istek sahteciliğini önleyen varsayılan Jenkins seçeneğini devre dışı bırakmamız gerekiyor. Bunu yapmak için, Jenkins'i Yönet'e gidin ve Küresel güvenliği yapılandır'ı seçin. Anonim okuma erişimine izin ver seçeneğini işaretleyin ve Siteler arası sahtecilik istismarlarını engelle seçeneğini işaretleyin. Ardından yapılandırmayı kaydedin.
Lütfen bunun yalnızca basitlik nedenleriyle yapıldığını unutmayın. Tam kurulum, bu öğreticinin kapsamını aşar ve Jenkins'in TLS bağlantısı üzerinde bir ters proxy arkasında daha fazla güvenliğini sağlamayı ve CSRF önlemeyi etkinleştirmeyi içerir.
Adım 4: Gradle Build
Artık Jenkins işine dönebilir ve onu yapılandırmaya devam edebiliriz. Derleme bölümünde, bir derleme adımı ekliyoruz: Gradle betiğini çağırın .
Bu forma aşağıdakileri giriyoruz:
Ekranda gösterildiği gibi, Gradle'ın ana bilgisayarda kurulu olmasını gerektirmeyen kullanışlı bir Gradle özelliği olan Gradle sarmalayıcısını kullanacağız. Aşamalı yürütülebilir yap kutusunu işaretlediğinizden emin olun.
Görevlerde build
ve buildDocker
.
Adım 5: Docker Etiket Resmi
Derlemenin bu kısmı, Gradle'ın dockerBuild
görevi tarafından önceden hazırlanmış bir Docker görüntüsünü etiketler. Bunun için işe yeni bir build adımı ekliyoruz: Execute Docker command . Resmi etiketle komutunu seçiyoruz ve resim adını, resmi iteceğimiz hedef depoyu ve etiketi belirliyoruz:
6. Adım: Docker Push to Amazon ECR
Son olarak, imajımızı Amazon ECR'ye nasıl göndereceğimizi tanımlamamız gerekiyor. Bunun için yeni bir Kabuk oluşturma adımı ekliyoruz ve AWS'de kimlik doğrulaması yapacak ve görüntüyü Amazon ECR'ye gönderecek komutları ayarlıyoruz:
#region for our account is us-west-2 aws ecr get-login --region us-west-2 | bash #push the previously tagged image docker push 058432294874.dkr.ecr.us-west-2.amazonaws.com/springbootdocker:${BUILD_NUMBER}
Bu sayede build işlemimizi tamamlamış oluyoruz. Depoya yeni kod gönderdikten sonra bu iş aktif hale gelecek ve Docker kayıt defterine “sihirli bir şekilde” yeni bir Docker imajı yüklemiş olacağız.
Görüntü daha sonra docker-engine
kurulu olduğu her yere çekilebilir ve aşağıdaki komutla çalıştırılabilir:
docker run -p 8080:8080 amazonRepository/springbootdocker
Bu komut, dosyalarımızı S3 kovasına yüklemek ve indirmek için aşağıdaki uç noktalarla Spring Boot mikro hizmetimizi başlatır:
-
http://hostnameURL:8080/api/storage/upload
-
http://hostnameURL:8080/api/storage/download?fileName=xyz
Java ve Sürekli Entegrasyon ile Sonraki Adımlar
Her zaman yapılacak daha çok şey vardır. Bu eğitimde çok şey işlendi, ancak bunu daha fazla bilgi edinmek için yalnızca bir başlangıç noktası olarak kabul ediyorum. Jenkins'i Nginx gibi bir web proxy sunucusunun arkasına koymak ve bir TLS bağlantısı kurmak, daha fazlasının yapılabileceğine ve muhtemelen yapılması gerektiğine dair sadece iki örnektir.
Docker imajımız Amazon ECR'de mevcuttur ve dağıtıma hazırdır. Artık onu alıp manuel olarak dağıtabiliriz. Ancak, daha iyi bir çözüm, onu daha fazla otomatikleştirmek olacaktır. CI yalnızca ilk adımdır ve sonraki adım Sürekli Teslimattır. Peki ya yüksek kullanılabilirlik? Amazon AWS EC2, üretim tabanlı hizmet için zorunlu olan, kümelenmiş bir ortamda kapsayıcıları bulutta kaydetmeye yönelik özellikler sağlar. Aşağıdaki AWS blog gönderisinde sürekli teslim süreci geliştirmeye yönelik iyi bir çalışma örneği bulunabilir.
Çözüm
Sonuç olarak, sorunsuz ve temiz bir yazılım geliştirme süreci oluşturduk. Mevcut araçları kullanarak verimliliğimizi en üst düzeye çıkarmaya yardımcı olan bir altyapı oluşturduk. Artık basit bir web servisi olan Java servisimizin REST bitiş noktasına sahip konfigürasyonu için endişelenmemize gerek yok. Spring Boot konvansiyonunun her şeyi halletmesine ve yalnızca hizmet mantığına odaklanmasına izin veriyoruz. Kodumuzu Bitbucket Git depomuza her aktardığımızda yeni bir Docker görüntüsü oluşturmak için Jenkins'i kullanırız ve sonunda, Docker görüntülerimizi ve dosyalarımızı depolamaktan bulutu sorumlu hale getiririz. Bir Docker görüntüsü içinde yer alan hizmetimizi dağıttığımızda, işletim sisteminin herhangi bir kısıtlamasından (işletim sisteminde bir docker-engine
kurulu olduğu sürece) umursanmayacağız.