目錄

  1. 專案概述
  2. 前置需求
  3. 第一階段:基礎設施設置
  4. 第二階段:應用設置與容器化
  5. 第三階段:使用 Jenkins CI/CD 自動化
  6. 第四階段:使用 HashiCorp Vault 保護機密資料
  7. 第五階段:Kubernetes 部署
  8. 第六階段:Kubernetes 中的安全加固
  9. 結論

專案概述

在這個 DevSecOps 專案中,您將使用 Jenkins、Docker、Kubernetes 和 HashiCorp Vault 部署一個安全的全棧 Node.js 網頁應用程式。專案將重點自動化整個部署過程,並在每個階段整合安全措施。我們將掃描 Docker 映像中的漏洞,安全地管理敏感資訊,並在 Kubernetes 叢集中部署應用程式,確保安全性貫穿始終。


前置需求

  1. AWS 帳戶(用於託管 EKS Kubernetes 叢集)。
  2. 本地或雲端的 Jenkins 伺服器。
  3. 在您的本地機器上安裝 Docker 和 Kubernetes CLI (kubectl)。
  4. 安裝 Terraform 以進行基礎設施配置。
  5. 安裝 HashiCorp Vault 以管理機密資料。
  6. 對 Node.js、Docker、Kubernetes 和 Jenkins 有基本了解。

第一階段:基礎設施設置

1.1 配置 Kubernetes 叢集 (EKS)

我們將使用 Terraform 在 AWS 上配置 EKS(彈性 Kubernetes 服務)叢集。

a. 安裝 Terraform:
# 安裝 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
b. 定義 Terraform 配置:

創建一個名為 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
}
c. 應用 Terraform 配置:
terraform init
terraform apply

叢集建立完成後,配置 kubectl 以指向您的新叢集:

aws eks --region us-west-2 update-kubeconfig --name devsecops-cluster

1.2 設置 Jenkins 伺服器

在本地機器或雲端伺服器上安裝 Jenkins。Jenkins 將自動化我們的 Node.js 應用程式的構建、測試和部署。

a. 安裝 Jenkins:
# 安裝 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 整合。


第二階段:應用設置與容器化

2.1 Node.js 網頁應用程式 (原始碼)

對於這個專案,我們將使用一個簡單的 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

2.2 創建 Dockerfile

創建一個 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"]

2.3 構建與測試 Docker 映像

a. 構建 Docker 映像:
docker build -t devsecops-nodejs-app .
b. 在本地運行 Docker 容器:
docker run -p 3000:3000 devsecops-nodejs-app

訪問 http://localhost:3000 以查看運行中的應用。


第三階段:使用 Jenkins CI/CD 自動化

3.1 Jenkins 管道設置

設置 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 保護機密資料

整合 HashiCorp Vault 以安全管理敏感數據,如資料庫憑證、API 金鑰和令牌。

4.1 安裝 HashiCorp Vault:

# 安裝 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

4.2 配置 Vault 用於 Kubernetes:

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 部署

在這一階段,我們將使用 Kubernetes 清單 將 Node.js 應用程式部署到 Kubernetes 叢集。部署過程包括創建資源,如 Deployment 和 Service 對象,定義我們的應用如何在叢集中運行。

5.1 創建 Kubernetes 部署檔案 (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  # 將應用暴露到互聯網

5.2 部署應用程式

現在,使用 kubectl 將應用程式部署到 Kubernetes 叢集中。

a. 應用部署和服務:
kubectl apply -f deployment.yaml
b. 驗證部署:
kubectl get deployments
c. 檢查 Pods:
kubectl get pods
d. 獲取服務的外部 IP:
kubectl get services

一旦服務運行,您可以使用負載均衡器提供的外部 IP 地址訪問 Node.js 應用。

5.3 使用 Kubernetes 處理機密資料

在 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 傳遞給應用容器,您的應用可以安全地讀取它。


第六階段:Kubernetes 中的安全加固

在這一階段,我們將通過實施 PodSecurityPolicies、RBAC 和 Network Policies 來增強 Kubernetes 部署的安全性。

6.1 PodSecurityPolicies (PSP)

PodSecurityPolicies 用於控制 Pod 的安全層面,例如特權容器執行、卷類型、主機網絡等。您可以創建一個政策,以防止容器以 root 使用者身份運行。

範例 PodSecurityPolicy (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

6.2 基於角色的存取控制 (RBAC)

RBAC 允許在 Kubernetes 中進行細粒度的存取控制。定義授予用戶或服務特定權限的角色。

範例 RBAC 配置 (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

6.3 網路策略

網路策略 定義允許或拒絕 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 應用程式安全部署過程。通過整合漏洞掃描和機密管理等安全實踐,我們確保應用程序在生產環境中安全部署。


👤 作者

banner

加入我們的 Telegram 社群 || Follow me on GitHub 獲取更多 DevOps 內容!


原文出處:https://dev.to/prodevopsguytech/devsecops-project-secure-full-stack-nodejs-web-application-deployment-with-jenkins-docker-kubernetes-and-hashicorp-vault-166


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝45   💬1  
729
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登