Pod & Container
Kubernetes 的最小调度单元是 Pod,在 Pod 中包含多个 Container。
Pod 基本操作
查看 Pod
pod 默认有 kube-default
和 kube-system
两个命名空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| kubectl get po|pod|pods
kubectl get pods -n [namspace]
kubectl get pods -A
kubectl get pod -o wide -n [namspace]
kubectl get pod -o wide -A
kubectl describe pod [pod-name]
|
先说一种不常用的方式,这种方式很 docker,该方式生产中一般不用。
1 2
| kubectl run [podname] --image=nginx:1.24
|
常用的创建方式:yml
文件(必须),创建 nginx-pod.yml
文件加入以下内容:
nginx-pod.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| apiVersion: v1
kind: Pod
metadata: name: nginx labels: key: value
spec: containers: - name: nginx image: nginx:1.24 ports: - containerPort: 80 restartPolicy: Always
|
IDEA 使用 Kubernetes 插件创建 yml
文件后输入 k
可以选择创建模板。
创建 pod:
1 2 3 4 5
| kubectl create -f nginx-pod.yml
kubectl apply -f nginx-pod.yml
|
默认会部署 pod 到当前的命名空间,如果要部署应用到指定的命名空间:kubectl apply -f filename.yml --namespace [namespace]
删除 Pod
1 2 3 4 5
| kubectl delete pod [podname]
kubectl delete -f [pod-yml]
|
Pod 其它操作
1 2 3 4 5 6 7
| kubectl exec -it [podname] -c [containername] -- bash
kubectl logs -f [podname]
kubectl logs -f [podname] -c [containername]
|
Pod 的 label 标签
标签是一组键值对组成,每个 key 对与给定对象必须是唯一的。
Pod Labels 必须小于 63 个字符;必须以字母、数字、字符开头和结尾;包含破折号、下划线、点和字母数字;
操作
1 2 3 4 5 6 7 8 9 10 11 12
| kubectl get pods --show-labels
kubectl label pod [podname] [key=value]
kubectl label --overwrite pod [podname] [key=value]
kubectl label pod [podname] [key-]
kubectl get pods -l [key/key=value]
|
Container 容器
容器重启策略
Pod 的 spec
包含一个 restartPolicy
字段,有三个可选值:Always(总是重启)、OnFailure(容器异常退出)、Never,默认为 Aways。
该值适用于 Pod 中的所有容器。
自定义容器的启动命令
推荐在 k8s 中使用 command
修改启动命令,使用 args
为启动命令传递参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: v1 kind: Pod metadata: name: redis labels: app: redis spec: containers: - name: redis image: redis:7.0.14 command: ["redis-server"] args: ["--appendonly yes"] ports: - containerPort: 6379 imagePullPolicy: IfNotPresent restartPolicy: Always
|
容器探针
probe 是由 kubelet 对容器执行的定期诊断,可以看作一个诊断工具。探针检测后有三种状态:
Sucess:成功,容器通过诊断;
Failure:失败,容器未通过诊断;
Unknown:未知,诊断失败,不会采取任何行动。
三种探针类型
livenessProbe:检测容器是否正在运行。
readinessProbe:检测容器是否准备好为请求提供服务。
startupProbe(1.7+):检测容器中的应用是否已经启动。
每种类型的探针都有以下几个机制/命令:
- exec:在容器内部执行命令,如果命令退出代码时返回 0,则诊断成功;
- grpc:使用远程过程调用,如果响应的状态是 “Serving”,则诊断成功。gRPC 探针是一个 Alpha 特性,需要启用
GPRCContainerProbe
特性时才能使用;
- httpGet:发送一个 GET 请求,如果响应码大于等于 200 且小于 400,则诊断成功;
- tcpSocket:对容器的 IP 地址上的指定端口执行 TCP 检查,如果端口打开,则诊断成功。如果远程系统在打开连接后立即将其关闭,这算作健康状态。
每种命令都有几个探针参数:
1 2 3 4 5 6 7 8 9 10
| initialDelaySeconds: 5
periodSeconds: 4
timeoutSeconds: 1
failureThreshold: 3
successThreshold: 1
|
举个例子:
举个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| apiVersion: v1 kind: Pod metadata: name: liveness-exec labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 args: - /bin/sh - -c - sleep 7;nginx -g "daemon off;" imagePuLLPoLicy: IfNotPresent livenessProbe: exec: command: - ls - /var/run/nginx.pid initialDelaySeconds: 5 speriodSeconds: 4 timeoutSeconds: 1 failureThreshold: 3 successThreshoLd: 1
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| apiVersion: v1 kind: Pod metadata: name: Liveness-httpget labels: httpget: httpget spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 args: - /bin/sh - -c - sleep 7;nginx -g "daemon off;" imagePuLLPoLicy: IfNotPresent livenessProbe: httpGet: port: 80 path: /index.htmt initialDelaySeconds: 5 speriodSeconds: 4 timeoutSeconds: 1 failureThreshold: 3 successThreshoLd: 1
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| apiVersion: v1 kind: Pod metadata: name: liveness-tcp labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 args: - /bin/sh - -c - sleep 7;nginx -g "daemon off;" imagePuLLPoLicy: IfNotPresent livenessProbe: tcpSocket: port: 80 initialDelaySeconds: 5 speriodSeconds: 4 timeoutSeconds: 1 failureThreshold: 3 successThreshoLd: 1
|
资源限制
在 Kubernetes 中对于容器的资源限制主要分为两类:内存资源限制、CPU 资源限制。Kubernetes 可以定义容易运行占用的资源限制,超过最大资源容器会被 kill,并报 OOM Error。
安装 metrics
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
| apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: metrics-server rbac.authorization.k8s.io/aggregate-to-admin: "true" rbac.authorization.k8s.io/aggregate-to-edit: "true" rbac.authorization.k8s.io/aggregate-to-view: "true" name: system:aggregated-metrics-reader rules: - apiGroups: - metrics.k8s.io resources: - pods - nodes verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: metrics-server name: system:metrics-server rules: - apiGroups: - "" resources: - nodes/metrics verbs: - get - apiGroups: - "" resources: - pods - nodes verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: k8s-app: metrics-server name: metrics-server-auth-reader namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: extension-apiserver-authentication-reader subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: k8s-app: metrics-server name: metrics-server:system:auth-delegator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: k8s-app: metrics-server name: system:metrics-server roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:metrics-server subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: v1 kind: Service metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: ports: - name: https port: 443 protocol: TCP targetPort: https selector: k8s-app: metrics-server --- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: selector: matchLabels: k8s-app: metrics-server strategy: rollingUpdate: maxUnavailable: 0 template: metadata: labels: k8s-app: metrics-server spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --metric-resolution=15s image: registry.k8s.io/metrics-server/metrics-server:v0.6.4 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /livez port: https scheme: HTTPS periodSeconds: 10 name: metrics-server ports: - containerPort: 4443 name: https protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /readyz port: https scheme: HTTPS initialDelaySeconds: 20 periodSeconds: 10 resources: requests: cpu: 100m memory: 200Mi securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 volumeMounts: - mountPath: /tmp name: tmp-dir nodeSelector: kubernetes.io/os: linux priorityClassName: system-cluster-critical serviceAccountName: metrics-server volumes: - emptyDir: {} name: tmp-dir --- apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: labels: k8s-app: metrics-server name: v1beta1.metrics.k8s.io spec: group: metrics.k8s.io groupPriorityMinimum: 100 insecureSkipTLSVerify: true service: name: metrics-server namespace: kube-system version: v1beta1 versionPriority: 100
|
安装之后可以使用 kubectl top pod [pod-name]
命令查看当前占用的系统资源情况。
- 限制内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: v1 kind: Pod metadata: name: liveness-tcp labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 imagePuLLPoLicy: IfNotPresent resources: requests: memory: 100M limits: memory: 200M
|
1 2
| kubectl get pod [pod-name] -o yaml
|
- 限制 CPU
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: v1 kind: Pod metadata: name: liveness-tcp labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 imagePuLLPoLicy: IfNotPresent resources: requests: cpu: 10m limits: cpu: 50m
|
- CPU 请求和限制的初衷
通过配置你的集群中运行的容器的ICPU请求和限制,你可以有效利用集群上可用的CPU资源。通过将Pod CPU 请求保持在较低水平,可以使 Pod 更有机会被调度。通过使 CPU 限制大于 CPU 请求,你可以完成两件事:
- Pod 可能会有突发性的活动,它可以利用碰巧可用的 CPU 资源。
- Pod 在突发负载期间可以使用的 CPU 资源数量仍被限制为合理的数量。
- 如果不指定 CPU 限制
如果你没有为容器指定 CPU 限制,则会发生以下情况之一:
- 容器在可以使用的 CPU 资源上没有上限。因而可以使用所在节点上所有的可用 CPU 资源。
- 容器在具有默认 CPU 限制的名称空间中运行,系统会自动为容器设置默认限制。
- 如果你设置了 CPU 限制但未设置 CPU 请求,Kubernetes 会自动为其设置与 CPU 限制相同的 CPU 请求值。类似的,如果容器设置了内存限制值但未设置内存请求值,Kubernetes 也会为其设置与内存限制值相同的内存请求。
Init 容器是一种特殊容器,在 Pod 内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。每个 Pod 中可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
- 它们总是运行到完成。
- 每个都必须在下一个启动之前成功完成。
如果 Pod 的 Init 容器失败,kubelet 会不断地重启该 Init 容器直到该容器成功为止。 然而,如果 Pod 对应的 restartPolicy 值为 “Never”,并且 Pod 的 Init 容器失败, 则 Kubernetes 会将整个 Pod 状态设置为失败。
Init 容器不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe, 因为它们必须在 Pod 就绪之前运行完成。
如果为一个 Pod 指定了多个 Init 容器,这些容器会按顺序逐个运行。 每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时, Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。
Pod 节点 label
作用:根据 label 确定 Pod 运行的节点(yaml 中使用 nodeSelector
)。
1 2 3 4 5 6
| kubectl get nodes
kubectl get nodes --show-labels;
kubectl label node [node-name] [key=value]
|
一般不单独创建 Pod,而是通过 Controller 创建并管理,Controller 也是通过 label 来关联 Pod 并进行管理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| apiVersion: apps/v1
kind: Deployment metadata: name: nginx-deployment labels: app: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
|
deployment 的一些命令和 Pod 类似,把 pod 换为 deployment 即可。这里不再举例。
deployment 伸缩
1 2 3 4
| kubectl get rs|replicaset
kubectl scale deployment [deployment-name] --replicas=num
|
deployment 回滚
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| kubectl rollout status [deployment deployment-name| deployment/deployment-name]
kubectl rollout history deployment [deployment-name]
kubectl rollout history deployment/[deployment-name] --revision=version-num
kubectl rollout undo deployment [deployment-name]
kubectl rollout undo deployment [deployment-name] --to-revision=version-num
kubectl rollout restart deployment [deployment-name]
kubectl rollout pause deployment [deployment-name]
kubectl rollout resume deployment [deployment-name]
|
StatefulSet 和 Deplotment 差不多,但是可以为 Pod 提供持久存储和持久标识符。
删除或这扩缩 StatefulSet 的时候,不会删除的它关联的数据卷,以此保证数据的安全。
不推荐删除 StatefulSet 的 yml。
Kubernetes 中 Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。
Helm 是一个 Kubernetes 的包管理器。
1 2 3 4 5 6 7 8 9 10 11 12
| helm search hub [name]
helm search repo [name]
helm list
helm create [chart-name]
helm lint [chart-name]
helm package path
|