本文基于 knative 文档中的 Orchestrating a source-to-URL deployment on Kubernetes 的简单例子,经过从源码到 URL 的部署流程一窥 Knative 给 Kubernetes 带来的改变。node
源码的构建是由 Knative build 子系统完成的,一般咱们须要在构建配置中定义一些构建步骤(step),经过这些构建步骤一步步地处理源码,详细能够参考 Knative Build resources。但 Knative 也支持使用多种构建模板,下文就介绍如何使用 kaniko 构建模板完成示例代码的构建。git
本示例借助 kaniko build template 来在你的 Kubernetes 集群上执行一次“从源码到容器”的构建。github
kaniko 是谷歌开源的用于从 Dockerfile 构建容器镜像的工具。它的特色在于不依赖 Docker daemon,并在用户空间内执行 Dockerfile 中的每一行命令。这使得在一些不能方便地或安全地运行 Docker daemon 的环境中,如标准 Kubernetes 集群中,也能构建容器镜像。docker
使用 kubectl 来安装 kaniko:编程
kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
复制代码
为了将从源代码构建获得的容器推送到 Docker Hub,须要在 Kubernetes 上登记密钥用于认证 Docker Hub。json
关于 Knative 中的认证,这是详细的说明,下面是几个关键步骤:api
建立一个 Secret
配置,用于存放你的 Docker Hub 认证信息。将文件保存为 docker-secret.yaml
:安全
apiVersion: v1
kind: Secret
metadata:
name: basic-user-pass
annotations:
build.knative.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
data:
# Use 'echo -n "username" | base64' to generate this string
username: BASE64_ENCODED_USERNAME
# Use 'echo -n "password" | base64' to generate this string
password: BASE64_ENCODED_PASSWORD
复制代码
上面的配置中,username
和 password
都是须要 base64 加密的。在 macOS 或 Linux 系统中,用下面的命令能够生成 base64 编码的值:bash
echo -n "username" | base64 -w 0
echo -n "password" | base64 -w 0
复制代码
注意:若是在 macOS 上提示 "invalid option -w" 错误,试着改为
base64 -b 0
。网络
建立一个Service Account
配置,用于将构建进程连接到Secret
。将文件保存为service-account.yaml
:
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-bot
secrets:
- name: basic-user-pass
复制代码
建立好配置文件后,经过kubectl
将它们应用到你的集群:
kubectl apply -f docker-secret.yaml
kubectl apply -f service-account.yaml
复制代码
本示例使用 github.com/mchmarny/si… 做为一个基础 Go 应用,但你也能够替换为你本身的 GitHub 项目。惟一要注意的是,项目必须包含一个Dockerfile
来描述如何为应用构建一个容器。
须要建立一个 service 配置来定义服务如何部署,包括源代码在哪儿、使用哪一个构建模板。建立service.yaml
并复制以下定义。将{DOCKER_USERNAME}
替换为你本身的 Docker Hub 用户名:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: app-from-source
namespace: default
spec:
runLatest:
configuration:
build:
apiVersion: build.knative.dev/v1alpha1
kind: Build
spec:
serviceAccountName: build-bot
source:
git:
url: https://github.com/mchmarny/simple-app.git
revision: master
template:
name: kaniko
arguments:
- name: IMAGE
value: docker.io/{DOCKER_USERNAME}/app-from-source:latest
revisionTemplate:
spec:
container:
image: docker.io/{DOCKER_USERNAME}/app-from-source:latest
imagePullPolicy: Always
env:
- name: SIMPLE_MSG
value: "Hello from the sample app!"
复制代码
使用kubectl
应用配置,并观察结果:
kubectl apply -f service.yaml
kubectl get po --watch
复制代码
输出相似于:
NAME READY STATUS RESTARTS AGE
app-from-source-00001-zhddx 0/1 Init:2/3 0 7s
app-from-source-00001-zhddx 0/1 PodInitializing 0 37s
app-from-source-00001-zhddx 0/1 Completed 0 38s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Pending 0 0s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Pending 0 0s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Init:0/1 0 0s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Init:0/1 0 2s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 PodInitializing 0 3s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 2/3 Running 0 6s
app-from-source-00001-deployment-6d6ff665f9-xfhm5 3/3 Running 0 11s
复制代码
能看到先是app-from-source-00001
启动,执行“从源码到镜像”的过程,再启动app-from-source-00001-deployment
拉取镜像,提供服务。
须要特别说明的是,笔者这个步骤失败了屡次,都是
app-from-source-00001
初始化过程意外退出。经过kubectl describe
查看详细信息,提示构建超时(默认构建超时是10分钟)。构建过程须要拉取一些镜像,推测可能因为网络缘由,该步骤耗时过长。能够在构建过程当中,经过kubectl describe po app-from-source-00001-zhddx
查看相关 Event,找到构建具体是在哪一步耗时过长。笔者最后多试几回成功了:)
当你看到 deployment pod 变为Running
状态时,Ctrl+C
退出观察。此时你的容器已经完成构建和部署了!
要检查服务的状态,能够
kubectl get ksvc app-from-source --output yaml
复制代码
当你建立服务时,Knative 随即执行如下步骤:
revision
指定的代码并构建到容器中revision
route
、ingress
、service
和负载均衡服务要获取你的集群的入口 IP,使用以下命令。若是你的集群是新建的,服务获取一个外部 IP 地址可能会花一些时间:
# In Knative 0.2.x and prior versions, the `knative-ingressgateway` service was used instead of `istio-ingressgateway`.
INGRESSGATEWAY=knative-ingressgateway
# The use of `knative-ingressgateway` is deprecated in Knative v0.3.x.
# Use `istio-ingressgateway` instead, since `knative-ingressgateway`
# will be removed in Knative v0.4.
if kubectl get configmap config-istio -n knative-serving &> /dev/null; then
INGRESSGATEWAY=istio-ingressgateway
fi
kubectl get svc $INGRESSGATEWAY --namespace istio-system
复制代码
须要注意的是,minikube 搭建的集群经过上面的方式是获取不到外部 IP 的。应该执行:
echo $(minikube ip):$(kubectl get svc $INGRESSGATEWAY --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}')
复制代码
要找到服务的 URL,输入:
kubectl get ksvc app-from-source --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
复制代码
如今你能够向你的应用发送一个请求来看看结果。将{IP_ADDRESS}
替换为你上一步得到的地址:
curl -H "Host: app-from-source.default.example.com" http://{IP_ADDRESS}
复制代码
要从你的集群移除示例应用,删除服务记录:
kubectl delete -f service.yaml
复制代码