第九章 Kubernetes进阶之将公司项目部署至k8s中
第九章 Kubernetes进阶之将公司项目部署至k8s中
Kubernetes集群搭建完毕以后可以将公司项目部署至其中
1.准备工作与注意事项
部署项目情况
1,业务架构及服务(dubbo,spring cloud)
2,第三方服务,例如mysql,redis,zookeeper,eruka,mq
3,服务之间怎么通信?
4,资源消耗:硬件资源,带宽。
部署项目时用到的k8s资源
1,使用namespace进行不同项目隔离,或者不同环境(test,prod,dev)
2,无状态应用(deployment)
3,有状态应用(statefulset,pv,pvc)
4,暴露外部访问(Service,ingress)
5,secert,configmap
2.准备基础镜像并推送至镜像仓库
3.部署PHP/Java项目
1,项目构建(java) CI/CD环境这个阶段自动完成(代码拉取->代码编译构建->镜像打包->推送到镜像仓库)
2,编写yaml文件,使用镜像
kubectl->yaml->镜像仓库拉取镜像->service(集群内部访问)/Ingress暴露给外网用户
准备环境,在192.168.1.61上配置NFS服务器共享目录是/ifs/kubernetes
配置PV动态供给
下载nfs支持的yaml文件 下载地址https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy
下载以下三个yaml文件

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
# cat rbac.yaml apiVersion: v1kind: ServiceAccountmetadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: nfs-client-provisioner-runnerrules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: run-nfs-client-provisionersubjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: defaultroleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: defaultrules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: defaultsubjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: defaultroleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io |
|
1
2
3
4
5
6
7
8
9
|
# cat class.yaml apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: #应用使用哪一个class创建PV name: managed-nfs-storageprovisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'parameters: archiveOnDelete: "false" |
deployment.yaml需要修改制定的NFS服务器地址
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# cat deployment.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: defaultspec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: quay.io/external_storage/nfs-client-provisioner:latest volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: fuseim.pri/ifs - name: NFS_SERVER value: 192.168.1.61 - name: NFS_PATH value: /ifs/kubernetes volumes: - name: nfs-client-root nfs: server: 192.168.1.61 path: /ifs/kubernetes |
应用
|
1
2
3
|
kubectl apply -f rbac.yaml kubectl apply -f class.yaml kubectl apply -f deployment.yaml |
部署Harbor镜像仓库部署地址为192.168.1.61
克隆延时代码
|
1
|
git clone https://github.com/lizhenliang/tomcat-java-demo.git |
准备mvn和java环境用于构建war包
|
1
|
yum -y install maven java-1.8.0-openjdk.x86_64 |
修改配置文件修改数据库地址和密码以后构建修改配置文件
|
1
|
src/main/resources/application.yml |
|
1
|
mvn clean install -Dmaven.test.skip=true |
部署tomcat是无状态,通过service即ingrss暴露
deployment
service
ingress
部署MySQL是有状态部署,需要使用PV进行数据存储以及实现自动供给
statefulset
headless service
pv,pvc(storageclass)
构建好以后创建镜像
|
1
2
3
4
5
|
cd tomcat-java-demo#构建镜像包docker build -t 192.168.1.61/project/java-demo .#推送至镜像仓库docker push 192.168.1.61/project/java-demo |
推送镜像仓库前需要登录docker login 192.168.1.61默认用户名密码是admin Harbor12345
以及配置好Harbor信任
|
1
2
3
4
5
|
# cat /etc/docker/daemon.json { "registry-mirrors": ["https://7sl94zzz.mirror.aliyuncs.com"], "insecure-registries": ["192.168.1.61"]} |
新建jave-demo文件夹用于本次部署
创建一个test命名空间
|
1
2
3
4
5
|
# cat namespace.yaml apiVersion: v1kind: Namespacemetadata: name: test |
|
1
|
kubectl apply -f namespace.yaml |
查看已经创建了test的命名空间
|
1
2
3
4
5
6
7
|
# kubectl get nsNAME STATUS AGEdefault Active 41hingress-nginx Active 16hkube-public Active 41hkube-system Active 41htest Active 43s |
创建create放置在命名空间test下 email随便指定一个即可registry-pull-secret为指定secret名称需要配置在拉取镜像的deployment中
|
1
|
kubectl create secret docker-registry registry-pull-secret --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@123.com -n test |
PS:使用以上方式创建的secret无法拉取镜像需要使用以下方式创建
自定义命名空间为test 需要先创建命名空间test否则无法应用会报错
|
1
2
3
4
5
6
7
8
9
10
11
|
# cat registry-pull-secret.yaml apiVersion: v1kind: Secretmetadata: name: registry-pull-secret namespace: testdata: .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuNjEiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTkuMDMuNiAobGludXgpIgoJfQp9type: kubernetes.io/dockerconfigjson# kubectl apply -f registry-pull-secret.yaml |
配置文件的秘钥在已经登录Harbor的主机使用以下命令获取
|
1
|
cat /root/.docker/config.json | base64 -w0 |
查看
|
1
2
3
4
|
# kubectl get secret -n testNAME TYPE DATA AGEdefault-token-5mnvg kubernetes.io/service-account-token 3 11mregistry-pull-secret kubernetes.io/dockerconfigjson 1 50s |
创建deployment
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
# cat deployment.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: tomcat-java-demo namespace: testspec: replicas: 3 selector: matchLabels: project: www run: java-demo template: metadata: labels: project: www run: java-demo spec: imagePullSecrets: - name: registry-pull-secret containers: - name: tomcat image: 192.168.1.61/project/java-demo imagePullPolicy: Always 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 |
创建
|
1
|
kubectl apply -f deployment.yaml |
查看 命名空间是test
|
1
2
3
4
5
|
# kubectl get pod -n testNAME READY STATUS RESTARTS AGEtomcat-java-demo-66466d7bc7-27q4v 1/1 Running 0 23mtomcat-java-demo-66466d7bc7-hjdgt 1/1 Running 0 23mtomcat-java-demo-66466d7bc7-x8zm9 1/1 Running 0 23m |
使用service发布刚刚运行的应用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# cat service.yaml apiVersion: v1kind: Servicemetadata: creationTimestamp: null name: tomcat-java-demo namespace: testspec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: project: www run: java-demo type: NodePortstatus: loadBalancer: {} |
PS:注意service的命名空间也需要设置为test否则创建的service无法访问后端的tomcat
应用
|
1
|
kubectl apply -f service.yaml |
查看
|
1
2
3
|
# kubectl get svc -n testNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEtomcat-java-demo NodePort 10.0.0.44 <none> 80:40995/TCP 4m52s |
没有部署ingress之前可以使用node ip加随机的nodeport端口进行访问
部署ingress 部署ingress之前需要确保已经部署好ingress控制器 查看是否已经部署控制器使用命令
|
1
|
kubectl get pod -n ingress-nginx |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# cat ingress.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: simple-fanout-example namespace: test annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: rules: #定义访问域名 - host: java.ctnrs.com http: paths: - path: / backend: #转发到哪个server下 serviceName: tomcat-java-demo servicePort: 80 |
应用
|
1
|
kubectl apply -f ingress.yaml |
查看
|
1
2
3
|
# kubectl get ingress -n testNAME HOSTS ADDRESS PORTS AGEsimple-fanout-example java.ctnrs.com 80 7s |
设置hosts可以通过域名访问http://java.ctnrs.com/
但是没有配置MySQL只能看见页面无法实现功能
部署mysql
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# cat mysql.yaml apiVersion: v1kind: Servicemetadata: name: mysql labels: project: java-demo run: mysqlspec: ports: - port: 3306 name: mysql #不需要clusterIP clusterIP: None selector: project: java-demo run: mysql---apiVersion: apps/v1kind: StatefulSetmetadata: name: dbspec: selector: matchLabels: project: java-demo run: mysql serviceName: "mysql" template: metadata: labels: project: java-demo run: mysql spec: containers: - name: mysql image: mysql:5.7 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "123456" volumeMounts: - mountPath: /var/lib/mysql name: data volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: "managed-nfs-storage" resources: requests: storage: 2Gi |
应用
|
1
|
kubectl apply -f mysql.yaml |
查看

