小夥!Kubernetes 部署如此簡單,你看徹底明白了

將項目遷移到k8s平臺是怎樣實現的?html

  1. 製做鏡像
  2. 控制器管理Pod
  3. Pod數據持久化
  4. 暴露應用
  5. 對外發布應用
  6. 日誌/監控

一、製做鏡像分爲三步

  • 第一基礎鏡像,是基於哪一個操做系統,好比Centos7或者其餘的
  • 第二步中間件鏡像,好比服務鏡像,跑的像nginx服務,tomcat服務
  • 第三步項目鏡像,它是服務鏡像之上的,將你的項目打包進去,那麼這個項目就能在你這個服務鏡像裏面運行了

通常運維人員都是提早將鏡像作好,而開發人員就能直接拿這個鏡像去用,這個鏡像必定要符合如今環境部署的環境。java

二、控制器管理 pod

也就是k8s去部署這個鏡像了,通常咱們都會去拿控制器去部署,用的最多的就是 deploymentnode

  • Deployment:無狀態部署
  • StatefulSet:有狀態部署
  • DaemonSet:守護進程部署
  • Job & CronJob:批處理

無狀態和有狀態的有什麼區別?nginx

有狀態的是有身份的,好比網絡ID、存儲、這個兩個是提早規劃好的,有序啓動/中止git

持久化與非持久化web

三、Pod 數據持久化

pod數據持久化主要是因對一個應用程序說的,好比開發一個項目,這個項目有沒有落地到本地文件,若是有落的話,就保證他持久的有了,那就必需要用到pod數據的持久化了。docker

容器部署過程當中通常有如下三種數據:數據庫

  • 啓動時須要的初始數據,能夠是配置文件
  • 啓動過程當中產生的臨時數據,該臨時數據須要多個容器間共享
  • 啓動過程當中產生的持久化數據

四、暴露應用

在 k8s中,部署一個deployment,它是沒法對外進行訪問的,即其餘應用程序要想訪問部署的deployment,它找不到該怎麼去訪問。爲何去這麼講,由於deployment通常都是多副本的去部署,有可能會分佈在不一樣的節點之上,並且重建 pod ip也會變,從新發布一下也會變了,因此沒有辦法去固定去訪問哪一個pod,即便固定了,其餘的pod也訪問不了。json

要想作到多個 pod 都去提供服務的話,前面有必需要加一個負載均衡,提供一個訪問入口,只有訪問這個統一入口,才能轉發到後端多個pod上,只要訪問這個Cluster IP就能轉發到後端的pod上。vim

Service

  • Service 定義了 Pod 的邏輯集合和訪問這個集合的策略
  • Service 引入爲了解決Pod的動態變化,提供服務發現和負載均衡
  • 使用 CoreDNS 解析 Service 名稱

五、對外發布應用

暴露出去以後呢,也就是須要讓用戶去訪問,好比搭建一個電商網站,讓用戶去訪問,ingress相對於service,它是一個互補的狀態,彌補了各自,service主要提供了集羣內部的訪問,也能夠暴露一個TCP/UDP的端口,而ingress主要是一個7層的轉發,也就是提供一個統一的入口,只要訪問ingress controller,它就能幫你轉發你部署全部的項目,也就是全部的項目都使用域名去訪問。

首先開發者將代碼部署到你的代碼倉庫中,主流的用的Git或者gitlab,提交完代碼經過CI/CD平臺須要對代碼進行拉取、編譯、構建,產生一個War包,而後交給Ansible而後發送到雲主機上/物理機,而後經過負載均衡將項目暴露出去,而後會有數據庫,監控系統,日誌系統來提供相關的服務。

首先也是開發將代碼放在代碼倉庫,而後經過jenkins去完成拉取代碼,編譯,上傳到咱們的鏡像倉庫。

這裏是將代碼打包成一個鏡像,而不是能夠執行的war或者jar包,這個鏡像包含了你的項目的運行環境和項目代碼,這個鏡像能夠放在任何docker上去run起來,均可以去訪問,首先得保證可以在docker上去部署起來,再部署到k8s上,打出來的鏡像去放在鏡像倉庫中,來集中的去管理這些鏡像。

由於天天會產生幾十個或者上百個鏡像,必須經過鏡像倉庫去管理,這裏可能會去寫一個腳本去鏈接k8smaster,而k8s會根據本身的部署去調度這些pod,而後經過ingress去發佈咱們的應用,讓用戶去訪問,每一個ingress會關聯一組pod,而service會建立這組pod的負載均衡,經過service去區分這些節點上的Pod。

而後數據庫是放在集羣以外,監控系統日誌系統也能夠放在k8s集羣放在去部署,也能夠放在以外,咱們是放在k8s集羣內的,也不是特別敏感,主要用來運維和開發調試用的,不會影響到咱們的業務,因此咱們優先去k8s中去部署。

如今以部署一個JAVA項目到咱們的k8s中

