{"id":18598072,"url":"https://github.com/mingslife/all-in-kind","last_synced_at":"2026-05-06T03:32:04.804Z","repository":{"id":230658104,"uuid":"462131203","full_name":"mingslife/all-in-kind","owner":"mingslife","description":"☸ All in KIND","archived":false,"fork":false,"pushed_at":"2022-03-29T13:53:52.000Z","size":2236,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-25T02:23:06.505Z","etag":null,"topics":["all-in-one","chartmuseum","cicd","cluster","docker","git","gitea","helm","jenkins","kind","kubernetes","registry"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mingslife.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-02-22T04:01:48.000Z","updated_at":"2022-03-31T07:05:29.000Z","dependencies_parsed_at":"2024-03-31T06:37:08.495Z","dependency_job_id":null,"html_url":"https://github.com/mingslife/all-in-kind","commit_stats":null,"previous_names":["mingslife/all-in-kind"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mingslife/all-in-kind","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingslife%2Fall-in-kind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingslife%2Fall-in-kind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingslife%2Fall-in-kind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingslife%2Fall-in-kind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mingslife","download_url":"https://codeload.github.com/mingslife/all-in-kind/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingslife%2Fall-in-kind/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32677926,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["all-in-one","chartmuseum","cicd","cluster","docker","git","gitea","helm","jenkins","kind","kubernetes","registry"],"created_at":"2024-11-07T01:30:39.915Z","updated_at":"2026-05-06T03:32:04.785Z","avatar_url":"https://github.com/mingslife.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# All in KIND\n\n中文 | [English](README_en.md)\n\n这个项目旨在教你使用 [Kind](https://github.com/kubernetes-sigs/kind) 快速在你的个人计算机上构建全功能的 Kubernetes 集群。\n\n你可以跟着这个教程一步一步学习构建一个生产完备的 Kubernetes 集群。\n\n由于它是基于 Kind，所以首先，你得确保你的计算机已经安装了 Docker。\n\n## 安装 Kind\n\n该部分的内容参考自 Kind 的[官方文档](https://github.com/kubernetes-sigs/kind#installation-and-usage).\n\n在 Linux 上：\n\n```bash\ncurl -Lo /usr/local/bin/kind \"https://kind.sigs.k8s.io/dl/v0.11.1/kind-$(uname)-amd64\"\nchmod +x /usr/local/bin/kind\n```\n\n在 macOS 上（使用 Homebrew）:\n```bash\nbrew install kind\n```\n\n在 Windows 上（使用 Chocolatey）:\n```powershell\nchoco install kind\n\n# 或者你也可以试试 winget 这个微软官方出品的包管理工具 :)\n```\n\n## 创建集群\n\n为了方便网络访问和持久化（生产中应尽量使用网络存储，如 NFS 等），我写了一个配置文件“[config.yaml](config.yaml)”，告诉 Kind 暴露 80 和 443 端口，并且挂载了一个目录到容器里，这个目录的路径为“/root/kind”，你可以替换成你想要存储你数据的地方。\n\n```bash\nkind create cluster --config config.yaml\n```\n\n可能还不到 5 分钟时间（除去下载 Kind 镜像的时间），我们就得到了一个本地 Kubernetes 集群。爽！！\n\n## 安装 ingress\n\n我们使用 Nginx Ingress 作为 Kubernetes Ingress 组件。\n\nNginx Ingress 组件安装的描述文件在“[ingress-nginx.yaml](ingress-nginx.yaml)”，修改自[这里](https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml)（主要是将镜像源改为国内，让你尽量不需要魔法上网就能愉快食用）。\n\n```bash\nkubectl apply -f ingress-nginx.yaml\n```\n\n## 搭建基础设施\n\n```bash\n# 创建基础设施放置的命名空间\nkubectl create namespace infra\n\n# 安装私有镜像仓库 Registry\nkubectl apply -f infra/registry.yaml -n infra\n\n# 等待 Registry 安装完毕之后，你可以通过如下命令获取访问镜像仓库的用户名和密码\nkubectl rollout status deployment registry -n infra\nexport REGISTRY_POD_NAME=$(kubectl get pod -l app=registry -n infra -o jsonpath='{.items[0].metadata.name}')\nexport REGISTRY_LOG=$(kubectl logs $REGISTRY_POD_NAME -n infra | grep \"password=\")\nexport REGISTRY_PASSWORD=$(echo ${${REGISTRY_LOG#*password=}% user=docker*})\necho \"Username: docker\\nPassword: $REGISTRY_PASSWORD\"\n\n# 安装 Chartmuseum\nkubectl apply -f infra/chartmuseum.yaml -n infra\n\n# TODO EFK\n```\n\n## CI/CD 搭建\n\n在这个部分，将讲述如何使用 Git 和 Jenkins 进行项目 CI/CD 的配置。\n\n### 安装 Gitea\n\n这里选用了 [Gitea](https://github.com/go-gitea/gitea) 这个开源的 Git 管理平台作为我们存储项目代码的地方，它是用 Go 编写的，最初是由 [Gogs](https://github.com/gogs/gogs) 项目 fork 而来。选择它是因为它足够轻量，占用资源少，且上手简单。当然，你也可以使用 GitLab 之类的版本管理平台进行私有部署，或者直接使用公用的 [GitHub](https://github.com/)、[GitLab](https://about.gitlab.com/)、[Gitee](https://gitee.com/) 等等。\n\n```bash\nkubectl apply -f infra/gitea.yaml -n infra\n```\n\n等待 Gitea 的 Kubernetes 资源都创建完毕后，我们还需要用浏览器访问 [http://gitea.localhost](http://gitea.localhost)，也就是 Gitea 的首页，进行配置安装。\n\n![Gitea](screenshots/gitea.png)\n\n为了后续 Jenkins 能够拉取到我们项目的代码，我们还需要创建一下我们的 Git SSH Key，我们可以通过如下命令进行生成：\n\n```bash\nssh-keygen -t rsa -f jenkins_rsa_key -C jenkins -P ''\n```\n\n然后我们就会得到“jenkins_rsa_key”和“jenkins_rsa_key.pub”两个文件，分别存放我们的私钥和公钥。\n\n回到 Gitea 的页面中，我们点击右上角用户头像，选择“设置”，找到“SSH / GPG 密钥”并点击进入，然后点击“增加密钥”，“密钥名称”随意输入，我这边输入的是“jenkins”，然后在“密钥内容”里输入公钥“jenkins_rsa_key.pub”里的文件内容，最后点击“增加密钥”即可。\n\n### 安装 Jenkins\n\n```bash\nkubectl apply -f jenkins/jenkins.yaml\n\n# 创建 Jenkins 拉取 Pod 镜像的 Kubernetes Secret\nkubectl create secret docker-registry regcred \\\n  --docker-server=http://registry.infra.svc.cluster.local:5000/v1/ \\\n  --docker-username=docker \\\n  --docker-password=$REGISTRY_PASSWORD \\\n  -n jenkins\n```\n\n类似的，等待 Jenkins 的 Kubernetes 资源都创建完毕后，我们还需要用浏览器访问 [http://jenkins.localhost](http://jenkins.localhost)，也就是 Jenkins 的首页，进行配置安装。\n\n初次进入 Jenkins 的首页，我们需要输入 Jenkins 初始化管理员密码，这个我们可以通过下面的方式获取到：\n\n```bash\n# 获取 Jenkins 初始化管理员密码\nkubectl rollout status deployment jenkins -n jenkins\nexport JENKINS_POD_NAME=$(kubectl get pod -l app=jenkins -n jenkins -o jsonpath='{.items[0].metadata.name}')\nexport JENKINS_PASSWORD=$(kubectl exec $JENKINS_POD_NAME -n jenkins -- cat /var/jenkins_home/secrets/initialAdminPassword)\necho $JENKINS_PASSWORD\n```\n\n输入密码之后，我们点“继续”，来到下一步，这个时候 Jenkins 会让我们选择要安装的插件，我们选择“安装推荐的推荐”，然后只要等待插件安装完成即可。\n\n等待插件安装完毕后，Jenkins 会要求我们创建管理员用户，这里为了方便，我们直接选择“使用 admin 账户继续”，用这种方式的话，管理员密码会沿用之前的 Jenkins 初始化管理员密码，我们也可以在此后重置它。\n\n接着 Jenkins 会提示我们配置 Jenkins URL，这个地方我们输入“[http://jenkins.localhost](http://jenkins.localhost)”，也就是我们在 Jenkins Ingress 配置的域名，然后点击“保存并完成”。\n\n至此，Jenkins 的初始化配置过程已经完成，接下来我们需要配置的 Kubernetes 构建节点。\n\n如果上面的步骤都顺利进行了，那么这个时候网页会自动跳转到 Jenkins 首页，我们在 Jenkins 首页左侧菜单里点击进入到“系统管理”，然后在“管理 Jenkins”页面里找到“插件管理”的模块并点击进入，然后点击“可选插件”选项页，然后找到“Kubernetes plugin”和“Generic Webhook Trigger Plugin”（方便在我们推送项目代码的时候自动触发构建过程）进行安装（可利用搜索去更快找到需要的插件），安装完毕之后按照提示重启我们的 Jenkins。\n\n待 Jenkins 重启完毕后，我们再一次进入到“管理 Jenkins”页面，找到“Manage Credentials”模块并点击进入。然后在“Stores scoped to Jenkins”列表里的域那一列，找到“全局”，点击进入“全局凭据”页面，点击左侧菜单里的“添加凭据”，我们需要通过这里新增以下两个凭据：\n\n1. Git SSH 密钥：类型为“SSH Username with private key”，描述可随意，我们填入“git”，“Username”填入“jenkins”，“Private Key”选择“Enter directly”，然后填入我们生成的 SSH 密钥（前面生成的“jenkins_rsa_key”里的内容）。\n2. Jenkins WebHook Trigger 的统一口令：类型为“Secret text”，描述可随意，我们填入“trigger”，然后填入我们自定的口令。\n\n我们再回到“管理 Jenkins”页面，找到“节点管理”的模块并点击进入，然后在左侧菜单里点击进入到“Configure Clouds”，并按照下图进行配置（注意，有些选项是默认隐藏起来的，需要我们点击详情进行详细配置）：\n\n![Jenkins Kubernetes](screenshots/jenkins-kubernetes.png)\n\n填写完毕之后点击“Save”进行保存。\n\n接下来我们回到终端上，准备 Jenkins Kubernetes 构建节点的 Docker 镜像构建。\n\n我们的构建过程中需要用到 [kaniko](https://github.com/GoogleContainerTools/kaniko)、[kubectl](https://github.com/kubernetes/kubectl)、[helm](https://github.com/helm/helm) 等工具，为了方便，我们选择构建我们自定义的构建节点的 Docker 镜像。镜像相关的文件（包括构建和部署的脚本）我放在了“jenkins/slave”目录下，你可以进入到这个目录并进行镜像的构建。\n\n```bash\ncd jenkins/slave\n\n# 直接用 docker build 命令进行构建\ndocker build -t registry.localhost/slave-kubernetes:0.0.1 .\n\n# 或者你也可以用 docker-compose build 进行构建\ndocker-compose build\n```\n\n然后为了让 Jenkins 在进行构建时，能够找到我们的镜像，我们还需要把镜像推送到我们指定的镜像仓库里，前面我们已经用 Registry 搭建了一个我们私有的 Docker 镜像仓库，我们可以登录到我们的镜像仓库，然后推送上去：\n\n```bash\n# 登录到我们的私有 Docker 镜像仓库\ndocker login registry.localhost\n# 输入我们在搭建时获取到的用户名和密码\n\ndocker push registry.localhost/slave-kubernetes:0.0.1\n```\n\n由于我们镜像仓库用的是 http 协议，而 docker login 默认是用的 https 协议，所以在我们登录的时候，应该是会验证失败，我们只需要在 Docker 配置文件（一般会放在“/etc/docker/daemon.json”）把我们的镜像仓库加入到“insecure-registries”即可，就像这样：\n\n```json\n{\n  \"insecure-registries\": [\n    \"registry.localhost\"\n  ]\n}\n```\n\n然后我们重启下 Docker 再重新登录推送即可。\n\n```bash\n# 重启 Docker\nservice docker restart\n```\n\n### 创建 Kubernetes 集群角色\n\n为了方便后边我们项目的部署和调试，我们可以创建 clusterrole-deployer 和 clusterrole-debugger 这两个 Kubernetes 集群角色，这两个角色已经分别配置了部署和调试时我们需要访问的 Kubernetes 资源权限，后边我们创建项目的服务账号的时候可以直接建立权限关联，具体可以参考 [clusterrole.yaml](clusterrole.yaml)。\n\n```bash\n# 创建 Kubernetes 集群角色\nkubectl apply -f clusterrole.yaml\n```\n\n## 项目配置\n\n在这里，我们用一个简单的 Web 静态网站来做示范，并将该项目命名为“sample”。\n\n### 创建仓库\n\n在浏览器地址栏里输入“[http://gitea.localhost](http://gitea.localhost)”回车进入到 Gitea，点击右上角的加号，选择“创建仓库”，并按照下图进行信息填写并创建仓库。\n\n![Sample Gitea](screenshots/sample-gitea.png)\n\n创建完仓库之后，我们还要在 Gitea 上配置 Jenkins 的 Webhook，使得在我们推送项目代码的时候，自动触发构建流水线。\n\n我们在项目 Gitea 仓库页面右上角找到“设置”，点击之后选择“Web 钩子”，然后点击右侧“添加 Web 钩子”，选择“Gitea”。\n\n在“添加 Web 钩子”的表单中，在“目标 URL”中填入“[http://master.jenkins.svc.cluster.local:8080/generic-webhook-trigger/invoke?token=\u003cJenkins WebHook Trigger 的统一口令\u003e](http://master.jenkins.svc.cluster.local:8080/generic-webhook-trigger/invoke)”。在“密钥文本”中填入触发项目构建的 Webhook 的项目独立口令（注意区分前面的统一口令，不是同一个），这里我设置的是“tri99er-s3cret-0f-sample”。在“分支过滤”中填入“{master,release*}”，意为仅在生产分支和测试分支（这里用的 git-flow 规范，了解详情请点击[这里](https://www.git-tower.com/learn/git/ebook/cn/command-line/advanced-topics/git-flow/)）有变动时才触发流水线构建。\n\n最后点击下面的“添加 Web 钩子”按钮即可完成 Webhook 的配置。\n\n### 创建命名空间和服务账号\n\n```bash\nexport NAMESPACE_NAME=\"sample-test\"\n\n# 创建命名空间\nkubectl create namespace $NAMESPACE_NAME\n\n# 创建从私有仓库拉取镜像的凭证\nkubectl create secret docker-registry regcred \\\n  --docker-server=http://registry.infra.svc.cluster.local:5000/v1/ \\\n  --docker-username=docker \\\n  --docker-password=$REGISTRY_PASSWORD \\\n  -n $NAMESPACE_NAME\n\n# 创建调试和部署的服务账号\nkubectl create serviceaccount deployer -n $NAMESPACE_NAME\nkubectl create serviceaccount debugger -n $NAMESPACE_NAME\n\n# 将服务账号和对应的权限关联起来\nkubectl create rolebinding deployer --clusterrole=deployer --serviceaccount=$NAMESPACE_NAME:deployer -n $NAMESPACE_NAME\nkubectl create rolebinding debugger --clusterrole=debugger --serviceaccount=$NAMESPACE_NAME:debugger -n $NAMESPACE_NAME\n\n# 获取部署服务账号的口令\nexport DEPLOYER_SECRET_NAME=$(kubectl get serviceaccount deployer -n $NAMESPACE_NAME -o jsonpath='{.secrets[0].name}')\nexport DEPLOYER_TOKEN=$(kubectl get secret $DEPLOYER_SECRET_NAME -n $NAMESPACE_NAME -o jsonpath='{.data.token}' | base64 -d)\n```\n\n### 配置流水线\n\n在浏览器地址栏里输入“[http://jenkins.localhost](http://jenkins.localhost)”回车进入到 Jenkins，点击左侧菜单里的“新建任务”，输入任务名称“sample”，选择“流水线”，点击“确定”进入到流水线配置，并按照下图进行信息填写并保存。\n\n![Sample Jenkins](screenshots/sample-jenkins.png)\n\n### 编写项目代码\n\n```bash\n# 克隆项目仓库\ngit clone http://gitea.localhost/gitea/sample.git\n# 输入 Gitea 的账号密码\n\ncd sample\n\n# 由于在 Jenkins 流水线配置了只有在 release 分支推送了代码才会触发构建，所以我们需要切换到 release 分支\ngit checkout release/0.0.1\n\necho \"Hello world\" \u003e index.html\ncat \u003e Dockerfile \u003c\u003c EOF\nFROM nginx:alpine\nCOPY index.html /usr/share/nginx/html/\nEOF\n\n# 创建构建时的环境变量配置\ncat \u003e .env \u003c\u003c EOF\nexport APP_NAME=sample\nexport APP_VERSION=0.0.1\nEOF\n\n# 创建 Helm chart\nmkdir chart \u0026\u0026 cd chart\nhelm create sample\ncat \u003e sample/values.yaml \u003c\u003c EOF\nreplicaCount: 1\n\nimage:\n  repository: registry.infra.svc.cluster.local:5000/gitea/sample\n  pullPolicy: IfNotPresent\n  tag: \"\"\n\nimagePullSecrets:\n- name: regcred\nnameOverride: \"\"\nfullnameOverride: \"\"\n\nserviceAccount:\n  create: true\n  annotations: {}\n  name: \"\"\n\npodAnnotations: {}\n\npodSecurityContext: {}\n\nsecurityContext: {}\n\nservice:\n  type: ClusterIP\n  port: 80\n\ningress:\n  enabled: true\n  className: \"\"\n  annotations: {}\n  hosts:\n    - host: sample.localhost\n      paths:\n        - path: /\n          pathType: ImplementationSpecific\n  tls: []\n\nresources: {}\n\nautoscaling:\n  enabled: false\n\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}\nEOF\n\ncat \u003e sample/Chart.yaml \u003c\u003c EOF\napiVersion: v2\nname: sample\ndescription: Sample Helm chart for Kubernetes\ntype: application\nversion: 0.1.0\nappVersion: \"0.0.1\"\nEOF\ncd ..\n\ngit add .\ngit commit -m \"Initial commit\"\n\n# 推送项目代码\ngit push origin release/0.0.1\n```\n\n## 参考\n\n* [kind](https://kind.sigs.k8s.io/)\n* [Docker Registry | Docker Documentation](https://docs.docker.com/registry/)\n* [ChartMuseum - Helm Chart Repository](https://chartmuseum.com/)\n* [Jenkins](https://www.jenkins.io/)\n* [Gitea](https://gitea.io/en-us/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmingslife%2Fall-in-kind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmingslife%2Fall-in-kind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmingslife%2Fall-in-kind/lists"}