Kubernetes教程FG097-Kubernetes控制器原理与实现
目录大纲
内容简介:本文深度解析Kubernetes控制器的工作原理与实现机制,包括控制器的核心概念、工作流程、常见类型以及生产环境中的控制器配置与优化策略。风哥教程参考Kubernetes官方文档控制器部分内容。
Part01-基础概念与理论知识
1.1 Kubernetes控制器概述
1.2 控制器工作原理
控制器的工作原理包括以下步骤:
- 监控:通过API服务器监控资源对象的状态。
- 比较:比较实际状态与期望状态的差异。
- 调整:采取行动调整集群状态,使实际状态接近期望状态。
- 循环:不断重复上述过程,确保集群状态持续符合期望。
1.3 常见控制器类型
Kubernetes常见的控制器类型包括:
- Deployment:管理无状态应用的部署和更新。
- StatefulSet:管理有状态应用的部署和更新。
- DaemonSet:确保所有或部分节点上运行一个Pod副本。
- Job:管理一次性任务的执行。
- CronJob:管理定时任务的执行。
- ReplicaSet:确保指定数量的Pod副本运行。
- ReplicationController:ReplicaSet的前身,功能类似。
- HorizontalPodAutoscaler:根据资源使用情况自动调整Pod数量。
Part02-生产环境规划与建议
2.1 控制器选择考虑因素
在生产环境中选择控制器时,需要考虑以下因素:
- 应用类型:无状态应用选择Deployment,有状态应用选择StatefulSet。
- 部署规模:根据应用的规模选择合适的控制器。
- 更新策略:根据应用的特性选择合适的更新策略。
- 资源需求:考虑控制器对集群资源的占用。
- 可靠性要求:根据应用的可靠性要求选择合适的控制器。
2.2 控制器配置最佳实践
控制器配置的最佳实践:
- 合理设置副本数:根据应用的负载和可靠性要求设置合适的副本数。
- 选择合适的更新策略:根据应用的特性选择滚动更新、蓝绿部署或金丝雀发布。
- 配置健康检查:为Pod配置合适的存活探针和就绪探针。
- 设置资源限制:为Pod设置合理的资源请求和限制。
- 使用标签和注释:合理使用标签和注释,便于管理和监控。
2.3 控制器拓扑设计
生产环境中常见的控制器拓扑设计包括:
- 单集群部署:所有控制器部署在同一个集群中,适用于小型应用。
- 多集群部署:控制器部署在多个集群中,提高可用性。
- 混合部署:核心控制器部署在主集群,非核心控制器部署在其他集群。
Part03-生产环境项目实施方案
3.1 控制器部署与配置
控制器的部署与配置:
[root@fgedu-master1 ~]# cat > deployment.yaml << EOF apiVersion: apps/v1 kind: Deployment metadata: name: fgedu-app namespace: fgedu-production spec: replicas: 3 selector: matchLabels: app: fgedu-app strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata:,风哥提示:。 labels: app: fgedu-app spec: containers: - name: fgedu-app image: nginx:latest ports: - containerPort: 80 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 5 EOF [root@fgedu-master1 ~]# kubectl apply -f deployment.yaml # StatefulSet控制器配置 [root@fgedu-master1 ~]# cat > statefulset.yaml << EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: fgedu-db namespace: fgedu-production spec: serviceName: "fgedu-db" replicas: 3 selector: matchLabels: app: fgedu-db template: metadata: labels: app: fgedu-db spec: containers: - name: fgedu-db image: mysql:8.0 ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "fgedu123" volumeMounts: - name: data mountPath: /var/lib/mysql volumeClaimTemplates: - metadata: name: data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 10Gi EOF [root@fgedu-master1 ~]# kubectl apply -f statefulset.yaml
3.2 控制器自定义与扩展
控制器的自定义与扩展:
[root@fgedu-master1 ~]# mkdir -p $GOPATH/src/github.com/fgedu/custom-controller
[root@fgedu-master1 ~]# cd $GOPATH/src/github.com/fgedu/custom-controller
[root@fgedu-master1 custom-controller]# kubebuilder init –domain fgedu.com
[root@fgedu-master1 custom-controller]# kubebuilder create api –group apps –version v1 –kind CustomApp
# 查看生成的控制器代码
[root@fgedu-master1 custom-controller]# ls -la controllers/
-rw-r–r– 1 root root 2048 Oct 1 10:00 customapp_controller.go,学习交流加群风哥微信: itpux-com。
# 构建和部署自定义控制器
[root@fgedu-master1 custom-controller]# make build
[root@fgedu-master1 custom-controller]# make deploy
# 验证自定义控制器部署
[root@fgedu-master1 custom-controller]# kubectl get pods -n custom-controller-system
NAME READY STATUS RESTARTS AGE
custom-controller-controller-manager-6b8b945955-5k9x8 2/2 Running 0 5m
3.3 控制器性能优化
控制器性能优化包括以下方面,风哥提示:。
[root@fgedu-master1 ~]# kubectl patch deployment deployment-controller -n kube-system –patch ‘{
“spec”: {
“template”: {
“spec”: {
“containers”: [
{
“name”: “deployment-controller”,
“args”: [
“–concurrent-deployment-syncs=10”
]
}
]
}
}
}
}’
# 调整控制器缓存大小
[root@fgedu-master1 ~]# kubectl patch deployment deployment-controller -n kube-system –patch ‘{
“spec”: {
“template”: {
“spec”: {
“containers”: [
{
“name”: “deployment-controller”,
“args”: [
“–deployment-cache-size=1000”
]
}
]
}
}
}
}’
# 优化控制器资源配置
[root@fgedu-master1 ~]# kubectl patch deployment deployment-controller -n kube-system –patch ‘{
“spec”: {
“template”: {
“spec”: {
“containers”: [
{
“name”: “deployment-controller”,
“resources”: {
“requests”: {
“cpu”: “100m”,
“memory”: “128Mi”
},
“limits”: {
“cpu”: “200m”,
“memory”: “256Mi”
}
}
}
]
}
}
}
}’
Part04-生产案例与实战讲解
4.1 Deployment控制器实战
Deployment控制器实战。
[root@fgedu-master1 ~]# kubectl apply -f deployment.yaml
# 查看Deployment状态,学习交流加群风哥QQ113257174。
[root@fgedu-master1 ~]# kubectl get deployment fgedu-app -n fgedu-production
NAME READY UP-TO-DATE AVAILABLE AGE
fgedu-app 3/3 3 3 5m
# 查看Pod状态
[root@fgedu-master1 ~]# kubectl get pods -n fgedu-production | grep fgedu-app
fgedu-app-6b8b945955-5k9x8 1/1 Running 0 5m
fgedu-app-6b8b945955-7q6x5 1/1 Running 0 5m
fgedu-app-6b8b945955-9r2t3 1/1 Running 0 5m
# 滚动更新应用
[root@fgedu-master1 ~]# kubectl set image deployment fgedu-app -n fgedu-production fgedu-app=nginx:1.21
# 查看更新状态
[root@fgedu-master1 ~]# kubectl rollout status deployment fgedu-app -n fgedu-production
Waiting for deployment “fgedu-app” rollout to finish: 1 out of 3 new replicas have been updated…
Waiting for deployment “fgedu-app” rollout to finish: 2 out of 3 new replicas have been updated…
Waiting for deployment “fgedu-app” rollout to finish: 2 out of 3 new replicas have been updated…
Waiting for deployment “fgedu-app” rollout to finish: 3 out of 3 new replicas have been updated…
deployment “fgedu-app” successfully rolled out
# 回滚更新
[root@fgedu-master1 ~]# kubectl rollout undo deployment fgedu-app -n fgedu-production
# 查看回滚状态
[root@fgedu-master1 ~]# kubectl rollout status deployment fgedu-app -n fgedu-production
Waiting for deployment “fgedu-app” rollout to finish: 1 out of 3 new replicas have been updated…
Waiting for deployment “fgedu-app” rollout to finish: 2 out of 3 new replicas have been updated…
Waiting for deployment “fgedu-app” rollout to finish: 2 out of 3 new replicas have been updated…
Waiting for deployment “fgedu-app” rollout to finish: 3 out of 3 new replicas have been updated…
deployment “fgedu-app” successfully rolled out
4.2 StatefulSet控制器实战
StatefulSet控制器实战:
[root@fgedu-master1 ~]# kubectl apply -f statefulset.yaml
# 查看StatefulSet状态
[root@fgedu-master1 ~]# kubectl get statefulset fgedu-db -n fgedu-production
NAME READY AGE
fgedu-db 3/3 10m
# 查看Pod状态
[root@fgedu-master1 ~]# kubectl get pods -n fgedu-production | grep fgedu-db
fgedu-db-0 1/1 Running 0 10m
fgedu-db-1 1/1 Running 0 9m
fgedu-db-2 1/1 Running 0 8m
# 查看PVC状态
[root@fgedu-master1 ~]# kubectl get pvc -n fgedu-production | grep data
data-fgedu-db-0 Bound pvc-5d789f45c6-7q6x5 10Gi RWO standard 10m
data-fgedu-db-1 Bound pvc-6b8b945955-5k9x8 10Gi RWO standard 9m
data-fgedu-db-2 Bound pvc-7c9c567890-9r2t3 10Gi RWO standard 8m
# 扩容StatefulSet
[root@fgedu-master1 ~]# kubectl scale statefulset fgedu-db -n fgedu-production –replicas=5
# 查看扩容状态
[root@fgedu-master1 ~]# kubectl get statefulset fgedu-db -n fgedu-production
NAME READY AGEfgedu-db 5/5 15m
# 缩容StatefulSet
[root@fgedu-master1 ~]# kubectl scale statefulset fgedu-db -n fgedu-production –replicas=3
# 查看缩容状态
[root@fgedu-master1 ~]# kubectl get statefulset fgedu-db -n fgedu-production
NAME READY AGE
fgedu-db 3/3 20m
4.3 自定义控制器开发实战
自定义控制器开发实战。
[root@fgedu-master1 ~]# curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
[root@fgedu-master1 ~]# chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
# 初始化项目
[root@fgedu-master1 ~]# mkdir -p $GOPATH/src/github.com/fgedu/custom-controller
[root@fgedu-master1 ~]# cd $GOPATH/src/github.com/fgedu/custom-controller
[root@fgedu-master1 custom-controller]# kubebuilder init –domain fgedu.com
# 创建API资源,更多视频教程www.fgedu.net.cn。
[root@fgedu-master1 custom-controller]# kubebuilder create api –group apps –version v1 –kind CustomApp
# 编写控制器逻辑
[root@fgedu-master1 custom-controller]# cat > controllers/customapp_controller.go << EOF
/*
Copyright 2023. All rights reserved.
*/
package controllers
import (
"context"
"fmt"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
appsv1beta1 "github.com/fgedu/custom-controller/api/v1beta1"
)
// CustomAppReconciler reconciles a CustomApp object
type CustomAppReconciler struct {
client.Client
Scheme *runtime.Scheme
}
//+kubebuilder:rbac:groups=apps.fgedu.com,resources=customapps,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=apps.fgedu.com,resources=customapps/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=apps.fgedu.com,resources=customapps/finalizers,verbs=update
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete
// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
func (r *CustomAppReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
// Fetch the CustomApp instance
customApp := &appsv1beta1.CustomApp{}err := r.Get(ctx, req.NamespacedName, customApp)
if err != nil {
if errors.IsNotFound(err) {
// Request object not found, could have been deleted after reconcile request.\n"
return ctrl.Result{}, nil
}
// Error reading the object - requeue the request.
return ctrl.Result{}, err
}
// Create or update Deployment
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: customApp.Name,
Namespace: customApp.Namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: &customApp.Spec.Replicas,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": customApp.Name,
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": customApp.Name,
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: customApp.Name,
Image: customApp.Spec.Image,
Ports: []corev1.ContainerPort{
{
ContainerPort: customApp.Spec.Port,
},
},
},
},更多学习教程公众号风哥教程itpux_com。
},
},
},
}
// Set CustomApp as the owner and controller
if err := ctrl.SetControllerReference(customApp, deployment, r.Scheme); err != nil {
return ctrl.Result{}, err
}
// Check if the Deployment already exists
found := &appsv1.Deployment{}
err = r.Get(ctx, req.NamespacedName, found)
if err != nil && errors.IsNotFound(err) {
fmt.Printf("Creating a new Deployment for CustomApp %s\n", customApp.Name)
err = r.Create(ctx, deployment)
if err != nil {
return ctrl.Result{}, err
}
} else if err != nil {
return ctrl.Result{}, err
} else if !metav1.IsControlledBy(found, customApp) {
return ctrl.Result{}, fmt.Errorf("Deployment %s is not controlled by CustomApp %s", found.Name, customApp.Name)
} else {
// Update the Deployment if needed
if found.Spec.Replicas != &customApp.Spec.Replicas || found.Spec.Template.Spec.Containers[0].Image != customApp.Spec.Image {
fmt.Printf("Updating Deployment for CustomApp %s\n", customApp.Name)
found.Spec.Replicas = &customApp.Spec.Replicas
found.Spec.Template.Spec.Containers[0].Image = customApp.Spec.Image
err = r.Update(ctx, found)if err != nil {
return ctrl.Result{}, err
}
}
}
// Create or update Service
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: customApp.Name,
Namespace: customApp.Namespace,
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{
"app": customApp.Name,
},
Ports: []corev1.ServicePort{
{
Port: customApp.Spec.Port,
TargetPort: corev1.IntStr{IntVal: customApp.Spec.Port},
},
},
Type: corev1.ServiceTypeClusterIP,
},
}
// Set CustomApp as the owner and controller
if err := ctrl.SetControllerReference(customApp, service, r.Scheme); err != nil {
return ctrl.Result{}, err
}
// Check if the Service already exists
serviceFound := &corev1.Service{}
err = r.Get(ctx, req.NamespacedName, serviceFound)
if err != nil && errors.IsNotFound(err) {
fmt.Printf("Creating a new Service for CustomApp %s\n", customApp.Name)
err = r.Create(ctx, service)
if err != nil {
return ctrl.Result{}, err
}
} else if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
func (r *CustomAppReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&appsv1beta1.CustomApp{}).
Owns(&appsv1.Deployment{}).
Owns(&corev1.Service{}).
Complete(r)
}
EOF
# 构建和部署自定义控制器,from K8S+DB视频:www.itpux.com。
[root@fgedu-master1 custom-controller]# make build
[root@fgedu-master1 custom-controller]# make deploy
# 创建自定义资源实例
[root@fgedu-master1 custom-controller]# cat > customapp.yaml << EOF
apiVersion: apps.fgedu.com/v1beta1
kind: CustomApp
metadata:
name: fgedu-custom-app
namespace: fgedu-production
spec:
replicas: 3。
image: nginx:latest
port: 80
EOF
[root@fgedu-master1 custom-controller]# kubectl apply -f customapp.yaml
# 验证自定义资源状态
[root@fgedu-master1 custom-controller]# kubectl get customapp fgedu-custom-app -n fgedu-production
NAME AGE
fgedu-custom-app 5m
# 验证生成的Deployment和Service
[root@fgedu-master1 custom-controller]# kubectl get deployment fgedu-custom-app -n fgedu-production
NAME READY UP-TO-DATE AVAILABLE AGE
fgedu-custom-app 3/3 3 3 5m
[root@fgedu-master1 custom-controller]# kubectl get service fgedu-custom-app -n fgedu-production
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
fgedu-custom-app ClusterIP 10.96.123.45 <none> 80/TCP 5m
Part05-风哥经验总结与分享
5.1 控制器最佳实践
控制器最佳实践。。
- 合理配置控制器参数:根据应用的需求配置合适的副本数、更新策略等参数。
- 使用标签和选择器:合理使用标签和选择器,便于控制器管理和监控。
- 配置健康检查:为Pod配置合适的存活探针和就绪探针,确保应用的健康运行。
- 设置资源限制:为Pod设置合理的资源请求和限制,避免资源滥用。
- 使用命名空间隔离:将不同的应用部署在不同的命名空间中,提高安全性和可管理性。
5.2 控制器故障排查技巧
控制器故障排查技巧:
- 查看控制器状态:使用kubectl get和kubectl describe命令查看控制器的状态。
- 查看Pod状态:检查Pod的状态和日志,了解应用的运行情况。
- 检查事件:查看控制器和Pod的事件,了解发生的问题。
- 验证资源配置:检查控制器的资源配置是否正确。
- 测试网络连接:检查Pod之间的网络连接是否正常。
- 查看控制器日志:查看控制器的日志,了解控制器的运行情况。
5.3 控制器安全防护建议
控制器安全防护建议:
- 使用RBAC控制访问:为控制器设置合适的RBAC权限,防止未授权的访问。
- 使用安全的镜像:使用官方或经过验证的镜像,避免使用不安全的镜像。
- 配置安全上下文:为Pod配置合适的安全上下文,提高安全性。
- 使用网络策略:配置网络策略,限制Pod之间的网络访问。
- 定期更新控制器:定期更新控制器的版本,修复安全漏洞。
- 监控控制器状态:使用监控工具监控控制器的状态,及时发现异常。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