1、安裝一個openjdk

[root@k8s-master ~]# yum -y install java-1.8.0-openjdk.x86_64 maven
[root@k8s-master ~]# java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

而後咱們將代碼拉到本地通常Dockerfile中跟咱們的代碼都放在同一目錄下,

[root@k8s-master tomcat-java-demo-master]# ls
db  Dockerfile  LICENSE  pom.xml  README.md  src
[root@k8s-master tomcat-java-demo-master]# vim Dockerfile
FROM lizhenliang/tomcat
LABEL maintainer zhaochengcheng
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war

2、進行編譯

這裏咱們須要配置maven的國內源,這樣的話就比較快一點

[root@k8s-master CI]# vim /etc/maven/settings.xml
<mirror>      
  <id>central</id>      
  <mirrorOf>central</mirrorOf>      
  <name>aliyun maven</name>  
   <url>https://maven.aliyun.com/repository/public</url> 
  </mirror>  
</mirrors>
[root@k8s-master tomcat-java-demo-master]# mvn clean package -D maven test.skip=true  
[root@k8s-master tomcat-java-demo-master]# ls  
db Dockerfile LICENSE pom.xml README.md src target  
[root@k8s-master tomcat-java-demo-master]# cd target/  
[root@k8s-master target]# ls  
classes generated-sources ly-simple-tomcat-0.0.1-SNAPSHOT ly-simple-tomcat-0.0.1-SNAPSHOT.war maven-archiver maven-status  
[root@k8s-master tomcat-java-demo-master]# cd target/

咱們就使用這個編譯好的war包,而後打成鏡像,上傳到咱們的Harbor倉庫裏

[root@k8s-master target]# ls
classes            ly-simple-tomcat-0.0.1-SNAPSHOT      maven-archivergenerated-sources  
ly-simple-tomcat-0.0.1-SNAPSHOT.war  maven-status

[root@k8s-master tomcat-java-demo-master]# docker build -t 192.168.30.24/library/java-demo:latest .

3、上傳到鏡像倉庫

[root@k8s-master tomcat-java-demo-master]# docker login 192.168.30.24
Username: admin
Password:
Error response from daemon: Get https://192.168.30.24/v2/: dial tcp 192.168.30.24:443: connect: connection refused

這裏報錯,其實咱們須要在每臺docker下都要寫入對harbor倉庫的信任才能夠,後面上傳鏡像也會用

[root@k8s-master java-demo]# vim /etc/docker/daemon.json
{        
  "registry-mirrors":["http://f1361db2.m.daocloud.io"],     
  "insecure-registries": ["192.168.30.24"]
    }

再等錄一下push就能夠了

[root@k8s-master tomcat-java-demo-master]# docker push 192.168.30.24/library/java-demo:latest

4、控制器管理pod

編寫deployment,通常項目都寫到自定義的命名空間下,名稱寫項目名稱,方便記憶,name: tomcat-java-demo
namespace: test

另外就是下一個項目名稱,這裏分爲多個,通常有不少的組件組成,因此下面能夠寫個app的名稱,好比組件一、二、3,起碼標籤有這兩個維度
project: www
app: java-demo

另外就是鏡像拉取,在哪一個倉庫去下載,這裏我建議鏡像倉庫的項目名稱和咱們定義的是一種,避免混了。我從新打個標籤,並傳到咱們的私有鏡像倉庫中

[root@k8s-master java-demo]# docker tag 192.168.30.24/library/java-demo  192.168.30.24/tomcat-java-demo/java-demo

[root@k8s-master java-demo]# docker push 192.168.30.24/tomcat-java-demo/java-demo:latest

鏡像地址也改一下地址

imagePullSecrets:  
 - name: registry-pull-secret  
containers:  
 - name: tomcat  
image: 192.168.30.24/tomcat-java-demo/java-demo:latest

如今開始建立 yaml

建立項目的命名空間

[root@k8s-master java-demo]# vim namespace.yaml  
apiVersion: v1  
kind: Namespace  
metadata:  
name: test  
  
[root@k8s-master java-demo]# kubectl create -f namespace.yaml  
namespace/test created  
[root@k8s-master java-demo]# kubectl get ns  
NAME STATUS AGE  
default Active 22h  
kube-node-lease Active 22h  
kube-public Active 22h  
kube-system Active 22h  
test Active 5s

建立一個secret來保證咱們harbor鏡像倉庫的認證信息,這裏必定要寫上咱們的項目的命名空間。

[root@k8s-master java-demo]# kubectl create secret docker-registry registry-pull-secret --docker-username=admin --docker-password=Harbor12345 --docker-email=111@qq.com --docker-server=192.168.30.24 -n test  
secret/registry-pull-secret created  
[root@k8s-master java-demo]# kubectl get ns  
NAME STATUS AGE  
default Active 23h  
kube-node-lease Active 23h  
kube-public Active 23h  
kube-system Active 23h  
test Active 6m39s  
[root@k8s-master java-demo]# kubectl get secret  
NAME TYPE DATA AGE  
default-token-2vtgm kubernetes.io/service-account-token 3 23h  
registry-pull-secret kubernetes.io/dockerconfigjson 1 46s  
  
