近期在研究dapr(分布式应用运行时)[1],这是一个很朴素却很棒的想法,目前大厂,如阿里和鹅厂都有大牛在研究该项目,甚至是利用dapr落地了部分应用。关于dapr,后续我也会用单独的文章详细说说。

dapr不仅支持k8s部署,还支持本地部署,并可以对接多个世界知名的公有云厂商的服务,比如:aws、azure、阿里云等。为了体验dapr对云原生应用的支持,我选择了将其部署于k8s中,同时我选择使用minikube[2]来构建本地k8s开发环境。而本文要说的就是将dapr安装到minikube时遇到的问题。

1. 安装minikube

Kubernetes在4月份发布了最新的1.21版本[3],但目前minikube的最新版依然为1.20版本[4]

minikube是k8s项目自己维护的一个k8s本地开发环境项目,它与k8s的api接口兼容,我们可以快速搭建一个minikube来进行k8s学习和实践。minikube官网[5]上有关于它的安装、使用和维护的详尽资料。

我这里在一个ubuntu 18.04的腾讯云主机上(1 vcpu, 2g mem)上安装minikube v1.20,minikube是一个单体二进制文件,我们先将这个文件下载到本地:

# curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 60.9M  100 60.9M    0     0  7764k      0  0:00:08  0:00:08 --:--:-- 11.5M
# install minikube-linux-amd64 /usr/local/bin/minikube

验证是否下载ok:

# minikube version
minikube version: v1.20.0
commit: c61663e942ec43b20e8e70839dcca52e44cd85ae

接下来我们就利用minikube启动一个k8s cluster用作本地开发环境。由于minikube默认的最低安装要求为2核cpu,而我的虚机仅为1核,我们需要为minikube传递一些命令行参数以让其在单核CPU上也能顺利地启动一个k8s cluster。另外minikube会从gcr.io这个国内被限制访问的站点下载一些控制平面的容器镜像,为了能让此过程顺利进行下去,我们还需要告诉minikube从哪个gcr.io的mirror站点下载容器镜像:


# minikube start --extra-config=kubeadm.ignore-preflight-errors=NumCPU --force --cpus 1 --memory=1024mb --image-mirror-country='cn'minikube v1.20.0 on Ubuntu 18.04 (amd64)minikube skips various validations when --force is supplied; this may lead to unexpected behaviorAutomatically selected the docker driver. Other choices: ssh, noneRequested cpu count 1 is less than the minimum allowed of 2has less than 2 CPUs available, but Kubernetes requires at least 2 to be availableYour cgroup does not allow setting memory.▪ More information: https://docs.docker.com/engine/install/linux-postinstall/#your-kernel-does-not-support-cgroup-swap-limit-capabilitiesRequested memory allocation 1024MiB is less than the usable minimum of 1800MBRequested memory allocation (1024MB) is less than the recommended minimum 1900MB. Deployments may fail.The requested memory allocation of 1024MiB does not leave room for system overhead (total system memory: 1833MiB). You may face stability issues.Suggestion: Start minikube with less memory allocated: 'minikube start --memory=1833mb'The "docker" driver should not be used with root privileges.If you are running minikube within a VM, consider using --driver=none:https://minikube.sigs.k8s.io/docs/reference/drivers/none/Using image repository registry.cn-hangzhou.aliyuncs.com/google_containersStarting control plane node minikube in cluster minikubePulling base image ...> registry.cn-hangzhou.aliyun...: 20.48 MiB / 358.10 MiB  5.72% 2.89 MiB p/
> registry.cn-hangzhou.aliyun...: 358.10 MiB / 358.10 MiB  100.00% 3.50 MiB> registry.cn-hangzhou.aliyun...: 358.10 MiB / 358.10 MiB  100.00% 3.50 MiB> registry.cn-hangzhou.aliyun...: 358.10 MiB / 358.10 MiB  100.00% 3.50 MiB> registry.cn-hangzhou.aliyun...: 358.10 MiB / 358.10 MiB  100.00% 6.83 MiBCreating docker container (CPUs=1, Memory=1024MB) ...Preparing Kubernetes v1.20.2 on Docker 20.10.6 ...▪ kubeadm.ignore-preflight-errors=NumCPU▪ Generating certificates and keys ...▪ Booting up control plane ...▪ Configuring RBAC rules ...Verifying Kubernetes components...▪ Using image registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5 (global image repository)Enabled addons: default-storageclass, storage-provisioner/usr/local/bin/kubectl is version 1.17.9, which may have incompatibilites with Kubernetes 1.20.2.▪ Want kubectl v1.20.2? Try 'minikube kubectl -- get pods -A'Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

