Kubernetes 集群部署踩坑指南

在前端开发中,Kubernetes 集群已经成为了部署应用的首选,其强大的扩展性和高可用性,让我们不必担心应用如何适应日益增长的用户量。

然而,在实践过程中,Kubernetes 集群部署经常会出现一些问题,本文将针对这些常见问题进行详细的探讨,帮助读者更好地理解 Kubernetes 集群部署的过程。

1. 准备工作

首先,我们需要准备一个 Kubernetes 集群。本文使用的版本为 v1.18.0。

在准备工作中,我们需要做以下几个关键的准备工作:

1.1 下载安装 kubectl、kubeadm 和 kubelet

首先,我们需要在部署节点上安装 kubectl、kubeadm 和 kubelet。

# 安装 kubectl
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

# 安装 kubeadm
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubeadm
chmod +x ./kubeadm
sudo mv ./kubeadm /usr/local/bin/kubeadm

# 安装 kubelet
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubelet
chmod +x ./kubelet
sudo mv ./kubelet /usr/local/bin/kubelet

1.2 部署 master 节点

接下来,我们需要在 Kubernetes 集群中部署 master 节点。首先,我们需要在 master 节点上执行以下命令:

kubeadm init --apiserver-advertise-address=192.168.1.1 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16

其中:

  • --apiserver-advertise-address:指定 master 节点的 IP 地址
  • --service-cidr:指定 Service 的 IP 范围
  • --pod-network-cidr:指定 Pod 的 IP 范围

执行成功后,我们将得到一个类似于这样的输出:

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.1:6443 --token v2askn.hb6xc8wsy010o7be \
    --discovery-token-ca-cert-hash sha256:XXXX

我们需要根据输出内容进行下一步的操作。在本例中,我们需要执行以下两个命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

接下来,我们需要在 master 节点上部署网络插件。网络插件的作用是提供跨节点的网络通信,使得 Pod 可以在集群中互相通信。

本例中,我们使用 Flannel 作为网络插件。我们可以通过以下命令部署 Flannel:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

到此为止,我们已经完成了 master 节点的部署。现在,我们需要部署 worker 节点。

1.3 部署 worker 节点

我们可以通过 kubeadm join 命令将 worker 节点加入到 Kubernetes 集群中。这个命令在 master 节点初始化输出中已经给出了,我们只需要在 node 节点上执行命令即可。例如:

kubeadm join 192.168.1.1:6443 --token v2askn.hb6xc8wsy010o7be \
    --discovery-token-ca-cert-hash sha256:XXXX

其中的 token 和 hash 在 master 节点初始化输出中已经给出了。

部署完 worker 节点后,我们可以使用 kubectl get nodes 命令检查集群中的节点是否可用:

$ kubectl get nodes
NAME                                      STATUS   ROLES    AGE   VERSION
kubernetes-node-1                         Ready    <none>   10m   v1.18.0
kubernetes-node-2                         Ready    <none>   9m    v1.18.0
kubernetes-node-3                         Ready    <none>   8m    v1.18.0

2. 部署应用

现在我们已经成功地部署了 Kubernetes 集群,接下来我们需要部署我们的应用。

2.1 构建 Docker 镜像

我们需要先在本地机器上构建 Docker 镜像,并推送到私有仓库中。这里以一个简单的 Nginx 为例:

FROM nginx:1.15-alpine

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

构建命令为:

docker build -t registry.example.com/nginx:1.0 .

推送到私有仓库:

docker push registry.example.com/nginx:1.0

2.2 创建 Kubernetes Deployment 和 Service

在 Kubernetes 中,Deployment 是一个基本的控制器,它用于控制 Pod 的数量和版本。Service 则是一组 Pod 的抽象,提供一个固定 IP 和 DNS 域名,使得其他 Pod 可以通过它来访问这组 Pod。

我们可以使用以下 YAML 文件创建 Deployment 和 Service(注意将 image 替换为自己构建的镜像):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.example.com/nginx:1.0
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - name: http
    port: 80
    targetPort: 80
  type: ClusterIP

创建命令:

kubectl apply -f nginx.yaml

然后我们可以使用 kubectl get pods 和 kubectl get services 命令来检查 Kubernetes 来确认部署是否成功。

2.3 部署 Ingress

Ingress 是 Kubernetes 中用于暴露 HTTP 和 HTTPS 服务的 API,它通过规则定义了如何路由到 Service,并提供了负载平衡和 SSL 终端的功能。

我们可以使用以下 YAML 文件创建 Ingress(注意将 host 替换为自己的域名):

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: http

创建命令:

kubectl apply -f ingress.yaml

2.4 部署 HPA

HPA(Horizontal Pod Autoscaler)是 Kubernetes 中的一个 API 对象,用于根据 CPU 或自定义指标自动扩展 Pod 的数量。

我们可以使用以下 YAML 文件创建 HPA:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-deployment
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 50

创建命令:

kubectl apply -f hpa.yaml

2.5 部署 Secret

在 Kubernetes 中,Secret 是一种用于保存敏感信息(如密码、证书等)的 API 对象。

我们可以使用以下命令创建 Secret:

kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=admin123

3. 常见问题

3.1 Docker Hub 的认证问题

在部署 Kubernetes 应用时,经常会遇到 Docker Hub 认证问题,这是由于默认情况下 Kubernetes 集群使用的是 kubeadm 配置中的 Docker 镜像,而该镜像需要有 Docker Hub 的认证才能使用。

解决方法是通过以下命令在 Kubernetes 集群中创建一个 secret:

kubectl create secret docker-registry my-secret \
   --docker-server=Docker Hub \
   --docker-username=username \
   --docker-password=password \
   --docker-email=email

其中 Docker Hub 对应的是 Docker Hub 的 URL,username 和 password 是 Docker Hub 的用户名和密码,email 是注册 Docker Hub 时使用的邮箱。

然后,在 Deployment 中指定该 secret:

spec:
  containers:
  - name: nginx
    image: registry.example.com/nginx:1.0
    imagePullPolicy: Always
  imagePullSecrets:
  - name: my-secret

3.2 每个节点上的 kubelet 启动失败

在部署 Kubernetes 集群时,有时会遇到每个节点上的 kubelet 启动失败的情况。这是由于 kubelet 使用了一个默认的 cgroup driver,而在某些系统上,这个 driver 可能会与系统配置冲突导致 kubelet 启动失败。

解决方法是手动指定一个合适的 cgroup driver。例如,在 Centos 7 上,我们可以将以下内容添加到 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 文件中:

[Service]
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"

4. 总结

本文详细介绍了 Kubernetes 集群部署的过程,包括准备工作、部署应用和常见问题。在实践中,我们需要仔细考虑每一个步骤,以避免遇到不必要的问题。希望这篇文章可以帮助读者更好地理解 Kubernetes 集群部署的过程。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a3b1a2add4f0e0ffbd5e49


纠错反馈