Kind教程#
技术介绍#
Kind(Kubernetes IN Docker)是一个使用Docker容器作为节点来运行本地Kubernetes集群的工具。它由Kubernetes SIGs(特别兴趣小组)开发和维护,专为测试和开发目的设计。Kind的主要特点是快速创建和销毁Kubernetes集群,非常适合CI/CD环境、集成测试和本地开发。
Kind核心概念#
- 集群:由多个节点组成的Kubernetes集群
- 节点:使用Docker容器模拟的Kubernetes节点
- 配置文件:定义集群的配置,如节点数量、版本等
- 镜像:包含Kubernetes组件的Docker镜像
Kind架构#
- 控制平面节点:运行Kubernetes控制平面组件的Docker容器
- 工作节点:运行工作负载的Docker容器
- 容器网络:连接各个节点容器的网络
入门级使用#
安装Kind#
在不同操作系统上安装Kind:
# Linux/macOS
# 使用curl安装
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/
# macOS使用Homebrew安装
brew install kind
# Windows使用Chocolatey安装
choco install kind
# 验证安装
kind --version基本Kind命令#
使用Kind的基本命令:
# 查看Kind版本
kind --version
# 创建集群
kind create cluster
# 创建指定名称的集群
kind create cluster --name my-cluster
# 查看集群
kind get clusters
# 删除集群
kind delete cluster
# 删除指定名称的集群
kind delete cluster --name my-cluster
# 查看集群节点
kubectl get nodes创建第一个Kind集群#
创建一个基本的Kind集群:
# 创建默认集群
kind create cluster
# 查看集群状态
kubectl cluster-info
# 查看节点
kubectl get nodes
# 部署应用
kubectl create deployment nginx --image=nginx
# 暴露服务
kubectl expose deployment nginx --port=80 --type=NodePort
# 访问应用
kubectl port-forward service/nginx 8080:80
curl http://localhost:8080
# 删除集群
kind delete cluster初级使用#
Kind配置文件#
使用Kind配置文件创建集群:
# 创建配置文件
cat > kind-config.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
# 使用配置文件创建集群
kind create cluster --config=kind-config.yaml
# 查看节点
kubectl get nodes
# 配置多控制平面节点
cat > kind-ha-config.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
EOF
# 创建高可用集群
kind create cluster --config=kind-ha-config.yamlKind网络配置#
配置Kind集群网络:
# 创建带自定义网络的配置文件
cat > kind-network-config.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
# 禁用默认CNI
disableDefaultCNI: true
# 自定义Pod CIDR
podSubnet: 192.168.0.0/16
# 自定义服务CIDR
serviceSubnet: 10.96.0.0/12
nodes:
- role: control-plane
- role: worker
EOF
# 创建集群
kind create cluster --config=kind-network-config.yaml
# 安装自定义CNI
kubectl apply -f https://docs.projectcalico.org/v3.24/manifests/calico.yaml
# 查看网络状态
kubectl get pods -n kube-systemKind镜像管理#
管理Kind集群镜像:
# 查看可用的Kind节点镜像
kind build node-image --help
# 使用指定版本的Kubernetes
kind create cluster --image=kindest/node:v1.23.0
# 构建自定义节点镜像
kind build node-image --image=my-custom-node-image
# 使用自定义节点镜像创建集群
kind create cluster --image=my-custom-node-image中级使用#
Kind与本地镜像#
在Kind集群中使用本地Docker镜像:
# 构建本地镜像
docker build -t my-app:latest .
# 加载镜像到Kind集群
kind load docker-image my-app:latest
# 部署应用使用本地镜像
kubectl apply -f app-deployment.yaml
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
# 查看应用状态
kubectl get podsKind与Ingress#
在Kind集群中配置Ingress:
# 创建带Ingress配置的集群
cat > kind-ingress-config.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
# 创建集群
kind create cluster --config=kind-ingress-config.yaml
# 安装Ingress控制器
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# 等待Ingress控制器就绪
kubectl wait --namespace ingress-nginx
--for=condition=ready pod
--selector=app.kubernetes.io/component=controller
--timeout=90s
# 部署应用和Ingress
kubectl apply -f app-with-ingress.yaml
# app-with-ingress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-app
spec:
replicas: 2
selector:
matchLabels:
app: hello-app
template:
metadata:
labels:
app: hello-app
spec:
containers:
- name: hello-app
image: gcr.io/hello-minikube-zero-install/hello-app:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
app: hello-app
ports:
- port: 80
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: hello-world.example
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-service
port:
number: 80
# 添加主机名到/etc/hosts
echo "127.0.0.1 hello-world.example" | sudo tee -a /etc/hosts
# 访问应用
curl http://hello-world.exampleKind与存储#
在Kind集群中配置存储:
# 创建带本地路径配置的集群
cat > kind-storage-config.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: /mnt/data
containerPath: /mnt/data
- role: worker
extraMounts:
- hostPath: /mnt/data
containerPath: /mnt/data
EOF
# 创建集群
kind create cluster --config=kind-storage-config.yaml
# 部署使用本地存储的应用
kubectl apply -f app-with-storage.yaml
# app-with-storage.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy:
Retain
storageClassName:
local-storage
local:
path: /mnt/data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- kind-worker
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName:
local-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-with-storage
spec:
replicas: 1
selector:
matchLabels:
app: app-with-storage
template:
metadata:
labels:
app: app-with-storage
spec:
containers:
- name: app-with-storage
image: nginx
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: local-pvc
# 查看存储状态
kubectl get pv
kubectl get pvc中上级使用#
Kind与CI/CD集成#
将Kind与CI/CD集成:
# .gitlab-ci.yml
stages:
- build
- test
- deploy
build:
stage: build
script:
- docker build -t my-app:latest .
.test:
stage: test
script:
- curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-amd64
- chmod +x ./kind
- sudo mv ./kind /usr/local/bin/
- kind create cluster
- kind load docker-image my-app:latest
- kubectl apply -f app-deployment.yaml
- kubectl wait --for=condition=ready pod -l app=my-app --timeout=90s
- kubectl port-forward service/my-app 8080:80 &
- sleep 5
- curl http://localhost:8080
- kind delete cluster
artifacts:
paths:
- ./kind
# Jenkinsfile
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'docker build -t my-app:latest .'
}
}
stage('Test') {
steps {
sh 'curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-amd64'
sh 'chmod +x ./kind'
sh 'sudo mv ./kind /usr/local/bin/'
sh 'kind create cluster'
sh 'kind load docker-image my-app:latest'
sh 'kubectl apply -f app-deployment.yaml'
sh 'kubectl wait --for=condition=ready pod -l app=my-app --timeout=90s'
sh 'kubectl port-forward service/my-app 8080:80 &'
sh 'sleep 5'
sh 'curl http://localhost:8080'
sh 'kind delete cluster'
}
}
}
}Kind与多集群#
管理多个Kind集群:
# 创建多个集群
kind create cluster --name cluster1
kind create cluster --name cluster2
# 查看集群
kind get clusters
# 切换集群上下文
kubectl config use-context kind-cluster1
kubectl get nodes
kubectl config use-context kind-cluster2
kubectl get nodes
# 删除集群
kind delete cluster --name cluster1
kind delete cluster --name cluster2Kind与自定义Kubernetes版本#
使用不同版本的Kubernetes:
# 查看可用的Kind节点镜像版本
docker pull kindest/node:v1.22.0
docker pull kindest/node:v1.23.0
docker pull kindest/node:v1.24.0
# 创建使用特定版本的集群
kind create cluster --image=kindest/node:v1.22.0 --name cluster-v1.22
# 查看集群版本
kubectl version
# 创建使用不同版本的集群
kind create cluster --image=kindest/node:v1.23.0 --name cluster-v1.23
# 查看集群版本
kubectl config use-context kind-cluster-v1.23
kubectl version高级使用#
Kind与Operator开发#
使用Kind开发和测试Kubernetes Operator:
# 创建测试集群
kind create cluster --name operator-test
# 安装Operator SDK
curl -LO https://github.com/operator-framework/operator-sdk/releases/download/v1.20.0/operator-sdk_linux_amd64
tar xvf operator-sdk_linux_amd64.tar.gz
chmod +x operator-sdk
mv operator-sdk /usr/local/bin/
# 初始化Operator项目
operator-sdk init --domain example.com --repo github.com/example/my-operator
# 创建API和控制器
operator-sdk create api --group apps --version v1alpha1 --kind MyApp --resource --controller
# 构建和推送镜像
make docker-build docker-push IMG=my-operator:latest
# 加载镜像到Kind集群
kind load docker-image my-operator:latest --name operator-test
# 部署Operator
make deploy IMG=my-operator:latest
# 查看Operator状态
kubectl get pods -n my-operator-system
# 创建自定义资源实例
kubectl apply -f config/samples/apps_v1alpha1_myapp.yaml
# 查看实例状态
kubectl get myappKind与网络策略#
在Kind集群中配置网络策略:
# 创建集群
kind create cluster --name network-policy-test
# 安装Calico CNI
kubectl apply -f https://docs.projectcalico.org/v3.24/manifests/calico.yaml
# 部署测试应用
kubectl apply -f network-policy-test.yaml
# network-policy-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox
labels:
app: busybox
spec:
replicas: 1
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
command:
- sleep
- "3600"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: nginx-network-policy
spec:
podSelector:
matchLabels:
app: nginx
ingress:
- from:
- podSelector:
matchLabels:
app: busybox
ports:
- protocol: TCP
port: 80
# 测试网络策略
# 从busybox Pod访问nginx
kubectl exec -it $(kubectl get pods -l app=busybox -o jsonpath='{.items[0].metadata.name}') -- wget -qO- http://nginx
# 创建另一个Pod尝试访问nginx
kubectl run --rm -it test-pod --image=busybox -- /bin/sh
# 在Pod中执行
wget -qO- http://nginx
# 应该无法访问Kind与Helm#
在Kind集群中使用Helm:
# 安装Helm
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
# 创建集群
kind create cluster --name helm-test
# 添加Helm仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 安装应用
helm install my-nginx bitnami/nginx
# 查看应用状态
helm status my-nginx
kubectl get pods
# 升级应用
helm upgrade my-nginx bitnami/nginx --set service.type=NodePort
# 卸载应用
helm uninstall my-nginx大师级使用#
Kind与多节点集群#
创建和管理多节点Kind集群:
# 创建多节点集群配置
cat > kind-multi-node.yaml << EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
- role: worker
- role: worker
EOF
# 创建集群
kind create cluster --config=kind-multi-node.yaml --name multi-node-cluster
# 查看节点
kubectl get nodes
# 部署应用到指定节点
kubectl apply -f app-with-node-selector.yaml
# app-with-node-selector.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-with-node-selector
spec:
replicas: 3
selector:
matchLabels:
app: app-with-node-selector
template:
metadata:
labels:
app: app-with-node-selector
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
containers:
- name: app-with-node-selector
image: nginx
ports:
- containerPort: 80
# 查看Pod分布
kubectl get pods -o wideKind与Kubernetes测试#
使用Kind进行Kubernetes测试:
# 创建测试集群
kind create cluster --name k8s-test
# 克隆Kubernetes仓库
git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
# 运行测试
make test WHAT=./pkg/kubelet GOFLAGS="-v"
# 运行集成测试
make integration WHAT=./test/integration/network
# 清理测试环境
kind delete cluster --name k8s-testKind与云原生工具链#
集成Kind与云原生工具链:
# 创建集群
kind create cluster --name cloud-native
# 安装Istio
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo -y
# 部署Bookinfo应用
kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
# 查看应用状态
kubectl get pods
# 访问应用
kubectl port-forward service/productpage 9080:9080
curl http://localhost:9080
# 安装Prometheus和Grafana
kubectl apply -f samples/addons/prometheus.yaml
kubectl apply -f samples/addons/grafana.yaml
# 访问Grafana
kubectl port-forward service/grafana 3000:3000 -n istio-system实战案例#
案例一:本地开发环境#
场景:为开发团队创建一致的本地Kubernetes开发环境。
解决方案:使用Kind创建标准化的本地集群。
实施步骤:
创建标准化配置:
cat > kind-dev-config.yaml << EOF kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane extraPortMappings: - containerPort: 80 hostPort: 80 - containerPort: 443 hostPort: 443 - role: worker EOF创建开发集群:
kind create cluster --config=kind-dev-config.yaml --name dev部署开发工具:
# 安装Ingress控制器 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml # 安装PostgreSQL helm repo add bitnami https://charts.bitnami.com/bitnami helm install postgres bitnami/postgresql --set auth.postgresPassword=secret # 安装Redis helm install redis bitnami/redis --set auth.password=secret
结果:
- 成功创建了标准化的本地开发环境
- 部署了开发所需的基础设施
- 团队成员可以使用相同的环境进行开发
案例二:CI/CD测试环境#
场景:在CI/CD pipeline中使用Kind进行应用测试。
解决方案:集成Kind到CI/CD系统。
实施步骤:
配置GitLab CI:
# .gitlab-ci.yml stages: - build - test - deploy build: stage: build script: - docker build -t my-app:latest . test: stage: test script: - curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.14.0/kind-linux-amd64 - chmod +x ./kind - ./kind create cluster - ./kind load docker-image my-app:latest - kubectl apply -f k8s/deployment.yaml - kubectl wait --for=condition=ready pod -l app=my-app --timeout=90s - kubectl port-forward service/my-app 8080:80 & - sleep 5 - curl http://localhost:8080/health - ./kind delete cluster运行CI/CD pipeline:
- 推送代码到GitLab仓库
- 触发CI/CD pipeline
- 查看测试结果
结果:
- 成功集成Kind到CI/CD系统
- 实现了自动化的应用测试
- 确保了应用在Kubernetes环境中的兼容性
案例三:Kubernetes版本升级测试#
场景:测试应用在不同Kubernetes版本上的兼容性。
解决方案:使用Kind创建不同版本的Kubernetes集群。
实施步骤:
- 创建不同版本的集群:
# 创建v1.22集群 kind create cluster --image=kindest/node:v1.22.0 --name k8s-v1.22 # 部署应用 kubectl apply -f app-deployment.yaml # 测试应用 kubectl port-forward service/my-app 8080:80 curl http://localhost:8080 # 删除集群 kind delete cluster --name k8s-v1.22 # 创建v1.23集群 kind create cluster --image=kindest/node:v1.23.0 --name k8s-v1.23 # 部署应用 kubectl apply -f app-deployment.yaml # 测试应用 kubectl port-forward service/my-app 8080:80 curl http://localhost:8080 # 删除集群 kind delete cluster --name k8s-v1.23
结果:
- 成功测试了应用在不同Kubernetes版本上的兼容性
- 发现了版本升级可能带来的问题
- 为生产环境的版本升级提供了参考
总结#
Kind是一种强大的本地Kubernetes集群工具,通过本教程的学习,您已经掌握了从入门到大师级的Kind使用技术。
主要技术回顾#
- 基础操作:Kind的基本安装和配置
- 集群管理:创建和管理Kind集群
- 高级功能:网络配置、存储配置、Ingress配置
- 企业级应用:CI/CD集成、多集群管理、Kubernetes测试
最佳实践#
- 版本管理:使用特定版本的Kind和Kubernetes镜像,确保环境一致性
- 配置标准化:创建标准化的Kind配置文件,确保团队使用相同的环境
- 资源管理:根据测试需求调整集群规模,避免资源浪费
- 镜像管理:使用本地镜像加速部署,提高测试效率
- 清理策略:测试完成后及时删除集群,释放资源
- 集成自动化:将Kind集成到CI/CD系统,实现自动化测试
- 文档化:为Kind配置和使用流程创建文档,便于团队协作
注意事项#
- 资源限制:Kind集群运行在Docker容器中,需要确保主机有足够的资源
- 网络配置:注意Kind集群的网络配置,确保与主机网络的兼容性
- 存储性能:本地存储的性能可能不如生产环境,测试时需考虑
- 版本兼容性:Kind支持的Kubernetes版本可能有限,需注意兼容性
- 安全配置:Kind集群主要用于测试,不建议用于生产环境
- 清理环境:测试完成后及时清理集群,避免资源泄漏
- 备份策略:对于重要的测试数据,制定适当的备份策略
通过合理学习和使用Kind,您可以快速创建和管理本地Kubernetes集群,为开发、测试和CI/CD提供可靠的环境。Kind的轻量级特性使其成为Kubernetes开发和测试的理想工具,同时保留了Kubernetes的核心功能,为您的应用提供真实的运行环境。