在对应的nfs服务器会创建一个文件夹用于持久保存MySQL数据

查看pv和pvc
|
1
|
kubectl get pv,pvc |
MySQL的连接地址是db-0.mysql.default 可以创建一个busybox测试
|
1
|
kubectl run -it --rm --image=busybox bash |
|
1
2
3
4
|
# ping db-0.mysql.defaultPING db-0.mysql.default (172.17.9.3): 56 data bytes64 bytes from 172.17.9.3: seq=0 ttl=64 time=0.084 ms64 bytes from 172.17.9.3: seq=1 ttl=64 time=0.076 ms |
修改项目的数据库配置
|
1
2
|
cd tomcat-java-demovim src/main/resources/application.yml |

重新打包
|
1
|
mvn clean install -Dmaven.test.skip=true |
重新打包docker镜像
|
1
|
docker build -t 192.168.1.61/project/java-demo:1.0 . |
推送至Harbor镜像仓库
|
1
|
docker push 192.168.1.61/project/java-demo:1.0 |
登录私有镜像仓库查看已经有了1.0版本

修改deployment.yaml修改一下版本号

滚动更新
|
1
|
kubectl apply -f deployment.yaml |

滚动更新是先现在新的镜像包启动以后再删除原有包
拷贝数据库脚本至容器
|
1
|
kubectl cp tables_ly_tomcat.sql db-0:/ |
登录容器导入数据库表
|
1
2
3
4
5
6
|
#登录容器kubectl exec -it db-0 bash#登录数据库mysql -uroot -p123456#导入表mysql> source tables_ly_tomcat.sql; |
因为连接了数据库所以登录web页面java.ctnrs.com即可实现该程序的简单功能添加信息
部署PHP项目
本次部署WordPress
下载示例代码
|
1
|
git clone https://github.com/lizhenliang/php-demo |
修改数据库配置
|
1
2
|
#cd php-demovim wp-config.php |

