如何解决Hugo 静态网站部署到 kubernetes 并通过入口 404 错误暴露
我为我们的开发人员构建了一个包含静态内容的网站。本网站由不同类型的用户使用。员工、经销商和分机……我通过使用不同的配置和参数进行管理,如下所示。当我通过 localhost 网站访问时一切正常,在本地环境中作为容器运行,或者在 kubernetes 中作为 port-forward
Pod通过 traefik 入口暴露它们以在集群外访问,内容没有正确加载(似乎 css、js 等没有加载),我有一些 404 错误,如下所示。
我有两个不同的掌舵图,因为我有两个独立的 Pod 为不同类型的用户运行。我想要实现的是,通过 https://foo-example.com/employees
和 https://foo-example.com/dealers
等入口公开它们..
我应该如何修复我的入口?可能的根本原因是什么?
├── config/
│ ├── _default
│ │ └── config.toml
│ ├── dealers
│ ├── config.toml
│ └── params.yaml
│ └── employees
│ ├── config.toml
│ └── params.yaml
├── helm
│ └── charts
│ ├── docu-dealers
│ └── docu-employees
正如我上面提到的,当我为不同的受众类型构建图像时,如下我将其传递给 params.yaml,它可以正常工作,没有任何问题。同时,当我移植我的 pod 时,一切也正常。
kubectl port-forward docu-plaform-dealers-docu-dealers-777bbf99-xcwl4 -n docu-platform 8084:8081
kubectl port-forward docu-plaform-employees-docu-employees-69df858dcc-brd5g -n docu-platform 8083:8081
docker build --no-cache -t docu-platform-employees . --build-arg AUDIENCE=employees
docker run -p 8081:8081 --name docu-platform-employees -d docu-platform-employees
这是我的 dockerfile。
FROM alpine:latest as build
#Label maintainer for this dockerfile
LABEL maintainer="Semih Ural <semih.ural@daimler.com>"
#Set environment variable for hugo version and directory
ENV HUGO_VERSION=0.78.0 \
HUGO_SITE=/src/hugo
#Set arguments for run hugo
ARG AUDIENCE
RUN sed -i.bak 's+https://+http://+' /etc/apk/repositories
#Install dependencies
RUN apk --no-cache add \
curl \
git \
libc6-compat \
libstdc++ \
nodejs \
npm
#Create dir for hugo app
WORKDIR ${HUGO_SITE}
#create package.json
COPY package.json ./
#Install npm depedencies for scss
RUN npm install -D --save postcss
RUN npm install -D autoprefixer
RUN npm install -D --save postcss-cli
#Install hugo extended version
RUN curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz \
-o /tmp/hugo.tar.gz \
&& tar -xzf /tmp/hugo.tar.gz -C /tmp \
&& cp /tmp/hugo /usr/local/bin/ \
&& apk del curl git\
&& mkdir -p ${HUGO_SITE} \
&& rm -rf /tmp/*
#Copy hugo to container
COPY . ${HUGO_SITE}
#Build hugo with environment variable
RUN hugo -e ${AUDIENCE}
#Prepare nginx
FROM nginx:latest
COPY --from=build /src/hugo/public /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
RUN chgrp -R root /var/cache/nginx /var/run /var/log/nginx && \
chmod -R 770 /var/cache/nginx /var/run /var/log/nginx
#Fire up nginx
EXPOSE 8081
CMD ["nginx","-g","daemon off;"]
这是我的 nginx.conf
server {
listen 8081;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location = /status {
access_log off;
default_type text/plain;
add_header Content-Type text/plain;
return 200 “alive”;
}
location = /50x.html {
root /usr/share/nginx/html;
}
}
这是入口。
# Source: docu-dealers/templates/ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: RELEASE-NAME-docu-dealers
labels:
app.kubernetes.io/name: docu-dealers
app.kubernetes.io/instance: RELEASE-NAME
app.kubernetes.io/managed-by: Helm
helm.sh/chart: docu-dealers-0.1.0
traffic-type: external
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: foo-example.com
http:
paths:
- path: /dealers
backend:
serviceName: docu-plaform-dealers-docu-dealers
servicePort: 80
# Source: docu-employees/templates/ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: RELEASE-NAME-docu-employees
labels:
app.kubernetes.io/name: docu-employees
app.kubernetes.io/instance: RELEASE-NAME
app.kubernetes.io/managed-by: Helm
helm.sh/chart: docu-employees-0.1.0
traffic-type: external
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: foo-example.com
http:
paths:
- path: /employees
backend:
serviceName: docu-plaform-employees-docu-employees
servicePort: 80
解决方法
最简单的调试方法是将 traefik 置于调试模式。
命令行:
--accesslog
--log
--log.level=DEBUG
在此之后,您将获得 pod 的日志:
kubectl logs pod/traefik-XYZ-ABC -n namespace -f
第二个是使用 IngressRoutes 与 Ingress。 你可以在这里找到一个例子: https://github.com/sleighzy/k3s-traefik-v2-kubernetes-crd
你会使用这样的匹配:
match: Host(`foo.example.com`) && PathPrefix(`/dealers`)