K8S笔记0502
K8S配置中的port、targetPort、nodePort和containerPort区别port:port是k8s集群内部访问service的端口,即通过clusterIP:port可以访问到某个servicenodePort:nodePort是外部访问k8s集群中service的端口,通过nodeIP: nodePort可以从外部访问到某个service。targetPort:target
K8S配置中的port、targetPort、nodePort和containerPort区别
- port:port是k8s集群内部访问service的端口,即通过clusterIP:port可以访问到某个service
- nodePort:nodePort是外部访问k8s集群中service的端口,通过nodeIP: nodePort可以从外部访问到某个service。
- targetPort:targetPort是pod的端口,从port和nodePort来的流量经过kube-proxy流入到后端pod的targetPort上,最后进入容器。
- containerPort:containerPort是pod内部容器的端口,targetPort映射到containerPort。
Statefulset
Statefulset为了解决有状态服务的部署(如某些服务启动是有依赖顺序)、集群之间的数据同步问题(如MySQL主从等)
- Statefulset所管理的Pod用于唯一且固定的Pod名称(0,1,2,3)
- Statefulset按照顺序对pod进行启停、伸缩和回收,回收从后向前,创建从前向后(前面的pod不会操作)。
- Headless Services(无头服务,请求的解析区别于无状态服务直接解析到podip而不是service),将名称解析为地址
创建服务时会按照顺序先创建第一个(名称永远都是0),第一个创建完成前不会创建下一个。
实例
创建pod
---
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: StatefulSet #类型
metadata:
name: myserver-myapp
namespace: myserver
spec:
replicas: 3
serviceName: "myserver-myapp-service" #匹配service名称
selector:
matchLabels:
app: myserver-myapp-frontend
template:
metadata:
labels:
app: myserver-myapp-frontend
spec:
containers:
- name: myserver-myapp-frontend
image: nginx:1.20.2-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-service
namespace: myserver
spec:
clusterIP: None#没有service IP,直接通过pod名称解析地址
ports:
- name: http
port: 80
selector:
app: myserver-myapp-frontend
验证
pod按照顺序创建,并且名称以0,1,2顺序命名
#跨namespace访问格式:pod名称-service名称-namespace名称-集群名称
ping myserver-myapp-0.myserver-myapp-service.myserver.svc.k8s.local
请求先经过coredns进行域名解析然后轮询发给后面三个pod,不经过service.
MySQL读写分离,可以分为两个无头service,读去pod0,写去pod1,pod2.
DaemonSet
DaemonSet在当前集群中部分节点(部分不参与调度节点如master,SchedulingDisabled)运行同一个pod,当有新的节点加入集群时也会为新的节点配置相同的pod,当节集群中移除时其pod也会被kubernetes回收,删除DaemonSet控制器将删除其创建的所有的pod。
常用场景:calicoctl和日志收集
案例一
创建pod
---
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: myserver-myapp
namespace: myserver
spec:
selector:
matchLabels:
app: myserver-myapp-frontend
template:
metadata:
labels:
app: myserver-myapp-frontend
spec:
tolerations:
# this toleration is to have the daemonset runnable on master nodes
# remove it if your masters can't run pods
- key: node-role.kubernetes.io/master #污点,即使master节点被标记SchedulingDisabled也会创建pod
operator: Exists
effect: NoSchedule
hostNetwork: true #减少service开销,使用宿主机网络,提高性能,service可以不使用
hostPID: true #在容器中能查看到宿主机pid
containers:
- name: myserver-myapp-frontend
image: nginx:1.20.2-alpine
ports:
- containerPort: 80 #直接监听在宿主机的80端口,不能冲突
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend
namespace: myserver
spec:
ports:
- name: http
port: 80
targetPort: 80
#nodePort: 30018
protocol: TCP
#type: NodePort
selector:
app: myserver-myapp-frontend
验证
案例二-部署日志收集
部署prometheus
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
labels:
k8s-app: node-exporter
spec:
selector:
matchLabels:
k8s-app: node-exporter
template:
metadata:
labels:
k8s-app: node-exporter
spec:
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
containers:
- image: prom/node-exporter:v1.3.1
imagePullPolicy: IfNotPresent
name: prometheus-node-exporter
ports:
- containerPort: 9100
hostPort: 9100
protocol: TCP
name: metrics
volumeMounts:
- mountPath: /host/proc
name: proc
- mountPath: /host/sys
name: sys
- mountPath: /host
name: rootfs
args:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --path.rootfs=/host
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: rootfs
hostPath:
path: /
hostNetwork: true
hostPID: true
Pod状态和探针
Pod常见状态
- Unschedulable: #Pod不能被调度, kube-scheduler没有匹配到合适的node节点
- PodScheduled:#pod正处于调度中,在kube-scheduler刚开始调度的时候,还没有将pod分配到指定的node,在筛选出合适的节点后就会更新etcd数据,将pod分配到指定的node
- Pending: #正在创建Pod但是Pod中的容器还没有全部被创建完成,处于此状态的Pod应该检查Pod依赖的存储是否有权限挂载等。
- Failed:#Pod中有容器启动失败而导致pod工作异常。
- Unknown:#由于某种原因无法获得pod的当前状态,通常是由于与pod所在的node节点通信错误"lnitialized:#所有pod中的初始化容器已经完成了
- lmagePullBackOff:#!Pod所在的node节点下载镜像失败,镜像找到了但下不了,与InvalidlmageName区别
- Running:#Pod内部的容器已经被创建并且启动,也包括探针检测通过了。
- Ready:#表示pod中的容器已经可以提供访问服务
- Error: #pod启动过程中发生错误NodeLost: #Pod所在节点失联
- Waiting: #Pod 等待启动
- Terminating: # Pod正在被销毁
- CrashLoopBackOff: #kubelet正在重启pod
- InvalidlmageName: #node节点无法解析镜像名称导致的镜像无法下载(404),找不到镜像
- lmageInspectError:#无法校验镜像,镜像不完整导致
- ErrlmageNeverPull:#策略禁止拉取镜像,镜像中心权限是私有等
- RegistryUnavailable:#镜像服务器不可用,网络原因或harbor宕机
- ErrlmagePull:#镜像拉取出错,超时或下载被强制终止
- CreateContainerConfigError:#不能创建kubelet使用的容器配置
- CreateContainerError:#创建容器失败
- RunContainerError: #pod运行失败,容器中没有初始化PID为1的守护进程等ContainersNotInitialized:#pod没有初始化完毕
- ContainersNotReady:#pod没有准备完毕
- ContainerCreating:#pod正在创建中
- PodInitializing:#pod正在初始化中
- DockerDaemonNotReady: #node节点decker服务没有启动
- NetworkPluginNotReady:#网络插件没有启动
Pause容器
Pause容器,又叫lnfra容器,是pod的基础容器,镜像体积只有几百KB左右,配置在kubelet(/etc/systemd/system/kubelet.service)中,主要的功能是一个pod中多个容器的网络通信。
lnfra容器被创建后会初始化Network Namespace,之后其它容器就可以加入到Infra容器中共享Infra 容器的网络了,因此如果一个Pod 中的两个容器A和B,那么关系如下:
- A容器和B容器能够直接使用localhost通信;
- A容器和B容器可以看到网卡、IP与端口监听信息。Pod只有一个IP地址,也就是该Pod的Network Namespace对应的IP地址(由Infra容器初始化并创建).
- k8s环境中的每个Pod有一个独立的IP地址(前提是地址足够用),并且此IP被当前Pod中所有容器在内部共享使用。
- pod删除后Infra容器随机被删除,其IP被回收。
Pause容器共享的Namespace:
- NET Namespace: Pod中的多个容器共享同一个网络命名空间,即使用相同的IP和端口信息。
- IPC Namespace: Pod中的多个容器可以使用System VIPC或POSIX消息队列进行通信。
- UTS Namespace: pod中的多个容器共享一个主机名。MNT Namespace、PID Namespace、User Namespace未共享。
Init容器
Init 容器是一种特殊容器,在Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。
每个Pod中可以包含多个容器, 应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成,只执行一次。
- 每个都必须在下一个启动之前成功完成。
如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy
值为 "Never",并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。
init容器的作用:
- 可以为业务容器提前准备好业务容器的运行环境,比如将业务容器需要的配置文件提前生成并放在指定位置、检查数据权限或完整性、软件版本等基础运行环境。
- 可以在运行业务容器之前准备好需要的业务数据,比如从OSS下载、或者从其它位置copy。
- 检查依赖的服务是否能够访问。
init容器的特点:
- 一个pod可以有多个业务容器还能在有多个init容器,但是每个init容器和业务容器的运行环境都是隔离的。
- init容器会比业务容器先启动。
- 如果一个pod有多个init容器,则需要从上到下逐个运行并且全部成功,最后才会运行业务容器。
- init容器不支持探针检测(因为初始化完成后就退出再也不运行了)。
案例
创建pod
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: myserver-myapp
name: myserver-myapp-deployment-name
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-myapp-frontend
template:
metadata:
labels:
app: myserver-myapp-frontend
spec:
containers:
- name: myserver-myapp-container
image: nginx:1.16.0
#imagePullPolicy: Always
volumeMounts:
- mountPath: "/usr/share/nginx/html/myserver" #挂载在/tmp/data/html
name: myserver-data
initContainers:
- name: init-web-data
image: centos:7.9.2009
command: ['/bin/bash','-c',"for i in `seq 1 10`;do echo '<h1>'$i web page at $(date +%Y%m%d%H%M%S) '<h1>' >> /data/nginx/html/myserver/index.html;sleep 1;done"]
volumeMounts:
- mountPath: "/data/nginx/html/myserver"
name: myserver-data
- name: change-data-owner
image: busybox:1.28
command: ['/bin/sh','-c',"/bin/chmod 644 /data/nginx/html/myserver/* -R"]
volumeMounts:
- mountPath: "/data/nginx/html/myserver"
name: myserver-data
volumes:
- name: myserver-data
hostPath:
path: /tmp/data/html
---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-myapp-service
name: myserver-myapp-service-name
namespace: myserver
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
selector:
app: myserver-myapp-frontend
验证
Helath Check
由发起者对容器进行周期性健康状态检测。周期检测相当于人类的周期性体检
案例一docker-compose检测
version: '3.6'
services:
nginx-service:
image: nginx:1.20.2
container_name: nginx-web1
expose:
- 80
- 443
ports:
- "8080:80"
restart: always
healthcheck: #添加服务健康状态检查
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 5s #健康状态检查的间隔时间,默认为30s
timeout: 5s #单次检查的失败超时时间,默认为30s
retries: 3 #连续失败次数默认3次,当连续失败retries次数后将容器置为unhealthy状态
start_period: 60s #60s后每间隔interval的时间检查一次,连续retries次后才将容器置为unhealthy状态, 但是start_period时间内检查成功就认为是检查成功并>装容器置于healthy状态
案例二 命令添加
FROM nginx:1.20.2
maintainer "834943551@qq.com"
HEALTHCHECK --interval=5s --timeout=2s --retries=3 \
CMD curl --silent --fail localhost:80 || exit 1
K8S的生命周期和探针
pod的生命周期,从start后可以配置postStart检测,运行过程中可以配置livenessProbe(存活探针)和readinessProbe(就绪探针),运行过程中Main Container提供主要业务服务,最后在stop前可以配置preStop操作。其中init、start和stop是一次性的,存活和就绪是周期性的。
探针简介
探针是由kubelet对容器执行的定期诊断,以保证pod的状态始终处于运行状态,要执行诊断,kubelet调用容器实现的Handler(处理程序)。有三种类型的处理程序:
1) ExecAction:
在容器中执行指定命令,如命令退出时返回码为0则认为诊断成功
2) TCPSockerAction
对指定端口上的容器的IP地址进行TCP检查,如果端口打开则认为成功
3) HTTPGetAction
对指定端口和路径上的容器执行httpget请求,如果响应的状态码大约等于200且小于400,则诊断成功
Pod重启策略
Pod一旦配置探针,在检测失败时候,会基于restartPolicy对Pod进行下一步操作,restartPolicy(容器重启策略):
- Always:当容器异常时, k8s自动重启该容器,默认策略
- ReplicationController/Replicaset/Deployment,默认为Always.OnFailure:当容器失败时(容器停止运行且退出码不为O),k8s自动重启该容器。
- Never:不论容器运行状态如何都不会重启该容器,Job或CronJob。
容器启动过程中类型
- startupProbe:#启动探针,判断容器内的应用程序是否已启动完成,如果配置了启动探测,则会先禁用所有其它的探测,直到startupProbe检测成功为止,如果startupProbe探测失败,则kubelet将杀死容器,容器将按照重启策略进行下一步操作,如果容器没有提供启动探测,则默认状态为成功
- livenessProbe(检测失败后重启pod): #存活探针,检测容器容器是否正在运行,如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为Success,livenessProbe用于控制是否重启pod。
- readinessProbe(检测失败后从service中摘除):#就绪探针,如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址,初始延迟之前的就绪状态默认为Failure(失败),如果容器不提供就绪探针,则默认状态为Success,readinessProbe用于控制pod是否添加至service。
探针通用配置参数
存活探针和就绪探针都适用以下参数配置
initialDelaySeconds: 120
#初始化延迟时间,告诉kubelet在执行第一次探测前应该等待多少秒,默认是O秒,最小值是O
failureThreshold:3
#从成功转为失败的重试次数,当Pod启动了并且探测到失败,Kubernetes的重试次数,存活探测情况下的放弃就意味着重新启动容器,就绪探测情况下的放弃Pod会被打上未就绪的标签,默认值是3,最小值是1。
periodSeconds: 60
#探测周期间隔时间,指定了kubelet应该每多少秒秒执行一次存活探测,默认是10秒。最小值是1
timeoutSeconds: 5
#单次探测超时时间,探测的超时后等待多少秒,默认值是1秒,最小值是1。
successThreshold: 1
#从失败转为成功的重试次数,探测器在失败后,被视为成功的最小连续成功数,默认值是1,存活探测的这个值必须是1,最小值是1.
探针http配置参数
HTTP探测器可以在 httpGet 上配置额外的字段:
host:#连接使用的主机名,默认是Pod的IP,也可以在HTTP头中设置“Host”来代替。
scheme: http #用于设置连接主机的方式(HTTP还是HTTPS),默认是HTTP。
path: /monitorlindex.html #访问HTTP服务的路径。
port: 80 #访问容器的端口号或者端口名,如果数字必须在1 ~65535之间。
案例一 基于http的检测
创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
#readinessProbe:
livenessProbe: #存活探针,检测失败会一直重启
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
readinessProbe: #就绪探针,检测失败会被从service中摘除
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 80
targetPort: 80
nodePort: 40018
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend-label
验证
案例二 基于TCP检测
对没有http访问接口的服务进行检测如redis、mysql等,通常检测方法是端口是否存在。
创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
livenessProbe:
#readinessProbe:
tcpSocket:
#port: 80
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 40012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend
案例三 命令探测
创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-redis-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-redis-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-redis,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-redis-label
spec:
containers:
- name: myserver-myapp-redis-container
image: redis
ports:
- containerPort: 6379
livenessProbe:
#readinessProbe:
exec:
command:
#- /apps/redis/bin/redis-cli
- /usr/local/bin/redis-cli
- quit
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-redis-service
namespace: myserver
spec:
ports:
- name: http
port: 6379
targetPort: 6379
nodePort: 40016
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-redis-label
验证
案例五 postStart
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
startupProbe: #检测失败不会执行下一步,且只会检测一次
httpGet:
#path: /monitor/index.html
path: /index.html
port: 80
initialDelaySeconds: 5 #首次检测延迟5s
failureThreshold: 3 #从成功转为失败的次数
periodSeconds: 3 #探测间隔周期
readinessProbe:
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
livenessProbe:
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 40012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend-label
检测
Startup probe检测失败不会执行下一个探针,会重启
案例六 preStop
在pod被执行前执行,用来优雅停止pod,不影响用户访问。
面试常见问题:使用preStop来进行优雅停止进程防止流量进来
Pod终止流程
创建pod完成调度流程----》容器启动并执行postStart、livenessProbe----》进入running状态----》readinessProbeservice关联pod接受客户端请求
删除pod----》Pod被设置为”Terminating”状态、从service的Endpoints列表中删除并不再接受客户端请求----》执行PreStop----》Kubernetes向pod中的容器发送SIGTERM信号(正常终止信号)终止pod里面的主进程,这个信号让容器知道自己很快将会被关闭----》terminationGracePeriodSeconds: 60 #可选终止等待期,如果有设置删除宽限时间,则等待宽限时间到期,否则最多等待30s。Kubernetes等待指定的时间称为优雅终止宽限期,默认情况下是30秒,值得注意的是等待期与preStop Hook和SIGTERM信号并行执行,即Kubernetes可能不会等待preStop Hook完成(最长30秒之后主进程还没有结束就就强制终止pod)。----》SIGKILL信号被发送到Pod,并删除Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp1-lifecycle
labels:
app: myserver-myapp1-lifecycle
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-myapp1-lifecycle-label
template:
metadata:
labels:
app: myserver-myapp1-lifecycle-label
spec:
terminationGracePeriodSeconds: 60 #可选终止等待期,如果有设置删除宽限时间,则等待宽限时间到期,否则最多等待30s。Kubernetes等待指定的时间称为优雅终止宽限期,默认情况下是30秒,值得注意的是等待期与preStop Hook和SIGTERM信号并行执行,即Kubernetes可能不会等待preStop Hook完成(最长30秒之后主进程还没有结束就就强制终止pod)。
containers:
- name: myserver-myapp1-lifecycle-label
image: tomcat:7.0.94-alpine
lifecycle:
postStart:
exec:
#command: 把自己注册到注册在中心
command: ["/bin/sh", "-c", "echo 'Hello from the postStart handler' >> /usr/local/tomcat/webapps/ROOT/index.html"]
#httpGet:
# #path: /monitor/monitor.html
# host: www.magedu.com
# port: 80
# scheme: HTTP
# path: index.html
preStop:
exec:
#command: 把自己从注册中心移除
command: ["/usr/local/tomcat/bin/catalina.sh","stop"]
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp1-lifecycle-service
namespace: myserver
spec:
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp1-lifecycle-label
实战案例-自定义镜像运行Nginx及tomcat服务并基于NFS实现动静分离
构建centos基础镜像
编辑Dockfile文件
[root@k8s-master1 system]# cat Dockerfile
FROM centos:7.8.2003
LABEL maintainer="834943551@qq.com"
ADD filebeat-7.12.1-x86_64.rpm /tmp
RUN yum install -y epel-release && yum install -y /tmp/filebeat-7.12.1-x86_64.rpm vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop && rm -rf /etc/localtime /tmp/filebeat-7.12.1-x86_64.rpm && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#安装日志收集工具以及一些常用命令工具,设置时区
上传centos基础镜像
[root@k8s-master1 system]# cat build-command.sh
#!/bin/bash
docker build -t k8s-harbor.com/public/centos-base:7.8.2003 .
docker push k8s-harbor.com/public/centos-base:7.8.2003
构建jdk基础镜像
编辑Dockfile文件
FROM k8s-harbor.com/public/centos-base:7.8.2003
LABEL maintainer="834943551@qq.com"
ADD jdk-8u212-linux-x64.tar.gz /usr/local/src/
RUN ln -sv /usr/local/src/jdk1.8.0_212 /usr/local/jdk
ADD profile /etc/profile
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin
#使用刚打好的centos镜像,添加jdk包并设置环境变量
上传jdk基础镜像
#!/bin/bash
docker build -t k8s-harbor.com/public/jdk-base:v8.212 .
sleep 1
docker push k8s-harbor.com/public/jdk-base:v8.212
构建nginx基础镜像
编辑Dockfile文件
[root@k8s-master1 nginx]# cat Dockerfile
#Nginx Base Image
FROM k8s-harbor.com/public/centos-base:7.8.2003
MAINTAINER "834943551@qq.com"
ADD nginx-1.20.2.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.20.2 && ./configure && make && make install && ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx &&rm -rf /usr/local/src/nginx-1.20.2.tar.gz
RUN useradd nginx -u 2022
#添加nginx包,解压并编译,设置nginx全局执行,并添加nginx普通用户
上传jdk基础镜像
[root@k8s-master1 nginx]# cat build-command.sh
#!/bin/bash
docker build -t k8s-harbor.com/public/nginx-base:v1.20.2 .
sleep 1
docker push k8s-harbor.com/public/nginx-base:v1.20.2
构建tomcat基础镜像
编辑Dockfile文件
[root@k8s-master1 base]# cat Dockerfile
#Tomcat 8.5.43基础镜像
FROM k8s-harbor.com/public/jdk-base:v8.212
LABEL maintainer="834943551@qq.com"
RUN mkdir /apps /data/tomcat/webapps /data/tomcat/logs -pv
ADD apache-tomcat-8.5.43.tar.gz /apps
RUN useradd tomcat -u 2050 && ln -sv /apps/apache-tomcat-8.5.43 /apps/tomcat && chown -R tomcat.tomcat /apps /data
上传tomcat基础镜像
[root@k8s-master1 base]# cat build-command.sh
#!/bin/bash
docker build -t k8s-harbor.com/public/tomcat-base:v8.5.43 .
sleep 3
docker push k8s-harbor.com/public/tomcat-base:v8.5.43
创建以tomcat为基础镜像
准备工作
[root@k8s-master1 tomcat-app1]# cat Dockerfile
#tomcat web1
FROM k8s-harbor.com/public/tomcat-base:v8.5.43
ADD catalina.sh /apps/tomcat/bin/catalina.sh
ADD server.xml /apps/tomcat/conf/server.xml #修改了代码路径/data/tomcat/webapps
#ADD myapp/* /data/tomcat/webapps/myapp/
ADD app1.tar.gz /data/tomcat/webapps/myapp/
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
#ADD filebeat.yml /etc/filebeat/filebeat.yml
RUN chown -R tomcat.tomcat /data/ /apps/
RUN chmod +x /apps/tomcat/bin/*.sh
RUN chown -R tomcat.tomcat /etc/hosts
#ADD filebeat-7.5.1-x86_64.rpm /tmp/
#RUN cd /tmp && yum localinstall -y filebeat-7.5.1-amd64.deb
EXPOSE 8080 8443
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
[root@k8s-master1 tomcat-app1]# cat run_tomcat.sh
#!/bin/bash
#echo "nameserver 223.6.6.6" > /etc/resolv.conf
#echo "192.168.7.248 k8s-vip.example.com" >> /etc/hosts
#/usr/share/filebeat/bin/filebeat -e -c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat &
su - tomcat -c "/apps/tomcat/bin/catalina.sh start"
tail -f /etc/hosts
#普通用户启动,一定要确保有执行权限,tail命令为守护进程
上传镜像
[root@k8s-master1 tomcat-app1]# cat build-command.sh
#!/bin/bash
TAG=$1
docker build -t k8s-harbor.com/project/tomcat-app1:${TAG} .
sleep 3
docker push k8s-harbor.com/project/tomcat-app1:${TAG}
通过K8S 实现nginx和tomcat动静分离
创建tomcat pod
root@k8s-master1 tomcat-app1]# cat tomcat-app1.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: magedu-tomcat-app1-deployment-label
name: magedu-tomcat-app1-deployment
namespace: magedu
spec:
replicas: 2
selector:
matchLabels:
app: magedu-tomcat-app1-selector
template:
metadata:
labels:
app: magedu-tomcat-app1-selector
spec:
containers:
- name: magedu-tomcat-app1-container
image: k8s-harbor.com/project/tomcat-app1:202205041638
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
imagePullPolicy: IfNotPresent
#imagePullPolicy: Always
#imagePullSecrets:
#- name: aliyun-registry-image-pull-key
ports:
- containerPort: 8080
protocol: TCP
name: http
env:
- name: "password"
value: "123456"
- name: "age"
value: "18"
resources:
limits:
cpu: 1
memory: "512Mi"
requests:
cpu: 500m
memory: "512Mi"
volumeMounts:
- name: magedu-images
mountPath: /data/tomcat/webapps/images
readOnly: false
- name: magedu-static
mountPath: /data/tomcat/webapps/static
readOnly: false
volumes:
- name: magedu-images
nfs:
server: 192.168.226.144
path: /data/k8sdata/magedu/images
- name: magedu-static
nfs:
server: 192.168.226.144
path: /data/k8sdata/magedu/static
# nodeSelector:
# project: magedu
# app: tomcat
imagePullSecrets:
- name: aliyun-registry-image-pull-key
---
kind: Service
apiVersion: v1
metadata:
labels:
app: magedu-tomcat-app1-service-label
name: magedu-tomcat-app1-service
namespace: magedu
spec:
#type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
#nodePort: 30092
selector:
app: magedu-tomcat-app1-selector
构建nginx镜像
修改nginx配置
upstream tomcat_webserver {
server magedu-tomcat-app1-service.magedu.svc.k8s.local:80;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /webapp {
root html;
index index.html index.htm;
}
location /myapp {
proxy_pass http://tomcat_webserver;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
[root@k8s-master1 app1]# cat Dockerfile
#Nginx 1.20.2
FROM k8s-harbor.com/public/nginx-base:v1.20.2
RUN useradd tomcat -u 2050
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
ADD app1.tar.gz /usr/local/nginx/html/webapp/
ADD index.html /usr/local/nginx/html/index.html
ADD run_tomcat.sh /usr/local/nginx/sbin/
#静态资源挂载路径
RUN mkdir -p /usr/local/nginx/html/webapp/static /usr/local/nginx/html/webapp/images && chown tomcat.tomcat -R /usr/local/nginx/html/webapp/static /usr/local/nginx/html/webapp/images
EXPOSE 80 443
CMD ["/usr/local/nginx/sbin/run_tomcat.sh"]
#CMD ["nginx"]
[root@k8s-master1 app1]# cat run_tomcat.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx
tail -f /etc/hosts
创建nginx pod
[root@k8s-master1 nginx]# cat nginx.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: magedu-nginx-deployment-label
name: magedu-nginx-deployment
namespace: magedu
spec:
replicas: 1
selector:
matchLabels:
app: magedu-nginx-selector
template:
metadata:
labels:
app: magedu-nginx-selector
spec:
containers:
- name: magedu-nginx-container
image: k8s-harbor.com/project/nginx-web1:202205041902
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
- containerPort: 443
protocol: TCP
name: https
env:
- name: "password"
value: "123456"
- name: "age"
value: "20"
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: magedu-images
mountPath: /usr/local/nginx/html/webapp/images
readOnly: false
- name: magedu-static
mountPath: /usr/local/nginx/html/webapp/static
readOnly: false
volumes:
- name: magedu-images
nfs:
server: 192.168.226.144
path: /data/k8sdata/magedu/images
- name: magedu-static
nfs:
server: 192.168.226.144
path: /data/k8sdata/magedu/static
#nodeSelector:
# group: magedu
imagePullSecrets:
- name: aliyun-registry-image-pull-key
---
kind: Service
apiVersion: v1
metadata:
labels:
app: magedu-nginx-service-label
name: magedu-nginx-service
namespace: magedu
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
nodePort: 30090
- name: https
port: 443
protocol: TCP
targetPort: 443
nodePort: 30099
selector:
app: magedu-nginx-selector
修改负载均衡配置
listen k8s_linux66_tomcat_80
bind 192.168.226.202:80
mode tcp
server node1 192.168.226.145:30090 check inter 2000 fall 3 rise 5
server node2 192.168.226.146:30090 check inter 2000 fall 3 rise 5
验证
静态文件转发到nginx,动态通过nginx转发到tomcat
更多推荐
所有评论(0)