Kubernetes

Docker Desktop 安装K8s集群

转载:https://zhuanlan.zhihu.com/p/388874530

前言


之前给大家介绍过几种在笔记本电脑上安装Kubernetes集群的工具,虽然安装起来不太繁琐但是多多少少还是需要花一些时间的,对于不想瞎倒腾,就想快速安装个本地集群开始学习和测试的同学,推荐你们试一试Docker桌面应用里自带的Kubernetes集群。其实我也是之前用Minikube安装的集群莫名其妙坏掉启动不起来后,偶然发现Docker桌面应用里内嵌了一个Kubernetes集群,试了试效果感觉还是挺不错的。下面我带大家简单过一下启用集群方法,全程几乎就是点点点,也不需要做啥。

启用Kubernetes


也不知道是什么时候开始(反正老早就有了,我这个是前年装的…一直没升级过),Docker的桌面应用除了提供Docker CLI集成外还内嵌了一个Kubernetes集群,默认是不开启的,启用后这个单点的Kubernetes集群会运行在本地的Docker实例中。

要启用这个集群只需要打开Docker应用的首选项(Preferences)界面,选择Kubernetes选项卡。

点击应用并重启,就可以去刷小视频了,再回来集群就安装好了。

除了启用Kubernetes集群外,如果电脑上之前没有安装过 kubectl(客户端命令工具)的话还会为你自动安装上kubectl,并配置连接到刚才启动的本地集群上。如果是本地之前安装过kubectl 和 存在其他Kubernetes集群,想要连接到Docker桌面应用内嵌的集群则需要切换一下 kubectl 的上下文。

$ kubectl config get-contexts
$ kubectl config use-context docker-desktop

使用Kubernetes


集群启用完成后,在打开Docker桌面应用的选项卡在 UI 上会有些微的变化,证明Kubernetes集群已经成功启动起来了。

让我们随便运行几个 kubctl 命令,试试效果。

➜  ~ kubectl get node                     
NAME             STATUS   ROLES                  AGE   VERSION
docker-desktop   Ready    control-plane,master   13d   v1.21.1

可以看到我们现在使用的是一个单节点,名字叫docker-desktop的集群(这个名没地方改)。

使用Docker桌面应用自带的Kubernetes集群还有一点方便的地方就是,集群外部通过 127.0.0.1 就能访问集群内部,也就是我们通过 NodePort类型的 Service 向集群外暴露的资源,通过 127.0.0.1:port 的形式就能访问到。

我们随便拿一个之前我们搭建MySQL开发环境的例子测试一下。搭建MySQL需要的YAML定义文件和步骤我就不再重复说了,忘记的同学之前访问上一篇文章:利用Kubernetes搭建便携式开发环境之MySQL和Redis

## 切到定义文件在的目录
kubectl apply -f mysql-configmap.yaml

kubectl apply -f deployment-service.yaml

--------------------------------------------------------
## 可以看到下面的Pod和Service资源
kubectl get pod

NAME                    READY   STATUS    RESTARTS   AGE
mysql-cc4479465-gwdj7   1/1     Running   0          13d
--------------------------------------------------------
kubectl get svc mysql
NAME    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
mysql   NodePort   10.104.123.151   <none>        3306:30306/TCP   13d

在电脑上只要通过127.0.0.1:30306就能访问到我们刚刚安装的MySQL啦,持久化之类的事情我也试过,只要我们不主动把MySQL这个Pod删掉数据就会一直在。

安装 dashboard


  • k8s集群启动以后,就可以用下面的命令确认集群是否ready
Mac-mini ~ % kubectl get node
NAME             STATUS   ROLES           AGE    VERSION
docker-desktop   Ready    control-plane   2d2h   v1.32.2
  • 接着运行以下命令来安装 Kubernetes Dashboard:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
  • 创建服务账户
admin-user.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
kubectl apply -f admin-user.yaml 

输出:
serviceaccount/admin-user created
  • 绑定服务账户集群角色
admin-user-role-binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
kubectl apply -f admin-user-role-binding.yaml 

输出:
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
  • 创建 admin-user 的 token(这个token好像会过期,如果过期的话,就用下面命令重新创建个)

Kubernetes 从 1.24 版本开始,默认启用ServiceAccount令牌的自动管理,生成的 Token 默认有效期为1 小时3600秒)。

kubectl -n kubernetes-dashboard create token admin-user
  • 创建永久 Token(不推荐,存在安全风险)
通过Secret手动创建不指定过期时间的 Token:

apiVersion: v1
kind: Secret
metadata:
  name: admin-user-permanent-token
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/service-account.name: "admin-user"  # 关联ServiceAccount
type: kubernetes.io/service-account-token

应用该 Secret 后,通过以下命令获取 Token:
该 Token 无过期时间,需手动删除 Secret 才能失效。
生产环境中应避免使用永久 Token,建议通过 RBAC 控制权限并定期轮换短期 Token。
kubectl get secret admin-user-permanent-token -n kubernetes-dashboard -o jsonpath="{.data.token}" | base64 -d
  • 用下面的命令启动 dashboard
kubectl proxy --port=8001
  • 用下面的url访问 dashboard
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
  • 输入刚刚创建的 admin-user 的 token, 然后登录就可以访问dashboard了

k8s部署一个简单完整的示例


我们使用 httpd (Apache) 镜像 来创建一个完整的示例,包括 Deployment、Service,并将服务暴露到集群外部

  • 创建示例的namespace
kubectl create namespace k8s-study
显示:
namespace/k8s-study created
  • 创建 Deployment
# httpd-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
  labels:
    app: httpd
spec:
  replicas: 3  # 创建3个Pod副本
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd:alpine  # 使用docker hub 官方httpd镜像(Alpine轻量版)
        ports:
        - containerPort: 80  # Apache默认端口
        resources:
          limits:
            memory: "128Mi"
            cpu: "100m"
应用 Deployment:
kubectl apply -f httpd-deployment.yaml -n k8s-study

显示:
deployment.apps/httpd-deployment created
  • 创建 Service

创建一个 NodePort 类型的 Service 来暴露 Apache 服务:

# httpd-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: httpd-service
spec:
  selector:
    app: httpd  # 匹配Deployment中的label
  ports:
    - protocol: TCP
      port: 80        # Service端口
      targetPort: 80  # Pod端口
  type: NodePort      # 暴露到集群外部
应用 Service:
kubectl apply -f httpd-service.yaml -n k8s-study

显示:
service/httpd-service created
  • 验证部署

检查 Deployment 和 Pod 状态:

kubectl get deployments -n k8s-study

kubectl get pods -n k8s-study
  • 检查 Service 状态并获取分配的 NodePort
kubectl get services httpd-service -n k8s-study

显示:
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
httpd-service   NodePort   10.101.194.247   <none>        80:32636/TCP   2m37s

这里的 32636 就是随机分配的 NodePort(范围 30000-32767)。
  • 从集群外部访问服务
curl http://localhost:32636
  • 通过dashboard也能查看pod状态

通过Docker桌面应用在电脑上安装Kubernetes集群可以说是把我们学习K8s的起步依赖降到了最低,让我们能快速跳过工具安装步骤开始正题的学习,想学K8s的同学们赶紧动手试试吧。