基于 Kubernetes 的云原生 DevOps 第 2 章 Kubernetes 简介
🏷️ Kubernetes 《基于 Kubernetes 的云原生 DevOps》
To do anything truly worth doing, I must not stand back shivering and thinking of the cold and danger, but jump in with gusto and scramble through as well as I can.
-- Og Mandion
2.1 第一次运行容器
容器是云原生开发的关键概念之一,而 Docker 是构建和运行容器的基本工具。
下载 Docker 并安装。
查看 docker 版本:
docker version
Docker 是几种相互关联的不同事物:容器镜像格式、容器运行时库(管理容器的生命周期)、命令行工具(用于打包和运行容器)以及用于容器管理的 API。
可以将容器镜像视为 ZIP 文件。容器镜像是一个二进制文件,拥有唯一的 ID,其中包含运行容器所需的一切。
无论是直接使用 Docker 还是在 Kubernetes 集群上运行容器,你只需指定容器镜像 ID 或 URL,系统就会为你查找、下载、解压并启动容器。
启动示例容器:
docker container run -p 9999:8888 --name hello cloudnatived/demo:hello
保持命令运行,并在浏览器打开 http://localhost:9999/ 。
Hello, 世界
在终端按下 Ctrl-C
停止容器。
2.2 演示应用程序
下载示例代码:
git clone https://github.com/cloudnativedevops/demo
示例代码使用 Go 语言编写的,代码这里就不贴了,有兴趣的可以自己下载下来试试。
Kubernetes 本身是用 Go 编写的,而且 Docker、Terraform 和许多其他流行的开源项目也是如此。因此 Go 是云原生应用程序开发不错的选择。
2.3 建立容器
使用 docker image build
命令构建容器镜像,该命令需要一个名为 Dockerfile 的特殊文件作为输入。 Dockerfile 准确的指明了需要放入容器镜像的内容。
容器的主要优点之一是能够在现有镜像之上建立新镜像。
hello/Dockerfile
FROM golang:1.17-alpine AS build
WORKDIR /src/
COPY main.go go.* /src/
RUN CGO_ENABLED=0 go build -o /bin/demo
FROM scratch
COPY --from=build /bin/demo /bin/demo
COPY --from=busybox:1.28 /bin/busybox /bin/busybox
ENTRYPOINT ["/bin/demo"]
进入 hello 目录构建镜像:
docker image build -t myhello .
构建镜像时,默认情况下镜像会获得一个十六进制 ID,以供之后引用。可以在 build 命令中加入 -t 参数指定一个方便阅读的名字。
运行刚刚创建的镜像:
docker container run -p 9999:8888 myhello
在容器中运行的程序与同一台计算机上运行的其他程序是相互隔离的,这意味着它们无法直接访问网络端口等资源。
可以通过 -p 参数来告诉 Docker 转发端口。
docker container run -p HOST_PORT:CONTAINER_PORT ...
容器运行后,任何发往本地计算机 HOST_PORT 上的请求都将自动转发到容器的 CONTAINER_PORT 上。
2.4 容器仓库
docker container run 命令默认的仓库是 Docker Hub ,但你也可以指定其它的仓库,或者建立自己的仓库。
在 Docker Hub 上注册后,可以推送镜像到自己的仓库:
登录:
docker login
命名镜像:
docker image tag myhello jiajiablog/myhello
推送镜像:
docker image push jiajiablog/myhello
运行镜像:
docker container run -p 9999:8888 jiajiablog/myhello
2.5 Kubernetes 入门
Docker Desktop 默认是带了一个 Kubernetes 的(Setting -> Kubernetes -> Enable Kubernetes),但是我这边启用后状态一直是: KUBERNETES FAILED TO START。
Error invoking remote method 'docker-run-container': Error: (HTTP code 400) unexpected - OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/usr/bin/kubelet.sh": stat /usr/bin/kubelet.sh: no such file or directory: unknown
Docker desktop - kubernetes failed to start
I tried numerous different changes to fix docker desktop kubernetes failing to start. What finally worked for me is...
Clicked the troubleshooting icon (it's a bug icon) and then chose Clean/Purge Data.*
按照上面的设置后仍然不起作用,最后安装了 Minikube 来启动 Kubernetes。
Minikube
可以在 minikube start 上直接下载对应的安装包,也可以直接在 PowerShell 运行如下脚本安装。
New-Item -Path 'c:\' -Name 'minikube' -ItemType Directory -Force
Invoke-WebRequest -OutFile 'c:\minikube\minikube.exe' -Uri 'https://github.com/kubernetes/minikube/releases/latest/download/minikube-windows-amd64.exe' -UseBasicParsing
如果实在下载不下来,可以使用我下载的 minikube 1.25.2 安装包 minikube-installer.zip 。解压后安装到 C:\minikube 目录。
修改 Path 环境变量:
$oldPath = [Environment]::GetEnvironmentVariable('Path', [EnvironmentVariableTarget]::Machine)
if ($oldPath.Split(';') -inotcontains 'C:\minikube'){ `
[Environment]::SetEnvironmentVariable('Path', $('{0};C:\minikube' -f $oldPath), [EnvironmentVariableTarget]::Machine) `
}
启动 minikube (以管理员身份运行 PowerShell):
minikube start
访问集群:
kubectl get po -A
启动 Kubernetes Dashboard:
minikube dashboard
启动 demo:hello 示例项目:
kubectl run myhello --image=jiajiablog/myhello --port=9999 --labels app=myhello
待容器启动后,通过 kubectl port-forward 命令转发本地的 9999 端口到 myhello Pod 的 8888 端口。
kubectl port-forward pod/myhello 9999:8888
2.7 小结
- 本书附带的演示代码库(https://github.com/cloudnativedevops/demo)提供了所有源代码示例。
- 你可以利用 Docker 工具在本地构建容器,然后推送到 Docker Hub 等容器仓库,或从中拉取镜像,并在你指定的计算机本地运行容器镜像。
- 容器镜像完全由 Dockerfile 指定:这是一个文本文件,其中包含有关如何构建容器的指令。
- 你可以利用 Docker 桌面版在自己的机器上运行一个小型(单节点)Kubernetes 集群,而且该集群能够运行任何容器化的应用程序。此外还有另一种选择:Minikube。
- kubectl 工具是与 Kubernetes 集群交互的主要方式,你可以通过命令式的方式(例如运行公共容器镜像并隐式地创建必要的 Kubernetes 资源),或声明式的方式,利用 YAML 清单应用 Kubernetes 的配置。