查看Dockerfile文件
|
1
2
3
4
|
# cat Dockerfile FROM lizhenliang/nginx-php:latestMAINTAINER www.ctnrs.comADD . /usr/local/nginx/html |
构建提交到私有仓库
|
1
2
|
docker build -t 192.168.1.61/project/php-demo:1.0 .docker push 192.168.1.61/project/php-demo:1.0 |
删除刚刚部署java的namespace为test的命名空间
|
1
|
kubectl delete -f namespace.yaml |
删除刚刚部署的数据库MySQL
|
1
|
kubectl delete -f mysql.yaml |
查看是否已经删除干净
|
1
2
3
4
5
6
7
|
#命名空间test的pod svc ingress都没有了# kubectl get pod,svc,ingress -n testNo resources found.#数据库db-0的坡道也没有了,保留了nfs# kubectl get podNAME READY STATUS RESTARTS AGEnfs-client-provisioner-7665588bd7-66q7w 1/1 Running 0 69m |
创建namespace名字为test
|
1
2
3
4
5
6
7
|
# cat namespace.yaml apiVersion: v1kind: Namespacemetadata: name: test#kubectl apply -f namespace.yaml |
查看
|
1
2
3
4
5
6
7
|
# kubectl get nsNAME STATUS AGEdefault Active 2d17hingress-nginx Active 41hkube-public Active 2d17hkube-system Active 2d17htest Active 17s |
创建Harbor加密认证
|
1
2
3
4
5
6
7
8
9
10
11
|
# cat registry-pull-secret.yamlapiVersion: v1kind: Secretmetadata: name: registry-pull-secret namespace: testdata: .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuNjEiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTkuMDMuNiAobGludXgpIgoJfQp9type: kubernetes.io/dockerconfigjson # kubectl apply -f registry-pull-secret.yaml |
查看
|
1
2
3
4
|
# kubectl get secret -n testNAME TYPE DATA AGEdefault-token-kklxx kubernetes.io/service-account-token 3 86sregistry-pull-secret kubernetes.io/dockerconfigjson 1 9s |
创建php deployment
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# cat deployment.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: php-demo namespace: testspec: replicas: 3 selector: matchLabels: project: www run: php-demo template: metadata: labels: project: www run: php-demo spec: imagePullSecrets: - name: registry-pull-secret containers: - name: php image: 192.168.1.61/project/php-demo:1.0 imagePullPolicy: Always resources: requests: cpu: 0.5 memory: 1Gi limits: cpu: 1 memory: 2Gi livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 60 timeoutSeconds: 20 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 60 timeoutSeconds: 20# kubectl apply -f deployment.yaml |
查看
|
1
2
3
4
5
|
# kubectl get pod -n testNAME READY STATUS RESTARTS AGEphp-demo-5c4b869ffd-2cwzr 0/1 Running 0 15sphp-demo-5c4b869ffd-7wt48 0/1 Running 0 15sphp-demo-5c4b869ffd-gsm4t 0/1 Running 0 15s |
创建service对应刚刚创建的deployment
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# cat service.yaml apiVersion: v1kind: Servicemetadata: creationTimestamp: null name: php-demo namespace: testspec: ports: - port: 80 protocol: TCP targetPort: 80 selector: project: www run: php-demo type: NodePortstatus: loadBalancer: {}# kubectl apply -f service.yaml service/php-demo created |
查看
|
1
2
3
|
# kubectl get svc -n testNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEphp-demo NodePort 10.0.0.14 <none> 80:49142/TCP 14s |
创建ingress 创建ingress之前确保已经部署了ingress-nginx
|
1
2
3
4
|
# kubectl get pod -n ingress-nginxNAME READY STATUS RESTARTS AGEnginx-ingress-controller-42gsg 1/1 Running 2 41hnginx-ingress-controller-5r29z 1/1 Running 2 41h |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# cat ingress.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: simple-fanout-example namespace: test annotations: nginx.ingress.kubernetes.io/rewrite-target: /spec: rules: #定义访问域名 - host: php.ctnrs.com http: paths: - path: / backend: #转发到哪个server下 serviceName: php-demo servicePort: 80# kubectl apply -f ingress.yaml ingress.extensions/simple-fanout-example created |
查看
|
1
2
3
|
# kubectl get ingress -n testNAME HOSTS ADDRESS PORTS AGEsimple-fanout-example php.ctnrs.com 80 25s |
设置hosts以后即可使用域名php.ctnrs.com访问

浙公网安备 33010602011771号