前幾天安裝了 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
