K8S(4):nginx demo
在k8s中新建一个nginx服务demo在k8s中新建一个nginx服务这个示例中,我们会在一个pod中封装一个nginx的镜像,然后通过deploy发布出来,并通过service暴露对外访问的接口在新版本的kubernetes中,引入了deployment对象,作为pod对象的管理器。通过deployment对象,可以实现pod的自动重启、状态监测等任务的自动化管理。线上应用都应该使用d...
在k8s中新建一个nginx服务demo
在k8s中新建一个nginx服务
这个示例中,我们会在一个pod中封装一个nginx的镜像,然后通过deploy发布出来,并通过service暴露对外访问的接口
在新版本的kubernetes中,引入了deployment
对象,作为pod
对象的管理器。通过deployment
对象,可以实现pod
的自动重启、状态监测等任务的自动化管理。
线上应用都应该使用deployment来管理应用
在集群的管理服务器上新建/root/k8s-tutorial
目录,后面的示例中的配置文件,我们均会在该目录下存储。
新增/root/k8s-tutorial/0-base
目录,用来存储本示例中的文件。
- (1)新增deploy配置文件,并创建deploy
新建deploy-nginx.yaml
文件,并写入如下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
该模板可以直接从阿里云上拷贝。需要注意的几点是:
- metadata.labels:是deployment的label,用于标记这个deployment
- spec.replicas:该deployment包含的pod副本的数量
- spec.selector.matchLabels:必须与spec.template.metadata.labels中能匹配上
- spec.template:表示deployment包含的单个pod的配置
- spec.template.metadata.labels:必须与spec.selector.matchLabels对应上,这样才能与deployment关联上
- spec.template.spec.containers:单个pod的所包含的所有镜像的配置
- spec.template.spec.containers[0].name:pod中第一个镜像的名称
- spec.template.spec.containers[0].image:pod中第一个镜像使用的镜像地址及版本
- spec.template.spec.containers[0].ports:pod中第一个镜像需要对外映射的端口列表
- spec.template.spec.containers[0].ports[0].containerPort:与Dockerfile中暴露的端口对应
通过kubectl create -f deploy-nginx.yaml
,在当前的namespace下创建一个deploy
通过kubectl get deploy
,可以查看deploy
通过kubectl get pod
,可以查看deploy中的pod
当deploy的结果中AVAILABLE
的数量与DESIRED
的数量一致时,表示deploy部署成功
- (2)新增service配置文件,并创建service
新建service-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: test-nginx
spec:
selector:
app: test-nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
该模板可以直接从阿里云上拷贝。需要注意的几点是:
- metadata.labels:表示这个Service的标签
- spec.selector:service关联的pod的label,与deployment中template配置中的label一致
- spec.type:默认的配置上ClusterI,只能在集群内部访问,不能外网访问NodePort表示将pod的端口映射到Node上。
- spec.ports[0].port:service在集群内访问的端口
- spec.ports[0].targetPort:pod中容器镜像的端口
- spec.ports[0].nodePort:pod中的端口映射到node机器中的端口,如果不指定,k8s会随机一个端口,范围默认是30000-32767,如果指定,端口范围推荐也在30000-32767范围内。
通过kubectl get service
,可以查看service
- (3)集群外访问
由于我们设置了Service的type为NodePort,因此可以直接在集群的node服务器上访问,即在集群外访问。直接在任意一台机器上访问localhost:30080
都可以访问到nginx服务。如果出现无法访问的情况,可以通过以下方式查看:
- 依次检查service/deploy/pod是否都运行正常
- 使用
kubectl log
命令(后面会具体讲)查看日志 - 使用
kubectl exec
命令进入容器内部查看,与docker exec
命令类似。例如:
kubectl exec -it [podName] bash
- (4)集群内访问
在集群内部,我们可以通过内部域名的方式来访问服务。这种方式性能更好,推荐在集群内部使用这种方式。
默认域名结构:
[serviceName].[namespace].svc.cluster.local
例如:“test” namespace下的"test-nginx" service,可以通过test-nginx.test.svc.cluster.local
访问
演示如下:
首先通过kubectl get pod
命令查询出当前运行的pod名称
然后通过kubectl exec -it [podName] bash
进入到容器内,即进入到集群内部环境中
可以使用ping test-nginx.test.svc.cluster.local
命令查看
- (4)删除nginx服务
删除服务时,使用kubectl delete -f [fileName]
的方式
kubectl delete -f service-nginx.yaml
kubectl delete -f deploy-nginx.yaml
给nginx服务限定资源配额
新增/root/k8s-tutorial/1-resources
目录,用来存储本示例中的文件。
- (1)新增service配置文件,并创建service
新建service-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: test-nginx
spec:
selector:
app: test-nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
运行命令kubectl create -f service-nginx.yaml
,创建service
- (2)新增deploy配置文件,并创建deploy
新建deploy-nginx.yaml
文件,并写入如下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
说明:
- spec.template.spec.containers[0].resources.requests:初始请求所需的资源
- spec.template.spec.containers[0].resources.requests.memory:初始请求所需的内存资源
- spec.template.spec.containers[0].resources.requests.cpu:初始请求所需的cpu资源
- spec.template.spec.containers[0].resources.limits:可以使用的资源的限制
- spec.template.spec.containers[0].resources.limits.memory:可以使用的内存资源的限制
- spec.template.spec.containers[0].resources.limits.cpu:可以使用的cpu资源的限制
内存的单位Mi
、Gi
分别表示1M和1G。对于一般的java程序,至少需要2Gi
的空间
cpu的单位为m
,一核cpu为1000m,以此类推
运行命令kubectl create -f deploy-nginx.yaml
,创建deploy
- (3)查看资源限额
运行命令kubectl get pod -o wide
,获得pod
所在的node
的nodeName
运行命令kubectl describe node [nodeName]
查看pod的资源占用
- (4)删除nginx服务
kubectl delete -f service-nginx.yaml
kubectl delete -f deploy-nginx.yaml
给nginx指定liveness和readiness探针
新增/root/k8s-tutorial/2-probe
目录,用来存储本示例中的文件。
- (1)新增service配置文件,并创建service
新建service-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: test-nginx
spec:
selector:
app: test-nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
运行命令kubectl create -f service-nginx.yaml
,创建service
- (2)新增deploy配置文件,并创建deploy
新建deploy-nginx.yaml
文件,并写入如下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /task/css/page.css
port: 8080
initialDelaySeconds: 360
timeoutSeconds: 5
periodSeconds: 5
readinessProbe:
httpGet:
path: /task/css/page.css
port: 8080
initialDelaySeconds: 120
timeoutSeconds: 5
periodSeconds: 5
说明:
- spec.template.spec.containers[0].ivenessProbe:存活探针,用来检测应用是否存活,如果检测失败,pod将会被自动重启
- spec.template.spec.containers[0].ivenessProbe.httpGet.path:http请求检测的路径
- spec.template.spec.containers[0].ivenessProbe.httpGet.port:http请求检测的端口
- spec.template.spec.containers[0].ivenessProbe.initialDelaySeconds:项目刚启动时,在多少秒内不进行存活检测
- spec.template.spec.containers[0].ivenessProbe.timeoutSeconds:超时时间,应用响应时间超过这个时间将会被判定检测失败
- spec.template.spec.containers[0].ivenessProbe.periodSeconds:检测周期,检测开始后,每隔多长时间进行一次检测
- spec.template.spec.containers[0].eadinessProbe:启动检测,用来检测应用是否可以对外提供服务,如果检测失败,应用将不会被分配流量
- spec.template.spec.containers[0].eadinessProbe.httpGet.path:http请求检测的路径
- spec.template.spec.containers[0].eadinessProbe.httpGet.port:http请求检测的端口
- spec.template.spec.containers[0].eadinessProbe.initialDelaySeconds:项目启动(或被重启)时,在多少秒内不进行检测
- spec.template.spec.containers[0].eadinessProbe.timeoutSeconds:超时时间,应用响应时间超过这个时间将会被判定检测失败
- spec.template.spec.containers[0].eadinessProbe.periodSeconds:检测周期,检测开始后,每隔多长时间进行一次检测
特别注意的有以下几点:
- 存活检测的
initialDelaySeconds
:这个值应该视具体应用的启动时间而定,应该比应用预估的最长启动时间再大一些。对于java应用,假设启动时间在180s(3分钟左右),而存活检测的initialDelaySeconds
如果设置为60s,那么60s内探针无法检测成功,会强制应用重启。这样导致的结果是应用反复重启而不能正常启动! - 存活检测的
periodSeconds
:这个值不宜过长,过长会导致应用已经宕了,但是迟迟没有重启恢复 - 启动检测的
initialDelaySeconds
:这个值应该略小于应用的预估启动时间,保证一旦项目启动成功,可以及时检测到。
运行命令kubectl create -f deploy-nginx.yaml
,创建deploy
启动时,可以观察鉴活探针和启动探针的具体表现
- (3)删除nginx服务
kubectl delete -f service-nginx.yaml
kubectl delete -f deploy-nginx.yaml
使用persistent volume
persistent volume(简写为pv)是对存储介质的抽象。存储介质包括:硬盘、NAS盘、NFS存储等。对于演示类的项目,可以使用本地磁盘作为pv,而在线上环境中,推荐使用云服务商的NAS、OSS等分布式存储作为pv
以下以阿里云的NAS为例,建立pv
persistent volume claim(简写为pvc)是对镜像与pv的连接的抽象。
新增/root/k8s-tutorial/3-pv
目录,用来存储本示例中的文件。
- (1)新增service配置文件,并创建service
新建service-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: test-nginx
spec:
selector:
app: test-nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
运行命令kubectl create -f service-nginx.yaml
,创建service
- (2)阿里云NAS中新增html文件
创建阿里云NAS服务,并挂载到ECS中,然后在其中创建/test-nginx-project/hello.html
文件:
<!DOCTYPE html>
<html>
<head>
<title>hello</title>
</head>
<body>
hello world
</body>
</html>
- (3)新增pv配置文件,并创建pv
新建pv-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-nginx-project-pv
spec:
capacity:
storage: 1M
storageClassName: test-nginx-project-pv
accessModes:
- ReadOnlyMany
flexVolume:
driver: "alicloud/nas"
options:
server: "xxxxxxxxx-jog17.cn-beijing.nas.aliyuncs.com"
path: "/test-nginx-project"
vers: "4.0"
mode: "755"
说明:
- spec.capacity.storage:存储的空间大小
- spec.storageClassName:存储的类,这个类会在pvc的定义中用到
- spec.accessModes:读取的方式
- spec.flexVolume.driver:pv驱动
- spec.flexVolume.options.server:阿里云nas提供的nas server的地址
- spec.flexVolume.options.path:nas中的映射的目录
- spec.flexVolume.options.vers:阿里云nas的版本
- spec.flexVolume.options.mode:阿里云nas中文件的mode
运行命令kubectl create -f pv-nginx.yaml
,创建pv
运行命令kubectl get pv
,查看创建的pv
- (4)新增pvc配置文件,并创建pvc
新建pvc-nginx.yaml
文件,并写入如下内容:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-nginx-project-pvc
spec:
accessModes:
- ReadOnlyMany
storageClassName: test-nginx-project-pv
resources:
requests:
storage: 1M
说明:
- spec.accessModes:权限不能大于pv
- spec.storageClassName:与pv对应的storageClass
- spec.resources.requests.storage:请求的空间大小
运行命令kubectl create -f pvc-nginx.yaml
,创建pvc
运行命令kubectl get pvc
,查看创建的pvc
- (5)新增deploy配置文件,并创建deploy
新建deploy-nginx.yaml
文件,并写入如下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
volumeMounts:
- name: base-project
mountPath: /usr/share/nginx/html
volumes:
- name: base-project
persistentVolumeClaim:
claimName: test-nginx-project-pvc
说明:
- spec.template.spec.volumes[0].name:引入的volume的名字
- spec.template.spec.volumes[0].persistentVolumeClaim.claimName:引入的volume对应的pvc,需要与之前创建的pvc的name对应
- spec.template.spec.containers[0].volumeMounts[0].name:与spec.template.spec.volumes[0].name对应
- spec.template.spec.containers[0].volumeMounts[0].mountPath:映射到容器中的路径
需要注意的是映射到容器中的指定路径后,路径如果已存在,那么路径中的文件会全部丢失,只会加载pv中的文件
- (6)测试
访问localhost:30080/hello.html
可以成功返回页面
- (7)删除nginx服务
kubectl delete -f service-nginx.yaml
kubectl delete -f deploy-nginx.yaml
kubectl delete -f pvc-nginx.yaml
kubectl delete -f pv-nginx.yaml
使用configmap外置配置文件
新增/root/k8s-tutorial/4-configmap
目录,用来存储本示例中的文件。
- (1)新增service配置文件,并创建service
新建service-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: test-nginx
spec:
selector:
app: test-nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
运行命令kubectl create -f service-nginx.yaml
,创建service
- (2)新增configmap配置文件,并创建configmap
新建configmap-nginx.yaml
文件,并写入如下内容:
apiVersion: v1
kind: ConfigMap
metadata:
name: test-nginx-config
data:
default.conf: |
server {
listen 80 default_server;
server_name default_server;
location / {
proxy_pass https://www.rishiqing.com
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
说明:
- data:key值为挂载到容器内的文件名。value值为文件的内容。注意value值中关于yaml文件格式的处理。
运行命令kubectl create -f configmap-nginx.yaml
,创建configmap
运行命令kubectl get configmap
,查看configmap
- (3)新增deploy配置文件,并创建deploy
新建deploy-nginx.yaml
文件,并写入如下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
volumeMounts:
- name: base-config
mountPath: /etc/nginx/conf.d
volumes:
- name: base-config
configMap:
name: test-nginx-config
说明:
- spec.template.spec.volumes[0].name:引入的volume的名字
- spec.template.spec.volumes[0].configMap.name:引入的configmap的名称
- spec.template.spec.containers[0].volumeMounts[0].name:与spec.template.spec.volumes[0].name对应
- spec.template.spec.containers[0].volumeMounts[0].mountPath:映射到容器中的路径
运行命令kubectl create -f deploy-nginx.yaml
,创建deploy
- (4)测试
访问localhost:30080
可以直接跳转到日事清
- (4)删除nginx服务
kubectl delete -f service-nginx.yaml
kubectl delete -f deploy-nginx.yaml
kubectl delete -f configmap-nginx.yaml
secret基本操作
相对于configmap,secret会对其中的数据进行base64 hash存储。其用法与configmap类似,也可以映射通过volumeMounts挂载到容器中
- (1)创建docker镜像仓库的密钥
kubectl create secret docker-registry [secretName] --docker-server=registry-vpc.cn-beijing.aliyuncs.com --docker-username=aaaa@xxx.com --docker-password=111111 --docker-email=hello@123.com
-
docker-registry:表示secret的类型,可以用来执行docker login
-
secretName:secret的名称
-
–docker-server:docker仓库的地址
-
–docker-username:登录用户名
-
–docker-password:登录密码
-
–docker-email:邮箱
-
(2)在拉取docker镜像时使用secret
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
imagePullSecrets:
- name: ali-docker
说明:
- spec.template.spec.imagePullSecrets.name:secret的名称
集群操作——deploy集群更新、伸缩与回滚
k8s集群中可以方便地进行更新、伸缩和回滚操作
查看容器运行日志
滚动显示一个pod的日志:
kubectl log -f [podName]
滚动显示一个pod的日志,且只显示后100行。由于输出的日志能比较多,因此--tail
参数会很常用
kubectl log -f --tail=100 [podName]
当pod重启后,-p
参数可以查看前一个pod
的日志,从而查找pod
重启的原因
kubectl log -p --tail=100 [podName]
集群更新
更新k8s中镜像版本:
kubectl set image deployment/[deployName] [containerName]=[imagePath]
说明:
-
deployName:deploy的名称
-
containerName:deploy的pod中的container的名称
-
imagePath:待更新的镜像的路径
-
(1)新建deploy
新建deploy-nginx.yaml
文件,并写入如下内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: test-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: test-nginx
image: registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.13.12
ports:
- containerPort: 80
- (2)更新image版本
kubectl set image deployment nginx-deploy test-nginx=registry-vpc.cn-beijing.aliyuncs.com/rsq-public/nginx:1.14
可以将nginx更新成1.14
版本
通过命令kubectl describe deployment nginx-deploy
可以查看是否更新到最新版本
集群回滚
- (1)查看历史版本
运行命令
kubectl rollout history deployment nginx-deploy
查看历史版本。如果要查看某个历史版本的详细信息,可以运行命令:
kubectl rollout history deployment nginx-deploy --revision=[revisionNumber]
其中[revisionNumber]为之前命令中查看到的版本号。在详细信息中可以看到具体的镜像版本
- (2)将deploy回滚到之前的某个版本
kubectl rollout undo deployment nginx-deploy --to-revision=[revisionNumber]
其中[revisionNumber]为需要回滚到的版本
集群伸缩
将副本数量伸缩成1个:
kubectl scale deployment nginx-deploy --replicas=1
将应用发布到kubernetes中
由于kubernetes集群中的应用是无状态的,因此如果要将一个应用发布到kubernetes中,首先需要考虑以下几个方面:
- 配置文件的存储方式。configmap/secret/pv
- 日志文件的输出方式。pv/console/日志服务
- 其他状态文件的存储,例如上传的文件等。pv/公共存储
更多推荐
所有评论(0)