Cluster information:
Kubernetes version: v1.32.3
Cloud being used: bare metal
Installation method: kubeadm
Host OS: Ubuntu 20
CNI and version: Calico v3.25.0
CRI and version: Not sure, but containerd --version
shows 1.7.24
It’s been around a month or more that I’m struggling this issue and it’s really driving me crazy:(
What I’m looking for
Deploying a simple WordPress application on K8S cluster on port 80 (not any other NodePort ports) and only on specific domain (like wp.saeed.com).
These are steps I did so far (and as I googled and used AIs also):
-
Installed K8S cluster using
apt install -y kubelet kubectl kubeadm
on one worker and one master (that’s for testing only, but I can increase server numbers if needed). Both can see each other andkubectl get nodes
shows bothReady
. -
Run these commands on master:
kubeadm init --control-plane-endpoint="$(hostname)" --upload-certs --pod-network-cidr=192.168.0.0/16
mkdir -p $HOME/.kube
ln -sf /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml
ssh -n worker1 "mkdir -pv $HOME/.kube"
rsync /etc/kubernetes/admin.conf worker1:$HOME/.kube/config
token=$(kubeadm token create --print-join-command)
ssh -n worker1 "$token"
sleep 15
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
kubectl wait --namespace metallb-system \
--for=condition=ready pod \
--selector=app=metallb \
--timeout=90s
sleep 30
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml
sleep 30
cat <<EOF > /root/metallb.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- 192.168.100.10/32
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default-l2
namespace: metallb-system
spec:
ipAddressPools:
- default-pool
interfaces:
- $(ip a | grep $(hostname -I | awk -F ' ' '{print $1}') | awk -F ' ' '{print $NF}')
EOF
kubectl apply -f /root/metallb.yaml
rm -vf /root/metallb.yaml
That’s how I run a cluster, deploying ingress-controller
, calico
and metallb
.
I use metallb
because I have a dedicated server with some IPs (let’s suppose my public available IPs are 192.168.100.10-192.168.100.20
).
I specified 192.168.100.11
to the master as fixed IP in netplan
file, and 192.168.100.12
to the worker as Floating IP (I mean this IP is not shown in the ip a
output command).
Both worker and master are in a private network 10.10.73.0/24
that can see and ping each other.
Master has two IPs: private and public, while worker has one private only.
- After setting everything up, I do these:
- create namespace
- create role_based_authorization (rbac) to ensure every namespace can only see its things:
"rules": [
{
"apiGroups": [""],
"resources": ["pods", "services", "deployments"],
"verbs": ["get", "list", "watch", "create", "update", "patch", "delete"]
}
]
- create RoleBinding
- create deployment on that namespace, and application like
wordpress
, andcontainerPort: 80
- create service like this:
if self.create_service:
service_manifest = {
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": self.name,
"namespace": self.namespace.name
},
"spec": {
"type": "ClusterIP",
"selector": {
"app": self.name
},
"ports": [
{
"protocol": "TCP",
"port": self.application.port,
"targetPort": self.application.port
}
]
}
}
- create ingress on that namespace, with things like:
ingress_manifest = {
"apiVersion": "networking.k8s.io/v1",
"kind": "Ingress",
"metadata": {
"name": f"{self.name}-ingress",
"namespace": self.namespace.name,
"annotations": {
"nginx.ingress.kubernetes.io/rewrite-target": "/"
}
},
"spec": {
'ingressClassName': 'nginx',
"rules": [
{
"host": self.domain,
"http": {
"paths": [
{
"path": "/",
"pathType": "Prefix",
"backend": {
"service": {
"name": self.name,
"port": {
"number": self.application.port
}
}
}
}
]
}
}
]
}
}
I also edit /etc/hosts
to point domain to both worker or master IP, but wp.saeed.com
shows Connection Refused
.
Did I write enough information regarding the issue?
How can I reach what I’m looking for?