查看启动的k8s集群状态:

# minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

我们看到minikube似乎成功启动了一个k8s cluster。

2. pod storage-provisioner处于ErrImagePull状态

在后续使用helm安装redis作为state store组件(components)时,发现安装后的redis处于下面的状态:

# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
redis-master-0     0/1     Pending   0          7m48s
redis-replicas-0   0/1     Pending   0          7m48s

通过kubectl describe命令详细查看redis-master-0这个pod:

# kubectl describe pod redis-master-0
Name:           redis-master-0
Namespace:      default
Priority:       0
Node:           <none>
Labels:         app.kubernetes.io/component=masterapp.kubernetes.io/instance=redisapp.kubernetes.io/managed-by=Helmapp.kubernetes.io/name=rediscontroller-revision-hash=redis-master-694655df77helm.sh/chart=redis-14.1.1statefulset.kubernetes.io/pod-name=redis-master-0
Annotations:    checksum/configmap: 0898a3adcb5d0cdd6cc60108d941d105cc240250ba6c7f84ed8b5337f1edd470checksum/health: 1b44d34c6c39698be89b2127b9fcec4395a221cff84aeab4fbd93ff4a636c210checksum/scripts: 465f195e1bffa9700282b017abc50056099e107d7ce8927fb2b97eb348907484checksum/secret: cd7ff82a84f998f50b11463c299c1200585036defc7cbbd9c141cc992ad80963
Status:         Pending
IP:
IPs:            <none>
Controlled By:  StatefulSet/redis-master
Containers:redis:Image:      docker.io/bitnami/redis:6.2.3-debian-10-r0Port:       6379/TCPHost Port:  0/TCPCommand:/bin/bashArgs:-c/opt/bitnami/scripts/start-scripts/start-master.shLiveness:   exec [sh -c /health/ping_liveness_local.sh 5] delay=5s timeout=6s period=5s #success=1 #failure=5Readiness:  exec [sh -c /health/ping_readiness_local.sh 1] delay=5s timeout=2s period=5s #success=1 #failure=5Environment:BITNAMI_DEBUG:           falseREDIS_REPLICATION_MODE:  masterALLOW_EMPTY_PASSWORD:    noREDIS_PASSWORD:          <set to the key 'redis-password' in secret 'redis'>  Optional: falseREDIS_TLS_ENABLED:       noREDIS_PORT:              6379Mounts:/data from redis-data (rw)/health from health (rw)/opt/bitnami/redis/etc/ from redis-tmp-conf (rw)/opt/bitnami/redis/mounted-etc from config (rw)/opt/bitnami/scripts/start-scripts from start-scripts (rw)/tmp from tmp (rw)/var/run/secrets/kubernetes.io/serviceaccount from redis-token-rtxk2 (ro)
Conditions:Type           StatusPodScheduled   False
Volumes:redis-data:Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)ClaimName:  redis-data-redis-master-0ReadOnly:   falsestart-scripts:Type:      ConfigMap (a volume populated by a ConfigMap)Name:      redis-scriptsOptional:  falsehealth:Type:      ConfigMap (a volume populated by a ConfigMap)Name:      redis-healthOptional:  falseconfig:Type:      ConfigMap (a volume populated by a ConfigMap)Name:      redis-configurationOptional:  falseredis-tmp-conf:Type:       EmptyDir (a temporary directory that shares a pod's lifetime)Medium:    SizeLimit:  <unset>tmp:Type:       EmptyDir (a temporary directory that shares a pod's lifetime)Medium:    SizeLimit:  <unset>redis-token-rtxk2:Type:        Secret (a volume populated by a Secret)SecretName:  redis-token-rtxk2Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300snode.kubernetes.io/unreachable:NoExecute for 300s
Events:Type     Reason            Age                 From               Message----     ------            ----                ----               -------Warning  FailedScheduling  18s (x6 over 5m7s)  default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.

