讓地端Kubernetes存取私有Registry-以Azure Container Registry為例

讓地端Kubernetes存取私有Registry-以Azure Container Registry為例

上一篇,是直接透過各種 containerd CLI 來存取 Private Registry 裡的 Images。其實這只算一個 PoC,因為要先學習如何存取私有 Registry。有了之前的經驗,那麼接下來的大目標是讓 Kubernetes 的 nodes 也能存取私有 Registry。之前提到,Kubernetes 本身是使用 crictl CLI 來與 containerd 溝通。

crictl pull --creds "UserName:Password" "ImageDetail"

但我們用 Kubernetes 時不可能這樣下指令,必須透過一些其他方法。Kubernetes 本身可以吃 docker 的 config.json 組態來使用。對「docker 的 config.json 組態」有沒有很熟悉的感覺。對,在上一篇我們透過 nerdctl login 協助,它預設會把相關組態儲存下來到 /root/.docker/config.json,這不就是我們需要的嗎。

當我們擁有 config.json 之,事情就好辦了。

kubectl create secret generic acrcreds \
    --from-file=.dockerconfigjson=/root/.docker/config.json \
    --type=kubernetes.io/dockerconfigjson

這裡我碰到存取 /root/ 之下檔案會有權限問題。可以先把 config.json 複到其他地方(例如:~),再執行匯入作業。

這裡去建立一個 kubernetes.io/dockerconfigjson 類型的 Secret。建立之後也能用 kubectl get secret 來查詢。

$ kubectl get secret acrcreds --output=yaml
apiVersion: v1
data:
  .dockerconfigjson: ewoJImF1dGhzI......PTDNFeCIKCQl9Cgl9Cn0=
kind: Secret
metadata:
  creationTimestamp: "2023-05-10T08:18:05Z"
  name: feazacr
  namespace: default
  resourceVersion: "1025522"
  uid: 3fbe8d12-4b50-46ac-8d04-737072ce0875
type: kubernetes.io/dockerconfigjson

另外也可以 base64 --decode 來還原完整的 config.json 內容。

$ kubectl get secret acrcreds --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
{
        "auths": {
                "???.azurecr.io": {
                        "auth": "a1RDRG9ja1..."
                }
        }

可以進一步拿 auth 來解碼取得原始的帳密。

echo "a1RDRG9ja1..." | base64 --decode

也就是說,整個 Secret 只是用 base64 幫你儲存,基本上和明碼沒有太多差異。

如果不想使用 nerdctl login 產的 config.json,那麼也能透過 kubectl 直接建立 Secret 來使用。

kubectl create secret docker-registry acrcreds --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>

基本上填 serverusernamepassword 三個資訊,一樣能建立我們需要的 Secret 來使用。

有了 Secret 就能拿來 Yaml 裡使用。

apiVersion: v1
kind: Pod
metadata:
  name: fe-l-teamteched
spec:
  containers:
  - name: fe-l-teamteched-container
    image: ???.azurecr.io/release/doc/teamteched:latest
  imagePullSecrets:
  - name: acrcreds

後續如果需要存取私有 Registry,那麼只需要透過 imagePullSecrets 來指定我們建立的 Secret,就能順利存取到私有 Registry,例如 Azure Container Registry 的映像檔。

$ kubectl apply -f fe-l-teamteched.yaml
pod/fe-l-teamteched created

$ kubectl get pod fe-l-teamteched
NAME              READY   STATUS    RESTARTS   AGE
fe-l-teamteched   1/1     Running   0          19s

$ kubectl describe pod fe-l-teamteched
Name:             fe-l-teamteched
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-worker1/192.168.56.20
Start Time:       Thu, 11 May 2023 02:48:19 +0000
Labels:           <none>
Annotations:      <none>
Status:           Running
IP:               10.244.1.64
IPs:
  IP:  10.244.1.64
Containers:
  fe-l-teamteched-container:
    Container ID:   containerd://9ad0200a41f36a99ee868a801d8eabfb68b63757ab4b554c397af170ded3649e
    Image:          ???.azurecr.io/release/doc/l-teamteched:latest
    Image ID:       ???.azurecr.io/release/doc/l-teamteched@sha256:c2b1775cfbf6776629c2e11a6a0ddb7baec67ee9b4f703e491bf209a83b1a1a9
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Thu, 11 May 2023 02:48:32 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-6w4cg (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-6w4cg:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  72s   default-scheduler  Successfully assigned default/fe-l-teamteched to k8s-worker1
  Normal  Pulling    71s   kubelet            Pulling image "???.azurecr.io/release/doc/l-teamteched:latest"
  Normal  Pulled     59s   kubelet            Successfully pulled image "???.azurecr.io/release/doc/l-teamteched:latest" in 12.549856464s
  Normal  Created    59s   kubelet            Created container fe-l-teamteched-container
  Normal  Started    59s   kubelet            Started container fe-l-teamteched-container

雖然我們的部屬到 worker1 執行,但 Secret 只需要在 Control Plane 上設定即可,從日誌就能清楚看到,pulling images 在 worker1 上很順利進行。

參考資料:https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。