|
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1. Kubernetes与容器编排概述
Kubernetes(简称K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。作为云原生时代的核心基础设施,Kubernetes提供了容器调度、服务发现、负载均衡、自动扩缩容等强大功能。
容器编排技术解决了大规模容器环境下的管理难题,包括:
• 应用部署与生命周期管理
• 资源调度与优化
• 服务发现与负载均衡
• 故障自愈与高可用
• 自动扩缩容
在Kubernetes生态系统中,存在众多管理工具,从基础的命令行工具kubectl到高级的包管理器Helm,它们共同构成了完整的容器编排工具链。
2. kubectl:Kubernetes命令行工具详解
kubectl是Kubernetes最基础也是最重要的命令行工具,通过它可以与Kubernetes集群进行交互。掌握kubectl是使用Kubernetes的第一步。
2.1 kubectl基础命令
- # 查看集群信息
- kubectl cluster-info
- # 查看Kubernetes版本
- kubectl version
- # 查看API资源列表
- kubectl api-resources
- # 查看当前上下文
- kubectl config current-context
复制代码- # 获取所有命名空间的Pod列表
- kubectl get pods --all-namespaces
- # 获取指定命名空间中的部署
- kubectl get deployments -n <namespace>
- # 获取服务详情
- kubectl get svc -o wide
- # 获取节点信息
- kubectl get nodes -o wide
- # 查看资源详细信息
- kubectl describe pod <pod-name> -n <namespace>
复制代码
2.2 资源创建与管理
- # 使用YAML文件创建资源
- kubectl apply -f deployment.yaml
- # 使用命令行直接创建部署
- kubectl create deployment nginx --image=nginx
- # 创建一个命名空间
- kubectl create namespace my-namespace
复制代码- # 更新部署的镜像版本
- kubectl set image deployment/nginx nginx=nginx:1.21.0
- # 使用edit命令直接编辑资源配置
- kubectl edit deployment nginx
- # 通过应用更新的YAML文件更新资源
- kubectl apply -f updated-deployment.yaml
复制代码- # 删除Pod
- kubectl delete pod <pod-name>
- # 删除部署
- kubectl delete deployment <deployment-name>
- # 使用YAML文件删除资源
- kubectl delete -f deployment.yaml
- # 强制删除Pod(当Pod处于Terminating状态时)
- kubectl delete pod <pod-name> --force --grace-period=0
复制代码
2.3 调试与故障排查
- # 查看Pod日志
- kubectl logs <pod-name>
- # 持续查看Pod日志(类似tail -f)
- kubectl logs -f <pod-name>
- # 查看前一个容器的日志(当容器崩溃重启时)
- kubectl logs <pod-name> --previous
- # 在Pod中执行命令
- kubectl exec -it <pod-name> -- /bin/bash
- # 复制文件到Pod中
- kubectl cp /path/to/local/file <pod-name>:/path/to/container/file
- # 复制文件从Pod中
- kubectl cp <pod-name>:/path/to/container/file /path/to/local/file
复制代码- # 查看命名空间中的事件
- kubectl get events -n <namespace>
- # 查看所有命名空间的事件
- kubectl get events --all-namespaces
- # 查看特定资源的事件
- kubectl get events --field-selector involvedObject.name=<pod-name>
- # 检查Pod状态
- kubectl get pods -o wide --watch
复制代码
2.4 kubectl高级技巧
- # 添加标签
- kubectl label pods <pod-name> app=frontend
- # 更新标签
- kubectl label pods <pod-name> app=backend --overwrite
- # 根据标签筛选资源
- kubectl get pods -l app=frontend
- # 添加注解
- kubectl annotate pods <pod-name> description="Frontend application"
复制代码- # 使用JSONPath提取特定信息
- kubectl get pods -o jsonpath='{.items[*].metadata.name}'
- # 获取所有Pod的IP地址
- kubectl get pods -o jsonpath='{.items[*].status.podIP}'
- # 获取所有节点的名称和容量
- kubectl get nodes -o jsonpath='{.items[*].metadata.name} {.items[*].status.capacity}'
复制代码- # 使用自定义列显示信息
- kubectl get pods -o custom-columns=POD:.metadata.name,IMAGE:.spec.containers[0].image,NODE:.spec.nodeName
- # 显示Pod及其所在节点
- kubectl get pods -o custom-columns=POD:.metadata.name,NODE:.spec.nodeName,STATUS:.status.phase
复制代码
2.5 kubectl配置管理
- # 查看当前配置的上下文
- kubectl config get-contexts
- # 切换上下文
- kubectl config use-context <context-name>
- # 添加新的集群配置
- kubectl config set-cluster <cluster-name> --server=<server-url> --certificate-authority=<path-to-ca>
- # 添加用户凭证
- kubectl config set-credentials <user-name> --client-certificate=<path-to-cert> --client-key=<path-to-key>
- # 创建新的上下文
- kubectl config set-context <context-name> --cluster=<cluster-name> --user=<user-name> --namespace=<namespace>
复制代码- # 在.bashrc或.zshrc中添加kubectl别名
- alias k=kubectl
- alias kgp='kubectl get pods'
- alias kgs='kubectl get services'
- alias kd='kubectl describe'
- alias kdel='kubectl delete'
- # 重新加载shell配置
- source ~/.bashrc
复制代码
3. Kubernetes Dashboard:Web界面管理
Kubernetes Dashboard是Kubernetes的官方Web UI,提供了一个可视化的界面来管理和排查Kubernetes集群。
3.1 Dashboard部署
- # 部署Dashboard
- kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml
- # 查看Dashboard部署状态
- kubectl get pods -n kubernetes-dashboard
- # 创建访问Dashboard的ServiceAccount和ClusterRoleBinding
- kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard
- kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin
- # 获取访问Dashboard的Token
- kubectl describe secrets -n kubernetes-dashboard $(kubectl -n kubernetes-dashboard get secret | awk '/dashboard-admin/{print $1}')
复制代码
3.2 Dashboard访问与使用
- # 启动代理访问Dashboard
- kubectl proxy
- # 访问Dashboard URL
- # http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
复制代码
Dashboard主要功能包括:
• 集群资源概览
• 工作负载管理(Deployment、StatefulSet、DaemonSet等)
• 服务与网络管理
• 存储管理
• 配置管理(ConfigMap、Secret)
• 命名空间管理
• 用户与权限管理
3.3 Dashboard替代方案
除了官方Dashboard,还有一些优秀的第三方Web界面工具:
Lens是一个功能强大的Kubernetes IDE,提供了直观的界面和丰富的功能。
- # Lens下载地址
- # https://k8slens.dev/
复制代码
Lens的主要特点:
• 多集群管理
• 实时监控
• 内置终端
• Helm集成
• 可视化编辑器
Octant是VMware开源的Kubernetes开发者工具,专注于提升开发体验。
- # Octant安装
- # macOS
- brew install octant
- # Linux
- wget https://github.com/vmware-tanzu/octant/releases/download/v0.25.1/octant_0.25.1_Linux-64bit.tar.gz
- tar -xvf octant_0.25.1_Linux-64bit.tar.gz
- sudo mv octant_0.25.1_Linux-64bit/octant /usr/local/bin/
复制代码
4. kubectx与kubens:上下文与命名空间切换工具
当管理多个Kubernetes集群或频繁切换命名空间时,kubectx和kubens工具可以大大提高效率。
4.1 kubectx:快速切换集群上下文
- # 安装kubectx
- # macOS
- brew install kubectx
- # Linux
- git clone https://github.com/ahmetb/kubectx.git ~/.kubectx
- COMPDIR=$(pkg-config --variable=completionsdir bash-completion)
- sudo ln -sf ~/.kubectx/completion/kubectx.bash $COMPDIR/kubectx
- sudo ln -sf ~/.kubectx/completion/kubens.bash $COMPDIR/kubens
- echo 'export PATH="$PATH:$HOME/.kubectx"' >> ~/.bashrc
- source ~/.bashrc
- # 查看所有可用上下文
- kubectx
- # 切换到指定上下文
- kubectx <context-name>
- # 切换到上一个上下文
- kubectx -
- # 重命名上下文
- kubectx <current-name>=<new-name>
- # 删除上下文
- kubectx -d <context-name>
复制代码
4.2 kubens:快速切换命名空间
- # 查看当前命名空间
- kubens
- # 查看所有命名空间
- kubens -l
- # 切换到指定命名空间
- kubens <namespace-name>
- # 切换到上一个命名空间
- kubens -
复制代码
4.3 kubectx与kubens集成使用
- # 在.bashrc或.zshrc中设置别名和函数
- # 显示当前上下文和命名空间
- function kcn() {
- echo "Current context: $(kubectl config current-context)"
- echo "Current namespace: $(kubectl config view --minify --output 'jsonpath={..namespace}')"
- }
- # 快速切换上下文和命名空间
- function kswitch() {
- kubectx $1
- kubens $2
- }
- # 重新加载shell配置
- source ~/.bashrc
复制代码
5. Stern:多Pod日志查看工具
Stern是一个强大的多Pod日志查看工具,支持颜色编码和实时更新,特别适合调试微服务应用。
5.1 Stern安装与基础使用
- # 安装Stern
- # macOS
- brew install stern
- # Linux
- wget https://github.com/stern/stern/releases/download/v1.21.0/stern_1.21.0_linux_amd64.tar.gz
- tar -xvf stern_1.21.0_linux_amd64.tar.gz
- sudo mv stern /usr/local/bin/
- # 查看所有Pod的日志
- stern .
- # 查看特定命名空间中的所有Pod日志
- stern . -n <namespace>
- # 查看特定标签的Pod日志
- stern -l app=frontend
- # 查看特定Pod的日志
- stern <pod-name-prefix>
- # 查看多个Pod的日志(使用正则表达式)
- stern "frontend-.*|backend-.*"
复制代码
5.2 Stern高级功能
- # 显示时间戳
- stern . --timestamps
- # 显示容器名称
- stern . --container
- # 自定义输出格式
- stern . --template "{{.PodName}} {{.ContainerName}} {{.Message}}\n"
- # 排除某些容器
- stern . --exclude-container istio-proxy
- # 设置日志显示行数
- stern . --tail 50
- # 设置日志显示时间范围
- stern . --since 1h
复制代码
6. Helm:Kubernetes包管理器
Helm是Kubernetes的包管理器,被称为”Kubernetes的apt/yum”,它简化了Kubernetes应用的部署和管理。
6.1 Helm基础概念
• Chart: Helm的包格式,包含了一组定义Kubernetes资源的文件
• Release: Chart在Kubernetes集群中的实例化
• Repository: 用于存储和共享Chart的集合
6.2 Helm安装与配置
- # 安装Helm
- # macOS
- brew install helm
- # Linux
- curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] 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
- # 验证Helm安装
- helm version
- # 添加官方仓库
- helm repo add stable https://charts.helm.sh/stable
- helm repo add bitnami https://charts.bitnami.com/bitnami
- # 更新仓库索引
- helm repo update
- # 列出所有已添加的仓库
- helm repo list
复制代码
6.3 Helm基础命令
- # 搜索Chart
- helm search repo nginx
- # 查看Chart详细信息
- helm show chart bitnami/nginx
- # 安装Chart
- helm install my-nginx bitnami/nginx
- # 安装特定版本的Chart
- helm install my-nginx bitnami/nginx --version 13.2.0
- # 使用自定义配置安装Chart
- helm install my-nginx bitnami/nginx -f values.yaml
- # 安装到指定命名空间
- helm install my-nginx bitnami/nginx --namespace my-namespace --create-namespace
复制代码- # 列出所有Release
- helm list
- # 列出所有命名空间的Release
- helm list --all-namespaces
- # 查看Release状态
- helm status my-nginx
- # 升级Release
- helm upgrade my-nginx bitnami/nginx
- # 回滚Release到上一个版本
- helm rollback my-nginx
- # 回滚到指定版本
- helm rollback my-nginx 1
- # 卸载Release
- helm uninstall my-nginx
复制代码- # 拉取Chart到本地
- helm pull bitnami/nginx
- # 拉取并解压Chart
- helm pull bitnami/nginx --untar
- # 查看Chart的values
- helm show values bitnami/nginx
- # 将values保存到文件
- helm show values bitnami/nginx > values.yaml
- # 打包Chart
- helm package ./nginx-chart
- # 验证Chart
- helm lint ./nginx-chart
复制代码
6.4 创建自定义Chart
- # 创建新Chart
- helm create my-chart
- # Chart目录结构
- my-chart/
- ├── charts/ # 依赖的Chart
- ├── Chart.yaml # Chart元数据
- ├── templates/ # Kubernetes资源模板
- │ ├── deployment.yaml
- │ ├── _helpers.tpl
- │ ├── hpa.yaml
- │ ├── ingress.yaml
- │ ├── NOTES.txt
- │ ├── serviceaccount.yaml
- │ ├── service.yaml
- │ └── tests/
- └── values.yaml # 默认配置值
复制代码
templates/deployment.yaml:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: {{ include "my-chart.fullname" . }}
- labels:
- {{- include "my-chart.labels" . | nindent 4 }}
- spec:
- replicas: {{ .Values.replicaCount }}
- selector:
- matchLabels:
- {{- include "my-chart.selectorLabels" . | nindent 6 }}
- template:
- metadata:
- labels:
- {{- include "my-chart.selectorLabels" . | nindent 8 }}
- spec:
- containers:
- - name: {{ .Chart.Name }}
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
- imagePullPolicy: {{ .Values.image.pullPolicy }}
- ports:
- - name: http
- containerPort: 80
- protocol: TCP
- livenessProbe:
- httpGet:
- path: /
- port: http
- readinessProbe:
- httpGet:
- path: /
- port: http
- resources:
- {{- toYaml .Values.resources | nindent 12 }}
复制代码
values.yaml:
- replicaCount: 1
- image:
- repository: nginx
- pullPolicy: IfNotPresent
- tag: ""
- service:
- type: ClusterIP
- port: 80
- ingress:
- enabled: false
- className: ""
- annotations: {}
- hosts:
- - host: chart-example.local
- paths:
- - path: /
- pathType: ImplementationSpecific
- resources:
- limits:
- cpu: 100m
- memory: 128Mi
- requests:
- cpu: 100m
- memory: 128Mi
- autoscaling:
- enabled: false
- minReplicas: 1
- maxReplicas: 100
- targetCPUUtilizationPercentage: 80
复制代码
6.5 Helm高级功能
- # 条件示例
- {{- if .Values.ingress.enabled -}}
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: {{ include "my-chart.fullname" . }}
- annotations:
- {{- toYaml .Values.ingress.annotations | nindent 4 }}
- spec:
- rules:
- {{- range .Values.ingress.hosts }}
- - host: {{ .host | quote }}
- http:
- paths:
- {{- range .paths }}
- - path: {{ .path }}
- pathType: {{ .pathType }}
- backend:
- service:
- name: {{ include "my-chart.fullname" $ }}
- port:
- name: http
- {{- end }}
- {{- end }}
- {{- end }}
复制代码
templates/_helpers.tpl:
- {{/*
- Expand the name of the chart.
- */}}
- {{- define "my-chart.name" -}}
- {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
- {{- end }}
- {{/*
- Create a default fully qualified app name.
- We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
- If release name contains chart name it will be used as a full name.
- */}}
- {{- define "my-chart.fullname" -}}
- {{- if .Values.fullnameOverride }}
- {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
- {{- else }}
- {{- $name := default .Chart.Name .Values.nameOverride }}
- {{- if contains $name .Release.Name }}
- {{- .Release.Name | trunc 63 | trimSuffix "-" }}
- {{- else }}
- {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
- {{- end }}
- {{- end }}
- {{- end }}
- {{/*
- Create chart name and version as used by the chart label.
- */}}
- {{- define "my-chart.chart" -}}
- {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
- {{- end }}
- {{/*
- Common labels
- */}}
- {{- define "my-chart.labels" -}}
- helm.sh/chart: {{ include "my-chart.chart" . }}
- {{ include "my-chart.selectorLabels" . }}
- {{- if .Chart.AppVersion }}
- app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
- {{- end }}
- app.kubernetes.io/managed-by: {{ .Release.Service }}
- {{- end }}
- {{/*
- Selector labels
- */}}
- {{- define "my-chart.selectorLabels" -}}
- app.kubernetes.io/name: {{ include "my-chart.name" . }}
- app.kubernetes.io/instance: {{ .Release.Name }}
- {{- end }}
复制代码- # Chart.yaml中的依赖定义
- dependencies:
- - name: redis
- version: "16.5.5"
- repository: "https://charts.bitnami.com/bitnami"
- condition: redis.enabled
- tags:
- - database
- - name: postgresql
- version: "11.6.12"
- repository: "https://charts.bitnami.com/bitnami"
- condition: postgresql.enabled
- tags:
- - database
复制代码- # templates/tests/test-connection.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: "{{ include "my-chart.fullname" . }}-test-connection"
- labels:
- {{- include "my-chart.labels" . | nindent 4 }}
- annotations:
- "helm.sh/hook": test
- spec:
- containers:
- - name: wget
- image: busybox
- command: ['wget']
- args: ['{{ include "my-chart.fullname" . }}:{{ .Values.service.port }}']
- restartPolicy: Never
复制代码
运行测试:
6.6 Helm仓库管理
- # 创建本地仓库
- helm repo index my-repo/ --url https://my-repo.example.com
- # 添加私有仓库
- helm repo add my-repo https://my-repo.example.com
- # 使用ChartMuseum创建私有仓库
- # 安装ChartMuseum
- docker run --rm -it -p 8080:8080 -v $(pwd)/charts:/charts chartmuseum/chartmuseum --storage-local-rootdir=/charts
- # 上传Chart到私有仓库
- curl --data-binary "@my-chart-0.1.0.tgz" http://localhost:8080/api/charts
复制代码
7. Kustomize:无模板的Kubernetes配置管理
Kustomize是Kubernetes原生的配置管理工具,它允许用户通过声明式的方式对YAML文件进行定制,而不需要使用模板。
7.1 Kustomize基础概念
• Base: 包含基本资源配置的目录
• Overlay: 基于Base进行环境特定定制的目录
• Kustomization.yaml: 定义如何定制资源的文件
7.2 Kustomize使用示例
base/kustomization.yaml:
- apiVersion: kustomize.config.k8s.io/v1beta1
- kind: Kustomization
- resources:
- - deployment.yaml
- - service.yaml
- commonLabels:
- app: my-app
复制代码
base/deployment.yaml:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: my-app
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: my-app
- template:
- metadata:
- labels:
- app: my-app
- spec:
- containers:
- - name: my-app
- image: my-app:1.0.0
- ports:
- - containerPort: 8080
复制代码
base/service.yaml:
- apiVersion: v1
- kind: Service
- metadata:
- name: my-app-service
- spec:
- selector:
- app: my-app
- ports:
- - protocol: TCP
- port: 80
- targetPort: 8080
复制代码
overlays/production/kustomization.yaml:
- apiVersion: kustomize.config.k8s.io/v1beta1
- kind: Kustomization
- bases:
- - ../../base
- images:
- - name: my-app
- newName: my-app
- newTag: 1.2.0
- replicas:
- - name: my-app
- count: 3
- patchesStrategicMerge:
- - replica-patch.yaml
复制代码
overlays/production/replica-patch.yaml:
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: my-app
- spec:
- template:
- spec:
- containers:
- - name: my-app
- resources:
- limits:
- cpu: 500m
- memory: 512Mi
- requests:
- cpu: 250m
- memory: 256Mi
复制代码
7.3 Kustomize命令使用
- # 查看生成的资源
- kustomize build overlays/production
- # 应用Kustomize配置
- kustomize build overlays/production | kubectl apply -f -
- # 查看差异
- kustomize build overlays/production | kubectl diff -f -
- # 删除资源
- kustomize build overlays/production | kubectl delete -f -
复制代码
7.4 Kustomize高级功能
overlays/production/kustomization.yaml:
- apiVersion: kustomize.config.k8s.io/v1beta1
- kind: Kustomization
- bases:
- - ../../base
- configMapGenerator:
- - name: app-config
- files:
- - config.properties
- literals:
- - ENV=production
- - LOG_LEVEL=info
- secretGenerator:
- - name: db-secret
- literals:
- - username=admin
- - password=secret123
复制代码
overlays/production/kustomization.yaml:
- apiVersion: kustomize.config.k8s.io/v1beta1
- kind: Kustomization
- bases:
- - ../../base
- patchesJson6902:
- - target:
- group: apps
- version: v1
- kind: Deployment
- name: my-app
- path: patch.yaml
复制代码
overlays/production/patch.yaml:
- - op: add
- path: /spec/template/spec/containers/0/env/-
- value:
- name: JAVA_OPTS
- value: "-Xmx512m"
复制代码
8. Operator:自动化Kubernetes应用管理
Operator是Kubernetes的一种扩展模式,它将运维知识编码到软件中,实现复杂应用的自动化管理。
8.1 Operator基础概念
• Custom Resource (CR): Kubernetes API的扩展,定义特定应用的配置
• Custom Resource Definition (CRD): 定义Custom Resource的结构
• Operator Controller: 监控CR状态并确保实际状态与期望状态一致
8.2 Operator开发工具
- # 安装Operator SDK
- # macOS
- brew install operator-sdk
- # Linux
- curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.22.0/operator-sdk_linux_amd64
- chmod +x operator-sdk_linux_amd64
- sudo mv operator-sdk_linux_amd64 /usr/local/bin/operator-sdk
- # 创建新Operator项目
- operator-sdk init --domain example.com --repo github.com/example/my-operator
- # 创建API和Controller
- operator-sdk create api --group app --version v1alpha1 --kind MyApp
复制代码- # 安装KubeBuilder
- # macOS
- brew install kubebuilder
- # Linux
- os=$(go env GOOS)
- arch=$(go env GOARCH)
- curl -L https://go.kubebuilder.io/dl/2.3.1/${os}/${arch} | tar -xz -C /tmp/
- sudo mv /tmp/kubebuilder_${os}_${arch} /usr/local/kubebuilder
- export PATH=$PATH:/usr/local/kubebuilder/bin
- # 创建新项目
- kubebuilder init --domain example.com --repo github.com/example/my-operator
- # 创建API
- kubebuilder create api --group app --version v1alpha1 --kind MyApp
复制代码
8.3 Operator示例
config/crd/bases/app.example.com_myapps.yaml:
- apiVersion: apiextensions.k8s.io/v1
- kind: CustomResourceDefinition
- metadata:
- name: myapps.app.example.com
- spec:
- group: app.example.com
- names:
- kind: MyApp
- listKind: MyAppList
- plural: myapps
- singular: myapp
- scope: Namespaced
- versions:
- - name: v1alpha1
- schema:
- openAPIV3Schema:
- properties:
- spec:
- properties:
- replicas:
- type: integer
- image:
- type: string
- port:
- type: integer
- type: object
- status:
- properties:
- availableReplicas:
- type: integer
- conditions:
- items:
- properties:
- lastTransitionTime:
- type: string
- message:
- type: string
- reason:
- type: string
- status:
- type: string
- type:
- type: string
- type: object
- type: array
- type: object
- type: object
- served: true
- storage: true
复制代码
controllers/myapp_controller.go:
- package controllers
- import (
- "context"
- "fmt"
- "time"
- appv1alpha1 "github.com/example/my-operator/api/v1alpha1"
- appsv1 "k8s.io/api/apps/v1"
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/runtime"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/reconcile"
- )
- // MyAppReconciler reconciles a MyApp object
- type MyAppReconciler struct {
- client.Client
- Scheme *runtime.Scheme
- }
- // +kubebuilder:rbac:groups=app.example.com,resources=myapps,verbs=get;list;watch;create;update;patch;delete
- // +kubebuilder:rbac:groups=app.example.com,resources=myapps/status,verbs=get;update;patch
- // +kubebuilder:rbac:groups=app.example.com,resources=myapps/finalizers,verbs=update
- // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
- // +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch
- func (r *MyAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- log := ctrl.Log.WithValues("myapp", req.NamespacedName)
- // 获取MyApp实例
- myApp := &appv1alpha1.MyApp{}
- if err := r.Get(ctx, req.NamespacedName, myApp); err != nil {
- if errors.IsNotFound(err) {
- log.Info("MyApp resource not found. Ignoring since object must be deleted")
- return ctrl.Result{}, nil
- }
- log.Error(err, "Failed to get MyApp")
- return ctrl.Result{}, err
- }
- // 检查是否已存在Deployment
- found := &appsv1.Deployment{}
- err := r.Get(ctx, client.ObjectKey{Name: myApp.Name, Namespace: myApp.Namespace}, found)
- if err != nil && errors.IsNotFound(err) {
- // 创建新的Deployment
- dep := r.deploymentForMyApp(myApp)
- log.Info("Creating a new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
- err = r.Create(ctx, dep)
- if err != nil {
- log.Error(err, "Failed to create new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
- return ctrl.Result{}, err
- }
- // 创建成功,重新排队
- return ctrl.Result{Requeue: true}, nil
- } else if err != nil {
- log.Error(err, "Failed to get Deployment")
- return ctrl.Result{}, err
- }
- // 更新状态
- if err := r.updateMyAppStatus(myApp, found); err != nil {
- log.Error(err, "Failed to update MyApp status")
- return ctrl.Result{}, err
- }
- return ctrl.Result{RequeueAfter: time.Minute}, nil
- }
- func (r *MyAppReconciler) deploymentForMyApp(m *appv1alpha1.MyApp) *appsv1.Deployment {
- labels := map[string]string{"app": m.Name}
- replicas := m.Spec.Replicas
- dep := &appsv1.Deployment{
- ObjectMeta: metav1.ObjectMeta{
- Name: m.Name,
- Namespace: m.Namespace,
- },
- Spec: appsv1.DeploymentSpec{
- Replicas: &replicas,
- Selector: &metav1.LabelSelector{
- MatchLabels: labels,
- },
- Template: corev1.PodTemplateSpec{
- ObjectMeta: metav1.ObjectMeta{
- Labels: labels,
- },
- Spec: corev1.PodSpec{
- Containers: []corev1.Container{{
- Image: m.Spec.Image,
- Name: m.Name,
- Ports: []corev1.ContainerPort{{
- ContainerPort: m.Spec.Port,
- Name: "http",
- }},
- }},
- },
- },
- },
- }
- // 设置MyApp实例作为Deployment的所有者
- ctrl.SetControllerReference(m, dep, r.Scheme)
- return dep
- }
- func (r *MyAppReconciler) updateMyAppStatus(myApp *appv1alpha1.MyApp, deployment *appsv1.Deployment) error {
- myApp.Status.AvailableReplicas = deployment.Status.AvailableReplicas
- return r.Status().Update(context.TODO(), myApp)
- }
- func (r *MyAppReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return ctrl.NewControllerManagedBy(mgr).
- For(&appv1alpha1.MyApp{}).
- Owns(&appsv1.Deployment{}).
- Complete(r)
- }
复制代码
config/samples/app_v1alpha1_myapp.yaml:
- apiVersion: app.example.com/v1alpha1
- kind: MyApp
- metadata:
- name: myapp-sample
- spec:
- replicas: 3
- image: nginx:1.21.0
- port: 80
复制代码
应用CR:
- kubectl apply -f config/samples/app_v1alpha1_myapp.yaml
复制代码
9. 其他实用工具
9.1 k9s:Kubernetes CLI管理器
k9s是一个终端UI,用于与Kubernetes集群交互,提供了直观的界面来管理资源。
- # 安装k9s
- # macOS
- brew install k9s
- # Linux
- wget https://github.com/derailed/k9s/releases/download/v0.25.18/k9s_Linux_x86_64.tar.gz
- tar -xvf k9s_Linux_x86_64.tar.gz
- sudo mv k9s /usr/local/bin/
- # 启动k9s
- k9s
- # 启动k9s并指定命名空间
- k9s -n <namespace>
复制代码
k9s的主要功能:
• 资源浏览和管理
• 日志查看
• 端口转发
• 进入容器
• 删除资源
• 描述资源
• YAML编辑
9.2 kubectl-neat:清理YAML输出
kubectl-neat是一个工具,用于移除kubectl输出中的系统生成字段,使YAML更易读。
- # 安装kubectl-neat
- # macOS
- brew install derailed/k9s/kubectl-neat
- # Linux
- go install github.com/itaysk/kubectl-neat/cmd/kubectl-neat@latest
- # 使用kubectl-neat
- kubectl get pod my-pod -o yaml | kubectl-neat
- # 创建kubectl别名
- alias k neat='kubectl get -o yaml | kubectl-neat'
复制代码
9.3 kubescape:Kubernetes安全扫描工具
kubescape是一个开源的Kubernetes安全扫描工具,用于检测集群和配置中的安全问题。
- # 安装kubescape
- # macOS
- brew install kubescape
- # Linux
- curl -s https://raw.githubusercontent.com/armosec/kubescape/master/install.sh | /bin/bash
- # 扫描集群
- kubescape scan
- # 扫描特定命名空间
- kubescape scan namespace <namespace>
- # 扫描YAML文件
- kubescape scan *.yaml
- # 生成HTML报告
- kubescape scan --format html --output results.html
复制代码
9.4 popeye:Kubernetes集群资源分析器
popeye是一个工具,用于扫描Kubernetes集群中的资源并报告潜在问题和配置错误。
- # 安装popeye
- # macOS
- brew install derailed/popeye/popeye
- # Linux
- wget https://github.com/derailed/popeye/releases/download/v0.10.1/popeye_Linux_x86_64.tar.gz
- tar -xvf popeye_Linux_x86_64.tar.gz
- sudo mv popeye /usr/local/bin/
- # 扫描集群
- popeye
- # 扫描特定命名空间
- popeye -n <namespace>
- # 生成HTML报告
- popeye -o html --save popeye-report.html
复制代码
10. 工具选择与最佳实践
10.1 工具选择指南
根据不同的使用场景和需求,可以选择不同的工具组合:
• kubectl: 基础命令行操作
• kubectx/kubens: 多集群和命名空间管理
• stern: 多Pod日志查看
• k9s: 终端UI管理
• Helm: 复杂应用打包和部署
• Kustomize: 环境特定配置管理
• Operator: 复杂有状态应用自动化管理
• Kubernetes Dashboard/Lens: Web界面管理
• kubectl-neat: 清理YAML输出
• kubescape/popeye: 安全和配置检查
10.2 最佳实践
- # 在.bashrc或.zshrc中设置常用别名和函数
- # kubectl别名
- alias k=kubectl
- alias kgp='kubectl get pods'
- alias kgs='kubectl get services'
- alias kd='kubectl describe'
- alias kdel='kubectl delete'
- alias kaf='kubectl apply -f'
- alias kex='kubectl exec -it'
- alias klo='kubectl logs -f'
- # kubectx和kubens别名
- alias kctx='kubectx'
- alias kns='kubens'
- # 常用函数
- function kpod() {
- kubectl get pods --all-namespaces -o wide | grep $1
- }
- function kdesc() {
- kubectl describe pod $1
- }
- function klogs() {
- kubectl logs -f $1
- }
- # 重新加载shell配置
- source ~/.bashrc
复制代码
1. 版本控制: 将所有Kubernetes配置文件存储在Git仓库中
2. 环境分离: 使用不同的命名空间或集群隔离开发、测试和生产环境
3. 声明式管理: 优先使用apply命令而非create命令
4. 标签和注解: 为资源添加有意义的标签和注解,便于管理和查询
1. 最小权限原则: 使用RBAC限制用户和服务账户的权限
2. 网络策略: 实施NetworkPolicy控制Pod间通信
3. 安全扫描: 定期使用kubescape等工具扫描集群安全
4. 密钥管理: 使用Secret管理敏感信息,考虑集成外部密钥管理系统
1. 集中式日志: 使用EFK(Elasticsearch, Fluentd, Kibana)或PLG(Promtail, Loki, Grafana)栈收集日志
2. 指标监控: 使用Prometheus和Grafana监控集群和应用指标
3. 告警设置: 配置Alertmanager设置告警规则
4. 健康检查: 为应用配置适当的liveness和readiness探针
11. 实际应用场景
11.1 微服务部署场景
假设我们需要部署一个包含前端、后端和数据库的微服务应用:
- # 创建自定义Chart
- helm create microservice-app
- # 修改values.yaml
- cat > values.yaml <<EOF
- global:
- imagePullSecrets: []
- imageRegistry: ""
- frontend:
- replicaCount: 2
- image:
- repository: my-frontend
- tag: "1.0.0"
- pullPolicy: IfNotPresent
- service:
- type: ClusterIP
- port: 80
- ingress:
- enabled: true
- className: "nginx"
- hosts:
- - host: app.example.com
- paths:
- - path: /
- pathType: Prefix
- backend:
- replicaCount: 2
- image:
- repository: my-backend
- tag: "1.0.0"
- pullPolicy: IfNotPresent
- service:
- type: ClusterIP
- port: 8080
- database:
- enabled: true
- image:
- repository: postgres
- tag: "13"
- pullPolicy: IfNotPresent
- persistence:
- enabled: true
- size: 10Gi
- service:
- type: ClusterIP
- port: 5432
- EOF
- # 部署应用
- helm install my-app ./microservice-app
- # 检查部署状态
- helm status my-app
复制代码- # 创建基础配置
- mkdir -p base
- cat > base/kustomization.yaml <<EOF
- apiVersion: kustomize.config.k8s.io/v1beta1
- kind: Kustomization
- resources:
- - frontend-deployment.yaml
- - frontend-service.yaml
- - backend-deployment.yaml
- - backend-service.yaml
- - database-deployment.yaml
- - database-service.yaml
- commonLabels:
- app: microservice-app
- EOF
- # 创建生产环境覆盖
- mkdir -p overlays/production
- cat > overlays/production/kustomization.yaml <<EOF
- apiVersion: kustomize.config.k8s.io/v1beta1
- kind: Kustomization
- bases:
- - ../../base
- images:
- - name: my-frontend
- newName: my-frontend
- newTag: 1.0.0
- - name: my-backend
- newName: my-backend
- newTag: 1.0.0
- patchesStrategicMerge:
- - production-replicas.yaml
- - production-resources.yaml
- EOF
- # 应用生产环境配置
- kustomize build overlays/production | kubectl apply -f -
复制代码
11.2 CI/CD集成场景
在CI/CD流水线中集成Kubernetes管理工具:
- name: Deploy to Kubernetes
- on:
- push:
- branches: [ main ]
- jobs:
- build-and-deploy:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v1
-
- - name: Login to DockerHub
- uses: docker/login-action@v1
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Build and push frontend
- uses: docker/build-push-action@v2
- with:
- context: ./frontend
- push: true
- tags: my-frontend:latest
-
- - name: Build and push backend
- uses: docker/build-push-action@v2
- with:
- context: ./backend
- push: true
- tags: my-backend:latest
-
- - name: Set up Kustomize
- uses: imjasonh/setup-kustomize@v1
-
- - name: Deploy to Kubernetes
- run: |
- mkdir -p $HOME/.kube
- echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > $HOME/.kube/config
- kustomize build overlays/production | kubectl apply -f -
复制代码- pipeline {
- agent any
-
- environment {
- DOCKER_REGISTRY = 'my-registry.example.com'
- KUBECONFIG_CREDENTIALS = credentials('kubeconfig')
- }
-
- stages {
- stage('Checkout') {
- steps {
- checkout scm
- }
- }
-
- stage('Build Frontend') {
- steps {
- script {
- docker.build("frontend", "./frontend")
- docker.image("frontend").push("${env.BUILD_ID}")
- }
- }
- }
-
- stage('Build Backend') {
- steps {
- script {
- docker.build("backend", "./backend")
- docker.image("backend").push("${env.BUILD_ID}")
- }
- }
- }
-
- stage('Deploy to Kubernetes') {
- steps {
- script {
- sh """
- mkdir -p ~/.kube
- echo "$KUBECONFIG_CREDENTIALS" > ~/.kube/config
- sed -i "s/FRONTEND_TAG/${env.BUILD_ID}/g" overlays/production/kustomization.yaml
- sed -i "s/BACKEND_TAG/${env.BUILD_ID}/g" overlays/production/kustomization.yaml
- kustomize build overlays/production | kubectl apply -f -
- """
- }
- }
- }
- }
- }
复制代码
11.3 灾难恢复场景
使用Kubernetes管理工具进行灾难恢复:
- # 使用Velero进行集群备份
- # 安装Velero
- velero install --provider aws --bucket velero-backups --secret-file ./credentials-velero --plugins velero/velero-plugin-for-aws:v1.2.0
- # 创建备份
- velero backup create my-backup --include-namespaces my-namespace
- # 列出备份
- velero backup get
- # 从备份恢复
- velero restore create --from-backup my-backup
- # 按计划备份
- velero schedule create my-schedule --schedule="0 1 * * *" --include-namespaces my-namespace
复制代码- # 使用Helm备份已安装的Release
- helm get all my-release > my-release-backup.yaml
- # 使用kubectl备份资源
- kubectl get all,configmap,secret -n my-namespace -o yaml > my-namespace-backup.yaml
- # 恢复应用
- kubectl apply -f my-namespace-backup.yaml
复制代码
12. 总结与展望
Kubernetes集群管理工具生态系统丰富多样,从基础的kubectl到高级的Helm和Operator,每种工具都有其特定的使用场景和优势。掌握这些工具并了解如何组合使用它们,对于高效管理Kubernetes集群至关重要。
12.1 工具选择建议
1. 初学者: 从kubectl和Kubernetes Dashboard开始,逐步学习其他工具
2. 开发人员: 使用Helm或Kustomize管理应用配置,结合kubectl进行调试
3. 运维人员: 熟练使用kubectl、kubectx/kubens、stern等工具,掌握Helm和Operator
4. 平台工程师: 深入理解Operator开发,构建自定义自动化解决方案
12.2 未来趋势
1. GitOps: 以Git作为单一事实来源,使用Argo CD或Flux等工具实现自动化部署
2. 服务网格: Istio、Linkerd等服务网格工具与Kubernetes的深度集成
3. Serverless: Knative等Serverless框架在Kubernetes上的应用
4. 多集群管理: 工具如Rancher、OpenShift等简化多集群管理
5. AI/ML集成: Kubernetes与机器学习工作负载的更好结合
12.3 持续学习资源
1. 官方文档: Kubernetes、Helm、Operator Framework等官方文档
2. 社区资源: CNCF、Kubernetes社区、GitHub上的开源项目
3. 在线课程: Kubernetes认证课程(CKA、CKAD、CKS)
4. 实践项目: 在个人项目中应用所学工具和技术
通过系统学习和实践,您可以全面掌握Kubernetes集群管理工具,从kubectl到Helm,真正掌握容器编排的核心技术,为云原生应用的开发和运维提供强大支持。 |
|