我们发现是该pod的PersistentVolumeClaims没有得到满足,没有绑定到适当PV(persistent volume)上。查看pvc的状态,也都是pending:

# kubectl get pvc
NAME                          STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
redis-data-redis-master-0     Pending                                      standard       35m
redis-data-redis-replicas-0   Pending                                      standard       35m

详细查看其中一个pvc的状态:

# kubectl describe  pvc redis-data-redis-master-0
Name:          redis-data-redis-master-0
Namespace:     default
StorageClass:  standard
Status:        Pending
Volume:
Labels:        app.kubernetes.io/component=masterapp.kubernetes.io/instance=redisapp.kubernetes.io/name=redis
Annotations:   volume.beta.kubernetes.io/storage-provisioner: k8s.io/minikube-hostpath
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode:    Filesystem
Mounted By:    redis-master-0
Events:Type    Reason                Age                  From                         Message----    ------                ----                 ----                         -------Normal  ExternalProvisioning  55s (x143 over 35m)  persistentvolume-controller  waiting for a volume to be created, either by external provisioner "k8s.io/minikube-hostpath" or manually created by system administrator

我们看到该pvc在等待绑定一个volume,而k8s cluster当前在default命名空间中没有任何pv资源。问题究竟出在哪里?

我们回到minikube自身上来,在minikube文档中,负责自动创建HostPath类型pv的是storage-provisioner插件:


图:minikube插件使能情况

我们看到storage-provisioner插件的状态为enabled,那么为什么该插件没能为redis提供需要的pv资源呢?我顺便查看了一下当前k8s cluster的控制平面组件的运行情况:

# kubectl get po -n kube-system
NAMESPACE     NAME                                    READY   STATUS             RESTARTS   AGE
kube-system   coredns-54d67798b7-n6vw4                1/1     Running            0          20h
kube-system   etcd-minikube                           1/1     Running            0          20h
kube-system   kube-apiserver-minikube                 1/1     Running            0          20h
kube-system   kube-controller-manager-minikube        1/1     Running            0          20h
kube-system   kube-proxy-rtvvj                        1/1     Running            0          20h
kube-system   kube-scheduler-minikube                 1/1     Running            0          20h
kube-system   storage-provisioner                     0/1     ImagePullBackOff   0          20h

我们惊奇的发现:storage-provisioner这个pod居然处于ImagePullBackOff状态,即下载镜像有误!

3. 发现真相

还记得在minikube start命令的输出信息的末尾,我们看到这样一行内容:

Using image registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5 (global image repository)

也就是说我们从registry.cn-hangzhou.aliyuncs.com下载storage-provisioner:v5有错误!我手动在本地执行了一下下面命令:

# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5Error response from daemon: pull access denied for registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

居然真的无法下载成功!

究竟是什么地方出现问题了呢?从提示来看,要么是该镜像不存在,要么是docker login被拒绝,由于registry.cn-hangzhou.aliyuncs.com是公共仓库,因此不存在docker login的问题,那么就剩下一个原因了:镜像不存在!

于是我在minikube官方的issue试着搜索了一下有关registry.cn-hangzhou.aliyuncs.com作为mirror的问题,还真让我捕捉到了蛛丝马迹。

在https://github.com/kubernetes/minikube/pull/10770这PR中,有人提及当--image-mirror-country使用cn时,minikube使用了错误的storage-provisioner镜像,镜像的地址不应该是registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5,而应该是registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5。

我在本地试了一下registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5,的确可以下载成功:

# docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5
v5: Pulling from google_containers/storage-provisioner
Digest: sha256:18eb69d1418e854ad5a19e399310e52808a8321e4c441c1dddad8977a0d7a944
Status: Image is up to date for registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5
registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5

4. 解决问题

发现问题真相:当--image-mirror-country使用cn时,minikube使用了错误的storage-provisioner镜像。那我们如何修正这个问题呢?

