Pods
官方文档
Pod 是 k8s 抽象出来的,表示一组一个或多个应用程序容器。以及这些容器的一些共享资源。
- 共享存储,当做卷
- 网络,唯一的集群 IP 地址
- 有关每个容器如何运行的信息
工作节点
一个 Pod 总是运行在工作节点,工作节点是 k8s 中的参与计算的机器。
每个 k8s 工作节点至少运行:
- kubelet,负责 k8s 主节点和工作节点之间通信的过程,它管理 Pod 和机器上运行的容器
- 容器运行时 (如 docker) 负责从仓库中提取容器镜像,解压容器和运行应用程序
- kubectl get - 列出资源
- kubectl describe - 显示有关资源的详细信息
- kubectl logs - 打印 pod 和其中容器的日志
- kubectl exec - 在 pod 中的容器上执行命令
1
2
3
4
5
6
7
8
|
# 查看所有 pod
kubectl get pods -owide
# 获取 Pod 信息
kubectl describe pods
# 查看标签
kubectl get po --show-labels
# 通过标签批量删除 pod, -l 是 --selector 的短命令
kubectl delete po -l name=busybox-pod
|
通过文件创建 pod
1
2
3
4
5
|
# 创建 yaml 文件
# 你可以使用 --dry-run=client 参数来预览而不真正提交即将下发到集群的对象实例
kubectl run redis --image=redis12 --dry-run=client -oyaml > redis-definition.yaml
# 通过文件创建 pod
kubectl create -f redis-definition.yaml
|
更新配置
- replace ,使用新的配置文件中的 API 对象,替换原有对象
- apply,执行一个对原有 API 对象的 PATCH 操作
1
2
3
4
5
|
# 修改 配置文件
kubectl apply xxx.yaml
# 或者
kubectl edit pod redis
kubectl replace -f redis.yaml --force
|
使用代理
1
|
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
|
查看日志
一旦 pod 启动并运行,可以直接在容器上执行命令
1
2
3
4
|
# 列出容器环境变量
kubectl exec $POD_NAME -- env
# 启动一个 bash 会话
kubectl exec -ti $POD_NAME -- bash
|
删除 pod
1
|
kubectl delete po/webapp
|
ReplicaSet
官方文档
目的是维护一组任何时候都处于运行状态的 Pod 副本的稳定集合。
1
2
3
4
5
6
7
8
|
# 查看系统上运行了多少 replicaSet
kc get rs
# 查看描述
kc describe rs/new-replica-set
# 查看解释
kc explain replicaset
# 批量删除
kc delete rs/replicaset-1 rs/replicaset-2
|
缩放 pod 的数量
1
|
kc scale rs/new-replica-set --replicas=5
|
获取编辑文件,修改参数
1
|
kc edit rs/new-replica-set
|
Deployment
官方文档
一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力。
常用命令
1
2
3
4
5
6
|
# 查看部署
kc get deploy
# 查看镜像
kc describe deploy/frontend-deployment | grep -i image
# 创建文件
kc create deploy httpd-frontend --image=httpd:2.4-alpine --replicas=3 --dry-run=client -oyaml > httpd-frontend.yaml
|
Namespace
官方文档
1
2
3
4
5
6
7
8
9
10
|
# 创建名字空间
kc create ns dev-ns
# 查看有多少名字空间
kc get ns --no-headers | wc -l
# 查看 research 空间下有多少 Pods
kc get po -n research
# 在 finance 空间创建镜像
kc run redis --image=redis -n finance
# 查看哪个 pod 属于 blue 空间
kc get po -A | grep blue
|
通过配置文件来创建或修改名字空间
通过 DNS 名称来访问
1
2
|
db-service.dev.svc.cluster.local
# <svc 名称>.<名字空间>.svc.cluster.local
|
重要的命令
创建 Pods ,加上 tier=db
标签
1
|
kc run redis --image=redis:alpine -l tier=db
|
在配置文件编写标签
设置端口
1
|
kc expose po/redis --name=redis-service --port=6379
|
- port 服务端口
- target-port 容器端口
- type 有四种 ClusterIP(默认),NodePort, LoadBalancer, ExternalName
创建 Pod 的同时暴露端口
1
|
kubectl run httpd --image=httpd:alpine --port=80 --expose
|
执行命令和参数
官方文档
Pod 创建文件中 comamnd
与 Dockerfile 中 ENTRYPOINT ["python", "app.py"]
对应
Pod 创建文件中 args: ["--color", "pink"]
与 Dockerfile 中CMD ["--color", "red"]
对应
1
2
|
# 创建容器时,修改参数
kc run webapp-green --image=kodekloud/webapp-color -- "--color=green"
|
ConfigMaps
官方文档
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。
ConfigMap 将环境配置信息和 容器镜像 解耦,便于应用配置的修改。
设置环境变量
1
2
3
4
5
6
7
8
|
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- env:
- name: APP_COLOR
value: green
|
常用命令
1
2
3
4
5
6
|
# 查看有多少 configmap
kc get cm
# 查看详情
kc describe cm/db-config
# 通过命令创建 configmap
kc create cm webapp-config-map --from-literal=APP_COLOR=darkblue
|
通过配置文件创建 configmap
1
|
kc create cm webapp-config-map --from-file=webapp-config-map.toml
|
为 Pod 配置 configmap
1
2
3
4
5
6
7
8
|
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- envFrom:
- configMapRef:
name: webapp-config-map
|
Secret
官方文档
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。使用 Secret 意味着你不需要在应用程序代码中包含机密数据。Secret 类似于 ConfigMap 但专门用于保存机密数据。
1
2
3
4
5
|
# 创建 通用类型 secret
kc create secret generic <名称> --from-literal=DB_Host=sql01
# 例子
kc create secret generic db-secret --from-literal=DB_Host=sql01 --from-literal=DB_User=root --from-literal=DB_Password=password123
|
为 Pod 配置 secret 环境变量
1
2
3
4
5
6
7
8
|
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- envFrom:
- secretRef:
name: db-secret
|
Security Context
官方文档
安全上下文定义 Pod 或 Container 的特权与访问控制设置。
1
2
|
# 在容器内执行命令,查看当前是哪个用户
kubectl exec <Pod 名称> -- whoami
|
配置系统用户
1
2
3
4
5
6
7
|
apiVersion: v1
kind: Pod
metadata:
spec:
securityContext:
runAsUser: 1010
containers:
|
Resource Limits
官方文档
OOMKILLED
错误表示内存不足
修改配置
- requests 资源设定请求值
- limit 约束值
K,M,G,T,P,E #通常是以1000为换算标准的。
Ki,Mi,Gi,Ti,Pi,Ei #通常是以1024为换算标准的。
K8S 的 1000 = CPU 一个核。四核表示 4*1000
1
2
3
4
5
6
7
8
9
10
11
12
|
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- resources:
limits:
memory: 20Mi
cpu:
requests:
memory: 5Mi
cpu:
|
Service-Accounts
官方文档
Kubernetes 区分用户账号和服务账号的概念
- 用户账号是针对人而言的。 服务账号是针对运行在 Pod 中的进程而言的。
- 用户账号是全局性的。其名称跨集群中名字空间唯一的。服务账号是名字空间作用域的。
通用命令
1
2
3
4
|
# 查看有多少 service account
kc get sa
# 创建
kc create sa <名称>
|
配置文件自动读取服务账号
1
2
3
4
5
6
|
apiVersion: v1
kind: Pod
metadata:
spec:
serviceAccountName: dashboard-sa
containers:
|
Taints And Tolerations
官方文档
污点和容忍度相互配合,可以用来避免 Pod 被分配到不合适的节点上。 如果你需要某个节点仅会运行某一类 Pod。
通用命令
效果
- NoSchedule,Kubernetes 不会将 Pod 分配到该节点。
- PreferNoSchedule,Kubernetes 会 尝试 不将 Pod 分配到该节点
- NoExecute, Kubernetes 不会将 Pod 分配到该节点,已经存在会驱逐。
1
2
3
4
5
6
|
# 查看节点上的污点
kubectl describe node node01 | grep -A2 -i taints
# 为 node01 节点创建污点
kc taint node node01 spray=mortein:NoSchedule
# 删除污点,默认加 - 号
kc taint node node01 spray=mortein:NoSchedule-
|
通过对 Pods 设置容忍,将 Pods 分配到指定污点的节点
1
2
3
4
5
6
7
8
9
10
|
apiVersion:
kind:
metadata:
spec:
tolerations:
- key: "spray"
operator: "Equal"
value: "mortein"
effect: "NoSchedule"
containers:
|
Node Affinity 节点亲和性
官方文档
有两种类型
- requiredDuringSchedulingIgnoredDuringExecution 硬需求,调度到一个节点必须满足的规则
- preferredDuringSchedulingIgnoredDuringExecution 软需求,调度器尝试执行,但不能保证达到
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
|
规则表示: Pod 只能放置在具有标签键kubernetes.io/e2e-az-name
且值为e2e-az1
或e2e-az2
的节点上。
另外,在满足这些标准的节点中,具有标签 another-node-label-key=another-node-label-value
的节点优先使用。
operator
的可选参数:
- In
- NotIn
- Exists
- DoesNotExist
- Gt
- Lt
依据强制的节点亲和性调度 Pod,下方的配置意味着 Pod 只会被调度到具有 color=blue
标签的节点上。如果你需要 Pod 优先或强制调度到某个节点。
已经部署的 Pod 不会处理。
1
2
3
4
5
6
|
# 查看所有节点的标签
kubectl get nodes --show-labels
# 为节点添加标签
kubectl label node node01 color=blue
# 删除标签
kc label node node01 color-
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
apiVersion:
kind:
metadata:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: color
operator: In
values:
- blue
containers:
|
将 Pod 部署到 master 节点上
1
2
3
4
5
6
7
8
9
10
11
12
|
apiVersion:
kind:
metadata:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/master
operator: Exists
containers:
|
存活/就绪/启动探测器
官方文档
livenessProbe
存活探测器可以探测到应用死锁,如果应用发生崩溃,Pod 会重启
readinessProbe
就绪探测器可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。当应用程序崩溃时,容器会重新启动。在此期间,服务将用户引导至可用的 POD。
- 启动探测器来了解应用容器何时启动。启动探测器可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- name: liveness
# http 存活探测
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
# 执行第一次探测前应该等待 5 秒
initialDelaySeconds: 3
# 每隔 3 秒执行一次存活探测
periodSeconds: 3
|
使用启动探测器保护慢启动容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- name: liveness
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1 # 探测失败时,重试次数,默认值 3
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
|
多容器 Pod
1
2
|
# 查看 webapp-2 Pod 中的 simple-webapp 容器
kubectl logs webapp-2 -c simple-webapp
|
性能检查
1
|
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
|
1
2
3
4
|
# 查看各个 node 性能
kubectl top node
# 查看各个 pod 性能
kc top po
|
更新
1
2
|
# 查看更新策略
kc describe deploy/frontend | grep StrategyType
|
重建更新
Recreate
重建更新,会立即停止所有容器,重新创建。
滚动更新
用户希望应用程序始终可用,而开发人员则需要每天多次部署它们的新版本。在 Kubernetes 中,这些是通过滚动更新(Rolling Updates)完成的。 滚动更新 允许通过使用新的实例逐步更新 Pod 实例,零停机进行 Deployment 更新。新的 Pod 将在具有可用资源的节点上进行调度。
默认情况下,更新期间不可用的 pod 的最大值和可以创建的新 pod 数都是 1。这两个选项都可以配置为(pod)数字或百分比。 在 Kubernetes 中,更新是经过版本控制的,任何 Deployment 更新都可以恢复到以前的(稳定)版本。
与应用程序扩展类似,如果公开了 Deployment,服务将在更新期间仅对可用的 pod 进行负载均衡。可用 Pod 是应用程序用户可用的实例。
滚动更新允许以下操作:
- 将应用程序从一个环境提升到另一个环境(通过容器镜像更新)
- 回滚到以前的版本
- 持续集成和持续交付应用程序,无需停机
kubectl set image 更新镜像
1
|
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
|
获取端口并设置成环境变量
1
|
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
|
检查
1
2
3
4
5
6
7
8
9
|
kubectl rollout status deployments/kubernetes-bootcamp
# 回滚
kubectl rollout undo deployments/kubernetes-bootcamp
# 重新部署
kubectl rollout restart deployments/kubernetes-bootcamp
# 查看历史版本
kubectl rollout history deployments/kubernetes-bootcamp
# 回到指定的历史版本
kubectl rollout undo deploy/frontend --to-revision=2
|
RollingUpdate
滚动更新,设置 maxUnavailable 和 maxSurge 控制更新容器幅度。
1
2
3
4
5
|
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
|
修改 strategy type ,使用 kubectl edit
可以直接修改。
Jobs And CronJob
如何列出隶属某 job 的所有 pods ?
1
|
kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}'
|
模板关键字
1
2
3
4
5
6
7
8
|
spec:
template:
# 最大失败次数,达到次数后视为 job 失败
backoffLimit: 4
# 控制并行数量(非负整数),默认为 1,设置为 0 时间相当于暂停任务
parallelism: 3
# 需要完成的数量
completions: 1
|
Service 网络服务
1
2
3
4
5
6
|
# 查看,第一个 kubernetes 是 k8s 启动默认创建的服务
kubectl get svc
# 创建模板
kc create svc nodeport webapp-service --tcp 8080:8080 --node-port 30080 --dry-run=client -oyaml > s.yaml
# 对现有的部署创建 svc
kubectl expose -n ingress-space deployment ingress-controller --type=NodePort --port=80 --name=ingress --dry-run=client -o yaml > ingress.yaml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: NodePort
ports:
- targetPort: 8080 # 容器接收流量的端口
port: 8080 # 主机上其他 Pod 通过该端口访问 Service
nodePort: 30080 # 外部流量访问K8s的一种方式,即nodeIP:nodePort
selector:
name: simple-webapp
|
Network Policy 网络策略
如果你希望在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量, 则你可以考虑为集群中特定应用使用 Kubernetes 网络策略(NetworkPolicy)。
前置条件
网络策略通过网络插件 来实现。要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。 创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。
Ingress
官方文档
可以提供负载均衡、SSL 终结和基于名称的虚拟托管
需要安装控制器
1
2
3
4
|
# 安装 ingress 控制器
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml
# 检查
kubectl get pods --namespace=ingress-nginx
|
Volume
持久化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
---
apiVersion: v1
kind:
metadata:
spec:
containers:
- name: nginx
# 容器内挂载的文件夹
volumeMounts:
- mountPath: /log
name: log-volume
volumes:
# 主机上的文件夹
- name: log-volume
hostPath:
path: /var/log/webapp
type: Directory
|
PersistentVolume
1
2
3
4
5
6
7
8
9
10
11
12
|
apiVersion: v1
kind: PersistentVolume
metadata:
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 100Mi
# 使用节点本地目录存储,生成环境不要使用
hostPath:
path: /tmp/data
|
accessModes |
说明 |
ReadOnlyMany |
只读 |
ReaedWriteOnce |
读写一次 |
ReadWriteMany |
读写多次 |
Helm
ubuntu 安装 helm
1
2
3
4
5
|
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt-get install apt-transport-https --yes
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
|
参考