k8s入门实践: 部署前端nginx镜像,并配置ingress

833 阅读4分钟

重要名词的通俗解释

镜像(Image)相当于容器(Container)的模板,两者的关系可以看成是安装光盘和安装出来的系统。容器是一个独立的运行环境,包括各种依赖项(代码/库/运行时)。

Pod是最小运行单元,一个Pod里可以指定一个或多个Container,每个Container需要指定各自的Image,以及可能的卷/端口/环境变量等参数。

Deployment用来管理Pod,Pod和容器在Deployment中声明,Deployment还可以指定Pod的副本数量等信息。 Service为Pod提供网络服务,可以通过标签选择器绑定到一组Pod,并提供一个固定IP,以确保Pod在动态扩缩容时外部始终可以通过该IP访问。 Ingress管理 HTTP 和 HTTPS 路由,为集群外部提供对 Service 的访问。

创建nginx 配置

编写configMap,存放nginx相关配置。前端nginx项目镜像会将dist文件拷贝到data目录下,因此如下配置:

apiVersion: v1
data:
  default.conf: |
    server {
        listen   *:80;

        server_name *.bressanone.com;

        client_max_body_size 1G;

        location / {
          root   /data/;
          index  index.html index.htm;
          try_files $uri $uri/ /index.html;
          gzip on;
          gzip_min_length 1k;
          gzip_buffers 4 16k;
          gzip_http_version 1.1;
          gzip_comp_level 9;
          gzip_types text/plain application/x-javascript application/json text/css text/javascript application/x-httpd-php image/jpeg image/gif image/png application/javascript;
          gzip_vary on;
        }
    }
kind: ConfigMap
metadata:
  name: bressanone-web-frontend.conf
  namespace: bressanone

应用配置

kubectl apply -f bressanone-web-frontend.conf.yaml

创建前端服务

编写deployment.yaml,部署前端nginx服务

kind: Deployment
apiVersion: apps/v1
metadata:
  name: bressanone-web-frontend
  namespace: bressanone
  annotations:
    description: bressanone-前端
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bressanone-web-frontend
  template:
    metadata:
      labels:
        app: bressanone-web-frontend
    spec:
      containers:
        - name: bressanone-web-frontend
          image: your-image-registry/image
          env:
            - name: PAAS_APP_NAME
              value: bressanone-web-frontend
            - name: PAAS_NAMESPACE
              value: bressanone
          resources:
            limits:
              memory: 512Mi
            requests:
              memory: 512Mi
          volumeMounts:
            - name: localtime
              readOnly: true
              mountPath: /etc/localtime
            - name: bressanone-web-nginx-conf
              readOnly: true
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: default.conf
          imagePullPolicy: Always
      volumes:
        - name: localtime
          hostPath:
            path: /etc/localtime
            type: ""
        - name: bressanone-web-nginx-conf
          configMap:
            defaultMode: 420
            name: bressanone-web-frontend.conf
      imagePullSecrets:
        - name: ***

应用配置

kubectl apply -f deployment.yaml

创建service

piVersion: v1
kind: Service
metadata:
  name: bressanone-web-frontend-service
spec:
  selector:
    app: bressanone-web-frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

应用配置

kubectl apply -f service.yaml

openssl 生成SSL证书

  1. 生成私钥文件
openssl genrsa -out private.key 2048
  1. 生成证书签发请求文件
openssl req -new -key private.key -out certificate.csr

这一步会要求输入国家/地区等信息,其中Comon Name 需要设置为 目标域名 3. 生成自签名SSL证书

openssl x509 -req -days 365 -in certificate.csr -signkey private.key -out certificate.crt

创建tls secret

kubectl create secret tls bressanone-tls -secret --key private.key --cert certificate.crt -n muh

创建ingress 配置

编写ingress.yaml,设置路由转发

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: bressanone-ingress
  namespace: bressanone
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - bressanone.com  
      secretName: bressanone-tls
  rules:
    - host: bressanone.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: bressanone-web-frontend-svc
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: bressanone-backend-svc
                port:
                  number: 8080

应用配置

kubectl apply -f ingress.yaml

本地验证

在集群中可以通过curl对应域名,查看是否能返回前端文件内容。

在本地电脑,可以通过ifconfig查看主机ip,修改host文件,将该ip映射到对应域名,访问网站。

问题排查

ingress 配置不生效

首先检查是否已经部署了ingress 控制器

kubectl get pods -A | grep ingress

如果没有输出ingress-nginx-controller的pod,那就需要先部署ingress controller

部署ingress controller

curl -O https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

kubectl apply -f deploy.yaml

deploy.yaml里的镜像需要替换为国内的源,否则很容易部署失败,出现ImagePullBackOff的错误。

此外,deploy.yaml里创建的service,需要把类型改成NodePort

如果部署失败,可以通过以下命令查看日志

kubectl logs <pod-name> -n <namespace>

tls配置不生效

如果tls配置没生效,访问网站,https的证书会显示Kubernetes Ingress Controller Fake Certificate

image.png

可能的原因有tls的hosts配置或secretName配置错误,hosts中的域名和证书中的域名不符合等。

可以通过logs命令查看ingress的日志,查看是否有tls相关日志。

kubectl logs -n ingress-nginx <ingress-nginx-pod-name>

常用命令

创建更新资源

# 创建/更新资源
kubectl apply -f <file-or-directory-path>
# 对于没有yaml文件的资源,可以直接使用edit命令,执行后k8s会自动更新
kubectl edit <resource-type>/<resource-name> [options]

参数-A是查看所有,可以替换成-n <namespace>查看特定命名空间的

查看集群

# 查看当前上下文(集群、命名空间、用户)
kubectl config current-context
# 检查集群信息
kubectl cluster-info

查看节点

# 查看集群中的节点及其状态
kubectl get nodes
# 查看节点的详细信息
kubectl describe node <node-name>

查看命名空间

# 列出集群中的命名空间
kubectl get namespaces

查看资源

# 查看所有资源
kubectl get all -n <namespace>
# 查看所有 Pod
kubectl get pods -A
# 查看所有 Service
kubectl get svc -A
# 查看所有 Deployment
kubectl get deployments -A
# 查看所有 Ingress
kubectl get ingress -A
# 列出所有资源类型
kubectl api-resources
# 查看集群的资源使用情况
kubectl top nodes
kubectl top pods -A

查看pod

# 查看 Pod 的详细信息
kubectl describe pod <pod-name> -n <namespace>
# 查看 Pod 的日志
kubectl logs <pod-name> -n <namespace>
# 实时查看日志
kubectl logs -f <pod-name> -n <namespace>
# 在 Pod 中执行命令
kubectl exec -it <pod-name> -n <namespace> -- /bin/bash

检查集群事件

kubectl get events -A

检查存储和卷信息

kubectl get pv

其他

# 创建 Secret
kubectl create secret generic <secret-name> --from-literal=<key>=<value> -n <namespace>