允许在 Kubernetes 上使用本地库中的图像

Enable use of images from the local library on Kubernetes

我正在学习教程 https://docs.openfaas.com/tutorials/first-python-function/,

目前,我有正确的图像

$ docker images | grep hello-openfaas
wm/hello-openfaas                                     latest                          bd08d01ce09b   34 minutes ago      65.2MB
$ faas-cli deploy -f ./hello-openfaas.yml 
Deploying: hello-openfaas.
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.

Deployed. 202 Accepted.
URL: http://IP:8099/function/hello-openfaas

有一个步骤警告我进行一些设置(我的情况是我正在使用 Kubernetesminikube 并且不想推送到远程容器注册表,我应该在 Kubernetes 上启用本地库中的图像。),我看到了提示

see the helm chart for how to set the ImagePullPolicy

我不确定如何正确配置它。最后的结果表明我失败了。

不出所料,我无法访问函数服务,我在 https://docs.openfaas.com/deployment/troubleshooting/#openfaas-didnt-start 中找到了一些线索,这可能有助于诊断问题。

$ kubectl logs -n openfaas-fn deploy/hello-openfaas
Error from server (BadRequest): container "hello-openfaas" in pod "hello-openfaas-558f99477f-wd697" is waiting to start: trying and failing to pull image

$ kubectl describe -n openfaas-fn deploy/hello-openfaas
Name:                   hello-openfaas
Namespace:              openfaas-fn
CreationTimestamp:      Wed, 16 Mar 2022 14:59:49 +0800
Labels:                 faas_function=hello-openfaas
Annotations:            deployment.kubernetes.io/revision: 1
                        prometheus.io.scrape: false
Selector:               faas_function=hello-openfaas
Replicas:               1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  0 max unavailable, 1 max surge
Pod Template:
  Labels:       faas_function=hello-openfaas
  Annotations:  prometheus.io.scrape: false
  Containers:
   hello-openfaas:
    Image:      wm/hello-openfaas:latest
    Port:       8080/TCP
    Host Port:  0/TCP
    Liveness:   http-get http://:8080/_/health delay=2s timeout=1s period=2s #success=1 #failure=3
    Readiness:  http-get http://:8080/_/health delay=2s timeout=1s period=2s #success=1 #failure=3
    Environment:
      fprocess:  python3 index.py
    Mounts:      <none>
  Volumes:       <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      False   MinimumReplicasUnavailable
  Progressing    False   ProgressDeadlineExceeded
