在這個 DevSecOps 專案中,您將使用 Jenkins、Docker、Kubernetes 和 HashiCorp Vault 部署一個安全的全棧 Node.js 網頁應用程式。專案將重點自動化整個部署過程,並在每個階段整合安全措施。我們將掃描 Docker 映像中的漏洞,安全地管理敏感資訊,並在 Kubernetes 叢集中部署應用程式,確保安全性貫穿始終。
kubectl
)。我們將使用 Terraform 在 AWS 上配置 EKS(彈性 Kubernetes 服務)叢集。
# 安裝 Terraform (Linux/macOS)
wget https://releases.hashicorp.com/terraform/1.0.11/terraform_1.0.11_linux_amd64.zip
unzip terraform_1.0.11_linux_amd64.zip
sudo mv terraform /usr/local/bin/
terraform --version
創建一個名為 eks-cluster.tf
的檔案,用於配置 EKS 叢集。
provider "aws" {
region = "us-west-2"
}
resource "aws_eks_cluster" "my_cluster" {
name = "devsecops-cluster"
role_arn = aws_iam_role.eks_role.arn
vpc_config {
subnet_ids = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
}
}
resource "aws_iam_role" "eks_role" {
name = "eks-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
terraform init
terraform apply
叢集建立完成後,配置 kubectl
以指向您的新叢集:
aws eks --region us-west-2 update-kubeconfig --name devsecops-cluster
在本地機器或雲端伺服器上安裝 Jenkins。Jenkins 將自動化我們的 Node.js 應用程式的構建、測試和部署。
# 安裝 Java(Jenkins 所需)
sudo apt update
sudo apt install openjdk-11-jdk
# 添加 Jenkins 倉庫並安裝 Jenkins
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update
sudo apt install jenkins
# 啟動 Jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
安裝後,配置 Jenkins 插件以進行 Kubernetes、Docker 和 Vault 整合。
對於這個專案,我們將使用一個簡單的 Node.js 網頁應用程式。創建以下檔案:
app.js
:const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello from DevSecOps Node.js App!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
package.json
:{
"name": "devsecops-nodejs-app",
"version": "1.0.0",
"description": "A simple Node.js app for DevSecOps project",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.17.1"
}
}
運行 npm install
以安裝依賴項:
npm install
創建一個 Dockerfile 用於容器化 Node.js 應用。
# 使用官方 Node.js 執行環境作為父映像
FROM node:14
# 設置工作目錄
WORKDIR /usr/src/app
# 複製 package.json 並安裝依賴項
COPY package*.json ./
RUN npm install
# 將應用程式源碼打包
COPY . .
# 開放應用程式埠
EXPOSE 3000
# 執行應用程式
CMD ["npm", "start"]
docker build -t devsecops-nodejs-app .
docker run -p 3000:3000 devsecops-nodejs-app
訪問 http://localhost:3000
以查看運行中的應用。
設置 Jenkins 管道以自動構建 Docker 映像、掃描漏洞、將映像推送到 DockerHub,並部署到 Kubernetes。
在您的專案庫中創建一個 Jenkinsfile
:
pipeline {
agent any
stages {
stage('Clone Repository') {
steps {
git 'https://github.com/your-repo.git'
}
}
stage('Build Docker Image') {
steps {
script {
docker.build("devsecops-nodejs-app:${env.BUILD_ID}")
}
}
}
stage('Security Scan') {
steps {
// 使用 Trivy 掃描 Docker 映像中的漏洞
sh 'docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest image devsecops-nodejs-app:${env.BUILD_ID}'
}
}
stage('Push Image to DockerHub') {
steps {
script {
docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-credentials') {
docker.image("devsecops-nodejs-app:${env.BUILD_ID}").push()
}
}
}
}
stage('Deploy to Kubernetes') {
steps {
kubernetesDeploy(kubeconfigId: 'kubeconfig', configs: 'k8s/deployment.yaml', enableConfigSubstitution: true)
}
}
}
}
整合 HashiCorp Vault 以安全管理敏感數據,如資料庫憑證、API 金鑰和令牌。
# 安裝 Vault
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install vault
vault auth enable kubernetes
vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host="https://$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.server}')" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
在這一階段,我們將使用 Kubernetes 清單 將 Node.js 應用程式部署到 Kubernetes 叢集。部署過程包括創建資源,如 Deployment 和 Service 對象,定義我們的應用如何在叢集中運行。
deployment.yaml
)Deployment 資源確保所需數量的應用實例(Pods)正在運行。如果一個 Pod 失敗,Kubernetes 將自動重新創建以滿足指定的副本計數。
創建一個名為 deployment.yaml
的檔案,內容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: devsecops-nodejs-app
labels:
app: devsecops-nodejs-app
spec:
replicas: 3 # 我們將運行 3 個應用實例 (Pods)
selector:
matchLabels:
app: devsecops-nodejs-app
template:
metadata:
labels:
app: devsecops-nodejs-app
spec:
containers:
- name: devsecops-nodejs-container
image: your-dockerhub-username/devsecops-nodejs-app:latest # 使用您的 DockerHub 倉庫
ports:
- containerPort: 3000
env:
- name: SECRET_MESSAGE
valueFrom:
secretKeyRef:
name: app-secret
key: secret-message # 會通過 Kubernetes 機密從 Vault 獲取秘密值
---
apiVersion: v1
kind: Service
metadata:
name: devsecops-nodejs-service
spec:
selector:
app: devsecops-nodejs-app
ports:
- protocol: TCP
port: 80 # 將服務暴露在 80 埠上
targetPort: 3000 # 內部轉發流量到容器的 3000 埠
type: LoadBalancer # 將應用暴露到互聯網
現在,使用 kubectl
將應用程式部署到 Kubernetes 叢集中。
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get pods
kubectl get services
一旦服務運行,您可以使用負載均衡器提供的外部 IP 地址訪問 Node.js 應用。
在 Deployment 清單中,我們引用了 Kubernetes Secret 對象,該對象由 HashiCorp Vault 安全管理。我們將 Vault 與 Kubernetes 整合,以便在運行時安全注入敏感數據,例如 API 金鑰、密碼或資料庫憑證到 Pods。
要在 Kubernetes 中創建一個機密,可以運行:
kubectl create secret generic app-secret \
--from-literal=secret-message="This is a secret from Vault!"
此機密將通過環境變數 SECRET_MESSAGE
傳遞給應用容器,您的應用可以安全地讀取它。
在這一階段,我們將通過實施 PodSecurityPolicies、RBAC 和 Network Policies 來增強 Kubernetes 部署的安全性。
PodSecurityPolicies 用於控制 Pod 的安全層面,例如特權容器執行、卷類型、主機網絡等。您可以創建一個政策,以防止容器以 root 使用者身份運行。
pod-security-policy.yaml
):apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted-psp
spec:
privileged: false
runAsUser:
rule: MustRunAsNonRoot
fsGroup:
rule: MustRunAs
ranges:
- min: 1
max: 65535
seLinux:
rule: RunAsAny
supplementalGroups:
rule: MustRunAs
ranges:
- min: 1
max: 65535
volumes:
- configMap
- secret
將政策應用到 Kubernetes 叢集:
kubectl apply -f pod-security-policy.yaml
RBAC 允許在 Kubernetes 中進行細粒度的存取控制。定義授予用戶或服務特定權限的角色。
rbac.yaml
):apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: app-deployer
rules:
- apiGroups: ["apps", "extensions"]
resources: ["deployments"]
verbs: ["create", "update", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-deployer-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: app-deployer
subjects:
- kind: User
name: jenkins # 將部署應用程式的 Jenkins 服務帳戶
apiGroup: rbac.authorization.k8s.io
應用 RBAC 政策:
kubectl apply -f rbac.yaml
網路策略 定義允許或拒絕 Pod 之間通信的流量規則。使用它們可以確保 Pod 之間的通信安全,並限制對應用的訪問。
network-policy.yaml
):apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-only-internal-traffic
namespace: default
spec:
podSelector:
matchLabels:
app: devsecops-nodejs-app
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: internal-service
這項政策限制對 devsecops-nodejs-app
Pods 的流量,僅允許來自標記為 internal-service
的 Pods 的通信。
應用網路策略:
kubectl apply -f network-policy.yaml
這個專案展示了使用 Jenkins、Docker、Kubernetes 和 HashiCorp Vault 完整的 Node.js 應用程式安全部署過程。通過整合漏洞掃描和機密管理等安全實踐,我們確保應用程序在生產環境中安全部署。
加入我們的 Telegram 社群 || Follow me on GitHub 獲取更多 DevOps 內容!