k8s基础知识扫盲及企业落地实践
k8s基础知识概念扫盲以及k8s企业级真实落地实践分享
k8s基础组件有那些
k8s容器编排,简单理解就是统一调度容器的执行顺序,例如哪个容器先处理,哪个容器后处理,同时也可以实现配置文件统一管理、节点动态的扩容和缩容、应用程序滚动升级以及具备自愈能力。k8s可以集成docker引擎来执行docker容器的调度,主要也是采用docker做为主要容器引擎的解决方案。
什么是NameSpace
NameSpace是kubernetes集群中的虚拟化集群 ,是对一组资源和对象的抽象集合,在一个k8s集群中可以有多个命名空间,彼此之间逻辑隔离。常见的pods、services、replication、controllers和deployments等都是属于某一个命名空间(不指定是default),而node、persistentVolumes等则不属于任何命名空间。
# 查看所有的命名空间
kubectl get namespace
# 创建命名空间
kubectl create namespace name
# 删除命名空间
kubectl delete namespace name
什么是Pod
Pod是k8s集群调度的最小单元,由一个或多个容器的组合,这些容器共享存储、网络和命名空间,以及运行的规范,在Pod中,所有容器都被同一安排和调度,并运行在共享的上下文中,就像豌豆荚中的一颗颗豆子。Pod中特别的有两个点,网络和存储。
每个Pod都会被指派唯一的IP地址,在Pod中的每一个容器共享网络命名空间,包括IP地址和端口。在同一个Pod中的容器可以使用localhost互相通信,类似在同一台虚拟主机。当Pod中的容器需要与外部进行通信时,则需要通过端口等共享的网络资源。
同时Pod能够被指定共享数据卷的集合,在Pod中所有的容器能够访问共享数据卷,允许这些容器共享数据。数据卷也允许在一个Pod持久化,以防止其中的容器被重启。
在k8s集群中, 一般不直接创建Pod,而是通过控制器和模版配置来管理和调度。Pod支持三种重启策略,以应对异常情况下Pod的中止,可以在配置文件中通过restartPolicy字段指定。
1:Always:只要退出就会重启
2:OnFailure:只有在失败退出(exit code不等于0)时,才会重启
3:Never:只要退出,就不再重启
# 查看default命名空间下的pods
kubectl get pods
# 查看icc命名空间下的pods
kubectl get pods -n icc
# 查看所有命名空间下的pods
kubectl get pod -A
# 在icc命名空间中创建一个pod副本的deployment
kubectl run icc-tomcat9 --image=tomcat:9.0.20-jre8-alpine --port=8080
# 将副本扩容至3个
kubectl scale --replicas=3 deployment/icc-tomcat9
# 创建服务
kubectl expose deployment icc-tomcat9 --name=tomcat9-svc --port=8888 --
target-port=8080 --protocol=TCP --type=NodePort
# 访问服务端口
curl 192.168.137.201:8888
什么是Service
在k8s集群中,可以看成Service是访问一组Pod的策略,一般通过Label Selector访问Pod组从而实现负载均衡,就像在一个房间里不管有多少个凳子,但总得有一个门可以出入。Service跟Pod是一对一或者一对多的关系。
Service有四种类型:
ClusterIP:默认,分配一个集群内部可以访问的虚拟IP
NodePort:在每个Node上分配一个端口作为外部访问入口
LoadBalancer:工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack
ExternalName:表示把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部服务的通信
Service有三个参数:
port :k8s集群服务之间访问的端口(可以理解成内网端口)
targetPort :Pod中容器端口,与制作容器时暴露的端口一致(容器的端口)
NodePort: 通过Node实现外网用户访问Service的端口(可以理解成外网端口,30000-32767)
什么是Deployment
k8s中控制器的别称,具有上线部署、滚动升级、创建副本、回滚到以前某一版本(成功/ 稳定)等功能。控制器也有好几种类型:
类型 | 作用 |
---|---|
Deployment | 声明式更新控制器,用于发布无状态应用 |
ReplicaSet | 副本集控制器,用于对Pod进行扩容或缩容 |
StatefulSet | 有状态副本集,用于发布有状态应用 |
DaemonSet | 在k8s集群每一个Node上运行一个副本, 用于发布监控或日志收集类等应用 |
Job | 运行一次性作业任务 |
CronJob | 运行周期性作业任务 |
Deployment包含ReplicaSet,除非需要自定义升级功能或者根本不需要升级Pod,否则建议使用 Deployment。
什么是ConfigMap
ConfigMap可以看成一个Map,可以用于保存配置数据的键值对,可以用来保存单个属性,也可以保存配置信息。
ConfigMap会将内容与文件映射,提供配置中心的功能,保持容器化应用程序的可移植性。Configmap 可以从文件、目录或者 key-value 字符串创建等创建;也可以通过 kubectl create -f从描述文件创建;可以使用 kubectl create创建命令。创建ConfigMap的方式有4种:
1:直接在命令行中指定configmap参数创建,即–from-literal。
2:指定文件创建,即将一个配置文件创建为一个ConfigMap–from-file=<文件>
3:指定目录创建,即将一个目录下的所有配置文件创建为一个ConfigMap,–from-file=<目录>
4:先写好标准的configmap的yaml文件,然后kubectl create -f 创建
Pod的生命周期
1: initContainer:容器初始化。遵从几个规则:init总是运行成功完成为止;上一个容器初始化成功才会执行下一个容器的初始化;如果容器初始化失败,k8s会不断重启该Pod,除非配置的restartPolicy为never。
2:readinessProbe:就绪检测,检测Pod是否启动完成
3:livenessProbe:存活性探测,检测Pod是否正常运行存活
4:startHook:容器启动后的钩子
Pod对象自从创建开始至终止的时间范围称为生命周期,在这段时间中,Pod会处于多种不同的状态,并执行一些操作;其中,创建主容器为必须的操作,其他包括初始化容器(initContainer)、启动的钩子(startHook)、容器的存活性探测(livenessProbe)、就绪性探测(readinessProbe)以及容器终止前钩子(preStopHook)等,这些操作都可以自定义。
镜像的执行策略有哪些
下载策略
imagePullPolicy:
Always:总是拉取 pull
IfNotPresent:如果本地有镜像,使用
Never:只使用本地镜像,从不拉取
重启策略
restartPolicy:
Always:只要退出就重启。
OnFailure:失败退出时(exit code不为0)才重启
Never:永远不重启
数据卷挂载的方式有那些
数据卷挂载主要有两种方式:hostPath、emptyDir。
hostPath类型的存储卷是指将工作节点上某文件系统的目录或文件挂载于Pod中的一种存储卷。把宿主机上的目录挂载到容器,但是在每个节点上都要有,因为不确定容器会分配到哪个节点。也是把存储从宿主机挂载到k8s集群上,但它有许多限制,例如只支持单节点(Node),而且只支持“ReadWriteOnce”模式。
emptyDir存储卷是Pod生命周期中的一个临时目录,在pod对象被移除时会被一并删除,可以用作Pod中容器间的数据共享,或者作为容器数据的临时存储目录用于数据缓存系统等。
企业级案例分享
最后再分享关于公司应用在k8s改造上的实践。模块本身的无状态改造这里就不介绍了,主要还是关注k8s的运用。
以其中的一个模块改造为例,因为配置中心不支持文件夹的挂载,而且挂载之后的文件只有读权限,没有写权限,所以在镜像打包的时候会把配置文件分成两部分,文件夹以及程序修改的文件直接打包到镜像里,其他配置文件则放到配置中心。
打包完镜像,推送到harbor
docker build --tag 172.16.15.121:10000/icc/mix-receiver:4.1.0 ./
docker push 172.16.15.121:10000/icc/mix-receiver:4.1.0
接着创建一个Service,统一Pod对外暴露的端口为30030
apiVersion: v1
kind: Service
metadata:
name: mix-receiver
namespace: icc
spec:
selector:
app: mix-receiver
ports:
- port: 30020
nodePort: 30030
type: NodePort
创建配置文件,配置文件就是简单的CV,但是需要注意yaml的文件输出控制符(|、>、>+、>-、|+、|-),一般用 | 就足够了,主要在server.conf上需要注意。
apiVersion: v1
kind: ConfigMap
metadata:
name: mix-receiver-config
namespace: icc
data:
application.properties: |
# 集群识别号: 0~3
server.clusterId=0
# 模块识别号
server.moduleId=0
# 机器识别号 0~31
server.workerId=1
# 接口接入验证时间上下限, 0代表不限制
security.authTimestampLowerLimitSeconds=0
security.authTimestampUpperLimitSeconds=0
# ********** MQ **********
rocketmq.namesrvAddr=127.0.0.1:9876
rocketmq.sendMsgTimeoutInMillis=8000
rocketmq.maxMessageSizeInMB=64
rocketmq.namespace=
# ********** 缓存 **********
cache.refresh.enabled=false
cache.customer.maxSize=1000000
cache.customer.expireSeconds=120
application-mysql.yml: |
icc-primary-db:
poolName: iccPrimaryDB
driverClassName: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/icc_4.1.0?useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&sessionVariables=FOREIGN_KEY_CHECKS=0&useUnicode=yes&characterEncoding=UTF-8&rewriteBatchedStatements=true
username: root
password:
autoCommit: false
maximumPoolSize: 50
minimumIdle: 8
initialSize: 8
connectionTimeout: 20000
validationQuery: select 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
redisson-cluster.json: |
{
"clusterServersConfig": {
"idleConnectionTimeout": 10000,
"pingTimeout": 1000,
"connectTimeout": 50000,
"timeout": 60000,
"retryAttempts": 3,
"retryInterval": 1500,
"failedSlaveReconnectionInterval": 3000,
"failedSlaveCheckInterval": 60000,
"password": ,
"subscriptionsPerConnection": 5,
"clientName": "icc-redis-cluster",
"loadBalancer": {
"class": "org.redisson.connection.balancer.RoundRobinLoadBalancer"
},
"subscriptionConnectionMinimumIdleSize": 1,
"subscriptionConnectionPoolSize": 8,
"slaveSubscriptionConnectionMinimumIdleSize":1,
"slaveSubscriptionConnectionPoolSize":6,
"slaveConnectionMinimumIdleSize":2,
"slaveConnectionPoolSize":16,
"masterConnectionMinimumIdleSize":2,
"masterConnectionPoolSize":16,
"readMode": "MASTER",
"subscriptionMode": "MASTER",
"nodeAddresses": [
"redis://127.0.0.1:7001",
"redis://127.0.0.1:7002",
"redis://127.0.0.1:7003",
"redis://127.0.0.1:7004",
"redis://127.0.0.1:7005",
"redis://127.0.0.1:7006"
],
"tcpNoDelay": false
},
"threads": 0,
"nettyThreads": 0,
"codec": {
"class": "org.redisson.codec.JsonJacksonCodec"
},
"transportMode": "NIO",
"useScriptCache": true
}
server.conf: >-
server.java.opts=-d64
-Xms2048m -Xmx2048m -Xmn1024m
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError
-javaagent:./agent/skywalking-agent.jar
-Dskywalking.agent.service_name=iccA11Server
-Dskywalking.collector.backend_service=localhost:11800
-Dskywalking.agent.instance_properties[groupName]=icc3.0
-Dskywalking.agent.instance_uuid=a11y-server
创建完配置文件,再创建Deployment,用来调度Pod。
apiVersion: apps/v1
kind: Deployment
metadata:
name: mix-receiver-deployment
namespace: icc
labels:
app: mix-receiver
spec:
replicas: 1
template:
metadata:
name: mix-receiver
labels:
app: mix-receiver
spec:
containers:
- name: mix-receiver
image: 172.16.15.121:10000/icc/mix-receiver:4.1.0
imagePullPolicy: Always
ports:
- containerPort: 30020
resources:
requests:
cpu: 1000m
memory: 5120Mi
limits:
cpu: 2000m
memory: 5120Mi
command: [ "sh", "-c", "cd /home/icc && cp -rf /conf/..data/* /home/icc/conf/ && sh startContainer.sh start" ]
volumeMounts:
- name: conf-volume
mountPath: /conf
- name: logs-volume
mountPath: /home/icc/logs
#启动探针
startupProbe:
failureThreshold: 3
tcpSocket:
port: 8848
initialDelaySeconds: 60
periodSeconds: 15
#就绪探针
#readinessProbe:
# tcpSocket:
# port: 30020
# initialDelaySeconds: 30
# periodSeconds: 15
#存活探针
livenessProbe:
tcpSocket:
port: 30020
initialDelaySeconds: 30
periodSeconds: 15
# 指定运行在某个节点
#nodeName: k8s-node-64
#tolerations:
# - effect: NoSchedule
# key: env
# operator: Equal
# value: test
volumes:
- name: conf-volume
configMap:
name: mix-receiver-config
- name: logs-volume
hostPath:
path: /home/icc/mix-receiver/logs
restartPolicy: Always
selector:
matchLabels:
app: mix-receiver
整个流程主要就是镜像的拉取、配置文件和数据卷的挂载,资源的限制以及Pod生命周期就绪探针和存活探针的运用,另外还配置了Pod的重启策略。
配置到kuboard,点击bash进入容器可以查看模块的启动情况,同时Deployment处于就续状态,则整体配置正常。
更多推荐
所有评论(0)