第9章 项目部署到kubernetes平台

一. 准备工作与注意事项

1. 部署的项目情况

(1) 业务架构及服务(dubbo, spring cloud)
(2) 第三方服务,例如mysql, redis, zookeeper, eruke, mq
(3) 服务之间怎么通信
(4) 资源消耗:硬件资源,带宽

2. 项目部署涉及相关k8s资源

(1) 使用namespace 进行不同项目隔离,或者隔离不同环境( test, prod, dev)
(2) 无状态应用(deployment)
(3) 有状态应用(statefulset, pv, pvc)
(4) 发布暴露外部访问( Service, ingress)
(5) 存储一些数据(secret, configmap)

3. 项目的基础镜像

4. 编排部署(镜像为交付物)

https://github.com/lizhenliang/tomcat-java-demo
https://github.com/lizhenliang/php-demo
代码仓库下都会有一个Dockerfile 镜像构建文件

(1). 持续集成与交付

项目构建(java),CI/CD 环境这个阶段自动完成(代码拉取->代码编译构建->镜像打包 -> 推送到镜像仓库)

(2). 编写yaml文件

编写yaml文件, 使用这个镜像

5. 持续部署

kubectl -> yaml -> 镜像仓库拉取镜像 -> Service(集群内部访问)/Ingress暴露外部用户访问

二. 部署Java项目

1. NFS网络存储准备

安装NFS服务,每个node节点都安装nfs客户端:

# yum install nfs-utils -y
# cat /etc/exports
/ifs/kubernetes *(rw,no_root_squash)

# mkdir /ifs/kubernetes -p
# systemctl start nfs

2. 配置NFS动态卷供给PV

下载三个yaml文件:
https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy
class.yaml 动态创建PV
deployment.yaml 创建控制及pod等资源
rbac.yaml deployment.yaml部署的pod时,需要访问api-server权限请求k8s的PV&PVC资源
注意: deployment.yaml中定义连接NFS的地址及目录

3. 部署私有镜像仓库harbor

https://www.jianshu.com/p/7ca6c59f9882
注意:私有镜像仓库-harbor 使用http访问必须在每个node做信任,并重启docker

# cat /etc/docker/daemon.json
{
  "registry-mirrors": ["http://bc437cce.m.daocloud.io"],
  "insecure-registries":["http://10.40.6.165"]
}

4. java代码拉取

用一个node节点clone java代码:

# yum install git -y 
# git clone https://github.com/lizhenliang/tomcat-java-demo.git
# cd tomcat-java-demo/
# ll
total 24
drwxr-xr-x 2 root root    34 Jun 15 11:40 db
-rw-r--r-- 1 root root   148 Jun 15 11:40 Dockerfile
-rw-r--r-- 1 root root 11357 Jun 15 11:40 LICENSE
-rw-r--r-- 1 root root  1930 Jun 15 11:40 pom.xml
-rw-r--r-- 1 root root    89 Jun 15 11:40 README.md
drwxr-xr-x 3 root root    18 Jun 15 11:40 src

要用容器化部署自己的项目,一般在你项目代码创建一个Dockerfile文件,使用Dockerfile构建项目镜像。

# cat Dockerfile 
FROM lizhenliang/tomcat 
LABEL maintainer www.ctnrs.com
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war 

5. maven和java环境准备

java是动态语言,需要构建war包或jar包,这构建需要maven和java环境

# tar xvf apache-maven-3.6.1-bin.tar.gz 
# tar xvf jdk-8u181-linux-x64.tar.gz 
#  mv apache-maven-3.6.1 /usr/local/services/
# mv jdk1.8.0_181 /usr/local/services/
# cat /etc/profile.d/java.sh
JAVA_HOME=/usr/local/services/jdk1.8.0_181
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME PATH

# source /etc/profile
# java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

# ln -sv /usr/local/services/apache-maven-3.6.1/bin/mvn /usr/bin/mvn

6. 项目代码编译

编译完成后会生产一个target 目录,此目录会有一个war包。

# cd tomcat-java-demo/
# mvn clean package
# ll target/
total 17840
drwxr-xr-x 5 root root       95 Jun 15 14:45 classes
drwxr-xr-x 3 root root       25 Jun 15 14:45 generated-sources
drwxr-xr-x 4 root root       37 Jun 15 14:46 ly-simple-tomcat-0.0.1-SNAPSHOT
-rw-r--r-- 1 root root 18265402 Jun 15 14:46 ly-simple-tomcat-0.0.1-SNAPSHOT.war
drwxr-xr-x 2 root root       28 Jun 15 14:46 maven-archiver
drwxr-xr-x 3 root root       35 Jun 15 14:45 maven-status

7. 构建项目镜像并推送至镜像仓库

通过Dockefile构建项目镜像

# cat Dockerfile 
FROM lizhenliang/tomcat 
LABEL maintainer www.ctnrs.com
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war

