手把手教你用Docker和K8S单机版在本地跑一个MySQL服务(附排错全记录)
从零搭建单机Kubernetes环境运行MySQL实战指南最近在本地开发环境中尝试用Kubernetes部署MySQL服务时发现网上大多数教程要么过于简单缺乏实战细节要么直接跳过了部署过程中常见的各种坑。作为一个踩过所有雷的过来人我把整个搭建过程整理成这份实战手册重点解决从环境准备到最终Pod运行的全流程问题特别是那些官方文档很少提及的证书缺失、镜像拉取失败等典型错误。1. 环境准备与基础配置在单机上运行Kubernetes集群首先需要确保基础环境符合要求。我使用的是CentOS 7.9系统内核版本3.10.0-1160.el7.x86_64这是目前与Kubernetes兼容性较好的一个组合。不同于生产环境开发环境可以适当放宽某些安全限制。关键配置步骤关闭防火墙和SELinux仅限开发环境sudo systemctl stop firewalld sudo systemctl disable firewalld sudo setenforce 0要永久禁用SELinux需要修改/etc/selinux/config文件sudo sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config配置稳定的YUM源。我推荐使用阿里云镜像源速度更快更稳定sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo sudo yum clean all sudo yum makecache安装必要的工具包sudo yum install -y yum-utils device-mapper-persistent-data lvm2注意这些安全配置变更需要重启系统才能完全生效。如果遇到奇怪的权限问题记得检查是否已经重启过系统。2. Docker安装与配置Kubernetes依赖容器运行时环境我们选择Docker作为容器引擎。最新版的Docker CE可能和某些Kubernetes版本存在兼容性问题建议安装经过验证的稳定版本。安装特定版本Dockersudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce-19.03.15 docker-ce-cli-19.03.15 containerd.io关键配置调整修改Docker守护进程配置sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m }, registry-mirrors: [https://registry.docker-cn.com] } EOF启动并启用Docker服务sudo systemctl daemon-reload sudo systemctl restart docker sudo systemctl enable docker验证Docker安装docker run hello-world如果看到欢迎信息说明Docker已经正确安装。3. Kubernetes单机集群部署对于开发测试环境我们可以使用kubeadm工具快速搭建单节点Kubernetes集群。这种方式比手动配置各个组件要简单得多。安装kubeadm、kubelet和kubectlcat EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF sudo yum install -y kubelet-1.20.15 kubeadm-1.20.15 kubectl-1.20.15 --disableexcludeskubernetes sudo systemctl enable --now kubelet初始化集群sudo kubeadm init --pod-network-cidr10.244.0.0/16 --ignore-preflight-errorsSwap初始化成功后按照提示配置kubectlmkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config由于是单机环境我们需要取消master节点的污点限制kubectl taint nodes --all node-role.kubernetes.io/master-安装网络插件kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml验证集群状态kubectl get nodes kubectl get pods --all-namespaces所有组件都应该显示为Running状态。4. MySQL部署与排错实战现在进入核心环节——在Kubernetes上部署MySQL服务。我们将创建一个包含持久化存储的MySQL实例并解决部署过程中可能遇到的各种问题。创建持久化存储首先准备一个PersistentVolume这里使用hostPath类型方便开发测试# mysql-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce hostPath: path: /data/mysql persistentVolumeReclaimPolicy: Retain创建PV并验证kubectl apply -f mysql-pv.yaml kubectl get pv部署MySQL创建Deployment和Service的配置文件# mysql-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD value: yoursecurepassword ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi --- apiVersion: v1 kind: Service metadata: name: mysql spec: ports: - port: 3306 selector: app: mysql应用配置kubectl apply -f mysql-deployment.yaml常见问题排查Pod卡在ContainerCreating状态kubectl describe pod mysql-xxxx查看Events部分常见原因包括镜像拉取失败存储卷挂载问题资源不足镜像拉取失败 如果遇到registry.access.redhat.com镜像拉取问题需要安装红帽证书sudo yum install -y *rhsm* wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | sudo tee /etc/rhsm/ca/redhat-uep.pemMySQL启动失败 检查日志kubectl logs mysql-xxxx常见问题包括权限问题/var/lib/mysql目录权限配置文件错误验证MySQL服务获取Pod名称并连接kubectl get pods kubectl exec -it mysql-xxxx -- mysql -uroot -p查看Service信息kubectl get svc mysql5. 高级配置与优化基础MySQL服务运行后我们可以进行一些优化配置使其更适合开发环境使用。资源配置调整修改Deployment增加资源限制resources: requests: memory: 512Mi cpu: 250m limits: memory: 1Gi cpu: 500m配置MySQL参数通过ConfigMap管理MySQL配置# mysql-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: mysql-config data: my.cnf: | [mysqld] max_connections200 innodb_buffer_pool_size256M skip-name-resolve然后在Deployment中挂载这个配置volumeMounts: - name: config-volume mountPath: /etc/mysql/conf.d volumes: - name: config-volume configMap: name: mysql-config备份策略开发环境中数据安全同样重要可以设置定期备份kubectl exec mysql-xxxx -- mysqldump -uroot -p yourdatabase backup.sql或者使用cronjob自动备份apiVersion: batch/v1beta1 kind: CronJob metadata: name: mysql-backup spec: schedule: 0 3 * * * jobTemplate: spec: template: spec: containers: - name: backup image: mysql:5.7 command: [/bin/sh, -c] args: - mysqldump -uroot -p$(MYSQL_ROOT_PASSWORD) --all-databases /backup/backup-$(date \%Y\%m\%d).sql volumeMounts: - name: backup-volume mountPath: /backup restartPolicy: OnFailure volumes: - name: backup-volume hostPath: path: /backups/mysql6. 日常维护与问题诊断MySQL在Kubernetes中运行后还需要一些日常维护工作。这里分享几个实用技巧。监控MySQL状态kubectl top pod mysql-xxxx查看慢查询日志kubectl exec mysql-xxxx -- cat /var/log/mysql/mysql-slow.log性能分析kubectl exec -it mysql-xxxx -- mysql -uroot -p -e SHOW ENGINE INNODB STATUS\G常见问题快速修复Pod崩溃循环kubectl describe pod mysql-xxxx kubectl logs --previous mysql-xxxx存储空间不足kubectl exec mysql-xxxx -- df -h连接数耗尽kubectl exec -it mysql-xxxx -- mysql -uroot -p -e SHOW PROCESSLIST;扩展MySQL实例如果需要扩展为多实例可以修改Deployment的replicas数量kubectl scale deployment mysql --replicas2或者配置MySQL主从复制# 主库配置 apiVersion: v1 kind: Service metadata: name: mysql-master spec: ports: - port: 3306 selector: app: mysql role: master # 从库配置 apiVersion: apps/v1 kind: Deployment metadata: name: mysql-slave spec: replicas: 2 selector: matchLabels: app: mysql role: slave template: metadata: labels: app: mysql role: slave spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD value: yoursecurepassword - name: MYSQL_MASTER_HOST value: mysql-master command: [/bin/sh, -c] args: - set -ex; echo Waiting for master to be ready...; until nc -zv mysql-master 3306; do sleep 1; done; echo Setting up replication...; mysql -uroot -p$MYSQL_ROOT_PASSWORD -e CHANGE MASTER TO MASTER_HOST$(MYSQL_MASTER_HOST), MASTER_USERrepl, MASTER_PASSWORDreplpassword, MASTER_AUTO_POSITION1; START SLAVE; exec docker-entrypoint.sh mysqld