|
19 | 19 | env: |
20 | 20 | STARTING_K3S_VERSION: v1.34.3+k3s1 |
21 | 21 | UPGRADE_K3S_VERSION: v1.35.1+k3s1 |
| 22 | + SITE_UPGRADE_K3S_VERSION: v1.35.6+k3s1 |
22 | 23 | # K3s requires privileged containers to run inside Docker and access to cgrougs. |
23 | 24 | steps: |
24 | 25 | - name: Set container OS based on service manager |
@@ -138,6 +139,37 @@ jobs: |
138 | 139 | - name: Verify K3s upgraded on Agent |
139 | 140 | run: docker exec agent-node k3s --version | grep ${UPGRADE_K3S_VERSION} |
140 | 141 |
|
| 142 | + # Second upgrade, this time re-running site.yml with a bumped version: it |
| 143 | + # must upgrade the running runtime on both the server and the agent, not |
| 144 | + # just replace the on-disk binary. |
| 145 | + - name: Modify the k3s_version in inventory for a site.yml upgrade |
| 146 | + run: | |
| 147 | + sed -i "s/k3s_version: .*/k3s_version: ${SITE_UPGRADE_K3S_VERSION}/" tests/${{ matrix.inventory }}.yml |
| 148 | +
|
| 149 | + - name: Run site Playbook to upgrade via a version bump |
| 150 | + run: ansible-playbook playbooks/site.yml -i tests/${{ matrix.inventory }}.yml |
| 151 | + |
| 152 | + # The install script replaces the on-disk binary regardless of a restart, |
| 153 | + # so assert the running version the kubelet reports to the API: it only |
| 154 | + # advances once the service was actually restarted onto the new build. |
| 155 | + # This is what fails if the version-bump restart regresses. |
| 156 | + - name: Verify the running K3s version upgraded on Server and Agent |
| 157 | + run: | |
| 158 | + for node in server-node agent-node; do |
| 159 | + for attempt in 1 2 3 4 5 6; do |
| 160 | + running=$(docker exec server-node k3s kubectl get node "$node" -o jsonpath='{.status.nodeInfo.kubeletVersion}' 2>&1) |
| 161 | + echo "$node running version: $running" |
| 162 | + if echo "$running" | grep -q "${SITE_UPGRADE_K3S_VERSION}"; then |
| 163 | + break |
| 164 | + fi |
| 165 | + if [ "$attempt" -eq 6 ]; then |
| 166 | + echo "$node did not reach ${SITE_UPGRADE_K3S_VERSION}" |
| 167 | + exit 1 |
| 168 | + fi |
| 169 | + sleep 10 |
| 170 | + done |
| 171 | + done |
| 172 | +
|
141 | 173 | - name: Wait for all deployments to be ready |
142 | 174 | run: | |
143 | 175 | for attempt in 1 2 3 4 5 6; do |
@@ -324,6 +356,50 @@ jobs: |
324 | 356 | done |
325 | 357 | exit 1 |
326 | 358 |
|
| 359 | + # #485: re-running site.yml with a bumped version must upgrade every etcd |
| 360 | + # server, restarting them one at a time so the quorum is never lost. |
| 361 | + - name: Modify the k3s_version in inventory for a site.yml upgrade |
| 362 | + run: | |
| 363 | + sed -i 's/k3s_version: v1.34.1+k3s1/k3s_version: v1.34.3+k3s1/' tests/ha.yml |
| 364 | +
|
| 365 | + - name: Run site Playbook to upgrade the servers via a version bump |
| 366 | + run: ansible-playbook playbooks/site.yml -i tests/ha.yml |
| 367 | + |
| 368 | + # Assert the running (kubelet-reported) version, not the on-disk binary: |
| 369 | + # without a rolling restart the joined servers stay on the old runtime. |
| 370 | + - name: Verify the running K3s version upgraded on all servers via site.yml |
| 371 | + run: | |
| 372 | + docker exec server-node1 k3s kubectl get nodes -o wide |
| 373 | + for SERVER in $SERVERS; do |
| 374 | + for attempt in 1 2 3 4 5 6; do |
| 375 | + running=$(docker exec server-node1 k3s kubectl get node "$SERVER" -o jsonpath='{.status.nodeInfo.kubeletVersion}' 2>&1) |
| 376 | + echo "$SERVER running version: $running" |
| 377 | + if echo "$running" | grep -q v1.34.3; then |
| 378 | + break |
| 379 | + fi |
| 380 | + if [ "$attempt" -eq 6 ]; then |
| 381 | + echo "$SERVER did not reach v1.34.3" |
| 382 | + exit 1 |
| 383 | + fi |
| 384 | + sleep 10 |
| 385 | + done |
| 386 | + done |
| 387 | +
|
| 388 | + - name: Wait for all deployments to be ready after the site.yml upgrade |
| 389 | + run: | |
| 390 | + for attempt in 1 2 3 4 5 6; do |
| 391 | + echo "Attempt $attempt: checking deployments" |
| 392 | + output=$(docker exec server-node1 k3s kubectl get deployments -n kube-system -o jsonpath='{range .items[*]}{.metadata.name}={.status.readyReplicas}/{.spec.replicas}{"\n"}{end}' 2>&1) |
| 393 | + echo "$output" |
| 394 | + if ! echo "$output" | grep -q "<no value>" && echo "$output" | awk -F '[=/]' '{if ($2 != $3) exit 1}' ; then |
| 395 | + exit 0 |
| 396 | + fi |
| 397 | + if [ "$attempt" -lt 6 ]; then |
| 398 | + sleep 15 |
| 399 | + fi |
| 400 | + done |
| 401 | + exit 1 |
| 402 | +
|
327 | 403 | - name: Debug nodes/pods on failure |
328 | 404 | if: failure() |
329 | 405 | run: | |
|
0 commit comments