实战指南:在指定 IP 配置下搭建私有 Docker Registry 与 Kubernetes 集群
随着容器技术的不断发展,Docker 和 Kubernetes 已成为现代应用部署和管理的核心工具。本指南将带您一步步搭建一个包含私有 Docker Registry、Kubernetes 集群(包含 Master 和多个 Worker 节点)的完整容器化环境,同时介绍如何部署应用、配置网络和安全、以及实施监控与管理。
前言
假设您的基础设施 IP 配置如下:
- Docker Registry:
192.168.0.180:5000
- Master 节点:
192.168.0.181
- Worker 节点:
192.168.0.182
192.168.0.183
192.168.0.184
本指南将涵盖以下内容:
- 设置私有 Docker Registry
- 配置 Kubernetes 集群
- 构建并推送 Docker 镜像到私有 Registry
- 在 Kubernetes 上部署应用
- 配置网络与安全
- 监控与管理
- 备份与恢复
- 常见问题与故障排除
- 进一步优化与扩展
- 结语
一、设置私有 Docker Registry
1.1 部署 Docker Registry
在 192.168.0.180
服务器上部署官方 Docker Registry:
# 拉取官方 Docker Registry 镜像
docker pull registry:2
# 运行 Docker Registry 容器
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
registry:2
1.2 配置 TLS 以确保安全通信
为确保与 Docker Registry 的通信安全,配置 TLS:
生成自签名证书:
mkdir -p certs openssl req -newkey rsa:4096 -nodes -sha256 \ -keyout certs/domain.key -x509 -days 365 \ -out certs/domain.crt
提示:在生成证书时,
Common Name (CN)
应设置为192.168.0.180
。运行 Docker Registry 并使用 TLS:
docker stop registry docker rm registry docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v "$(pwd)/certs:/certs" \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ registry:2
在各 Kubernetes 节点上信任自签名证书:
将
domain.crt
拷贝到每个节点的/etc/docker/certs.d/192.168.0.180:5000/ca.crt
:mkdir -p /etc/docker/certs.d/192.168.0.180:5000/ cp domain.crt /etc/docker/certs.d/192.168.0.180:5000/ca.crt # 重启 Docker 服务 systemctl restart docker
二、配置 Kubernetes 集群
2.1 安装 Kubernetes 组件
在所有节点(Master 和 Workers)上安装 Docker、kubeadm
、kubelet
和 kubectl
,可参考 官方文档。
2.2 初始化 Master 节点
在 Master 节点 (192.168.0.181
) 上执行:
kubeadm init \
--apiserver-advertise-address=192.168.0.181 \
--pod-network-cidr=10.244.0.0/16
完成后,按照提示配置 kubectl
:
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
2.3 部署网络插件
以 Flannel 为例:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
2.4 添加 Worker 节点
在每个 Worker 节点上执行 kubeadm join
命令(在初始化时生成):
kubeadm join 192.168.0.181:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
2.5 验证集群状态
在 Master 节点上查看节点状态:
kubectl get nodes
应看到所有节点均为 Ready
状态。
三、构建并推送 Docker 镜像到私有 Registry
3.1 编写 Dockerfile
创建 Dockerfile
:
# 基于官方 Node.js 镜像
FROM node:14-alpine
# 设置工作目录
WORKDIR /app
# 安装依赖
COPY package.json .
RUN npm install
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["npm", "start"]
3.2 构建镜像
docker build -t 192.168.0.180:5000/my-app:v1.0 .
3.3 推送镜像到私有 Registry
docker push 192.168.0.180:5000/my-app:v1.0
注意:确保 Docker 已信任 Registry 的 TLS 证书。
四、在 Kubernetes 上部署应用
4.1 创建 Deployment 配置
创建 my-app-deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
imagePullSecrets:
- name: regcred
containers:
- name: my-app-container
image: 192.168.0.180:5000/my-app:v1.0
ports:
- containerPort: 3000
4.2 应用 Deployment
kubectl apply -f my-app-deployment.yaml
4.3 创建 Service
创建 my-app-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30007
4.4 应用 Service
kubectl apply -f my-app-service.yaml
4.5 访问应用
通过任一 Worker 节点的 IP 及端口访问:
http://192.168.0.182:30007
五、配置网络与安全
5.1 设置网络策略
创建 db-network-policy.yaml
,仅允许特定 Pod 访问数据库:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-my-app
namespace: database
spec:
podSelector:
matchLabels:
app: postgres
ingress:
- from:
- podSelector:
matchLabels:
app: my-app
ports:
- protocol: TCP
port: 5432
应用网络策略:
kubectl apply -f db-network-policy.yaml
5.2 配置 RBAC 权限
创建角色和角色绑定 role.yaml
:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: demo-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
应用配置:
kubectl apply -f role.yaml
5.3 安全最佳实践
- 最小权限原则:仅授予必要的权限。
- 限制特权容器:避免使用特权模式。
- 定期更新:保持镜像和组件的最新安全补丁。
六、监控与管理
6.1 部署 Prometheus 和 Grafana
使用 Helm 部署
添加 Helm 仓库:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update
安装 Prometheus:
helm install prometheus prometheus-community/prometheus
安装 Grafana:
helm install grafana prometheus-community/grafana
访问 Grafana:
获取初始密码:
kubectl get secret grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
端口转发:
kubectl port-forward svc/grafana 3000:80
在浏览器访问
http://localhost:3000
。
6.2 部署 Kubernetes Dashboard
部署 Dashboard:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.0/aio/deploy/recommended.yaml
创建管理员账户:
创建
dashboard-admin.yaml
:apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
应用配置:
kubectl apply -f dashboard-admin.yaml
获取登录令牌:
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"
访问 Dashboard:
运行代理:
kubectl proxy
在浏览器访问:
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
七、备份与恢复
7.1 备份 etcd
备份命令:
ETCDCTL_API=3 etcdctl snapshot save backup.db \
--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
7.2 恢复 etcd(如有必要)
恢复命令:
ETCDCTL_API=3 etcdctl snapshot restore backup.db \
--data-dir=/var/lib/etcd-from-backup
注意:恢复 etcd 涉及停机操作,请谨慎执行,并参考 官方文档。
八、常见问题与故障排除
8.1 Pod 无法拉取镜像
解决方式:
- 检查
imagePullSecrets
:确保已正确创建和引用。 - 验证 TLS 证书:确保节点信任 Registry 证书。
- 确认镜像存在:使用
curl
检查镜像仓库。
8.2 节点状态为 NotReady
解决方式:
检查 kubelet:
systemctl status kubelet
验证网络连接:确保节点间网络通畅。
查看日志:
journalctl -u kubelet
8.3 应用性能问题
解决方式:
- 资源分配:检查 Pod 的资源请求和限制。
- 日志查看:通过
kubectl logs
查看应用日志。 - 监控分析:使用 Prometheus 和 Grafana 分析性能瓶颈。
九、进一步优化与扩展
9.1 使用 Helm 简化部署
创建 Helm Chart:
helm create my-app
配置 values.yaml
:
image:
repository: 192.168.0.180:5000/my-app
tag: v1.0
imagePullSecrets:
- name: regcred
安装 Chart:
helm install my-app-release my-app
9.2 集成 CI/CD 流水线
示例:GitLab CI/CD
在 .gitlab-ci.yml
中配置:
stages:
- build
- deploy
build:
stage: build
script:
- docker build -t 192.168.0.180:5000/my-app:${CI_COMMIT_SHA} .
- docker push 192.168.0.180:5000/my-app:${CI_COMMIT_SHA}
deploy:
stage: deploy
script:
- kubectl set image deployment/my-app-deployment my-app-container=192.168.0.180:5000/my-app:${CI_COMMIT_SHA}
9.3 配置自动伸缩(HPA)
安装 Metrics Server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
创建 HPA:
kubectl autoscale deployment my-app-deployment --cpu-percent=50 --min=1 --max=5
9.4 部署 Ingress 控制器
安装 Nginx Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
创建 Ingress 资源:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
rules:
- host: myapp.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
更新本地 Hosts 文件:
echo "192.168.0.182 myapp.local" | sudo tee -a /etc/hosts
十、结语
通过本指南,您已成功搭建了一个包含私有 Docker Registry 和 Kubernetes 集群的完整容器化环境,实现了:
- 安全的镜像管理:通过配置私有 Registry 和 TLS,确保镜像分发的安全性。
- 高效的应用部署:利用 Kubernetes 的自动化能力,实现应用的快速部署和扩展。
- 完善的监控与运维:采用 Prometheus、Grafana 等工具,实现集群的可观测性。
- 持续集成与交付:集成 CI/CD 流水线,提高开发和部署效率。
最佳实践建议
- 持续更新:定期升级 Kubernetes 和相关组件,应用最新的安全补丁。
- 加强安全:遵循最小权限原则,定期审计权限设置,使用镜像签名等技术。
- 优化资源:监控资源使用,合理设置请求和限制,避免资源浪费。
- 完善文档与自动化:记录操作流程,使用工具自动化部署,提高运维效率。
通过持续的优化与实践,您可以打造一个高性能、高可用的容器化平台,为业务发展提供坚实的基础。