我们查看一下storage-provisioner pod的imagePullPolicy:

# kubectl get pod storage-provisioner  -n kube-system -o yaml
... ...
spec:containers:- command:- /storage-provisionerimage: registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5imagePullPolicy: IfNotPresentname: storage-provisioner

我们发现storage-provisioner的imagePullPolicy为ifNotPresent,这意味着如果本地有storage-provisioner:v5这个镜像的话,minikube不会再去远端下载该image。这样我们可以先将storage-provisioner:v5下载到本地并重新tag为registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5。

下面我们就来操作一下:

# docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5 registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5

一旦有了image,通过minikube addons子命令重新enable对应pod,可以重启storage-provisioner pod,让其进入正常状态:

# minikube addons enable storage-provisioner▪ Using image registry.cn-hangzhou.aliyuncs.com/google_containers/k8s-minikube/storage-provisioner:v5 (global image repository)The 'storage-provisioner' addon is enabled# kubectl get po -n kube-system
NAME                               READY   STATUS    RESTARTS   AGE
coredns-54d67798b7-n6vw4           1/1     Running   0          25h
etcd-minikube                      1/1     Running   0          25h
kube-apiserver-minikube            1/1     Running   0          25h
kube-controller-manager-minikube   1/1     Running   0          25h
kube-proxy-rtvvj                   1/1     Running   0          25h
kube-scheduler-minikube            1/1     Running   0          25h
storage-provisioner                1/1     Running   0          69m

当storgae-provisioner恢复正常后,之前安装的dapr state component组件redis也自动恢复正常了:

# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
redis-master-0     1/1     Running   0          18h
redis-replicas-0   1/1     Running   1          18h
redis-replicas-1   1/1     Running   0          16h
redis-replicas-2   1/1     Running   0          16h

“Gopher部落”知识星球正式转正(从试运营星球变成了正式星球)!“gopher部落”旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!部落目前虽小,但持续力很强。在2021年上半年,部落将策划两个专题系列分享,并且是部落独享哦:

  • Go技术书籍的书摘和读书体会系列

  • Go与eBPF系列

欢迎大家加入!

Go技术专栏“改善Go语⾔编程质量的50个有效实践[6]”正在慕课网火热热销中!本专栏主要满足广大gopher关于Go语言进阶的需求,围绕如何写出地道且高质量Go代码给出50条有效实践建议,上线后收到一致好评!欢迎大家订 阅!


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用[7]”在慕课网热卖中,欢迎小伙伴们订阅学习!

Gopher Daily(Gopher每日新闻)归档仓库 - https://github.com/bigwhite/gopherdaily

我的联系方式:

  • 微博:https://weibo.com/bigwhite20xx

  • 微信公众号:iamtonybai

  • 博客:tonybai.com

  • github: https://github.com/bigwhite

  • “Gopher部落”知识星球:https://public.zsxq.com/groups/51284458844544

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

参考资料

[1]

dapr(分布式应用运行时): https://dapr.io

[2]

minikube: https://github.com/kubernetes/minikube

[3]

1.21版本: https://kubernetes.io/blog/2021/04/08/kubernetes-1-21-release-announcement/

[4]

1.20版本: https://github.com/kubernetes/minikube/releases/tag/v1.20.0

[5]

minikube官网: https://minikube.sigs.k8s.io/docs/start/

[6]

改善Go语⾔编程质量的50个有效实践: https://www.imooc.com/read/87

[7]

Kubernetes实战:高可用集群搭建、配置、运维与应用: https://coding.imooc.com/class/284.html

