Subsections of Networking
DNS Setup
Overview
For any self-hosted service to be accessible via browser, you need:
- A domain name (e.g.
72602.online) - DNS A records pointing each subdomain to your public IP
- (Optional) cert-manager for automatic TLS certificates
72602 Cluster DNS
All subdomains use A records β 47.110.67.161 (ECS public IP):
72602.online A 47.110.67.161
argocd.72602.online A 47.110.67.161
ops.docs.72602.online A 47.110.67.161
token.72602.space A 47.110.67.161
home.72602.online A 47.110.67.161
n8n.72602.online A 47.110.67.161
webhook.n8n.72602.online A 47.110.67.161
ops.agent.72602.online A 47.110.67.161
uptime.72602.space A 47.110.67.161
clash.72602.online A 47.110.67.161
api.minio.72602.online A 47.110.67.161
console.minio.72602.online A 47.110.67.161Add these records in your DNS provider (Cloudflare / Aliyun DNS / etc.).
Traffic Flow
Browser β A record β 47.110.67.161:443
β ECS sshd (reverse tunnel from minipc)
127.0.0.1:32443 (minipc ingress-nginx NodePort via SSH -R)
β ingress-nginx NodePort
k3s ingress controller
β Ingress rules
Service β PodTLS Certificates
With ingress-nginx + cert-manager, TLS is automatic:
- Install cert-manager (see
Installation/Networking/Cert_Manager.md) - Create a ClusterIssuer named
lets-encrypt - Each Ingress gets annotation
cert-manager.io/cluster-issuer: lets-encrypt - cert-manager automatically provisions TLS certificates via HTTP-01 challenge
β οΈ For clusters behind NAT/SSH reverse tunnel (like 72602), HTTP-01 validation requires the domain to resolve to the public IP and port 80/443 to reach the cluster. This works because ECS forwards 80/443 β minipc NodePort via SSH reverse tunnel (managed by autossh systemd services).
Prerequisites
Before deploying any app, ensure:
- Domain registered and DNS manageable
- k3s cluster running
- ingress-nginx installed (NodePort mode)
- cert-manager installed with
lets-encryptClusterIssuer - ArgoCD installed
- DNS A records added for each target subdomain
Install Cert Manager
Installation
Preliminary
1. Kubernetes is installed; if not, check πlink2. Helm binary is installed; if not, check πlink1.get helm repo
Details
helm repo add cert-manager-repo https://charts.jetstack.io
helm repo update2.install chart
Details
helm install cert-manager-repo/cert-manager --generate-name --version 1.20.2Using Mirror
helm repo add ay-helm-mirror https://aaronyang0628.github.io/helm-chart-mirror/charts \
&& helm install ay-helm-mirror/cert-manager --generate-name --version 1.20.2for more information, you can check πhttps://aaronyang0628.github.io/helm-chart-mirror/
Preliminary
1. Kubernetes is installed; if not, check πlink2. ArgoCD is installed; if not, check πlink3. Helm binary is installed; if not, check πlink1.prepare `cert-manager.yaml`
kubectl -n argocd apply -f https://raw.githubusercontent.com/AaronYang0628/docs/main/manifests/zjlab/cert-manager.yamlkubectl -n argocd apply -f - << EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
project: default
source:
repoURL: https://aaronyang0628.github.io/helm-chart-mirror/charts
chart: cert-manager
targetRevision: 1.20.2
helm:
releaseName: cert-manager
values: |
installCRDs: true
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-controller
tag: v1.20.2
webhook:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-webhook
tag: v1.20.2
cainjector:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-cainjector
tag: v1.20.2
acmesolver:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-acmesolver
tag: v1.20.2
startupapicheck:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-startupapicheck
tag: v1.20.2
destination:
server: https://kubernetes.default.svc
namespace: basic-components
EOFkubectl -n argocd apply -f - << EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
project: default
source:
repoURL: https://charts.jetstack.io
chart: cert-manager
targetRevision: 1.20.2
helm:
releaseName: cert-manager
values: |
installCRDs: true
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-controller
tag: v1.20.2
webhook:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-webhook
tag: v1.20.2
cainjector:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-cainjector
tag: v1.20.2
acmesolver:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-acmesolver
tag: v1.20.2
startupapicheck:
image:
repository: m.daocloud.io/quay.io/jetstack/cert-manager-startupapicheck
tag: v1.20.2
destination:
server: https://kubernetes.default.svc
namespace: basic-components
EOF2.sync by argocd
Details
argocd app sync argocd/cert-managerPreliminary
1. Docker|Podman|Buildah is installed; if not, check πlink1.just run
Details
docker run --name cert-manager -e ALLOW_EMPTY_PASSWORD=yes bitnami/cert-manager:latestUsing Proxy
you can run an addinational daocloud image to accelerate your pulling, check Daocloud Proxy
docker run --name cert-manager \
-e ALLOW_EMPTY_PASSWORD=yes
m.daocloud.io/docker.io/bitnami/cert-manager:latestPreliminary
1. Kubernetes is installed; if not, check πlink1.just run
Details
kubectl create -f https://github.com/jetstack/cert-manager/releases/download/v1.20.2/cert-manager.yamlPrepare Certificate Issuer
kubectl apply -f - <<EOF
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
namespace: basic-components
name: self-signed-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
namespace: basic-components
name: my-self-signed-ca
spec:
isCA: true
commonName: my-self-signed-ca
secretName: root-secret
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: self-signed-issuer
kind: Issuer
group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: self-signed-ca-issuer
spec:
ca:
secretName: root-secret
EOFkubectl apply -f - << EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: lets-encrypt
spec:
acme:
email: byang628@zhejianglab.org
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- http01:
ingress:
class: nginx
EOFkubectl -n kube-system apply -f - << EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: lets-encrypt
spec:
acme:
email: aaron19940628@gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- http01:
ingress:
class: nginx
EOFFAQ
FAQ
Install HAProxy
πInstallation
1.prepare ECS host and backups
ssh root@47.110.67.161 hostname
sudo ss -ltnp
sudo test -e /etc/haproxy || echo absentBack up /etc/haproxy before installing. Keep the backup outside tracked
source. The 72602 mail change also keeps the reverse-tunnel unit backup on
the minipc.
2.install Ubuntu package
sudo apt-get install --no-install-recommends haproxyDo not run upgrade, full-upgrade, or dist-upgrade. Ubuntu may start the
package service during installation; stop it before replacing the default
configuration and before the tunnel backends are ready.
3.configure TCP passthrough
/etc/haproxy/haproxy.cfg must use mode tcp, bind public IPv4 and IPv6
25, 465, 587, and 993, and send PROXY v2 to:
127.0.0.1:10225
127.0.0.1:10465
127.0.0.1:10587
127.0.0.1:10993Do not terminate TLS or configure HTTP, relay, or authentication in HAProxy. Validate before starting it:
haproxy -c -f /etc/haproxy/haproxy.cfg4.start after tunnel verification
# Confirm the four ECS loopback backends are sshd listeners first.
sudo ss -ltnp
sudo systemctl enable --now haproxy
sudo systemctl is-active haproxy
sudo systemctl is-enabled haproxy
sudo ss -ltnpThe public mail ports must belong to haproxy; only the four high ports on
127.0.0.1 may belong to the tunnel sshd.
5.rollback
sudo systemctl stop haproxy
# Restore the saved 10022 unit on 72602-minipc, daemon-reload, restart only 10022.Do not restore an old HAProxy configuration or uninstall the package as part of this rollback. Preserve Mailu Secrets and PVCs.
ποΈFAQ
Install Ingress
Installation
Preliminary
1. Kubernetes is installed; if not, check πlink2. Helm is installed; if not, check πlink1.get helm repo
Details
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update2.install chart
Details
helm install ingress-nginx/ingress-nginx --generate-nameUsing Mirror
helm repo add ay-helm-mirror https://aaronyang0628.github.io/helm-chart-mirror/charts &&
helm install ay-helm-mirror/ingress-nginx --generate-name --version 4.15.1for more information, you can check πhttps://aaronyang0628.github.io/helm-chart-mirror/
Preliminary
1. Kubernetes is installed; if not, check πlink2. ArgoCD is installed; if not, check πlink1.prepare `ingress-nginx.yaml`
```shell kubectl -n argocd apply -f https://raw.githubusercontent.com/AaronYang0628/docs/main/manifests/zjlab/ingress-nginx.yaml ```
Details
kubectl -n argocd apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ingress-nginx
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
project: default
source:
repoURL: https://kubernetes.github.io/ingress-nginx
chart: ingress-nginx
targetRevision: 4.15.1
helm:
releaseName: ingress-nginx
values: |
controller:
image:
registry: m.daocloud.io/registry.k8s.io
service:
enabled: true
type: NodePort
nodePorts:
http: 32080
https: 32443
tcp:
8080: 32808
5324: 33224 #pg
resources:
requests:
cpu: 100m
memory: 128Mi
admissionWebhooks:
enabled: true
patch:
enabled: true
image:
registry: m.daocloud.io/registry.k8s.io
metrics:
enabled: false
defaultBackend:
enabled: false
image:
registry: m.daocloud.io/registry.k8s.io
destination:
server: https://kubernetes.default.svc
namespace: basic-components
EOF[Optional] 2.apply to k8s
Details
kubectl -n argocd apply -f ingress-nginx.yaml3.sync by argocd
Details
argocd app sync argocd/ingress-nginxFAQ
Install Istio
Installation
Preliminary
1. Kubernetes is installed; if not, check πlink2. Helm is installed; if not, check πlink1.get helm repo
Details
helm repo add ay-helm-mirror https://aaronyang0628.github.io/helm-chart-mirror/charts
helm repo update2.install chart
Details
helm install ay-helm-mirror/kube-prometheus-stack --generate-nameUsing Proxy
for more information, you can check πhttps://artifacthub.io/packages/helm/prometheus-community/prometheus
Preliminary
1. Kubernetes is installed; if not, check πlink2. Helm is installed; if not, check πlink3. ArgoCD is installed; if not, check πlink1.prepare `deploy-istio-base.yaml`
Details
kubectl -n argocd apply -f - << EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: istio-base
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
project: default
source:
repoURL: https://istio-release.storage.googleapis.com/charts
chart: base
targetRevision: 1.23.2
helm:
releaseName: istio-base
values: |
defaults:
global:
istioNamespace: istio-system
base:
enableCRDTemplates: false
enableIstioConfigCRDs: true
defaultRevision: "default"
destination:
server: https://kubernetes.default.svc
namespace: istio-system
EOF2.sync by argocd
Details
argocd app sync argocd/istio-base3.prepare `deploy-istiod.yaml`
Details
kubectl -n argocd apply -f - << EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: istiod
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
project: default
source:
repoURL: https://istio-release.storage.googleapis.com/charts
chart: istiod
targetRevision: 1.23.2
helm:
releaseName: istiod
values: |
defaults:
global:
istioNamespace: istio-system
defaultResources:
requests:
cpu: 10m
memory: 128Mi
limits:
cpu: 100m
memory: 128Mi
hub: m.daocloud.io/docker.io/istio
proxy:
autoInject: disabled
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 2000m
memory: 1024Mi
pilot:
autoscaleEnabled: true
resources:
requests:
cpu: 500m
memory: 2048Mi
cpu:
targetAverageUtilization: 80
podAnnotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
destination:
server: https://kubernetes.default.svc
namespace: istio-system
EOF4.sync by argocd
Details
argocd app sync argocd/istiod5.prepare `deploy-istio-ingressgateway.yaml`
Details
kubectl -n argocd apply -f - << EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: istio-ingressgateway
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
project: default
source:
repoURL: https://istio-release.storage.googleapis.com/charts
chart: gateway
targetRevision: 1.23.2
helm:
releaseName: istio-ingressgateway
values: |
defaults:
replicaCount: 1
podAnnotations:
inject.istio.io/templates: "gateway"
sidecar.istio.io/inject: "true"
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 2000m
memory: 1024Mi
service:
type: LoadBalancer
ports:
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
- name: http2
port: 80
protocol: TCP
targetPort: 80
- name: https
port: 443
protocol: TCP
targetPort: 443
autoscaling:
enabled: true
minReplicas: 1
maxReplicas: 5
destination:
server: https://kubernetes.default.svc
namespace: istio-system
EOF6.sync by argocd
Details
argocd app sync argocd/istio-ingressgatewayPreliminary
1. Kubernetes is installed; if not, check πlink2. Helm is installed; if not, check πlink3. ArgoCD is installed; if not, check πlink4. Argo Workflow is installed; if not, check πlink1.prepare `argocd-login-credentials`
Details
kubectl get namespaces database > /dev/null 2>&1 || kubectl create namespace database2.apply rolebinding to k8s
Details
kubectl apply -f - <<EOF
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: application-administrator
rules:
- apiGroups:
- argoproj.io
resources:
- applications
verbs:
- '*'
- apiGroups:
- apps
resources:
- deployments
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: application-administration
namespace: argocd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: application-administrator
subjects:
- kind: ServiceAccount
name: argo-workflow
namespace: business-workflows
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: application-administration
namespace: application
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: application-administrator
subjects:
- kind: ServiceAccount
name: argo-workflow
namespace: business-workflows
EOF4.prepare `deploy-xxxx-flow.yaml`
Details
6.submit to argo workflow client
Details
argo -n business-workflows submit deploy-xxxx-flow.yaml7.decode password
Details
kubectl -n application get secret xxxx-credentials -o jsonpath='{.data.xxx-password}' | base64 -dFAQ
Install Nginx
1. prepare server.conf
cat << EOF > default.conf
server {
listen 80;
location / {
root /usr/share/nginx/html;
autoindex on;
}
}
EOF2. install
mkdir $(pwd)/data
podman run --rm -p 8080:80 \
-v $(pwd)/data:/usr/share/nginx/html:ro \
-v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf:ro \
-d docker.io/library/nginx:1.19.9-alpine
echo 'this is a test' > $(pwd)/data/some-data.txtTip
you can run an addinational daocloud image to accelerate your pulling, check Daocloud Proxy
visit http://localhost:8080