# docker build -t 10.40.6.165/project/java-demo:v1 .   ##docker build -t 镜像仓库推送地址
# docker login 10.40.6.165
# docker push 10.40.6.165/project/java-demo:v1    ##推到到镜像仓库

8. 编写部署项目yaml文件

yaml部署资源流程:
tomcat:
deployment
service
ingress


mysql:
statefuleset
healess service
pv,pvc(storageclass PV 自动供给 )

yaml文件:
namespace.yaml
deployment.yaml
ingress.yaml
service.yaml
mysql.yaml
registry-pull-secret.yaml
这些yaml文件可以统一写到一个yaml, 使用'---'分隔即可。

9. 创建项目资源

(1). 创建命名空间

# cat namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: test

#kubectl create -f namespace.yaml
# kubectl get ns -n test

(2). 创建镜像仓库Secret用户验证

拉取镜像需要用户验证,先创建kubernetes 登录镜像仓库的Secret用户验证,注意拉取镜像的yaml配置文件中Secret name字段,要与此创建的一致

# kubectl create secret --help
# kubectl create secret docker-registry --help
     ....
Usage:
kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email

指定Secret创建到 test命名空间,因为我们的项目创建在test命名空间

# kubectl create secret docker-registry registry-pull-secret --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@test.com --docker-server=10.40.6.165 -n test

# kubectl get secret -n test
NAME                   TYPE                                  DATA   AGE
default-token-vqllw    kubernetes.io/service-account-token   3      30m
registry-pull-secret   kubernetes.io/dockerconfigjson        1      69s

(3). 创建项目pod

# cat 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: 10.40.6.165/project/java-demo:v1 
        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

# kubectl create -f deployment.yaml
# kubectl get pod -n test

(4). 创建 service

# cat 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

# kubectl create -f service.yaml
# kubectl get svc -n test

(5). 创建ingress规则

# cat ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tomcat-java-demo 
  namespace: test
spec:
  rules:
    - host: java.ctnrs.com
      http:
        paths:
        - path: /
          backend:
            serviceName: tomcat-java-demo 
            servicePort: 80
# kubectl create -f ingress.yaml 
# kubectl get ingress -n test
# kubectl get pods,svc,ing -n test

10. 测试访问

# kubectl get pods -n ingress-nginx -o wide
NAME                                        READY   STATUS    RESTARTS   AGE    IP            NODE          NOMINATED NODE
nginx-ingress-controller-74cbc544f6-9v5qv   1/1     Running   0          2d3h   172.17.59.5   10.40.6.213   <none>
nginx-ingress-controller-74cbc544f6-qklwh   1/1     Running   0          2d3h   172.17.31.5   10.40.6.210   <none>

# kubectl get ing -n test
NAME               HOSTS            ADDRESS   PORTS   AGE
tomcat-java-demo   java.ctnrs.com             80      10m

绑定域名到ingress-nginx的节点IP上访问:
10.40.6.210 java.ctnrs.com
http://java.ctnrs.com

11. 创建数据库service、pod、PV和PVC

# cat mysql.yaml 
apiVersion: v1
kind: Service
metadata:
  name: java-demo-mysql
  namespace: test
  labels:
    project: java-demo
    app: mysql
spec:
  ports:
  - port: 3306
    name: java-demo-mysql
  clusterIP: None
  selector:
    project: java-demo
    app: mysql

---

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: db
  namespace: test
spec:
  selector:
    matchLabels:
      project: java-demo
      app: mysql
  serviceName: "java-demo-mysql"
  template:
    metadata:
      labels:
        project: java-demo
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7 
        env: 
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
        ports: 
        volumeMounts:
        - mountPath: "/var/lib/mysql"
          name: mysql-data
  volumeClaimTemplates:
  - metadata:
      name: mysql-data 
    spec:
      accessModes: ["ReadWriteMany"]
      storageClassName: "managed-nfs-storage"
      resources:
        requests:
          storage: 2Gi 

# kubectl create -f mysql.yaml
# kubectl get svc,pods -n test

# kubectl get pv,pvc -n test
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS          REASON   AGE
persistentvolume/pvc-03054e78-8f53-11e9-8287-005056b614b3   2Gi        RWX            Delete           Bound    test/mysql-data-db-0   managed-nfs-storage            14m

NAME                                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
persistentvolumeclaim/mysql-data-db-0   Bound    pvc-03054e78-8f53-11e9-8287-005056b614b3   2Gi        RWX            managed-nfs-storage   14m

12. 数据库配置

将tables_ly_tomcat.sql sql文件导入进去,并修改数据库连接

# scp  db/tables_ly_tomcat.sql 10.40.6.201:~   ##将文件拷贝到master节点
# kubectl cp /root/tables_ly_tomcat.sql db-0:/ -n test   ## 将sql文件cp到db-0容器中
# kubectl exec -it db-0 -n test bash
root@db-0:/# mysql -uroot -p123456
mysql> source /tables_ly_tomcat.sql
Query OK, 1 row affected (0.01 sec)

