Kubernets 核心概念

Pods

官方文档

Pod 是 k8s 抽象出来的,表示一组一个或多个应用程序容器。以及这些容器的一些共享资源。

  • 共享存储,当做卷
  • 网络,唯一的集群 IP 地址
  • 有关每个容器如何运行的信息

img

工作节点

一个 Pod 总是运行在工作节点,工作节点是 k8s 中的参与计算的机器。

每个 k8s 工作节点至少运行:

  • kubelet,负责 k8s 主节点和工作节点之间通信的过程,它管理 Pod 和机器上运行的容器
  • 容器运行时 (如 docker) 负责从仓库中提取容器镜像,解压容器和运行应用程序

img

  • 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
kubectl proxy
1
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/

查看日志

1
kubectl logs $POD_NAME

一旦 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

image-20220320124356690

Deployment

官方文档

一个 DeploymentPodsReplicaSets 提供声明式的更新能力。

常用命令

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

通过配置文件来创建或修改名字空间

image-20220320125952509

通过 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

在配置文件编写标签

image-20220320130936982

设置端口

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"] 对应

image-20220320142938781

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
APP_COLOR=darkblue
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-az1e2e-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

参考

本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy