如何启动mac版docker自带的k8s

本文使用的docker-desktop版本为4.6.0 (75818),内置Kubernetes: v1.22.5。之前也尝试使用homebrew安装docker-desktop,但cask上的docker版本较低,在docker-dashboard里始终下载不了Kubernetes,遂放弃,到docker官网上下载安装后成功了。

一、添加docker国内镜像加速

首先,安装完docker-desktop之后,打开docker-dashboard,在配置面板的Docker Engine选项卡中可以编辑docker配置,需要自行添加registry-mirrors配置国内镜像地址,这样以后在执行docker pull的时候可以加快速度。

{
  "registry-mirrors": [
    "http://f1361db2.m.daocloud.io",
    "https://mirror.ccs.tencentyun.com",
    "https://reg-mirror.qiniu.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://dockerhub.azk8s.cn",
    "https://hub-mirror.c.163.com",
    "https://registry.docker-cn.com"
  ]
}

二、启用docker-desktop内置的Kubernetes

如果你之前自行安装过kubectl,推荐你先卸载掉,因为启用k8s后,docker-desktop会自动安装一个kubectl。在docker-dashboard配置面板中找到Kubernetes选项卡,进去勾选启用Kubernetes就可以了,等一会会自动安装好全套k8s环境,包括kubectl命令行工具,并且kubectl环境已经自动指向docker-desktop。

三、安装Kubernetes Dashboard

启用Kubernetes后,docker-desktop并没有安装Kubernetes Dashboard,需要自行安装。参考文档:

https://kubernetes.io/zh/docs/tasks/access-application-cluster/web-ui-dashboard/

https://github.com/kubernetes/dashboard

首先在mac终端里执行命令,在k8s环境中部署Kubernetes Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml

四、访问Kubernetes Dashboard

任何安装在k8s环境中的应用程序或服务,都需要主动暴露给外界才能从外部访问。有很多种方式可以将Dashboard暴露给外部访问,下面列举一些。

1、使用Kubernetes Api Server代理

这个方法仅限本机访问,因为你不可能把k8s的控制权公之于众。可以使用以下命令启动Kubernetes Api Server代理服务,代理默认监听在8001端口

kubectl proxy

然后你就可以通过Api Server访问到k8s内部的kubernetes-dashboard

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

2、使用k8s端口转发

这也是一个临时调试的方法,仅限本机使用,可以快速打通k8s内外通信,下面的命令将本机的8080端口映射给k8s环境中dashboard service的443端口,这样本机就可以直接访问https://localhost:8080

kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8080:443

3、使用NodePort服务

这个方法适用于大多数需要暴露给外部访问的应用程序,需要重新编辑kubernetes-dashboard service配置文件

kubectl -n kubernetes-dashboard edit service kubernetes-dashboard

运行以上命令后会打开kubernetes-dashboard service的yaml配置文件,编辑方法和控制台的vi编辑器一样。 需要将type: ClusterIP改成type: NodePort,还要添加nodePort: 30001,否则会随机生成nodePort。 保存之后k8s会迅速应用新的配置,然后就可以访问https://localhost:30001

这里额外解释一下service配置文件中port、nodePort、targetPort的含义:

  1. port:service本身提供的访问端口,这个端口只是k8s环境内部使用的
  2. nodePort:外部访问本服务的端口,会在node节点上暴露给外部环境
  3. targetPort:目标端口,指向pod对外暴露的端口,也就是docker容器对外暴露的端口

所以,不管是在k8s环境内部访问service的port端口,还是在k8s环境外部访问节点的nodePort端口,最终目标都是访问到targetPort

4、使用Ingress

1) 部署Ingress

首先下载官方提供的yaml文件,用于部署ingress-nginx和ingress-nginx-controller

curl -o ingress-nginx-deploy.yaml https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml

然后这个文件里面的docker镜像地址需要修改一下,不然国内根本下载不了

# 第一处,替换nginx-ingress-controller镜像
# image: k8s.gcr.io/ingress-nginx/controller:v1.1.1@sha256:0bc88eb15f9e7f84e8e56c14fa5735aaa488b840983f87bd79b1054190e660de
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1

# 第二处,替换两个Job所使用的kube-webhook-certgen镜像,注意是有两个Job用到了这个镜像文件,所以要替换两次
# image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1

然后进行部署

kubectl apply -f ingress-nginx-deploy.yaml

因为要拉取docker镜像可能比较慢,可以随时查看pod状态

kubectl get pods -n ingress-nginx

这里需要提醒一下的是,如果你没有提前修改yaml文件替换docker镜像,直接进行部署的话可能会下载不了镜像文件,这时如果再去修改镜像文件地址后不能直接进行部署,需要先删除两个Job,这是因为Job任务是一次性的,无法进行修改,如果运行失败了,只能删除后才能重建任务

kubectl delete -n ingress-nginx job ingress-nginx-admission-create
kubectl delete -n ingress-nginx job ingress-nginx-admission-patch

2) 配置Ingress

由于dashboard默认要求使用https进行访问,ingress-nginx相当于充当反向代理,要访问内部的https资源,需要开启backend-protocol: "HTTPS",至于对外提供服务时是否需要开启https则视情况而定。我们只是用来本地测试,nginx对外就不使用https了,使用下面的yaml直接创建Ingress服务即可。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-dashboard
  namespace: kubernetes-dashboard
  annotations:
    # 指定了我们使用后端ingress controller的类别,如果后端有多个ingress controller的时候很重要
    kubernetes.io/ingress.class: "nginx"
    # 指定我们的rules的path可以使用正则表达式,如果我们没有使用正则表达式,此项则可不使用
    nginx.ingress.kubernetes.io/use-regex: "true"
    # 匹配到rules的规则后,重写到目标路径(可指定目标域名),再发送给backend
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    # nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  # tls:
  # kubernetes-dashboard-certs是之前部署dashboard时自动创建好的证书,如果你想开启对外https服务,可以直接使用
  # (直接使用会报证书错误,不过流程就是这样了,本地测试可以不管证书问题。正式环境的话还是要自行制作有效证书,证书和域名是要匹配的)
  # - secretName: kubernetes-dashboard-certs
  # 下面是配置域名,不配置的话也可以用127.0.0.1或localhost,如果和证书不匹配,也会报证书错误
  # - hosts:
  #   - ingress.local
  rules:
  - http:
      paths:
      - path: /(.*)
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443

应用配置文件

kubectl apply -f ingress-dashboard.yaml

可以查看一下刚才设置的ingress-dashboard服务

kubectl get ingress ingress-dashboard -n kubernetes-dashboard

NAME                CLASS    HOSTS   ADDRESS     PORTS   AGE
ingress-dashboard   <none>   *       localhost   80      3h38m

这里可以看到已经配置完成了,通过访问本机80端口就可以打开dashboard

3) 关于https证书

在k8s添加证书也很简单,以下是示例

# 为 dashboard.k8s.loc 域名创建证书,有效期10年,将生成 dashboard.key 和 dashboard.crt 两个文件
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout dashboard.key -out dashboard.crt -subj "/CN=dashboard.k8s.loc/O=dashboard.k8s.loc"
# 将证书添加到 kubernetes-dashboard 命名空间中,名称为kubernetes-dashboard-certs
kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.crt --from-file=dashboard.key -n kubernetes-dashboard

5、其他方式

其他对外暴露服务的方式还有LoadBalancer、ExternalName等,暂时不表,可以自行查阅文档

https://kubernetes.io/zh/docs/concepts/services-networking/service/#loadbalancer

五、创建管理员账号并登录

打开kubernetes-dashboard登录页面可以看到需要权限才能进去,可以使用用户token作为访问令牌,默认k8s内部是有很多用户账号的,但是各个账号的作用不同,这里我们来新创建一个管理员账号,这样登录dashboard之后才能看到更多内容。

首先创建一个dashboard-adminuser.yaml配置文件,内容如下

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
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: kube-system

使用kubectl应用配置

kubectl create -f dashboard-adminuser.yaml

上面创建了一个叫admin-user的服务账号,并放在kube-system命名空间下,并将cluster-admin角色绑定到admin-user账户,这样admin-user账户就有了管理员的权限。默认情况下,kubeadm创建集群时已经创建了cluster-admin角色,直接绑定即可。

查看admin-user的token

kubectl -n kube-system describe secret admin-user

找到token字段,复制并保存起来,以后每次登录dashboard时复制粘贴一下这段token就可以了