Skip to content

Commit 251cca4

Browse files
committed
Add setup rancher and harvester in air-gapped environment
Signed-off-by: Frank Yang <[email protected]>
1 parent eb0f87a commit 251cca4

File tree

2 files changed

+277
-0
lines changed

2 files changed

+277
-0
lines changed

docs/airgap.md

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,283 @@ This section describes how to use Harvester in an air gapped environment. Some u
1212

1313
The Harvester ISO image contains all the packages to make it work in an air gapped environment.
1414

15+
## Working without HTTP Proxy
16+
17+
In this example, we use KVM to provision Harvester and integrate it with Rancher.
18+
19+
### Setup offline Harvester
20+
21+
1. Clone [harvester/ipxe-examples](https://github.com/harvester/ipxe-examples).
22+
1. Go to `vagrant-pxe-harvester` folder.
23+
1. Edit [settings.yml](https://github.com/harvester/ipxe-examples/blob/c8267b6270660255bf71149a1fef3a7a914550de/vagrant-pxe-harvester/settings.yml#L44) and set `offline: true`.
24+
1. Execute [setup_harvester.sh](https://github.com/harvester/ipxe-examples/blob/main/vagrant-pxe-harvester/setup_harvester.sh) script.
25+
26+
### Deploy Rancher on k3s and setup private registry in another VM.
27+
28+
1. Create another KVM with two network interfaces `harvester` and `vagrant-libvirt`. `harvester` network interface is for intranet and `vagrant-libvirt` is for internet. We need `vagrant-libvirt` to download all required resources. We will remove it before we start Rancher. Also, please give this VM at least 300GB to save all required images.
29+
1. Install [Docker](https://www.docker.com/) and [Helm](https://helm.sh/).
30+
1. Create `certs` folder.
31+
```
32+
mkdir -p certs
33+
```
34+
1. Generate private registry certificate files.
35+
```
36+
openssl req \
37+
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
38+
-addext "subjectAltName = DNS:myregistry.local" \
39+
-x509 -days 365 -out certs/domain.crt
40+
```
41+
1. Move certificate files to `/etc/docker/certs.d`.
42+
```
43+
sudo mkdir -p /etc/docker/certs.d/myregistry.local:5000
44+
sudo cp certs/domain.crt /etc/docker/certs.d/myregistry.local:5000/domain.crt
45+
```
46+
1. Start private registry.
47+
```
48+
docker run -d \
49+
-p 5000:5000 \
50+
--restart=always \
51+
--name registry \
52+
-v "$(pwd)"/certs:/certs \
53+
-v "$(pwd)"/registry:/var/lib/registry \
54+
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
55+
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
56+
registry:2
57+
```
58+
1. Add `myregistry.local` to `/etc/hosts`. Remember to change `192.168.0.50` to your private ip.
59+
```
60+
# vim /etc/hosts
61+
192.168.0.50 myregistry.local
62+
```
63+
1. Create `get-rancher` script.
64+
```
65+
# vim get-rancher
66+
#!/bin/bash
67+
if [[ $# -eq 0 ]] ; then
68+
echo 'This requires you to pass a version for the url like "v2.6.4"'
69+
exit 1
70+
fi
71+
wget https://github.com/rancher/rancher/releases/download/$1/rancher-images.txt
72+
wget https://github.com/rancher/rancher/releases/download/$1/rancher-load-images.sh
73+
wget https://github.com/rancher/rancher/releases/download/$1/rancher-save-images.sh
74+
chmod +x ./rancher-save-images.sh
75+
chmod +x ./rancher-load-images.sh
76+
```
77+
1. Make `get-rancher` script be excutable.
78+
```
79+
chmod +x get-rancher
80+
```
81+
1. Download `rancher-images.txt`, `rancher-load-images.sh` and `rancher-save-images.sh`.
82+
```
83+
./get-rancher v2.6.4
84+
```
85+
1. Add cert-manager images to `rancher-images.txt`.
86+
```
87+
helm repo add jetstack https://charts.jetstack.io/
88+
helm repo update
89+
helm fetch jetstack/cert-manager --version v1.7.1
90+
helm template ./cert-manager-v1.7.1.tgz | awk '$1 ~ /image:/ {print $2}' | sed s/\"//g >> ./rancher-images.txt
91+
```
92+
1. Sort `rancher-images.txt`.
93+
```
94+
sort -u rancher-images.txt -o rancher-images.txt
95+
```
96+
1. Get images. This step may take 1 to 2 hours. It depends on your network speed.
97+
```
98+
./rancher-save-images.sh --image-list ./rancher-images.txt
99+
```
100+
1. Create `get-k3s` script.
101+
```
102+
# vim get-k3s
103+
#!/bin/bash
104+
if [[ $# -eq 0 ]] ; then
105+
echo 'This requires you to pass a version for the url like "v1.23.4+k3s1"'
106+
exit 1
107+
fi
108+
wget https://github.com/k3s-io/k3s/releases/download/$1/k3s-airgap-images-amd64.tar
109+
wget https://github.com/k3s-io/k3s/releases/download/$1/k3s
110+
wget https://get.k3s.io/ -O install.sh
111+
chmod +x ./k3s
112+
chmod +x ./install.sh
113+
```
114+
1. Make `get-k3s` be excutable.
115+
```
116+
chmod +x get-kes
117+
```
118+
1. Download `k3s-airgap-images-amd64.tar`, `k3s` and `install.sh`.
119+
```
120+
./get-k3s v1.23.4+k3s1
121+
```
122+
1. Download Rancher.
123+
```
124+
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
125+
helm fetch rancher-latest/rancher --version=v2.6.4
126+
```
127+
1. Download `cert-manager-crds.yaml`.
128+
```
129+
mkdir cert-manager
130+
curl -L -o cert-manager/cert-manager-crd.yaml https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.crds.yaml
131+
```
132+
1. Remove `vagrant-libvirt` network interface. We've downloaded all required resources. We can cut network from this step.
133+
1. Move `k3s-airgap-images-amd64.tar` to `/var/lib/rancher/k3s/agent/images/`.
134+
```
135+
sudo mkdir -p /var/lib/rancher/k3s/agent/images/
136+
sudo cp k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/agent/images/
137+
```
138+
1. Create `/etc/rancher/k3s` folder.
139+
```
140+
mkdir -p /etc/rancher/k3s
141+
```
142+
1. Add `registries.yaml` to `/etc/rancher/k3s`.
143+
```
144+
# vim /etc/rancher/k3s/registries.yaml
145+
mirrors:
146+
docker.io:
147+
endpoint:
148+
- "https://myregistry.local:5000/"
149+
configs:
150+
"myregistry.local:5000":
151+
tls:
152+
insecure_skip_verify: true
153+
```
154+
1. Install k3s.
155+
```
156+
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
157+
```
158+
1. Generate cert-manager YAML files.
159+
```
160+
helm template cert-manager ./cert-manager-v1.7.1.tgz --output-dir . \
161+
--namespace cert-manager \
162+
--set image.repository=myregistry.local:5000/quay.io/jetstack/cert-manager-controller \
163+
--set webhook.image.repository=myregistry.local:5000/quay.io/jetstack/cert-manager-webhook \
164+
--set cainjector.image.repository=myregistry.local:5000/quay.io/jetstack/cert-manager-cainjector \
165+
--set startupapicheck.image.repository=myregistry.local:5000/quay.io/jetstack/cert-manager-ctl
166+
```
167+
1. Move `/etc/rancher/k3s/k3s.yaml` to `~/.kube`.
168+
```
169+
mkdir ~/.kube
170+
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
171+
sudo chown $USER ~/.kube/config
172+
export KUBECONFIG=~/.kube/config
173+
```
174+
1. Install cert-manager.
175+
```
176+
kubectl create namespace cert-manager
177+
kubectl apply -f cert-manager/cert-manager-crd.yaml
178+
kubectl apply -R -f ./cert-manager
179+
```
180+
1. Create CA private key and certifacate file.
181+
```
182+
openssl genrsa -out cakey.pem 2048
183+
openssl req -x509 -sha256 -new -nodes -key cakey.pem -days 3650 -out cacerts.pem -subj "/CN=cattle-ca"
184+
```
185+
1. Create `openssl.cnf`. Remember to change `192.168.0.50` to your private ip.
186+
```
187+
[req]
188+
req_extensions = v3_req
189+
distinguished_name = req_distinguished_name
190+
[req_distinguished_name]
191+
[ v3_req ]
192+
basicConstraints = CA:FALSE
193+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
194+
extendedKeyUsage = clientAuth, serverAuth
195+
subjectAltName = @alt_names
196+
[alt_names]
197+
DNS.1 = myrancher.local
198+
IP.1 = 192.168.0.50
199+
```
200+
1. Generate private key and certificate file for `myrancher.local`.
201+
```
202+
openssl genrsa -out tls.key 2048
203+
openssl req -sha256 -new -key tls.key -out tls.csr -subj "/CN=myrancher.local" -config openssl.cnf
204+
openssl x509 -sha256 -req -in tls.csr -CA cacerts.pem \
205+
-CAkey cakey.pem -CAcreateserial -out tls.crt \
206+
-days 3650 -extensions v3_req \
207+
-extfile openssl.cnf
208+
```
209+
1. Create `cattle-system` namespace.
210+
```
211+
kubectl create ns cattle-system
212+
```
213+
1. Create `tls.sa` secret.
214+
```
215+
kubectl -n cattle-system create secret generic tls-ca \
216+
--from-file=cacerts.pem=./cacerts.pem
217+
```
218+
1. Create `tls-rancher-ingress` secret.
219+
```
220+
kubectl -n cattle-system create secret tls tls-rancher-ingress \
221+
--cert=tls.crt \
222+
--key=tls.key
223+
```
224+
1. Generate Rancher YAML files.
225+
```
226+
helm template rancher ./rancher-2.6.4.tgz --output-dir . \
227+
--no-hooks \
228+
--namespace cattle-system \
229+
--set hostname=myrancher.local \
230+
--set rancherImageTag=v2.6.4 \
231+
--set rancherImage=myregistry.local:5000/rancher/rancher \
232+
--set systemDefaultRegistry=myregistry.local:5000 \
233+
--set useBundledSystemChart=true \
234+
--set ingress.tls.source=secret \
235+
--set privateCA=true
236+
```
237+
1. Install Rancher.
238+
```
239+
kubectl -n cattle-system apply -R -f ./rancher
240+
```
241+
1. Add `myrancher.local` to `/etc/hosts`. Remember to change `192.168.0.50` to your private ip.
242+
```
243+
# vim /etc/hosts
244+
192.168.0.50 myregistry.local myrancher.local
245+
```
246+
247+
### Integrate Harvester with Rancher in air-gapped environment
248+
249+
1. (Harvester VM) Add `myregistry.local` to `/etc/hosts`. Remember to change `192.168.0.50` to your private ip.
250+
```
251+
# vim /etc/hosts
252+
192.168.0.50 myregistry.local
253+
```
254+
1. (Harvester VM) Add `registries.yaml` to `/etc/rancher/rke2/`.
255+
```
256+
# vim /etc/rancher/rke2/registries.yaml
257+
mirrors:
258+
docker.io:
259+
endpoint:
260+
- "https://myregistry.local:5000"
261+
configs:
262+
"myregistry.local:5000":
263+
tls:
264+
insecure_skip_verify: true
265+
```
266+
1. (Harvester VM) Restart RKE2.
267+
```
268+
systemctl restart rke2-server.service
269+
```
270+
1. (Harvester VM) Update `rke2-coredns-rke2-coredns` ConfigMap.
271+
```
272+
# replace data like following
273+
data:
274+
Corefile: ".:53 {\n errors \n health {\n lameduck 5s\n }\n ready
275+
\n kubernetes cluster.local cluster.local in-addr.arpa ip6.arpa {\n pods
276+
insecure\n fallthrough in-addr.arpa ip6.arpa\n ttl 30\n }\n prometheus
277+
\ 0.0.0.0:9153\n hosts /etc/coredns/customdomains.db myrancher.local {\n
278+
\ fallthrough\n }\n forward . /etc/resolv.conf\n cache 30\n loop
279+
\n reload \n loadbalance \n}"
280+
customdomains.db: |
281+
192.168.0.50 myrancher.local
282+
```
283+
1. (Harvester VM) Update `rke2-coredns-rke2-coredns` Deployment.
284+
```
285+
# Add customdomains.db to volumes
286+
- key: customdomains.db
287+
path: customdomains.db
288+
```
289+
![rke2-dns-customdomains.db](./assets/rke2-dns-customdomains.db.png)
290+
1. Follow [Rancher Integration](./rancher/rancher-integration.md) to import Harvester to Rancher.
291+
15292
## Working Behind an HTTP Proxy
16293

17294
In some environments, the connection to external services, from the servers or VMs, requires an HTTP(S) proxy.
57.4 KB
Loading

0 commit comments

Comments
 (0)