k8s中常见的资源对象的使用
Deployment
基本特性:
确保预期的pod副本数量
无状态应用部署
有状态应用部署
确保所有的node运行同一个pod
一次性任务和定时任务
与Pod之间的关系
Pod是通过Controller实现应用的运维,例如伸缩,滚动升级。
Pod和Controller之间通过label标签和selector选择器建立关系
应用场景
部署无状态应,web服务,微服务
管理Pod和ReplicaSet
部署,滚动升级等功能
示例:
root@deploy:/opt/k8s-data# cat deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: web labels: app: web spec: selector: matchLabels: app: web replicas: 2 template: metadata: labels: app: web spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent - name: tomcat image: tomcat imagePullPolicy: IfNotPresent --- kind: Service apiVersion: v1 metadata: labels: app: web-service name: web-service namespace: default spec: type: NodePort ports: - name: nginx port: 80 protocol: TCP targetPort: 80 nodePort: 30001 - name: tomcat port: 8080 protocol: TCP targetPort: 8080 nodePort: 30002 selector: app: web
验证访问
Deployment滚动升级
Deployment每次创建的Pod数量是可以定制的。 Kubernetes提供了两个参数maxSurge和maxUnavailable来精细控制Pod的替换数量 。
Deployment会在.spec.strategy.type==RollingUpdate时,采取滚动更新的方式更新Pods。
指定maxUnavailable和maxSurge来控制滚动更新过程。
最大不可用
.spec.strategy.rollingUpdate.maxUnavailable是一个可选字段,用来指定更新过程中不可用的Pod的个数上限。该值可以是绝对数字(例如,5),也可以是所需 Pods的百分比(例如,10%)。百分比值会转换成绝对数并去除小数部分。如果.spec.strategy.rollingUpdate.maxSurge为0,则此值不能为0。默认值为25%。
maxUnavailable,此参数控制滚动更新过程中不可用的副本相占DESIRED的最大比例。maxUnavailable可以是具体的整数(比如3),也可以是百分百,向下取整。maxUnavailable默认值为25%。
例如,DESIRED为10,那么可用的副本数至少要为10 - roundDown(10 * 25%)= 8,所以看到AVAILABLE是8。(则Deployment创建的pod副本数为4,升级过程中,旧的数量副本数为3,4-4*0.25)
例如,当此值设置为30%时,滚动更新开始时会立即将旧ReplicaSet缩容到期望Pod个数的70%。新Pod准备就绪后,可以继续缩容旧有的ReplicaSet,然后对新的ReplicaSet扩容,确保在更新期间可用的Pods总数在任何时候都至少为所需的Pod个数的70%。
最大峰值
.spec.strategy.rollingUpdate.maxSurge 是一个可选字段,用来指定可以创建的超出期望 Pod 个数的 Pod 数量。此值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。如果 MaxUnavailable 为 0,则此值不能为 0。百分比值会通过向上取整转换为绝对数。此字段的默认值为 25%。
maxSurge,此参数控制滚动更新过程中副本总数超DESIRE的上限。maxSurge可以是具体的整数(比如3),也可以是百分百,向上取整。maxSurge默认值为25%。例如, DESIRED为10, 那么副本总数的最大值为roundUp(10 + 10 * 25%) =13,所以看到CURRENT就是13。
例如,当此值为30%时,启动滚动更新后,会立即对新的ReplicaSet扩容,同时保证新旧Pod的总数不超过所需 Pod 总数的 130%。一旦旧Pods被杀死,新的ReplicaSet可以进一步扩容,同时确保更新期间的任何时候运行中的Pods 总数最多为所需Pods总数的 130%。(例如:当前4个副本,最大峰值为25%,则副本pod数量最高不能超过5个,4+4*0.25)
滚动升级
kubectl set image deployment/nginx nginx=10.0.0.11:5000/lxh/nginx:v1 --record # --record记录滚动升级的change-cause,能在rollout history中体现
验证:升级成功
kube# kubectl rollout status deployment web deployment "web" successfully rolled out
查看升级的历史:
root@master:~/.kube# kubectl rollout history deployment web deployment.apps/web REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 kubectl set image deployment/nginx nginx=10.0.0.11:5000/lxh/nginx:v1 --record=true
Deployment回滚
undo默认还原至上一个版本
kubectl rollout undo deployment/nginx
回滚可以在升级后进行版本回退
使用--to-reversion=<版本号>,指定版本进行回滚
root@master:~/.kube# kubectl rollout undo deployment web --to-revision=3 deployment.apps/web rolled back
Deployment终止升级
kubectl rollout pause deployment web
Deployment恢复终止升级
kubectl rollout resume deployment web
SVC
Kubernetes Service定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector
Service能够提供负载均衡的能力,但是在使用上有以下限制:
只提供 4 层负载均衡能力,而没有 7 层功能,但有时可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的
Service存在意义
(1)防止Pod失联(服务)
(2)定义一组pod的访问策略(负载均衡)
service类型
--type参数:
(1)clusterIP:集群内部使用
(2)NodePort:对外访问应用
(3)LoadBalance:对外访问应用,公有云
clusterIP
用于pod之间互访访问,访问方式:直接访问service名称
多端口service示例:
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - name: http protocol: TCP port: 80 targetPort: 9376 - name: https protocol: TCP port: 443 targetPort: 9377
查看后端pod节点:(type为clueterIP)
[root@master10 svc]# kubectl get endpoints NAME ENDPOINTS AGE svc-dp-nginx 10.100.222.185:80,10.100.72.45:80,10.100.72.46:80 4m28s
验证service,pod内部之间访问:
NodePort
默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
多端口创建svc:
kubectl expose deployment nginx --type=NodePort --port=80,443 --target-port=80,443 --dry-run=client -o yaml > svc_multiport.yaml cat svc_multiport.yaml apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: nginx name: nginx spec: ports: - nodePort: 32110 name: port-1 port: 80 protocol: TCP targetPort: 80 - nodePort: 32443 name: port-2 port: 443 protocol: TCP targetPort: 443 selector: app: nginx type: NodePort status: loadBalancer: {}
手动命令expose创建svc,
先创建SVC,默认clusterIP模式
kubectl expose deployment nginx-deployment --port=8080 --target-port=80 #指定deployment,将nginx访问的80端口转发到8080 [root@master01 ~]# kubectl get svc #查看SVC NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 14d nginx-deployment ClusterIP 10.100.139.198 <none> 8080/TCP 84s 访问验证 [root@master01 ~]# curl -I 10.100.139.198:8080 #成功访问 HTTP/1.1 200 OK Server: nginx/1.19.5 Date: Sun, 13 Dec 2020 01:27:10 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 24 Nov 2020 13:02:03 GMT Connection: keep-alive ETag: "5fbd044b-264" Accept-Ranges: bytes [root@master01 ~]# ipvsadm -Ln #查看LVS成功负载均衡,并做了rr轮询 TCP 10.200.139.198:8080 rr -> 10.100.1.17:80 Masq 1 0 0 -> 10.100.1.18:80 Masq 1 0 1 -> 10.100.2.2:80
配置转发映射为NodePort模式,暴露SVC端口
[root@master01 ~]# kubectl edit svc nginx-deployment #编辑SVC配置文件 spec: clusterIP: 10.100.139.198 externalTrafficPolicy: Cluster ports: - nodePort: 30401 port: 8080 protocol: TCP targetPort: 80 selector: run: nginx-deployment sessionAffinity: None type: NodePort #将ClusterIP修改为NodePort [root@master01 ~]# kubectl get svc #验证,得到映射到本机的30401端口 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 14d nginx-deployment NodePort 10.100.139.198 <none> 8080:30401/TCP 7m24s [root@master01 ~]# ss -lntup|grep 30401 #本地端口已被监听 tcp LISTEN 0 128 [::]:30401 [::]:* users:(("kube-proxy",pid=3114,fd=11))
ConfigMap
Configmap配置信息和镜像解耦,实现方式为将配置信息放到configmap对象中,然后再pod的中做为Volume挂载到pod中,从而实现导入配置的目的。
使用场景:
通过Configmap给pod定义全局环境变量
通过Configmap给pod传递命令行参数,如mysql -u -p中的账户名密码可以通过Configmap传递。
通过Configmap给pod中的容器服务提供配置文件,配置文件以挂载到容器的形式使用。
作用:
存储不加密数据到etcd,让Pod以变量或者Volume挂载到容器中。
与Secret的区别在于:Secret对数据加密,ConfigMap不对数据加密
注意:
Configmap需要在pod使用它之前创建。
pod只能使用位于同一个namespace的Configmap、及Configmap不能跨namespace使用
通常用于非安全加密的配置场景。
Configmap通常是小于1MB的配置。
使用场景:服务的配置文件
Nginx配置文件
1、创建config文件
conf 与 conf2分别是key ,“|”管道符对应 value内容
root@deploy:~# mkdir config/ root@deploy:~# cd config/ root@deploy:~/config# vim config.yaml apiVersion: v1 kind: ConfigMap metadata: name: nginx-config data: conf: | server { listen 8080; server_name www.configtest.com; location / { root /usr/share/nginx/html/configtest; index index.html index.htm; } } conf2: | server { listen 8081; server_name www.configtest2.com; location / { root /usr/share/nginx/html/configtest2; index index.html index.htm; } } root@deploy:~/config# kubectl apply -f config.yaml
2、创建应用和svc
root@deploy:~/config# vim nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: web name: web-deployment namespace: default spec: replicas: 2 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - image: nginx name: nginx imagePullPolicy: IfNotPresent - name: nginx-conf mountPath: "/etc/nginx/conf.d" - name: nginx-conf configMap: name: nginx-config items: - key: conf path: web.conf - key: conf2 path: web2.conf --- apiVersion: v1 kind: Service metadata: labels: app: web-svc name: web-svc namespace: default spec: ports: - name: web1 port: 80 protocol: TCP targetPort: 8080 nodePort: 30220 - name: web2 port: 81 protocol: TCP targetPort: 8081 nodePort: 30221 selector: app: web type: NodePort
查看创建的cofnigmap
查看pods
查看svc
客户端访问测试:
以Volume挂载到pod容器中
创建pod yaml
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: busybox image: busybox command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ] volumeMounts: - name: config-volume mountPath: "/etc/config" volumes: - name: config-volume configMap: name: redis-config restartPolicy: Never
验证:查看pod容器内日志输出
以变量形式挂载到pod容器中
创建ConfigMap yaml文件,声明两个变量special.level,special.type
apiVersion: v1 kind: ConfigMap metadata: name: myconfig namespace: default data: special.level: info special.type: hello
查看创建的configmap,在DATA一列为对应的两个变量
创建pod yaml,声明两个变量:LEVEL、TYPE,输出两个变量信息
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: busybox image: busybox command: [ "/bin/sh","-c","echo ${LEVEL} ${TYPE}" ] env: - name: LEVEL valueFrom: configMapKeyRef: name: myconfig key: special.level - name: TYPE valueFrom: configMapKeyRef: name: myconfig key: special.type restartPolicy: Never
查看pod日志输出变量信息
Secret
secret用来保存小片敏感数据的k8s资源,例如密码,token,OCP客户端配
置文件,Docker配置文件,私有sorce registry凭据或者秘钥。Secret对象可以与
pods分离独立定义,通过临时卷将敏感信息挂载给pods使用。这类数据当然也可以存放在Pod或者镜像中,但是放在Secret中是为了更方便的控制如何使用数据,并减少暴露的风险。
在通过yaml文件创建secret时,可以设置data或stringData字段,data和stringData字段都是可选的,data字段中所有键值都必须是base64编码的字符串,如果不希望执行base64字符串的转换操作,也可以选择设置stringData字段,其中可以使用任何非加密的字符串作为其取值。
Secret类型
(1)generic:键值对,对变量值base64加密,类型为Opaque。
(2)docker-registry:用于访问registry仓库的凭据,类型kubernetes.io/dockerconfigjson。
(3)tls:保存TLS公钥和私钥,类型为Opaque。
(4)basic-auth:用于基本身份验证凭据
(5)ssh-auth:用于SSH身份认证的凭据
(6)token:启动引导令牌数据
(7)service-account-token:ServiceAccount令牌
场景:generic
1、使用--from-literal=<key>=<value>标签提供Secret数据。
可以多次使用此标签,提供多个键值对。请注意,特殊字符(例如:$,\,*,= 和 !)由你的shell解释执行,而且需要转义。
kubectl create secret generic mysecret1 --from-literal=user=tom --from-literal=password1=redhat --from-literal=password2=redhat
查看yaml配置
kubectl get secrets mysecret1 -o yaml apiVersion: v1 data: password1: cmVkaGF0 password2: cmVkaGF0 user: dG9t kind: Secret metadata: creationTimestamp: "2022-06-25T06:04:14Z" name: mysecret1 namespace: default resourceVersion: "84642" uid: 8eebe653-53f3-4834-a00a-dc9278c27bcc type: Opaque
base64 –d解密
echo -n dG9t|base64 -d tom echo -n cmVkaGF0|base64 -d redhat
2、使用指定文件创建secret
(1)--from-file,指定文件进行创建secret,并以文件名作为secret的key。
一个 Secret 可以包含 Pod 访问数据库所需的用户凭证。例如,由用户名和密码组成的数据库连接字符串。可以在本地计算机上,将用户名存储在文件./username.txt中,将密码存储在文件./password.txt 中。
echo -n 标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。
echo -n 'admin' > ./username.txt echo -n '1f2d1e2e67df' > ./password.txt
kubectl create secret generic db-user-pass \ --from-file=./username.txt \ --from-file=./password.txt
查看yaml配置
key则是文件名,所以使用文件名作为key应规范创建密码文件
kubectl get secrets db-user-pass -o yaml apiVersion: v1 data: password.txt: MWYyZDFlMmU2N2Rm username.txt: YWRtaW4= kind: Secret metadata: creationTimestamp: "2022-06-25T07:02:47Z" name: db-user-pass namespace: default resourceVersion: "89570" uid: e8da86e3-5079-4443-b58c-480a0a085608 type: Opaque
解码 Secret
要查看创建的 Secret 的内容,运行以下命令:
kubectl get secret db-user-pass -o jsonpath='{.data}'
输出
{"password":"MWYyZDFlMmU2N2Rm","username":"YWRtaW4="}
(2)使用--from-env-file指定文件进行创建secret key和value
cat env.txt username=admin password=R0ot!z#$ kubectl create secret generic secretenv --from-env-file=env.txt
查看yaml配置
kubectl get secrets secretenv -o yaml apiVersion: v1 data: password: UjBvdCF6IyQ= username: YWRtaW4= kind: Secret metadata: creationTimestamp: "2022-06-25T07:23:01Z" name: secretenv namespace: default resourceVersion: "91271" uid: 8be27660-c2d4-438a-b381-18e9582b9c4b type: Opaque
3、stringData非加密类型
以使用任何非加密的字符串作为其取值
root@deploy:~/config# vim stringData.yaml apiVersion: v1 stringData: user: "admin" password: "admin" kind: Secret metadata: name: user-pass namespace: default type: Opaque
查看stringData信息得到的是非加密的
场景:凭证
作用:加密数据存在etcd里面,让Pod容器以挂载Volume方式进行访问
示例:
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4K password: MTIzNDU2Cg==
1、以变量形式挂载到pod容器中
pod声明用户名变量和密码变量:分别是SECRET_USERNAME,SECRET_PASSWORD
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: nginx image: nginx env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
验证:
进入到容器内,输出变量得到base64解码内容
创建数据库凭据
kubectl create secret generic mysecret --from-literal=username=root --from-literal=password=123456 cat secret_env.yaml apiVersion: v1 kind: Pod metadata: name: mysql labels: name: mysql spec: containers: - image: hub.c.163.com/library/mysql:latest imagePullPolicy: IfNotPresent name: mysql ports: - containerPort: 3306 name: mysql env: - name: MYSQL_ROOT_PASSWORD # 原先通过value设置环境变量值 valueFrom: secretKeyRef: name: mysecret key: password
验证
登录mysql,输入密码123456
2、以Volume形式挂载到容器中
(1)创建secret,nginx发布
kubectl create secret generic mysecret --from-literal="index.html"='hello K8s' kubectl get secrets mysecret -o yaml apiVersion: v1 data: index.html: aGVsbG8gSzhz kind: Secret metadata: creationTimestamp: "2022-06-25T08:01:31Z" name: mysecret namespace: default resourceVersion: "94519" uid: d97f7880-9301-46e2-9bbb-7cd979750d77 type: Opaque
创建pod,以volume形式引用secret
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: nginx image: nginx volumeMounts: - name: foo mountPath: "/usr/share/nginx/html" readOnly: true volumes: - name: foo secret: secretName: mysecret
验证:
本文来自博客园,作者:PunchLinux,转载请注明原文链接:https://www.cnblogs.com/punchlinux/p/16550791.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)