[root@k8s-master java-demo]# vim deployment.yaml  
apiVersion: apps/v1beta1  
kind: Deployment  
metadata:  
name: tomcat-java-demo  
namespace: test  
spec:  
replicas: 3  
selector:  
matchLabels:  
project: www  
app: java-demo  
template:  
metadata:  
labels:  
project: www  
app: java-demo  
spec:  
imagePullSecrets:  
 - name: registry-pull-secret  
containers:  
 - name: tomcat  
image: 192.168.30.24/tomcat-java-demo/java-demo:latest  
imagePullPolicy: Always  
ports:  
 - containerPort: 8080  
name: web  
protocol: TCP  
resources:  
requests:  
cpu: 0.5  
memory: 1Gi  
limits:  
cpu: 1  
memory: 2Gi  
livenessProbe:  
httpGet:  
path: /  
port: 8080  
initialDelaySeconds: 60  
timeoutSeconds: 20  
readinessProbe:  
httpGet:  
path: /  
port: 8080  
initialDelaySeconds: 60  
timeoutSeconds: 20  
  
[root@k8s-master java-demo]# kubectl get pod -n test  
NAME READY STATUS RESTARTS AGE  
tomcat-java-demo-6d798c6996-fjjvk 1/1 Running 0 2m58s  
tomcat-java-demo-6d798c6996-lbklf 1/1 Running 0 2m58s  
tomcat-java-demo-6d798c6996-strth 1/1 Running 0 2m58s

另外就是暴露一個Service,這裏的標籤也要保持一致,否則他找不到相應的標籤就提供不了服務,這裏咱們是使用ingress來訪問發佈應該,直接使用ClusterIP就能夠

[root@k8s-master java-demo]# vim service.yaml  
apiVersion: v1  
kind: Service  
metadata:  
name: tomcat-java-demo  
namespace: test  
spec:  
selector:  
project: www  
app: java-demo  
ports:  
 - name: web  
port: 80  
targetPort: 8080  
  
[root@k8s-master java-demo]# kubectl get pod,svc -n test  
NAME READY STATUS RESTARTS AGE  
pod/tomcat-java-demo-6d798c6996-fjjvk 1/1 Running 0 37m  
pod/tomcat-java-demo-6d798c6996-lbklf 1/1 Running 0 37m  
pod/tomcat-java-demo-6d798c6996-strth 1/1 Running 0 37m  
  
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE  
service/tomcat-java-demo ClusterIP 10.1.175.191 <none> 80/TCP 19s

測試訪問咱們的項目,是能夠的,如今要發佈出去經過ingress

測試訪問咱們的項目,是能夠的,如今要發佈出去經過ingress

[root@k8s-master java-demo]# curl 10.1.175.191  
<!DOCTYPE html>  
<html>  
<head lang="en">  
<meta charset="utf-8">  
<meta http-equiv="X-UA-Compatible" content="IE=edge">  
<title>把美女帶回家應用案例</title>  
<meta name="description" content="把美女帶回家應用案例">  
<meta name="keywords" content="index">

如今部署一個ingress-nginx的控制器,這個網上均可以找到,官方也有,我這裏是按DaemonSet的方式去部署的,因此每一個節點都會跑一個控制器。

[root@k8s-master java-demo]# kubectl get pod -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-g95pp   1/1     Running   0          3m6s
nginx-ingress-controller-wq6l6   1/1     Running   0          3m6s

發佈應用

這裏注意兩點,第一個就是網站域名,一個是service的命名空間。

[root@k8s-master java-demo]# kubectl get pod,svc -n test  
NAME READY STATUS RESTARTS AGE  
pod/tomcat-java-demo-6d798c6996-fjjvk 1/1 Running 0 53m  
pod/tomcat-java-demo-6d798c6996-lbklf 1/1 Running 0 53m  
pod/tomcat-java-demo-6d798c6996-strth 1/1 Running 0 53m  
  
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE  
service/tomcat-java-demo ClusterIP 10.1.175.191 <none> 80/TCP 16m  
[root@k8s-master java-demo]# vim service.yaml  
[root@k8s-master java-demo]# kubectl create -f ingress.yaml  
apiVersion: extensions/v1beta1  
kind: Ingress  
metadata:  
name: tomcat-java-demo  
namespace: test  
spec:  
rules:  
 - host: java.maidikebi.com  
http:  
paths:  
 - path: /  
backend:  
serviceName: tomcat-java-demo  
servicePort: 80

另外我這邊是測試的,因此綁定我本地的hosts來進行訪問,在hosts文件裏面加入域名和和節點ip就能訪問到咱們的項目了。

相關文章
相關標籤/搜索