minikube v1.20.0版本的一个bug相关推荐

  1. QingScan v1.1.0 版本发布会实录

    一.背景 QingScan今天晚上要发布v1.1.0版本了,这个版本黑盒详情页改版还是蛮大的,另外添加了队列功能和扫描进度信息:那今天晚上主要是讲解这个QingScan的一个新版本的一个使用方法以及搭 ...

  2. tim工具包-task 定时任务调度中心 分布式可配置v1.3.0版本

    相关文章: tim工具包-dao层查询工具 tim工具包-sql管理平台-admin tim工具包-自动生成api接口 tim工具包-MyMath牛逼的计算工具 tim工具包-数据处理工具 v1.2 ...

  3. Volcano社区v1.6.0版本正式发布

    摘要:Volcano社区v1.6.0版本正式发布.此次版本增加了弹性作业管理.基于真实负载的动态调度. 基于真实负载的重调度.Volcano Job插件--MPI等多个新特性. 本文分享自华为云社区& ...

  4. .NET 2.0 RC的一个Bug

    .NET 2.0 Bug   --虚拟COM口名出错 今天发现.NET 2.0 RC版本(2.0.50727)的一个BUG: 很简单的一句话 Dim ports As String() = Syste ...

  5. SOFA Weekly|MOSN v1.3.0 版本发布、公众号半自助投稿、本周 Contributor QA

    SOFA WEEKLY | 每周精选  筛选每周精华问答,同步开源进展 欢迎留言互动- SOFAStack(Scalable Open Financial Architecture Stack)是蚂蚁 ...

  6. 缺陷程序数据集Defects4J v1.4.0版本的配置

    文章目录 前言 步骤 后续 前言 如题,对Defects4J缺陷程序数据集v1.4.0版本的配置简单记录一下. 步骤 主要参考下图的First,Then,Finally三步即可. apt-get up ...

  7. fortify扫描java_fortify代码扫描使用教程(20.0版本)

    先下载20.0版本的fortify,下载地址:http://www.pc6.com/softview/SoftView_837967.html 下载后傻瓜式安装 安装完成后,打开Audit Workb ...

  8. 以太坊2.0客户端Lighthouse发布v1.3.0版本,为高优先级建议立即更新

    官方消息,以太坊2.0客户端Lighthouse开发团队Sigma Prime表示,发布Lighthouse v1.3.0版本.该版本包括对信标链节点的重要错误修复,应将其视为所有质押者的高优先级,应 ...

  9. 所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置!

    所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置! 原因:我们安装的pyecharts版本是最新版本1.8.1,而很多实例是基于1.7.1版本而设计的,故而我们需要 ...

最新文章

  1. INSTALL_FAILED_INVALID_APK
  2. 函数调用过程详解:函数栈帧的创建与销毁
  3. VScode操作记录
  4. Android和IOS 调用 支付宝和微信 支付方法
  5. CSharpGL(23)用ComputeShader实现一个简单的ParticleSimulator
  6. 密钥文件登录服务器,密钥文件登录云服务器
  7. tensorflow框架
  8. 程序员黑话,看懂的都是老司机!
  9. 【数论】蓝桥20:数列求值
  10. Silverlight使用WCF实现数据通信
  11. matlab x轴特殊符号,matlab中的特殊符号
  12. 由公司APP大面积闪退问题引发的测试基建思考
  13. 求两个整数中的较大者(用函数实现)
  14. C语言笔记第02章:三大基本结构
  15. 使用python编写多普勒频移函数,绘制多普勒频移随速度变化的曲线,给出代码并举例,代码以markdown格式给出...
  16. kingcms php 排序 标签,kingcms全部标签使用教程
  17. java怎么给pr 上字幕_如何给Final Cut Pro快速加字幕(PR也适用)
  18. DNS与CDN——前端重点
  19. 智慧城市八大应用,助力城市更加智慧
  20. speedoffice表格中身份证号码显示不全怎么解决?

热门文章

  1. matlab中的plot的用法
  2. Java正则工具类从地址中提取省市区
  3. python爬取快手app视频(fiddler抓json包实现)
  4. Feathers JS – 基于 Express 构建数据驱动的服务
  5. 菜鸡瞎逼逼:基于UGUI的图文混排
  6. android服务的原理,android service原理
  7. 一款免费清爽的markdown软件vnote的完全配置手册-无忧配置Graphviz、plantuml、mathjax
  8. 抖音玩法到底怎么玩?学会它实现不一样的人生道路?
  9. PostgreSQL不区分大小写的排序规则
  10. 面对焦虑我们怎么办 - 凭什么我们要去焦虑!