# Kubernetes - [Kubernetes](#kubernetes) - [Setup](#setup) - [MetalLB](#metallb) - [Ingress Nginx](#ingress-nginx) - [Cert Manager](#cert-manager) - [Storage](#storage) ## Setup ```bash pacman -S kubeadm kubelet containerd cni-plugins cilium-cli helm kubectl ``` /etc/modules-load.d/k8s.conf ```conf overlay br_netfilter ``` /etc/sysctl.d/k8s.conf ```conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 ``` /etc/containerd/config.toml ```toml [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true ``` ```bash reboot mkdir /etc/containerd containerd config default > /etc/containerd/config.toml systemctl enable --now containerd systemctl enable --now kubelet kubeadm init --pod-network-cidr='10.244.0.0/16' mkdir -p $HOME/.kube cp /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config cilium-cli install # Note the "-" at the end, this removes the taint kubectl taint node kube node-role.kubernetes.io/control-plane:NoSchedule- ``` ## MetalLB Install with helm: ```bash helm repo add metallb https://metallb.github.io/metallb helm install metallb metallb/metallb -n kube-system ``` You must create a production pool if IP Addresses. Apply the following config (substituting your public IP address space) ```yaml apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: production namespace: kube-system spec: # Production services will go here. Public IPs are expensive, so we leased # just 4 of them. addresses: - 192.168.122.206/32 ``` Here is an example service which allows IP sharing and uses the "production" address pool. ```yaml apiVersion: v1 kind: Service metadata: name: ingress-nginx-demo annotations: metallb.universe.tf/address-pool: production metallb.universe.tf/allow-shared-ip: "nginx" spec: type: LoadBalancer externalTrafficPolicy: Cluster selector: app.kubernetes.io/name: ingress-nginx-demo ports: - name: ingress-nginx-demo protocol: TCP port: 8000 targetPort: http ``` ## Ingress Nginx Now we need an ingress solution (preferably with certs for https). We'll be using nginx since it's a little bit more configurable than traefik (though don't sell traefik short, it's really good. Just finnicky when you have use cases they haven't explicitly coded for). ```bash helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm upgrade --install \ ingress-nginx \ ingress-nginx/ingress-nginx \ --values ingress-nginx-values.yaml \ --namespace ingress-nginx \ --create-namespace ``` ## Cert Manager Cert manager handles automatic TLS for our ingress with Let's Encrypt. Install with helm: ```bash helm repo add jetstack https://charts.jetstack.io helm repo update helm upgrade --install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.12.4 \ --set installCRDs=true ``` Now we need to create an issuer. Apply the following config: ```yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: nginx@ducoterra.net # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: nginx ``` Here's an example ingress definition: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-nginx-demo annotations: cert-manager.io/cluster-issuer: letsencrypt kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.org/client-max-body-size: "0" spec: rules: - host: ingress-nginx-demo.reeseapps.com http: paths: - path: / pathType: Prefix backend: service: name: ingress-nginx-demo port: number: 80 tls: - hosts: - ingress-nginx-demo.reeseapps.com secretName: ingress-nginx-demo-tls-cert ``` ## Storage We can use host-path storage immediately like so: ```yaml apiVersion: v1 kind: Pod metadata: name: test-webserver spec: containers: - name: test-webserver image: registry.k8s.io/test-webserver:latest volumeMounts: - mountPath: /var/local/aaa name: mydir - mountPath: /var/local/aaa/1.txt name: myfile volumes: - name: mydir hostPath: # Ensure the file directory is created. path: /var/local/aaa type: DirectoryOrCreate - name: myfile hostPath: path: /var/local/aaa/1.txt type: FileOrCreate ```