1. 为什么选择阿里云ECS搭建Kubernetes?
在云计算领域,Kubernetes已经成为容器编排的事实标准。而阿里云作为国内领先的云服务提供商,其ECS(弹性计算服务)产品线提供了稳定可靠的基础设施支持。将两者结合,可以为企业级应用提供弹性、高可用的容器化部署方案。
我最近在阿里云上搭建了一个生产级的Kubernetes集群,整个过程虽然遇到了一些挑战,但也积累了不少实战经验。相比其他云平台,阿里云ECS有几个显著优势:
- 网络性能优异:阿里云的内网带宽最高可达25Gbps,节点间通信延迟低
- 磁盘IO稳定:ESSD云盘提供稳定的IOPS性能,适合运行etcd等关键组件
- 地域覆盖广:国内多地域可选,便于实现跨区域部署
- 成本可控:按量付费模式灵活,搭配预留实例券可节省30%以上成本
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与资源配置
2.1 ECS实例选型建议
根据我的经验,搭建Kubernetes集群的ECS实例配置需要根据集群规模和工作负载特点来选择:
| 节点角色 | 推荐配置 | 数量 | 系统盘 | 数据盘 |
|---|---|---|---|---|
| Master | 4核8G | 3台 | 100G | 200G |
| Worker | 8核16G | ≥2台 | 100G | 500G |
注意:生产环境务必保证Master节点数量为奇数(3或5),这是etcd集群的硬性要求。
2.2 网络规划要点
在创建ECS实例前,需要做好网络规划:
- 专有网络VPC:建议为K8s集群单独创建VPC,CIDR块建议使用10.0.0.0/16
- 交换机配置:至少创建2个不同可用区的交换机,实现跨AZ高可用
- 安全组规则:需要开放以下端口:
- Master节点:6443, 2379-2380, 10250-10252
- Worker节点:10250, 30000-32767
- EIP配置:为Master节点绑定弹性公网IP,方便远程管理
3. Kubernetes集群部署实战
3.1 系统初始化配置
在所有节点上执行以下初始化操作:
bash复制# 关闭swap
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
# 关闭SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# 配置内核参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# 安装基础工具
yum install -y yum-utils device-mapper-persistent-data lvm2
3.2 使用kubeadm部署集群
首先在所有节点上安装Docker和kubeadm:
bash复制# 配置阿里云Docker CE源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装Docker
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io
systemctl enable --now docker
# 配置阿里云Kubernetes源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 安装kubeadm
yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0
systemctl enable --now kubelet
在Master节点上初始化集群:
bash复制kubeadm init \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=<Master节点内网IP> \
--control-plane-endpoint=<Master节点内网IP>:6443
初始化完成后,按照提示配置kubectl:
bash复制mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
4. 网络插件与存储配置
4.1 安装Flannel网络插件
Kubernetes需要网络插件实现Pod间通信,这里选择Flannel:
bash复制kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
验证网络插件状态:
bash复制kubectl get pods -n kube-system -l app=flannel
4.2 配置阿里云CSI插件
为了使用阿里云云盘作为持久化存储,需要安装CSI插件:
bash复制# 添加阿里云Helm仓库
helm repo add alibaba https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/charts-incubator/
helm repo update
# 安装CSI插件
helm install csi-disk alibaba/aliyun-csi-driver -n kube-system
创建StorageClass:
yaml复制apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: alicloud-disk-essd
provisioner: diskplugin.csi.alibabacloud.com
parameters:
type: cloud_essd
fsType: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
5. 运维优化与问题排查
5.1 常见问题解决方案
问题1:kubeadm init卡在preflight阶段
可能原因:节点时间不同步
解决方案:
bash复制yum install -y ntpdate
ntpdate ntp.aliyun.com
问题2:Pod一直处于Pending状态
可能原因:资源不足或节点有污点
解决方案:
bash复制kubectl describe pod <pod-name> # 查看具体原因
kubectl get nodes -o wide # 检查节点资源
5.2 性能优化建议
- kubelet配置优化:
bash复制# 在/var/lib/kubelet/config.yaml中添加:
evictionHard:
memory.available: "500Mi"
nodefs.available: "10%"
nodefs.inodesFree: "5%"
imagefs.available: "10%"
- etcd调优:
bash复制# 修改/etc/kubernetes/manifests/etcd.yaml中的启动参数:
--quota-backend-bytes=8589934592 # 8GB
--auto-compaction-retention=24h
- API Server参数优化:
bash复制# 修改/etc/kubernetes/manifests/kube-apiserver.yaml:
--max-requests-inflight=3000
--max-mutating-requests-inflight=1000
6. 监控与日志方案
6.1 部署Prometheus监控
使用Helm安装Prometheus Operator:
bash复制helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring
配置阿里云SLS日志服务:
- 在阿里云控制台开通SLS服务
- 创建Project和Logstore
- 部署Logtail DaemonSet:
bash复制kubectl apply -f https://raw.githubusercontent.com/aliyun/aliyun-log-kubernetes/master/logtail/kubernetes/alicloud-log-k8s.yaml
配置日志采集规则:
yaml复制apiVersion: log.alibabacloud.com/v1alpha1
kind: AliyunLogConfig
metadata:
name: nginx-log
namespace: default
spec:
logstore: k8s-nginx
shardCount: 2
lifeCycle: 90
machineGroups:
- k8s-group
inputDetail:
type: plugin
plugin:
inputs:
- type: service_docker_stdout
detail:
IncludeLabel:
app: nginx
processors:
- type: processor_regex
detail:
SourceKey: content
Regex: '(.*)'
Keys: ["content"]
7. 安全加固措施
7.1 RBAC权限控制
创建最小权限ServiceAccount:
yaml复制apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-deploy
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deploy-role
namespace: default
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deploy-rolebinding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: deploy-role
subjects:
- kind: ServiceAccount
name: ci-deploy
namespace: default
7.2 网络策略配置
限制Pod间网络访问:
yaml复制apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
7.3 镜像安全扫描
集成阿里云容器镜像服务的安全扫描功能:
- 在容器镜像服务控制台启用安全扫描
- 配置自动扫描策略
- 在CI/CD流水线中添加扫描结果检查:
bash复制# 示例检查脚本
SCAN_RESULT=$(aliyun cr GetImageScanResult --region cn-hangzhou --repoNamespace myns --repoName myapp --imageTag v1.0.0 | jq '.Data.Status')
if [ "$SCAN_RESULT" != "\"SUCCESS\"" ]; then
echo "Image scan failed!"
exit 1
fi
8. 成本优化实践
8.1 使用弹性伸缩
配置Cluster Autoscaler:
yaml复制apiVersion: autoscaling/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: cluster-autoscaler
template:
metadata:
labels:
app: cluster-autoscaler
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/google_containers/cluster-autoscaler:v1.20.0
name: cluster-autoscaler
command:
- ./cluster-autoscaler
- --v=4
- --stderrthreshold=info
- --cloud-provider=alicloud
- --nodes=1:10:worker-auto-scaling-group
env:
- name: ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: alicloud-credentials
key: access-key-id
- name: ACCESS_KEY_SECRET
valueFrom:
secretKeyRef:
name: alicloud-credentials
key: access-key-secret
8.2 合理使用Spot实例
创建Spot实例节点池:
bash复制# 使用aliyuncli创建抢占式实例节点池
aliyun cs CreateClusterNodePool \
--cluster_id <cluster-id> \
--name spot-worker \
--count 3 \
--instance_type ecs.g6ne.large \
--system_disk_category cloud_essd \
--system_disk_size 100 \
--image_type aliyun_2_1903_x64_20G_alibase_20210630.vhd \
--spot_strategy SpotAsPriceGo \
--spot_price_limit "0.5" \
--vswitch_ids '["vsw-xxx1","vsw-xxx2"]' \
--login_password <your-password>
8.3 资源配额管理
设置Namespace资源配额:
yaml复制apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-team-quota
namespace: dev
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
pods: "100"
services: "20"
9. 持续集成与交付
9.1 基于GitLab的CI/CD流水线
.gitlab-ci.yml示例:
yaml复制stages:
- build
- test
- scan
- deploy
variables:
DOCKER_DRIVER: overlay2
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
build:
stage: build
image: docker:19.03.12
services:
- docker:19.03.12-dind
script:
- docker build -t $IMAGE_TAG .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $IMAGE_TAG
scan:
stage: scan
image: registry.cn-hangzhou.aliyuncs.com/acs/security-scan:v0.6.0
script:
- ./scan --image $IMAGE_TAG --exit-code
allow_failure: false
deploy:
stage: deploy
image: registry.cn-hangzhou.aliyuncs.com/acs/kubectl:v1.20.0-aliyun.1
script:
- echo $KUBE_CONFIG | base64 -d > kubeconfig.yaml
- export KUBECONFIG=./kubeconfig.yaml
- kubectl set image deployment/myapp myapp=$IMAGE_TAG -n production
9.2 使用Argo CD实现GitOps
安装Argo CD:
bash复制kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
配置阿里云Git仓库同步:
yaml复制apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: production-app
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
namespace: production
project: default
source:
path: kustomize/overlays/production
repoURL: git@code.aliyun.com:myteam/myrepo.git
targetRevision: HEAD
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
10. 备份与灾难恢复
10.1 etcd数据备份
创建定时备份任务:
bash复制# 备份脚本/etc/kubernetes/etcd-backup.sh
#!/bin/bash
DATE=$(date +%Y%m%d)
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /backup/etcd-snapshot-${DATE}.db
# 上传到OSS
aliyun oss cp /backup/etcd-snapshot-${DATE}.db oss://my-bucket/etcd-backup/
配置CronJob:
yaml复制apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: etcd-backup
namespace: kube-system
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: etcd-backup
image: registry.cn-hangzhou.aliyuncs.com/acs/etcdctl:v3.4.13
command: ["/bin/sh", "/backup.sh"]
volumeMounts:
- mountPath: /backup
name: backup-volume
- mountPath: /etc/kubernetes/pki/etcd
name: etcd-certs
readOnly: true
volumes:
- name: backup-volume
hostPath:
path: /var/etcd-backups
type: DirectoryOrCreate
- name: etcd-certs
hostPath:
path: /etc/kubernetes/pki/etcd
type: Directory
restartPolicy: OnFailure
10.2 应用数据备份
使用Velero实现应用级备份:
bash复制# 安装Velero客户端
wget https://github.com/vmware-tanzu/velero/releases/download/v1.7.0/velero-v1.7.0-linux-amd64.tar.gz
tar -xvf velero-v1.7.0-linux-amd64.tar.gz
sudo mv velero-v1.7.0-linux-amd64/velero /usr/local/bin/
# 配置阿里云OSS备份存储
velero install \
--provider alibabacloud \
--plugins velero/velero-plugin-for-alibabacloud:v1.2.0 \
--bucket velero-backup \
--secret-file ./credentials-velero \
--backup-location-config region=cn-hangzhou \
--snapshot-location-config region=cn-hangzhou \
--use-volume-snapshots=true \
--use-restic=true
创建定时备份策略:
bash复制velero schedule create daily-backup \
--schedule="0 3 * * *" \
--include-namespaces production \
--ttl 168h