Database changed
Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.01 sec)
mysql> use test
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| user           |
+----------------+
1 row in set (0.00 sec)
mysql> desc user;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(100) | NO   |     | NULL    |                |
| age   | int(3)       | NO   |     | NULL    |                |
| sex   | char(1)      | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
4 rows in set (0.02 sec)

登录项目容器测试mysql容器域名:
域名格式:pod_name.service_name.namespace

# kubectl exec -it tomcat-java-demo-5f87cd895d-4zszj -n test bash
[root@tomcat-java-demo-5f87cd895d-4zszj tomcat]# ping -c 1 db-0.java-demo-mysql.test
PING db-0.java-demo-mysql.test.svc.cluster.local (172.17.59.6) 56(84) bytes of data.

# kubectl get pod -n test -o wide
NAME                                READY   STATUS    RESTARTS   AGE    IP            NODE          NOMINATED NODE
db-0                                1/1     Running   0          20m    172.17.59.6   10.40.6.213   <none>

修改项目连接数据库配置文件 src/main/resources/application.yml

# cat src/main/resources/application.yml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://db-0.java-demo-mysql.test:3306/test?characterEncoding=utf-8
    username: root
    password: 12345
    driver-class-name: com.mysql.jdbc.Driver
  freemarker:
    allow-request-override: false
    cache: true
    check-template-location: true
    charset: UTF-8
    content-type: text/html; charset=utf-8
    expose-request-attributes: false
    expose-session-attributes: false
    expose-spring-macro-helpers: false
    suffix: .ftl
    template-loader-path:
      - classpath:/templates/

更新代码后更新镜像,并推送到镜像仓库

# docker build -t 10.40.6.165/project/java-demo:v2 .
# docker push 10.40.6.165/project/java-demo:v2

修改deployment.yaml 项目镜像版本为:10.40.6.165/project/java-demo:v2
滚动更新项目:kubectl apply -f deployment.yaml
然后访问站点添加美女.

添加美女.png

今晚翻盘哪个美女.png

三. 部署PHP

部署跟java基本一致,只是代码不需要编译构建
clone代码 -> 制作代码镜像 -> 代码镜像推送至镜像仓库->编写yaml配置文件 ->创建资源对象

1. clone代码

git clone https://github.com/lizhenliang/php-demo.git

2. 构建项目镜像并推送至镜像仓库

这里的数据库就用上边java项目创建的数据库,修改php代码连接数据库的配置文件:

php代码连接数据库的配置文件
# cat php-demo/wp-config.php
      ....
/** MySQL主机 */
define('DB_HOST', 'db-0.java-demo-mysql.test');
     ....


代码目录php-demo中的Dockfile文件:
# cat Dockerfile
FROM lizhenliang/nginx-php:latest
MAINTAINER www.ctnrs.com
ADD . /usr/local/nginx/html

构建项目镜像,并推送到镜像仓库
# docker build -t 10.40.6.165/project/php-demo:1.0 .
# docker push 10.40.6.165/project/php-demo:1.0 

3. 编写yaml配置文件并创建资源对象

命名空间test 在java 项目已经创建,这里不再创建

(1). 创建pod

# cat deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: php-demo
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      project: www
      app: php-demo
  template:
    metadata:
      labels:
        project: www
        app: php-demo
    spec:
      imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: nginx
        image: 10.40.6.165/project/php-demo:1.0
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          name: web
          protocol: TCP
        resources:
          requests:
            cpu: 0.5
            memory: 256Mi
          limits:
            cpu: 1
            memory: 1Gi
        livenessProbe:
          httpGet:
            path: /index.php
            port: 80
          initialDelaySeconds: 6
          timeoutSeconds: 20

# kubectl create -f deployment.yaml
# kubectl get pod -n test

(2). 创建service

# cat service.yaml
apiVersion: v1
kind: Service
metadata:
  name: php-demo
  namespace: test
spec:
  selector:
    project: www
    app: php-demo
  ports:
  - name: web
    port: 80
    targetPort: 80

# kubectl create -f service.yaml
# kubectl get svc -n test

(3). 创建ingress规则

# cat ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: php-demo
  namespace: test
spec:
  rules:
    - host: php.ctnrs.com
      http:
        paths:
        - path: /
          backend:
            serviceName: php-demo
            servicePort: 80

# kubectl create -f ingress.yaml
# kubectl  get ing -n test

(4). 配置数据库

php项目与java项目同用一个数据库test, test库中有同用一个user表,这里将之前java项目到user表删除掉

# kubectl exec -it db-0 bash  -n test
root@db-0:/# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| user           |
+----------------+
1 row in set (0.00 sec)

mysql> drop table user;
Query OK, 0 rows affected (0.01 sec)

(5). 验证

绑定域名,浏览器访问

# kubectl get ing -n test
NAME               HOSTS            ADDRESS   PORTS   AGE
php-demo           php.ctnrs.com              80      14m
tomcat-java-demo   java.ctnrs.com             80      8h

本地绑定hosts:
10.40.6.210 php.ctnrs.com

访问: http://php.ctnrs.com
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容