在企業級場景中,EDAS會被內建到客戶側的研發測試的IT流程中形成更加完整的企業IT雲化整體解決方案,如對接到客戶的CMP多雲管理平台,被串聯到客戶的CICD流水線中,和客戶的統一監控運維平台對接等。為友善EDAS更好的在各行業中使用和內建,我們基于多個真實項目經驗輸出了本次最佳實踐,以供您參考。
背景資訊
企業級分布式應用服務EDAS(Enterprise Distributed Application Service)是阿裡雲原生産品體系的核心産品之一,為複雜微服務的建構和托管提供端到端應用生命周期管理。
最佳實踐概述
本次最佳實踐通過打通客戶側GitLab、Jenkins與專有雲企業版提供的EDAS和ACK來幫助客戶建構端到端企業級雲原生CICD流水線。具體實作思路為通過JAVA編寫一個EDAS-SDK适配插件,Jenkins通過在腳本庫預先設定的SHELL腳本來調用該插件,進而內建EDAS在持續傳遞層面的能力。在大中型場景中,我們推薦企業級開發測試雲場景使用企業版或靈活版中的雲效+EDAS組合。
最佳實踐價值
EDAS本身可以作為微服務精細化治理中心,并關聯ACK容器服務支撐微服務的部署和運作,是一個非常完整優質的雲原生解決方案(關于使用EDAS進行微服務開發的最佳實踐将在另外的篇章中單獨輸出,在這裡不做贅述)。通過企業版的POP 網關,您可以快速的調用EDAS-OpenAPI,進而将阿裡側雲原生能力快速內建到企業的現有研發和運維IT流程中。
軟體環境介紹
本最佳實踐基于阿裡雲專有雲企業版V3.9.0版,如下圖為專有雲企業版V3.9.0 Apsara Stack控制台界面。EDAS控制台由Apsara Stack控制台單點登入并跳轉。
送出代碼
本示例中代碼管理在GitLab中。完成以下步驟送出代碼:
- 開發送出代碼到git本地倉庫。
2. 開發對需要釋出的版本打上Tag。
3. 通過GitLab的tag push,将本地倉庫代碼同步到遠端的gitLab服務上。
WebHook觸發Jenkins的建構任務
前提條件:代碼已送出到GitLab服務。
完成以下步驟,觸發建構任務:
- 在cicd的源碼管理頁面,配置git庫位址。
2. 在cicd的建構觸發器頁面,配置觸發器,并擷取觸發器的URL和Secret Token。
3. 在cicd的Settings頁面,配置git庫的WebHook。
說明 URL和Secret Token的值即上一步中擷取的觸發器的URL和Secret Token。
4. 在cicd的建構頁面,配置建構鏡像和推送鏡像。
5. 執行如下指令配置觸發調用EDAS Open API小程式對外暴露的請求位址,用于通路EDAS背景。
curl 192.XXX.XXX.XXX:XXX/aliyun/edas/deploy
準備工作
Jenkins建構完項目後,您需要按版本号通過以下步驟操作把鏡像上傳到鏡像倉庫,然後即可調用EDAS OpenAPI拉取鏡像部署應用、通知相關人員等。
前提條件:
- 在JAVA項目工程中聲明并引入EDAS-SDK。
- 擷取EDAS-OpenAPI對外的服務域名,即專有雲EDAS-endpoint位址。
- 在适配插件中拼裝請求封包,完成API調用的指令。
背景條件:CICD流程調用EDAS OpenAPI接口:
- 調用GetK8sApplication接口擷取容器服務K8s中部署的應用鏡像URL資訊。
- 調用DeployK8sApplication接口拉取應用鏡像部署容器服務K8S應用。
-
在适配插件中引入EDAS-SDK。
在IDE工具上打開Maven項目下的pom.xml檔案,在檔案中添加
和sdk:aliyun-java-sdk-core
依賴。sdk:aliyun-java-sdk-edas
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.4.3</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-edas</artifactId>
<version>2.53.1</version>
</dependency>
2. 擷取RegionId、AccessKey ID和AccessKey Secret。
登入Apsara Stack控制台,在左側導航欄單擊使用者中心 > 部門管理,選擇對應的部門,單擊擷取AccessKey 。
3. 擷取EDAS API服務位址endpoint。
登入天基平台,單擊報表 > 全部報表 > 資源申請報表,全局搜尋edas-api,其中詳情頁面domain即endpoint的值。
擷取容器服務中部署的應用資訊
請求URL
/pop/v5/changeorder/co_application
請求參數
名稱 | 類型 | 是否必選 | 描述 |
AppId | String | 是 | 應用ID |
EndPoint | String | 是 | - |
From | String | 否 | 來源 |
傳回參數
名稱 | 類型 | 描述 |
Code | Integer | 傳回碼 |
Message | String | 傳回資訊 |
AppId | String | 應用 ID |
ImageUrl | String | 鏡像 URL |
RepoName | String | 鏡像倉庫名稱 |
RegionId | String | 鏡像區域 ID |
RepoId | String | 鏡像倉庫 ID |
RepoNamespace | String | 鏡像倉庫命名空間 |
RepoOriginType | String | 鏡像倉庫來源類型 |
Tag | String | 鏡像 tag |
ApplicationType | String | 應用類型 |
Cmd | String | startUp 指令 |
CmdArgs | String | 指令參數 |
DeployType | String | 部署類型 |
EdasContainerVersion | String | EDAS 容器版本 |
BuildpackId | String | 應用建構類型 ID |
TomcatVersion | String | Apache Tomcat 版本 |
Name | String | 環境變量名稱 |
Value | String | 環境變量值 |
JarStartArgs | String | JAR 啟動參數 |
JarStartOptions | String | JAR 啟動選項 |
K8sCmd | String | 啟動指令 |
K8sCmdArgs | String | 啟動指令參數 |
K8sLocalvolumeInfo | String | 本地存儲資訊 |
K8sNasInfo | String | NAS 存儲資訊 |
K8sVolumeInfo | String | 存儲資訊 |
Liveness | String | K8s 容器存活狀态監測資訊 |
PostStart | String | K8s 容器啟動後執行資訊 |
PreStop | String | K8s 容器停止前執行資訊 |
Readiness | String | K8s 容器業務狀态檢查資訊 |
ComponentId | String | 元件 ID |
ComponentKey | String | 元件關鍵字 |
請求示例
public class GetK8sApplicationSimpleInfo {
public String getK8sApplication() throws ClientException {
//請填寫要執行 API 調用的應用所在地域 ID.
String regionId = "your_ regionId";
//請填寫阿裡雲主賬号或子賬号 AccessKey ID.
String accessKeyId = " your_accessKeyId ";
//請填寫阿裡雲主賬号或子賬号 AccessKey Secret.
String accessKeySecret = " your_accessKeySecret ";
String productName = "Edas";
String domain ="edas-api.console.cn-*******-****-***.com";
DefaultProfile defaultProfile = DefaultProfile.getProfile(regionId,
accessKeyId, accessKeySecret);
DefaultAcsClient defaultAcsClient = new DefaultAcsClient(defaultProfile);
GetK8sApplicationRequest request = new GetK8sApplicationRequest();
request.setAppId("f66a22ec-c98d-4b79-ab41-c8641bf9ac87");
request.setEndpoint("edas-api.console. your_regionId.cloud.poc2.com");
GetK8sApplicationResponse response;
String resp = "";
try {
response = defaultAcsClient.getAcsResponse(request);
resp = "傳回碼:" + response.getCode() + "----" + "傳回資訊:" + response.getMessage()
+ "鏡像URL:" + response.getApplcation().getImageInfo().getImageUrl();
System.out.printf("傳回碼:" + response.getCode() + "----" + "傳回資訊:" + response.getMessage()
+ "鏡像URL:" + response.getApplcation().getImageInfo().getImageUrl());
} catch(ClientException e) {
e.printStackTrace();
}
return resp;
}
}
傳回示例
GetK8sApplicationResponse response;
String resp = "";
try {
response = defaultAcsClient.getAcsResponse(request);
resp = "傳回碼:" + response.getCode() + "----" + "傳回資訊:" + response.getMessage()
+ "鏡像URL:" + response.getApplcation().getImageInfo().getImageUrl();
System.out.printf("傳回碼:" + response.getCode() + "----" + "傳回資訊:" + response.getMessage()
+ "鏡像URL:" + response.getApplcation().getImageInfo().getImageUrl());
} catch(ClientException e) {
e.printStackTrace();
}
return resp;
部署容器服務K8s應用
請求URL
/pop/v5/k8s/acs/k8s_apps
請求參數
名稱 | 類型 | 是否必選 | 描述 |
AppId | String | 是 | 應用ID |
EndPoint | String | 是 | - |
PreStop | String | 否 | 停止前執行腳本,格式如:{"tcpSocket":{"host":"", "port":8080}}。如果設定為 “” 或者 {} 代表删除,不設定代表忽略。 |
Envs | String | 否 | - |
ImageTag | String | 否 | 鏡像Tag |
BatchWaitTime | Integer | 否 | PoD更新最小間隔時間。 |
Command | String | 否 | 容器啟動Command指令。清空需設定為空字元串 ""。 |
PostStart | String | 否 | - |
Readiness | String | 否 | - |
Liveness | String | 否 | - |
Args | String | 否 | - |
Replicas | Integer | 否 | - |
Image | String | 否 | - |
CpuLimit | Integer | 否 | - |
MemoryLimit | Integer | 否 | - |
CpuRequest | Integer | 否 | - |
MemoryRequest | Integer | 否 | - |
NasId | String | 否 | - |
MountDescs | String | 否 | - |
StorageType | String | 否 | - |
LocalVolume | String | 否 | - |
PackageUrl | String | 否 | - |
PackageVersion | String | 否 | - |
JDK | String | 否 | - |
WebContainer | String | 否 | - |
EdasContainerVersion | String | 否 | - |
UriEncoding | String | 否 | - |
UseBodyEncoding | Boolean | 否 | - |
UpdateStrategy | String | 否 | - |
MCpuRequest | Integer | 否 | - |
MCpuLimit | Integer | 否 | - |
傳回參數
名稱 | 類型 | 示例值 | 描述 |
ChangeOrderId | String | cd65b247-****-475b-ad4b-7039040d625c | 調用 GetChangeOrderInfo 接口擷取這次部署具體執行進展。 |
Code | Integer | 200 | code碼 |
Message | String | success | 資訊 |
RequestId | String | a5281053-08e4-47a5-b2ab-5c0323de7b5a | 請求唯一标示ID |
請求示例
public class DeployK8sApplictionSimpleInfo {
public String deployK8sApplication() {
//請填寫阿裡雲主賬号或子賬号 AccessKey ID.
String aliyun_user_ak = "your_ AccessKey ID ";
//請填寫阿裡雲主賬号或子賬号 AccessKey Secret.
String aliyun_user_sk = "your_ AccessKey Secret ";
//請填寫要執行 API 調用的應用所在地域 ID.
String region_id = "your_regionid";
DefaultProfile defaultProfile = DefaultProfile.getProfile(region_id,
aliyun_user_ak, aliyun_user_sk);
DefaultAcsClient defaultAcsClient = new
DefaultAcsClient(defaultProfile);
DeployK8sApplicationRequest request = new DeployK8sApplicationRequest();
request.setAppId("f66a22ec-c98d-4b79-ab41-c8641bf9ac87");
request.setEndpoint("edas-api.console. your_regionId.cloud.poc2.com");
request.setImage("cr.registry.cloud.poc2.com/pdsa/k8s-nacos-consumer:v2");
request.setImageTag("v2");
request.setJDK("Open JDK 8");
request.setEnvs("[{\"name\":\"updatetime\",\"value\":\""+ new Date() + "\"}]");
DeployK8sApplicationResponse response;
String resp = "";
try {
response = defaultAcsClient.getAcsResponse(request);
resp = "傳回碼:" +response.getCode() + "----" + "傳回資訊:" + response.getMessage();
System.out.printf("傳回碼:" + response.getCode() + "----" + "傳回資訊:" + response.getMessage());
}catch (ClientException e) {
e.printStackTrace();
}
return resp;
}
}
傳回示例
DeployK8sApplicationResponse response;
String resp = "";
try {
response = defaultAcsClient.getAcsResponse(request);
resp = "傳回碼:" +response.getCode() + "----" + "傳回資訊:" + response.getMessage();
System.out.printf("傳回碼:" + response.getCode() + "----" + "傳回資訊:" + response.getMessage());
}catch (ClientException e) {
e.printStackTrace();
}
return resp;