目录
原生Kubernetes容器云平台应用部署
案例目标
- 了解YAML文件的语法。
- 掌握Deployment、Pod、Service的部署
- 基于Kubernetes部署Wordpress服务
案例分析
1、节点规划:
双节点部署,Master与Node节点,IP自拟。
2、环境准备:
每个节点都已部署Kubernetes集群,且正常连通外网。
案例实施
一、YAML文件
1.1、YAML简介:
YAML是专门用来写配置文件的语言,非常简洁和强大,使用比JSON更方便,它实质上是一种通用的数据串行化格式。
1.1.1、YAML语法规则:
- 大小写敏感。
- 使用缩进表示层级关系。
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。
- “#”表示注释,从这个字符一直到行尾,都会被解释器忽略。
1.1.2、Kubernetes中必须掌握的两种结构类型
- Lists
- Maps
1.1.3、使用YAML用于K8S的定义的优势:
- 便携性:不必添加大量的参数到命令行中执行命令。
- 可维护性:YAML文件可以通过源头控制,跟踪每次操作。
- 灵活性:YAML文件可以创建比命令行更加复杂的结构。
1.2、YAML Maps
Map
顾名思义指的是字典,即一个Key:Value
的键值对信息。例如:
---
apiVersion: v1
kind: Pod
注意:---为可选的分隔符,当需要在一个文件中定义多个结构的时候需要使用。上述内容百表示有两个键apiVersion和kind,分别对应的值为v1和Pod。
Maps
的value
既能够对应字符串
也能够对应一个Maps
。例如:
---
apiVersion:v1
kind:Pod
metadate:
name: kube100-site
labels:
app:web
在上述的YAML文件中,metadata
这个KEY对应的值是一个Maps
,而嵌套的labels
这个KEY的值又是一个Map
。实际使用中可视情况进行多层嵌套
。
YAML处理器
根据行缩进来知道内容之间的关联。上述例子中,使用两个空格作为缩进,但空格的数量并不重要,只是要求至少一个空格并且所有缩进保持一致。例如name
和labels
是相同的缩进级别,因此YAML处理器
知道它们属于同一个map
;app
是labels
的值,因为app
的缩进量比labels
更大。
1.3、YAML Lists
Lists即列表,类似于数组,例如:
args:
-beijing
-shanghai
-shenzhen
-guangzhou
可以指定任何数量的项在列表中,每个项的定义以破折号“-”
开头,并且与父元素之间存在缩进。在JSON格式中,表示如下:
{
"args":["beijing","shanghai","shenzhen","guangzhou"]
}
当然Lists的子项也可以是Maps,Maps的子项也可以是Lists,例如:
---
apiVersion:v1
kind:Pod
metadate:
name: kube100-site
labels:
app:web
spec:
containers:
- name: font-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports: 8080
如上述文件所示,定义一个containers的List对象,每个子项都由name、image、ports组成,每个ports都有一个KEY为containerPort的Map组成。
1.4、创建Pod
创建YAML文件:
[root@master ~]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test
labels:
os: centos
spec:
containers:
- name: hello
image: nginx:latest
imagePullPolicy: Never
env:
- name: Test
value: "123456"
command: ["bash","-c","while true;do date;sleep 1;done"]
通过YAML文件创建管理Pod:
[root@master ~]# kubectl create -f test.yaml
pod/pod-test created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-ccb467dc5-5r8d5 1/1 Running 0 3h21m
nginx-ccb467dc5-c4lkb 1/1 Running 0 3h21m
nginx-ccb467dc5-t75gg 1/1 Running 0 3h21m
nginx-ccb467dc5-tknfq 1/1 Running 0 3h21m
pod-test 1/1 Running 0 5s
PS:如果因为文件内容错误导致的pod启动失败,需要先删除已生成的pod(生成的pod在default这个命名空间中)
再重新执行创建命令,步骤如下:
删除方式1:
[root@master ~]# kubectl delete pod -n default pod-test
pod "pod-test" deleted
删除方式2:
[root@master ~]# kubectl delete -f test.yaml
pod "pod-test" deleted
再创建
[root@master ~]# kubectl create -f test.yaml
pod/pod-test created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-ccb467dc5-5r8d5 1/1 Running 0 3h21m
nginx-ccb467dc5-c4lkb 1/1 Running 0 3h21m
nginx-ccb467dc5-t75gg 1/1 Running 0 3h21m
nginx-ccb467dc5-tknfq 1/1 Running 0 3h21m
pod-test 1/1 Running 0 5s
二、部署应用
在Kubernetes上运行WordPress的好处是显而易见的。首先是安装非常简单(在已有集群的情况下),其次是可靠性非常高,第三是规模可以伸缩。当然,可以在多个云之间更为容易地迁移也是非常重要的一点。
在Kubernetes上运行WordPress是一个可伸缩性服务运行于云原生集群的典型案例,其用来作为学习案例也是很好的。
2.1、新建namespace
新建blog namespace
,将应用都部署到blog命名空间下。
[root@master ~]# kubectl create namespace blog
namespace/blog created
2.2、创建MySQL的Deployment对象
注意:节点中如有主机已安装数据库请按文件提示中操作:
#查询数据库相关内容
[root@node ~]# yum list *mysql*
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
已安装的软件包
mysql-community-client.x86_64 5.7.34-1.el7 installed
mysql-community-common.x86_64 5.7.34-1.el7 installed
mysql-community-libs.x86_64 5.7.34-1.el7 installed
mysql-community-server.x86_64 5.7.34-1.el7 installed
可安装的软件包
MySQL-python.x86_64 1.2.5-1.el7 base
#卸载对应已安装内容
[root@node ~]# yum remove -y mysql-community-*
[root@node ~]# rm -rf /var/lib/mysql/* #清理残余文件
创建一MySQL的Deployment对象wordpress-db.yaml
。
[root@master ~]# cat wordpress-db.yaml
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mysql-deploy
namespace: blog
labels:
app: mysql
spec:
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
name: dbport
env:
- name: MYSQL_ROOT_PASSWORD
value: rootPassWord
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
- name: db
mountPath: /var/lib/mysql
volumes:
- name: db
hostPath:
path: /var/lib/mysql #该路径为数据库默认目录,如有主机已安装数据库请修改为其它目录,如:/var/lib/mysql,或者直接卸载主机数据库并清理对应文件
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: blog
spec:
selector:
app: mysql
ports:
- name: mysqlport
protocol: TCP
port: 3306
targetPort: dbport
然后创建上面的wordpress-db.yaml
文件
[root@master ~]# kubectl create -f wordpress-db.yaml
deployment.apps/mysql-deploy created
service/mysql created
然后查看Service的详细情况:
[root@master ~]# kubectl describe svc mysql -n blog
Name: mysql
Namespace: blog
Labels: <none>
Annotations: <none>
Selector: app=mysql
Type: ClusterIP
IP: 10.108.71.31
Port: mysqlport 3306/TCP
TargetPort: dbport/TCP
Endpoints: 10.16.1.10:3306
Session Affinity: None
Events: <none>
可以看到Endpoint
部分匹配到了一个Pod,生成了一个clusterIP
为10.100.21.147,现在就可以通过这个clusterIP
加上定义的3306端口访问MySQL服务了。
PS:倘若资源创建后发现异常,请先删除该资源修正yaml文件后再行创建,删除命令:
[root@master ~]# kubectl delete -f wordpress-db.yaml
2.3、创建WordPress服务
创建WordPress服务,将上面的wordpress的Pod转换成Deployment
对象wordpress.yaml
。
[root@master ~]# vi wordpress.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: wordpress-deploy
namespace: blog
labels:
app: wordpress
spec:
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: wdport
env:
- name: WORDPRESS_DB_HOST
value: 10.108.71.31:3306 #此处的IP是MySQL svc的clusterIP
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: blog
spec:
selector:
app: wordpress
ports:
- name: wordpressport
protocol: TCP
port: 80
targetPort: wdport
注意:要添加属性type: NodePort
,然后创建wordpress.yaml
。
[root@master ~]# kubectl create -f wordpress.yaml
deployment.apps/wordpress-deploy created
service/wordpress created
2.4、编写YAML文件
编写YAML文件wordpress-pod.yaml
。
[root@master ~]# vi wordpress-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: wordpress
namespace: blog
spec:
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: wdport
env:
- name: WORDPRESS_DB_HOST
value: localhost:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
name: dbport
env:
- name: MYSQL_ROOT_PASSWORD
value: rootPassWord
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
- name: db
mountPath: /var/lib/mysql
volumes:
- name: db
hostPath:
path: /var/lib/mysql #该项注意与上文步骤同步
注意:这里针对MySQL这个容器做了一个数据卷的挂载,这是为了能够将MySQL的数据能够持久化到节点上,这样在MySQL容器重启过后数据不至于丢失。
2.5、创建Pod
[root@master ~]# kubectl create -f wordpress-pod.yaml
pod/wordpress created
2.6、访问服务
查看svc:
[root@master ~]# kubectl get svc -n blog
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql ClusterIP 10.108.71.31 <none> 3306/TCP 4m46s
wordpress NodePort 10.104.43.115 <none> 80:32694/TCP 74s
可以看到WordPress服务
产生了一个32694
的端口,现在通过任意节点的NodeIP
加上32694端口,就可以访问WordPress应用了,如图所示:
三、优化应用
3.1、增加健康检测
liveness probe
和rediness probe
是提高应用稳定性非常重要的方法。
livenessProbe:
tcpSocket: #通过端口探针的方式
port: 80
initiaIDelaySeconds: 3
periodSeconds: 3
redinessProbe:
tcpSocket: #通过端口探测的方式
port: 80
initiaIDelaySeconds: 5
periodSeconds: 10
增加上面两个探针,每10s检测一次应用是否可读,每3s检测一次应用是否存活。
3.2、增加Pod资源限制
配置HPA,让应用能够自动应对流量高峰期。
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
3.3、增加滚动更新策略
增加滚动更新策略,这样可以保证在更新应用的时候,服务不会被中断。
replicas:
revisionHistoryLimit: 10
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge:
maxUnavailable: 1
3.4、修改MySQL主机值
如果MySQL服务被重新创建了,其clusterIP
非常有可能就变化了,所以上面环境变量中的WORDPRESS_DB_HOST
的值就会有问题,会导致访问不了数据库服务,此处可以直接使用Service
的名称来代替host
,这样即使clusterIP
变化了,也不会有任何影响。
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
3.5、添加initContainer
在部署WordPress服务
的时候,MySQL服务
已经启动起来了吗?如果没有启动起来,则无法连接数据库。此时在启动WordPress应用之前,需要检查MySQL服务,如果服务正常,就可以开始部署服务。
initContainers:
- name: init-db
image: busybox
command: ['sh','-c','until nslookup mysql; do echo waitinng for mysql service; sleep 2; done;']
直到MySQL服务创建完成后,initContainer
才结束,结束后开始下面的部署。
3.6、整合YAML
把部署的应用整合到一个YAML文件wordpress-all.yaml
中。
[root@master ~]# vi wordpress-all.yaml
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: mysql-deploy
namespace: blog
labels:
app: mysql
spec:
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
name: dbport
env:
- name: MYSQL_ROOT_PASSWORD
value: rootPassWord
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
volumeMounts:
- name: db
mountPath: /var/lib/mysql
volumes:
- name: db
hostPath:
path: /var/lib/mysql
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: blog
spec:
selector:
app: mysql
ports:
- name: mysqlport
protocol: TCP
port: 3306
targetPort: dbport
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: wordpress-deploy
namespace: blog
labels:
app: wordpress
spec:
revisionHistoryLimit: 10
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: wordpress
spec:
initContainers:
- name: init-db
image: busybox
command: ['sh','-c','until nslookup mysql; do echo waiting for mysql service; sleep 2; done;']
containers:
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: wdport
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: blog
spec:
selector:
app: wordpress
type: NodePort
ports:
- name: wordpressport
protocol: TCP
port: 80
nodePort: 32574
targetPort: wdport
3.7、创建服务
创建服务之前需要先删除之前的服务:
[root@master ~]# kubectl delete -f wordpress-db.yaml
deployment.apps "mysql-deploy" deleted
service "mysql" deleted
[root@master ~]# kubectl delete -f wordpress.yaml
deployment.apps "wordpress-deploy" deleted
service "wordpress" deleted
[root@master ~]# kubectl delete -f wordpress-pod.yaml
pod "wordpress" deleted
ps:也可以利用冲突内容直接一次性反向删除
[root@master ~]# kubectl delete -f wordpress-all.yaml
deployment.apps "mysql-deploy" deleted
service "mysql" deleted
deployment.apps "wordpress-deploy" deleted
service "wordpress" deleted
pod "wordpress" deleted
然后创建:
[root@master ~]# kubectl create -f wordpress-all.yaml
deployment.apps/mysql-deploy created
service/mysql created
deployment.apps/wordpress-deploy created
service/wordpress created
3.8、配置HPA
[root@master ~]# kubectl autoscale deployment wordpress-deploy --cpu-percent=10 --min=1 --max=10 -n blog
horizontalpodautoscaler.autoscaling/wordpress-deploy autoscaled
用kubectl autoscale
命令为wordpress-deploy
创建一个HPA对象,最小的Pod副本数为1,最大为10,HPA会根据设定的CPU使用率(10%)动态的增加或者减少Pod副本数量。
3.9、访问服务
在浏览器中输入http://任意Node_IP:32574
来访问服务,如图所示:
至此,WordPress应用的优化就完成了。