k8s 部署 Java 專案

運維工作棧發表於2020-12-05

前幾天安裝了 k8s 並測試了自動伸縮功能(HPA),今天來部署一個簡單的 Java 應用到 k8s。

 

開始之前需要先安裝一下 ingress 外掛。ingress 作為 k8s 的流量入口,有多種實現。我知道的有 traefik,haproxy-ingress,ingress-nginx。今天以 ingress-nginx 為例來部署。

 

1. 部署 ingress-nginx

1.1 由於網路的原因我們還是先拉取映象。(每個節點都要拉取)

docker pull ninejy/ingress-nginx-controller:v0.41.0
docker tag ninejy/ingress-nginx-controller:v0.41.0 k8s.gcr.io/ingress-nginx/controller:v0.41.0

 

1.2 下載並修改 deploy.yaml 檔案

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.0/deploy/static/provider/baremetal/deploy.yaml
# 332 行 映象後面的一串字串去掉,因為我們的 docker tag 後面沒跟這一串字元,(太長了 ^_^)

 

1.3 安裝 ingress-nginx

kubectl apply -f deploy/yaml

kubectl get pod -n ingress-nginx
# 執行這個命令看到類似下圖的內容就說明 ingress-nginx 安裝成功了

 

2. 部署 Java 應用到 k8s

2.1 建立 jenkins 任務

    jenkins 任務依然是 pipeline 風格的,下面是 pipeline file

pipeline {
    agent any
    stages {
        stage('clone code from gitlab') {
            steps {
                checkout([$class: 'GitSCM',
                branches: [[name: "master"]],
                userRemoteConfigs: [[
                    credentialsId: 'gitlab-robot',
                    refspec: "+refs/heads/*:refs/remotes/origin/*",
                    url: 'ssh://git@192.168.0.11:8222/examples/spring-boot-helloworld.git']]
                ])
            }
        }
        stage('mvn clean package') {
            steps {
                sh '''
                    mvn clean package -Dmaven.test.skip=true
                '''
            }
            
        }
        stage('docker build && docker push') {
            steps {
                script{
                    withDockerRegistry(credentialsId: 'docker-hub', url: 'https://index.docker.io/v1/') {
                        def myappImage = docker.build "ninejy/examples-helloworld", "-f Dockerfile ." 
                        myappImage.push()
                    }
                }
            }
        }
        stage('deploy to k8s') {
            steps {
                sh '''
                    kubectl apply -f /data/k8s-yaml/deploy-examples-helloworld.yaml
                '''
            }
        }
        stage('clean dir') {
            steps {
                sh '''
                    echo "clean workspace"
                '''
            }
            post {
                always {
                    cleanDir()
                }
            }
        }
    }
}

 

deploy-examples-helloworld.yaml 的內容

apiVersion: apps/v1
kind: Deployment
metadata:
  name: examples-helloworld
spec:
  replicas: 2
  selector:
    matchLabels:
      name: helloworld
  template:
    metadata:
      labels:
        name: helloworld
    spec:
      containers:
      - name: helloworld
        image: ninejy/examples-helloworld
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            port: 8080
            path: /healthy
          initialDelaySeconds: 20
          periodSeconds: 3
        livenessProbe:
          httpGet:
            port: 8080
            path: /healthy
          initialDelaySeconds: 20
          periodSeconds: 3
          timeoutSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: examples-helloworld-svc
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    name: helloworld
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: www.ninejy.io
spec:
  rules:
  - host: www.ninejy.io
    http:
      paths:
      - path: /
        backend:
          serviceName: examples-helloworld-svc
          servicePort: 80

 

說明:

    1. jenkins 伺服器要能夠訪問 k8s 叢集(網路通)

    2. jenkins 伺服器上有可用的 kubectl 命令

    3. jenkins 伺服器上在執行 jenkins 程式的使用者家目錄有訪問 k8s 的有效憑證。~/.kube/config。這裡為演示簡單,直接拷貝 k8s-master 節點的檔案。

    4. 這裡使用的 docker 映象倉庫是 hub.docker.com 網路很慢,可以自己搭建 harbor。

    5. readinessProbe.initialDelaySeconds 這個值的設定很關鍵,這是 k8s 就緒檢測的設定,由這個測試程式啟動需要十幾秒,所以這裡設定了 20s,如果設定時間太短會導致容器多次重啟最終達到最大重啟次數,然後啟動失敗。

 

2.2 準備工作做好之後就可以手動執行 jenkins 任務了。jenkins 任務成功執行之後到 k8s-master 節點檢視

kubectl get svc
kubectl get ingress
kubectl get pod

有類似下圖的輸出就說明部署成功了

 

2.3. 配置 nginx

    叢集外部我們還需要安裝一個 nginx 用來代理 ingress-nginx-controller

    先檢視 ingress-nginx-controller 的 nodePort

kubectl get svc -n ingress-nginx

 

nginx 配置檔案,配置好之後記得重啟 nginx 服務

# cat www-ninejy-io.conf
server {
    listen 80;
    server_name www.ninejy.io;

    location / {
        proxy_set_header Host $host;
        proxy_pass http://192.168.0.6:31901;
    }
    
    access_log /var/log/nginx/www-access.log;
}

 

2.4 解析域名

    由於我的域名沒有在dns伺服器上解析,所以需要綁 hosts 訪問

192.168.0.61 www.ninejy.io
# 上面這一行寫到 hosts 檔案中,注意換成自己的 k8s 叢集外 nginx 伺服器的IP

 

2.5 訪問測試

    瀏覽器中輸入:http://www.ninejy.io/hello

    有下面的結果就說明所有配置都成功了。

 

 

以上實驗中的 Java 程式程式碼在 https://github.com/ninejy-io/spring-boot-helloworld

 

相關文章