ローカル環境(kind)でingressを試す

はじめに

kind (kubernetes in docker)でIngressを作成したい場合、ingress controllerを使う必要があります。

しかし、ドキュメント通りに実行してもM1 macなどのApple シリコンでは動きません。

理由は hashicorp/http-echo が arm64に対応していないからです。

$ docker container run --rm hashicorp/http-echo:latest -text 'aaa'

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
runtime: failed to create new OS thread (have 2 already; errno=22)
fatal error: newosproc

runtime stack:
runtime.throw(0x6955a0, 0x9)
    /usr/local/go/src/runtime/panic.go:596 +0x95
runtime.newosproc(0xc420022000, 0xc420032000)
    /usr/local/go/src/runtime/os_linux.go:163 +0x18c
runtime.newm(0x6a4348, 0x0)
    /usr/local/go/src/runtime/proc.go:1628 +0x137
runtime.main.func1()
    /usr/local/go/src/runtime/proc.go:126 +0x36
runtime.systemstack(0x7cc200)
    /usr/local/go/src/runtime/asm_amd64.s:327 +0x79
runtime.mstart()
    /usr/local/go/src/runtime/proc.go:1132

goroutine 1 [running]:
runtime.systemstack_switch()
    /usr/local/go/src/runtime/asm_amd64.s:281 fp=0xc42001e788 sp=0xc42001e780
runtime.main()
    /usr/local/go/src/runtime/proc.go:127 +0x6c fp=0xc42001e7e0 sp=0xc42001e788
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc42001e7e8 sp=0xc42001e7e0

今回はM1 Macでも動くように、修正します

クラスターを作成する

kind-config.yaml

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: ingress-nginx
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
$ kind create cluster --config kind-config.yaml
$ kind get clusters
ingress-nginx

$ kubectl config current-context
kind-ingress-nginx

ingress-nginxをapplyする

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

$ kubectl get pod -n ingress-nginx        
NAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-8m6zg       0/1     Completed   0          35m
ingress-nginx-admission-patch-rc9bm        0/1     Completed   1          35m
ingress-nginx-controller-6bccc5966-249gx   1/1     Running     0          35m

$ kubectl api-resources | grep ingress
ingressclasses                                 networking.k8s.io/v1                   false        IngressClass
ingresses                         ing          networking.k8s.io/v1                   true         Ingress

$ kubectl get ingressclasses -n ingress-nginx
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       37m

$ kubectl get ingressclasses -n ingress-nginx nginx -o yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.k8s.io/v1","kind":"IngressClass","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"controller","app.kubernetes.io/instance":"ingress-nginx","app.kubernetes.io/name":"ingress-nginx","app.kubernetes.io/part-of":"ingress-nginx","app.kubernetes.io/version":"1.5.1"},"name":"nginx"},"spec":{"controller":"k8s.io/ingress-nginx"}}
  creationTimestamp: "2022-11-11T14:16:22Z"
  generation: 1
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.5.1
  name: nginx
  resourceVersion: "1550"
  uid: 9ed127ea-e3e3-4051-910e-0486d1e9c53a
spec:
  controller: k8s.io/ingress-nginx

http-echoのイメージを作成する

ドキュメントのUsing Ingress ではPodやServiceをapplyすることになるのですが、先ほどお伝えしたようにM1 macではエラーになるので、イメージをhttp-echoのコードから作成します。

Dockerfile

FROM golang:1.19.3-bullseye as build
RUN git clone https://github.com/hashicorp/http-echo.git
RUN cd http-echo && CGO_ENABLED=0 go build

FROM gcr.io/distroless/static-debian11:debug
COPY --from=build /go/http-echo/http-echo /
ENTRYPOINT [ "/http-echo" ]
$ docker build . -t http-echo:0.0.1

$ docker image ls http-echo        
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
http-echo    0.0.1     500c71506129   3 days ago   9.86MB

クラスターにイメージを入れる

自分でbuildしたイメージをPodに指定して使用するには、 kind load docker-image コマンドを使ってクラスターにイメージを渡します

$ kind load docker-image http-echo:0.0.1 --name ingress-nginx
$ docker exec -it ingress-nginx-control-plane crictl images | grep http-echo
docker.io/library/http-echo                          0.0.1                500c71506129b       11.4MB

Loading an Image Into Your Cluster

Ingressを作成する

Using Ingressからマニフェストをコピーしてimageを変更します

app.yaml

kind: Pod
apiVersion: v1
metadata:
  name: foo-app
  labels:
    app: foo
spec:
  containers:
  - name: foo-app
 # image: hashicorp/http-echo:0.2.3 ではなく http-echo:0.0.1に変更
    image: http-echo:0.0.1
    args:
    - "-text=foo"
---
kind: Service
apiVersion: v1
metadata:
  name: foo-service
spec:
  selector:
    app: foo
  ports:
  # Default port used by the image
  - port: 5678
---
kind: Pod
apiVersion: v1
metadata:
  name: bar-app
  labels:
    app: bar
spec:
  containers:
  - name: bar-app
 # image: hashicorp/http-echo:0.2.3 ではなく http-echo:0.0.1に変更
    image: http-echo:0.0.1
    args:
    - "-text=bar"
---
kind: Service
apiVersion: v1
metadata:
  name: bar-service
spec:
  selector:
    app: bar
  ports:
  # Default port used by the image
  - port: 5678
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - http:
      paths:
      - pathType: Prefix
        path: "/foo"
        backend:
          service:
            name: foo-service
            port:
              number: 5678
      - pathType: Prefix
        path: "/bar"
        backend:
          service:
            name: bar-service
            port:
              number: 5678
---
$ kubectl apply  -f app.yaml

$ kubectl get pod                 
NAME      READY   STATUS    RESTARTS   AGE
bar-app   1/1     Running   0          26s
foo-app   1/1     Running   0          26s

動作確認

$ curl localhost/foo
foo

$ curl localhost/bar
bar

M1 Macでも無事動くことが確認できました。

クラスター削除

$ kind delete cluster --name ingress-nginx