Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 77 additions & 68 deletions platform/cluster/flux/apps/agents/agents-login/worker.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
# Pod-local resolver for the agents-login worker. Codex 0.141.x ships a musl
# static binary whose resolver ignores /etc/gai.conf and /etc/hosts for the
# failing auth.openai.com path; this CoreDNS sidecar strips AAAA at DNS level
# while forwarding every non-AAAA lookup to kube-dns.
apiVersion: v1
kind: ConfigMap
metadata:
name: agents-login-worker-coredns
namespace: agents-system
labels:
app.kubernetes.io/name: agents-login-worker
app.kubernetes.io/part-of: agents-login
data:
Corefile: |
.:53 {
errors
health :8080
ready :8181
template IN AAAA . {
rcode NOERROR
}
forward . 10.43.0.10
cache 30
}
---
# Private half of the portal. Owns the PTY that runs `claude setup-token` and
# `codex login --device`, captures credentials, and posts them to agents-api
# under a Lease lock. Single instance + Recreate so the Lease is never
Expand Down Expand Up @@ -33,6 +58,17 @@ spec:
spec:
serviceAccountName: agents-login-worker
automountServiceAccountToken: true
dnsPolicy: None
dnsConfig:
nameservers:
- 127.0.0.1
searches:
- agents-system.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: '5'
# The image is amd64-only (it bundles the Claude/Codex CLIs + node-pty and
# is not worth a QEMU arm64 build). Keep it off the arm64 Pi nodes, where
# it would ImagePullBackOff on "no match for platform in manifest".
Expand All @@ -45,74 +81,50 @@ spec:
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
# Codex 0.141.x ships a musl static binary. In this cluster IPv6 egress is
# unreachable, and musl ignores /etc/gai.conf, so auth.openai.com AAAA
# answers can make `codex login --device-auth` fail before it tries IPv4.
# Resolve A records at pod startup and mount a pod-local hosts file instead
# of using static hostAliases, which would stale when Cloudflare rotates IPs.
initContainers:
- name: codex-auth-hosts
image: ghcr.io/extratoast/personal-stack/agents-login:latest
imagePullPolicy: Always
command:
- node
- -e
- |
const dns = require('node:dns').promises;
const { writeFileSync } = require('node:fs');

const hosts = (process.env.CODEX_IPV4_HOSTS || 'auth.openai.com')
.split(/[\s,]+/)
.filter(Boolean);
const podIp = process.env.POD_IP || '127.0.0.1';
const hostname = process.env.HOSTNAME || 'agents-login-worker';
const lines = [
'# Kubernetes hosts file generated by codex-auth-hosts.',
'127.0.0.1\tlocalhost',
'::1\tlocalhost ip6-localhost ip6-loopback',
'fe00::0\tip6-localnet',
'fe00::0\tip6-mcastprefix',
'fe00::1\tip6-allnodes',
'fe00::2\tip6-allrouters',
`${podIp}\t${hostname}`,
'',
];

(async () => {
for (const host of hosts) {
const ips = await dns.resolve4(host);
if (ips.length === 0) {
throw new Error(`no A records for ${host}`);
}
for (const ip of ips) {
lines.push(`${ip}\t${host}`);
}
console.log(`resolved ${host}: ${ips.join(', ')}`);
}
writeFileSync('/generated-hosts/hosts', `${lines.join('\n')}\n`, { mode: 0o644 });
})().catch((err) => {
console.error(err);
process.exit(1);
});
env:
- name: CODEX_IPV4_HOSTS
value: auth.openai.com
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
containers:
- name: dns
image: registry.k8s.io/coredns/coredns:v1.12.1
imagePullPolicy: IfNotPresent
args:
- -conf
- /etc/coredns/Corefile
ports:
- name: dns-udp
containerPort: 53
protocol: UDP
- name: dns-tcp
containerPort: 53
protocol: TCP
securityContext:
runAsNonRoot: false
runAsUser: 0
runAsGroup: 0
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop: ['ALL']
add: ['NET_BIND_SERVICE']
volumeMounts:
- name: codex-auth-hosts
mountPath: /generated-hosts
containers:
- name: coredns-config
mountPath: /etc/coredns
readOnly: true
readinessProbe:
httpGet:
path: /ready
port: 8181
initialDelaySeconds: 1
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 20
resources:
requests:
cpu: 5m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi
- name: worker
image: ghcr.io/extratoast/personal-stack/agents-login:latest
imagePullPolicy: Always
Expand Down Expand Up @@ -151,10 +163,6 @@ spec:
capabilities:
drop: ['ALL']
volumeMounts:
- name: codex-auth-hosts
mountPath: /etc/hosts
subPath: hosts
readOnly: true
- name: home
mountPath: /home/agent
- name: tmp
Expand All @@ -177,8 +185,9 @@ spec:
cpu: 500m
memory: 512Mi
volumes:
- name: codex-auth-hosts
emptyDir: {}
- name: coredns-config
configMap:
name: agents-login-worker-coredns
- name: home
emptyDir: {}
- name: tmp
Expand Down