OldReplicaSets:  <none>
NewReplicaSet:   hello-openfaas-558f99477f (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  29m   deployment-controller  Scaled up replica set hello-openfaas-558f99477f to 1

hello-openfaas.yml

version: 1.0
provider:
  name: openfaas
  gateway: http://IP:8099
functions:
  hello-openfaas:
    lang: python3
    handler: ./hello-openfaas
    image: wm/hello-openfaas:latest
    imagePullPolicy: Never

我创建了一个新项目hello-openfaas2来重现这个错误

$ faas-cli new --lang python3 hello-openfaas2 --prefix="wm"
Folder: hello-openfaas2 created.
# I add `imagePullPolicy: Never` to `hello-openfaas2.yml`
$ faas-cli build -f ./hello-openfaas2.yml 
$ faas-cli deploy -f ./hello-openfaas2.yml 
Deploying: hello-openfaas2.
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.

Deployed. 202 Accepted.
URL: http://192.168.1.3:8099/function/hello-openfaas2


$ kubectl logs -n openfaas-fn deploy/hello-openfaas2
Error from server (BadRequest): container "hello-openfaas2" in pod "hello-openfaas2-7c67488865-7d7vm" is waiting to start: image can't be pulled

$ kubectl get pods --all-namespaces
NAMESPACE              NAME                                        READY   STATUS             RESTARTS         AGE
kube-system            coredns-64897985d-kp7vf                     1/1     Running            0                47h
...
openfaas-fn            env-6c79f7b946-bzbtm                        1/1     Running            0                4h28m
openfaas-fn            figlet-54db496f88-957xl                     1/1     Running            0                18h
openfaas-fn            hello-openfaas-547857b9d6-z277c             0/1     ImagePullBackOff   0                127m
openfaas-fn            hello-openfaas-7b6946b4f9-hcvq4             0/1     ImagePullBackOff   0                165m
openfaas-fn            hello-openfaas2-7c67488865-qmrkl            0/1     ImagePullBackOff   0                13m
openfaas-fn            hello-openfaas3-65847b8b67-b94kd            0/1     ImagePullBackOff   0                97m
openfaas-fn            hello-python-554b464498-zxcdv               0/1     ErrImagePull       0                3h23m
openfaas-fn            hello-python-8698bc68bd-62gh9               0/1     ImagePullBackOff   0                3h25m

https://docs.openfaas.com/reference/yaml/,我知道我把imagePullPolicy放在了错误的地方,它的架构中没有这样的关键字。

我也试过eval $(minikube docker-env,但仍然出现同样的错误。


感觉faas-cli deploy可以换成helm,都是指运行Kubernetes集群中的镜像(无论是远程还是本地),那我可以使用 helm chart 在那里设置 pullPolicy。尽管我还不清楚细节,但这个发现启发了我。


到目前为止,在 eval $(minikube docker-env)

之后
$ docker images
REPOSITORY                                TAG        IMAGE ID       CREATED             SIZE
wm/hello-openfaas2                        0.1        03c21bd96d5e   About an hour ago   65.2MB
python                                    3-alpine   69fba17b9bae   12 days ago         48.6MB
ghcr.io/openfaas/figlet                   latest     ca5eef0de441   2 weeks ago         14.8MB
ghcr.io/openfaas/alpine                   latest     35f3d4be6bb8   2 weeks ago         14.2MB
ghcr.io/openfaas/faas-netes               0.14.2     524b510505ec   3 weeks ago         77.3MB
k8s.gcr.io/kube-apiserver                 v1.23.3    f40be0088a83   7 weeks ago         135MB
k8s.gcr.io/kube-controller-manager        v1.23.3    b07520cd7ab7   7 weeks ago         125MB
k8s.gcr.io/kube-scheduler                 v1.23.3    99a3486be4f2   7 weeks ago         53.5MB
k8s.gcr.io/kube-proxy                     v1.23.3    9b7cc9982109   7 weeks ago         112MB
ghcr.io/openfaas/gateway                  0.21.3     ab4851262cd1   7 weeks ago         30.6MB
ghcr.io/openfaas/basic-auth               0.21.3     16e7168a17a3   7 weeks ago         14.3MB
k8s.gcr.io/etcd                           3.5.1-0    25f8c7f3da61   4 months ago        293MB
ghcr.io/openfaas/classic-watchdog         0.2.0      6f97aa96da81   4 months ago        8.18MB
k8s.gcr.io/coredns/coredns                v1.8.6     a4ca41631cc7   5 months ago        46.8MB
k8s.gcr.io/pause                          3.6        6270bb605e12   6 months ago        683kB
ghcr.io/openfaas/queue-worker             0.12.2     56e7216201bc   7 months ago        7.97MB
kubernetesui/dashboard                    v2.3.1     e1482a24335a   9 months ago        220MB
kubernetesui/metrics-scraper              v1.0.7     7801cfc6d5c0   9 months ago        34.4MB
nats-streaming                            0.22.0     12f2d32e0c9a   9 months ago        19.8MB
gcr.io/k8s-minikube/storage-provisioner   v5         6e38f40d628d   11 months ago       31.5MB
functions/markdown-render                 latest     93b5da182216   2 years ago         24.6MB
functions/hubstats                        latest     01affa91e9e4   2 years ago         29.3MB
functions/nodeinfo                        latest     2fe8a87bf79c   2 years ago         71.4MB
functions/alpine                          latest     46c6f6d74471   2 years ago         21.5MB
prom/prometheus                           v2.11.0    b97ed892eb23   2 years ago         126MB
prom/alertmanager                         v0.18.0    ce3c87f17369   2 years ago         51.9MB
alexellis2/openfaas-colorization          0.4.1      d36b67b1b5c1   2 years ago         1.84GB
rorpage/text-to-speech                    latest     5dc20810eb54   2 years ago         86.9MB
stefanprodan/faas-grafana                 4.6.3      2a4bd9caea50   4 years ago         284MB

$ kubectl get pods --all-namespaces
NAMESPACE              NAME                                        READY   STATUS             RESTARTS        AGE
kube-system            coredns-64897985d-kp7vf                     1/1     Running            0               6d
kube-system            etcd-minikube                               1/1     Running            0               6d
kube-system            kube-apiserver-minikube                     1/1     Running            0               6d
kube-system            kube-controller-manager-minikube            1/1     Running            0               6d
kube-system            kube-proxy-5m8lr                            1/1     Running            0               6d
kube-system            kube-scheduler-minikube                     1/1     Running            0               6d
kube-system            storage-provisioner                         1/1     Running            1 (6d ago)      6d
kubernetes-dashboard   dashboard-metrics-scraper-58549894f-97tsv   1/1     Running            0               5d7h
kubernetes-dashboard   kubernetes-dashboard-ccd587f44-lkwcx        1/1     Running            0               5d7h
openfaas-fn            base64-6bdbcdb64c-djz8f                     1/1     Running            0               5d1h
openfaas-fn            colorise-85c74c686b-2fz66                   1/1     Running            0               4d5h
openfaas-fn            echoit-5d7df6684c-k6ljn                     1/1     Running            0               5d1h
openfaas-fn            env-6c79f7b946-bzbtm                        1/1     Running            0               4d5h
openfaas-fn            figlet-54db496f88-957xl                     1/1     Running            0               4d19h
openfaas-fn            hello-openfaas-547857b9d6-z277c             0/1     ImagePullBackOff   0               4d3h
openfaas-fn            hello-openfaas-7b6946b4f9-hcvq4             0/1     ImagePullBackOff   0               4d3h
openfaas-fn            hello-openfaas2-5c6f6cb5d9-24hkz            0/1     ImagePullBackOff   0               9m22s
openfaas-fn            hello-openfaas2-8957bb47b-7cgjg             0/1     ImagePullBackOff   0               2d22h
openfaas-fn            hello-openfaas3-65847b8b67-b94kd            0/1     ImagePullBackOff   0               4d2h
openfaas-fn            hello-python-6d6976845f-cwsln               0/1     ImagePullBackOff   0               3d19h
openfaas-fn            hello-python-b577cb8dc-64wf5                0/1     ImagePullBackOff   0               3d9h
openfaas-fn            hubstats-b6cd4dccc-z8tvl                    1/1     Running            0               5d1h
openfaas-fn            markdown-68f69f47c8-w5m47                   1/1     Running            0               5d1h
openfaas-fn            nodeinfo-d48cbbfcc-hfj79                    1/1     Running            0               5d1h
openfaas-fn            openfaas2-fun                               1/1     Running            0               15s
openfaas-fn            text-to-speech-74ffcdfd7-997t4              0/1     CrashLoopBackOff   2235 (3s ago)   4d5h
openfaas-fn            wordcount-6489865566-cvfzr                  1/1     Running            0               5d1h
openfaas               alertmanager-88449c789-fq2rg                1/1     Running            0               3d1h
openfaas               basic-auth-plugin-75fd7d69c5-zw4jh          1/1     Running            0               3d2h
openfaas               gateway-5c4bb7c5d7-n8h27                    2/2     Running            0               3d2h
openfaas               grafana                                     1/1     Running            0               4d8h
openfaas               nats-647b476664-hkr7p                       1/1     Running            0               3d2h
openfaas               prometheus-687648749f-tl8jp                 1/1     Running            0               3d1h
openfaas               queue-worker-7777ffd7f6-htx6t               1/1     Running            0               3d2h


$ kubectl get -o yaml -n openfaas-fn deploy/hello-openfaas2
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "6"
    prometheus.io.scrape: "false"
  creationTimestamp: "2022-03-17T12:47:35Z"
  generation: 6
  labels:
    faas_function: hello-openfaas2
  name: hello-openfaas2
  namespace: openfaas-fn
  resourceVersion: "400833"
  uid: 9c4e9d26-23af-4f93-8538-4e2d96f0d7e0
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      faas_function: hello-openfaas2
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      annotations:
        prometheus.io.scrape: "false"
      creationTimestamp: null
      labels:
        faas_function: hello-openfaas2
        uid: "969512830"
      name: hello-openfaas2
    spec:
      containers:
      - env:
        - name: fprocess
          value: python3 index.py
        image: wm/hello-openfaas2:0.1
        imagePullPolicy: Always
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /_/health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 2
          periodSeconds: 2
          successThreshold: 1
          timeoutSeconds: 1
        name: hello-openfaas2
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /_/health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 2
          periodSeconds: 2
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      enableServiceLinks: false
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  conditions:
  - lastTransitionTime: "2022-03-17T12:47:35Z"
    lastUpdateTime: "2022-03-17T12:47:35Z"
    message: Deployment does not have minimum availability.
    reason: MinimumReplicasUnavailable
    status: "False"
    type: Available
  - lastTransitionTime: "2022-03-20T12:16:56Z"
    lastUpdateTime: "2022-03-20T12:16:56Z"
    message: ReplicaSet "hello-openfaas2-5d6c7c7fb4" has timed out progressing.
    reason: ProgressDeadlineExceeded
    status: "False"
    type: Progressing
  observedGeneration: 6
  replicas: 2
  unavailableReplicas: 2
  updatedReplicas: 1

在一个 shell,

docker@minikube:~$ docker run  --name wm -ti wm/hello-openfaas2:0.1
2022/03/20 13:04:52 Version: 0.2.0  SHA: 56bf6aac54deb3863a690f5fc03a2a38e7d9e6ef
2022/03/20 13:04:52 Timeouts: read: 5s write: 5s hard: 0s health: 5s.
2022/03/20 13:04:52 Listening on port: 8080
...

还有一个shell

docker@minikube:~$ docker ps | grep wm
d7796286641c   wm/hello-openfaas2:0.1             "fwatchdog"              3 minutes ago       Up 3 minutes (healthy)   8080/tcp   wm

如果您的图片有 latest 标签,则 Pod 的 ImagePullPolicy 将自动设置为 Always。每次创建 pod 时,Kubernetes 都会尝试拉取最新的镜像。

尽量不要将图像标记为 latest 或手动将 Pod 的 ImagePullPolicy 设置为 Never。 如果您使用静态清单创建 Pod,设置将如下所示:

containers:
  - name: test-container
    image: testImage:latest
    imagePullPolicy: Never

当您指定要从中提取的图像时没有 url,这默认为 DockerHub。当你使用 :latest 标签时,它总是会拉取最新的图像,无论定义什么拉取策略。

所以要使用本地构建的图像 - 不要使用最新的标签。

要让 minikube 从您的本地机器拉取镜像,您需要做几件事:

  1. 将您的 docker 客户端指向 VM 的 docker 守护进程:eval $(minikube docker-env)
  2. 配置镜像拉取策略:imagePullPolicy: Never
  3. 有一个标志要传入以在 minikube VM 中使用不安全的注册表。这必须在创建机器时指定:minikube start --insecure-registry

请注意,您必须在每个要使用的终端上 运行 eval eval $(minikube docker-env),因为它只会为当前 shell 会话设置环境变量。

此流程有效:

# Start minikube and set docker env
minikube start
eval $(minikube docker-env)

# Build image
docker build -t foo:1.0 .

# Run in minikube
kubectl run hello-foo --image=foo:1.0 --image-pull-policy=Never

您可以在 minikube docs 阅读更多内容。

根据最初 post 的评论,我收集到:

  • 问题是来自您的 Minikube 集群的容器 运行time 与您构建函数映像的主机的时间不同(并非总是如此:minikube 可以 运行 with docker driver我认为 暗示主机 docker 运行时间与集群共享)
  • 容器 运行Minikube 使用的时间是 docker(可能是 cri-o / 以下步骤不适用于这种情况。那些使用 crio 的人可能 switch to docker, as I'm not sure image loading is possible with cri-o )

您可以尝试从 Minikube 实例中的 shell 构建函数映像。

或者您可以:

  • 导出您的图片 (docker save -o image.tar my/image)
  • 将此复制到您的 minikube 实例 (scp -i ~/.minikube/machines/minikube/id_rsa image.tar docker@$(minikube ip):)
  • 打开一个 shell ( ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) )
  • 加载该图像 (docker load -i image.tar)

然后,确保你的 openfaas 是使用 faasnetes.imagePullPolicy=NeverIfNotPresent 部署的,因为我怀疑直接在你的函数中设置 imagePullPolicy 是否可行(还没有在他们的文档中读到这个,它正如您指出的那样,而是提到在 openfaas 部署期间覆盖它)。检查您的部署 yaml 定义 ( kubectl get -o yaml -n openpaas-fn deploy/hello-openfaas ) 应该确认您没有使用 Always:如果已经是这种情况,则无需进一步挖掘:只需确保您的图像已导入,名称和标签匹配你的函数引用的那个。


... 回答您最后的评论:您不确定 openfaas 是如何部署的。确保设置正确选项的一种方法是查看 openfaas 命名空间 ( kubectl get -o yaml -n openfaas deploy/gateway ) 中的网关部署。

在那里,您应该找到一个名为“operator”的容器。该容器应包含一些环境变量,其中之一可能是 image_pull_policy。 (我们可以看到 the Chart sources )。您希望将该环境变量设置为 IfNotPresent,根据需要添加或编辑它。

检查您的最后一次编辑,我们可以看到您的函数创建的 Deployment 对象说:

    image: wm/hello-openfaas2:0.1
    imagePullPolicy: Always

所以可以肯定:您确实需要重新配置 openfaas,添加 image_pull_policy 环境变量。