update summary
parent
78ca17b2d4
commit
efca2855d9
14
SUMMARY.md
14
SUMMARY.md
|
@ -19,9 +19,9 @@
|
||||||
* [Application Scope](cloud-native/application-scope.md)
|
* [Application Scope](cloud-native/application-scope.md)
|
||||||
* [Application Configuration](cloud-native/application-configuration.md)
|
* [Application Configuration](cloud-native/application-configuration.md)
|
||||||
* [Crossplane](cloud-native/crossplane.md)
|
* [Crossplane](cloud-native/crossplane.md)
|
||||||
* [云原生编程语言](cloud-native/cloud-native-programming-languages.md)
|
* [云原生平台配置语言](cloud-native/cloud-native-programming-languages.md)
|
||||||
* [云原生编程语言 Ballerina](cloud-native/cloud-native-programming-language-ballerina.md)
|
* [Ballerina](cloud-native/cloud-native-programming-language-ballerina.md)
|
||||||
* [云原生编程语言 Pulumi](cloud-native/cloud-native-programming-language-pulumi.md)
|
* [Pulumi](cloud-native/cloud-native-programming-language-pulumi.md)
|
||||||
* [云原生的未来](cloud-native/the-future-of-cloud-native.md)
|
* [云原生的未来](cloud-native/the-future-of-cloud-native.md)
|
||||||
|
|
||||||
## 快速入门
|
## 快速入门
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
## 概念与原理
|
## 概念与原理
|
||||||
|
|
||||||
* [Kubernetes 架构](concepts/index.md)
|
* [Kubernetes 架构](concepts/index.md)
|
||||||
* [设计理念](concepts/concepts.md)
|
* [Kubernetes 的设计理念](concepts/concepts.md)
|
||||||
* [Etcd 解析](concepts/etcd.md)
|
* [Etcd 解析](concepts/etcd.md)
|
||||||
* [开放接口](concepts/open-interfaces.md)
|
* [开放接口](concepts/open-interfaces.md)
|
||||||
* [容器运行时接口(CRI)](concepts/cri.md)
|
* [容器运行时接口(CRI)](concepts/cri.md)
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
* [使用 CRD 扩展 Kubernetes API](concepts/crd.md)
|
* [使用 CRD 扩展 Kubernetes API](concepts/crd.md)
|
||||||
* [Aggregated API Server](concepts/aggregated-api-server.md)
|
* [Aggregated API Server](concepts/aggregated-api-server.md)
|
||||||
* [APIService](concepts/apiservice.md)
|
* [APIService](concepts/apiservice.md)
|
||||||
* [Service Catalog](concepts/service-catalog.md)
|
* [服务目录(Service Catalog)](concepts/service-catalog.md)
|
||||||
* [多集群管理](concepts/multicluster.md)
|
* [多集群管理](concepts/multicluster.md)
|
||||||
* [多集群服务 API(Multi-Cluster Services API)](concepts/multi-cluster-services-api.md)
|
* [多集群服务 API(Multi-Cluster Services API)](concepts/multi-cluster-services-api.md)
|
||||||
* [集群联邦(Cluster Federation)](practice/federation.md)
|
* [集群联邦(Cluster Federation)](practice/federation.md)
|
||||||
|
@ -131,8 +131,7 @@
|
||||||
* [通过端口转发访问集群中的应用程序](guide/connecting-to-applications-port-forward.md)
|
* [通过端口转发访问集群中的应用程序](guide/connecting-to-applications-port-forward.md)
|
||||||
* [使用 service 访问群集中的应用程序](guide/service-access-application-cluster.md)
|
* [使用 service 访问群集中的应用程序](guide/service-access-application-cluster.md)
|
||||||
* [从外部访问 Kubernetes 中的 Pod](guide/accessing-kubernetes-pods-from-outside-of-the-cluster.md)
|
* [从外部访问 Kubernetes 中的 Pod](guide/accessing-kubernetes-pods-from-outside-of-the-cluster.md)
|
||||||
* [Cabin - Kubernetes 手机客户端](guide/cabin-mobile-dashboard-for-kubernetes.md)
|
* [Lens - Kubernetes IDE](guide/kubernetes-desktop-client.md)
|
||||||
* [Lens - Kubernetes IDE/桌面客户端](guide/kubernetes-desktop-client.md)
|
|
||||||
* [Kubernator - 更底层的 Kubernetes UI](guide/kubernator-kubernetes-ui.md)
|
* [Kubernator - 更底层的 Kubernetes UI](guide/kubernator-kubernetes-ui.md)
|
||||||
* [在 Kubernetes 中开发部署应用](guide/application-development-deployment-flow.md)
|
* [在 Kubernetes 中开发部署应用](guide/application-development-deployment-flow.md)
|
||||||
* [适用于 Kubernetes 的应用开发部署流程](guide/deploy-applications-in-kubernetes.md)
|
* [适用于 Kubernetes 的应用开发部署流程](guide/deploy-applications-in-kubernetes.md)
|
||||||
|
@ -194,7 +193,6 @@
|
||||||
* [Prometheus](practice/prometheus.md)
|
* [Prometheus](practice/prometheus.md)
|
||||||
* [使用 Prometheus 监控 Kubernetes 集群](practice/using-prometheus-to-monitor-kuberentes-cluster.md)
|
* [使用 Prometheus 监控 Kubernetes 集群](practice/using-prometheus-to-monitor-kuberentes-cluster.md)
|
||||||
* [Prometheus 查询语言 PromQL 使用说明](practice/promql.md)
|
* [Prometheus 查询语言 PromQL 使用说明](practice/promql.md)
|
||||||
* [使用 Vistio 监控 Istio 服务网格中的流量](practice/vistio-visualize-your-istio-mesh.md)
|
|
||||||
* [分布式追踪](practice/distributed-tracing.md)
|
* [分布式追踪](practice/distributed-tracing.md)
|
||||||
* [OpenTracing](practice/opentracing.md)
|
* [OpenTracing](practice/opentracing.md)
|
||||||
* [服务编排管理](practice/services-management-tool.md)
|
* [服务编排管理](practice/services-management-tool.md)
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
CNCF 生态中的诸多应用都已支持 Kubernetes Operator,可以说 Operator 将成为云原生中默认的软件动态运行时管理工具,参考 CoreOS(已被 RedHat 收购,RedHat 已被 IBM 收购) CTO Brandon Philips 的这篇文章 [Introducing the Operator Framework: Building Apps on Kubernetes](https://www.redhat.com/en/blog/introducing-operator-framework-building-apps-kubernetes)。
|
CNCF 生态中的诸多应用都已支持 Kubernetes Operator,可以说 Operator 将成为云原生中默认的软件动态运行时管理工具,参考 CoreOS(已被 RedHat 收购,RedHat 已被 IBM 收购) CTO Brandon Philips 的这篇文章 [Introducing the Operator Framework: Building Apps on Kubernetes](https://www.redhat.com/en/blog/introducing-operator-framework-building-apps-kubernetes)。
|
||||||
|
|
||||||
## ServiceMesher社区
|
## ServiceMesher 社区
|
||||||
|
|
||||||
下图展示的是 2019 Q1 的软件架构趋势,(图片来自 [Architecture and Design InfoQ Trends Report - January 2019](https://www.infoq.com/articles/architecture-trends-2019))我们可以看到 Service Mesh 还处于创新者阶段,如果从软件生命周期的全阶段来看,它还只是刚刚进入很多人的眼帘,对于这张的新兴技术,在蚂蚁金服的支持的下创办了 [ServiceMesher 社区](http://www.servicemesher.com)。
|
下图展示的是 2019 Q1 的软件架构趋势,(图片来自 [Architecture and Design InfoQ Trends Report - January 2019](https://www.infoq.com/articles/architecture-trends-2019))我们可以看到 Service Mesh 还处于创新者阶段,如果从软件生命周期的全阶段来看,它还只是刚刚进入很多人的眼帘,对于这张的新兴技术,在蚂蚁金服的支持的下创办了 [ServiceMesher 社区](http://www.servicemesher.com)。
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
## 社区资源
|
## 社区资源
|
||||||
|
|
||||||
Kubernetes 社区的贡献、交流和治理方式相关的内容都保存在 <https://github.com/kubernetes/community> 这个 repo 中,建议参与 Kubernetes 社区前先阅读该 repo 中的资料。
|
Kubernetes 社区的贡献、交流和治理方式相关的内容都保存在[这个 repo](https://github.com/kubernetes/community) 中,建议参与 Kubernetes 社区前先阅读该 repo 中的资料。
|
||||||
|
|
||||||
在这里你可以找到:
|
在这里你可以找到:
|
||||||
|
|
||||||
|
@ -43,9 +43,8 @@ Kubernetes和Cloud Native相关网站、专栏、博客等。
|
||||||
- [giantswarm blog](https://blog.giantswarm.io/)
|
- [giantswarm blog](https://blog.giantswarm.io/)
|
||||||
- [k8smeetup.com](http://www.k8smeetup.com)
|
- [k8smeetup.com](http://www.k8smeetup.com)
|
||||||
- [dockone.io](http://www.dockone.io)
|
- [dockone.io](http://www.dockone.io)
|
||||||
- [Cloud Native知乎专栏](https://zhuanlan.zhihu.com/cloud-native)
|
- [Cloud Native 知乎专栏](https://zhuanlan.zhihu.com/cloud-native)
|
||||||
- [kubernetes.org.cn](https://www.kubernetes.org.cn/)
|
- [kubernetes.org.cn](https://www.kubernetes.org.cn/)
|
||||||
- [servicemesher.com](https://www.servicemesher.com)
|
|
||||||
|
|
||||||
### 博客
|
### 博客
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
# 快速部署一个云原生本地实验环境
|
# 快速部署一个云原生本地实验环境
|
||||||
|
|
||||||
本文旨在帮助您快速部署一个云原生本地实验环境,让您可以基本不需要任何Kubernetes和云原生技术的基础就可以对云原生环境一探究竟。
|
本文旨在帮助您快速部署一个云原生本地实验环境,让您可以基本不需要任何 Kubernetes 和云原生技术的基础就可以对云原生环境一探究竟。
|
||||||
|
|
||||||
本文中使用[kubernetes-vagrant-centos-cluster](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster)在本地使用 Vagrant 启动三个虚拟机部署分布式的Kubernetes集群。
|
本文中使用 [kubernetes-vagrant-centos-cluster](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster) 在本地使用 Vagrant 启动三个虚拟机部署分布式的 Kubernetes 集群。
|
||||||
|
|
||||||
如仅需要体验云原生环境和测试服务功能,可以使用更加轻量级的[cloud-native-sandbox](https://github.com/rootsongjc/cloud-native-sandbox),通过个人电脑的Docker部署单节点的Kubernetes、Istio等云原生环境。
|
如仅需要体验云原生环境和测试服务功能,可以使用更加轻量级的 [cloud-native-sandbox](https://github.com/rootsongjc/cloud-native-sandbox),通过个人电脑的 Docker 部署单节点的 Kubernetes、Istio 等云原生环境。
|
||||||
|
|
||||||
## 准备环境
|
## 准备环境
|
||||||
|
|
||||||
需要准备以下软件和环境:
|
需要准备以下软件和环境:
|
||||||
|
|
||||||
- 8G以上内存
|
- 8G 以上内存
|
||||||
- [Vagrant 2.0+](https://www.vagrantup.com/)
|
- [Vagrant 2.0+](https://www.vagrantup.com/)
|
||||||
- [VirtualBox 5.0 +](https://www.virtualbox.org/wiki/Downloads)
|
- [VirtualBox 5.0 +](https://www.virtualbox.org/wiki/Downloads)
|
||||||
- 提前下载kubernetes1.9.1以上版本的release压缩包,[至百度网盘下载](https://pan.baidu.com/s/1zkg2xEAedvZHObmTHDFChg)(并将名字中的版本号删除)
|
- 提前下载 Kubernetes1.9.1 以上版本的 release 压缩包,[至百度网盘下载](https://pan.baidu.com/s/1zkg2xEAedvZHObmTHDFChg)(并将名字中的版本号删除)
|
||||||
- Mac/Linux,**不支持Windows**
|
- Mac/Linux,**不支持 Windows**
|
||||||
- 支持Kubernetes1.9以上版本(支持当前Kubernetes最新版本1.11.1)
|
- 支持 Kubernetes1.9 以上版本(支持当前 Kubernetes 最新版本 1.11.1)
|
||||||
|
|
||||||
## 集群
|
## 集群
|
||||||
|
|
||||||
我们使用Vagrant和Virtualbox安装包含3个节点的kubernetes集群,其中master节点同时作为node节点。
|
我们使用 Vagrant 和 VirtualBox 安装包含 3 个节点的 Kubernetes 集群,其中 master 节点同时作为 node 节点。
|
||||||
|
|
||||||
| IP | 主机名 | 组件 |
|
| IP | 主机名 | 组件 |
|
||||||
| ------------ | ------ | ------------------------------------------------------------ |
|
| ------------ | ------ | ------------------------------------------------------------ |
|
||||||
|
@ -52,7 +52,7 @@ Kubernetes service IP范围:10.254.0.0/16
|
||||||
|
|
||||||
## 使用说明
|
## 使用说明
|
||||||
|
|
||||||
确保安装好以上的准备环境后,执行下列命令启动kubernetes集群:
|
确保安装好以上的准备环境后,执行下列命令启动 kubernetes 集群:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster.git
|
git clone https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster.git
|
||||||
|
@ -60,37 +60,37 @@ cd kubernetes-vagrant-centos-cluster
|
||||||
vagrant up
|
vagrant up
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意**:克隆完Git仓库后,需要提前下载kubernetes的压缩包到`kubenetes-vagrant-centos-cluster`目录下,**并将压缩包名字中的版本号删除**,包括如下两个文件:
|
**注意**:克隆完 Git 仓库后,需要提前下载 kubernetes 的压缩包到 `kubenetes-vagrant-centos-cluster` 目录下,**并将压缩包名字中的版本号删除**,包括如下两个文件:
|
||||||
|
|
||||||
- kubernetes-client-linux-amd64.tar.gz
|
- kubernetes-client-linux-amd64.tar.gz
|
||||||
- kubernetes-server-linux-amd64.tar.gz
|
- kubernetes-server-linux-amd64.tar.gz
|
||||||
|
|
||||||
如果是首次部署,会自动下载`centos/7`的box,这需要花费一些时间,另外每个节点还需要下载安装一系列软件包,整个过程大概需要10几分钟。
|
如果是首次部署,会自动下载 `centos/7` 的 box,这需要花费一些时间,另外每个节点还需要下载安装一系列软件包,整个过程大概需要 10 几分钟。
|
||||||
|
|
||||||
如果您在运行`vagrant up`的过程中发现无法下载`centos/7`的box,可以手动下载后将其添加到vagrant中。
|
如果您在运行 `vagrant up` 的过程中发现无法下载 `centos/7` 的 box,可以手动下载后将其添加到 vagrant 中。
|
||||||
|
|
||||||
**手动添加centos/7 box**
|
**手动添加 centos/7 box**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -c http://cloud.centos.org/centos/7/vagrant/x86_64/images/CentOS-7-x86_64-Vagrant-1801_02.VirtualBox.box
|
wget -c http://cloud.centos.org/centos/7/vagrant/x86_64/images/CentOS-7-x86_64-Vagrant-1801_02.VirtualBox.box
|
||||||
vagrant box add CentOS-7-x86_64-Vagrant-1801_02.VirtualBox.box --name centos/7
|
vagrant box add CentOS-7-x86_64-Vagrant-1801_02.VirtualBox.box --name centos/7
|
||||||
```
|
```
|
||||||
|
|
||||||
这样下次运行`vagrant up`的时候就会自动读取本地的`centos/7` box而不会再到网上下载。
|
这样下次运行 `vagrant up` 的时候就会自动读取本地的 `centos/7` box 而不会再到网上下载。
|
||||||
|
|
||||||
### 访问kubernetes集群
|
### 访问 kubernetes 集群
|
||||||
|
|
||||||
访问Kubernetes集群的方式有三种:
|
访问 Kubernetes 集群的方式有三种:
|
||||||
|
|
||||||
- 本地访问
|
- 本地访问
|
||||||
- 在VM内部访问
|
- 在 VM 内部访问
|
||||||
- kubernetes dashboard
|
- kubernetes dashboard
|
||||||
|
|
||||||
**通过本地访问**
|
**通过本地访问**
|
||||||
|
|
||||||
可以直接在你自己的本地环境中操作该kubernetes集群,而无需登录到虚拟机中,执行以下步骤:
|
可以直接在你自己的本地环境中操作该 kubernetes 集群,而无需登录到虚拟机中,执行以下步骤:
|
||||||
|
|
||||||
将`conf/admin.kubeconfig`文件放到`~/.kube/config`目录下即可在本地使用`kubectl`命令操作集群。
|
将 `conf/admin.kubeconfig` 文件放到 `~/.kube/config` 目录下即可在本地使用 `kubectl` 命令操作集群。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.kube
|
mkdir -p ~/.kube
|
||||||
|
@ -111,69 +111,69 @@ kubectl get nodes
|
||||||
|
|
||||||
**Kubernetes dashboard**
|
**Kubernetes dashboard**
|
||||||
|
|
||||||
还可以直接通过dashboard UI来访问:https://172.17.8.101:8443
|
还可以直接通过 dashboard UI 来访问:[https://172.17.8.101:8443](https://172.17.8.101:8443/)
|
||||||
|
|
||||||
可以在本地执行以下命令获取token的值(需要提前安装kubectl):
|
可以在本地执行以下命令获取 token 的值(需要提前安装 kubectl):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl -n kube-system describe secret `kubectl -n kube-system get secret|grep admin-token|cut -d " " -f1`|grep "token:"|tr -s " "|cut -d " " -f2
|
kubectl -n kube-system describe secret `kubectl -n kube-system get secret|grep admin-token|cut -d " " -f1`|grep "token:"|tr -s " "|cut -d " " -f2
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意**:token的值也可以在`vagrant up`的日志的最后看到。
|
**注意**:token 的值也可以在 `vagrant up` 的日志的最后看到。
|
||||||
|
|
||||||
![Kubernetes dashboard](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/dashboard-animation.gif)
|
![Kubernetes dashboard](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/dashboard-animation.gif)
|
||||||
|
|
||||||
**Heapster监控**
|
**Heapster 监控**
|
||||||
|
|
||||||
创建Heapster监控:
|
创建 Heapster 监控:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl apply -f addon/heapster/
|
kubectl apply -f addon/heapster/
|
||||||
```
|
```
|
||||||
|
|
||||||
访问Grafana
|
访问 Grafana
|
||||||
|
|
||||||
使用Ingress方式暴露的服务,在本地`/etc/hosts`中增加一条配置:
|
使用 Ingress 方式暴露的服务,在本地 `/etc/hosts` 中增加一条配置:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
172.17.8.102 grafana.jimmysong.io
|
172.17.8.102 grafana.jimmysong.io
|
||||||
```
|
```
|
||||||
|
|
||||||
访问Grafana:`http://grafana.jimmysong.io`
|
访问 Grafana:`http://grafana.jimmysong.io`
|
||||||
|
|
||||||
![Grafana](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/grafana-animation.gif)
|
![Grafana](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/grafana-animation.gif)
|
||||||
|
|
||||||
**Traefik**
|
**Traefik**
|
||||||
|
|
||||||
部署Traefik ingress controller和增加ingress配置:
|
部署 Traefik ingress controller 和增加 ingress 配置:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl apply -f addon/traefik-ingress
|
kubectl apply -f addon/traefik-ingress
|
||||||
```
|
```
|
||||||
|
|
||||||
在本地`/etc/hosts`中增加一条配置:
|
在本地 `/etc/hosts` 中增加一条配置:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
172.17.8.102 traefik.jimmysong.io
|
172.17.8.102 traefik.jimmysong.io
|
||||||
```
|
```
|
||||||
|
|
||||||
访问Traefik UI:<http://traefik.jimmysong.io>
|
访问 Traefik UI:[http://traefik.jimmysong.io](http://traefik.jimmysong.io/)
|
||||||
|
|
||||||
![Traefik dashboard](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/traefik-ingress.gif)
|
![Traefik dashboard](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/traefik-ingress.gif)
|
||||||
|
|
||||||
**EFK**
|
**EFK**
|
||||||
|
|
||||||
使用EFK做日志收集。
|
使用 EFK 做日志收集。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl apply -f addon/efk/
|
kubectl apply -f addon/efk/
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意**:运行EFK的每个节点需要消耗很大的CPU和内存,请保证每台虚拟机至少分配了4G内存。
|
**注意**:运行 EFK 的每个节点需要消耗很大的 CPU 和内存,请保证每台虚拟机至少分配了 4G 内存。
|
||||||
|
|
||||||
**Helm**
|
**Helm**
|
||||||
|
|
||||||
用来部署helm。
|
用来部署 helm。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hack/deploy-helm.sh
|
hack/deploy-helm.sh
|
||||||
|
@ -181,7 +181,7 @@ hack/deploy-helm.sh
|
||||||
|
|
||||||
### Service Mesh
|
### Service Mesh
|
||||||
|
|
||||||
我们使用 [istio](https://istio.io) 作为 service mesh。
|
我们使用 [Istio](https://istio.io/) 作为 service mesh。
|
||||||
|
|
||||||
**安装**
|
**安装**
|
||||||
|
|
||||||
|
@ -196,14 +196,14 @@ kubectl apply -n default -f <(istioctl kube-inject -f yaml/istio-bookinfo/bookin
|
||||||
istioctl create -f yaml/istio-bookinfo/bookinfo-gateway.yaml
|
istioctl create -f yaml/istio-bookinfo/bookinfo-gateway.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
在您自己的本地主机的`/etc/hosts`文件中增加如下配置项。
|
在您自己的本地主机的 `/etc/hosts` 文件中增加如下配置项。
|
||||||
|
|
||||||
```
|
```
|
||||||
172.17.8.102 grafana.istio.jimmysong.io
|
172.17.8.102 grafana.istio.jimmysong.io
|
||||||
172.17.8.102 servicegraph.istio.jimmysong.io
|
172.17.8.102 servicegraph.istio.jimmysong.io
|
||||||
```
|
```
|
||||||
|
|
||||||
我们可以通过下面的URL地址访问以上的服务。
|
我们可以通过下面的 URL 地址访问以上的服务。
|
||||||
|
|
||||||
| Service | URL |
|
| Service | URL |
|
||||||
| ------------ | ------------------------------------------------------------ |
|
| ------------ | ------------------------------------------------------------ |
|
||||||
|
@ -212,34 +212,13 @@ istioctl create -f yaml/istio-bookinfo/bookinfo-gateway.yaml
|
||||||
| tracing | `http://172.17.8.101:$JAEGER_PORT` |
|
| tracing | `http://172.17.8.101:$JAEGER_PORT` |
|
||||||
| productpage | `http://172.17.8.101:$GATEWAY_PORT/productpage` |
|
| productpage | `http://172.17.8.101:$GATEWAY_PORT/productpage` |
|
||||||
|
|
||||||
**注意**:`JAEGER_PORT`可以通过`kubectl -n istio-system get svc tracing -o jsonpath='{.spec.ports[0].nodePort}'`获取,`GATEWAY_PORT`可以通过`kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.spec.ports[0].nodePort}'`获取。
|
**注意**:`JAEGER_PORT` 可以通过 `kubectl -n istio-system get svc tracing -o jsonpath='{.spec.ports[0].nodePort}'` 获取,`GATEWAY_PORT` 可以通过 `kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.spec.ports[0].nodePort}'` 获取。
|
||||||
|
|
||||||
![bookinfo示例](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/bookinfo-demo.gif)
|
![bookinfo示例](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/bookinfo-demo.gif)
|
||||||
|
|
||||||
### Vistio
|
|
||||||
|
|
||||||
[Vizceral](https://github.com/Netflix/vizceral)是Netflix发布的一个开源项目,用于近乎实时地监控应用程序和集群之间的网络流量。Vistio是使用Vizceral对Istio和网格监控的改进。它利用Istio Mixer生成的指标,然后将其输入Prometheus。Vistio查询Prometheus并将数据存储在本地以允许重播流量。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Deploy vistio via kubectl
|
|
||||||
kubectl apply -f addon/vistio/
|
|
||||||
|
|
||||||
# Expose vistio-api
|
|
||||||
kubectl -n default port-forward $(kubectl -n default get pod -l app=vistio-api -o jsonpath='{.items[0].metadata.name}') 9091:9091 &
|
|
||||||
|
|
||||||
# Expose vistio in another terminal window
|
|
||||||
kubectl -n default port-forward $(kubectl -n default get pod -l app=vistio-web -o jsonpath='{.items[0].metadata.name}') 8080:8080 &
|
|
||||||
```
|
|
||||||
|
|
||||||
如果一切都已经启动并准备就绪,您就可以访问Vistio UI,开始探索服务网格网络,访问[http://localhost:8080](http://localhost:8080/) 您将会看到类似下图的输出。
|
|
||||||
|
|
||||||
![vistio视图动画](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/vistio-animation.gif)
|
|
||||||
|
|
||||||
更多详细内容请参考[Vistio—使用Netflix的Vizceral可视化Istio service mesh](https://servicemesher.github.io/blog/vistio-visualize-your-istio-mesh-using-netflixs-vizceral/)。
|
|
||||||
|
|
||||||
### Kiali
|
### Kiali
|
||||||
|
|
||||||
Kiali是一个用于提供Istio service mesh观察性的项目,更多信息请查看 [https://kiali.io](https://kiali.io/)。
|
Kiali 是一个用于提供 Istio service mesh 观察性的项目,更多信息请查看 [https://kiali.io](https://kiali.io/)。
|
||||||
|
|
||||||
在本地该项目的根路径下执行下面的命令:
|
在本地该项目的根路径下执行下面的命令:
|
||||||
|
|
||||||
|
@ -247,17 +226,19 @@ Kiali是一个用于提供Istio service mesh观察性的项目,更多信息请
|
||||||
kubectl apply -n istio-system -f addon/kiali
|
kubectl apply -n istio-system -f addon/kiali
|
||||||
```
|
```
|
||||||
|
|
||||||
Kiali web地址:`http://172.17.8.101:31439`
|
Kiali web 地址:`http://172.17.8.101:31439`
|
||||||
|
|
||||||
用户名/密码:admin/admin
|
用户名 / 密码:admin/admin
|
||||||
|
|
||||||
![Kiali页面](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/kiali.gif)
|
![Kiali页面](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster/raw/master/images/kiali.gif)
|
||||||
|
|
||||||
**注意**:Kilia使用Jaeger做追踪,请不用屏蔽kilia页面的弹出窗口。
|
**注意**:Kilia使用Jaeger做追踪,请不用屏蔽kilia页面的弹出窗口。
|
||||||
|
|
||||||
|
**注意**:Kilia 使用 Jaeger 做追踪,请不用屏蔽 kilia 页面的弹出窗口。
|
||||||
|
|
||||||
### Weave scope
|
### Weave scope
|
||||||
|
|
||||||
[Weave scope](https://github.com/weaveworks/scope)可用于监控、可视化和管理Docker&Kubernetes集群,详情见 https://www.weave.works/oss/scope/
|
[Weave scope](https://github.com/weaveworks/scope) 可用于监控、可视化和管理 Docker&Kubernetes 集群,详情见 [Weave 官方文档](https://www.weave.works/oss/scope/)。
|
||||||
|
|
||||||
在本地该项目的根路径下执行下面的命令:
|
在本地该项目的根路径下执行下面的命令:
|
||||||
|
|
||||||
|
@ -265,7 +246,7 @@ Kiali web地址:`http://172.17.8.101:31439`
|
||||||
kubectl apply -f addon/weave-scope
|
kubectl apply -f addon/weave-scope
|
||||||
```
|
```
|
||||||
|
|
||||||
在本地的`/etc/hosts`下增加一条记录。
|
在本地的 `/etc/hosts` 下增加一条记录。
|
||||||
|
|
||||||
```
|
```
|
||||||
172.17.8.102 scope.weave.jimmysong.io
|
172.17.8.102 scope.weave.jimmysong.io
|
||||||
|
@ -277,7 +258,7 @@ kubectl apply -f addon/weave-scope
|
||||||
|
|
||||||
## 管理
|
## 管理
|
||||||
|
|
||||||
除了特别说明,以下命令都在当前的repo目录下操作。
|
除了特别说明,以下命令都在当前的 repo 目录下操作。
|
||||||
|
|
||||||
### 挂起
|
### 挂起
|
||||||
|
|
||||||
|
@ -324,7 +305,7 @@ cd /vagrant/hack
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
现在你已经拥有一个完整的基础的kubernetes运行环境,在该repo的根目录下执行下面的命令可以获取kubernetes dahsboard的admin用户的token。
|
现在你已经拥有一个完整的基础的 kubernetes 运行环境,在该 repo 的根目录下执行下面的命令可以获取 kubernetes dahsboard 的 admin 用户的 token。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
hack/get-dashboard-token.sh
|
hack/get-dashboard-token.sh
|
||||||
|
@ -348,6 +329,5 @@ rm -rf .vagrant
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Kubernetes handbook - jimmysong.io](https://jimmysong.io/kubernetes-handbook)
|
- [Kubernetes handbook - jimmysong.io](https://jimmysong.io/kubernetes-handbook)
|
||||||
- [duffqiu/centos-vagrant](https://github.com/duffqiu/centos-vagrant)
|
- [duffqiu/centos-vagrant - github.com](https://github.com/duffqiu/centos-vagrant)
|
||||||
- [coredns/deployment](https://github.com/coredns/deployment)
|
- [coredns/deployment - github.com](https://github.com/coredns/deployment)
|
||||||
- [Vistio—使用Netflix的Vizceral可视化Istio service mesh](http://www.servicemesher.com/blog/vistio-visualize-your-istio-mesh-using-netflixs-vizceral/)
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# 云原生编程语言 Ballerina
|
# Ballerina
|
||||||
|
|
||||||
当我第一眼看到 [Ballerina](https://ballerina.io) 还真有点惊艳的感觉。Ballerina 这个单词的意思是“芭蕾舞女演员”。我想他们之所以给公司和这们语言起这个名字,可能是希望它成为云原生这个大舞台中,Ballerina 能像一个灵活的芭蕾舞者一样轻松自如吧!
|
当我第一眼看到 [Ballerina](https://ballerina.io) 还真有点惊艳的感觉。Ballerina 这个单词的意思是“芭蕾舞女演员”。我想他们之所以给公司和这们语言起这个名字,可能是希望它成为云原生这个大舞台中,Ballerina 能像一个灵活的芭蕾舞者一样轻松自如吧!
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# 云原生编程语言 Pulumi
|
# Pulumi
|
||||||
|
|
||||||
2018 年 6 月 18 日 Joe Duffy 在[他的博客](http://joeduffyblog.com/2018/06/18/hello-pulumi/)中宣布开源了云原生编程语言 [Pulumi](https://www.pulumi.com/)。这是继 [Ballerina](https://ballerina.io/) 之后我看到的另一款云原生编程语言,他们之间有一些共同的特点,例如都是为了支持多种云环境,基于不可变基础设施和基础设施即代码的理念构建,使云原生应用的集成更加方便,但也有一些不同,Ballerina 是直接创建了一个基于 JVM 的语言,而 Pulumi 是为不同编程语言构建了 SDK。
|
2018 年 6 月 18 日 Joe Duffy 在[他的博客](http://joeduffyblog.com/2018/06/18/hello-pulumi/)中宣布开源了云原生编程语言 [Pulumi](https://www.pulumi.com/)。这是继 [Ballerina](https://ballerina.io/) 之后我看到的另一款云原生编程语言,他们之间有一些共同的特点,例如都是为了支持多种云环境,基于不可变基础设施和基础设施即代码的理念构建,使云原生应用的集成更加方便,但也有一些不同,Ballerina 是直接创建了一个基于 JVM 的语言,而 Pulumi 是为不同编程语言构建了 SDK。
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,29 @@
|
||||||
# 云原生编程语言
|
# 云原生平台配置语言
|
||||||
|
|
||||||
> 以下内容来自Joe Duffy的博客,[Hello, Pulumi!](http://joeduffyblog.com/2018/06/18/hello-pulumi/)。他说这些是为了说明为什么要创造Pulumi,在此我引用它说明为什么会有云原生编程语言。
|
云原生平台配置语言是一种 DSL(Domain Specific Language),通过编程的方式来创建云原生平台,目前已有的云原生 DSL 有:
|
||||||
|
|
||||||
对于每一个serverless函数来说,我都要写几十行的JSON或者YAML配置。要链接到一个API端点,我还要学习晦涩的概念,执行一系列复制-粘贴的低级工作。如果我想在本机上运行一个小的集群的话,那么Docker还是很棒的,但是如果要在生产上使用的话,那么就要手动管理etcd集群,配置网络和iptables路由表,还有一系列与我的应用程序本身不相干的事情。不过Kubernetes的出现至少让我可以配置一次下次就可以跨云平台重用,但这还是会分散开发人员的精力。
|
- Ballerina
|
||||||
|
- Pulumi
|
||||||
|
- Cue
|
||||||
|
- KSL
|
||||||
|
- Kusion
|
||||||
|
|
||||||
我认为我还算一个经验丰富的工程师,已经在软件行业从业20年了,但是当我想要将自己的代码部署到云中的时候,我感觉自己就像是个傻子。真是太令人悲哀了!如果我掌握了这些能力,那么是世界就会出触手可及。我总是在淌这浑水,处理云的复杂性,而我真正想做的是花时间来创造业务价值。
|
以下内容引用自 [Joe Duffy 的博客](http://joeduffyblog.com/2018/06/18/hello-pulumi/)。他说这些是为了说明为什么要创造 Pulumi,在此我引用它说明为什么会有云原生编程语言。
|
||||||
|
|
||||||
|
对于每一个 serverless 函数来说,我都要写几十行的 JSON 或者 YAML 配置。要链接到一个 API 端点,我还要学习晦涩的概念,执行一系列复制 - 粘贴的低级工作。如果我想在本机上运行一个小的集群的话,那么 Docker 还是很棒的,但是如果要在生产上使用的话,那么就要手动管理 etcd 集群,配置网络和 iptables 路由表,还有一系列与我的应用程序本身不相干的事情。不过 Kubernetes 的出现至少让我可以配置一次下次就可以跨云平台重用,但这还是会分散开发人员的精力。
|
||||||
|
|
||||||
|
我认为我还算一个经验丰富的工程师,已经在软件行业从业 20 年了,但是当我想要将自己的代码部署到云中的时候,我感觉自己就像是个傻子。真是太令人悲哀了!如果我掌握了这些能力,那么是世界就会出触手可及。我总是在淌这浑水,处理云的复杂性,而我真正想做的是花时间来创造业务价值。
|
||||||
|
|
||||||
关于编程的许多方面都经历了类似的转变过程:
|
关于编程的许多方面都经历了类似的转变过程:
|
||||||
|
|
||||||
- 在80年代初,我们使用汇编语言对微处理器进行了编程。最终,编译器技术进步了,我们可以同时处理多种常见的架构。像FORTRAN和C这样的Low-level的编程语言开始兴起。
|
- 在 80 年代初,我们使用汇编语言对微处理器进行了编程。最终,编译器技术进步了,我们可以同时处理多种常见的架构。像 FORTRAN 和 C 这样的 Low-level 的编程语言开始兴起。
|
||||||
- 在90年代初期,我们直接针对低级别操作系统原语进行编程,无论是POSIX系统调用还是Win32 API,并进行手动内存和资源管理。最终,语言运行时技术和处理器速度提升到了可以使用更高级别语言的状态,如Java。除了动态语言之外,这种趋势已经加速,如JavaScript统治了Web。
|
- 在 90 年代初期,我们直接针对低级别操作系统原语进行编程,无论是 POSIX 系统调用还是 Win32 API,并进行手动内存和资源管理。最终,语言运行时技术和处理器速度提升到了可以使用更高级别语言的状态,如 Java。除了动态语言之外,这种趋势已经加速,如 JavaScript 统治了 Web。
|
||||||
- 在21世纪初期,我们的编程模型中的共享内存并发性最好是原始的([我花了很多时间在这个问题上](http://joeduffyblog.com/2016/11/30/15-years-of-concurrency/))。现在,我们简单地假设OS具有高级线程共享、调度和异步IO功能,以及编程到更高级别的API,例如任务和承诺。
|
- 在 21 世纪初期,我们的编程模型中的共享内存并发性最好是原始的([我花了很多时间在这个问题上](http://joeduffyblog.com/2016/11/30/15-years-of-concurrency/))。现在,我们简单地假设 OS 具有高级线程共享、调度和异步 IO 功能,以及编程到更高级别的 API,例如任务和承诺。
|
||||||
|
|
||||||
我相信云软件也在进行类似的转变。从构建单一应用程序到构建真正的云优先分布式系统,我们正处在一场巨变中。然而,当海啸发生之前,人们几乎不知道它正在发生。
|
我相信云软件也在进行类似的转变。从构建单一应用程序到构建真正的云优先分布式系统,我们正处在一场巨变中。然而,当海啸发生之前,人们几乎不知道它正在发生。
|
||||||
|
|
||||||
从上面的角度来看,使用“配置”情况是有道理的。在虚拟机的早期,我们利用现有的应用程序并将它们扔在栅栏上,以便有人添加一点INI或XML粘合剂,让它们在虚拟机内部运行,以实现更灵活的管理。随着我们将这些相同的虚拟机“提升并转移到云中”,这种配置方法一直伴随着我们。这将我们带到了大致正确的边界。
|
从上面的角度来看,使用 “配置” 情况是有道理的。在虚拟机的早期,我们利用现有的应用程序并将它们扔在栅栏上,以便有人添加一点 INI 或 XML 粘合剂,让它们在虚拟机内部运行,以实现更灵活的管理。随着我们将这些相同的虚拟机 “提升并转移到云中”,这种配置方法一直伴随着我们。这将我们带到了大致正确的边界。
|
||||||
|
|
||||||
使用这种相同类型的配置表示基于容器的微服务、serverless和细粒度托管服务之间的关系导致了异常的复杂性。将应用程序转变为分布式系统应该是事后的想法。事实证明,云覆盖了您的架构和设计。表达架构和设计的最好的方式是使用代码,使用真正的编程语言编写抽象,重用和优秀的工具。
|
使用这种相同类型的配置表示基于容器的微服务、serverless 和细粒度托管服务之间的关系导致了异常的复杂性。将应用程序转变为分布式系统应该是事后的想法。事实证明,云覆盖了您的架构和设计。表达架构和设计的最好的方式是使用代码,使用真正的编程语言编写抽象,重用和优秀的工具。
|
||||||
|
|
||||||
早些时候,Eric和我采访了几十个客户。我们发现,开发人员和DevOps工程师都普遍感到幻灭。我们发现了极端的专业化,即使在同一个团队中,工程师也不会使用同一种语言。最近几周我已经听到了这个消息,我期待有一天会出现NoYAML运动。
|
早些时候,Eric 和我采访了几十个客户。我们发现,开发人员和 DevOps 工程师都普遍感到幻灭。我们发现了极端的专业化,即使在同一个团队中,工程师也不会使用同一种语言。最近几周我已经听到了这个消息,我期待有一天会出现 NoYAML 运动。
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
# Play with Kubernetes
|
# Play with Kubernetes
|
||||||
|
|
||||||
本书的主角是Kubernetes,在开始后面几章的长篇大论之前让大家可以零基础上手,揭开Kubernetes的神秘面纱。
|
本书的主角是 Kubernetes,在开始后面几章的长篇大论之前让大家可以零基础上手,揭开 Kubernetes 的神秘面纱。
|
||||||
|
|
||||||
本文不是讲解Kubernetes的高深原理也不是讲Kuberentes的具体用法,而是通过[Play with Kubernetes](https://labs.play-with-k8s.com/)来带您进入Kubernetes的世界,相当于Kubernetes世界的“Hello World”!而且除了一台可以上网的电脑和浏览器之外不需要再准备任何东西,甚至(至少目前为止)不需要注册账号,上手即玩。
|
本文不是讲解 Kubernetes 的高深原理也不是讲 Kuberentes 的具体用法,而是通过 [Play with Kubernetes](https://labs.play-with-k8s.com/) 来带您进入 Kubernetes 的世界,相当于 Kubernetes 世界的 “Hello World”!而且除了一台可以上网的电脑和浏览器之外不需要再准备任何东西,甚至(至少目前为止)不需要注册账号,上手即玩。
|
||||||
|
|
||||||
当然免费使用也是有限制的,当前的限制如下:
|
当然免费使用也是有限制的,当前的限制如下:
|
||||||
|
|
||||||
- 内置kubeadm来创建kubernetes集群,版本为v1.8.4
|
- 内置 kubeadm 来创建 kubernetes 集群,版本为 v1.8.4
|
||||||
- 每个实例配置为1 core,4G Memory,最多创建5个实例
|
- 每个实例配置为 1 core,4G Memory,最多创建 5 个实例
|
||||||
- 每个集群的使用时间是4个小时(当然你可以同时启动多个集群,根据浏览器的session来判断集群)
|
- 每个集群的使用时间是 4 个小时(当然你可以同时启动多个集群,根据浏览器的 session 来判断集群)
|
||||||
- 在Kubernetes集群中创建的服务无法通过外网访问,只能在Play with Kubernetes的网络内访问
|
- 在 Kubernetes 集群中创建的服务无法通过外网访问,只能在 Play with Kubernetes 的网络内访问
|
||||||
|
|
||||||
登陆[Play with Kubernetes](https://labs.play-with-k8s.com/),点击【登陆】-【开始】即可开始你的Kubernetes之旅!
|
登陆 [Play with Kubernetes](https://labs.play-with-k8s.com/),点击【登陆】-【开始】即可开始你的 Kubernetes 之旅!
|
||||||
|
|
||||||
## 创建Kubernetes集群
|
## 创建 Kubernetes 集群
|
||||||
|
|
||||||
启动第一个实例作为Master节点,在web终端上执行:
|
启动第一个实例作为 Master 节点,在 web 终端上执行:
|
||||||
|
|
||||||
**1.** 初始化master节点:
|
**1.** 初始化 master 节点:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubeadm init --apiserver-advertise-address $(hostname -i)
|
kubeadm init --apiserver-advertise-address $(hostname -i)
|
||||||
|
@ -37,18 +37,17 @@ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||||
chown $(id -u):$(id -g) $HOME/.kube/config
|
chown $(id -u):$(id -g) $HOME/.kube/config
|
||||||
```
|
```
|
||||||
|
|
||||||
**4.** 启动新的实例作为node节点,根据master节点上的提示,在新的web终端上执行:
|
**4.** 启动新的实例作为 node 节点,根据 master 节点上的提示,在新的 web 终端上执行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubeadm join --token 513212.cfea0165b8988d18 192.168.0.13:6443 --discovery-token-ca-cert-hash sha256:b7b6dcc98f3ead3f9e363cb3928fbc04774ee0d63e8eb2897ae30e05aebf8070
|
kubeadm join --token 513212.cfea0165b8988d18 192.168.0.13:6443 --discovery-token-ca-cert-hash sha256:b7b6dcc98f3ead3f9e363cb3928fbc04774ee0d63e8eb2897ae30e05aebf8070
|
||||||
```
|
```
|
||||||
|
|
||||||
注意:`192.168.0.13`是master节点的IP,请替换您的master节点的实际IP。
|
注意:`192.168.0.13` 是 master 节点的 IP,请替换您的 master 节点的实际 IP。
|
||||||
|
|
||||||
再添加几个实例,重复执行第四步,即可向Kubernetes集群中增加节点。
|
再添加几个实例,重复执行第四步,即可向 Kubernetes 集群中增加节点。
|
||||||
|
|
||||||
此时在master节点上执行`kubectl get nodes`查看节点所有节点状态,并创建nginx deployment,如下图所示:
|
此时在 master 节点上执行 `kubectl get nodes` 查看节点所有节点状态,并创建 nginx deployment,如下图所示:
|
||||||
|
|
||||||
![Play with Kubernetes网页截图](../images/play-with-kubernetes.jpg)
|
![Play with Kubernetes 网页截图](../images/play-with-kubernetes.jpg)
|
||||||
|
|
||||||
Play with Kuberentes (PWK) is a project hacked by [Marcos Lilljedahl](https://www.twitter.com/marcosnils) and [Jonathan Leibiusky](https://www.twitter.com/xetorthio) and sponsored by Docker Inc.
|
|
||||||
|
|
|
@ -176,4 +176,4 @@ Grafana 是一个优秀的仪表盘、分析和数据可视化工具。它没有
|
||||||
|
|
||||||
云原生领域的开源项目众多(见 [Awesome Cloud Native / 云原生开源项目大全](https://jimmysong.io/awesome-cloud-native)),其中有大量的优秀项目可供我们学习。此外,Kubernetes 开源已经多年时间,网上有大量的学习资料,业界出版过很多[书籍](https://jimmysong.io/cloud-native/note/books/),建议大家通过阅读[官方文档](https://kubernetes.io/)和实践来学习,也可以参考我编写的 [Kubernetes Handbook——Kubernetes 中文指南 / 云原生架构实践手册](https://jimmysong.io/kubernetes-handbook)。
|
云原生领域的开源项目众多(见 [Awesome Cloud Native / 云原生开源项目大全](https://jimmysong.io/awesome-cloud-native)),其中有大量的优秀项目可供我们学习。此外,Kubernetes 开源已经多年时间,网上有大量的学习资料,业界出版过很多[书籍](https://jimmysong.io/cloud-native/note/books/),建议大家通过阅读[官方文档](https://kubernetes.io/)和实践来学习,也可以参考我编写的 [Kubernetes Handbook——Kubernetes 中文指南 / 云原生架构实践手册](https://jimmysong.io/kubernetes-handbook)。
|
||||||
|
|
||||||
推荐大家加入我发起创办的[云原生社区](https://cloudnative.to/),这是一个立足中国,放眼世界的云原生终端用户社区,致力于云原生技术的传播和应用。云原生社区主办的[云原生学院](https://github.com/cloudnativeto/academy)定期邀请云原生和开源领域的大咖在 B 站上进行直播分享,成员自发组织了多个 SIG(特别兴趣小组)进行讨论学习。欢迎加入我们,共同学习和交流云原生技术。
|
推荐大家加入笔者发起创办的[云原生社区](https://cloudnative.to/),这是一个立足中国,放眼世界的云原生终端用户社区,致力于云原生技术的传播和应用。云原生社区主办的[云原生学院](https://github.com/cloudnativeto/academy)定期邀请云原生和开源领域的大咖进行直播分享,成员自发组织了多个 SIG(特别兴趣小组)进行讨论学习。欢迎加入我们,共同学习和交流云原生技术。
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
准入控制器(Admission Controller)位于 API Server 中,在对象被持久化之前,准入控制器拦截对 API Server 的请求,一般用来做身份验证和授权。其中包含两个特殊的控制器:`MutatingAdmissionWebhook` 和 `ValidatingAdmissionWebhook`。分别作为配置的变异和验证[准入控制 webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)。
|
准入控制器(Admission Controller)位于 API Server 中,在对象被持久化之前,准入控制器拦截对 API Server 的请求,一般用来做身份验证和授权。其中包含两个特殊的控制器:`MutatingAdmissionWebhook` 和 `ValidatingAdmissionWebhook`。分别作为配置的变异和验证[准入控制 webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)。
|
||||||
|
|
||||||
**变更(Mutating)准入控制**:修改请求的对象
|
准入控制器包括以下两种:
|
||||||
|
|
||||||
**验证(Validating)准入控制**:验证请求的对象
|
- **变更(Mutating)准入控制**:修改请求的对象
|
||||||
|
- **验证(Validating)准入控制**:验证请求的对象
|
||||||
|
|
||||||
准入控制器是在 API Server 的启动参数重配置的。一个准入控制器可能属于以上两者中的一种,也可能两者都属于。当请求到达 API Server 的时候首先执行变更准入控制,然后再执行验证准入控制。
|
准入控制器是在 API Server 的启动参数重配置的。一个准入控制器可能属于以上两者中的一种,也可能两者都属于。当请求到达 API Server 的时候首先执行变更准入控制,然后再执行验证准入控制。
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,22 @@
|
||||||
# Aggregated API Server
|
# Aggregated API Server
|
||||||
|
|
||||||
Aggregated(聚合的)API server是为了将原来的API server这个巨石(monolithic)应用给拆分成,为了方便用户开发自己的API server集成进来,而不用直接修改kubernetes官方仓库的代码,这样一来也能将API server解耦,方便用户使用实验特性。这些API server可以跟core API server无缝衔接,使用kubectl也可以管理它们。
|
Aggregated(聚合的)API server 是为了将原来的 API server 这个巨石(monolithic)应用给拆分成,为了方便用户开发自己的 API server 集成进来,而不用直接修改 kubernetes 官方仓库的代码,这样一来也能将 API server 解耦,方便用户使用实验特性。这些 API server 可以跟 core API server 无缝衔接,使用 kubectl 也可以管理它们。
|
||||||
|
|
||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
我们需要创建一个新的组件,名为`kube-aggregator`,它需要负责以下几件事:
|
我们需要创建一个新的组件,名为 `kube-aggregator`,它需要负责以下几件事:
|
||||||
|
|
||||||
- 提供用于注册API server的API
|
- 提供用于注册 API server 的 API
|
||||||
- 汇总所有的API server信息
|
- 汇总所有的 API server 信息
|
||||||
- 代理所有的客户端到API server的请求
|
- 代理所有的客户端到 API server 的请求
|
||||||
|
|
||||||
**注意**:这里说的API server是一组“API Server”,而不是说我们安装集群时候的那个API server,而且这组API server是可以横向扩展的。
|
**注意**:这里说的 API server 是一组 “API Server”,而不是说我们安装集群时候的那个 API server,而且这组 API server 是可以横向扩展的。
|
||||||
|
|
||||||
关于聚合的API server的更多信息请参考:[Aggregated API Server](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md)
|
## 安装配置聚合的 API server
|
||||||
|
|
||||||
## 安装配置聚合的API server
|
有两种方式来启用 `kube-aggregator`:
|
||||||
|
|
||||||
有两种方式来启用`kube-aggregator`:
|
- 使用 **test mode/single-user mode**,作为一个独立的进程来运行
|
||||||
|
- 使用 **gateway mode**,`kube-apiserver` 将嵌入到 `kbe-aggregator` 组件中,它将作为一个集群的 gateway,用来聚合所有 apiserver。
|
||||||
|
|
||||||
- 使用**test mode/single-user mode**,作为一个独立的进程来运行
|
`kube-aggregator` 二进制文件已经包含在 Kubernetes release 里面了。
|
||||||
- 使用**gateway mode**,`kube-apiserver`将嵌入到`kbe-aggregator`组件中,它将作为一个集群的gateway,用来聚合所有apiserver。
|
|
||||||
|
|
||||||
`kube-aggregator`二进制文件已经包含在kubernetes release里面了。
|
|
||||||
|
|
||||||
## 参考
|
|
||||||
|
|
||||||
[Aggregated API Servers - kuberentes design-proposals](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md)
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Cilium架构设计与概念解析
|
# Cilium 架构设计与概念解析
|
||||||
|
|
||||||
Cilium 要求 Linux kernel 版本在 4.8.0 以上,Cilium 官方建议 kernel 版本至少在 4.9.17 以上,高版本的 Ubuntu 发行版中 Linux 内核版本一般在 4.12 以上,如使用 CentOS7 需要升级内核才能运行 Cilium。
|
Cilium 要求 Linux kernel 版本在 4.8.0 以上,Cilium 官方建议 kernel 版本至少在 4.9.17 以上,高版本的 Ubuntu 发行版中 Linux 内核版本一般在 4.12 以上,如使用 CentOS7 需要升级内核才能运行 Cilium。
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# 集群信息
|
# 集群资源管理
|
||||||
|
|
||||||
为了管理异构和不同配置的主机,为了便于 Pod 的运维管理,Kubernetes 中提供了很多集群管理的配置和管理功能,通过 namespace 划分的空间,通过为 node 节点创建label和 taint 用于 pod 的调度等。
|
为了管理异构和不同配置的主机,为了便于 Pod 的运维管理,Kubernetes 中提供了很多集群管理的配置和管理功能,通过 namespace 划分的空间,通过为 node 节点创建 label 和 taint 用于 pod 的调度等。
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
## ConfigMap
|
## ConfigMap
|
||||||
|
|
||||||
其实ConfigMap功能在Kubernetes1.2版本的时候就有了,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。这些配置信息需要与docker image解耦,你总不能每修改一个配置就重做一个image吧?ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
|
其实 ConfigMap 功能在 Kubernetes1.2 版本的时候就有了,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。这些配置信息需要与 docker image 解耦,你总不能每修改一个配置就重做一个 image 吧?ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象。
|
||||||
|
|
||||||
## ConfigMap概览
|
## ConfigMap 概览
|
||||||
|
|
||||||
**ConfigMap API**资源用来保存**key-value pair**配置数据,这个数据可以在**pods**里使用,或者被用来为像**controller**一样的系统组件存储配置数据。虽然ConfigMap跟[Secrets](https://kubernetes.io/docs/user-guide/secrets/)类似,但是ConfigMap更方便的处理不含敏感信息的字符串。 注意:ConfigMaps不是属性配置文件的替代品。ConfigMaps只是作为多个properties文件的引用。你可以把它理解为Linux系统中的`/etc`目录,专门用来存储配置文件的目录。下面举个例子,使用ConfigMap配置来创建Kubernetes Volumes,ConfigMap中的每个data项都会成为一个新文件。
|
**ConfigMap API** 资源用来保存 **key-value pair** 配置数据,这个数据可以在 **pods** 里使用,或者被用来为像 **controller** 一样的系统组件存储配置数据。虽然 ConfigMap 跟 [Secrets](https://kubernetes.io/docs/user-guide/secrets/) 类似,但是 ConfigMap 更方便的处理不含敏感信息的字符串。 注意:ConfigMaps 不是属性配置文件的替代品。ConfigMaps 只是作为多个 properties 文件的引用。你可以把它理解为 Linux 系统中的 `/etc` 目录,专门用来存储配置文件的目录。下面举个例子,使用 ConfigMap 配置来创建 Kubernetes Volumes,ConfigMap 中的每个 data 项都会成为一个新文件。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
|
@ -22,31 +22,31 @@ data:
|
||||||
property.3=value-3
|
property.3=value-3
|
||||||
```
|
```
|
||||||
|
|
||||||
`data`一栏包括了配置数据,ConfigMap可以被用来保存单个属性,也可以用来保存一个配置文件。 配置数据可以通过很多种方式在Pods里被使用。ConfigMaps可以被用来:
|
`data` 一栏包括了配置数据,ConfigMap 可以被用来保存单个属性,也可以用来保存一个配置文件。 配置数据可以通过很多种方式在 Pods 里被使用。ConfigMaps 可以被用来:
|
||||||
|
|
||||||
1. 设置环境变量的值
|
1. 设置环境变量的值
|
||||||
2. 在容器里设置命令行参数
|
2. 在容器里设置命令行参数
|
||||||
3. 在数据卷里面创建config文件
|
3. 在数据卷里面创建 config 文件
|
||||||
|
|
||||||
用户和系统组件两者都可以在ConfigMap里面存储配置数据。
|
用户和系统组件两者都可以在 ConfigMap 里面存储配置数据。
|
||||||
|
|
||||||
其实不用看下面的文章,直接从`kubectl create configmap -h`的帮助信息中就可以对ConfigMap究竟如何创建略知一二了。
|
其实不用看下面的文章,直接从 `kubectl create configmap -h` 的帮助信息中就可以对 ConfigMap 究竟如何创建略知一二了。
|
||||||
|
|
||||||
```
|
```
|
||||||
Examples:
|
Examples:
|
||||||
# Create a new configmap named my-config based on folder bar
|
# Create a new configmap named my-config based on folder bar
|
||||||
kubectl create configmap my-config --from-file=path/to/bar
|
kubectl create configmap my-config --from-file=path/to/bar
|
||||||
|
|
||||||
# Create a new configmap named my-config with specified keys instead of file basenames on disk
|
# Create a new configmap named my-config with specified keys instead of file basenames on disk
|
||||||
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
|
kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
|
||||||
|
|
||||||
# Create a new configmap named my-config with key1=config1 and key2=config2
|
# Create a new configmap named my-config with key1=config1 and key2=config2
|
||||||
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
|
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
|
||||||
```
|
```
|
||||||
|
|
||||||
## 创建ConfigMaps
|
## 创建 ConfigMaps
|
||||||
|
|
||||||
可以使用该命令,用给定值、文件或目录来创建ConfigMap。
|
可以使用该命令,用给定值、文件或目录来创建 ConfigMap。
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl create configmap
|
kubectl create configmap
|
||||||
|
@ -54,7 +54,7 @@ kubectl create configmap
|
||||||
|
|
||||||
### 使用目录创建
|
### 使用目录创建
|
||||||
|
|
||||||
比如我们已经有了一些配置文件,其中包含了我们想要设置的ConfigMap的值:
|
比如我们已经有了一些配置文件,其中包含了我们想要设置的 ConfigMap 的值:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ls docs/user-guide/configmap/kubectl/
|
$ ls docs/user-guide/configmap/kubectl/
|
||||||
|
@ -77,15 +77,15 @@ allow.textmode=true
|
||||||
how.nice.to.look=fairlyNice
|
how.nice.to.look=fairlyNice
|
||||||
```
|
```
|
||||||
|
|
||||||
使用下面的命令可以创建一个包含目录中所有文件的ConfigMap。
|
使用下面的命令可以创建一个包含目录中所有文件的 ConfigMap。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl
|
$ kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl
|
||||||
```
|
```
|
||||||
|
|
||||||
`—from-file`指定在目录下的所有文件都会被用在ConfigMap里面创建一个键值对,键的名字就是文件名,值就是文件的内容。
|
`—from-file` 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容。
|
||||||
|
|
||||||
让我们来看一下这个命令创建的ConfigMap:
|
让我们来看一下这个命令创建的 ConfigMap:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
$ kubectl describe configmaps game-config
|
$ kubectl describe configmaps game-config
|
||||||
|
@ -100,13 +100,13 @@ game.properties: 158 bytes
|
||||||
ui.properties: 83 bytes
|
ui.properties: 83 bytes
|
||||||
```
|
```
|
||||||
|
|
||||||
我们可以看到那两个key是从kubectl指定的目录中的文件名。这些key的内容可能会很大,所以在kubectl describe的输出中,只能够看到键的名字和他们的大小。 如果想要看到键的值的话,可以使用`kubectl get`:
|
我们可以看到那两个 key 是从 kubectl 指定的目录中的文件名。这些 key 的内容可能会很大,所以在 kubectl describe 的输出中,只能够看到键的名字和他们的大小。 如果想要看到键的值的话,可以使用 `kubectl get`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl get configmaps game-config -o yaml
|
$ kubectl get configmaps game-config -o yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
我们以`yaml`格式输出配置。
|
我们以 `yaml` 格式输出配置。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -136,15 +136,12 @@ metadata:
|
||||||
|
|
||||||
### 使用文件创建
|
### 使用文件创建
|
||||||
|
|
||||||
刚才**使用目录创建**的时候我们`—from-file`指定的是一个目录,只要指定为一个文件就可以从单个文件中创建ConfigMap。
|
刚才**使用目录创建**的时候我们 `—from-file` 指定的是一个目录,只要指定为一个文件就可以从单个文件中创建 ConfigMap。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties
|
$ kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties
|
||||||
|
|
||||||
$ kubectl get configmaps game-config-2 -o yaml
|
$ kubectl get configmaps game-config-2 -o yaml
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
data:
|
data:
|
||||||
game-special-key: |
|
game-special-key: |
|
||||||
|
@ -165,19 +162,16 @@ metadata:
|
||||||
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
|
uid: 05f8da22-d671-11e5-8cd0-68f728db1985
|
||||||
```
|
```
|
||||||
|
|
||||||
`—from-file`这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的。
|
`—from-file` 这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的。
|
||||||
|
|
||||||
### 使用字面值创建
|
### 使用字面值创建
|
||||||
|
|
||||||
使用文字值创建,利用`—from-literal`参数传递配置信息,该参数可以使用多次,格式如下;
|
使用文字值创建,利用 `—from-literal` 参数传递配置信息,该参数可以使用多次,格式如下;
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
|
$ kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
|
||||||
|
|
||||||
$ kubectl get configmaps special-config -o yaml
|
$ kubectl get configmaps special-config -o yaml
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
data:
|
data:
|
||||||
special.how: very
|
special.how: very
|
||||||
|
@ -192,11 +186,11 @@ metadata:
|
||||||
uid: dadce046-d673-11e5-8cd0-68f728db1985
|
uid: dadce046-d673-11e5-8cd0-68f728db1985
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pod中使用ConfigMap
|
## Pod 中使用 ConfigMap
|
||||||
|
|
||||||
**使用ConfigMap来替代环境变量**
|
**使用 ConfigMap 来替代环境变量**
|
||||||
|
|
||||||
ConfigMap可以被用来填入环境变量。看下下面的ConfigMap。
|
ConfigMap 可以被用来填入环境变量。看下下面的 ConfigMap。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -207,9 +201,6 @@ metadata:
|
||||||
data:
|
data:
|
||||||
special.how: very
|
special.how: very
|
||||||
special.type: charm
|
special.type: charm
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -219,7 +210,7 @@ data:
|
||||||
log_level: INFO
|
log_level: INFO
|
||||||
```
|
```
|
||||||
|
|
||||||
我们可以在Pod中这样使用ConfigMap:
|
我们可以在 Pod 中这样使用 ConfigMap:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -248,7 +239,7 @@ spec:
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
```
|
```
|
||||||
|
|
||||||
这个Pod运行后会输出如下几行:
|
这个 Pod 运行后会输出如下几行:
|
||||||
|
|
||||||
```
|
```
|
||||||
SPECIAL_LEVEL_KEY=very
|
SPECIAL_LEVEL_KEY=very
|
||||||
|
@ -256,9 +247,9 @@ SPECIAL_TYPE_KEY=charm
|
||||||
log_level=INFO
|
log_level=INFO
|
||||||
```
|
```
|
||||||
|
|
||||||
**用ConfigMap设置命令行参数**
|
**用 ConfigMap 设置命令行参数**
|
||||||
|
|
||||||
ConfigMap也可以被使用来设置容器中的命令或者参数值。它使用的是Kubernetes的$(VAR_NAME)替换语法。我们看下下面这个ConfigMap。
|
ConfigMap 也可以被使用来设置容器中的命令或者参数值。它使用的是 Kubernetes 的 $(VAR_NAME) 替换语法。我们看下下面这个 ConfigMap。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -271,7 +262,7 @@ data:
|
||||||
special.type: charm
|
special.type: charm
|
||||||
```
|
```
|
||||||
|
|
||||||
为了将ConfigMap中的值注入到命令行的参数里面,我们还要像前面那个例子一样使用环境变量替换语法`${VAR_NAME)`。(其实这个东西就是给Docker容器设置环境变量,以前我创建镜像的时候经常这么玩,通过docker run的时候指定-e参数修改镜像里的环境变量,然后docker的CMD命令再利用该$(VAR_NAME)通过sed来修改配置文件或者作为命令行启动参数。)
|
为了将 ConfigMap 中的值注入到命令行的参数里面,我们还要像前面那个例子一样使用环境变量替换语法 `${VAR_NAME)`。(其实这个东西就是给 Docker 容器设置环境变量,以前我创建镜像的时候经常这么玩,通过 docker run 的时候指定 - e 参数修改镜像里的环境变量,然后 docker 的 CMD 命令再利用该 $(VAR_NAME) 通过 sed 来修改配置文件或者作为命令行启动参数。)
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -297,15 +288,15 @@ spec:
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
```
|
```
|
||||||
|
|
||||||
运行这个Pod后会输出:
|
运行这个 Pod 后会输出:
|
||||||
|
|
||||||
```
|
```
|
||||||
very charm
|
very charm
|
||||||
```
|
```
|
||||||
|
|
||||||
**通过数据卷插件使用ConfigMap**
|
**通过数据卷插件使用 ConfigMap**
|
||||||
|
|
||||||
ConfigMap也可以在数据卷里面被使用。还是这个ConfigMap。
|
ConfigMap 也可以在数据卷里面被使用。还是这个 ConfigMap。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -318,7 +309,7 @@ data:
|
||||||
special.type: charm
|
special.type: charm
|
||||||
```
|
```
|
||||||
|
|
||||||
在数据卷里面使用这个ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容:
|
在数据卷里面使用这个 ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -340,9 +331,9 @@ spec:
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
```
|
```
|
||||||
|
|
||||||
运行这个Pod的输出是`very`。
|
运行这个 Pod 的输出是 `very`。
|
||||||
|
|
||||||
我们也可以在ConfigMap值被映射的数据卷里控制路径。
|
我们也可以在 ConfigMap 值被映射的数据卷里控制路径。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -367,4 +358,4 @@ spec:
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
```
|
```
|
||||||
|
|
||||||
运行这个Pod后的结果是`very`。
|
运行这个 Pod 后的结果是 `very`。
|
||||||
|
|
|
@ -613,4 +613,4 @@ crontabs/my-new-cron-object 3s
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Extend the Kubernetes API with CustomResourceDefinitions - kubernetes.io](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/)
|
- [Extend the Kubernetes API with CustomResourceDefinitions - kubernetes.io](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/)
|
||||||
- [如何从零开始编写一个Kubernetes CRD - servicemesher.com](https://www.servicemesher.com/blog/kubernetes-crd-quick-start/)
|
- [如何从零开始编写一个 Kubernetes CRD - cloudnative.to](https://cloudnative.to/blog/kubernetes-crd-quick-start/)
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
Kubernetes 中不仅支持 CPU、内存为指标的 HPA,还支持自定义指标的 HPA,例如 QPS。
|
Kubernetes 中不仅支持 CPU、内存为指标的 HPA,还支持自定义指标的 HPA,例如 QPS。
|
||||||
|
|
||||||
本文中使用的 yaml 文件见 [manifests/HPA](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/HPA)。
|
本文中使用的 YAML 文件见 [manifests/HPA](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/HPA)。
|
||||||
|
|
||||||
## 设置自定义指标
|
## 设置自定义指标
|
||||||
|
|
||||||
**kubernetes1.6**
|
**Kubernetes1.6**
|
||||||
|
|
||||||
> 在 kubernetes1.6 集群中配置自定义指标的 HPA 的说明已废弃。
|
> 在 Kubernetes1.6 集群中配置自定义指标的 HPA 的说明已废弃。
|
||||||
|
|
||||||
在设置定义指标 HPA 之前需要先进行如下配置:
|
在设置定义指标 HPA 之前需要先进行如下配置:
|
||||||
|
|
||||||
|
@ -18,13 +18,13 @@ Kubernetes 中不仅支持 CPU、内存为指标的 HPA,还支持自定义指
|
||||||
- 启用 custom metric API
|
- 启用 custom metric API
|
||||||
- 将 kube-controller-manager 的启动参数中 `--horizontal-pod-autoscaler-use-rest-clients` 设置为 true,并指定 `--master` 为 API server 地址,如 `--master=http://172.20.0.113:8080`
|
- 将 kube-controller-manager 的启动参数中 `--horizontal-pod-autoscaler-use-rest-clients` 设置为 true,并指定 `--master` 为 API server 地址,如 `--master=http://172.20.0.113:8080`
|
||||||
|
|
||||||
在 kubernetes1.5 以前很容易设置,参考 [1.6 以前版本的 kubernetes 中开启自定义 HPA](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac),而在 1.6 中因为取消了原来的 annotation 方式设置 custom metric,只能通过 API server 和 kube-aggregator 来获取 custom metric,因为只有两种方式来设置了,一是直接通过 API server 获取 heapster 的 metrics,二是部署 [kube-aggragator](https://github.com/kubernetes/kube-aggregator) 来实现。
|
在 Kubernetes1.5 以前很容易设置,参考 [1.6 以前版本的 kubernetes 中开启自定义 HPA](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac),而在 1.6 中因为取消了原来的 annotation 方式设置 custom metric,只能通过 API server 和 kube-aggregator 来获取 custom metric,因为只有两种方式来设置了,一是直接通过 API server 获取 heapster 的 metrics,二是部署 [kube-aggragator](https://github.com/kubernetes/kube-aggregator) 来实现。
|
||||||
|
|
||||||
我们将在 kubernetes1.8 版本的 kubernetes 中,使用聚合的 API server 来实现自定义指标的 HPA。
|
我们将在 Kubernetes1.8 版本的 Kubernetes 中,使用聚合的 API server 来实现自定义指标的 HPA。
|
||||||
|
|
||||||
**kuberentes1.7+**
|
**Kuberentes1.7+**
|
||||||
|
|
||||||
确认您的 kubernetes 版本在 1.7 或以上,修改以下配置:
|
确认您的 Kubernetes 版本在 1.7 或以上,修改以下配置:
|
||||||
|
|
||||||
- 将 kube-controller-manager 的启动参数中 `--horizontal-pod-autoscaler-use-rest-clients` 设置为 true,并指定 `--master` 为 API server 地址,如 `--master=http://172.20.0.113:8080`
|
- 将 kube-controller-manager 的启动参数中 `--horizontal-pod-autoscaler-use-rest-clients` 设置为 true,并指定 `--master` 为 API server 地址,如 `--master=http://172.20.0.113:8080`
|
||||||
- 修改 kube-apiserver 的配置文件 apiserver,增加一条配置 `--requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem --requestheader-allowed-names=aggregator --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --proxy-client-cert-file=/etc/kubernetes/ssl/kubernetes.pem --proxy-client-key-file=/etc/kubernetes/ssl/kubernetes-key.pem`,用来配置 aggregator 的 CA 证书。
|
- 修改 kube-apiserver 的配置文件 apiserver,增加一条配置 `--requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem --requestheader-allowed-names=aggregator --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --proxy-client-cert-file=/etc/kubernetes/ssl/kubernetes.pem --proxy-client-key-file=/etc/kubernetes/ssl/kubernetes-key.pem`,用来配置 aggregator 的 CA 证书。
|
||||||
|
|
|
@ -1,60 +1,29 @@
|
||||||
# 使用自定义资源扩展 API
|
# 使用自定义资源扩展 API
|
||||||
|
|
||||||
> **注意:**TPR 已经停止维护,kubernetes 1.7 及以上版本请使用 CRD。
|
自定义资源是对 Kubernetes API 的扩展,Kubernetes 中的每个资源都是一个 API 对象的集合,例如我们在 YAML 文件里定义的那些 spec 都是对 Kubernetes 中的资源对象的定义,所有的自定义资源可以跟 Kubernetes 中内建的资源一样使用 kubectl 操作。
|
||||||
|
|
||||||
自定义资源是对 Kubernetes API 的扩展,kubernetes 中的每个资源都是一个 API 对象的集合,例如我们在 YAML 文件里定义的那些 spec 都是对 kubernetes 中的资源对象的定义,所有的自定义资源可以跟 kubernetes 中内建的资源一样使用 kubectl 操作。
|
|
||||||
|
|
||||||
## 自定义资源
|
## 自定义资源
|
||||||
|
|
||||||
Kubernetes1.6 版本中包含一个内建的资源叫做 TPR(ThirdPartyResource),可以用它来创建自定义资源,但该资源在 kubernetes1.7 中版本已被 CRD(CustomResourceDefinition)取代。
|
Kubernetes 从 1.6 版本开始包含一个内建的资源叫做 TPR(ThirdPartyResource),可以用它来创建自定义资源,但该资源在 Kubernetes 1.7 版本开始已被 CRD(CustomResourceDefinition)取代。
|
||||||
|
|
||||||
## 扩展 API
|
## 扩展 API
|
||||||
|
|
||||||
自定义资源实际上是为了扩展 kubernetes 的 API,向 kubenetes API 中增加新类型,可以使用以下三种方式:
|
自定义资源实际上是为了扩展 Kubernetes 的 API,向 Kubernetes API 中增加新类型,可以使用以下三种方式:
|
||||||
|
|
||||||
- 修改 kubenetes 的源码,显然难度比较高,也不太合适
|
- 修改 Kubernetes 的源码,显然难度比较高,也不太合适
|
||||||
- 创建自定义 API server 并聚合到 API 中
|
- 创建自定义 API server 并聚合到 API 中
|
||||||
- 1.7 以下版本编写 TPR,kubernetes1.7 及以上版本用 CRD
|
|
||||||
|
|
||||||
编写自定义资源是扩展 kubernetes API 的最简单的方式,是否编写自定义资源来扩展 API 请参考 [Should I add a custom resource to my Kubernetes Cluster?](https://kubernetes.io/docs/concepts/api-extension/custom-resources/),行动前请先考虑以下几点:
|
编写自定义资源是扩展 Kubernetes API 的最简单的方式,是否编写自定义资源来扩展 API 请参考 [Should I add a custom resource to my Kubernetes Cluster?](https://kubernetes.io/docs/concepts/api-extension/custom-resources/),行动前请先考虑以下几点:
|
||||||
|
|
||||||
- 你的 API 是否属于 [声明式的](https://kubernetes.io/docs/concepts/api-extension/custom-resources/#declarative-apis)
|
- 你的 API 是否属于 [声明式的](https://kubernetes.io/docs/concepts/api-extension/custom-resources/#declarative-apis)
|
||||||
- 是否想使用 kubectl 命令来管理
|
- 是否想使用 kubectl 命令来管理
|
||||||
- 是否要作为 kubenretes 中的对象类型来管理,同时显示在 kubernetes dashboard 上
|
- 是否要作为 Kubernetes 中的对象类型来管理,同时显示在 Kubernetes dashboard 上
|
||||||
- 是否可以遵守 kubernetes 的 API 规则限制,例如 URL 和 API group、namespace 限制
|
- 是否可以遵守 Kubernetes 的 API 规则限制,例如 URL 和 API group、namespace 限制
|
||||||
- 是否可以接受该 API 只能作用于集群或者 namespace 范围
|
- 是否可以接受该 API 只能作用于集群或者 namespace 范围
|
||||||
- 想要复用 kubernetes API 的公共功能,比如 CRUD、watch、内置的认证和授权等
|
- 想要复用 Kubernetes API 的公共功能,比如 CRUD、watch、内置的认证和授权等
|
||||||
|
|
||||||
如果这些都不是你想要的,那么你可以开发一个独立的 API。
|
如果这些都不是你想要的,那么你可以开发一个独立的 API。
|
||||||
|
|
||||||
## TPR
|
|
||||||
|
|
||||||
> **注意:**TPR 已经停止维护,kubernetes 1.7 及以上版本请使用 CRD。
|
|
||||||
|
|
||||||
假如我们要创建一个名为 `cron-tab.stable.example.com` 的 TPR,yaml 文件定义如下:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
kind: ThirdPartyResource
|
|
||||||
metadata:
|
|
||||||
name: cron-tab.stable.example.com
|
|
||||||
description: "A specification of a Pod to run on a cron style schedule"
|
|
||||||
versions:
|
|
||||||
- name: v1
|
|
||||||
```然后使用`kubectl create`命令创建该资源,这样就可以创建出一个 API 端点`/apis/stable.example.com/v1/namespaces/<namespace>/crontabs/...`。
|
|
||||||
|
|
||||||
下面是在 [Linkerd](https://linkerd.io) 中的一个实际应用,Linkerd 中的一个名为 namerd 的组件使用了 TPR,定义如下:
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
kind: ThirdPartyResource
|
|
||||||
apiVersion: extensions/v1beta1
|
|
||||||
metadata:
|
|
||||||
name: d-tab.l5d.io
|
|
||||||
description: stores dtabs used by namerd
|
|
||||||
versions:
|
|
||||||
- name: v1alpha1
|
|
||||||
```
|
|
||||||
|
|
||||||
### CRD
|
### CRD
|
||||||
|
|
||||||
参考下面的 CRD,resourcedefinition.yaml:
|
参考下面的 CRD,resourcedefinition.yaml:
|
||||||
|
@ -82,9 +51,17 @@ spec:
|
||||||
# CLI 中使用的资源简称
|
# CLI 中使用的资源简称
|
||||||
shortNames:
|
shortNames:
|
||||||
- ct
|
- ct
|
||||||
```创建该 CRD:```bash
|
```
|
||||||
|
|
||||||
|
创建该 CRD:
|
||||||
|
|
||||||
|
```bash
|
||||||
kubectl create -f resourcedefinition.yaml
|
kubectl create -f resourcedefinition.yaml
|
||||||
```访问 RESTful API 端点如 <http://172.20.0.113:8080> 将看到如下 API 端点已创建:```bash
|
```
|
||||||
|
|
||||||
|
访问 RESTful API 端点如 <http://172.20.0.113:8080> 将看到如下 API 端点已创建:
|
||||||
|
|
||||||
|
```bash
|
||||||
/apis/stable.example.com/v1/namespaces/*/crontabs/...
|
/apis/stable.example.com/v1/namespaces/*/crontabs/...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -124,7 +101,7 @@ metadata:
|
||||||
|
|
||||||
单纯设置了自定义资源,并没有什么用,只有跟自定义控制器结合起来,才能将资源对象中的声明式 API 翻译成用户所期望的状态。自定义控制器可以用来管理任何资源类型,但是一般是跟自定义资源结合使用。
|
单纯设置了自定义资源,并没有什么用,只有跟自定义控制器结合起来,才能将资源对象中的声明式 API 翻译成用户所期望的状态。自定义控制器可以用来管理任何资源类型,但是一般是跟自定义资源结合使用。
|
||||||
|
|
||||||
请参考使用 [Operator](https://coreos.com/blog/introducing-operators.html) 模式,该模式可以让开发者将自己的领域知识转换成特定的 kubenretes API 扩展。
|
请参考使用 [Operator](https://coreos.com/blog/introducing-operators.html) 模式,该模式可以让开发者将自己的领域知识转换成特定的 Kubernetes API 扩展。
|
||||||
|
|
||||||
## API server 聚合
|
## API server 聚合
|
||||||
|
|
||||||
|
@ -134,6 +111,6 @@ Aggregated(聚合的)API server 是为了将原来的 API server 这个巨
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Custom Resources](https://kubernetes.io/docs/concepts/api-extension/custom-resources/)
|
- [Custom Resources - kubernetes.io](https://kubernetes.io/docs/concepts/api-extension/custom-resources/)
|
||||||
- [Extend the Kubernetes API with CustomResourceDefinitions](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)
|
- [Extend the Kubernetes API with CustomResourceDefinitions - kubernetes.io](https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/)
|
||||||
- [Introducing Operators: Putting Operational Knowledge into Software](https://coreos.com/blog/introducing-operators.html)
|
- [Introducing Operators: Putting Operational Knowledge into Software - coreos.com](https://coreos.com/blog/introducing-operators.html)
|
|
@ -1,3 +1,3 @@
|
||||||
# 扩展
|
# 扩展
|
||||||
|
|
||||||
Kubernetes是一个高度开放可扩展的架构,可以通过自定义资源类型CRD来定义自己的类型,还可以自己来扩展API服务,用户的使用方式跟Kubernetes的原生对象无异。
|
Kubernetes 是一个高度开放可扩展的架构,可以通过自定义资源类型(CRD)来定义自己的类型,还可以自己来扩展 API 服务,用户的使用方式跟 Kubernetes 的原生对象无异。
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
# Horizontal Pod Autoscaling
|
# Horizontal Pod Autoscaling
|
||||||
|
|
||||||
应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让service中的Pod个数自动调整呢?这就有赖于Horizontal Pod Autoscaling了,顾名思义,使Pod水平自动缩放。这个Object(跟Pod、Deployment一样都是API resource)也是最能体现kubernetes之于传统运维价值的地方,不再需要手动扩容了,终于实现自动化了,还可以自定义指标,没准未来还可以通过人工智能自动进化呢!
|
应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让 service 中的 Pod 个数自动调整呢?这就有赖于 Horizontal Pod Autoscaling 了,顾名思义,使 Pod 水平自动缩放。这个 Object(跟 Pod、Deployment 一样都是 API resource)也是最能体现 kubernetes 之于传统运维价值的地方,不再需要手动扩容了,终于实现自动化了,还可以自定义指标,没准未来还可以通过人工智能自动进化呢!
|
||||||
|
|
||||||
HPA属于Kubernetes中的**autoscaling** SIG(Special Interest Group),其下有两个feature:
|
HPA 属于 Kubernetes 中的 **autoscaling** SIG(Special Interest Group),其下有两个 feature:
|
||||||
|
|
||||||
- [Arbitrary/Custom Metrics in the Horizontal Pod Autoscaler#117](https://github.com/kubernetes/features/issues/117)
|
- [Arbitrary/Custom Metrics in the Horizontal Pod Autoscaler#117](https://github.com/kubernetes/features/issues/117)
|
||||||
- [Monitoring Pipeline Metrics HPA API #118](https://github.com/kubernetes/features/issues/118)
|
- [Monitoring Pipeline Metrics HPA API #118](https://github.com/kubernetes/features/issues/118)
|
||||||
|
|
||||||
Kubernetes自1.2版本引入HPA机制,到1.6版本之前一直是通过kubelet来获取监控指标来判断是否需要扩缩容,1.6版本之后必须通过API server、Heapseter或者kube-aggregator来获取监控指标。
|
Kubernetes 自 1.2 版本引入 HPA 机制,到 1.6 版本之前一直是通过 kubelet 来获取监控指标来判断是否需要扩缩容,1.6 版本之后必须通过 API server、Heapseter 或者 kube-aggregator 来获取监控指标。
|
||||||
|
|
||||||
对于1.6以前版本中开启自定义HPA请参考[Kubernetes autoscaling based on custom metrics without using a host port](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac)。
|
对于 1.6 以前版本中开启自定义 HPA 请参考 [Kubernetes autoscaling based on custom metrics without using a host port](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac)。
|
||||||
|
|
||||||
## HPA解析
|
## HPA 解析
|
||||||
|
|
||||||
Horizontal Pod Autoscaling仅适用于Deployment和ReplicaSet,在v1版本中仅支持根据Pod的CPU利用率扩缩容,在v1alpha版本中,支持根据内存和用户自定义的metric扩缩容。
|
Horizontal Pod Autoscaling 仅适用于 Deployment 和 ReplicaSet,在 v1 版本中仅支持根据 Pod 的 CPU 利用率扩缩容,在 v1alpha 版本中,支持根据内存和用户自定义的 metric 扩缩容。
|
||||||
|
|
||||||
如果你不想看下面的文章可以直接看下面的示例图,组件交互、组件的配置、命令示例,都画在图上了。
|
如果你不想看下面的文章可以直接看下面的示例图,组件交互、组件的配置、命令示例,都画在图上了。
|
||||||
|
|
||||||
Horizontal Pod Autoscaling由API server和controller共同实现。
|
Horizontal Pod Autoscaling 由 API server 和 controller 共同实现。
|
||||||
|
|
||||||
![horizontal-pod-autoscaler](../images/horizontal-pod-autoscaler.png)
|
![horizontal-pod-autoscaler](../images/horizontal-pod-autoscaler.png)
|
||||||
|
|
||||||
## Metrics支持
|
## Metrics 支持
|
||||||
|
|
||||||
在不同版本的API中,HPA autoscale时可以根据以下指标来判断:
|
在不同版本的 API 中,HPA autoscale 时可以根据以下指标来判断:
|
||||||
|
|
||||||
- autoscaling/v1
|
- autoscaling/v1
|
||||||
- CPU
|
- CPU
|
||||||
- autoscaling/v1alpha1
|
- autoscaling/v1alpha1
|
||||||
- 内存
|
- 内存
|
||||||
- 自定义metrics
|
- 自定义 metrics
|
||||||
- kubernetes1.6起支持自定义metrics,但是必须在kube-controller-manager中配置如下两项:
|
- kubernetes1.6 起支持自定义 metrics,但是必须在 kube-controller-manager 中配置如下两项:
|
||||||
- `--horizontal-pod-autoscaler-use-rest-clients=true`
|
- `--horizontal-pod-autoscaler-use-rest-clients=true`
|
||||||
- `--api-server`指向[kube-aggregator](https://github.com/kubernetes/kube-aggregator),也可以使用heapster来实现,通过在启动heapster的时候指定`--api-server=true`。查看[kubernetes metrics](https://github.com/kubernetes/metrics)
|
- `--api-server` 指向 [kube-aggregator](https://github.com/kubernetes/kube-aggregator),也可以使用 heapster 来实现,通过在启动 heapster 的时候指定 `--api-server=true`。查看 [kubernetes metrics](https://github.com/kubernetes/metrics)
|
||||||
- 多种metrics组合
|
- 多种 metrics 组合
|
||||||
- HPA会根据每个metric的值计算出scale的值,并将最大的那个值作为扩容的最终结果。
|
- HPA 会根据每个 metric 的值计算出 scale 的值,并将最大的那个值作为扩容的最终结果。
|
||||||
|
|
||||||
## 使用kubectl管理
|
## 使用 kubectl 管理
|
||||||
|
|
||||||
Horizontal Pod Autoscaling作为API resource也可以像Pod、Deployment一样使用kubeclt命令管理,使用方法跟它们一样,资源名称为`hpa`。
|
Horizontal Pod Autoscaling 作为 API resource 也可以像 Pod、Deployment 一样使用 kubeclt 命令管理,使用方法跟它们一样,资源名称为 `hpa`。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl create hpa
|
kubectl create hpa
|
||||||
|
@ -47,7 +47,7 @@ kubectl describe hpa
|
||||||
kubectl delete hpa
|
kubectl delete hpa
|
||||||
```
|
```
|
||||||
|
|
||||||
有一点不同的是,可以直接使用`kubectl autoscale`直接通过命令行的方式创建Horizontal Pod Autoscaler。
|
有一点不同的是,可以直接使用 `kubectl autoscale` 直接通过命令行的方式创建 Horizontal Pod Autoscaler。
|
||||||
|
|
||||||
用法如下:
|
用法如下:
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MA
|
||||||
kubectl autoscale deployment foo --min=2 --max=5 --cpu-percent=80
|
kubectl autoscale deployment foo --min=2 --max=5 --cpu-percent=80
|
||||||
```
|
```
|
||||||
|
|
||||||
为Deployment foo创建 一个autoscaler,当Pod的CPU利用率达到80%的时候,RC的replica数在2到5之间。
|
为 Deployment foo 创建 一个 autoscaler,当 Pod 的 CPU 利用率达到 80% 的时候,RC 的 replica 数在 2 到 5 之间。
|
||||||
|
|
||||||
**注意** :如果为ReplicaSet创建HPA的话,无法使用rolling update,但是对于Deployment来说是可以的,因为Deployment在执行rolling update的时候会自动创建新的ReplicationController。
|
**注意** :如果为 ReplicaSet 创建 HPA 的话,无法使用 rolling update,但是对于 Deployment 来说是可以的,因为 Deployment 在执行 rolling update 的时候会自动创建新的 ReplicationController。
|
||||||
|
|
||||||
## 什么是 Horizontal Pod Autoscaling?
|
## 什么是 Horizontal Pod Autoscaling?
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ Horizontal Pod Autoscaler 作为 kubernetes API resource 和 controller 的实
|
||||||
|
|
||||||
Horizontal Pod Autoscaler 由一个控制循环实现,循环周期由 controller manager 中的 `--horizontal-pod-autoscaler-sync-period` 标志指定(默认是 30 秒)。
|
Horizontal Pod Autoscaler 由一个控制循环实现,循环周期由 controller manager 中的 `--horizontal-pod-autoscaler-sync-period` 标志指定(默认是 30 秒)。
|
||||||
|
|
||||||
在每个周期内,controller manager 会查询 HorizontalPodAutoscaler 中定义的 metric 的资源利用率。Controller manager 从 resource metric API(每个 pod 的 resource metric)或者自定义 metric API(所有的metric)中获取 metric。
|
在每个周期内,controller manager 会查询 HorizontalPodAutoscaler 中定义的 metric 的资源利用率。Controller manager 从 resource metric API(每个 pod 的 resource metric)或者自定义 metric API(所有的 metric)中获取 metric。
|
||||||
|
|
||||||
- 每个 Pod 的 resource metric(例如 CPU),controller 通过 resource metric API 获取 HorizontalPodAutoscaler 中定义的每个 Pod 中的 metric。然后,如果设置了目标利用率,controller 计算利用的值与每个 Pod 的容器里的 resource request 值的百分比。如果设置了目标原始值,将直接使用该原始 metric 值。然后 controller 计算所有目标 Pod 的利用率或原始值(取决于所指定的目标类型)的平均值,产生一个用于缩放所需 replica 数量的比率。 请注意,如果某些 Pod 的容器没有设置相关的 resource request ,则不会定义 Pod 的 CPU 利用率,并且 Aucoscaler 也不会对该 metric 采取任何操作。
|
- 每个 Pod 的 resource metric(例如 CPU),controller 通过 resource metric API 获取 HorizontalPodAutoscaler 中定义的每个 Pod 中的 metric。然后,如果设置了目标利用率,controller 计算利用的值与每个 Pod 的容器里的 resource request 值的百分比。如果设置了目标原始值,将直接使用该原始 metric 值。然后 controller 计算所有目标 Pod 的利用率或原始值(取决于所指定的目标类型)的平均值,产生一个用于缩放所需 replica 数量的比率。 请注意,如果某些 Pod 的容器没有设置相关的 resource request ,则不会定义 Pod 的 CPU 利用率,并且 Aucoscaler 也不会对该 metric 采取任何操作。
|
||||||
- 对于每个 Pod 自定义的 metric,controller 功能类似于每个 Pod 的 resource metric,只是它使用原始值而不是利用率值。
|
- 对于每个 Pod 自定义的 metric,controller 功能类似于每个 Pod 的 resource metric,只是它使用原始值而不是利用率值。
|
||||||
- 对于 object metric,获取单个度量(描述有问题的对象),并与目标值进行比较,以产生如上所述的比率。
|
- 对于 object metric,获取单个度量(描述有问题的对象),并与目标值进行比较,以产生如上所述的比率。
|
||||||
|
|
||||||
|
@ -92,58 +92,58 @@ Scale 是一个允许您动态设置副本数并检查其当前状态的接口
|
||||||
|
|
||||||
## API Object
|
## API Object
|
||||||
|
|
||||||
Horizontal Pod Autoscaler 是 kubernetes 的 `autoscaling` API 组中的 API 资源。当前的稳定版本中,只支持 CPU 自动扩缩容,可以在`autoscaling/v1` API 版本中找到。
|
Horizontal Pod Autoscaler 是 kubernetes 的 `autoscaling` API 组中的 API 资源。当前的稳定版本中,只支持 CPU 自动扩缩容,可以在 `autoscaling/v1` API 版本中找到。
|
||||||
|
|
||||||
在 alpha 版本中支持根据内存和自定义 metric 扩缩容,可以在`autoscaling/v2alpha1` 中找到。`autoscaling/v2alpha1` 中引入的新字段在`autoscaling/v1` 中是做为 annotation 而保存的。
|
在 alpha 版本中支持根据内存和自定义 metric 扩缩容,可以在 `autoscaling/v2alpha1` 中找到。`autoscaling/v2alpha1` 中引入的新字段在 `autoscaling/v1` 中是做为 annotation 而保存的。
|
||||||
|
|
||||||
## 在 kubectl 中支持 Horizontal Pod Autoscaling
|
## 在 kubectl 中支持 Horizontal Pod Autoscaling
|
||||||
|
|
||||||
Horizontal Pod Autoscaler 和其他的所有 API 资源一样,通过 `kubectl` 以标准的方式支持。
|
Horizontal Pod Autoscaler 和其他的所有 API 资源一样,通过 `kubectl` 以标准的方式支持。
|
||||||
|
|
||||||
我们可以使用`kubectl create`命令创建一个新的 autoscaler。
|
我们可以使用 `kubectl create` 命令创建一个新的 autoscaler。
|
||||||
|
|
||||||
我们可以使用`kubectl get hpa`列出所有的 autoscaler,使用`kubectl describe hpa`获取其详细信息。
|
我们可以使用 `kubectl get hpa` 列出所有的 autoscaler,使用 `kubectl describe hpa` 获取其详细信息。
|
||||||
|
|
||||||
最后我们可以使用`kubectl delete hpa`删除 autoscaler。
|
最后我们可以使用 `kubectl delete hpa` 删除 autoscaler。
|
||||||
|
|
||||||
另外,可以使用`kubectl autoscale`命令,很轻易的就可以创建一个 Horizontal Pod Autoscaler。
|
另外,可以使用 `kubectl autoscale` 命令,很轻易的就可以创建一个 Horizontal Pod Autoscaler。
|
||||||
|
|
||||||
例如,执行`kubectl autoscale rc foo —min=2 —max=5 —cpu-percent=80`命令将为 replication controller *foo* 创建一个 autoscaler,目标的 CPU 利用率是`80%`,replica 的数量介于 2 和 5 之间。
|
例如,执行 `kubectl autoscale rc foo —min=2 —max=5 —cpu-percent=80` 命令将为 replication controller *foo* 创建一个 autoscaler,目标的 CPU 利用率是 `80%`,replica 的数量介于 2 和 5 之间。
|
||||||
|
|
||||||
## 滚动更新期间的自动扩缩容
|
## 滚动更新期间的自动扩缩容
|
||||||
|
|
||||||
目前在Kubernetes中,可以通过直接管理 replication controller 或使用 deployment 对象来执行 滚动更新,该 deployment 对象为您管理基础 replication controller。
|
目前在 Kubernetes 中,可以通过直接管理 replication controller 或使用 deployment 对象来执行 滚动更新,该 deployment 对象为您管理基础 replication controller。
|
||||||
|
|
||||||
Horizontal Pod Autoscaler 仅支持后一种方法:Horizontal Pod Autoscaler 被绑定到 deployment 对象,它设置 deployment 对象的大小,deployment 负责设置底层 replication controller 的大小。
|
Horizontal Pod Autoscaler 仅支持后一种方法:Horizontal Pod Autoscaler 被绑定到 deployment 对象,它设置 deployment 对象的大小,deployment 负责设置底层 replication controller 的大小。
|
||||||
|
|
||||||
Horizontal Pod Autoscaler 不能使用直接操作 replication controller 进行滚动更新,即不能将 Horizontal Pod Autoscaler 绑定到 replication controller,并进行滚动更新(例如使用`kubectl rolling-update`)。
|
Horizontal Pod Autoscaler 不能使用直接操作 replication controller 进行滚动更新,即不能将 Horizontal Pod Autoscaler 绑定到 replication controller,并进行滚动更新(例如使用 `kubectl rolling-update`)。
|
||||||
|
|
||||||
这不行的原因是,当滚动更新创建一个新的 replication controller 时,Horizontal Pod Autoscaler 将不会绑定到新的 replication controller 上。
|
这不行的原因是,当滚动更新创建一个新的 replication controller 时,Horizontal Pod Autoscaler 将不会绑定到新的 replication controller 上。
|
||||||
|
|
||||||
## 支持多个 metric
|
## 支持多个 metric
|
||||||
|
|
||||||
Kubernetes 1.6 中增加了支持基于多个 metric 的扩缩容。您可以使用`autoscaling/v2alpha1` API 版本来为 Horizontal Pod Autoscaler 指定多个 metric。然后 Horizontal Pod Autoscaler controller 将权衡每一个 metric,并根据该 metric 提议一个新的 scale。在所有提议里最大的那个 scale 将作为最终的 scale。
|
Kubernetes 1.6 中增加了支持基于多个 metric 的扩缩容。您可以使用 `autoscaling/v2alpha1` API 版本来为 Horizontal Pod Autoscaler 指定多个 metric。然后 Horizontal Pod Autoscaler controller 将权衡每一个 metric,并根据该 metric 提议一个新的 scale。在所有提议里最大的那个 scale 将作为最终的 scale。
|
||||||
|
|
||||||
## 支持自定义 metric
|
## 支持自定义 metric
|
||||||
|
|
||||||
**注意:** Kubernetes 1.2 根据特定于应用程序的 metric ,通过使用特殊注释的方式,增加了对缩放的 alpha 支持。
|
**注意:** Kubernetes 1.2 根据特定于应用程序的 metric ,通过使用特殊注释的方式,增加了对缩放的 alpha 支持。
|
||||||
|
|
||||||
在 Kubernetes 1.6中删除了对这些注释的支持,有利于`autoscaling/v2alpha1` API。 虽然旧的收集自定义 metric 的旧方法仍然可用,但是这些 metric 将不可供 Horizontal Pod Autoscaler 使用,并且用于指定要缩放的自定义 metric 的以前的注释也不在受 Horizontal Pod Autoscaler 认可。
|
在 Kubernetes 1.6 中删除了对这些注释的支持,有利于 `autoscaling/v2alpha1` API。 虽然旧的收集自定义 metric 的旧方法仍然可用,但是这些 metric 将不可供 Horizontal Pod Autoscaler 使用,并且用于指定要缩放的自定义 metric 的以前的注释也不在受 Horizontal Pod Autoscaler 认可。
|
||||||
|
|
||||||
Kubernetes 1.6增加了在 Horizontal Pod Autoscale r中使用自定义 metric 的支持。
|
Kubernetes 1.6 增加了在 Horizontal Pod Autoscale r 中使用自定义 metric 的支持。
|
||||||
|
|
||||||
您可以为`autoscaling/v2alpha1` API 中使用的 Horizontal Pod Autoscaler 添加自定义 metric 。
|
您可以为 `autoscaling/v2alpha1` API 中使用的 Horizontal Pod Autoscaler 添加自定义 metric 。
|
||||||
|
|
||||||
Kubernetes 然后查询新的自定义 metric API 来获取相应自定义 metric 的值。
|
Kubernetes 然后查询新的自定义 metric API 来获取相应自定义 metric 的值。
|
||||||
|
|
||||||
## 前提条件
|
## 前提条件
|
||||||
|
|
||||||
为了在 Horizontal Pod Autoscaler 中使用自定义 metric,您必须在您集群的 controller manager 中将 `--horizontal-pod-autoscaler-use-rest-clients` 标志设置为 true。然后,您必须通过将 controller manager 的目标 API server 设置为 API server aggregator(使用`--apiserver`标志),配置您的 controller manager 通过 API server aggregator 与API server 通信。 Resource metric API和自定义 metric API 也必须向 API server aggregator 注册,并且必须由集群上运行的 API server 提供。
|
为了在 Horizontal Pod Autoscaler 中使用自定义 metric,您必须在您集群的 controller manager 中将 `--horizontal-pod-autoscaler-use-rest-clients` 标志设置为 true。然后,您必须通过将 controller manager 的目标 API server 设置为 API server aggregator(使用 `--apiserver` 标志),配置您的 controller manager 通过 API server aggregator 与 API server 通信。 Resource metric API 和自定义 metric API 也必须向 API server aggregator 注册,并且必须由集群上运行的 API server 提供。
|
||||||
|
|
||||||
您可以使用 Heapster 实现 resource metric API,方法是将 `--api-server` 标志设置为 true 并运行 Heapster。 单独的组件必须提供自定义 metric API(有关自定义metric API的更多信息,可从 [k8s.io/metrics repository](https://github.com/kubernetes/metrics) 获得)。
|
您可以使用 Heapster 实现 resource metric API,方法是将 `--api-server` 标志设置为 true 并运行 Heapster。 单独的组件必须提供自定义 metric API(有关自定义 metric API 的更多信息,可从 [k8s.io/metrics repository](https://github.com/kubernetes/metrics) 获得)。
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [HPA说明 - kubernetes.io(https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
|
- [HPA 说明 - kubernetes.io](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
|
||||||
- [HPA详解 - kubernetes.io](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/)
|
- [HPA 详解 - kubernetes.io](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/)
|
||||||
- [自定义metrics开发 - github.com](https://github.com/kubernetes/metrics)
|
- [自定义 metrics 开发 - github.com](https://github.com/kubernetes/metrics)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Ingress 解析
|
# Ingress
|
||||||
|
|
||||||
Ingress 是从 Kubernetes 集群外部访问集群内部服务的入口,这篇文章部分译自 Kubernetes 官方文档 [Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/),后面的章节会讲到使用 [Traefik](https://github.com/containous/traefik) 来做 Ingress controller,文章末尾给出了几个相关链接。
|
Ingress 是从 Kubernetes 集群外部访问集群内部服务的入口,这篇文章部分译自 Kubernetes 官方文档 [Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/),后面的章节会讲到使用 [Traefik](https://github.com/containous/traefik) 来做 Ingress controller,文章末尾给出了几个相关链接。
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# Job
|
# Job
|
||||||
|
|
||||||
Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
|
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。
|
||||||
|
|
||||||
## Job Spec格式
|
## Job Spec 格式
|
||||||
|
|
||||||
- spec.template格式同Pod
|
- spec.template 格式同 Pod
|
||||||
- RestartPolicy仅支持Never或OnFailure
|
- RestartPolicy 仅支持 Never 或 OnFailure
|
||||||
- 单个Pod时,默认Pod成功运行后Job即结束
|
- 单个 Pod 时,默认 Pod 成功运行后 Job 即结束
|
||||||
- `.spec.completions`标志Job结束需要成功运行的Pod个数,默认为1
|
- `.spec.completions` 标志 Job 结束需要成功运行的 Pod 个数,默认为 1
|
||||||
- `.spec.parallelism`标志并行运行的Pod的个数,默认为1
|
- `.spec.parallelism` 标志并行运行的 Pod 的个数,默认为 1
|
||||||
- `spec.activeDeadlineSeconds`标志失败Pod的重试最大时间,超过这个时间不会继续重试
|
- `spec.activeDeadlineSeconds` 标志失败 Pod 的重试最大时间,超过这个时间不会继续重试
|
||||||
|
|
||||||
一个简单的例子:
|
一个简单的例子:
|
||||||
|
|
||||||
|
@ -28,9 +28,6 @@ spec:
|
||||||
image: perl
|
image: perl
|
||||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||||
restartPolicy: Never
|
restartPolicy: Never
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ kubectl create -f ./job.yaml
|
$ kubectl create -f ./job.yaml
|
||||||
job "pi" created
|
job "pi" created
|
||||||
$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name})
|
$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name})
|
||||||
|
@ -38,6 +35,6 @@ $ kubectl logs $pods -c pi
|
||||||
3.141592653589793238462643383279502...
|
3.141592653589793238462643383279502...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Bare Pods
|
## Bare Pod
|
||||||
|
|
||||||
所谓Bare Pods是指直接用PodSpec来创建的Pod(即不在ReplicaSets或者ReplicationController的管理之下的Pods)。这些Pod在Node重启后不会自动重启,但Job则会创建新的Pod继续任务。所以,推荐使用Job来替代Bare Pods,即便是应用只需要一个Pod。
|
所谓 Bare Pod 是指直接用 PodSpec 来创建的 Pod(即不在 ReplicaSet 或者 ReplicationController 的管理之下的 Pod)。这些 Pod 在 Node 重启后不会自动重启,但 Job 则会创建新的 Pod 继续任务。所以,推荐使用 Job 来替代 Bare Pod,即便是应用只需要一个 Pod。
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Label
|
# Label
|
||||||
|
|
||||||
Label是附着到object上(例如Pod)的键值对。可以在创建object的时候指定,也可以在object创建后随时指定。Labels的值对系统本身并没有什么含义,只是对用户才有意义。
|
Label 是附着到 object 上(例如 Pod)的键值对。可以在创建 object 的时候指定,也可以在 object 创建后随时指定。Labels 的值对系统本身并没有什么含义,只是对用户才有意义。
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"labels": {
|
"labels": {
|
||||||
|
@ -9,11 +9,11 @@ Label是附着到object上(例如Pod)的键值对。可以在创建object的
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Kubernetes最终将对labels最终索引和反向索引用来优化查询和watch,在UI和命令行中会对它们排序。不要在label中使用大型、非标识的结构化数据,记录这样的数据应该用annotation。
|
Kubernetes 最终将对 labels 最终索引和反向索引用来优化查询和 watch,在 UI 和命令行中会对它们排序。不要在 label 中使用大型、非标识的结构化数据,记录这样的数据应该用 annotation。
|
||||||
|
|
||||||
## 动机
|
## 动机
|
||||||
|
|
||||||
Label能够将组织架构映射到系统架构上(就像是康威定律),这样能够更便于微服务的管理,你可以给object打上如下类型的label:
|
Label 能够将组织架构映射到系统架构上(就像是康威定律),这样能够更便于微服务的管理,你可以给 object 打上如下类型的 label:
|
||||||
|
|
||||||
- `"release" : "stable"`, `"release" : "canary"`
|
- `"release" : "stable"`, `"release" : "canary"`
|
||||||
- `"environment" : "dev"`, `"environment" : "qa"`, `"environment" : "production"`
|
- `"environment" : "dev"`, `"environment" : "qa"`, `"environment" : "production"`
|
||||||
|
@ -24,27 +24,27 @@ Label能够将组织架构映射到系统架构上(就像是康威定律),
|
||||||
|
|
||||||
## 语法和字符集
|
## 语法和字符集
|
||||||
|
|
||||||
Label key的组成:
|
Label key 的组成:
|
||||||
|
|
||||||
- 不得超过63个字符
|
- 不得超过 63 个字符
|
||||||
- 可以使用前缀,使用/分隔,前缀必须是DNS子域,不得超过253个字符,系统中的自动化组件创建的label必须指定前缀,`kubernetes.io/`由kubernetes保留
|
- 可以使用前缀,使用 / 分隔,前缀必须是 DNS 子域,不得超过 253 个字符,系统中的自动化组件创建的 label 必须指定前缀,`kubernetes.io/` 由 kubernetes 保留
|
||||||
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
|
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
|
||||||
|
|
||||||
Label value的组成:
|
Label value 的组成:
|
||||||
|
|
||||||
- 不得超过63个字符
|
- 不得超过 63 个字符
|
||||||
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
|
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
|
||||||
|
|
||||||
## Label selector
|
## Label selector
|
||||||
|
|
||||||
Label不是唯一的,很多object可能有相同的label。
|
Label 不是唯一的,很多 object 可能有相同的 label。
|
||||||
|
|
||||||
通过label selector,客户端/用户可以指定一个object集合,通过label selector对object的集合进行操作。
|
通过 label selector,客户端/用户可以指定一个 object 集合,通过 label selector 对 object 的集合进行操作。
|
||||||
|
|
||||||
Label selector有两种类型:
|
Label selector 有两种类型:
|
||||||
|
|
||||||
- *equality-based* :可以使用`=`、`==`、`!=`操作符,可以使用逗号分隔多个表达式
|
- *equality-based* :可以使用 `=`、`==`、`!=` 操作符,可以使用逗号分隔多个表达式
|
||||||
- *set-based* :可以使用`in`、`notin`、`!`操作符,另外还可以没有操作符,直接写出某个label的key,表示过滤有某个key的object而不管该key的value是何值,`!`表示没有该label的object
|
- *set-based* :可以使用 `in`、`notin`、`!` 操作符,另外还可以没有操作符,直接写出某个 label 的 key,表示过滤有某个 key 的 object 而不管该 key 的 value 是何值,`!` 表示没有该 label 的 object
|
||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
|
@ -55,16 +55,16 @@ $ kubectl get pods -l 'environment in (production, qa)'
|
||||||
$ kubectl get pods -l 'environment,environment notin (frontend)'
|
$ kubectl get pods -l 'environment,environment notin (frontend)'
|
||||||
```
|
```
|
||||||
|
|
||||||
## 在API object中设置label selector
|
## 在 API object 中设置 label selector
|
||||||
|
|
||||||
在`service`、`replicationcontroller`等object中有对pod的label selector,使用方法只能使用等于操作,例如:
|
在 `service`、`replicationcontroller` 等 object 中有对 pod 的 label selector,使用方法只能使用等于操作,例如:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
selector:
|
selector:
|
||||||
component: redis
|
component: redis
|
||||||
```
|
```
|
||||||
|
|
||||||
在`Job`、`Deployment`、`ReplicaSet`和`DaemonSet`这些object中,支持*set-based*的过滤,例如:
|
在 `Job`、`Deployment`、`ReplicaSet` 和 `DaemonSet` 这些 object 中,支持 *set-based* 的过滤,例如:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
selector:
|
selector:
|
||||||
|
@ -75,11 +75,11 @@ selector:
|
||||||
- {key: environment, operator: NotIn, values: [dev]}
|
- {key: environment, operator: NotIn, values: [dev]}
|
||||||
```
|
```
|
||||||
|
|
||||||
如Service通过label selector将同一类型的pod作为一个服务expose出来。
|
如 Service 通过 label selector 将同一类型的 pod 作为一个服务 expose 出来。
|
||||||
|
|
||||||
![label示意图](../images/labels.png)
|
![label示意图](../images/labels.png)
|
||||||
|
|
||||||
另外在node affinity和pod affinity中的label selector的语法又有些许不同,示例如下:
|
另外在 node affinity 和 pod affinity 中的 label selector 的语法又有些许不同,示例如下:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
affinity:
|
affinity:
|
||||||
|
|
|
@ -9,4 +9,3 @@ Kubernetes 用户可能希望将他们的部署分成多个集群,但仍然保
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [KEP-1645: Multi-Cluster Services API - github.com](https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api)
|
- [KEP-1645: Multi-Cluster Services API - github.com](https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api)
|
||||||
|
|
||||||
|
|
|
@ -27,4 +27,3 @@
|
||||||
|
|
||||||
- [Multicluster Special Interest Group - github.com](https://github.com/kubernetes/community/blob/master/sig-multicluster/README.md)
|
- [Multicluster Special Interest Group - github.com](https://github.com/kubernetes/community/blob/master/sig-multicluster/README.md)
|
||||||
- [配置对多集群的访问 - kubernetes.io](https://kubernetes.io/zh/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
|
- [配置对多集群的访问 - kubernetes.io](https://kubernetes.io/zh/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Network Policy
|
# NetworkPolicy
|
||||||
|
|
||||||
网络策略说明一组 `Pod` 之间是如何被允许互相通信,以及如何与其它网络 Endpoint 进行通信。 `NetworkPolicy` 资源使用标签来选择 `Pod`,并定义了一些规则,这些规则指明允许什么流量进入到选中的 `Pod` 上。关于 Network Policy 的详细用法请参考 [Kubernetes 官网](https://kubernetes.io/docs/concepts/services-networking/network-policies/)。
|
网络策略说明一组 `Pod` 之间是如何被允许互相通信,以及如何与其它网络 Endpoint 进行通信。 `NetworkPolicy` 资源使用标签来选择 `Pod`,并定义了一些规则,这些规则指明允许什么流量进入到选中的 `Pod` 上。关于 Network Policy 的详细用法请参考 [Kubernetes 官网](https://kubernetes.io/docs/concepts/services-networking/network-policies/)。
|
||||||
|
|
||||||
|
@ -102,5 +102,4 @@ spec:
|
||||||
```
|
```
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Network Policies - k8smeetup.github.io](https://k8smeetup.github.io/docs/concepts/services-networking/network-policies/)
|
|
||||||
- [Network Policies - kubernetes.io](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
|
- [Network Policies - kubernetes.io](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
# Pause容器
|
# Pause容器
|
||||||
|
|
||||||
Pause容器,又叫Infra容器,本文将探究该容器的作用与原理。
|
Pause 容器,又叫 Infra 容器,本文将探究该容器的作用与原理。
|
||||||
|
|
||||||
我们知道在kubelet的配置中有这样一个参数:
|
我们知道在 kubelet 的配置中有这样一个参数:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
KUBELET_POD_INFRA_CONTAINER=--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest
|
KUBELET_POD_INFRA_CONTAINER=--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
上面是openshift中的配置参数,kubernetes中默认的配置参数是:
|
上面是 openshift 中的配置参数,kubernetes 中默认的配置参数是:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
KUBELET_POD_INFRA_CONTAINER=--pod-infra-container-image=gcr.io/google_containers/pause-amd64:3.0
|
KUBELET_POD_INFRA_CONTAINER=--pod-infra-container-image=gcr.io/google_containers/pause-amd64:3.0
|
||||||
```
|
```
|
||||||
|
|
||||||
Pause容器,是可以自己来定义,官方使用的`gcr.io/google_containers/pause-amd64:3.0`容器的代码见[Github](https://github.com/kubernetes/kubernetes/tree/master/build/pause),使用C语言编写。
|
Pause 容器,是可以自己来定义,官方使用的 `gcr.io/google_containers/pause-amd64:3.0` 容器的代码见 [Github](https://github.com/kubernetes/kubernetes/tree/master/build/pause),使用 C 语言编写。
|
||||||
|
|
||||||
## Pause容器特点
|
## Pause 容器特点
|
||||||
|
|
||||||
- 镜像非常小,目前在700KB左右
|
- 镜像非常小,目前在 700KB 左右
|
||||||
- 永远处于Pause(暂停)状态
|
- 永远处于 Pause (暂停) 状态
|
||||||
|
|
||||||
## Pause容器背景
|
## Pause 容器背景
|
||||||
|
|
||||||
像 Pod 这样一个东西,本身是一个逻辑概念。那在机器上,它究竟是怎么实现的呢?这就是我们要解释的一个问题。
|
像 Pod 这样一个东西,本身是一个逻辑概念。那在机器上,它究竟是怎么实现的呢?这就是我们要解释的一个问题。
|
||||||
|
|
||||||
|
@ -31,25 +31,25 @@ Pause容器,是可以自己来定义,官方使用的`gcr.io/google_container
|
||||||
|
|
||||||
所以说具体的解法分为两个部分:网络和存储。
|
所以说具体的解法分为两个部分:网络和存储。
|
||||||
|
|
||||||
Pause容器就是为解决Pod中的网络问题而生的。
|
Pause 容器就是为解决 Pod 中的网络问题而生的。
|
||||||
|
|
||||||
## Pause容器实现
|
## Pause 容器实现
|
||||||
|
|
||||||
Pod 里的多个容器怎么去共享网络?下面是个例子:
|
Pod 里的多个容器怎么去共享网络?下面是个例子:
|
||||||
|
|
||||||
比如说现在有一个 Pod,其中包含了一个容器 A 和一个容器 B,它们两个就要共享 Network Namespace。在 Kubernetes 里的解法是这样的:它会在每个 Pod 里,额外起一个 Infra container 小容器来共享整个 Pod 的 Network Namespace。
|
比如说现在有一个 Pod,其中包含了一个容器 A 和一个容器 B,它们两个就要共享 Network Namespace。在 Kubernetes 里的解法是这样的:它会在每个 Pod 里,额外起一个 Infra container 小容器来共享整个 Pod 的 Network Namespace。
|
||||||
|
|
||||||
Infra container 是一个非常小的镜像,大概 700KB 左右,是一个C语言写的、永远处于“暂停”状态的容器。由于有了这样一个 Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。
|
Infra container 是一个非常小的镜像,大概 700KB 左右,是一个 C 语言写的、永远处于 “暂停” 状态的容器。由于有了这样一个 Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。
|
||||||
|
|
||||||
所以说一个 Pod 里面的所有容器,它们看到的网络视图是完全一样的。即:它们看到的网络设备、IP地址、Mac地址等等,跟网络相关的信息,其实全是一份,这一份都来自于 Pod 第一次创建的这个 Infra container。这就是 Pod 解决网络共享的一个解法。
|
所以说一个 Pod 里面的所有容器,它们看到的网络视图是完全一样的。即:它们看到的网络设备、IP 地址、Mac 地址等等,跟网络相关的信息,其实全是一份,这一份都来自于 Pod 第一次创建的这个 Infra container。这就是 Pod 解决网络共享的一个解法。
|
||||||
|
|
||||||
在 Pod 里面,一定有一个 IP 地址,是这个 Pod 的 Network Namespace 对应的地址,也是这个 Infra container 的 IP 地址。所以大家看到的都是一份,而其他所有网络资源,都是一个 Pod 一份,并且被 Pod 中的所有容器共享。这就是 Pod 的网络实现方式。
|
在 Pod 里面,一定有一个 IP 地址,是这个 Pod 的 Network Namespace 对应的地址,也是这个 Infra container 的 IP 地址。所以大家看到的都是一份,而其他所有网络资源,都是一个 Pod 一份,并且被 Pod 中的所有容器共享。这就是 Pod 的网络实现方式。
|
||||||
|
|
||||||
由于需要有一个相当于说中间的容器存在,所以整个 Pod 里面,必然是 Infra container 第一个启动。并且整个 Pod 的生命周期是等同于 Infra container 的生命周期的,与容器 A 和 B 是无关的。这也是为什么在 Kubernetes 里面,它是允许去单独更新 Pod 里的某一个镜像的,即:做这个操作,整个 Pod 不会重建,也不会重启,这是非常重要的一个设计。
|
由于需要有一个相当于说中间的容器存在,所以整个 Pod 里面,必然是 Infra container 第一个启动。并且整个 Pod 的生命周期是等同于 Infra container 的生命周期的,与容器 A 和 B 是无关的。这也是为什么在 Kubernetes 里面,它是允许去单独更新 Pod 里的某一个镜像的,即:做这个操作,整个 Pod 不会重建,也不会重启,这是非常重要的一个设计。
|
||||||
|
|
||||||
## Pause容器的作用
|
## Pause 容器的作用
|
||||||
|
|
||||||
我们检查node节点的时候会发现每个node上都运行了很多的pause容器,例如如下。
|
我们检查 node 节点的时候会发现每个 node 上都运行了很多的 pause 容器,例如如下。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker ps
|
$ docker ps
|
||||||
|
@ -61,22 +61,22 @@ CONTAINER ID IMAGE
|
||||||
5a5ef33b0d58 jimmysong/pause-amd64:3.0 "/pause" 3 hours ago Up 3 hours k8s_POD_kubernetes-dashboard-65486f5fdf-lshl7_kube-system_27c414a1-29c0-11e8-9e88-525400005732_0
|
5a5ef33b0d58 jimmysong/pause-amd64:3.0 "/pause" 3 hours ago Up 3 hours k8s_POD_kubernetes-dashboard-65486f5fdf-lshl7_kube-system_27c414a1-29c0-11e8-9e88-525400005732_0
|
||||||
```
|
```
|
||||||
|
|
||||||
kubernetes中的pause容器主要为每个业务容器提供以下功能:
|
kubernetes 中的 pause 容器主要为每个业务容器提供以下功能:
|
||||||
|
|
||||||
- 在pod中担任Linux命名空间共享的基础;
|
- 在 pod 中担任 Linux 命名空间共享的基础;
|
||||||
- 启用pid命名空间,开启init进程。
|
- 启用 pid 命名空间,开启 init 进程。
|
||||||
|
|
||||||
在[The Almighty Pause Container](https://www.ianlewis.org/en/almighty-pause-container)这篇文章中做出了详细的说明,pause容器的作用可以从这个例子中看出,首先见下图:
|
[这篇文章](https://www.ianlewis.org/en/almighty-pause-container)做出了详细的说明,pause 容器的作用可以从这个例子中看出,首先见下图:
|
||||||
|
|
||||||
![Pause容器](../images/pause-container.png)
|
![Pause容器](../images/pause-container.png)
|
||||||
|
|
||||||
我们首先在节点上运行一个pause容器。
|
我们首先在节点上运行一个 pause 容器。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d --name pause -p 8880:80 jimmysong/pause-amd64:3.0
|
docker run -d --name pause -p 8880:80 jimmysong/pause-amd64:3.0
|
||||||
```
|
```
|
||||||
|
|
||||||
然后再运行一个nginx容器,nginx将为`localhost:2368`创建一个代理。
|
然后再运行一个 nginx 容器,nginx 将为 `localhost:2368` 创建一个代理。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cat <<EOF >> nginx.conff
|
$ cat <<EOF >> nginx.conff
|
||||||
|
@ -96,17 +96,37 @@ EOF
|
||||||
$ docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause nginx
|
$ docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
然后再为[ghost](https://github.com/TryGhost/Ghost)创建一个应用容器,这是一款博客软件。
|
然后再运行一个 nginx 容器,nginx 将为 `localhost:2368` 创建一个代理。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cat <<EOF >> nginx.conff
|
||||||
|
error_log stderr;
|
||||||
|
events { worker_connections 1024; }
|
||||||
|
http {
|
||||||
|
access_log /dev/stdout combined;
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name example.com www.example.com;
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:2368;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
$ docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf --net=container:pause --ipc=container:pause --pid=container:pause nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
然后再为 [ghost](https://github.com/TryGhost/Ghost) 创建一个应用容器,这是一款博客软件。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker run -d --name ghost --net=container:pause --ipc=container:pause --pid=container:pause ghost
|
$ docker run -d --name ghost --net=container:pause --ipc=container:pause --pid=container:pause ghost
|
||||||
```
|
```
|
||||||
|
|
||||||
现在访问<http://localhost:8880/>就可以看到ghost博客的界面了。
|
现在访问 http://localhost:8880/ 就可以看到 ghost 博客的界面了。
|
||||||
|
|
||||||
**解析**
|
**解析**
|
||||||
|
|
||||||
pause容器将内部的80端口映射到宿主机的8880端口,pause容器在宿主机上设置好了网络namespace后,nginx容器加入到该网络namespace中,我们看到nginx容器启动的时候指定了`--net=container:pause`,ghost容器同样加入到了该网络namespace中,这样三个容器就共享了网络,互相之间就可以使用`localhost`直接通信,`--ipc=contianer:pause --pid=container:pause`就是三个容器处于同一个namespace中,init进程为`pause`,这时我们进入到ghost容器中查看进程情况。
|
pause 容器将内部的 80 端口映射到宿主机的 8880 端口,pause 容器在宿主机上设置好了网络 namespace 后,nginx 容器加入到该网络 namespace 中,我们看到 nginx 容器启动的时候指定了 `--net=container:pause`,ghost 容器同样加入到了该网络 namespace 中,这样三个容器就共享了网络,互相之间就可以使用 `localhost` 直接通信,`--ipc=contianer:pause --pid=container:pause` 就是三个容器处于同一个 namespace 中,init 进程为 `pause`,这时我们进入到 ghost 容器中查看进程情况。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# ps aux
|
# ps aux
|
||||||
|
@ -119,11 +139,9 @@ root 79 0.1 0.0 4336 812 pts/0 Ss 14:09 0:00 sh
|
||||||
root 87 0.0 0.0 17500 2080 pts/0 R+ 14:10 0:00 ps aux
|
root 87 0.0 0.0 17500 2080 pts/0 R+ 14:10 0:00 ps aux
|
||||||
```
|
```
|
||||||
|
|
||||||
在ghost容器中同时可以看到pause和nginx容器的进程,并且pause容器的PID是1。而在kubernetes中容器的PID=1的进程即为容器本身的业务进程。
|
在 ghost 容器中同时可以看到 pause 和 nginx 容器的进程,并且 pause 容器的 PID 是 1。而在 Kubernetes 中容器的 PID=1 的进程即为容器本身的业务进程。
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [The Almighty Pause Container](https://www.ianlewis.org/en/almighty-pause-container)
|
- [The Almighty Pause Container - ianlewis.org](https://www.ianlewis.org/en/almighty-pause-container)
|
||||||
- [Kubernetes之Pause容器](https://o-my-chenjian.com/2017/10/17/The-Pause-Container-Of-Kubernetes/)
|
- [Kubernetes 之 Pause 容器 - o-my-chenjian.com](https://o-my-chenjian.com/2017/10/17/The-Pause-Container-Of-Kubernetes/)
|
||||||
- [CNCF&Aliyun云原生课程](https://edu.aliyun.com/lesson_1651_16895?spm=5176.10731542.0.0.41a620be3s3dmu#_16895)
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Pod中断与PDB(Pod中断预算)
|
# Pod 中断与 PDB(Pod 中断预算)
|
||||||
|
|
||||||
这篇文档适用于要构建高可用应用程序的所有者,因此他们需要了解 Pod 可能发生什么类型的中断。也适用于要执行自动集群操作的集群管理员,如升级和集群自动扩容。
|
这篇文档适用于要构建高可用应用程序的所有者,因此他们需要了解 Pod 可能发生什么类型的中断。也适用于要执行自动集群操作的集群管理员,如升级和集群自动扩容。
|
||||||
|
|
||||||
|
|
|
@ -37,5 +37,5 @@ Hook 调用的日志没有暴露给 Pod 的 event,所以只能通过 `describe
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Attach Handlers to Container Lifecycle Events](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/)
|
- [Attach Handlers to Container Lifecycle Events - kuberentes.io](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/)
|
||||||
- [Container Lifecycle Hooks](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)
|
- [Container Lifecycle Hooks - kubernetes.io](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Pod Preset
|
# Pod Preset
|
||||||
|
|
||||||
> **注意:**PodPreset 资源对象只有 kubernetes 1.8 以上版本才支持。
|
> **注意:**PodPreset 资源对象只有 Kubernetes 1.8 以上版本才支持。
|
||||||
|
|
||||||
Preset 就是预设,有时候想要让一批容器在启动的时候就注入一些信息,比如 secret、volume、volume mount 和环境变量,而又不想一个一个的改这些 Pod 的 template,这时候就可以用到 PodPreset 这个资源对象了。
|
Preset 就是预设,有时候想要让一批容器在启动的时候就注入一些信息,比如 secret、volume、volume mount 和环境变量,而又不想一个一个的改这些 Pod 的 template,这时候就可以用到 PodPreset 这个资源对象了。
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Pod状态与生命周期管理
|
# Pod状态与生命周期管理
|
||||||
|
|
||||||
该节将带领大家了解Kubernetes中的基本概念,尤其是作为Kubernetes中调度的最基本单位Pod。
|
该节将带领大家了解 Kubernetes 中的基本概念,尤其是作为 Kubernetes 中调度的最基本单位 Pod。
|
||||||
|
|
||||||
本节中包括以下内容:
|
本节中包括以下内容:
|
||||||
|
|
||||||
- 了解Pod的构成
|
- 了解 Pod 的构成
|
||||||
- Pod的生命周期
|
- Pod 的生命周期
|
||||||
- Pod中容器的启动顺序模板定义
|
- Pod 中容器的启动顺序模板定义
|
||||||
|
|
||||||
Kubernetes中的基本组件`kube-controller-manager`就是用来控制Pod的状态和生命周期的,在了解各种controller之前我们有必要先了解下Pod本身和其生命周期。
|
Kubernetes 中的基本组件 `kube-controller-manager` 就是用来控制 Pod 的状态和生命周期的,在了解各种 controller 之前我们有必要先了解下 Pod 本身和其生命周期。
|
||||||
|
|
124
concepts/pod.md
124
concepts/pod.md
|
@ -1,50 +1,52 @@
|
||||||
# Pod解析
|
# Pod 解析
|
||||||
|
|
||||||
Pod是kubernetes中可以创建的最小部署单元。
|
Pod 是 Kubernetes 中可以创建的最小部署单元,也是 Kubernetes REST API 中的顶级资源类型。V1 core 版本的 Pod 的配置模板见 [Pod template](../manifests/template/pod-v1-template.yaml)。
|
||||||
|
|
||||||
V1 core版本的Pod的配置模板见[Pod template](../manifests/template/pod-v1-template.yaml)。
|
在 Kuberentes V1 core API 版本中的 Pod 的数据结构如下图所示:
|
||||||
|
|
||||||
## 什么是Pod?
|
![Pod Cheatsheet](../images/kubernetes-pod-cheatsheet.png)
|
||||||
|
|
||||||
Pod就像是豌豆荚一样,它由一个或者多个容器组成(例如Docker容器),它们共享容器存储、网络和容器运行配置项。Pod中的容器总是被同时调度,有共同的运行环境。你可以把单个Pod想象成是运行独立应用的“逻辑主机”——其中运行着一个或者多个紧密耦合的应用容器——在有容器之前,这些应用都是运行在几个相同的物理机或者虚拟机上。
|
## 什么是 Pod?
|
||||||
|
|
||||||
尽管kubernetes支持多种容器运行时,但是Docker依然是最常用的运行时环境,我们可以使用Docker的术语和规则来定义Pod。
|
Pod 就像是豌豆荚一样,它由一个或者多个容器组成(例如 Docker 容器),它们共享容器存储、网络和容器运行配置项。Pod 中的容器总是被同时调度,有共同的运行环境。你可以把单个 Pod 想象成是运行独立应用的 “逻辑主机”—— 其中运行着一个或者多个紧密耦合的应用容器 —— 在有容器之前,这些应用都是运行在几个相同的物理机或者虚拟机上。
|
||||||
|
|
||||||
Pod中共享的环境包括Linux的namespace、cgroup和其他可能的隔绝环境,这一点跟Docker容器一致。在Pod的环境中,每个容器中可能还有更小的子隔离环境。
|
尽管 kubernetes 支持多种容器运行时,但是 Docker 依然是最常用的运行时环境,我们可以使用 Docker 的术语和规则来定义 Pod。
|
||||||
|
|
||||||
Pod中的容器共享IP地址和端口号,它们之间可以通过`localhost`互相发现。它们之间可以通过进程间通信,例如[SystemV](https://en.wikipedia.org/wiki/UNIX_System_V)信号或者POSIX共享内存。不同Pod之间的容器具有不同的IP地址,不能直接通过IPC通信。
|
Pod 中共享的环境包括 Linux 的 namespace、cgroup 和其他可能的隔绝环境,这一点跟 Docker 容器一致。在 Pod 的环境中,每个容器中可能还有更小的子隔离环境。
|
||||||
|
|
||||||
Pod中的容器也有访问共享volume的权限,这些volume会被定义成pod的一部分并挂载到应用容器的文件系统中。
|
Pod 中的容器共享 IP 地址和端口号,它们之间可以通过 `localhost` 互相发现。它们之间可以通过进程间通信,例如 [SystemV](https://en.wikipedia.org/wiki/UNIX_System_V) 信号或者 POSIX 共享内存。不同 Pod 之间的容器具有不同的 IP 地址,不能直接通过 IPC 通信。
|
||||||
|
|
||||||
根据Docker的结构,Pod中的容器共享namespace和volume,不支持共享PID的namespace。
|
Pod 中的容器也有访问共享 volume 的权限,这些 volume 会被定义成 pod 的一部分并挂载到应用容器的文件系统中。
|
||||||
|
|
||||||
就像每个应用容器,pod被认为是临时(非持久的)实体。在Pod的生命周期中讨论过,pod被创建后,被分配一个唯一的ID(UID),调度到节点上,并一致维持期望的状态直到被终结(根据重启策略)或者被删除。如果node死掉了,分配到了这个node上的pod,在经过一个超时时间后会被重新调度到其他node节点上。一个给定的pod(如UID定义的)不会被“重新调度”到新的节点上,而是被一个同样的pod取代,如果期望的话甚至可以是相同的名字,但是会有一个新的UID。
|
根据 Docker 的结构,Pod 中的容器共享 namespace 和 volume,不支持共享 PID 的 namespace。
|
||||||
|
|
||||||
Volume跟pod有相同的生命周期(当其UID存在的时候)。当Pod因为某种原因被删除或者被新创建的相同的Pod取代,它相关的东西(例如volume)也会被销毁和再创建一个新的volume。
|
就像每个应用容器,pod 被认为是临时(非持久的)实体。在 Pod 的生命周期中讨论过,pod 被创建后,被分配一个唯一的 ID(UID),调度到节点上,并一致维持期望的状态直到被终结(根据重启策略)或者被删除。如果 node 死掉了,分配到了这个 node 上的 pod,在经过一个超时时间后会被重新调度到其他 node 节点上。一个给定的 pod(如 UID 定义的)不会被 “重新调度” 到新的节点上,而是被一个同样的 pod 取代,如果期望的话甚至可以是相同的名字,但是会有一个新的 UID。
|
||||||
|
|
||||||
|
Volume 跟 pod 有相同的生命周期(当其 UID 存在的时候)。当 Pod 因为某种原因被删除或者被新创建的相同的 Pod 取代,它相关的东西(例如 volume)也会被销毁和再创建一个新的 volume。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
![Pod示意图](../images/pod-overview.png)
|
![Pod示意图](../images/pod-overview.png)
|
||||||
|
|
||||||
*一个多容器Pod,包含文件提取程序和Web服务器,该服务器使用持久卷在容器之间共享存储。*
|
说明:一个多容器 Pod,包含文件提取程序和 Web 服务器,该服务器使用持久卷在容器之间共享存储。 s
|
||||||
|
|
||||||
## Pod的动机
|
## Pod 的动机
|
||||||
|
|
||||||
### 管理
|
### 管理
|
||||||
|
|
||||||
Pod是一个服务的多个进程的聚合单位,pod提供这种模型能够简化应用部署管理,通过提供一个更高级别的抽象的方式。Pod作为一个独立的部署单位,支持横向扩展和复制。共生(协同调度),命运共同体(例如被终结),协同复制,资源共享,依赖管理,Pod都会自动的为容器处理这些问题。
|
Pod 是一个服务的多个进程的聚合单位,pod 提供这种模型能够简化应用部署管理,通过提供一个更高级别的抽象的方式。Pod 作为一个独立的部署单位,支持横向扩展和复制。共生(协同调度),命运共同体(例如被终结),协同复制,资源共享,依赖管理,Pod 都会自动的为容器处理这些问题。
|
||||||
|
|
||||||
### 资源共享和通信
|
### 资源共享和通信
|
||||||
|
|
||||||
Pod中的应用可以共享网络空间(IP地址和端口),因此可以通过`localhost`互相发现。因此,pod中的应用必须协调端口占用。每个pod都有一个唯一的IP地址,跟物理机和其他pod都处于一个扁平的网络空间中,它们之间可以直接连通。
|
Pod 中的应用可以共享网络空间(IP 地址和端口),因此可以通过 `localhost` 互相发现。因此,pod 中的应用必须协调端口占用。每个 pod 都有一个唯一的 IP 地址,跟物理机和其他 pod 都处于一个扁平的网络空间中,它们之间可以直接连通。
|
||||||
|
|
||||||
Pod中应用容器的hostname被设置成Pod的名字。
|
Pod 中应用容器的 hostname 被设置成 Pod 的名字。
|
||||||
|
|
||||||
Pod中的应用容器可以共享volume。Volume能够保证pod重启时使用的数据不丢失。
|
Pod 中的应用容器可以共享 volume。Volume 能够保证 pod 重启时使用的数据不丢失。
|
||||||
|
|
||||||
## Pod的使用
|
## Pod 的使用
|
||||||
|
|
||||||
Pod也可以用于垂直应用栈(例如LAMP),这样使用的主要动机是为了支持共同调度和协调管理应用程序,例如:
|
Pod 也可以用于垂直应用栈(例如 LAMP),这样使用的主要动机是为了支持共同调度和协调管理应用程序,例如:
|
||||||
|
|
||||||
- 内容管理系统、文件和数据加载器、本地换群管理器等。
|
- 内容管理系统、文件和数据加载器、本地换群管理器等。
|
||||||
- 日志和检查点备份、压缩、旋转、快照等。
|
- 日志和检查点备份、压缩、旋转、快照等。
|
||||||
|
@ -52,7 +54,7 @@ Pod也可以用于垂直应用栈(例如LAMP),这样使用的主要动机
|
||||||
- 代理、桥接和适配器等。
|
- 代理、桥接和适配器等。
|
||||||
- 控制器、管理器、配置器、更新器等。
|
- 控制器、管理器、配置器、更新器等。
|
||||||
|
|
||||||
通常单个pod中不会同时运行一个应用的多个实例。
|
通常单个 pod 中不会同时运行一个应用的多个实例。
|
||||||
|
|
||||||
详细说明请看: [The Distributed System ToolKit: Patterns for Composite Containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns/).
|
详细说明请看: [The Distributed System ToolKit: Patterns for Composite Containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns/).
|
||||||
|
|
||||||
|
@ -60,76 +62,68 @@ Pod也可以用于垂直应用栈(例如LAMP),这样使用的主要动机
|
||||||
|
|
||||||
**为什么不直接在一个容器中运行多个应用程序呢?**
|
**为什么不直接在一个容器中运行多个应用程序呢?**
|
||||||
|
|
||||||
1. 透明。让Pod中的容器对基础设施可见,以便基础设施能够为这些容器提供服务,例如进程管理和资源监控。这可以为用户带来极大的便利。
|
1. 透明。让 Pod 中的容器对基础设施可见,以便基础设施能够为这些容器提供服务,例如进程管理和资源监控。这可以为用户带来极大的便利。
|
||||||
2. 解耦软件依赖。每个容器都可以进行版本管理,独立的编译和发布。未来kubernetes甚至可能支持单个容器的在线升级。
|
2. 解耦软件依赖。每个容器都可以进行版本管理,独立的编译和发布。未来 kubernetes 甚至可能支持单个容器的在线升级。
|
||||||
3. 使用方便。用户不必运行自己的进程管理器,还要担心错误信号传播等。
|
3. 使用方便。用户不必运行自己的进程管理器,还要担心错误信号传播等。
|
||||||
4. 效率。因为由基础架构提供更多的职责,所以容器可以变得更加轻量级。
|
4. 效率。因为由基础架构提供更多的职责,所以容器可以变得更加轻量级。
|
||||||
|
|
||||||
**为什么不支持容器的亲和性的协同调度?**
|
**为什么不支持容器的亲和性的协同调度?**
|
||||||
|
|
||||||
这种方法可以提供容器的协同定位,能够根据容器的亲和性进行调度,但是无法实现使用pod带来的大部分好处,例如资源共享,IPC,保持状态一致性和简化管理等。
|
这种方法可以提供容器的协同定位,能够根据容器的亲和性进行调度,但是无法实现使用 pod 带来的大部分好处,例如资源共享,IPC,保持状态一致性和简化管理等。
|
||||||
|
|
||||||
## Pod的持久性(或者说缺乏持久性)
|
## Pod 的持久性(或者说缺乏持久性)
|
||||||
|
|
||||||
Pod在设计支持就不是作为持久化实体的。在调度失败、节点故障、缺少资源或者节点维护的状态下都会死掉会被驱逐。
|
Pod 在设计支持就不是作为持久化实体的。在调度失败、节点故障、缺少资源或者节点维护的状态下都会死掉会被驱逐。
|
||||||
|
|
||||||
通常,用户不需要手动直接创建Pod,而是应该使用controller(例如[Deployments](./deployment.md)),即使是在创建单个Pod的情况下。Controller可以提供集群级别的自愈功能、复制和升级管理。
|
通常,用户不需要手动直接创建 Pod,而是应该使用 controller(例如 [Deployments](deployment.md)),即使是在创建单个 Pod 的情况下。Controller 可以提供集群级别的自愈功能、复制和升级管理。
|
||||||
|
|
||||||
使用集合API作为主要的面向用户的原语在集群调度系统中相对常见,包括[Borg](https://research.google.com/pubs/pub43438.html)、[Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html)、[Aurora](http://aurora.apache.org/documentation/latest/reference/configuration/#job-schema)和[Tupperware](https://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997)。
|
使用集合 API 作为主要的面向用户的原语在集群调度系统中相对常见,包括 [Borg](https://research.google.com/pubs/pub43438.html)、[Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html)、[Aurora](https://aurora.apache.org/documentation/latest/reference/configuration/#job-schema) 和 [Tupperware](https://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997)。
|
||||||
|
|
||||||
Pod 原语有利于:
|
Pod 原语有利于:
|
||||||
|
|
||||||
- 调度程序和控制器可插拔性
|
- 调度程序和控制器可插拔性
|
||||||
- 支持pod级操作,无需通过控制器API“代理”它们
|
- 支持 pod 级操作,无需通过控制器 API “代理” 它们
|
||||||
- 将pod生命周期与控制器生命周期分离,例如用于自举(bootstrap)
|
- 将 pod 生命周期与控制器生命周期分离,例如用于自举(bootstrap)
|
||||||
- 控制器和服务的分离——端点控制器只是监视pod
|
- 控制器和服务的分离 —— 端点控制器只是监视 pod
|
||||||
- 将集群级功能与Kubelet级功能的清晰组合——Kubelet实际上是“pod控制器”
|
- 将集群级功能与 Kubelet 级功能的清晰组合 ——Kubelet 实际上是 “pod 控制器”
|
||||||
- 高可用性应用程序,它们可以在终止之前及在删除之前更换pod,例如在计划驱逐、镜像预拉取或实时pod迁移的情况下[#3949](https://github.com/kubernetes/kubernetes/issues/3949)
|
- 高可用性应用程序,它们可以在终止之前及在删除之前更换 pod,例如在计划驱逐、镜像预拉取或实时 pod 迁移的情况下[#3949](https://github.com/kubernetes/kubernetes/issues/3949)
|
||||||
|
|
||||||
[StatefulSet](statefulset.md) 控制器支持有状态的Pod。在1.4版本中被称为PetSet。在kubernetes之前的版本中创建有状态pod的最佳方式是创建一个replica为1的replication controller。
|
[StatefulSet](./statefulset.md) 控制器支持有状态的 Pod。在 1.4 版本中被称为 PetSet。在 kubernetes 之前的版本中创建有状态 pod 的最佳方式是创建一个 replica 为 1 的 replication controller。
|
||||||
|
|
||||||
## Pod的终止
|
## Pod 的终止
|
||||||
|
|
||||||
因为Pod作为在集群的节点上运行的进程,所以在不再需要的时候能够优雅的终止掉是十分必要的(比起使用发送KILL信号这种暴力的方式)。用户需要能够发起一个删除 Pod 的请求,并且知道它们何时会被终止,是否被正确的删除。用户想终止程序时发送删除pod的请求,在pod可以被强制删除前会有一个宽限期,会发送一个TERM请求到每个容器的主进程。一旦超时,将向主进程发送KILL信号并从API server中删除。如果kubelet或者container manager在等待进程终止的过程中重启,在重启后仍然会重试完整的宽限期。
|
因为 Pod 作为在集群的节点上运行的进程,所以在不再需要的时候能够优雅的终止掉是十分必要的(比起使用发送 KILL 信号这种暴力的方式)。用户需要能够发起一个删除 Pod 的请求,并且知道它们何时会被终止,是否被正确的删除。用户想终止程序时发送删除 pod 的请求,在 pod 可以被强制删除前会有一个宽限期,会发送一个 TERM 请求到每个容器的主进程。一旦超时,将向主进程发送 KILL 信号并从 API server 中删除。如果 kubelet 或者 container manager 在等待进程终止的过程中重启,在重启后仍然会重试完整的宽限期。
|
||||||
|
|
||||||
示例流程如下:
|
示例流程如下:
|
||||||
|
|
||||||
1. 用户发送删除pod的命令,默认宽限期是30秒;
|
1. 用户发送删除 pod 的命令,默认宽限期是 30 秒;
|
||||||
2. 在Pod超过该宽限期后API server就会更新Pod的状态为“dead”;
|
2. 在 Pod 超过该宽限期后 API server 就会更新 Pod 的状态为 “dead”;
|
||||||
3. 在客户端命令行上显示的Pod状态为“terminating”;
|
3. 在客户端命令行上显示的 Pod 状态为 “terminating”;
|
||||||
4. 跟第三步同时,当kubelet发现pod被标记为“terminating”状态时,开始停止pod进程:
|
4. 跟第三步同时,当 kubelet 发现 pod 被标记为 “terminating” 状态时,开始停止 pod 进程:
|
||||||
1. 如果在pod中定义了preStop hook,在停止pod前会被调用。如果在宽限期过后,preStop hook依然在运行,第二步会再增加2秒的宽限期;
|
1. 如果在 pod 中定义了 preStop hook,在停止 pod 前会被调用。如果在宽限期过后,preStop hook 依然在运行,第二步会再增加 2 秒的宽限期;
|
||||||
2. 向Pod中的进程发送TERM信号;
|
2. 向 Pod 中的进程发送 TERM 信号;
|
||||||
5. 跟第三步同时,该Pod将从该service的端点列表中删除,不再是replication controller的一部分。关闭的慢的pod将继续处理load balancer转发的流量;
|
5. 跟第三步同时,该 Pod 将从该 service 的端点列表中删除,不再是 replication controller 的一部分。关闭的慢的 pod 将继续处理 load balancer 转发的流量;
|
||||||
6. 过了宽限期后,将向Pod中依然运行的进程发送SIGKILL信号而杀掉进程。
|
6. 过了宽限期后,将向 Pod 中依然运行的进程发送 SIGKILL 信号而杀掉进程。
|
||||||
7. Kubelet会在API server中完成Pod的的删除,通过将优雅周期设置为0(立即删除)。Pod在API中消失,并且在客户端也不可见。
|
7. Kubelet 会在 API server 中完成 Pod 的的删除,通过将优雅周期设置为 0(立即删除)。Pod 在 API 中消失,并且在客户端也不可见。
|
||||||
|
|
||||||
删除宽限期默认是30秒。 `kubectl delete`命令支持 `—grace-period=<seconds>` 选项,允许用户设置自己的宽限期。如果设置为0将强制删除pod。在kubectl>=1.5版本的命令中,你必须同时使用 `--force` 和 `--grace-period=0` 来强制删除pod。
|
删除宽限期默认是 30 秒。 `kubectl delete` 命令支持 `—grace-period=<seconds>` 选项,允许用户设置自己的宽限期。如果设置为 0 将强制删除 pod。在 kubectl>=1.5 版本的命令中,你必须同时使用 `--force` 和 `--grace-period=0` 来强制删除 pod。 在 yaml 文件中可以通过 `{{ .spec.spec.terminationGracePeriodSeconds }}` 来修改此值。
|
||||||
在 yaml 文件中可以通过 `{{ .spec.spec.terminationGracePeriodSeconds }}` 来修改此值。
|
|
||||||
|
|
||||||
### 强制删除Pod
|
### 强制删除 Pod
|
||||||
|
|
||||||
Pod的强制删除是通过在集群和etcd中将其定义为删除状态。当执行强制删除命令时,API server不会等待该pod所运行在节点上的kubelet确认,就会立即将该pod从API server中移除,这时就可以创建跟原pod同名的pod了。这时,在节点上的pod会被立即设置为terminating状态,不过在被强制删除之前依然有一小段优雅删除周期。
|
Pod 的强制删除是通过在集群和 etcd 中将其定义为删除状态。当执行强制删除命令时,API server 不会等待该 pod 所运行在节点上的 kubelet 确认,就会立即将该 pod 从 API server 中移除,这时就可以创建跟原 pod 同名的 pod 了。这时,在节点上的 pod 会被立即设置为 terminating 状态,不过在被强制删除之前依然有一小段优雅删除周期。
|
||||||
|
|
||||||
强制删除对于某些pod具有潜在危险性,请谨慎使用。使用StatefulSet pod的情况下,请参考删除StatefulSet中的pod文章。
|
强制删除对于某些 pod 具有潜在危险性,请谨慎使用。使用 StatefulSet pod 的情况下,请参考删除 StatefulSet 中的 pod 文章。
|
||||||
|
|
||||||
## Pod中容器的特权模式
|
## Pod 中容器的特权模式
|
||||||
|
|
||||||
从Kubernetes1.1版本开始,pod中的容器就可以开启privileged模式,在容器定义文件的 `SecurityContext` 下使用 `privileged` flag。 这在使用Linux的网络操作和访问设备的能力时是很有用的。容器内进程可获得近乎等同于容器外进程的权限。在不需要修改和重新编译kubelet的情况下就可以使用pod来开发节点的网络和存储插件。
|
从 Kubernetes1.1 版本开始,pod 中的容器就可以开启 privileged 模式,在容器定义文件的 `SecurityContext` 下使用 `privileged` flag。 这在使用 Linux 的网络操作和访问设备的能力时是很有用的。容器内进程可获得近乎等同于容器外进程的权限。在不需要修改和重新编译 kubelet 的情况下就可以使用 pod 来开发节点的网络和存储插件。
|
||||||
|
|
||||||
如果master节点运行的是kuberentes1.1或更高版本,而node节点的版本低于1.1版本,则API server将也可以接受新的特权模式的pod,但是无法启动,pod将处于pending状态。
|
如果 master 节点运行的是 kuberentes1.1 或更高版本,而 node 节点的版本低于 1.1 版本,则 API server 将也可以接受新的特权模式的 pod,但是无法启动,pod 将处于 pending 状态。
|
||||||
|
|
||||||
执行 `kubectl describe pod FooPodName`,可以看到为什么pod处于pending状态。输出的event列表中将显示:
|
执行 `kubectl describe pod FooPodName`,可以看到为什么 pod 处于 pending 状态。输出的 event 列表中将显示: `Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'`
|
||||||
`Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'`
|
|
||||||
|
|
||||||
如果master节点的版本低于1.1,无法创建特权模式的pod。如果你仍然试图去创建的话,你得到如下错误:
|
如果 master 节点的版本低于 1.1,无法创建特权模式的 pod。如果你仍然试图去创建的话,你得到如下错误:
|
||||||
|
|
||||||
`The Pod "FooPodName" is invalid. spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'`
|
```
|
||||||
|
The Pod "FooPodName" is invalid. spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'
|
||||||
## API Object
|
```
|
||||||
|
|
||||||
Pod是kubernetes REST API中的顶级资源类型。
|
|
||||||
|
|
||||||
在kuberentes1.6的V1 core API版本中的Pod的数据结构如下图所示:
|
|
||||||
|
|
||||||
![Pod Cheatsheet](../images/kubernetes-pod-cheatsheet.png)
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# 资源调度
|
# 资源调度
|
||||||
|
|
||||||
Kubernetes作为一个容器编排调度引擎,资源调度是它的最基本也是最重要的功能,这一节中我们将着重讲解Kubernetes中是如何做资源调度的。
|
Kubernetes 作为一个容器编排调度引擎,资源调度是它的最基本也是最重要的功能,这一节中我们将着重讲解 Kubernetes 中是如何做资源调度的。
|
||||||
|
|
||||||
Kubernetes中有一个叫做`kube-scheduler`的组件,该组件就是专门监听`kube-apiserver`中是否有还未调度到node上的pod,再通过特定的算法为pod指定分派node运行。
|
Kubernetes 中有一个叫做 `kube-scheduler` 的组件,该组件就是专门监听 `kube-apiserver` 中是否有还未调度到 node 上的 pod,再通过特定的算法为 pod 指定分派 node 运行。
|
||||||
|
|
||||||
Kubernetes中的众多资源类型,例如Deployment、DaemonSet、StatefulSet等都已经定义了Pod运行的一些默认调度策略,但是如果我们细心的根据node或者pod的不同属性,分别为它们打上标签之后,我们将发现Kubernetes中的高级调度策略是多么强大。当然如果要实现动态的资源调度,即pod已经调度到某些节点上后,因为一些其它原因,想要让pod重新调度到其它节点。
|
Kubernetes 中的众多资源类型,例如 Deployment、DaemonSet、StatefulSet 等都已经定义了 Pod 运行的一些默认调度策略,但是如果我们细心的根据 node 或者 pod 的不同属性,分别为它们打上标签之后,我们将发现 Kubernetes 中的高级调度策略是多么强大。当然如果要实现动态的资源调度,即 pod 已经调度到某些节点上后,因为一些其它原因,想要让 pod 重新调度到其它节点。
|
||||||
|
|
||||||
考虑以下两种情况:
|
考虑以下两种情况:
|
||||||
|
|
||||||
- 集群中有新增节点,想要让集群中的节点的资源利用率比较均衡一些,想要将一些高负载的节点上的pod驱逐到新增节点上,这是kuberentes的scheduler所不支持的,需要使用如[descheduler](https://github.com/kubernetes-incubator/descheduler)这样的插件来实现。
|
- 集群中有新增节点,想要让集群中的节点的资源利用率比较均衡一些,想要将一些高负载的节点上的 pod 驱逐到新增节点上,这是 kuberentes 的 scheduler 所不支持的,需要使用如 [descheduler](https://github.com/kubernetes-sigs/descheduler) 这样的插件来实现。
|
||||||
- 想要运行一些大数据应用,设计到资源分片,pod需要与数据分布达到一致均衡,避免个别节点处理大量数据,而其它节点闲置导致整个作业延迟,这时候可以考虑使用[kube-batch](https://github.com/kubernetes-incubator/kube-batch)。
|
- 想要运行一些大数据应用,设计到资源分片,pod 需要与数据分布达到一致均衡,避免个别节点处理大量数据,而其它节点闲置导致整个作业延迟,这时候可以考虑使用 [kube-batch](https://github.com/kubernetes-sigs/kube-batch)。
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
# Secret
|
# Secret
|
||||||
|
|
||||||
Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。
|
Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。
|
||||||
|
|
||||||
Secret有三种类型:
|
Secret 有三种类型:
|
||||||
|
|
||||||
* **Service Account** :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的`/run/secrets/kubernetes.io/serviceaccount`目录中;
|
- **Service Account** :用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 `/run/secrets/kubernetes.io/serviceaccount` 目录中;
|
||||||
* **Opaque** :base64编码格式的Secret,用来存储密码、密钥等;
|
- **Opaque** :base64 编码格式的 Secret,用来存储密码、密钥等;
|
||||||
* **kubernetes.io/dockerconfigjson** :用来存储私有docker registry的认证信息。
|
- **kubernetes.io/dockerconfigjson** :用来存储私有 docker registry 的认证信息。
|
||||||
|
|
||||||
## Opaque Secret
|
## Opaque Secret
|
||||||
|
|
||||||
Opaque类型的数据是一个map类型,要求value是base64编码格式:
|
Opaque 类型的数据是一个 map 类型,要求 value 是 base64 编码格式:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ echo -n "admin" | base64
|
$ echo -n "admin" | base64
|
||||||
|
@ -32,14 +32,14 @@ data:
|
||||||
username: YWRtaW4=
|
username: YWRtaW4=
|
||||||
```
|
```
|
||||||
|
|
||||||
接着,就可以创建secret了:`kubectl create -f secrets.yml`。
|
接着,就可以创建 secret 了:`kubectl create -f secrets.yml`。
|
||||||
|
|
||||||
创建好secret之后,有两种方式来使用它:
|
创建好 secret 之后,有两种方式来使用它:
|
||||||
|
|
||||||
* 以Volume方式
|
- 以 Volume 方式
|
||||||
* 以环境变量方式
|
- 以环境变量方式
|
||||||
|
|
||||||
### 将Secret挂载到Volume中
|
### 将 Secret 挂载到 Volume 中
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -66,7 +66,7 @@ spec:
|
||||||
hostPort: 5432
|
hostPort: 5432
|
||||||
```
|
```
|
||||||
|
|
||||||
### 将Secret导出到环境变量中
|
### 将 Secret 导出到环境变量中
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
|
@ -103,14 +103,14 @@ spec:
|
||||||
|
|
||||||
## kubernetes.io/dockerconfigjson
|
## kubernetes.io/dockerconfigjson
|
||||||
|
|
||||||
可以直接用`kubectl`命令来创建用于docker registry认证的secret:
|
可以直接用 `kubectl` 命令来创建用于 docker registry 认证的 secret:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
|
$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
|
||||||
secret "myregistrykey" created.
|
secret "myregistrykey" created.
|
||||||
```
|
```
|
||||||
|
|
||||||
也可以直接读取`~/.docker/config.json`的内容来创建:
|
也可以直接读取 `~/.docker/config.json` 的内容来创建:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cat ~/.docker/config.json | base64
|
$ cat ~/.docker/config.json | base64
|
||||||
|
@ -126,7 +126,7 @@ EOF
|
||||||
$ kubectl create -f myregistrykey.yaml
|
$ kubectl create -f myregistrykey.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
在创建Pod的时候,通过`imagePullSecrets`来引用刚创建的`myregistrykey`:
|
在创建 Pod 的时候,通过 `imagePullSecrets` 来引用刚创建的 `myregistrykey`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -143,7 +143,7 @@ spec:
|
||||||
|
|
||||||
### Service Account
|
### Service Account
|
||||||
|
|
||||||
Service Account用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的`/run/secrets/kubernetes.io/serviceaccount`目录中。
|
Service Account 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的 `/run/secrets/kubernetes.io/serviceaccount` 目录中。
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ kubectl run nginx --image nginx
|
$ kubectl run nginx --image nginx
|
||||||
|
@ -156,5 +156,3 @@ ca.crt
|
||||||
namespace
|
namespace
|
||||||
token
|
token
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,63 +1,60 @@
|
||||||
# 服务目录(Service Catalog)
|
# 服务目录(Service Catalog)
|
||||||
|
|
||||||
服务目录(Service Catalog)是Kubernetes的扩展API,它使运行在Kubernetes集群中的应用程序可以轻松使用外部托管软件产品,例如由云提供商提供的数据存储服务。
|
服务目录(Service Catalog)是 Kubernetes 的扩展 API,它使运行在 Kubernetes 集群中的应用程序可以轻松使用外部托管软件产品,例如由云提供商提供的数据存储服务。
|
||||||
|
|
||||||
它提供列表清单、提供(provision)和绑定(binding)来自服务代理(Service Brokers)的外部托管服务,而不需要关心如何创建或管理这些服务的详细情况。
|
它提供列表清单、提供 (provision) 和绑定 (binding) 来自服务代理(Service Brokers)的外部托管服务,而不需要关心如何创建或管理这些服务的详细情况。
|
||||||
|
|
||||||
由Open Service Broker API规范定义的Service broker是由第三方提供和维护的一组托管服务的端点(endpoint),该第三方可以是AWS,GCP或Azure等云提供商。
|
由 Open Service Broker API 规范定义的 Service broker 是由第三方提供和维护的一组托管服务的端点 (endpoint),该第三方可以是 AWS,GCP 或 Azure 等云提供商。
|
||||||
|
|
||||||
托管服务可以是Microsoft Azure Cloud Queue,Amazon Simple Queue Service和Google Cloud Pub/Sub等,它们可以是应用可以使用的提供的各种软件。
|
托管服务可以是 Microsoft Azure Cloud Queue,Amazon Simple Queue Service 和 Google Cloud Pub/Sub 等,它们可以是应用可以使用的提供的各种软件。
|
||||||
|
|
||||||
通过Service Catalog,集群运营者可以浏览由Service Broker提供的托管服务列表,提供的托管服务实例,并与其绑定,使其可被Kubernetes集群中的应用程序所使用。
|
通过 Service Catalog,集群运营者可以浏览由 Service Broker 提供的托管服务列表,提供的托管服务实例,并与其绑定,使其可被 Kubernetes 集群中的应用程序所使用。
|
||||||
|
|
||||||
## 场景样例
|
## 场景样例
|
||||||
|
|
||||||
应用程序开发人员编写基于Kubernetes集群的应用程序,他们希望使用消息队列作为其应用程序的一部分。但是,他们不想自己配置和管理这个服务服务。恰好,有一家云提供商通过其服务代理(Service Broker)提供消息队列服务。
|
应用程序开发人员编写基于 Kubernetes 集群的应用程序,他们希望使用消息队列作为其应用程序的一部分。但是,他们不想自己配置和管理这个服务服务。恰好,有一家云提供商通过其服务代理 (Service Broker) 提供消息队列服务。
|
||||||
|
|
||||||
集群运营商可以设置Service Catalog并使用它与云提供商的Service Broker进行通信,以调配消息排队服务的实例并使其可用于Kubernetes集群内的应用程序。因此,应用程序开发人员不需要关心消息队列的实现细节或管理,可以简单地像服务一样使用它。
|
集群运营商可以设置 Service Catalog 并使用它与云提供商的 Service Broker 进行通信,以调配消息排队服务的实例并使其可用于 Kubernetes 集群内的应用程序。因此,应用程序开发人员不需要关心消息队列的实现细节或管理,可以简单地像服务一样使用它。
|
||||||
|
|
||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
Service Catalog使用[Open Service Broker API](https://github.com/openservicebrokerapi/servicebroker)与Service Broker进行通信,充当Kubernetes API服务器的中介,发起供应并返回应用程序使用托管服务所需的凭据。
|
Service Catalog 使用 [Open Service Broker API](https://github.com/openservicebrokerapi/servicebroker) 与 Service Broker 进行通信,充当 Kubernetes API 服务器的中介,发起供应并返回应用程序使用托管服务所需的凭据。
|
||||||
|
|
||||||
Service Catalog通过扩展API服务器和控制器实现,使用etcd进行存储。它还使用Kubernetes 1.7+中提供的聚合层来呈现其API。
|
Service Catalog 通过扩展 API 服务器和控制器实现,使用 etcd 进行存储。它还使用 Kubernetes 1.7 + 中提供的聚合层来呈现其 API。
|
||||||
|
|
||||||
![Service Catalog Architecture](../images/service-catalog-architecture.jpg)
|
![Service Catalog 架构](../images/service-catalog-architecture.jpg)
|
||||||
|
|
||||||
|
### API 资源
|
||||||
|
|
||||||
### API资源
|
Service Catalog 安装 servicecatalog.k8s.ioAPI 并提供以以下 Kubernetes 资源:
|
||||||
Service Catalog安装servicecatalog.k8s.ioAPI并提供以以下Kubernetes资源:
|
|
||||||
|
|
||||||
* ClusterServiceBroker:作为service broker的群集内代理,封装其服务器连接详细信息。这些由集群运营者创建和管理,希望使用broker服务在其集群中提供新类型的托管服务。
|
- ClusterServiceBroker:作为 service broker 的群集内代理,封装其服务器连接详细信息。这些由集群运营者创建和管理,希望使用 broker 服务在其集群中提供新类型的托管服务。
|
||||||
|
- ClusterServiceClass:由特定 service broker 提供的托管服务。将新 ClusterServiceBroker 资源添加到群集时,Service catalog controller 将连接到 service broker 以获取可用托管服务的列表清单。然后它会创建新的 ClusterServiceClass 资源,与每个托管服务相对应。
|
||||||
* ClusterServiceClass:由特定service broker提供的托管服务。将新ClusterServiceBroker资源添加到群集时,Service catalog controller将连接到service broker以获取可用托管服务的列表清单。然后它会创建新的ClusterServiceClass资源,与每个托管服务相对应。
|
- ClusterServicePlan:托管服务的特定产品。例如,托管服务可能有不同的可用套餐,例如免费套餐或付费套餐,或者可能有不同的配置选项,例如使用 SSD 存储或拥有更多资源。同向群集添加 ClusterServiceClass 一样,当添加一个新的 ClusterServiceBroker 时,Service Catalog 会创建一个新的 ClusterServicePlan 资源,与每个托管服务可用的每个服务套餐对应。
|
||||||
|
- ServiceInstance:一个提供好的 ClusterServiceClass 实例。这些是由集群运营者创建的托管服务的特定实例,供一个或多个集群内应用程序使用。当创建一个新的 ServiceInstance 资源时,Service Catalog controller 连接到相应的服务代理并指示它提供服务实例。
|
||||||
* ClusterServicePlan:托管服务的特定产品。例如,托管服务可能有不同的可用套餐,例如免费套餐或付费套餐,或者可能有不同的配置选项,例如使用SSD存储或拥有更多资源。同向群集添加ClusterServiceClass一样,当添加一个新的ClusterServiceBroker时,Service Catalog会创建一个新的ClusterServicePlan资源,与每个托管服务可用的每个服务套餐对应。
|
- ServiceBinding:访问 ServiceInstance 的凭据。由想让他们的应用利用 ServiceInstance 的集群集运营者创建。创建之后,Service Catalog controller 将创建一个与此服务实例对应的 Kubernetes 的 Secret,包含此服务实例的连接详细信息和凭证 ,可以挂载到 Pod 中。
|
||||||
|
|
||||||
* ServiceInstance:一个提供好的ClusterServiceClass实例。这些是由集群运营者创建的托管服务的特定实例,供一个或多个集群内应用程序使用。当创建一个新的ServiceInstance资源时,Service Catalog controller连接到相应的服务代理并指示它提供服务实例。
|
|
||||||
|
|
||||||
* ServiceBinding:访问ServiceInstance的凭据。由想让他们的应用利用ServiceInstance的集群集运营者创建。创建之后,Service Catalog controller将创建一个与此服务实例对应的Kubernetes的Secret,包含此服务实例的连接详细信息和凭证 ,可以挂载到Pod中。
|
|
||||||
|
|
||||||
### 鉴权认证
|
### 鉴权认证
|
||||||
|
|
||||||
Service Catalog 支持这些认证方法:
|
Service Catalog 支持这些认证方法:
|
||||||
|
|
||||||
* Basic (username/password)
|
- Basic (username/password)
|
||||||
* [OAuth 2.0 Bearer Token](https://tools.ietf.org/html/rfc6750)
|
- [OAuth 2.0 Bearer Token](https://tools.ietf.org/html/rfc6750)
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
群集运营者可以使用Service Catalog API资源来提供托管服务,并使其在Kubernetes群集中可用。涉及的步骤是:
|
|
||||||
|
|
||||||
1. 列出Service Broker提供的托管服务清单和服务套餐。
|
群集运营者可以使用 Service Catalog API 资源来提供托管服务,并使其在 Kubernetes 群集中可用。涉及的步骤是:
|
||||||
|
|
||||||
|
1. 列出 Service Broker 提供的托管服务清单和服务套餐。
|
||||||
2. 提供托管服务的新实例。
|
2. 提供托管服务的新实例。
|
||||||
3. 绑定到托管服务,该服务返回连接凭证。
|
3. 绑定到托管服务,该服务返回连接凭证。
|
||||||
4. 将连接凭证映射到应用程序中。
|
4. 将连接凭证映射到应用程序中。
|
||||||
|
|
||||||
### 列出托管服务和服务套餐
|
### 列出托管服务和服务组
|
||||||
|
|
||||||
首先,群集运营者必须在servicecatalog.k8s.io群组内创建ClusterServiceBroker资源。此资源包含访问服务代理端点所需的URL和连接详细信息。
|
首先,群集运营者必须在 servicecatalog.k8s.io 群组内创建 ClusterServiceBroker 资源。此资源包含访问服务代理端点所需的 URL 和连接详细信息。
|
||||||
|
|
||||||
这是一个ClusterServiceBroker资源的例子:
|
这是一个 ClusterServiceBroker 资源的例子:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: servicecatalog.k8s.io/v1beta1
|
apiVersion: servicecatalog.k8s.io/v1beta1
|
||||||
|
@ -72,38 +69,48 @@ spec:
|
||||||
# with the service broker, such as bearer token info or a caBundle for TLS.
|
# with the service broker, such as bearer token info or a caBundle for TLS.
|
||||||
#####
|
#####
|
||||||
```
|
```
|
||||||
以下是说明从一个service broker列出托管服务和套餐所涉及步骤的顺序图:
|
|
||||||
|
|
||||||
![List Services](../images/service-catalog-list.jpg)
|
以下是说明从一个 service broker 列出托管服务和套餐所涉及步骤的顺序图:
|
||||||
|
|
||||||
|
![列出服务](../images/service-catalog-list.jpg)
|
||||||
|
|
||||||
|
1. 将 ClusterServiceBroker 资源添加到 Service catalog 中,它会触发对外部 Service Broker 的调用以获取可用服务的清单。
|
||||||
|
|
||||||
|
2. Service Broker 返回可用托管服务的清单和服务套餐的列表,它们分别在本地缓存为 `ClusterServiceClass` 资源和 `ClusterServicePlan` 资源。
|
||||||
|
|
||||||
1. 将ClusterServiceBroker资源添加到Service catalog中,它会触发对外部Service Broker的调用以获取可用服务的清单。
|
|
||||||
2. Service Broker返回可用托管服务的清单和服务套餐的列表,它们分别在本地缓存为`ClusterServiceClass`资源和`ClusterServicePlan`资源。
|
|
||||||
3. 然后,集群运营者可以使用以下命令获取可用托管服务的清单:
|
3. 然后,集群运营者可以使用以下命令获取可用托管服务的清单:
|
||||||
|
|
||||||
kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
|
```sh
|
||||||
|
kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
|
||||||
|
```
|
||||||
|
|
||||||
它应该输出一个类似于以下格式的服务名称列表:
|
它应该输出一个类似于以下格式的服务名称列表:
|
||||||
|
|
||||||
SERVICE NAME EXTERNAL NAME
|
```sh
|
||||||
4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 cloud-provider-service
|
SERVICE NAME EXTERNAL NAME
|
||||||
... ...
|
4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 cloud-provider-service
|
||||||
|
... ...
|
||||||
|
```
|
||||||
|
|
||||||
他们还可以使用以下命令查看可用的服务套餐:
|
他们还可以使用以下命令查看可用的服务套餐:
|
||||||
|
|
||||||
kubectl get clusterserviceplans -o=custom-columns=PLAN\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
|
```sh
|
||||||
|
kubectl get clusterserviceplans -o=custom-columns=PLAN\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
|
||||||
|
```
|
||||||
|
|
||||||
它应该输出一个类似于以下格式的套餐名称列表:
|
它应该输出一个类似于以下格式的套餐名称列表:
|
||||||
|
|
||||||
PLAN NAME EXTERNAL NAME
|
|
||||||
86064792-7ea2-467b-af93-ac9694d96d52 service-plan-name
|
|
||||||
... ...
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PLAN NAME EXTERNAL NAME
|
||||||
|
86064792-7ea2-467b-af93-ac9694d96d52 service-plan-name
|
||||||
|
... ...
|
||||||
|
```
|
||||||
|
|
||||||
### 提供新的实例
|
### 提供新的实例
|
||||||
|
|
||||||
集群运营者可以通过创建ServiceInstance资源来启动新实例的供应。
|
集群运营者可以通过创建 ServiceInstance 资源来启动新实例的供应。
|
||||||
|
|
||||||
如下是一个ServiceInstance资源的例子:
|
如下是一个 ServiceInstance 资源的例子:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: servicecatalog.k8s.io/v1beta1
|
apiVersion: servicecatalog.k8s.io/v1beta1
|
||||||
|
@ -120,19 +127,20 @@ spec:
|
||||||
# which may be used by the service broker.
|
# which may be used by the service broker.
|
||||||
#####
|
#####
|
||||||
```
|
```
|
||||||
|
|
||||||
以下序列图说明了提供一个新的托管服务的实例所涉及的步骤:
|
以下序列图说明了提供一个新的托管服务的实例所涉及的步骤:
|
||||||
|
|
||||||
![Provision a Service](../images/service-catalog-provision.jpg)
|
![启用一个服务](../images/service-catalog-provision.jpg)
|
||||||
|
|
||||||
1. 当`ServiceInstance`资源创建后,Service Catalog发起到外部service broker来提供服务的一个实例。
|
1. 当 `ServiceInstance` 资源创建后,Service Catalog 发起到外部 service broker 来提供服务的一个实例。
|
||||||
2. service broker创建托管服务的新实例并返回HTTP响应。
|
2. service broker 创建托管服务的新实例并返回 HTTP 响应。
|
||||||
3. 然后,群集运营者可以检查实例的状态,来确认它是否准备就绪。
|
3. 然后,群集运营者可以检查实例的状态,来确认它是否准备就绪。
|
||||||
|
|
||||||
### 绑定到托管服务
|
### 绑定到托管服务
|
||||||
|
|
||||||
在提供新实例后,群集运营者必须绑定到托管服务才能获取到应用程序使用服务所需的连接凭证和服务帐户详细信息。这是通过创建`ServiceBinding`资源完成的。
|
在提供新实例后,群集运营者必须绑定到托管服务才能获取到应用程序使用服务所需的连接凭证和服务帐户详细信息。这是通过创建 `ServiceBinding` 资源完成的。
|
||||||
|
|
||||||
以下是一个`ServiceBinding`资源的例子:
|
以下是一个 `ServiceBinding` 资源的例子:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: servicecatalog.k8s.io/v1beta1
|
apiVersion: servicecatalog.k8s.io/v1beta1
|
||||||
|
@ -163,13 +171,13 @@ spec:
|
||||||
|
|
||||||
绑定后,最后一步是将连接凭证和服务特定的信息映射到应用程序中。这些信息存储在secret中,应用程序可以用来访问并与托管服务连接。
|
绑定后,最后一步是将连接凭证和服务特定的信息映射到应用程序中。这些信息存储在secret中,应用程序可以用来访问并与托管服务连接。
|
||||||
|
|
||||||
![Map connection credentials](../images/service-catalog-map.jpg)
|
![映射连接凭证](../images/service-catalog-map.jpg)
|
||||||
|
|
||||||
#### Pod配置文件
|
#### Pod 配置文件
|
||||||
|
|
||||||
执行此映射的一种方法是使用声明式Pod配置文件。
|
执行此映射的一种方法是使用声明式 Pod 配置文件。
|
||||||
|
|
||||||
以下示例描述了如何将服务帐户凭证映射到应用程序中。被调用的sa-key密钥存储在名为provider-cloud-key的卷中,并且应用程序将此卷挂载到/var/secrets/provider/key.json。环境变量PROVIDER_APPLICATION_CREDENTIALS是从挂载文件的值映射而来的。
|
以下示例描述了如何将服务帐户凭证映射到应用程序中。被调用的 sa-key 密钥存储在名为 provider-cloud-key 的卷中,并且应用程序将此卷挂载到 /var/secrets/provider/key.json。环境变量 PROVIDER_APPLICATION_CREDENTIALS 是从挂载文件的值映射而来的。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
...
|
...
|
||||||
|
@ -188,7 +196,7 @@ spec:
|
||||||
value: "/var/secrets/provider/key.json"
|
value: "/var/secrets/provider/key.json"
|
||||||
```
|
```
|
||||||
|
|
||||||
以下示例描述如何将secret值映射到应用程序环境变量。在此示例中,消息传递队列`topic`名称从名为`provider-queue-credentials`的secret的key topic值映射到环境变量`TOPIC`。
|
以下示例描述如何将 secret 值映射到应用程序环境变量。在此示例中,消息传递队列 `topic` 名称从名为 `provider-queue-credentials` 的 secret 的 key topic 值映射到环境变量 `TOPIC`。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
...
|
...
|
||||||
|
@ -202,134 +210,155 @@ spec:
|
||||||
|
|
||||||
## 下一步
|
## 下一步
|
||||||
|
|
||||||
* 如果熟悉Helm Charts ,使用Helm将Service Catalog安装到Kubernetes集群中。或者,可以使用SC工具安装服务目录。
|
- 如果熟悉 Helm Charts ,使用 Helm 将 Service Catalog 安装到 Kubernetes 集群中。或者,可以使用 SC 工具安装服务目录。
|
||||||
* 查看 [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
|
- 查看 [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers)。
|
||||||
* 探索[kubernetes-incubator/service-catalog](https://github.com/kubernetes-incubator/service-catalog) 项目。
|
- 探索 [kubernetes-incubator/service-catalog](https://github.com/kubernetes-sigs/service-catalog) 项目。
|
||||||
|
|
||||||
以上翻译自[官方文档](https://kubernetes.io/docs/concepts/service-catalog/)。
|
以上翻译自[官方文档](https://kubernetes.io/docs/concepts/extend-kubernetes/service-catalog/)。
|
||||||
|
|
||||||
## Service Catalog的安装(利用Helm)和交互
|
## Service Catalog 的安装 (利用 Helm) 和交互
|
||||||
|
|
||||||
以下翻译自[官方项目文档](https://github.com/kubernetes-incubator/service-catalog/blob/master/docs/install.md)。与[官方网站文档](https://kubernetes.io/docs/tasks/service-catalog/install-service-catalog-using-helm/)大致一致。
|
以下翻译自[官方项目文档](https://github.com/kubernetes-incubator/service-catalog/blob/master/docs/install.md)。与[官方网站文档](https://kubernetes.io/docs/tasks/service-catalog/install-service-catalog-using-helm/)大致一致。
|
||||||
|
|
||||||
Kubernetes 1.7或更高版本的集群运行 API Aggregator,它位于core API Server前面的专用proxy服务器。
|
Kubernetes 1.7 或更高版本的集群运行 API Aggregator,它位于 core API Server 前面的专用 proxy 服务器。
|
||||||
|
|
||||||
服务目录(Service Catalog)提供了一个位于API aggregator后面的API Server,因此可以用kubectl像平常一样与Service Catalog进行交互。
|
服务目录 (Service Catalog) 提供了一个位于 API aggregator 后面的 API Server,因此可以用 kubectl 像平常一样与 Service Catalog 进行交互。
|
||||||
|
|
||||||
要了解更多关于API aggregation的信息,请参阅 [Kubernetes文档](https://kubernetes.io/docs/concepts/api-extension/apiserver-aggregation/)。
|
要了解更多关于 API aggregation 的信息,请参阅 [Kubernetes 文档](https://kubernetes.io/docs/concepts/api-extension/apiserver-aggregation/)。
|
||||||
|
|
||||||
本文档的其余部分详细介绍了如何:
|
本文档的其余部分详细介绍了如何:
|
||||||
|
|
||||||
- 在群集上设置Service Catalog
|
- 在群集上设置 Service Catalog
|
||||||
- 与Service Catalog API进行交互
|
- 与 Service Catalog API 进行交互
|
||||||
|
|
||||||
## 前提条件
|
## 前提条件
|
||||||
|
|
||||||
### Kubernetes版本
|
### Kubernetes 版本
|
||||||
Service Catalog需要Kubernetes v1.7或更高版本。您还需要 在主机上安装[Kubernetes configuration file](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) 。你需要这个文件,以便可以使用kubectl和 helm与群集通信。许多Kubernetes安装工具或云提供商会为你设置此配置文件。有关详细信息,请与您的工具或提供商联系。
|
|
||||||
|
|
||||||
#### `kubectl`版本
|
Service Catalog 需要 Kubernetes v1.7 或更高版本。您还需要 在主机上安装 [Kubernetes configuration file](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) 。你需要这个文件,以便可以使用 kubectl 和 helm 与群集通信。许多 Kubernetes 安装工具或云提供商会为你设置此配置文件。有关详细信息,请与您的工具或提供商联系。
|
||||||
大多数与Service Catalog系统的交互都是通过`kubectl`命令行界面实现的。与群集版本一样,Service Catalog需要kubectl版本1.7或更高版本。
|
|
||||||
|
|
||||||
首先,检查`kubectl`版本:
|
#### `kubectl` 版本
|
||||||
|
|
||||||
|
大多数与 Service Catalog 系统的交互都是通过 `kubectl` 命令行界面实现的。与群集版本一样,Service Catalog 需要 kubectl 版本 1.7 或更高版本。
|
||||||
|
|
||||||
|
首先,检查 `kubectl` 版本:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl version
|
kubectl version
|
||||||
```
|
```
|
||||||
确保Kubernetes版本和kubectl版本均为1.7或更高。
|
|
||||||
|
|
||||||
如果需要升级客户端,请按照[安装说明](https://kubernetes.io/docs/tasks/kubectl/install/) 获取新的`kubectl`二进制文件。
|
确保 Kubernetes 版本和 kubectl 版本均为 1.7 或更高。
|
||||||
|
|
||||||
例如,运行以下命令以在Mac OS上获取最新的二进制文件:
|
如果需要升级客户端,请按照[安装说明](https://kubernetes.io/docs/tasks/kubectl/install/) 获取新的 `kubectl` 二进制文件。
|
||||||
|
|
||||||
|
例如,运行以下命令以在 Mac OS 上获取最新的二进制文件:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
|
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
|
||||||
chmod +x ./kubectl
|
chmod +x ./kubectl
|
||||||
```
|
```
|
||||||
### 群集内DNS
|
|
||||||
|
|
||||||
您需要启用Kubernetes集群内的DNS。大多数常用的安装方法会为您自动配置群集内DNS:
|
### 群集内 DNS
|
||||||
|
|
||||||
|
您需要启用 Kubernetes 集群内的 DNS。大多数常用的安装方法会为您自动配置群集内 DNS:
|
||||||
|
|
||||||
- [Minikube](https://github.com/kubernetes/minikube)
|
- [Minikube](https://github.com/kubernetes/minikube)
|
||||||
- [`hack/local-up-cluster.sh`](https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh)
|
- [`hack/local-up-cluster.sh`](https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh)
|
||||||
- 大多数云提供商
|
- 大多数云提供商
|
||||||
|
|
||||||
### Helm
|
### Helm
|
||||||
使用Helm安装Service Catalog ,需要v2.7.0或更高版本。请参阅以下步骤进行安装。
|
|
||||||
|
|
||||||
#### 如果还没有安装Helm
|
使用 Helm 安装 Service Catalog ,需要 v2.7.0 或更高版本。请参阅以下步骤进行安装。
|
||||||
如果尚未安装Helm,请下载[`helm` CLI](https://github.com/kubernetes/helm#install),然后运行helm init(这会将Helm的服务器端组件Tiller安装到Kubernetes群集中)。
|
|
||||||
|
|
||||||
#### 如果已经安装了Helm
|
#### 如果还没有安装 Helm
|
||||||
如果已经安装了Helm,请运行helm version并确保客户端和服务器版本均为v2.7.0或更高。
|
|
||||||
|
|
||||||
如果不是, 请安装[更新版本的helm CLI](https://github.com/kubernetes/helm#install)并运行`helm init --upgrade`。
|
如果尚未安装 Helm,请下载 [`helm` CLI](https://github.com/kubernetes/helm#install),然后运行 helm init(这会将 Helm 的服务器端组件 Tiller 安装到 Kubernetes 群集中)。
|
||||||
|
|
||||||
有关安装的更多详细信息,请参阅 Helm安装说明。
|
#### 如果已经安装了 Helm
|
||||||
|
|
||||||
|
如果已经安装了 Helm,请运行 helm version 并确保客户端和服务器版本均为 v2.7.0 或更高。
|
||||||
|
|
||||||
|
如果不是, 请安装[更新版本的 helm CLI](https://github.com/kubernetes/helm#install) 并运行 `helm init --upgrade`。
|
||||||
|
|
||||||
|
有关安装的更多详细信息,请参阅 Helm 安装说明。
|
||||||
|
|
||||||
#### Tiller 权限
|
#### Tiller 权限
|
||||||
Tiller是Helm的服务端组件。默认情况下, helm init将Tiller pod安装到kube-system名称空间中,并将Tiller配置为使用default服务帐户(service account)。
|
|
||||||
|
|
||||||
需要对Tiller进行配置`cluster-admin`权限,才能正确安装Service Catalog:
|
Tiller 是 Helm 的服务端组件。默认情况下, helm init 将 Tiller pod 安装到 kube-system 名称空间中,并将 Tiller 配置为使用 default 服务帐户(service account)。
|
||||||
|
|
||||||
|
需要对 Tiller 进行配置 `cluster-admin` 权限,才能正确安装 Service Catalog:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl create clusterrolebinding tiller-cluster-admin \
|
kubectl create clusterrolebinding tiller-cluster-admin \
|
||||||
--clusterrole=cluster-admin \
|
--clusterrole=cluster-admin \
|
||||||
--serviceaccount=kube-system:default
|
--serviceaccount=kube-system:default
|
||||||
```
|
```
|
||||||
### Helm Repository设置
|
|
||||||
Service Catalog很容易通过 Helm chart 安装 。
|
|
||||||
|
|
||||||
此chart位于 chart repository 中。将此repository添加到本地计算机:
|
### Helm Repository 设置
|
||||||
|
|
||||||
|
Service Catalog 很容易通过 Helm chart 安装 。
|
||||||
|
|
||||||
|
此 chart 位于 chart repository 中。将此 repository 添加到本地计算机:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
helm repo add svc-cat https://svc-catalog-charts.storage.googleapis.com
|
helm repo add svc-cat https://svc-catalog-charts.storage.googleapis.com
|
||||||
```
|
```
|
||||||
然后,确保repository已成功添加:
|
|
||||||
|
然后,确保 repository 已成功添加:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
helm search service-catalog
|
helm search service-catalog
|
||||||
```
|
```
|
||||||
|
|
||||||
应该看到以下输出:
|
应该看到以下输出:
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
NAME VERSION DESCRIPTION
|
NAME VERSION DESCRIPTION
|
||||||
svc-cat/catalog x,y.z service-catalog API server and controller-manag...
|
svc-cat/catalog x,y.z service-catalog API server and controller-manag...
|
||||||
```
|
```
|
||||||
### RBAC
|
|
||||||
Kubernetes群集必须启用[RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) 才能使用Service Catalog。
|
|
||||||
|
|
||||||
与群集内DNS一样,许多安装方法都有对应启用RBAC的途径。
|
### RBAC
|
||||||
|
|
||||||
|
Kubernetes 群集必须启用 [RBAC](https://kubernetes.io/docs/admin/authorization/rbac/) 才能使用 Service Catalog。
|
||||||
|
|
||||||
|
与群集内 DNS 一样,许多安装方法都有对应启用 RBAC 的途径。
|
||||||
|
|
||||||
#### Minikube
|
#### Minikube
|
||||||
如果您正在使用Minikube,请使用以下命令启动群集:
|
|
||||||
|
如果您正在使用 Minikube,请使用以下命令启动群集:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
minikube start --extra-config=apiserver.Authorization.Mode=RBAC
|
minikube start --extra-config=apiserver.Authorization.Mode=RBAC
|
||||||
```
|
```
|
||||||
|
|
||||||
#### hack/local-cluster-up.sh
|
#### hack/local-cluster-up.sh
|
||||||
如果使用[`hack/local-up-cluster.sh`](https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh)脚本,请使用以下命令启动群集:
|
|
||||||
|
如果使用 [`hack/local-up-cluster.sh`](https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh) 脚本,请使用以下命令启动群集:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
AUTHORIZATION_MODE=Node,RBAC hack/local-up-cluster.sh -O
|
AUTHORIZATION_MODE=Node,RBAC hack/local-up-cluster.sh -O
|
||||||
```
|
```
|
||||||
#### 云提供商
|
|
||||||
许多云提供商为你启用了RBAC的新集群。有关详细信息,请查阅你的提供商的文档。
|
|
||||||
|
|
||||||
## 安装Service Catalog
|
#### 云提供商
|
||||||
集群和Helm配置正确,安装Service Catalog很简单:
|
|
||||||
|
许多云提供商为你启用了 RBAC 的新集群。有关详细信息,请查阅你的提供商的文档。
|
||||||
|
|
||||||
|
## 安装 Service Catalog
|
||||||
|
|
||||||
|
集群和 Helm 配置正确,安装 Service Catalog 很简单:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
helm install svc-cat/catalog \
|
helm install svc-cat/catalog \
|
||||||
--name catalog --namespace catalog
|
--name catalog --namespace catalog
|
||||||
```
|
```
|
||||||
## 安装Service Catalog CLI 客户端
|
|
||||||
按照适用于操作系统的说明安装svcat。二进制文件可以单独使用,也可以作为kubectl插件使用。
|
## 安装 Service Catalog CLI 客户端
|
||||||
|
|
||||||
|
按照适用于操作系统的说明安装 svcat。二进制文件可以单独使用,也可以作为 kubectl 插件使用。
|
||||||
|
|
||||||
### MacOS
|
### MacOS
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -sLO https://download.svcat.sh/cli/latest/darwin/amd64/svcat
|
curl -sLO https://download.svcat.sh/cli/latest/darwin/amd64/svcat
|
||||||
chmod +x ./svcat
|
chmod +x ./svcat
|
||||||
mv ./svcat /usr/local/bin/
|
mv ./svcat /usr/local/bin/
|
||||||
|
@ -338,15 +367,16 @@ svcat version --client
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -sLO https://download.svcat.sh/cli/latest/linux/amd64/svcat
|
curl -sLO https://download.svcat.sh/cli/latest/linux/amd64/svcat
|
||||||
chmod +x ./svcat
|
chmod +x ./svcat
|
||||||
mv ./svcat /usr/local/bin/
|
mv ./svcat /usr/local/bin/
|
||||||
svcat version --client
|
svcat version --client
|
||||||
```
|
```
|
||||||
### Windows
|
|
||||||
下面的片段仅在当前会话的PATH添加一个路径。后续使用需要将它相应的路径永久添加到PATH中。
|
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
下面的片段仅在当前会话的 PATH 添加一个路径。后续使用需要将它相应的路径永久添加到 PATH 中。
|
||||||
|
|
||||||
```
|
```
|
||||||
iwr 'https://download.svcat.sh/cli/latest/windows/amd64/svcat.exe' -UseBasicParsing -OutFile svcat.exe
|
iwr 'https://download.svcat.sh/cli/latest/windows/amd64/svcat.exe' -UseBasicParsing -OutFile svcat.exe
|
||||||
|
@ -356,18 +386,21 @@ svcat version --client
|
||||||
```
|
```
|
||||||
|
|
||||||
### 手动方式
|
### 手动方式
|
||||||
|
|
||||||
1. 对应操作系统下载相应的二进制文件:
|
1. 对应操作系统下载相应的二进制文件:
|
||||||
* macOS: https://download.svcat.sh/cli/latest/darwin/amd64/svcat
|
- [macOS](https://download.svcat.sh/cli/latest/darwin/amd64/svcat)
|
||||||
* Windows: https://download.svcat.sh/cli/latest/windows/amd64/svcat.exe
|
- [Windows](https://download.svcat.sh/cli/latest/windows/amd64/svcat.exe)
|
||||||
* Linux: https://download.svcat.sh/cli/latest/linux/amd64/svcat
|
- [Linux](https://download.svcat.sh/cli/latest/linux/amd64/svcat)
|
||||||
2. 使二进制文件可执行。
|
2. 使二进制文件可执行。
|
||||||
3. 将二进制文件移动到PATH相应的目录。
|
3. 将二进制文件移动到 PATH 相应的目录。
|
||||||
|
|
||||||
### 插件方式使用客户端
|
### 插件方式使用客户端
|
||||||
要将svcat用作插件,请在下载后运行以下命令:
|
|
||||||
|
要将 svcat 用作插件,请在下载后运行以下命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./svcat install plugin
|
$ ./svcat install plugin
|
||||||
Plugin has been installed to ~/.kube/plugins/svcat. Run kubectl plugin svcat --help for help using the plugin.
|
Plugin has been installed to ~/.kube/plugins/svcat. Run kubectl plugin svcat --help for help using the plugin.
|
||||||
```
|
```
|
||||||
当作为插件运行时,这些命令与添加全局kubectl配置标志相同。其中一个例外是,在插件模式下运行时不支持布尔标志,所以不要使用`--flag`,必须指定`--flag=true`。
|
|
||||||
|
当作为插件运行时,这些命令与添加全局 kubectl 配置标志相同。其中一个例外是,在插件模式下运行时不支持布尔标志,所以不要使用 `--flag`, 必须指定 `--flag=true`。
|
||||||
|
|
|
@ -435,4 +435,4 @@ Kubernetes 最主要的哲学之一,是用户不应该暴露那些能够导致
|
||||||
|
|
||||||
## 更多信息
|
## 更多信息
|
||||||
|
|
||||||
- [使用 Service 连接 Frontend 到 Backend](https://kubernetes.io/docs/tutorials/connecting-apps/connecting-frontend-backend/)
|
- [使用 Service 连接 Frontend 到 Backend - kubernetes.io](https://kubernetes.io/docs/tutorials/connecting-apps/connecting-frontend-backend/)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Service Account
|
# ServiceAccount
|
||||||
|
|
||||||
Service Account为Pod中的进程提供身份信息。
|
ServiceAccount 为 Pod 中的进程提供身份信息。
|
||||||
|
|
||||||
**注意**:**本文是关于 Service Account 的用户指南,管理指南另见 Service Account 的集群管理指南 。**
|
**注意**:**本文是关于 Service Account 的用户指南,管理指南另见 Service Account 的集群管理指南 。**
|
||||||
|
|
||||||
|
@ -205,4 +205,4 @@ spec:
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Configure Service Accounts for Pods](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
|
- [Configure Service Accounts for Pods - kubernetes.io](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
|
||||||
|
|
|
@ -711,6 +711,6 @@ spec:
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- https://kubernetes.io/docs/concepts/storage/volumes/
|
- [Volumes - kubernetes.io](https://kubernetes.io/docs/concepts/storage/volumes/)
|
||||||
|
|
||||||
- [使用持久化卷来部署 WordPress 和 MySQL](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/)
|
- [使用持久化卷来部署 WordPress 和 MySQL - kubernetes.io](https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# 访问集群
|
# 访问集群
|
||||||
|
|
||||||
|
本文列举了集中访问 Kubernetes 集群的方式。
|
||||||
|
|
||||||
## 第一次使用 kubectl 访问
|
## 第一次使用 kubectl 访问
|
||||||
|
|
||||||
如果您是第一次访问 Kubernetes API 的话,我们建议您使用 Kubernetes 命令行工具:`kubectl`。
|
如果您是第一次访问 Kubernetes API 的话,我们建议您使用 Kubernetes 命令行工具:`kubectl`。
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# 访问 Kubernetes 集群
|
# 访问 Kubernetes 集群
|
||||||
|
|
||||||
根据用户部署和暴露服务的方式不同,有很多种方式可以用来访问 kubernetes 集群。
|
根据用户部署和暴露服务的方式不同,有很多种方式可以用来访问 Kubernetes 集群。
|
||||||
|
|
||||||
- 最简单也是最直接的方式是使用 `kubectl` 命令。
|
- 最简单也是最直接的方式是使用 `kubectl` 命令。
|
||||||
- 其次可以使用 `kubeconfig` 文件来认证授权访问 API server。
|
- 其次可以使用 `kubeconfig` 文件来认证授权访问 API server。
|
||||||
- 通过各种 proxy 经过端口转发访问 kubernetes 集群中的服务
|
- 通过各种 proxy 经过端口转发访问 Kubernetes 集群中的服务
|
||||||
- 使用 Ingress,在集群外访问 kubernetes 集群内的 service
|
- 使用 Ingress,在集群外访问 Kubernetes 集群内的 service
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# 从外部访问Kubernetes中的Pod
|
# 从外部访问 Kubernetes 中的 Pod
|
||||||
|
|
||||||
前面几节讲到如何访问kubneretes集群,本文主要讲解访问kubenretes中的Pod和Serivce的几种方式,包括如下几种:
|
前面几节讲到如何访问 Kubernetes 集群,本文主要讲解访问 Kubernetes 中的 Pod 和 Serivce 的几种方式,包括如下几种:
|
||||||
|
|
||||||
- hostNetwork
|
- hostNetwork
|
||||||
- hostPort
|
- hostPort
|
||||||
|
@ -8,13 +8,13 @@
|
||||||
- LoadBalancer
|
- LoadBalancer
|
||||||
- Ingress
|
- Ingress
|
||||||
|
|
||||||
说是暴露Pod其实跟暴露Service是一回事,因为Pod就是Service的backend。
|
说是暴露 Pod 其实跟暴露 Service 是一回事,因为 Pod 就是 Service 的 backend。
|
||||||
|
|
||||||
## hostNetwork: true
|
## hostNetwork: true
|
||||||
|
|
||||||
这是一种直接定义Pod网络的方式。
|
这是一种直接定义 Pod 网络的方式。
|
||||||
|
|
||||||
如果在Pod中使用`hostNotwork:true`配置的话,在这种pod中运行的应用程序可以直接看到pod启动的主机的网络接口。在主机的所有网络接口上都可以访问到该应用程序。以下是使用主机网络的pod的示例定义:
|
如果在 Pod 中使用 `hostNotwork:true` 配置的话,在这种 pod 中运行的应用程序可以直接看到 pod 启动的主机的网络接口。在主机的所有网络接口上都可以访问到该应用程序。以下是使用主机网络的 pod 的示例定义:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -28,29 +28,29 @@ spec:
|
||||||
image: influxdb
|
image: influxdb
|
||||||
```
|
```
|
||||||
|
|
||||||
部署该Pod:
|
部署该 Pod:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl create -f influxdb-hostnetwork.yml
|
$ kubectl create -f influxdb-hostnetwork.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
访问该pod所在主机的8086端口:
|
访问该 pod 所在主机的 8086 端口:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -v http://$POD_IP:8086/ping
|
curl -v http://$POD_IP:8086/ping
|
||||||
```
|
```
|
||||||
|
|
||||||
将看到204 No Content的204返回码,说明可以正常访问。
|
将看到 204 No Content 的 204 返回码,说明可以正常访问。
|
||||||
|
|
||||||
注意每次启动这个Pod的时候都可能被调度到不同的节点上,所有外部访问Pod的IP也是变化的,而且调度Pod的时候还需要考虑是否与宿主机上的端口冲突,因此一般情况下除非您知道需要某个特定应用占用特定宿主机上的特定端口时才使用`hostNetwork: true`的方式。
|
注意每次启动这个 Pod 的时候都可能被调度到不同的节点上,所有外部访问 Pod 的 IP 也是变化的,而且调度 Pod 的时候还需要考虑是否与宿主机上的端口冲突,因此一般情况下除非您知道需要某个特定应用占用特定宿主机上的特定端口时才使用 `hostNetwork: true` 的方式。
|
||||||
|
|
||||||
这种Pod的网络模式有一个用处就是可以将网络插件包装在Pod中然后部署在每个宿主机上,这样该Pod就可以控制该宿主机上的所有网络。
|
这种 Pod 的网络模式有一个用处就是可以将网络插件包装在 Pod 中然后部署在每个宿主机上,这样该 Pod 就可以控制该宿主机上的所有网络。
|
||||||
|
|
||||||
## hostPort
|
## hostPort
|
||||||
|
|
||||||
这是一种直接定义Pod网络的方式。
|
这是一种直接定义 Pod 网络的方式。
|
||||||
|
|
||||||
`hostPort`是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的IP加上<hostPort>来访问Pod了,如<hostIP>:<hostPort>。
|
`hostPort` 是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的 IP 加上来访问 Pod 了,如:。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -66,13 +66,13 @@ spec:
|
||||||
hostPort: 8086
|
hostPort: 8086
|
||||||
```
|
```
|
||||||
|
|
||||||
这样做有个缺点,因为Pod重新调度的时候该Pod被调度到的宿主机可能会变动,这样<hostIP>就变化了,用户必须自己维护一个Pod与所在宿主机的对应关系。
|
这样做有个缺点,因为 Pod 重新调度的时候该 Pod 被调度到的宿主机可能会变动,这样就变化了,用户必须自己维护一个 Pod 与所在宿主机的对应关系。
|
||||||
|
|
||||||
这种网络方式可以用来做 nginx ingress controller。外部流量都需要通过kubenretes node节点的80和443端口。
|
这种网络方式可以用来做 nginx ingress controller。外部流量都需要通过 Kubernetes node 节点的 80 和 443 端口。
|
||||||
|
|
||||||
## NodePort
|
## NodePort
|
||||||
|
|
||||||
NodePort在kubenretes里是一个广泛应用的服务暴露方式。Kubernetes中的service默认情况下都是使用的`ClusterIP`这种类型,这样的service会产生一个ClusterIP,这个IP只能在集群内部访问,要想让外部能够直接访问service,需要将service type修改为 `nodePort`。
|
NodePort 在 Kubernetes 里是一个广泛应用的服务暴露方式。Kubernetes 中的 service 默认情况下都是使用的 `ClusterIP` 这种类型,这样的 service 会产生一个 ClusterIP,这个 IP 只能在集群内部访问,要想让外部能够直接访问 service,需要将 service type 修改为 `nodePort`。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -89,7 +89,7 @@ spec:
|
||||||
- containerPort: 8086
|
- containerPort: 8086
|
||||||
```
|
```
|
||||||
|
|
||||||
同时还可以给service指定一个`nodePort`值,范围是30000-32767,这个值在API server的配置文件中,用`--service-node-port-range`定义。
|
同时还可以给 service 指定一个 `nodePort` 值,范围是 30000-32767,这个值在 API server 的配置文件中,用 `--service-node-port-range` 定义。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -105,13 +105,13 @@ spec:
|
||||||
name: influxdb
|
name: influxdb
|
||||||
```
|
```
|
||||||
|
|
||||||
集群外就可以使用kubernetes任意一个节点的IP加上30000端口访问该服务了。kube-proxy会自动将流量以round-robin的方式转发给该service的每一个pod。
|
集群外就可以使用 kubernetes 任意一个节点的 IP 加上 30000 端口访问该服务了。kube-proxy 会自动将流量以 round-robin 的方式转发给该 service 的每一个 pod。
|
||||||
|
|
||||||
这种服务暴露方式,无法让你指定自己想要的应用常用端口,不过可以在集群上再部署一个反向代理作为流量入口。
|
这种服务暴露方式,无法让你指定自己想要的应用常用端口,不过可以在集群上再部署一个反向代理作为流量入口。
|
||||||
|
|
||||||
## LoadBalancer
|
## LoadBalancer
|
||||||
|
|
||||||
`LoadBalancer` 只能在service上定义。这是公有云提供的负载均衡器,如AWS、Azure、CloudStack、GCE等。
|
`LoadBalancer` 只能在 service 上定义。这是公有云提供的负载均衡器,如 AWS、Azure、CloudStack、GCE 等。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -134,18 +134,18 @@ NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
influxdb 10.97.121.42 10.13.242.236 8086:30051/TCP 39s
|
influxdb 10.97.121.42 10.13.242.236 8086:30051/TCP 39s
|
||||||
```
|
```
|
||||||
|
|
||||||
内部可以使用ClusterIP加端口来访问服务,如19.97.121.42:8086。
|
内部可以使用 ClusterIP 加端口来访问服务,如 19.97.121.42:8086。
|
||||||
|
|
||||||
外部可以用以下两种方式访问该服务:
|
外部可以用以下两种方式访问该服务:
|
||||||
|
|
||||||
- 使用任一节点的IP加30051端口访问该服务
|
- 使用任一节点的 IP 加 30051 端口访问该服务
|
||||||
- 使用`EXTERNAL-IP`来访问,这是一个VIP,是云供应商提供的负载均衡器IP,如10.13.242.236:8086。
|
- 使用 `EXTERNAL-IP` 来访问,这是一个 VIP,是云供应商提供的负载均衡器 IP,如 10.13.242.236:8086。
|
||||||
|
|
||||||
## Ingress
|
## Ingress
|
||||||
|
|
||||||
`Ingress`是自kubernetes1.1版本后引入的资源类型。必须要部署 Ingress controller 才能创建Ingress资源,Ingress controller是以一种插件的形式提供。Ingress controller 是部署在Kubernetes之上的Docker容器。它的Docker镜像包含一个像nginx或HAProxy的负载均衡器和一个控制器守护进程。控制器守护程序从Kubernetes接收所需的Ingress配置。它会生成一个nginx或HAProxy配置文件,并重新启动负载平衡器进程以使更改生效。换句话说,Ingress controller是由Kubernetes管理的负载均衡器。
|
`Ingress` 是自 kubernetes1.1 版本后引入的资源类型。必须要部署 Ingress controller 才能创建 Ingress 资源,Ingress controller 是以一种插件的形式提供。Ingress controller 是部署在 Kubernetes 之上的 Docker 容器。它的 Docker 镜像包含一个像 nginx 或 HAProxy 的负载均衡器和一个控制器守护进程。控制器守护程序从 Kubernetes 接收所需的 Ingress 配置。它会生成一个 nginx 或 HAProxy 配置文件,并重新启动负载平衡器进程以使更改生效。换句话说,Ingress controller 是由 Kubernetes 管理的负载均衡器。
|
||||||
|
|
||||||
Kubernetes Ingress提供了负载平衡器的典型特性:HTTP路由,粘性会话,SSL终止,SSL直通,TCP和UDP负载平衡等。目前并不是所有的Ingress controller都实现了这些功能,需要查看具体的Ingress controller文档。
|
Kubernetes Ingress 提供了负载平衡器的典型特性:HTTP 路由,粘性会话,SSL 终止,SSL 直通,TCP 和 UDP 负载平衡等。目前并不是所有的 Ingress controller 都实现了这些功能,需要查看具体的 Ingress controller 文档。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
|
@ -162,11 +162,11 @@ spec:
|
||||||
servicePort: 8086
|
servicePort: 8086
|
||||||
```
|
```
|
||||||
|
|
||||||
外部访问URL `http://influxdb.kube.example.com/ping` 访问该服务,入口就是80端口,然后Ingress controller直接将流量转发给后端Pod,不需再经过kube-proxy的转发,比LoadBalancer方式更高效。
|
外部访问 URL `http://influxdb.kube.example.com/ping` 访问该服务,入口就是 80 端口,然后 Ingress controller 直接将流量转发给后端 Pod,不需再经过 kube-proxy 的转发,比 LoadBalancer 方式更高效。
|
||||||
|
|
||||||
## 总结
|
## 总结
|
||||||
|
|
||||||
总的来说Ingress是一个非常灵活和越来越得到厂商支持的服务暴露方式,包括Nginx、HAProxy、Traefik,还有各种Service Mesh,而其它服务暴露方式可以更适用于服务调试、特殊应用的部署。
|
总的来说 Ingress 是一个非常灵活和越来越得到厂商支持的服务暴露方式,包括 Nginx、HAProxy、Traefik,还有各种 服务网格,而其它服务暴露方式可以更适用于服务调试、特殊应用的部署。
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
|
|
|
@ -629,6 +629,7 @@ rules:
|
||||||
#### 认证 API
|
#### 认证 API
|
||||||
|
|
||||||
您可以使用 `certificates.k8s.io` API将 x509 证书配置为用于身份验证,如 [此处](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster) 所述。
|
您可以使用 `certificates.k8s.io` API将 x509 证书配置为用于身份验证,如 [此处](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster) 所述。
|
||||||
官方最新文档地址:https://kubernetes.io/docs/admin/authentication/
|
|
||||||
|
|
||||||
译者:[Jimmy Song](https://jimmysong.io)
|
## 参考
|
||||||
|
|
||||||
|
- [Authenticating - kubernetes.io](https://kubernetes.io/docs/reference/access-authn-authz/authentication/)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Cabin - Kubernetes手机客户端
|
# Cabin - Kubernetes 手机客户端
|
||||||
|
|
||||||
cabin是由[bitnami](https://bitnami.com/)开源的手机管理Kubernetes集群的客户端,目前提供iOS和安卓版本,代码开源在GitHub上:<https://bitnami.com/>
|
cabin是由[bitnami](https://bitnami.com/)开源的手机管理Kubernetes集群的客户端,目前提供iOS和安卓版本,代码开源在GitHub上:<https://bitnami.com/>
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
# 配置Pod的liveness和readiness探针
|
# 配置Pod的liveness和readiness探针
|
||||||
|
|
||||||
当你使用kubernetes的时候,有没有遇到过Pod在启动后一会就挂掉然后又重新启动这样的恶性循环?你有没有想过kubernetes是如何检测pod是否还存活?虽然容器已经启动,但是kubernetes如何知道容器的进程是否准备好对外提供服务了呢?让我们通过kubernetes官网的这篇文章[Configure Liveness and Readiness Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),来一探究竟。
|
当你使用 Kubernetes 的时候,有没有遇到过 Pod 在启动后一会就挂掉然后又重新启动这样的恶性循环?你有没有想过 Kubernetes 是如何检测 pod 是否还存活?虽然容器已经启动,但是 Kubernetes 如何知道容器的进程是否准备好对外提供服务了呢?让我们通过 Kubernetes 官网的这篇文章 [Configure Liveness and Readiness Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),来一探究竟。
|
||||||
|
|
||||||
本文将展示如何配置容器的存活和可读性探针。
|
本文将展示如何配置容器的存活和可读性探针。
|
||||||
|
|
||||||
Kubelet使用liveness probe(存活探针)来确定何时重启容器。例如,当应用程序处于运行状态但无法做进一步操作,liveness探针将捕获到deadlock,重启处于该状态下的容器,使应用程序在存在bug的情况下依然能够继续运行下去(谁的程序还没几个bug呢)。
|
Kubelet 使用 liveness probe(存活探针)来确定何时重启容器。例如,当应用程序处于运行状态但无法做进一步操作,liveness 探针将捕获到 deadlock,重启处于该状态下的容器,使应用程序在存在 bug 的情况下依然能够继续运行下去(谁的程序还没几个 bug 呢)。
|
||||||
|
|
||||||
Kubelet使用readiness probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当Pod中的容器都处于就绪状态时kubelet才会认定该Pod处于就绪状态。该信号的作用是控制哪些Pod应该作为service的后端。如果Pod处于非就绪状态,那么它们将会被从service的load balancer中移除。
|
Kubelet 使用 readiness probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当 Pod 中的容器都处于就绪状态时 kubelet 才会认定该 Pod 处于就绪状态。该信号的作用是控制哪些 Pod 应该作为 service 的后端。如果 Pod 处于非就绪状态,那么它们将会被从 service 的 load balancer 中移除。
|
||||||
|
|
||||||
## 定义 liveness命令
|
## 定义 liveness 命令
|
||||||
|
|
||||||
许多长时间运行的应用程序最终会转换到broken状态,除非重新启动,否则无法恢复。Kubernetes提供了liveness probe来检测和补救这种情况。
|
许多长时间运行的应用程序最终会转换到 broken 状态,除非重新启动,否则无法恢复。Kubernetes 提供了 liveness probe 来检测和补救这种情况。
|
||||||
|
|
||||||
在本次练习将基于 `gcr.io/google_containers/busybox`镜像创建运行一个容器的Pod。以下是Pod的配置文件`exec-liveness.yaml`:
|
在本次练习将基于 `gcr.io/google_containers/busybox` 镜像创建运行一个容器的 Pod。以下是 Pod 的配置文件 `exec-liveness.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -38,7 +38,7 @@ spec:
|
||||||
periodSeconds: 5
|
periodSeconds: 5
|
||||||
```
|
```
|
||||||
|
|
||||||
该配置文件给Pod配置了一个容器。`periodSeconds` 规定kubelet要每隔5秒执行一次liveness probe。 `initialDelaySeconds` 告诉kubelet在第一次执行probe之前要的等待5秒钟。探针检测命令是在容器中执行 `cat /tmp/healthy` 命令。如果命令执行成功,将返回0,kubelet就会认为该容器是活着的并且很健康。如果返回非0值,kubelet就会杀掉这个容器并重启它。
|
该配置文件给 Pod 配置了一个容器。`periodSeconds` 规定 kubelet 要每隔 5 秒执行一次 liveness probe。 `initialDelaySeconds` 告诉 kubelet 在第一次执行 probe 之前要的等待 5 秒钟。探针检测命令是在容器中执行 `cat /tmp/healthy` 命令。如果命令执行成功,将返回 0,kubelet 就会认为该容器是活着的并且很健康。如果返回非 0 值,kubelet 就会杀掉这个容器并重启它。
|
||||||
|
|
||||||
容器启动时,执行该命令:
|
容器启动时,执行该命令:
|
||||||
|
|
||||||
|
@ -46,21 +46,21 @@ spec:
|
||||||
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
|
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
|
||||||
```
|
```
|
||||||
|
|
||||||
在容器生命的最初30秒内有一个 `/tmp/healthy` 文件,在这30秒内 `cat /tmp/healthy`命令会返回一个成功的返回码。30秒后, `cat /tmp/healthy` 将返回失败的返回码。
|
在容器生命的最初 30 秒内有一个 `/tmp/healthy` 文件,在这 30 秒内 `cat /tmp/healthy` 命令会返回一个成功的返回码。30 秒后, `cat /tmp/healthy` 将返回失败的返回码。
|
||||||
|
|
||||||
创建Pod:
|
创建 Pod:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/exec-liveness.yaml
|
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/exec-liveness.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
在30秒内,查看Pod的event:
|
在 30 秒内,查看 Pod 的 event:
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl describe pod liveness-exec
|
kubectl describe pod liveness-exec
|
||||||
```
|
```
|
||||||
|
|
||||||
结果显示没有失败的liveness probe:
|
结果显示没有失败的 liveness probe:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||||
|
@ -72,13 +72,13 @@ FirstSeen LastSeen Count From SubobjectPath Type
|
||||||
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
|
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
|
||||||
```
|
```
|
||||||
|
|
||||||
启动35秒后,再次查看pod的event:
|
启动 35 秒后,再次查看 pod 的 event:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl describe pod liveness-exec
|
kubectl describe pod liveness-exec
|
||||||
```
|
```
|
||||||
|
|
||||||
在最下面有一条信息显示liveness probe失败,容器被删掉并重新创建。
|
在最下面有一条信息显示 liveness probe 失败,容器被删掉并重新创建。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||||
|
@ -91,22 +91,22 @@ FirstSeen LastSeen Count From SubobjectPath Type
|
||||||
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
|
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
|
||||||
```
|
```
|
||||||
|
|
||||||
再等30秒,确认容器已经重启:
|
再等 30 秒,确认容器已经重启:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl get pod liveness-exec
|
kubectl get pod liveness-exec
|
||||||
```
|
```
|
||||||
|
|
||||||
从输出结果来`RESTARTS`值加1了。
|
从输出结果来 `RESTARTS` 值加 1 了。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
NAME READY STATUS RESTARTS AGE
|
NAME READY STATUS RESTARTS AGE
|
||||||
liveness-exec 1/1 Running 1 1m
|
liveness-exec 1/1 Running 1 1m
|
||||||
```
|
```
|
||||||
|
|
||||||
## 定义一个liveness HTTP请求
|
## 定义一个 liveness HTTP 请求
|
||||||
|
|
||||||
我们还可以使用HTTP GET请求作为liveness probe。下面是一个基于`gcr.io/google_containers/liveness`镜像运行了一个容器的Pod的例子`http-liveness.yaml`:
|
我们还可以使用 HTTP GET 请求作为 liveness probe。下面是一个基于 `gcr.io/google_containers/liveness` 镜像运行了一个容器的 Pod 的例子 `http-liveness.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -132,11 +132,11 @@ spec:
|
||||||
periodSeconds: 3
|
periodSeconds: 3
|
||||||
```
|
```
|
||||||
|
|
||||||
该配置文件只定义了一个容器,`livenessProbe` 指定kubelet需要每隔3秒执行一次liveness probe。`initialDelaySeconds` 指定kubelet在该执行第一次探测之前需要等待3秒钟。该探针将向容器中的server的8080端口发送一个HTTP GET请求。如果server的`/healthz`路径的handler返回一个成功的返回码,kubelet就会认定该容器是活着的并且很健康。如果返回失败的返回码,kubelet将杀掉该容器并重启它。
|
该配置文件只定义了一个容器,`livenessProbe` 指定 kubelet 需要每隔 3 秒执行一次 liveness probe。`initialDelaySeconds` 指定 kubelet 在该执行第一次探测之前需要等待 3 秒钟。该探针将向容器中的 server 的 8080 端口发送一个 HTTP GET 请求。如果 server 的 `/healthz` 路径的 handler 返回一个成功的返回码,kubelet 就会认定该容器是活着的并且很健康。如果返回失败的返回码,kubelet 将杀掉该容器并重启它。
|
||||||
|
|
||||||
任何大于200小于400的返回码都会认定是成功的返回码。其他返回码都会被认为是失败的返回码。
|
任何大于 200 小于 400 的返回码都会认定是成功的返回码。其他返回码都会被认为是失败的返回码。
|
||||||
|
|
||||||
最开始的10秒该容器是活着的, `/healthz` handler返回200的状态码。这之后将返回500的返回码。
|
最开始的 10 秒该容器是活着的, `/healthz` handler 返回 200 的状态码。这之后将返回 500 的返回码。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -151,26 +151,25 @@ http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
容器启动3秒后,kubelet开始执行健康检查。第一次健康监测会成功,但是10秒后,健康检查将失败,kubelet将杀掉和重启容器。
|
容器启动 3 秒后,kubelet 开始执行健康检查。第一次健康监测会成功,但是 10 秒后,健康检查将失败,kubelet 将杀掉和重启容器。
|
||||||
|
|
||||||
创建一个Pod来测试一下HTTP liveness检测:
|
创建一个 Pod 来测试一下 HTTP liveness 检测:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/http-liveness.yaml
|
kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/http-liveness.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
After 10 seconds, view Pod events to verify that liveness probes have failed and
|
After 10 seconds, view Pod events to verify that liveness probes have failed and the Container has been restarted:
|
||||||
the Container has been restarted:
|
|
||||||
|
|
||||||
10秒后,查看Pod的event,确认liveness probe失败并重启了容器。
|
10 秒后,查看 Pod 的 event,确认 liveness probe 失败并重启了容器。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl describe pod liveness-http
|
kubectl describe pod liveness-http
|
||||||
```
|
```
|
||||||
|
|
||||||
## 定义TCP liveness探针
|
## 定义 TCP liveness 探针
|
||||||
|
|
||||||
第三种liveness probe使用TCP Socket。 使用此配置,kubelet将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。
|
第三种 liveness probe 使用 TCP Socket。 使用此配置,kubelet 将尝试在指定端口上打开容器的套接字。 如果可以建立连接,容器被认为是健康的,如果不能就认为是失败的。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -197,13 +196,13 @@ spec:
|
||||||
periodSeconds: 20
|
periodSeconds: 20
|
||||||
```
|
```
|
||||||
|
|
||||||
如您所见,TCP检查的配置与HTTP检查非常相似。 此示例同时使用了readiness和liveness probe。 容器启动后5秒钟,kubelet将发送第一个readiness probe。 这将尝试连接到端口8080上的goproxy容器。如果探测成功,则该pod将被标记为就绪。Kubelet将每隔10秒钟执行一次该检查。
|
如您所见,TCP 检查的配置与 HTTP 检查非常相似。 此示例同时使用了 readiness 和 liveness probe。 容器启动后 5 秒钟,kubelet 将发送第一个 readiness probe。 这将尝试连接到端口 8080 上的 goproxy 容器。如果探测成功,则该 pod 将被标记为就绪。Kubelet 将每隔 10 秒钟执行一次该检查。
|
||||||
|
|
||||||
除了readiness probe之外,该配置还包括liveness probe。 容器启动15秒后,kubelet将运行第一个liveness probe。 就像readiness probe一样,这将尝试连接到goproxy容器上的8080端口。如果liveness probe失败,容器将重新启动。
|
除了 readiness probe 之外,该配置还包括 liveness probe。 容器启动 15 秒后,kubelet 将运行第一个 liveness probe。 就像 readiness probe 一样,这将尝试连接到 goproxy 容器上的 8080 端口。如果 liveness probe 失败,容器将重新启动。
|
||||||
|
|
||||||
## 使用命名的端口
|
## 使用命名的端口
|
||||||
|
|
||||||
可以使用命名的ContainerPort作为HTTP或TCP liveness检查:
|
可以使用命名的 ContainerPort 作为 HTTP 或 TCP liveness 检查:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
ports:
|
ports:
|
||||||
|
@ -217,11 +216,11 @@ livenessProbe:
|
||||||
port: liveness-port
|
port: liveness-port
|
||||||
```
|
```
|
||||||
|
|
||||||
## 定义readiness探针
|
## 定义 readiness 探针
|
||||||
|
|
||||||
有时,应用程序暂时无法对外部流量提供服务。 例如,应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下,你不想杀死应用程序,但你也不想发送请求。 Kubernetes提供了readiness probe来检测和减轻这些情况。 Pod中的容器可以报告自己还没有准备,不能处理Kubernetes服务发送过来的流量。
|
有时,应用程序暂时无法对外部流量提供服务。 例如,应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下,你不想杀死应用程序,但你也不想发送请求。 Kubernetes 提供了 readiness probe 来检测和减轻这些情况。 Pod 中的容器可以报告自己还没有准备,不能处理 Kubernetes 服务发送过来的流量。
|
||||||
|
|
||||||
Readiness probe的配置跟liveness probe很像。唯一的不同是使用 `readinessProbe `而不是`livenessProbe`。
|
Readiness probe 的配置跟 liveness probe 很像。唯一的不同是使用 `readinessProbe` 而不是 `livenessProbe`。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
|
@ -233,29 +232,29 @@ readinessProbe:
|
||||||
periodSeconds: 5
|
periodSeconds: 5
|
||||||
```
|
```
|
||||||
|
|
||||||
Readiness probe的HTTP和TCP的探测器配置跟liveness probe一样。
|
Readiness probe 的 HTTP 和 TCP 的探测器配置跟 liveness probe 一样。
|
||||||
|
|
||||||
Readiness和livenss probe可以并行用于同一容器。 使用两者可以确保流量无法到达未准备好的容器,并且容器在失败时重新启动。
|
Readiness 和 livenss probe 可以并行用于同一容器。 使用两者可以确保流量无法到达未准备好的容器,并且容器在失败时重新启动。
|
||||||
|
|
||||||
## 配置Probe
|
## 配置 Probe
|
||||||
|
|
||||||
Probe 中有很多精确和详细的配置,通过它们你能准确的控制liveness和readiness检查:
|
Probe 中有很多精确和详细的配置,通过它们你能准确的控制 liveness 和 readiness 检查:
|
||||||
|
|
||||||
- `initialDelaySeconds`:容器启动后第一次执行探测是需要等待多少秒。
|
- `initialDelaySeconds`:容器启动后第一次执行探测是需要等待多少秒。
|
||||||
- `periodSeconds`:执行探测的频率。默认是10秒,最小1秒。
|
- `periodSeconds`:执行探测的频率。默认是 10 秒,最小 1 秒。
|
||||||
- `timeoutSeconds`:探测超时时间。默认1秒,最小1秒。
|
- `timeoutSeconds`:探测超时时间。默认 1 秒,最小 1 秒。
|
||||||
- `successThreshold`:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。
|
- `successThreshold`:探测失败后,最少连续探测成功多少次才被认定为成功。默认是 1。对于 liveness 必须是 1。最小值是 1。
|
||||||
- `failureThreshold`:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
|
- `failureThreshold`:探测成功后,最少连续探测失败多少次才被认定为失败。默认是 3。最小值是 1。
|
||||||
|
|
||||||
HTTP probe 中可以给 `httpGet`设置其他配置项:
|
HTTP probe 中可以给 `httpGet` 设置其他配置项:
|
||||||
|
|
||||||
- `host`:连接的主机名,默认连接到pod的IP。你可能想在http header中设置"Host"而不是使用IP。
|
- `host`:连接的主机名,默认连接到 pod 的 IP。你可能想在 http header 中设置 "Host" 而不是使用 IP。
|
||||||
- `scheme`:连接使用的schema,默认HTTP。
|
- `scheme`:连接使用的 schema,默认 HTTP。
|
||||||
- `path`: 访问的HTTP server的path。
|
- `path`: 访问的 HTTP server 的 path。
|
||||||
- `httpHeaders`:自定义请求的header。HTTP运行重复的header。
|
- `httpHeaders`:自定义请求的 header。HTTP 运行重复的 header。
|
||||||
- `port`:访问的容器的端口名字或者端口号。端口号必须介于1和65535之间。
|
- `port`:访问的容器的端口名字或者端口号。端口号必须介于 1 和 65535 之间。
|
||||||
|
|
||||||
对于HTTP探测器,kubelet向指定的路径和端口发送HTTP请求以执行检查。 Kubelet将probe发送到容器的IP地址,除非地址被`httpGet`中的可选`host`字段覆盖。 在大多数情况下,你不想设置主机字段。 有一种情况下你可以设置它。 假设容器在127.0.0.1上侦听,并且Pod的`hostNetwork`字段为true。 然后,在`httpGet`下的`host`应该设置为127.0.0.1。 如果你的pod依赖于虚拟主机,这可能是更常见的情况,你不应该是用`host`,而是应该在`httpHeaders`中设置`Host`头。
|
对于 HTTP 探测器,kubelet 向指定的路径和端口发送 HTTP 请求以执行检查。 Kubelet 将 probe 发送到容器的 IP 地址,除非地址被 `httpGet` 中的可选 `host` 字段覆盖。 在大多数情况下,你不想设置主机字段。 有一种情况下你可以设置它。 假设容器在 127.0.0.1 上侦听,并且 Pod 的 `hostNetwork` 字段为 true。 然后,在 `httpGet` 下的 `host` 应该设置为 127.0.0.1。 如果你的 pod 依赖于虚拟主机,这可能是更常见的情况,你不应该是用 `host`,而是应该在 `httpHeaders` 中设置 `Host` 头。
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,7 @@
|
||||||
|
|
||||||
```
|
```
|
||||||
6379
|
6379
|
||||||
|
```
|
||||||
```
|
|
||||||
|
|
||||||
## 将本地端口转发到 Pod 中的端口
|
## 将本地端口转发到 Pod 中的端口
|
||||||
|
|
||||||
|
@ -58,9 +57,8 @@
|
||||||
```
|
```
|
||||||
I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:6379 -> 6379
|
I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:6379 -> 6379
|
||||||
I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:6379 -> 6379
|
I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:6379 -> 6379
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 启动 Redis 命令行界面
|
2. 启动 Redis 命令行界面
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
# 适用于kubernetes的应用开发部署流程
|
# 适用于 Kubernetes 的应用开发部署流程
|
||||||
|
|
||||||
本文讲解了如何开发容器化应用,并使用Wercker持续集成工具构建docker镜像上传到docker镜像仓库中,然后在本地使用*docker-compose*测试后,再使用`kompose`自动生成kubernetes的yaml文件,再将注入Envoy sidecar容器,集成Istio service mesh中的详细过程。
|
本文讲解了如何开发容器化应用,并使用 Wercker 持续集成工具构建 docker 镜像上传到 docker 镜像仓库中,然后在本地使用 *docker-compose* 测试后,再使用 `kompose` 自动生成 kubernetes 的 yaml 文件,再将注入 Envoy sidecar 容器,集成 Istio service mesh 中的详细过程。
|
||||||
|
|
||||||
整个过程如下图所示。
|
整个过程如下图所示。
|
||||||
|
|
||||||
![流程图](../images/how-to-use-kubernetes-with-istio.jpg)
|
![流程图](../images/how-to-use-kubernetes-with-istio.jpg)
|
||||||
|
|
||||||
为了讲解详细流程,我特意写了用Go语言开发的示例程序放在GitHub中,模拟监控流程:
|
为了讲解详细流程,我特意写了用 Go 语言开发的示例程序放在 GitHub 中,模拟监控流程:
|
||||||
|
|
||||||
- [k8s-app-monitor-test](https://github.com/rootsongjc/k8s-app-monitor-test):生成模拟的监控数据,在接收到http请求返回json格式的metrics信息
|
- [k8s-app-monitor-test](https://github.com/rootsongjc/k8s-app-monitor-test):生成模拟的监控数据,在接收到 http 请求返回 json 格式的 metrics 信息
|
||||||
- [K8s-app-monitor-agent](https://github.com/rootsongjc/k8s-app-monitor-agent):获取监控metrics信息并绘图,访问该服务将获得监控图表
|
- [K8s-app-monitor-agent](https://github.com/rootsongjc/k8s-app-monitor-agent):获取监控 metrics 信息并绘图,访问该服务将获得监控图表
|
||||||
|
|
||||||
API文档见[k8s-app-monitor-test](https://github.com/rootsongjc/k8s-app-monitor-test)中的`api.html`文件,该文档在API blueprint中定义,使用[aglio](https://github.com/danielgtaylor/aglio)生成,打开后如图所示:
|
API 文档见 [k8s-app-monitor-test](https://github.com/rootsongjc/k8s-app-monitor-test) 中的 `api.html` 文件,该文档在 API blueprint 中定义,使用 [aglio](https://github.com/danielgtaylor/aglio) 生成,打开后如图所示:
|
||||||
|
|
||||||
![API](../images/k8s-app-monitor-test-api-doc.jpg)
|
![API](../images/k8s-app-monitor-test-api-doc.jpg)
|
||||||
|
|
||||||
## 关于服务发现
|
## 关于服务发现
|
||||||
|
|
||||||
`K8s-app-monitor-agent`服务需要访问`k8s-app-monitor-test`服务,这就涉及到服务发现的问题,我们在代码中直接写死了要访问的服务的内网DNS地址(kubedns中的地址,即`k8s-app-monitor-test.default.svc.cluster.local`)。
|
`K8s-app-monitor-agent` 服务需要访问 `k8s-app-monitor-test` 服务,这就涉及到服务发现的问题,我们在代码中直接写死了要访问的服务的内网 DNS 地址(kubedns 中的地址,即 `k8s-app-monitor-test.default.svc.cluster.local`)。
|
||||||
|
|
||||||
我们知道Kubernetes在启动Pod的时候为容器注入环境变量,这些环境变量在所有的 namespace 中共享(环境变量是不断追加的,新启动的Pod中将拥有老的Pod中所有的环境变量,而老的Pod中的环境变量不变)。但是既然使用这些环境变量就已经可以访问到对应的service,那么获取应用的地址信息,究竟是使用变量呢?还是直接使用DNS解析来发现?
|
我们知道 Kubernetes 在启动 Pod 的时候为容器注入环境变量,这些环境变量在所有的 namespace 中共享(环境变量是不断追加的,新启动的 Pod 中将拥有老的 Pod 中所有的环境变量,而老的 Pod 中的环境变量不变)。但是既然使用这些环境变量就已经可以访问到对应的 service,那么获取应用的地址信息,究竟是使用变量呢?还是直接使用 DNS 解析来发现?
|
||||||
|
|
||||||
答案是使用DNS,详细说明见[Kubernetes中的服务发现与Docker容器间的环境变量传递源码探究](https://jimmysong.io/posts/exploring-kubernetes-env-with-docker/)。
|
答案是使用 DNS,详细说明见[Kubernetes中的服务发现与Docker容器间的环境变量传递源码探究](https://jimmysong.io/blog/exploring-kubernetes-env-with-docker/)。
|
||||||
|
|
||||||
## 持续集成
|
## 持续集成
|
||||||
|
|
||||||
因为我使用wercker自动构建,构建完成后自动打包成docker镜像并上传到docker hub中(需要现在docker hub中创建repo)。
|
因为我使用 wercker 自动构建,构建完成后自动打包成 docker 镜像并上传到 docker hub 中(需要现在 docker hub 中创建 repo)。
|
||||||
|
|
||||||
构建流程见:https://app.wercker.com/jimmysong/k8s-app-monitor-agent/
|
构建流程见:https://app.wercker.com/jimmysong/k8s-app-monitor-agent/
|
||||||
|
|
||||||
![wercker构建页面](../images/k8s-app-monitor-agent-wercker.jpg)
|
![wercker构建页面](../images/k8s-app-monitor-agent-wercker.jpg)
|
||||||
|
|
||||||
生成了如下两个docker镜像:
|
生成了如下两个 docker 镜像:
|
||||||
|
|
||||||
- jimmysong/k8s-app-monitor-test:9c935dd
|
- jimmysong/k8s-app-monitor-test:9c935dd
|
||||||
- jimmysong/k8s-app-monitor-agent:234d51c
|
- jimmysong/k8s-app-monitor-agent:234d51c
|
||||||
|
|
||||||
## 测试
|
## 测试
|
||||||
|
|
||||||
在将服务发布到线上之前,我们可以先使用*docker-compose*在本地测试一下,这两个应用的`docker-compose.yaml`文件如下:
|
在将服务发布到线上之前,我们可以先使用 *docker-compose* 在本地测试一下,这两个应用的 `docker-compose.yaml` 文件如下:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: '2'
|
version: '2'
|
||||||
|
@ -65,19 +65,19 @@ services:
|
||||||
docker-compose up
|
docker-compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
在浏览器中访问<http://localhost:8888/k8s-app-monitor-test>就可以看到监控页面。
|
在浏览器中访问 http://localhost:8888/k8s-app-monitor-test 就可以看到监控页面。
|
||||||
|
|
||||||
## 发布
|
## 发布
|
||||||
|
|
||||||
所有的kubernetes应用启动所用的yaml配置文件都保存在那两个GitHub仓库的`manifest.yaml`文件中。也可以使用[kompose](https://github.com/kubernetes/kompose)这个工具,可以将*docker-compose*的YAML文件转换成kubernetes规格的YAML文件。
|
所有的 kubernetes 应用启动所用的 yaml 配置文件都保存在那两个 GitHub 仓库的 `manifest.yaml` 文件中。也可以使用 [kompose](https://github.com/kubernetes/kompose) 这个工具,可以将 *docker-compose* 的 YAML 文件转换成 kubernetes 规格的 YAML 文件。
|
||||||
|
|
||||||
分别在两个GitHub目录下执行`kubectl create -f manifest.yaml`即可启动服务。也可以直接在*k8s-app-monitor-agent*代码库的`k8s`目录下执行`kubectl apply -f kompose `。
|
分别在两个 GitHub 目录下执行 `kubectl create -f manifest.yaml` 即可启动服务。也可以直接在 *k8s-app-monitor-agent* 代码库的 `k8s` 目录下执行 `kubectl apply -f kompose`。
|
||||||
|
|
||||||
在以上YAML文件中有包含了Ingress配置,是为了将*k8s-app-monitor-agent*服务暴露给集群外部访问。
|
在以上 YAML 文件中有包含了 Ingress 配置,是为了将 *k8s-app-monitor-agent* 服务暴露给集群外部访问。
|
||||||
|
|
||||||
**方式一**
|
**方式一**
|
||||||
|
|
||||||
服务启动后需要更新ingress配置,在[ingress.yaml](../manifests/traefik-ingress/ingress.yaml)文件中增加以下几行:
|
服务启动后需要更新 ingress 配置,在 [ingress.yaml](https://jimmysong.io/kubernetes-handbook/manifests/traefik-ingress/ingress.yaml) 文件中增加以下几行:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- host: k8s-app-monitor-agent.jimmysong.io
|
- host: k8s-app-monitor-agent.jimmysong.io
|
||||||
|
@ -89,19 +89,19 @@ docker-compose up
|
||||||
servicePort: 8888
|
servicePort: 8888
|
||||||
```
|
```
|
||||||
|
|
||||||
保存后,然后执行`kubectl replace -f ingress.yaml`即可刷新ingress。
|
保存后,然后执行 `kubectl replace -f ingress.yaml` 即可刷新 ingress。
|
||||||
|
|
||||||
修改本机的`/etc/hosts`文件,在其中加入以下一行:
|
修改本机的 `/etc/hosts` 文件,在其中加入以下一行:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
172.20.0.119 k8s-app-monitor-agent.jimmysong.io
|
172.20.0.119 k8s-app-monitor-agent.jimmysong.io
|
||||||
```
|
```
|
||||||
|
|
||||||
当然你也可以将该域名加入到内网的DNS中,为了简单起见我使用hosts。
|
当然你也可以将该域名加入到内网的 DNS 中,为了简单起见我使用 hosts。
|
||||||
|
|
||||||
**方式二**
|
**方式二**
|
||||||
|
|
||||||
或者不修改已有的Ingress,而是为该队外暴露的服务单独创建一个Ingress,如下:
|
或者不修改已有的 Ingress,而是为该队外暴露的服务单独创建一个 Ingress,如下:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
|
@ -123,34 +123,34 @@ spec:
|
||||||
|
|
||||||
详见[边缘节点配置](../practice/edge-node-configuration.md)。
|
详见[边缘节点配置](../practice/edge-node-configuration.md)。
|
||||||
|
|
||||||
## 集成Istio service mesh
|
## 集成 Istio service mesh
|
||||||
|
|
||||||
上一步中我们生成了kubernetes可读取的应用的YAML配置文件,我们可以将所有的YAML配置和并到同一个YAML文件中假如文件名为`k8s-app-monitor-istio-all-in-one.yaml`,如果要将其集成到Istio service mesh,只需要执行下面的命令。
|
上一步中我们生成了 Kubernetes 可读取的应用的 YAML 配置文件,我们可以将所有的 YAML 配置和并到同一个 YAML 文件中假如文件名为 `k8s-app-monitor-istio-all-in-one.yaml`,如果要将其集成到 Istio service mesh,只需要执行下面的命令。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl apply -n default -f <(istioctl kube-inject -f k8s-app-monitor-istio-all-in-one.yaml)
|
kubectl apply -n default -f <(istioctl kube-inject -f k8s-app-monitor-istio-all-in-one.yaml)
|
||||||
```
|
```
|
||||||
|
|
||||||
这样就会在每个Pod中注入一个sidecar容器。
|
这样就会在每个 Pod 中注入一个 sidecar 容器。
|
||||||
|
|
||||||
## 验证
|
## 验证
|
||||||
|
|
||||||
如果您使用的是Traefik ingress来暴露的服务,那么在浏览器中访问<http://k8s-app-monitor-agent.jimmysong.io/k8s-app-monitor-agent>,可以看到如下的画面,每次刷新页面将看到新的柱状图。
|
如果您使用的是 Traefik ingress 来暴露的服务,那么在浏览器中访问 http://k8s-app-monitor-agent.jimmysong.io/k8s-app-monitor-agent,可以看到如下的画面,每次刷新页面将看到新的柱状图。
|
||||||
|
|
||||||
![图表](../images/k8s-app-monitor-agent.jpg)
|
![图表](../images/k8s-app-monitor-agent.jpg)
|
||||||
|
|
||||||
使用[kubernetes-vagrant-centos-cluster](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster)来部署的kubernetes集群,该应用集成了Istio service mesh后可以通过<http://172.17.8.101:32000/k8s-app-monitor-agent>来访问。
|
使用 [kubernetes-vagrant-centos-cluster](https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster) 来部署的 kubernetes 集群,该应用集成了 Istio service mesh 后可以通过 http://172.17.8.101:32000/k8s-app-monitor-agent 来访问。
|
||||||
|
|
||||||
在对*k8s-app-monitor-agent*服务进行了N此访问之后,再访问<http://grafana.istio.jimmysong.io>可以看到Service Mesh的监控信息。
|
在对 *k8s-app-monitor-agent* 服务进行了 N 此访问之后,再访问 [http://grafana.istio.jimmysong.io](http://grafana.istio.jimmysong.io/) 可以看到 Service Mesh 的监控信息。
|
||||||
|
|
||||||
![Grafana页面](../images/k8s-app-monitor-istio-grafana.png)
|
![Grafana页面](../images/k8s-app-monitor-istio-grafana.png)
|
||||||
|
|
||||||
访问<http://servicegraph.istio.jimmysong.io/dotviz>可以看到服务的依赖和QPS信息。
|
访问 <http://servicegraph.istio.jimmysong.io/dotviz> 可以看到服务的依赖和 QPS 信息。
|
||||||
|
|
||||||
![servicegraph页面](../images/k8s-app-monitor-istio-servicegraph-dotviz.png)
|
![servicegraph 页面](../images/k8s-app-monitor-istio-servicegraph-dotviz.png)
|
||||||
|
|
||||||
访问<http://zipkin.istio.jimmysong.io>可以选择查看`k8s-app-monitor-agent`应用的追踪信息。
|
访问 <http://zipkin.istio.jimmysong.io> 可以选择查看 `k8s-app-monitor-agent` 应用的追踪信息。
|
||||||
|
|
||||||
![Zipkin页面](../images/k8s-app-monitor-istio-zipkin.png)
|
![Zipkin页面](../images/k8s-app-monitor-istio-zipkin.png)
|
||||||
|
|
||||||
至此从代码提交到上线到Kubernetes集群上并集成Istio service mesh的过程就全部完成了。
|
至此从代码提交到上线到 Kubernetes 集群上并集成 Istio service mesh 的过程就全部完成了。
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# docker用户过渡到kubectl命令行指南
|
# Docker 用户过渡到 kubectl 命令行指南
|
||||||
|
|
||||||
对于没有使用过 kubernetes 的 docker 用户,如何快速掌握 kubectl 命令?
|
对于没有使用过 Kubernetes 的 Docker 用户,如何快速掌握 kubectl 命令?
|
||||||
|
|
||||||
在本文中,我们将向 docker-cli 用户介绍 Kubernetes 命令行如何与 api 进行交互。该命令行工具——kubectl,被设计成 docker-cli 用户所熟悉的样子,但是它们之间又存在一些必要的差异。该文档将向您展示每个 docker 子命令和 kubectl 与其等效的命令。
|
在本文中,我们将向 docker-cli 用户介绍 Kubernetes 命令行如何与 api 进行交互。该命令行工具——kubectl,被设计成 docker-cli 用户所熟悉的样子,但是它们之间又存在一些必要的差异。该文档将向您展示每个 docker 子命令和 kubectl 与其等效的命令。
|
||||||
|
|
||||||
|
@ -266,4 +266,3 @@ Grafana is running at https://108.59.85.141/api/v1/namespaces/kube-system/servic
|
||||||
Heapster is running at https://108.59.85.141/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
|
Heapster is running at https://108.59.85.141/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
|
||||||
InfluxDB is running at https://108.59.85.141/api/v1/namespaces/kube-system/services/monitoring-influxdb/proxy
|
InfluxDB is running at https://108.59.85.141/api/v1/namespaces/kube-system/services/monitoring-influxdb/proxy
|
||||||
```
|
```
|
||||||
原文地址:https://github.com/rootsongjc/kubernetes.github.io/blob/master/docs/user-guide/docker-cli-to-kubectl.md
|
|
||||||
|
|
|
@ -7,8 +7,3 @@
|
||||||
- 集群安全性管理
|
- 集群安全性管理
|
||||||
- 如何访问 Kubernetes 集群
|
- 如何访问 Kubernetes 集群
|
||||||
- 如何在 Kubernetes 中开发部署应用
|
- 如何在 Kubernetes 中开发部署应用
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ MASQUERADE all -- anywhere anywhere /* ip-masq-agent:
|
||||||
|
|
||||||
默认情况下,在 GCE/GKE 中将启动 kubernetes 1.7.0 版本,ip-masq-agent 已经在集群中运行。如果您在其他环境中运行 kubernetes,那么您可以将 ip-masq-agent 以 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 的方式在集群中运行。
|
默认情况下,在 GCE/GKE 中将启动 kubernetes 1.7.0 版本,ip-masq-agent 已经在集群中运行。如果您在其他环境中运行 kubernetes,那么您可以将 ip-masq-agent 以 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 的方式在集群中运行。
|
||||||
|
|
||||||
原文地址:https://k8smeetup.github.io/docs/tasks/administer-cluster/ip-masq-agent/
|
## 参考
|
||||||
|
|
||||||
|
- [IP Masquerade Agent User Guide - kubernetes.io](https://kubernetes.io/docs/tasks/administer-cluster/ip-masq-agent/)
|
||||||
|
|
||||||
译者:[rootsongjc](https://github.com/rootsongjc)
|
|
||||||
|
|
|
@ -291,9 +291,8 @@ $ kubectl taint nodes foo dedicated=special-user:NoSchedule
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Kubectl 概览](https://kubernetes.io/docs/user-guide/kubectl-overview)
|
- [Kubectl 概览 - kubernetes.io](https://kubernetes.io/docs/user-guide/kubectl-overview)
|
||||||
|
|
||||||
|
|
||||||
- [JsonPath 手册](https://kubernetes.io/docs/user-guide/jsonpath)
|
- [JsonPath 手册 - kubernetes.io](https://kubernetes.io/docs/user-guide/jsonpath)
|
||||||
|
- [Cheatsheet - kubernetes.io](https://kubernetes.io/docs/user-guide/kubectl-cheatsheet/)
|
||||||
本文是对官方文档的中文翻译,原文地址:<https://kubernetes.io/docs/user-guide/kubectl-cheatsheet/>
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# 创建用户认证授权的kubeconfig文件
|
# 创建用户认证授权的 kubeconfig 文件
|
||||||
|
|
||||||
当我们安装好集群后,如果想要把 kubectl 命令交给用户使用,就不得不对用户的身份进行认证和对其权限做出限制。
|
当我们安装好集群后,如果想要把 kubectl 命令交给用户使用,就不得不对用户的身份进行认证和对其权限做出限制。
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
## 创建 CA 证书和秘钥
|
## 创建 CA 证书和秘钥
|
||||||
|
|
||||||
**创建 `devuser-csr.json ` 文件**
|
**创建 `devuser-csr.json` 文件**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -134,6 +134,6 @@ No resources found.
|
||||||
|
|
||||||
现在 kubectl 命令默认使用的 context 就是 devuser 了,且该用户只能操作 dev 和 test 这两个 namespace,并拥有完全的访问权限。
|
现在 kubectl 命令默认使用的 context 就是 devuser 了,且该用户只能操作 dev 和 test 这两个 namespace,并拥有完全的访问权限。
|
||||||
|
|
||||||
可以使用我写的[create-user.sh脚本](https://github.com/rootsongjc/kubernetes-handbook/blob/master/tools/create-user/create-user.sh)来创建namespace和用户并授权,参考[说明](../tools/create-user/README.md)。
|
可以使用我写的 [create-user.sh 脚本](https://github.com/rootsongjc/kubernetes-handbook/blob/master/tools/create-user/create-user.sh)来创建 namespace 和用户并授权,参考[说明](../tools/create-user/README.md)。
|
||||||
|
|
||||||
关于角色绑定的更多信息请参考 [RBAC——基于角色的访问控制](rbac.md)。
|
关于角色绑定的更多信息请参考 [RBAC——基于角色的访问控制](rbac.md)。
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# Kublet的认证授权
|
# Kublet 的认证授权
|
||||||
|
|
||||||
## 概览
|
|
||||||
|
|
||||||
Kubelet 的 HTTPS 端点对外暴露了用于访问不同敏感程度数据的 API,并允许您在节点或者容器内执行不同权限级别的操作。
|
Kubelet 的 HTTPS 端点对外暴露了用于访问不同敏感程度数据的 API,并允许您在节点或者容器内执行不同权限级别的操作。
|
||||||
|
|
||||||
|
@ -46,17 +44,17 @@ kubelet 使用与 apiserver 相同的 [请求属性](https://kubernetes.io/docs/
|
||||||
|
|
||||||
Verb(动词)是根据传入的请求的 HTTP 动词确定的:
|
Verb(动词)是根据传入的请求的 HTTP 动词确定的:
|
||||||
|
|
||||||
| HTTP 动词 | request 动词 |
|
| HTTP 动词 | request 动词 |
|
||||||
| --------- | ---------- |
|
| --------- | ------------ |
|
||||||
| POST | create |
|
| POST | create |
|
||||||
| GET, HEAD | get |
|
| GET, HEAD | get |
|
||||||
| PUT | update |
|
| PUT | update |
|
||||||
| PATCH | patch |
|
| PATCH | patch |
|
||||||
| DELETE | delete |
|
| DELETE | delete |
|
||||||
|
|
||||||
资源和子资源根据传入请求的路径确定:
|
资源和子资源根据传入请求的路径确定:
|
||||||
|
|
||||||
| Kubelet API | 资源 | 子资源 |
|
| Kubelet API | 资源 | 子资源 |
|
||||||
| ------------ | ----- | ------- |
|
| ------------ | ----- | ------- |
|
||||||
| /stats/* | nodes | stats |
|
| /stats/* | nodes | stats |
|
||||||
| /metrics/* | nodes | metrics |
|
| /metrics/* | nodes | metrics |
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Lens - Kubernetes IDE/桌面客户端
|
# Lens - Kubernetes IDE
|
||||||
|
|
||||||
[Lens](https://k8slens.dev/) 是一款开源的 Kubenretes IDE,也可以作为桌面客户端,官方网站 <https://k8slens.dev>,具有以下特性:
|
[Lens](https://k8slens.dev/) 是一款开源的 Kubenretes IDE,也可以作为桌面客户端,官方网站 <https://k8slens.dev>,具有以下特性:
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
# 管理集群中的TLS
|
# 管理集群中的TLS
|
||||||
|
|
||||||
在本书的最佳实践部分,我们在CentOS上部署了kuberentes集群,其中最开始又重要的一步就是创建TLS认证的,查看[创建TLS证书和秘钥](../practice/create-tls-and-secret-key.md)。很多人在进行到这一步时都会遇到各种各样千奇百怪的问题,这一步是创建集群的基础,我们有必要详细了解一下其背后的流程和原理。
|
在本书的最佳实践部分,我们在 CentOS 上部署了 Kuberentes 集群,其中最开始又重要的一步就是创建 TLS 认证的,查看[创建TLS证书和秘钥](../practice/create-tls-and-secret-key.md)。很多人在进行到这一步时都会遇到各种各样千奇百怪的问题,这一步是创建集群的基础,我们有必要详细了解一下其背后的流程和原理。
|
||||||
|
|
||||||
## 概览
|
## 概览
|
||||||
|
|
||||||
每个Kubernetes集群都有一个集群根证书颁发机构(CA)。 集群中的组件通常使用CA来验证API server的证书,由API服务器验证kubelet客户端证书等。为了支持这一点,CA证书包被分发到集群中的每个节点,并作为一个secret附加分发到默认service account上。 或者,你的workload可以使用此CA建立信任。 你的应用程序可以使用类似于[ACME草案](https://github.com/ietf-wg-acme/acme/)的协议,使用`certificates.k8s.io` API请求证书签名。
|
每个 Kubernetes 集群都有一个集群根证书颁发机构(CA)。 集群中的组件通常使用 CA 来验证 API server 的证书,由 API 服务器验证 kubelet 客户端证书等。为了支持这一点,CA 证书包被分发到集群中的每个节点,并作为一个 secret 附加分发到默认 service account 上。 或者,你的 workload 可以使用此 CA 建立信任。 你的应用程序可以使用类似于 [ACME 草案](https://github.com/ietf-wg-acme/acme/)的协议,使用 `certificates.k8s.io` API 请求证书签名。
|
||||||
|
|
||||||
## 集群中的TLS信任
|
## 集群中的 TLS 信任
|
||||||
|
|
||||||
让Pod中运行的应用程序信任集群根CA通常需要一些额外的应用程序配置。 您将需要将CA证书包添加到TLS客户端或服务器信任的CA证书列表中。 例如,您可以使用golang TLS配置通过解析证书链并将解析的证书添加到[`tls.Config`](https://godoc.org/crypto/tls#Config)结构中的`Certificates`字段中,CA证书捆绑包将使用默认服务账户自动加载到pod中,路径为`/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`。 如果您没有使用默认服务账户,请请求集群管理员构建包含您有权访问使用的证书包的configmap。
|
让 Pod 中运行的应用程序信任集群根 CA 通常需要一些额外的应用程序配置。 您将需要将 CA 证书包添加到 TLS 客户端或服务器信任的 CA 证书列表中。 例如,您可以使用 golang TLS 配置通过解析证书链并将解析的证书添加到 [`tls.Config`](https://godoc.org/crypto/tls#Config)结构中的 `Certificates` 字段中,CA 证书捆绑包将使用默认服务账户自动加载到 pod 中,路径为 `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`。 如果您没有使用默认服务账户,请请求集群管理员构建包含您有权访问使用的证书包的 configmap。
|
||||||
|
|
||||||
## 请求认证
|
## 请求认证
|
||||||
|
|
||||||
以下部分演示如何为通过DNS访问的Kubernetes服务创建TLS证书。
|
以下部分演示如何为通过 DNS 访问的 Kubernetes 服务创建 TLS 证书。
|
||||||
|
|
||||||
### 步骤0. 下载安装SSL
|
### 下载安装SSL
|
||||||
|
|
||||||
下载cfssl工具:[https://pkg.cfssl.org/](https://pkg.cfssl.org/).
|
[下载 cfssl 工具](https://pkg.cfssl.org/)。
|
||||||
|
|
||||||
### 步骤1. 创建证书签名请求
|
### 创建证书签名请求
|
||||||
|
|
||||||
通过运行以下命令生成私钥和证书签名请求(或CSR):
|
通过运行以下命令生成私钥和证书签名请求(或 CSR):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cat <<EOF | cfssl genkey - | cfssljson -bare server
|
$ cat <<EOF | cfssl genkey - | cfssljson -bare server
|
||||||
|
@ -40,7 +40,7 @@ $ cat <<EOF | cfssl genkey - | cfssljson -bare server
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
`172.168.0.24` 是 service 的 cluster IP,`my-svc.my-namespace.svc.cluster.local` 是 service 的 DNS 名称, `10.0.34.2` 是 Pod 的 IP, `my-pod.my-namespace.pod.cluster.local` 是pod 的 DNS 名称,你可以看到以下输出:
|
`172.168.0.24` 是 service 的 cluster IP,`my-svc.my-namespace.svc.cluster.local` 是 service 的 DNS 名称, `10.0.34.2` 是 Pod 的 IP, `my-pod.my-namespace.pod.cluster.local` 是 pod 的 DNS 名称,你可以看到以下输出:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
2017/03/21 06:48:17 [INFO] generate received request
|
2017/03/21 06:48:17 [INFO] generate received request
|
||||||
|
@ -49,11 +49,11 @@ EOF
|
||||||
2017/03/21 06:48:17 [INFO] encoded CSR
|
2017/03/21 06:48:17 [INFO] encoded CSR
|
||||||
```
|
```
|
||||||
|
|
||||||
此命令生成两个文件; 它生成包含PEM编码的[pkcs #10](https://tools.ietf.org/html/rfc2986)认证请求的`server.csr`,以及包含仍然要创建的证书的PEM编码密钥的`server-key.pem`。
|
此命令生成两个文件;它生成包含 PEM 编码的 [pkcs #10](https://tools.ietf.org/html/rfc2986) 认证请求的 `server.csr`,以及包含仍然要创建的证书的 PEM 编码密钥的 `server-key.pem`。
|
||||||
|
|
||||||
### 步骤2. 创建证书签名请求对象以发送到Kubernetes API
|
### 创建证书签名请求对象以发送到 Kubernetes API
|
||||||
|
|
||||||
使用以下命令创建CSR yaml文件,并发送到API server:
|
使用以下命令创建 CSR yaml 文件,并发送到 API server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cat <<EOF | kubectl create -f -
|
$ cat <<EOF | kubectl create -f -
|
||||||
|
@ -72,9 +72,9 @@ spec:
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
请注意,在步骤1中创建的`server.csr`文件是base64编码并存储在`.spec.request`字段中。 我们还要求提供“数字签名”,“密钥加密”和“服务器身份验证”密钥用途的证书。
|
请注意,在步骤 1 中创建的 `server.csr` 文件是 base64 编码并存储在`.spec.request` 字段中。 我们还要求提供 “数字签名”,“密钥加密” 和 “服务器身份验证” 密钥用途的证书。
|
||||||
|
|
||||||
在API server中可以看到这些CSR处于pending状态。执行下面的命令你将可以看到:
|
在 API server 中可以看到这些 CSR 处于 pending 状态。执行下面的命令你将可以看到:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl describe csr my-svc.my-namespace
|
$ kubectl describe csr my-svc.my-namespace
|
||||||
|
@ -94,13 +94,13 @@ Subject Alternative Names:
|
||||||
Events: <none>
|
Events: <none>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 步骤3. 获取证书签名请求
|
### 获取证书签名请求
|
||||||
|
|
||||||
批准证书签名请求是通过自动批准过程完成的,或由集群管理员一次完成。 有关这方面涉及的更多信息,请参见下文。
|
批准证书签名请求是通过自动批准过程完成的,或由集群管理员一次完成。 有关这方面涉及的更多信息,请参见下文。
|
||||||
|
|
||||||
### 步骤4. 下载签名并使用
|
### 下载签名并使用
|
||||||
|
|
||||||
一旦CSR被签署并获得批准,您应该看到以下内容:
|
一旦 CSR 被签署并获得批准,您应该看到以下内容:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl get csr
|
$ kubectl get csr
|
||||||
|
@ -108,18 +108,18 @@ NAME AGE REQUESTOR CONDITION
|
||||||
my-svc.my-namespace 10m yourname@example.com Approved,Issued
|
my-svc.my-namespace 10m yourname@example.com Approved,Issued
|
||||||
```
|
```
|
||||||
|
|
||||||
你可以通过运行以下命令下载颁发的证书并将其保存到`server.crt`文件中:
|
你可以通过运行以下命令下载颁发的证书并将其保存到 `server.crt` 文件中:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
|
$ kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
|
||||||
| base64 -d > server.crt
|
| base64 -d > server.crt
|
||||||
```
|
```
|
||||||
|
|
||||||
现在你可以用`server.crt`和`server-key.pem`来做为keypair来启动HTTPS server。
|
现在你可以用 `server.crt` 和 `server-key.pem` 来做为 keypair 来启动 HTTPS server。
|
||||||
|
|
||||||
## 批准证书签名请求
|
## 批准证书签名请求
|
||||||
|
|
||||||
Kubernetes 管理员(具有适当权限)可以使用 `kubectl certificate approve` 和`kubectl certificate deny` 命令手动批准(或拒绝)证书签名请求。但是,如果您打算大量使用此 API,则可以考虑编写自动化的证书控制器。
|
Kubernetes 管理员(具有适当权限)可以使用 `kubectl certificate approve` 和 `kubectl certificate deny` 命令手动批准(或拒绝)证书签名请求。但是,如果您打算大量使用此 API,则可以考虑编写自动化的证书控制器。
|
||||||
|
|
||||||
如果上述机器或人类使用 kubectl,批准者的作用是验证 CSR 满足如下两个要求:
|
如果上述机器或人类使用 kubectl,批准者的作用是验证 CSR 满足如下两个要求:
|
||||||
|
|
||||||
|
@ -130,4 +130,4 @@ Kubernetes 管理员(具有适当权限)可以使用 `kubectl certificate ap
|
||||||
|
|
||||||
## 给集群管理员的一个建议
|
## 给集群管理员的一个建议
|
||||||
|
|
||||||
本教程假设将signer设置为服务证书API。Kubernetes controller manager提供了一个signer的默认实现。 要启用它,请将`--cluster-signing-cert-file`和`--cluster-signing-key-file`参数传递给controller manager,并配置具有证书颁发机构的密钥对的路径。
|
本教程假设将 signer 设置为服务证书 API。Kubernetes controller manager 提供了一个 signer 的默认实现。 要启用它,请将 `--cluster-signing-cert-file` 和 `--cluster-signing-key-file` 参数传递给 controller manager,并配置具有证书颁发机构的密钥对的路径。
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# 管理namespace中的资源配额
|
# 管理 namespace 中的资源配额
|
||||||
|
|
||||||
当用多个团队或者用户共用同一个集群的时候难免会有资源竞争的情况发生,这时候就需要对不同团队或用户的资源使用配额做出限制。
|
当用多个团队或者用户共用同一个集群的时候难免会有资源竞争的情况发生,这时候就需要对不同团队或用户的资源使用配额做出限制。
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
目前有两种资源分配管理相关的控制策略插件 `ResourceQuota` 和 `LimitRange`。
|
目前有两种资源分配管理相关的控制策略插件 `ResourceQuota` 和 `LimitRange`。
|
||||||
|
|
||||||
要启用它们只要 API Server 的启动配置的 `KUBE_ADMISSION_CONTROL` 参数中加入了 `ResourceQuota` 的设置,这样就给集群开启了资源配额限制功能,加入 `LimitRange` 可以用来限制一个资源申请的范围限制,参考 [为 namesapce 配置默认的内存请求与限额](https://k8smeetup.github.io/docs/tasks/administer-cluster/memory-default-namespace/) 和 [在 namespace 中配置默认的CPU请求与限额](https://k8smeetup.github.io/docs/tasks/administer-cluster/cpu-default-namespace/)。
|
要启用它们只要 API Server 的启动配置的 `KUBE_ADMISSION_CONTROL` 参数中加入了 `ResourceQuota` 的设置,这样就给集群开启了资源配额限制功能,加入 `LimitRange` 可以用来限制一个资源申请的范围限制,参考 [为 namesapce 配置默认的内存请求与限额](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/) 和 [在 namespace 中配置默认的CPU请求与限额](https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)。
|
||||||
|
|
||||||
两种控制策略的作用范围都是对于某一 namespace,`ResourceQuota` 用来限制 namespace 中所有的 Pod 占用的总的资源 request 和 limit,而 `LimitRange` 是用来设置 namespace 中 Pod 的默认的资源 request 和 limit 值。
|
两种控制策略的作用范围都是对于某一 namespace,`ResourceQuota` 用来限制 namespace 中所有的 Pod 占用的总的资源 request 和 limit,而 `LimitRange` 是用来设置 namespace 中 Pod 的默认的资源 request 和 limit 值。
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
- 存储资源配额
|
- 存储资源配额
|
||||||
- 对象数量配额
|
- 对象数量配额
|
||||||
|
|
||||||
关于资源配额的详细信息请参考 kubernetes 官方文档 [资源配额](https://k8smeetup.github.io/docs/concepts/policy/resource-quotas/)。
|
关于资源配额的详细信息请参考 Kubernetes 官方文档 [资源配额](https://kubernetes.io/docs/concepts/policy/resource-quotas/)。
|
||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
|
@ -94,6 +94,6 @@ spec:
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [资源配额](https://k8smeetup.github.io/docs/concepts/policy/resource-quotas/)
|
- [资源配额 - kubernetes.io](https://kubernetes.io/docs/concepts/policy/resource-quotas/)
|
||||||
- [为命名空间配置默认的内存请求与限额](https://k8smeetup.github.io/docs/tasks/administer-cluster/memory-default-namespace/)
|
- [为命名空间配置默认的内存请求与限额 - kubernetes.io](https://kubernetes.io/docs/tasks/administer-cluster/memory-default-namespace/)
|
||||||
- [在命名空间中配置默认的CPU请求与限额](https://k8smeetup.github.io/docs/tasks/administer-cluster/cpu-default-namespace/)
|
- [在命名空间中配置默认的 CPU 请求与限额 - kubernetes.io](https://kubernetes.io/docs/tasks/administer-cluster/cpu-default-namespace/)
|
||||||
|
|
|
@ -577,5 +577,3 @@ Pod 中有多个容器。但是,pod 中的每个容器必须请求其挂载卷
|
||||||
- 可以创建和使用 secret 的 pod 的用户也可以看到该 secret 的值。即使 API server 策略不允许用户读取 secret 对象,用户也可以运行暴露 secret 的 pod。
|
- 可以创建和使用 secret 的 pod 的用户也可以看到该 secret 的值。即使 API server 策略不允许用户读取 secret 对象,用户也可以运行暴露 secret 的 pod。
|
||||||
- 如果运行了多个副本,那么这些 secret 将在它们之间共享。默认情况下,etcd 不能保证与 SSL/TLS 的对等通信,尽管可以进行配置。
|
- 如果运行了多个副本,那么这些 secret 将在它们之间共享。默认情况下,etcd 不能保证与 SSL/TLS 的对等通信,尽管可以进行配置。
|
||||||
- 目前,任何节点的 root 用户都可以通过模拟 kubelet 来读取 API server 中的任何 secret。只有向实际需要它们的节点发送 secret 才能限制单个节点的根漏洞的影响,该功能还在计划中。
|
- 目前,任何节点的 root 用户都可以通过模拟 kubelet 来读取 API server 中的任何 secret。只有向实际需要它们的节点发送 secret 才能限制单个节点的根漏洞的影响,该功能还在计划中。
|
||||||
|
|
||||||
原文地址:https://github.com/rootsongjc/kubernetes.github.io/blob/master/docs/concepts/configuration/secret.md
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# 使用etcdctl访问kubernetes数据
|
# 使用 etcdctl 访问 Kubernetes 数据
|
||||||
|
|
||||||
Kubenretes1.6中使用etcd V3版本的API,使用`etcdctl`直接`ls`的话只能看到`/kube-centos`一个路径。需要在命令前加上`ETCDCTL_API=3`这个环境变量才能看到kuberentes在etcd中保存的数据。
|
Kubenretes1.6 中使用 etcd V3 版本的 API,使用 `etcdctl` 直接 `ls` 的话只能看到 `/kube-centos` 一个路径。需要在命令前加上 `ETCDCTL_API=3` 这个环境变量才能看到 kuberentes 在 etcd 中保存的数据。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ETCDCTL_API=3 etcdctl get /registry/namespaces/default -w=json|python -m json.tool
|
ETCDCTL_API=3 etcdctl get /registry/namespaces/default -w=json|python -m json.tool
|
||||||
|
@ -15,9 +15,9 @@ ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
|
||||||
get /registry/namespaces/default -w=json | jq .
|
get /registry/namespaces/default -w=json | jq .
|
||||||
```
|
```
|
||||||
|
|
||||||
- `-w`指定输出格式
|
- `-w` 指定输出格式
|
||||||
|
|
||||||
将得到这样的json的结果:
|
将得到这样的 json 的结果:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -40,13 +40,13 @@ get /registry/namespaces/default -w=json | jq .
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
使用`--prefix`可以看到所有的子目录,如查看集群中的namespace:
|
使用 `--prefix` 可以看到所有的子目录,如查看集群中的 namespace:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ETCDCTL_API=3 etcdctl get /registry/namespaces --prefix -w=json|python -m json.tool
|
ETCDCTL_API=3 etcdctl get /registry/namespaces --prefix -w=json|python -m json.tool
|
||||||
```
|
```
|
||||||
|
|
||||||
输出结果中可以看到所有的namespace。
|
输出结果中可以看到所有的 namespace。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
{
|
{
|
||||||
|
@ -118,18 +118,18 @@ ETCDCTL_API=3 etcdctl get /registry/namespaces --prefix -w=json|python -m json.t
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
key的值是经过base64编码,需要解码后才能看到实际值,如:
|
key 的值是经过 base64 编码,需要解码后才能看到实际值,如:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ echo L3JlZ2lzdHJ5L25hbWVzcGFjZXMvYXV0b21vZGVs|base64 -d
|
$ echo L3JlZ2lzdHJ5L25hbWVzcGFjZXMvYXV0b21vZGVs|base64 -d
|
||||||
/registry/namespaces/automodel
|
/registry/namespaces/automodel
|
||||||
```
|
```
|
||||||
|
|
||||||
## etcd中kubernetes的元数据
|
## etcd 中 kubernetes 的元数据
|
||||||
|
|
||||||
我们使用kubectl命令获取的kubernetes的对象状态实际上是保存在etcd中的,使用下面的脚本可以获取etcd中的所有kubernetes对象的key:
|
我们使用 kubectl 命令获取的 kubernetes 的对象状态实际上是保存在 etcd 中的,使用下面的脚本可以获取 etcd 中的所有 kubernetes 对象的 key:
|
||||||
|
|
||||||
> 注意,我们使用了ETCD v3版本的客户端命令来访问etcd。
|
> 注意,我们使用了 ETCD v3 版本的客户端命令来访问 etcd。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
@ -141,7 +141,7 @@ for x in $keys;do
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
通过输出的结果我们可以看到kubernetes的原数据是按何种结构包括在kuberentes中的,输出结果如下所示:
|
通过输出的结果我们可以看到 kubernetes 的原数据是按何种结构包括在 kuberentes 中的,输出结果如下所示:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
/registry/ThirdPartyResourceData/istio.io/istioconfigs/default/route-rule-details-default
|
/registry/ThirdPartyResourceData/istio.io/istioconfigs/default/route-rule-details-default
|
||||||
|
@ -158,9 +158,9 @@ done
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
我们可以看到所有的Kuberentes的所有元数据都保存在`/registry`目录下,下一层就是API对象类型(复数形式),再下一层是`namespace`,最后一层是对象的名字。
|
我们可以看到所有的 Kuberentes 的所有元数据都保存在 `/registry` 目录下,下一层就是 API 对象类型(复数形式),再下一层是 `namespace`,最后一层是对象的名字。
|
||||||
|
|
||||||
以下是etcd中存储的kubernetes所有的元数据类型:
|
以下是 etcd 中存储的 kubernetes 所有的元数据类型:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
ThirdPartyResourceData
|
ThirdPartyResourceData
|
||||||
|
@ -197,8 +197,3 @@ statefulsets
|
||||||
storageclasses
|
storageclasses
|
||||||
thirdpartyresources
|
thirdpartyresources
|
||||||
```
|
```
|
||||||
|
|
||||||
## 参考
|
|
||||||
|
|
||||||
- [etcd中文文档](https://github.com/doczhcn/etcd)
|
|
||||||
- [etcd官方文档](https://coreos.com/etcd/docs/latest/)
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Kubectl命令概览
|
# Kubectl 命令概览
|
||||||
|
|
||||||
Kubernetes提供的kubectl命令是与集群交互最直接的方式,v1.6版本的kubectl命令参考图如下:
|
Kubernetes 提供的 kubectl 命令是与集群交互最直接的方式,v1.6 版本的 kubectl 命令参考图如下:
|
||||||
|
|
||||||
![kubectl cheatsheet](../images/kubernetes-kubectl-cheatsheet.png)
|
![kubectl cheatsheet](../images/kubernetes-kubectl-cheatsheet.png)
|
||||||
|
|
||||||
Kubectl的子命令主要分为8个类别:
|
Kubectl 的子命令主要分为 8 个类别:
|
||||||
|
|
||||||
- 基础命令(初学者都会使用的)
|
- 基础命令(初学者都会使用的)
|
||||||
- 基础命令(中级)
|
- 基础命令(中级)
|
||||||
|
@ -15,35 +15,35 @@ Kubectl的子命令主要分为8个类别:
|
||||||
- 设置命令
|
- 设置命令
|
||||||
- 其他命令
|
- 其他命令
|
||||||
|
|
||||||
熟悉这些命令有助于大家来操作和管理kubernetes集群。
|
熟悉这些命令有助于大家来操作和管理 kubernetes 集群。
|
||||||
|
|
||||||
## 命令行提示
|
## 命令行提示
|
||||||
|
|
||||||
为了使用kubectl命令更加高效,我们可以选择安装一下开源软件来增加操作kubectl命令的快捷方式,同时为kubectl命令增加命令提示。
|
为了使用 kubectl 命令更加高效,我们可以选择安装一下开源软件来增加操作 kubectl 命令的快捷方式,同时为 kubectl 命令增加命令提示。
|
||||||
|
|
||||||
![增加kubeclt命令的工具(图片来自网络)](../images/tools-to-supercharge-kubectl.jpg)
|
![增加kubeclt命令的工具(图片来自网络)](../images/tools-to-supercharge-kubectl.jpg)
|
||||||
|
|
||||||
- [kubectx](https://github.com/ahmetb/kubectx):用于切换kubernetes context
|
- [kubectx](https://github.com/ahmetb/kubectx):用于切换 Kubernetes context
|
||||||
- [kube-ps1](https://github.com/jonmosco/kube-ps1):为命令行终端增加`$PROMPT`字段
|
- [kube-ps1](https://github.com/jonmosco/kube-ps1):为命令行终端增加`$PROMPT`字段
|
||||||
- [kube-shell](https://github.com/cloudnativelabs/kube-shell):交互式带命令提示的kubectl终端
|
- [kube-shell](https://github.com/cloudnativelabs/kube-shell):交互式带命令提示的 kubectl 终端
|
||||||
|
|
||||||
全部配置完成后的kubectl终端如下图所示:
|
全部配置完成后的 kubectl 终端如下图所示:
|
||||||
|
|
||||||
![增强的kubectl命令](../images/supercharged-kubectl.jpg)
|
![增强的kubectl命令](../images/supercharged-kubectl.jpg)
|
||||||
|
|
||||||
### kube-shell
|
kube-shell
|
||||||
|
|
||||||
开源项目[kube-shell](https://github.com/cloudnativelabs/kube-shell)可以为kubectl提供自动的命令提示和补全,使用起来特别方便,推荐给大家。
|
开源项目 [kube-shell](https://github.com/cloudnativelabs/kube-shell) 可以为 kubectl 提供自动的命令提示和补全,使用起来特别方便,推荐给大家。
|
||||||
|
|
||||||
Kube-shell有以下特性:
|
Kube-shell 有以下特性:
|
||||||
|
|
||||||
- 命令提示,给出命令的使用说明
|
- 命令提示,给出命令的使用说明
|
||||||
- 自动补全,列出可选命令并可以通过tab键自动补全,支持模糊搜索
|
- 自动补全,列出可选命令并可以通过 tab 键自动补全,支持模糊搜索
|
||||||
- 高亮
|
- 高亮
|
||||||
- 使用tab键可以列出可选的对象
|
- 使用 tab 键可以列出可选的对象
|
||||||
- vim模式
|
- vim 模式
|
||||||
|
|
||||||
**Mac下安装**
|
**Mac 下安装**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install kube-shell --user -U
|
pip install kube-shell --user -U
|
||||||
|
@ -51,21 +51,21 @@ pip install kube-shell --user -U
|
||||||
|
|
||||||
![kube-shell页面](../images/kube-shell.jpg)
|
![kube-shell页面](../images/kube-shell.jpg)
|
||||||
|
|
||||||
## kubectl的身份认证
|
## kubectl 的身份认证
|
||||||
|
|
||||||
Kubernetes中存在三种安全认证方式:
|
Kubernetes 中存在三种安全认证方式:
|
||||||
|
|
||||||
- **CA证书**:API server与其它几个组件之间都是通过这种方式认证的
|
- **CA 证书**:API server 与其它几个组件之间都是通过这种方式认证的
|
||||||
- **HTTP base**:即在API server的启动参数中指定的`--token-auth-file=/etc/kubernetes/token.csv`文件中明文的用户、组、密码和UID配置
|
- **HTTP base**:即在 API server 的启动参数中指定的 `--token-auth-file=/etc/kubernetes/token.csv` 文件中明文的用户、组、密码和 UID 配置
|
||||||
- **bearer token**:HTTP请求中`header`中传递的`Autorization:Bearer token`,这个token通常保存在创建角色跟`serviceaccount`绑定的时候生成的secret中。
|
- **bearer token**:HTTP 请求中 `header` 中传递的 `Autorization:Bearer token`,这个 token 通常保存在创建角色跟 `serviceaccount` 绑定的时候生成的 secret 中。
|
||||||
|
|
||||||
kubectl通过读取`kubeconfig`文件中的配置信息在向API server发送请求的时候同时传递认证信息,同时支持CA证书和bearer token的认证方式,请参考[使用kubeconfig文件配置跨集群认证](../guide/authenticate-across-clusters-kubeconfig.md)。
|
kubectl 通过读取 `kubeconfig` 文件中的配置信息在向 API server 发送请求的时候同时传递认证信息,同时支持 CA 证书和 bearer token 的认证方式,请参考[使用 kubeconfig 文件配置跨集群认证](../guide/authenticate-across-clusters-kubeconfig.md)。
|
||||||
|
|
||||||
## 终端下kubectl命令自动补全
|
## 终端下 kubectl 命令自动补全
|
||||||
|
|
||||||
建议使用[oh-my-zsh](http://ohmyz.sh/),增加对kubectl命令自动补全支持。
|
建议使用 [oh-my-zsh](http://ohmyz.sh/),增加对 kubectl 命令自动补全支持。
|
||||||
|
|
||||||
修改`~/.zshrc`文件,增加如下两行:
|
修改 `~/.zshrc` 文件,增加如下两行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
plugins=(kubectl)
|
plugins=(kubectl)
|
||||||
|
@ -74,4 +74,6 @@ source <(kubectl completion zsh)
|
||||||
|
|
||||||
保存后重启终端即可生效。
|
保存后重启终端即可生效。
|
||||||
|
|
||||||
参考:[Install and Set Up kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#using-zsh)
|
## 参考
|
||||||
|
|
||||||
|
- [Install and Set Up kubectl - kubernetes.io](https://kubernetes.io/docs/tasks/tools/install-kubectl/#using-zsh)
|
||||||
|
|
|
@ -1,26 +1,24 @@
|
||||||
# 使用StatefulSet部署有状态应用
|
# 使用StatefulSet部署有状态应用
|
||||||
|
|
||||||
[StatefulSet](../concepts/statefulset.md) 这个对象是专门用来部署用状态应用的,可以为Pod提供稳定的身份标识,包括hostname、启动顺序、DNS名称等。
|
[StatefulSet](../concepts/statefulset.md) 这个对象是专门用来部署用状态应用的,可以为 Pod 提供稳定的身份标识,包括 hostname、启动顺序、DNS 名称等。
|
||||||
|
|
||||||
下面以在kubernetes1.6版本中部署zookeeper和kafka为例讲解StatefulSet的使用,其中kafka依赖于zookeeper。
|
下面以在 kubernetes1.6 版本中部署 zookeeper 和 kafka 为例讲解 StatefulSet 的使用,其中 kafka 依赖于 zookeeper。
|
||||||
|
|
||||||
Dockerfile和配置文件见 [zookeeper](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/zookeeper) 和 [kafka](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/kafka)。
|
Dockerfile 和配置文件见 [zookeeper](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/zookeeper) 和 [kafka](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/kafka)。
|
||||||
|
|
||||||
**注:**所有的镜像基于CentOS系统的JDK制作,为我的私人镜像,外部无法访问,yaml中没有配置持久化存储。
|
**注:**所有的镜像基于 CentOS 系统的 JDK 制作,为我的私人镜像,外部无法访问,yaml 中没有配置持久化存储。
|
||||||
|
|
||||||
## 部署Zookeeper
|
## 部署 Zookeeper
|
||||||
|
|
||||||
Dockerfile中从远程获取zookeeper的安装文件,然后在定义了三个脚本:
|
Dockerfile 中从远程获取 zookeeper 的安装文件,然后在定义了三个脚本:
|
||||||
|
|
||||||
- zkGenConfig.sh:生成zookeeper配置文件
|
- zkGenConfig.sh:生成 zookeeper 配置文件
|
||||||
- zkMetrics.sh:获取zookeeper的metrics
|
- zkMetrics.sh:获取 zookeeper 的 metrics
|
||||||
- zkOk.sh:用来做ReadinessProb
|
- zkOk.sh:用来做 ReadinessProb
|
||||||
|
|
||||||
我们在来看下这三个脚本的执行结果:
|
我们在来看下这三个脚本的执行结果。
|
||||||
|
|
||||||
zkGenConfig.sh
|
zkMetrics.sh 脚本实际上执行的是下面的命令:
|
||||||
|
|
||||||
zkMetrics.sh脚本实际上执行的是下面的命令:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ echo mntr | nc localhost $ZK_CLIENT_PORT >& 1
|
$ echo mntr | nc localhost $ZK_CLIENT_PORT >& 1
|
||||||
|
@ -44,7 +42,7 @@ zk_synced_followers 1
|
||||||
zk_pending_syncs 0
|
zk_pending_syncs 0
|
||||||
```
|
```
|
||||||
|
|
||||||
zkOk.sh脚本实际上执行的是下面的命令:
|
zkOk.sh 脚本实际上执行的是下面的命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ echo ruok | nc 127.0.0.1 $ZK_CLIENT_PORT
|
$ echo ruok | nc 127.0.0.1 $ZK_CLIENT_PORT
|
||||||
|
@ -53,7 +51,7 @@ imok
|
||||||
|
|
||||||
**zookeeper.yaml**
|
**zookeeper.yaml**
|
||||||
|
|
||||||
下面是启动三个zookeeper实例的yaml配置文件:
|
下面是启动三个 zookeeper 实例的 YAML 配置文件:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
|
@ -200,11 +198,11 @@ spec:
|
||||||
|
|
||||||
我们再主要下上面那三个脚本的用途。
|
我们再主要下上面那三个脚本的用途。
|
||||||
|
|
||||||
## 部署kafka
|
## 部署 kafka
|
||||||
|
|
||||||
Kafka的docker镜像制作跟zookeeper类似,都是从远程下载安装包后,解压安装。
|
Kafka 的 docker 镜像制作跟 zookeeper 类似,都是从远程下载安装包后,解压安装。
|
||||||
|
|
||||||
与zookeeper不同的是,只要一个脚本,但是又依赖于我们上一步安装的zookeeper,kafkaGenConfig.sh用来生成kafka的配置文件。
|
与 zookeeper 不同的是,只要一个脚本,但是又依赖于我们上一步安装的 zookeeper,kafkaGenConfig.sh 用来生成 kafka 的配置文件。
|
||||||
|
|
||||||
我们来看下这个脚本。
|
我们来看下这个脚本。
|
||||||
|
|
||||||
|
@ -224,11 +222,11 @@ sed -i s"/broker.id=0/broker.id=$MY_ID/g" /opt/kafka/config/server.properties
|
||||||
sed -i s'/zookeeper.connect=localhost:2181/zookeeper.connect=zk-0.zk-svc.brand.svc:2181,zk-1.zk-svc.brand.svc:2181,zk-2.zk-svc.brand.svc:2181/g' /opt/kafka/config/server.properties
|
sed -i s'/zookeeper.connect=localhost:2181/zookeeper.connect=zk-0.zk-svc.brand.svc:2181,zk-1.zk-svc.brand.svc:2181,zk-2.zk-svc.brand.svc:2181/g' /opt/kafka/config/server.properties
|
||||||
```
|
```
|
||||||
|
|
||||||
该脚本根据statefulset生成的pod的hostname的后半截数字部分作为broker ID,同时再替换zookeeper的地址。
|
该脚本根据 statefulset 生成的 pod 的 hostname 的后半截数字部分作为 broker ID,同时再替换 zookeeper 的地址。
|
||||||
|
|
||||||
**Kafka.yaml**
|
**Kafka.yaml**
|
||||||
|
|
||||||
下面是创建3个kafka实例的yaml配置。
|
下面是创建 3 个 kafka 实例的 YAML 配置。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
|
@ -322,5 +320,4 @@ spec:
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
|
- [StatefulSet - kubernetes.i](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)
|
||||||
- [kubernetes contrib - statefulsets](https://github.com/kubernetes/contrib/tree/master/statefulsets)
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 67 KiB |
Binary file not shown.
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 75 KiB |
|
@ -1,4 +1,4 @@
|
||||||
# 安装配置kube-dns
|
# 安装配置 kube-dns
|
||||||
|
|
||||||
在我们安装Kubernetes集群的时候就已经安装了kube-dns插件,这个插件也是官方推荐安装的。通过将 Service 注册到 DNS 中,Kuberentes 可以为我们提供一种简单的服务注册发现与负载均衡方式。
|
在我们安装Kubernetes集群的时候就已经安装了kube-dns插件,这个插件也是官方推荐安装的。通过将 Service 注册到 DNS 中,Kuberentes 可以为我们提供一种简单的服务注册发现与负载均衡方式。
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ Kubernetes 1.3 版本起引入了支持多站点 Kubernetes 安装的集群联
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Configure DNS Service](https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/)
|
- [Configure DNS Service - kubernetes.io](https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/)
|
||||||
- [Service 和 Pod 的 DNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/)
|
- [Service 和 Pod 的 DNS - kubernetes.io](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/)
|
||||||
- [自动扩容集群中的 DNS 服务](https://kubernetes.io/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)
|
- [自动扩容集群中的 DNS 服务 - kubernetes.io](https://kubernetes.io/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)
|
||||||
- [Using CoreDNS for Service Discovery](https://kubernetes.io/docs/tasks/administer-cluster/coredns/)
|
- [Using CoreDNS for Service Discovery - kubernetes.io](https://kubernetes.io/docs/tasks/administer-cluster/coredns/)
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
# 安装配置CoreDNS
|
# 安装配置 CoreDNS
|
||||||
|
|
||||||
CoreDNS可以在具有标准的Kube-DNS的Kubernetes集群中运行。作为Kubernetes 的插件使用,CoreDNS将从
|
CoreDNS 可以在具有标准的 Kube-DNS 的 Kubernetes 集群中运行。作为 Kubernetes 的插件使用,CoreDNS 将从 Kubernetes 集群中读取区(zone)数据。它实现了为 Kubernetes 的 DNS 服务发现定义的规范:[Kubernetes DNS-Based Service Discovery](https://github.com/kubernetes/dns/blob/master/docs/specification.md)。
|
||||||
Kubernetes集群中读取区(zone)数据。它实现了为Kubernetes的DNS服务发现定义的规范:[Kubernetes DNS-Based Service Discovery](https://github.com/kubernetes/dns/blob/master/docs/specification.md)。
|
|
||||||
|
|
||||||
## 部署CoreDNS
|
## 部署 CoreDNS
|
||||||
|
|
||||||
部署 CoreDNS 需要使用到官方提供的两个文件 [deploy.sh](https://github.com/coredns/deployment/blob/master/kubernetes/deploy.sh)和[coredns.yaml.sed](https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed)(这两个文件已经放入manifest的coredns目录中)
|
部署 CoreDNS 需要使用到官方提供的两个文件 [deploy.sh](https://github.com/coredns/deployment/blob/master/kubernetes/deploy.sh) 和 [coredns.yaml.sed](https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed)(这两个文件已经放入 manifest 的 coredns 目录中)
|
||||||
|
|
||||||
`deploy.sh` 是一个用于在已经运行kube-dns的集群中生成运行CoreDNS部署文件(manifest)的工具脚本。它使用 `coredns.yaml.sed`文件作为模板,创建一个ConfigMap和CoreDNS的deployment,然后更新集群中已有的kube-dns
|
`deploy.sh` 是一个用于在已经运行 kube-dns 的集群中生成运行 CoreDNS 部署文件(manifest)的工具脚本。它使用 `coredns.yaml.sed` 文件作为模板,创建一个 ConfigMap 和 CoreDNS 的 deployment,然后更新集群中已有的 kube-dns 服务的 selector 使用 CoreDNS 的 deployment。重用已有的服务并不会在服务的请求中发生冲突。
|
||||||
服务的selector使用CoreDNS的deployment。重用已有的服务并不会在服务的请求中发生冲突。
|
|
||||||
|
|
||||||
`deploy.sh`文件并不会删除kube-dns的deployment或者replication controller。如果要删除kube-dns,你必须在部署CoreDNS后手动的删除kube-dns。
|
`deploy.sh` 文件并不会删除 kube-dns 的 deployment 或者 replication controller。如果要删除 kube-dns,你必须在部署 CoreDNS 后手动的删除 kube-dns。
|
||||||
|
|
||||||
你需要仔细测试manifest文件,以确保它能够对你的集群正常运行。这依赖于你的怎样构建你的集群以及你正在运行的集群版本。
|
你需要仔细测试 manifest 文件,以确保它能够对你的集群正常运行。这依赖于你的怎样构建你的集群以及你正在运行的集群版本。
|
||||||
|
|
||||||
对manifest文件做一些修改是有比要的。
|
对 manifest 文件做一些修改是有比要的。
|
||||||
|
|
||||||
在最佳的案例场景中,使用CoreDNS替换Kube-DNS只需要使用下面的两个命令:
|
在最佳的案例场景中,使用 CoreDNS 替换 Kube-DNS 只需要使用下面的两个命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./deploy.sh | kubectl apply -f -
|
$ ./deploy.sh | kubectl apply -f -
|
||||||
$ kubectl delete --namespace=kube-system deployment kube-dns
|
$ kubectl delete --namespace=kube-system deployment kube-dns
|
||||||
```
|
```
|
||||||
|
|
||||||
注意:我们建议在部署CoreDNS后删除kube-dns。否则如果CoreDNS和kube-dns同时运行,服务查询可能会随机的在CoreDNS和kube-dns之间产生。
|
注意:我们建议在部署 CoreDNS 后删除 kube-dns。否则如果 CoreDNS 和 kube-dns 同时运行,服务查询可能会随机的在 CoreDNS 和 kube-dns 之间产生。
|
||||||
|
|
||||||
对于非RBAC部署,你需要编辑生成的结果yaml文件:
|
对于非 RBAC 部署,你需要编辑生成的结果 yaml 文件:
|
||||||
1. 从yaml文件的`Deployment`部分删除 `serviceAccountName: coredns`
|
|
||||||
2. 删除 `ServiceAccount`、 `ClusterRole `和 `ClusterRoleBinding` 部分
|
1. 从 yaml 文件的 `Deployment` 部分删除 `serviceAccountName: coredns`
|
||||||
|
2. 删除 `ServiceAccount`、 `ClusterRole` 和 `ClusterRoleBinding` 部分
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Kubernetes DNS-Based Service Discovery](https://github.com/kubernetes/dns/blob/master/docs/specification.md)
|
- [Kubernetes DNS-Based Service Discovery - github.com](https://github.com/kubernetes/dns/blob/master/docs/specification.md)
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# 创建TLS证书和秘钥
|
# 创建 TLS 证书和秘钥
|
||||||
|
|
||||||
## 前言
|
|
||||||
|
|
||||||
执行下列步骤前建议你先阅读以下内容:
|
执行下列步骤前建议你先阅读以下内容:
|
||||||
|
|
||||||
|
@ -8,7 +6,7 @@
|
||||||
- [kubelet的认证授权](../guide/kubelet-authentication-authorization.md):向您描述如何通过认证授权来访问 kubelet 的 HTTPS 端点。
|
- [kubelet的认证授权](../guide/kubelet-authentication-authorization.md):向您描述如何通过认证授权来访问 kubelet 的 HTTPS 端点。
|
||||||
- [TLS bootstrap](../guide/tls-bootstrapping.md):介绍如何为 kubelet 设置 TLS 客户端证书引导(bootstrap)。
|
- [TLS bootstrap](../guide/tls-bootstrapping.md):介绍如何为 kubelet 设置 TLS 客户端证书引导(bootstrap)。
|
||||||
|
|
||||||
**注意**:这一步是在安装配置kubernetes的所有步骤中最容易出错也最难于排查问题的一步,而这却刚好是第一步,万事开头难,不要因为这点困难就望而却步。
|
**注意**:这一步是在安装配置 kubernetes 的所有步骤中最容易出错也最难于排查问题的一步,而这却刚好是第一步,万事开头难,不要因为这点困难就望而却步。
|
||||||
|
|
||||||
**如果您足够有信心在完全不了解自己在做什么的情况下能够成功地完成了这一步的配置,那么您可以尽管跳过上面的几篇文章直接进行下面的操作。**
|
**如果您足够有信心在完全不了解自己在做什么的情况下能够成功地完成了这一步的配置,那么您可以尽管跳过上面的几篇文章直接进行下面的操作。**
|
||||||
|
|
||||||
|
@ -404,6 +402,5 @@ cp *.pem /etc/kubernetes/ssl
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
+ [Generate self-signed certificates](https://coreos.com/os/docs/latest/generate-self-signed-certificates.html)
|
+ [Generate self-signed certificates - coreos.com](https://coreos.com/os/docs/latest/generate-self-signed-certificates.html)
|
||||||
+ [Client Certificates V/s Server Certificates](https://blogs.msdn.microsoft.com/kaushal/2012/02/17/client-certificates-vs-server-certificates/)
|
+ [Client Certificates V/s Server Certificates - blogs.msdn.microsoft.com](https://blogs.msdn.microsoft.com/kaushal/2012/02/17/client-certificates-vs-server-certificates/)
|
||||||
+ [TLS bootstrap 引导程序](../guide/tls-bootstrapping.md)
|
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
## 分布式负载测试
|
## 分布式负载测试
|
||||||
|
|
||||||
该教程描述如何在[Kubernetes](http://kubernetes.io)中进行分布式负载均衡测试,包括一个web应用、docker镜像和Kubernetes controllers/services。关于分布式负载测试的更多资料请查看[Distributed Load Testing Using Kubernetes](http://cloud.google.com/solutions/distributed-load-testing-using-kubernetes) 。
|
该教程描述如何在 [Kubernetes](https://kubernetes.io/) 中进行分布式负载均衡测试,包括一个 web 应用、docker 镜像和 Kubernetes controllers/services。关于分布式负载测试的更多资料请查看 [Distributed Load Testing Using Kubernetes](https://cloud.google.com/solutions/distributed-load-testing-using-kubernetes) 。
|
||||||
|
|
||||||
## 准备
|
## 准备
|
||||||
|
|
||||||
**不需要GCE及其他组件,你只需要有一个kubernetes集群即可。**
|
不需要 GCE 及其他组件,你只需要有一个 kubernetes 集群即可。
|
||||||
|
|
||||||
如果你还没有kubernetes集群,可以参考[kubernetes-handbook](https://www.gitbook.com/book/rootsongjc/kubernetes-handbook)部署一个。
|
## 部署 Web 应用
|
||||||
|
|
||||||
## 部署Web应用
|
本文中使用的镜像、kubernetes 应用的 yaml 配置来自我的另一个项目,请参考 [GitHub](https://github.com/rootsongjc/distributed-load-testing-using-kubernetes)。
|
||||||
|
|
||||||
本文中使用的镜像、kubernetes应用的yaml配置来自我的另一个项目,请参考:https://github.com/rootsongjc/distributed-load-testing-using-kubernetes
|
`sample-webapp` 目录下包含一个简单的 web 测试应用。我们将其构建为 docker 镜像,在 kubernetes 中运行。
|
||||||
|
|
||||||
`sample-webapp` 目录下包含一个简单的web测试应用。我们将其构建为docker镜像,在kubernetes中运行。
|
在 kubernetes 上部署 sample-webapp。
|
||||||
|
|
||||||
在kubernetes上部署sample-webapp。
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/rootsongjc/distributed-load-testing-using-kubernetes.git
|
$ git clone https://github.com/rootsongjc/distributed-load-testing-using-kubernetes.git
|
||||||
|
@ -23,55 +21,58 @@ $ kubectl create -f sample-webapp-controller.yaml
|
||||||
$ kubectl create -f sample-webapp-service.yaml
|
$ kubectl create -f sample-webapp-service.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
## 部署Locust的Controller和Service
|
## 部署 Locust 的 Controller 和 Service
|
||||||
|
|
||||||
`locust-master`和`locust-work`使用同样的docker镜像,修改cotnroller中`spec.template.spec.containers.env`字段中的value为你`sample-webapp` service的名字。
|
`locust-master` 和 `locust-work` 使用同样的 docker 镜像,修改 cotnroller 中 `spec.template.spec.containers.env` 字段中的 value 为你 `sample-webapp` service 的名字。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: TARGET_HOST
|
- name: TARGET_HOST
|
||||||
value: http://sample-webapp:8000
|
value: http://sample-webapp:8000
|
||||||
```
|
```
|
||||||
|
|
||||||
### 创建Controller Docker镜像(可选)
|
### 创建 Controller Docker 镜像(可选)
|
||||||
|
|
||||||
`locust-master`和`locust-work` controller使用的都是`locust-tasks` docker镜像。你可以直接下载`gcr.io/cloud-solutions-images/locust-tasks`,也可以自己编译。自己编译大概要花几分钟时间,镜像大小为820M。
|
`locust-master` 和 `locust-work` controller 使用的都是 `locust-tasks` docker 镜像。你可以直接下载 `gcr.io/cloud-solutions-images/locust-tasks`,也可以自己编译。自己编译大概要花几分钟时间,镜像大小为 820M。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker build -t jimmysong/locust-tasks:latest .
|
$ docker build -t jimmysong/locust-tasks:latest .
|
||||||
$ docker push jimmysong/locust-tasks:latest
|
$ docker push jimmysong/locust-tasks:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
每个controller的yaml的`spec.template.spec.containers.image` 字段指定的是我的镜像:
|
每个 controller 的 yaml 的 `spec.template.spec.containers.image` 字段指定的是我的镜像:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
image: jimmysong/locust-tasks:latest
|
image: jimmysong/locust-tasks:latest
|
||||||
```
|
```
|
||||||
### 部署locust-master
|
|
||||||
|
### 部署 locust-master
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl create -f locust-master-controller.yaml
|
$ kubectl create -f locust-master-controller.yaml
|
||||||
$ kubectl create -f locust-master-service.yaml
|
$ kubectl create -f locust-master-service.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
### 部署locust-worker
|
### 部署 locust-worker
|
||||||
|
|
||||||
Now deploy `locust-worker-controller`:
|
Now deploy `locust-worker-controller`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl create -f locust-worker-controller.yaml
|
$ kubectl create -f locust-worker-controller.yaml
|
||||||
```
|
```
|
||||||
你可以很轻易的给work扩容,通过命令行方式:
|
|
||||||
|
你可以很轻易的给 work 扩容,通过命令行方式:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ kubectl scale --replicas=20 replicationcontrollers locust-worker
|
$ kubectl scale --replicas=20 replicationcontrollers locust-worker
|
||||||
```
|
```
|
||||||
当然你也可以通过WebUI:Dashboard - Workloads - Replication Controllers - **ServiceName** - Scale来扩容。
|
|
||||||
|
|
||||||
![使用dashboard来扩容](../images/dashbaord-scale.jpg)
|
当然你也可以通过 WebUI:Dashboard - Workloads - Replication Controllers - **ServiceName** - Scale 来扩容。
|
||||||
|
|
||||||
|
![使用 dashboard 来扩容](../images/dashbaord-scale.jpg)
|
||||||
|
|
||||||
### 配置Traefik
|
### 配置Traefik
|
||||||
|
|
||||||
参考[kubernetes的traefik ingress安装](https://jimmysong.io/posts/traefik-ingress-installation/),在`ingress.yaml`中加入如下配置:
|
参考 [Kubernetes 的 traefik ingress 安装](https://jimmysong.io/posts/traefik-ingress-installation/),在 `ingress.yaml` 中加入如下配置:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- host: traefik.locust.io
|
- host: traefik.locust.io
|
||||||
|
@ -83,25 +84,25 @@ $ kubectl scale --replicas=20 replicationcontrollers locust-worker
|
||||||
servicePort: 8089
|
servicePort: 8089
|
||||||
```
|
```
|
||||||
|
|
||||||
然后执行`kubectl replace -f ingress.yaml`即可更新traefik。
|
然后执行 `kubectl replace -f ingress.yaml` 即可更新 traefik。
|
||||||
|
|
||||||
通过Traefik的dashboard就可以看到刚增加的`traefik.locust.io`节点。
|
通过 Traefik 的 dashboard 就可以看到刚增加的 `traefik.locust.io` 节点。
|
||||||
|
|
||||||
![Traefik的UI](../images/traefik-dashboard-locust.jpg)
|
![Traefik的UI](../images/traefik-dashboard-locust.jpg)
|
||||||
|
|
||||||
## 执行测试
|
## 执行测试
|
||||||
|
|
||||||
打开`http://traefik.locust.io`页面,点击`Edit`输入伪造的用户数和用户每秒发送的请求个数,点击`Start Swarming`就可以开始测试了。
|
打开 `http://traefik.locust.io` 页面,点击 `Edit` 输入伪造的用户数和用户每秒发送的请求个数,点击 `Start Swarming` 就可以开始测试了。
|
||||||
|
|
||||||
![Locust启动界面](../images/locust-start-swarming.jpg)
|
![Locust启动界面](../images/locust-start-swarming.jpg)
|
||||||
|
|
||||||
在测试过程中调整`sample-webapp`的pod个数(默认设置了1个pod),观察pod的负载变化情况。
|
在测试过程中调整 `sample-webapp` 的 pod 个数(默认设置了 1 个 pod),观察 pod 的负载变化情况。
|
||||||
|
|
||||||
![Dashboard查看页面](../images/sample-webapp-rc.jpg)
|
![Dashboard查看页面](../images/sample-webapp-rc.jpg)
|
||||||
|
|
||||||
从一段时间的观察中可以看到负载被平均分配给了3个pod。
|
从一段时间的观察中可以看到负载被平均分配给了 3 个 pod。
|
||||||
|
|
||||||
在locust的页面中可以实时观察也可以下载测试结果。
|
在 locust 的页面中可以实时观察也可以下载测试结果。
|
||||||
|
|
||||||
![Locust测试结果页面](../images/locust-dashboard.jpg)
|
![Locust测试结果页面](../images/locust-dashboard.jpg)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# 安装EFK插件
|
# 安装 EFK 插件
|
||||||
|
|
||||||
我们通过在每台node上部署一个以DaemonSet方式运行的fluentd来收集每台node上的日志。Fluentd将docker日志目录`/var/lib/docker/containers`和`/var/log`目录挂载到Pod中,然后Pod会在node节点的`/var/log/pods`目录中创建新的目录,可以区别不同的容器日志输出,该目录下有一个日志文件链接到`/var/lib/docker/contianers`目录下的容器日志输出。
|
我们通过在每台 node 上部署一个以 DaemonSet 方式运行的 fluentd 来收集每台 node 上的日志。Fluentd 将 docker 日志目录 `/var/lib/docker/containers` 和 `/var/log` 目录挂载到 Pod 中,然后 Pod 会在 node 节点的 `/var/log/pods` 目录中创建新的目录,可以区别不同的容器日志输出,该目录下有一个日志文件链接到 `/var/lib/docker/contianers` 目录下的容器日志输出。
|
||||||
|
|
||||||
官方文件目录:`cluster/addons/fluentd-elasticsearch`
|
官方文件目录:`cluster/addons/fluentd-elasticsearch`
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ $ ls *.yaml
|
||||||
es-controller.yaml es-service.yaml fluentd-es-ds.yaml kibana-controller.yaml kibana-service.yaml efk-rbac.yaml
|
es-controller.yaml es-service.yaml fluentd-es-ds.yaml kibana-controller.yaml kibana-service.yaml efk-rbac.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
同样EFK服务也需要一个`efk-rbac.yaml`文件,配置serviceaccount为`efk`。
|
同样 EFK 服务也需要一个`efk-rbac.yaml`文件,配置 serviceaccount 为 `efk`。
|
||||||
|
|
||||||
已经修改好的 yaml 文件见:[../manifests/EFK](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/EFK)
|
已经修改好的 YAML 文件见:[../manifests/EFK](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/EFK)
|
||||||
|
|
||||||
|
|
||||||
## 配置 es-controller.yaml
|
## 配置 es-controller.yaml
|
||||||
|
@ -26,7 +26,7 @@ $ diff es-controller.yaml.orig es-controller.yaml
|
||||||
|
|
||||||
## 配置 es-service.yaml
|
## 配置 es-service.yaml
|
||||||
|
|
||||||
无需配置;
|
无需配置。
|
||||||
|
|
||||||
## 配置 fluentd-es-ds.yaml
|
## 配置 fluentd-es-ds.yaml
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ $ kubectl label nodes 172.20.0.113 beta.kubernetes.io/fluentd-ds-ready=true
|
||||||
node "172.20.0.113" labeled
|
node "172.20.0.113" labeled
|
||||||
```
|
```
|
||||||
|
|
||||||
给其他两台node打上同样的标签。
|
给其他两台 node 打上同样的标签。
|
||||||
|
|
||||||
## 执行定义文件
|
## 执行定义文件
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ elasticsearch-logging 10.254.77.62 <none> 9200/TCP
|
||||||
kibana-logging 10.254.8.113 <none> 5601/TCP 2m
|
kibana-logging 10.254.8.113 <none> 5601/TCP 2m
|
||||||
```
|
```
|
||||||
|
|
||||||
kibana Pod 第一次启动时会用较长时间(10-20分钟)来优化和 Cache 状态页面,可以 tailf 该 Pod 的日志观察进度:
|
Kibana Pod 第一次启动时会用较长时间(10-20分钟)来优化和 Cache 状态页面,可以 tailf 该 Pod 的日志观察进度:
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
$ kubectl logs kibana-logging-1432287342-0gdng -n kube-system -f
|
$ kubectl logs kibana-logging-1432287342-0gdng -n kube-system -f
|
||||||
|
@ -152,10 +152,10 @@ server.basePath: /api/v1/proxy/namespaces/kube-system/services/kibana-logging
|
||||||
|
|
||||||
**可能遇到的问题**
|
**可能遇到的问题**
|
||||||
|
|
||||||
如果你在这里发现Create按钮是灰色的无法点击,且Time-filed name中没有选项,fluentd要读取`/var/log/containers/`目录下的log日志,这些日志是从`/var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log`链接过来的,查看你的docker配置,`—log-dirver`需要设置为**json-file**格式,默认的可能是**journald**,参考[docker logging](https://docs.docker.com/engine/admin/logging/overview/#examples)。
|
如果你在这里发现 Create 按钮是灰色的无法点击,且 Time-filed name 中没有选项,fluentd 要读取 `/var/log/containers/` 目录下的 log 日志,这些日志是从 `/var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log` 链接过来的,查看你的 docker 配置,`—log-dirver` 需要设置为 **json-file** 格式,默认的可能是 **journald**,参考 [docker logging](https://docs.docker.com/engine/admin/logging/overview/#examples)。
|
||||||
|
|
||||||
![es-setting](../images/es-setting.png)
|
![es-setting](../images/es-setting.png)
|
||||||
|
|
||||||
创建Index后,可以在 `Discover` 下看到 ElasticSearch logging 中汇聚的日志;
|
创建 Index 后,可以在 `Discover` 下看到 ElasticSearch logging 中汇聚的日志;
|
||||||
|
|
||||||
![es-home](../images/kubernetes-efk-kibana.jpg)
|
![es-home](../images/kubernetes-efk-kibana.jpg)
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
## 安装flannel网络插件
|
# 安装 flannel 网络插件
|
||||||
|
|
||||||
所有的node节点都需要安装网络插件才能让所有的Pod加入到同一个局域网中,本文是安装flannel网络插件的参考文档。
|
所有的 node 节点都需要安装网络插件才能让所有的 Pod 加入到同一个局域网中,本文是安装 flannel 网络插件的参考文档。
|
||||||
|
|
||||||
建议直接使用yum安装flanneld,除非对版本有特殊需求,默认安装的是0.7.1版本的flannel。
|
建议直接使用 yum 安装 flanneld,除非对版本有特殊需求,默认安装的是 0.7.1 版本的 flannel。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yum install -y flannel
|
yum install -y flannel
|
||||||
```
|
```
|
||||||
|
|
||||||
service配置文件`/usr/lib/systemd/system/flanneld.service`。
|
service 配置文件 `/usr/lib/systemd/system/flanneld.service`。
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Unit]
|
[Unit]
|
||||||
|
@ -35,7 +35,7 @@ WantedBy=multi-user.target
|
||||||
RequiredBy=docker.service
|
RequiredBy=docker.service
|
||||||
```
|
```
|
||||||
|
|
||||||
`/etc/sysconfig/flanneld`配置文件:
|
`/etc/sysconfig/flanneld` 配置文件:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
# Flanneld configuration options
|
# Flanneld configuration options
|
||||||
|
@ -51,11 +51,11 @@ FLANNEL_ETCD_PREFIX="/kube-centos/network"
|
||||||
FLANNEL_OPTIONS="-etcd-cafile=/etc/kubernetes/ssl/ca.pem -etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem -etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem"
|
FLANNEL_OPTIONS="-etcd-cafile=/etc/kubernetes/ssl/ca.pem -etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem -etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem"
|
||||||
```
|
```
|
||||||
|
|
||||||
如果是多网卡(例如vagrant环境),则需要在FLANNEL_OPTIONS中增加指定的外网出口的网卡,例如-iface=eth2
|
如果是多网卡(例如 vagrant 环境),则需要在 FLANNEL_OPTIONS 中增加指定的外网出口的网卡,例如 - iface=eth2
|
||||||
|
|
||||||
**在etcd中创建网络配置**
|
**在 etcd 中创建网络配置**
|
||||||
|
|
||||||
执行下面的命令为docker分配IP地址段。
|
执行下面的命令为 docker 分配 IP 地址段。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
etcdctl --endpoints=https://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 \
|
etcdctl --endpoints=https://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 \
|
||||||
|
@ -70,11 +70,11 @@ etcdctl --endpoints=https://172.20.0.113:2379,https://172.20.0.114:2379,https://
|
||||||
mk /kube-centos/network/config '{"Network":"172.30.0.0/16","SubnetLen":24,"Backend":{"Type":"vxlan"}}'
|
mk /kube-centos/network/config '{"Network":"172.30.0.0/16","SubnetLen":24,"Backend":{"Type":"vxlan"}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
如果你要使用`host-gw`模式,可以直接将vxlan改成`host-gw`即可。
|
如果你要使用 `host-gw` 模式,可以直接将 vxlan 改成 `host-gw` 即可。
|
||||||
|
|
||||||
**注**:参考[网络和集群性能测试](network-and-cluster-perfermance-test.md)那节,最终我们使用的`host-gw`模式,关于flannel支持的backend模式见:<https://github.com/coreos/flannel/blob/master/Documentation/backends.md>。
|
**注**:参考[网络和集群性能测试](network-and-cluster-perfermance-test.md)那节,最终我们使用的 `host-gw` 模式,关于 flannel 支持的 backend 模式见 [GitHub](https://github.com/coreos/flannel/blob/master/Documentation/backends.md)。
|
||||||
|
|
||||||
**启动flannel**
|
**启动 flannel**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
@ -83,7 +83,7 @@ systemctl start flanneld
|
||||||
systemctl status flanneld
|
systemctl status flanneld
|
||||||
```
|
```
|
||||||
|
|
||||||
现在查询etcd中的内容可以看到:
|
现在查询 etcd 中的内容可以看到:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$etcdctl --endpoints=${ETCD_ENDPOINTS} \
|
$etcdctl --endpoints=${ETCD_ENDPOINTS} \
|
||||||
|
@ -124,4 +124,4 @@ $etcdctl --endpoints=${ETCD_ENDPOINTS} \
|
||||||
{"PublicIP":"172.20.0.113","BackendType":"vxlan","BackendData":{"VtepMAC":"e6:b2:fd:f6:66:96"}}
|
{"PublicIP":"172.20.0.113","BackendType":"vxlan","BackendData":{"VtepMAC":"e6:b2:fd:f6:66:96"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
如果可以查看到以上内容证明flannel已经安装完成,下一步是在node节点上安装和配置docker、kubelet、kube-proxy等,请参考下一节[部署node节点](node-installation.md)。
|
如果可以查看到以上内容证明 flannel 已经安装完成,下一步是在 node 节点上安装和配置 docker、kubelet、kube-proxy 等,请参考下一节[部署 node 节点](node-installation.md)。
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
# 安装heapster插件
|
# 安装 heapster 插件
|
||||||
|
|
||||||
|
注:Heapster 已不再维护。
|
||||||
|
|
||||||
## 准备镜像
|
## 准备镜像
|
||||||
|
|
||||||
官方镜像保存在 gcr.io 中需要翻墙才能下载,请自行拷贝到私有仓库。
|
官方镜像保存在 gcr.io 中需要翻墙才能下载,请自行拷贝到私有仓库。
|
||||||
|
|
||||||
## 准备YAML文件
|
## 准备 YAML 文件
|
||||||
|
|
||||||
到 [heapster release 页面](https://github.com/kubernetes/heapster/releases) 下载最新版本的 heapster。
|
到 [heapster release 页面](https://github.com/kubernetes/heapster/releases) 下载最新版本的 heapster。
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
wget https://github.com/kubernetes/heapster/archive/v1.3.0.zip
|
wget https://github.com/kubernetes/heapster/archive/v1.3.0.zip
|
||||||
unzip v1.3.0.zip
|
unzip v1.3.0.zip
|
||||||
mv v1.3.0.zip heapster-1.3.0
|
mv v1.3.0.zip heapster-1.3.0
|
||||||
|
@ -16,13 +18,13 @@ mv v1.3.0.zip heapster-1.3.0
|
||||||
|
|
||||||
文件目录: `heapster-1.3.0/deploy/kube-config/influxdb`
|
文件目录: `heapster-1.3.0/deploy/kube-config/influxdb`
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
$ cd heapster-1.3.0/deploy/kube-config/influxdb
|
$ cd heapster-1.3.0/deploy/kube-config/influxdb
|
||||||
$ ls *.yaml
|
$ ls *.yaml
|
||||||
grafana-deployment.yaml grafana-service.yaml heapster-deployment.yaml heapster-service.yaml influxdb-deployment.yaml influxdb-service.yaml heapster-rbac.yaml
|
grafana-deployment.yaml grafana-service.yaml heapster-deployment.yaml heapster-service.yaml influxdb-deployment.yaml influxdb-service.yaml heapster-rbac.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
我们自己创建了heapster的rbac配置`heapster-rbac.yaml`。
|
我们自己创建了 heapster 的 rbac 配置 `heapster-rbac.yaml`。
|
||||||
|
|
||||||
已经修改好的 yaml 文件见:[../manifests/heapster](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/heapster/)
|
已经修改好的 yaml 文件见:[../manifests/heapster](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/heapster/)
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ $ diff grafana-deployment.yaml.orig grafana-deployment.yaml
|
||||||
> #value: /
|
> #value: /
|
||||||
```
|
```
|
||||||
|
|
||||||
+ 如果后续使用 kube-apiserver 或者 kubectl proxy 访问 grafana dashboard,则必须将 `GF_SERVER_ROOT_URL` 设置为 `/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/`,否则后续访问grafana时访问时提示找不到`http://172.20.0.113:8086/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/api/dashboards/home` 页面;
|
如果后续使用 kube-apiserver 或者 kubectl proxy 访问 grafana dashboard,则必须将 `GF_SERVER_ROOT_URL` 设置为 `/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/`,否则后续访问grafana时访问时提示找不到`http://172.20.0.113:8086/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/api/dashboards/home` 页面;
|
||||||
|
|
||||||
|
|
||||||
## 配置 heapster-deployment
|
## 配置 heapster-deployment
|
||||||
|
@ -106,7 +108,7 @@ $ diff influxdb-service.yaml.orig influxdb-service.yaml
|
||||||
> name: admin
|
> name: admin
|
||||||
```
|
```
|
||||||
|
|
||||||
- 定义端口类型为 NodePort,额外增加了 admin 端口映射,用于后续浏览器访问 influxdb 的 admin UI 界面;
|
定义端口类型为 NodePort,额外增加了 admin 端口映射,用于后续浏览器访问 influxdb 的 admin UI 界面;
|
||||||
|
|
||||||
## 执行所有定义文件
|
## 执行所有定义文件
|
||||||
|
|
||||||
|
@ -190,7 +192,7 @@ monitoring-influxdb-1411048194-lzrpc 1/1 Running 0 2m
|
||||||
|
|
||||||
获取 influxdb http 8086 映射的 NodePort
|
获取 influxdb http 8086 映射的 NodePort
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ kubectl get svc -n kube-system|grep influxdb
|
$ kubectl get svc -n kube-system|grep influxdb
|
||||||
monitoring-influxdb 10.254.22.46 <nodes> 8086:32299/TCP,8083:30269/TCP 9m
|
monitoring-influxdb 10.254.22.46 <nodes> 8086:32299/TCP,8083:30269/TCP 9m
|
||||||
```
|
```
|
||||||
|
@ -199,7 +201,7 @@ monitoring-influxdb 10.254.22.46 <nodes> 8086:32299/TCP,8083:30269/T
|
||||||
|
|
||||||
在页面的 “Connection Settings” 的 Host 中输入 node IP, Port 中输入 8086 映射的 nodePort 如上面的 32299,点击 “Save” 即可(我的集群中的地址是172.20.0.113:32299):
|
在页面的 “Connection Settings” 的 Host 中输入 node IP, Port 中输入 8086 映射的 nodePort 如上面的 32299,点击 “Save” 即可(我的集群中的地址是172.20.0.113:32299):
|
||||||
|
|
||||||
![kubernetes-influxdb-heapster](../images/kubernetes-influxdb-heapster.jpg)
|
![Influxdb 页面](../images/kubernetes-influxdb-heapster.jpg)
|
||||||
|
|
||||||
## 注意
|
## 注意
|
||||||
|
|
||||||
|
@ -208,7 +210,3 @@ monitoring-influxdb 10.254.22.46 <nodes> 8086:32299/TCP,8083:30269/T
|
||||||
![修改grafana模板](../images/grafana-dashboard-setting.jpg)
|
![修改grafana模板](../images/grafana-dashboard-setting.jpg)
|
||||||
|
|
||||||
将 Templating 中的 namespace 的 Data source 设置为 influxdb-datasource,Refresh 设置为 on Dashboard Load 保存设置,刷新浏览器,即可看到其他 namespace 选项。
|
将 Templating 中的 namespace 的 Data source 设置为 influxdb-datasource,Refresh 设置为 on Dashboard Load 保存设置,刷新浏览器,即可看到其他 namespace 选项。
|
||||||
|
|
||||||
## 参考
|
|
||||||
|
|
||||||
[使用Heapster获取集群对象的metric数据](../practice/using-heapster-to-get-object-metrics.md)
|
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
# 最佳实践概览
|
# 最佳实践概览
|
||||||
|
|
||||||
本章节从零开始创建我们自己的kubernetes集群,并在该集群的基础上,配置服务发现、负载均衡和日志收集等功能,使我们的集群能够成为一个真正线上可用、功能完整的集群。
|
本章节从零开始手动创建我们自己的 Kubernetes 集群,并在该集群的基础上,配置服务发现、负载均衡和日志收集等功能,使我们的集群能够成为一个真正线上可用、功能完整的集群。
|
||||||
|
|
||||||
- 第一部分[ 在CentOS上部署kubernetes集群](install-kubernetes-on-centos.md)中介绍了如何通过二进制文件在CentOS物理机(也可以是公有云主机)上快速部署一个kubernetes集群。
|
|
||||||
- 第二部分介绍如何在kubernetes中的服务发现与负载均衡。
|
|
||||||
- 第三部分介绍如何运维kubernetes集群。
|
|
||||||
- 第四部分介绍kubernetes中的存储管理。
|
|
||||||
- 第五部分关于kubernetes集群和应用的监控。
|
|
||||||
- 第六部分介绍kuberentes中的服务编排与管理。
|
|
||||||
- 第七部分介绍如何基于kubernetes做持续集成与发布。
|
|
||||||
- 第八部分是kubernetes集群与插件的更新升级。
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- 第一部分[ 在CentOS上部署kubernetes集群](install-kubernetes-on-centos.md)中介绍了如何通过二进制文件在 CentOS 物理机(也可以是公有云主机)上快速部署一个 kubernetes 集群。
|
||||||
|
- 第二部分介绍如何在 kubernetes 中的服务发现与负载均衡。
|
||||||
|
- 第三部分介绍如何运维 kubernetes 集群。
|
||||||
|
- 第四部分介绍 kubernetes 中的存储管理。
|
||||||
|
- 第五部分关于 kubernetes 集群和应用的监控。
|
||||||
|
- 第六部分介绍 kuberentes 中的服务编排与管理。
|
||||||
|
- 第七部分介绍如何基于 kubernetes 做持续集成与发布。
|
||||||
|
- 第八部分是 kubernetes 集群与插件的更新升级。
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
# 在CentOS上部署kubernetes集群
|
# 在 CentOS 上部署 Kubernetes 集群
|
||||||
|
|
||||||
> 本文档最初是基于kubenetes1.6版本编写的,对于kuberentes1.8及以上版本同样适用,只是个别位置有稍许变动,变动的地方我将特别注明版本要求。
|
> 本文档最初是基于 kubenetes1.6 版本编写的,对于 kuberentes1.8 及以上版本同样适用,只是个别位置有稍许变动,变动的地方我将特别注明版本要求。
|
||||||
|
|
||||||
本系列文档介绍使用二进制部署 `kubernetes` 集群的所有步骤,而不是使用 `kubeadm` 等自动化方式来部署集群,同时开启了集群的TLS安全认证,该安装步骤适用于所有bare metal环境、on-premise环境和公有云环境。
|
本系列文档介绍使用二进制部署 `Kubernetes` 集群的所有步骤,而不是使用 `kubeadm` 等自动化方式来部署集群,同时开启了集群的 TLS 安全认证,该安装步骤适用于所有 bare metal 环境、on-premise 环境和公有云环境。
|
||||||
|
|
||||||
> 如果您想快速的在自己电脑的本地环境下使用虚拟机来搭建kubernetes集群,可以参考[本地分布式开发环境搭建(使用Vagrant和Virtualbox)](../develop/using-vagrant-and-virtualbox-for-development.md)。
|
> 如果您想快速的在自己电脑的本地环境下使用虚拟机来搭建 Kubernetes 集群,可以参考 [本地分布式开发环境搭建(使用 Vagrant 和 Virtualbox)](../develop/using-vagrant-and-virtualbox-for-development.md)。
|
||||||
|
|
||||||
在部署的过程中,将详细列出各组件的启动参数,给出配置文件,详解它们的含义和可能遇到的问题。
|
在部署的过程中,将详细列出各组件的启动参数,给出配置文件,详解它们的含义和可能遇到的问题。
|
||||||
|
|
||||||
部署完成后,你将理解系统各组件的交互原理,进而能快速解决实际问题。
|
部署完成后,你将理解系统各组件的交互原理,进而能快速解决实际问题。
|
||||||
|
|
||||||
所以本文档主要适合于那些有一定 kubernetes 基础,想通过一步步部署的方式来学习和了解系统配置、运行原理的人。
|
所以本文档主要适合于那些有一定 Kubernetes 基础,想通过一步步部署的方式来学习和了解系统配置、运行原理的人。
|
||||||
|
|
||||||
**注:本文档中不包括docker和私有镜像仓库的安装,安装说明中使用的镜像来自 Google Cloud Platform,中国大陆用户若无法访问请自行选择其他镜像仓库备份。**
|
**注:本文档中不包括 docker 和私有镜像仓库的安装,安装说明中使用的镜像来自 Google Cloud Platform,中国大陆用户若无法访问请自行选择其他镜像仓库备份。**
|
||||||
|
|
||||||
**欲下载最新版本的官方镜像请访问 [Google 云平台容器注册表](https://console.cloud.google.com/gcr/images/google-containers/GLOBAL)。**
|
**欲下载最新版本的官方镜像请访问 [Google 云平台容器注册表](https://console.cloud.google.com/gcr/images/google-containers/GLOBAL)。**
|
||||||
|
|
||||||
|
@ -20,26 +20,26 @@
|
||||||
|
|
||||||
集群安装时所有组件用到的配置文件,包含在以下目录中:
|
集群安装时所有组件用到的配置文件,包含在以下目录中:
|
||||||
|
|
||||||
- **etc**:service的环境变量配置文件
|
-**etc**:service 的环境变量配置文件
|
||||||
- **manifest**:kubernetes应用的yaml文件
|
-**manifest**:Kubernetes 应用的 yaml 文件
|
||||||
- **systemd** :systemd serivce配置文件
|
-**systemd**:systemd serivce 配置文件
|
||||||
|
|
||||||
## 集群详情
|
## 集群详情
|
||||||
|
|
||||||
+ OS:CentOS Linux release 7.4.1708 (Core) 3.10.0-693.11.6.el7.x86_64
|
+ OS:CentOS Linux release 7.4.1708 (Core) 3.10.0-693.11.6.el7.x86_64
|
||||||
+ Kubernetes 1.6.0+(最低的版本要求是1.6)
|
+ Kubernetes 1.6.0+(最低的版本要求是 1.6)
|
||||||
+ Docker:建议使用 Docker CE,**请勿使用 docker-1.13.1-84.git07f3374.el7.centos.x86_64 版本**,[查看详情](https://jimmysong.io/posts/docker-exec-bug-on-centos7/)
|
+ Docker:建议使用 Docker CE,**请勿使用 docker-1.13.1-84.git07f3374.el7.centos.x86_64 版本**,[查看详情](https://jimmysong.io/posts/docker-exec-bug-on-centos7/)
|
||||||
+ Etcd 3.1.5
|
+ Etcd 3.1.5
|
||||||
+ Flannel 0.7.1 vxlan或者host-gw 网络
|
+ Flannel 0.7.1 vxlan 或者 host-gw 网络
|
||||||
+ TLS 认证通信 (所有组件,如 etcd、kubernetes master 和 node)
|
+ TLS 认证通信 (所有组件,如 etcd、Kubernetes master 和 node)
|
||||||
+ RBAC 授权
|
+ RBAC 授权
|
||||||
+ kubelet TLS BootStrapping
|
+ kubelet TLS BootStrapping
|
||||||
+ kubedns、dashboard、heapster(influxdb、grafana)、EFK(elasticsearch、fluentd、kibana) 集群插件
|
+ kubedns、dashboard、heapster (influxdb、grafana)、EFK (elasticsearch、fluentd、kibana) 集群插件
|
||||||
+ 私有docker镜像仓库[harbor](https://github.com/goharbor/harbor)(请自行部署,harbor提供离线安装包,直接使用docker-compose启动即可)
|
+ 私有 docker 镜像仓库 [harbor](https://github.com/goharbor/harbor)(请自行部署,harbor 提供离线安装包,直接使用 docker-compose 启动即可)
|
||||||
|
|
||||||
## 环境说明
|
## 环境说明
|
||||||
|
|
||||||
在下面的步骤中,我们将在三台CentOS系统的物理机上部署具有三个节点的kubernetes1.6.0集群。
|
在下面的步骤中,我们将在三台 CentOS 系统的物理机上部署具有三个节点的 Kubernetes1.6.0 集群。
|
||||||
|
|
||||||
角色分配如下:
|
角色分配如下:
|
||||||
|
|
||||||
|
@ -49,50 +49,52 @@
|
||||||
|
|
||||||
**Node**:172.20.0.113、172.20.0.114、172.20.0.115
|
**Node**:172.20.0.113、172.20.0.114、172.20.0.115
|
||||||
|
|
||||||
注意:172.20.0.113这台主机master和node复用。所有生成证书、执行kubectl命令的操作都在这台节点上执行。一旦node加入到kubernetes集群之后就不需要再登陆node节点了。
|
注意:172.20.0.113 这台主机 master 和 node 复用。所有生成证书、执行 kubectl 命令的操作都在这台节点上执行。一旦 node 加入到 Kubernetes 集群之后就不需要再登陆 node 节点了。
|
||||||
|
|
||||||
## 安装前的准备
|
## 安装前的准备
|
||||||
|
|
||||||
1. 在node节点上安装docker1.12.5
|
1. 在 node 节点上安装 docker1.12.5
|
||||||
|
|
||||||
直接使用`yum install docker`
|
直接使用 `yum install docker`
|
||||||
|
|
||||||
2. 关闭所有节点的SELinux
|
2. 关闭所有节点的 SELinux
|
||||||
|
|
||||||
**永久方法 – 需要重启服务器**
|
**永久方法 – 需要重启服务器**
|
||||||
|
|
||||||
修改`/etc/selinux/config`文件中设置SELINUX=disabled ,然后重启服务器。
|
修改 `/etc/selinux/config` 文件中设置 SELINUX=disabled ,然后重启服务器。
|
||||||
|
|
||||||
**临时方法 – 设置系统参数**
|
**临时方法 – 设置系统参数**
|
||||||
|
|
||||||
使用命令`setenforce 0`
|
使用命令 `setenforce 0`
|
||||||
|
|
||||||
**附:**
|
**附:**
|
||||||
setenforce 1 设置SELinux 成为enforcing模式
|
setenforce 1 设置 SELinux 成为 enforcing 模式
|
||||||
setenforce 0 设置SELinux 成为permissive模式
|
setenforce 0 设置 SELinux 成为 permissive 模式
|
||||||
|
|
||||||
3. 准备harbor私有镜像仓库
|
3. 准备 harbor 私有镜像仓库
|
||||||
|
|
||||||
参考:https://github.com/vmware/harbor
|
参考:https://github.com/vmware/harbor
|
||||||
|
|
||||||
## 步骤介绍
|
## 步骤介绍
|
||||||
|
|
||||||
1. [创建 TLS 证书和秘钥](create-tls-and-secret-key.md)
|
1. [创建 TLS 证书和秘钥](create-tls-and-secret-key.md)
|
||||||
2. [创建kubeconfig 文件](create-kubeconfig.md)
|
2. [创建 kubeconfig 文件](create-kubeconfig.md)
|
||||||
3. [创建高可用etcd集群](etcd-cluster-installation.md)
|
3. [创建高可用 etcd 集群](etcd-cluster-installation.md)
|
||||||
4. [安装kubectl命令行工具](kubectl-installation.md)
|
4. [安装 kubectl 命令行工具](kubectl-installation.md)
|
||||||
5. [部署master节点](master-installation.md)
|
5. [部署 master 节点](master-installation.md)
|
||||||
6. [安装flannel网络插件](flannel-installation.md)
|
6. [安装 flannel 网络插件](flannel-installation.md)
|
||||||
7. [部署node节点](node-installation.md)
|
7. [部署 node 节点](node-installation.md)
|
||||||
8. [安装kubedns插件](kubedns-addon-installation.md)
|
8. [安装 kubedns 插件](kubedns-addon-installation.md)
|
||||||
9. [安装dashboard插件](dashboard-addon-installation.md)
|
9. [安装 dashboard 插件](dashboard-addon-installation.md)
|
||||||
10. [安装heapster插件](heapster-addon-installation.md)
|
10. [安装 heapster 插件](heapster-addon-installation.md)
|
||||||
11. [安装EFK插件](efk-addon-installation.md)
|
11. [安装 EFK 插件](efk-addon-installation.md)
|
||||||
|
|
||||||
## 提醒
|
## 提醒
|
||||||
|
|
||||||
1. 由于启用了 TLS 双向认证、RBAC 授权等严格的安全机制,建议**从头开始部署**,而不要从中间开始,否则可能会认证、授权等失败!
|
1. 由于启用了 TLS 双向认证、RBAC 授权等严格的安全机制,建议**从头开始部署**,而不要从中间开始,否则可能会认证、授权等失败!
|
||||||
2. 部署过程中需要有很多证书的操作,请大家耐心操作,不明白的操作可以参考本书中的其他章节的解释。
|
2. 部署过程中需要有很多证书的操作,请大家耐心操作,不明白的操作可以参考本书中的其他章节的解释。
|
||||||
3. 该部署操作仅是搭建成了一个可用 kubernetes 集群,而很多地方还需要进行优化,heapster 插件、EFK 插件不一定会用于真实的生产环境中,但是通过部署这些插件,可以让大家了解到如何部署应用到集群上。
|
3. 该部署操作仅是搭建成了一个可用 Kubernetes 集群,而很多地方还需要进行优化,heapster 插件、EFK 插件不一定会用于真实的生产环境中,但是通过部署这些插件,可以让大家了解到如何部署应用到集群上。
|
||||||
|
|
||||||
**注:本安装文档参考了 [opsnull 跟我一步步部署 kubernetes 集群](https://github.com/opsnull/follow-me-install-kubernetes-cluster/)**
|
## 参考
|
||||||
|
|
||||||
|
- [opsnull 跟我一步步部署 kubernetes 集群 - github.com](https://github.com/opsnull/follow-me-install-kubernetes-cluster/)
|
||||||
|
|
|
@ -1,38 +1,53 @@
|
||||||
# 用kubeadm在Ubuntu上快速构建Kubernetes测试集群
|
# 用 kubeadm 在 Ubuntu 上快速构建 Kubernetes 测试集群
|
||||||
|
|
||||||
本文将介绍如何在Ubuntu server 16.04版本上安装kubeadm,并利用kubeadm快速的在Ubuntu server 版本 16.04上构建一个kubernetes的基础的测试集群,用来做学习和测试用途,当前(2018-04-14)最新的版本是1.10.1。参考文档包括kubernetes官方网站的[kubeadm安装文档](https://kubernetes.io/docs/setup/independent/install-kubeadm/)以及[利用kubeadm创建集群](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/)这两个文档。
|
本文将介绍如何在 Ubuntu server 16.04 版本上安装 kubeadm,并利用 kubeadm 快速的在 Ubuntu server 版本 16.04 上构建一个 kubernetes 的基础的测试集群,用来做学习和测试用途,当前(2018-04-14)最新的版本是 1.10.1。参考文档包括 kubernetes 官方网站的 [kubeadm 安装文档](https://kubernetes.io/docs/setup/independent/install-kubeadm/)以及[利用 kubeadm 创建集群](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/)这两个文档。
|
||||||
|
|
||||||
生产用途的环境,需要考虑各个组件的高可用,建议参考Kubernetes的官方的相关的安装文档。
|
生产用途的环境,需要考虑各个组件的高可用,建议参考 Kubernetes 的官方的相关的安装文档。
|
||||||
|
|
||||||
## 概述
|
## 概述
|
||||||
|
|
||||||
本次安装建议至少4台服务器或者虚拟机,每台服务器4G内存,2个CPU核心以上,基本架构为1台master节点,3台slave节点。整个安装过程将在Ubuntu服务器上安装完kubeadm,以及安装kubernetes的基本集群,包括canal网络,另后台存储可参考本书的最佳实践中的存储管理内容。
|
本次安装建议至少 4 台服务器或者虚拟机,每台服务器 4G 内存,2 个 CPU 核心以上,基本架构为 1 台 master 节点,3 台 slave 节点。整个安装过程将在 Ubuntu 服务器上安装完 kubeadm,以及安装 kubernetes 的基本集群,包括 canal 网络,另后台存储可参考本书的最佳实践中的存储管理内容。 本次安装一共 4 个节点,节点信息如下:
|
||||||
本次安装一共4个节点,节点信息如下:
|
|
||||||
|
|
||||||
| 角色 | 主机名 | IP地址 |
|
| 角色 | 主机名 | IP 地址 |
|
||||||
|----------|----------- |------------|
|
| ------ | ------------- | ------------- |
|
||||||
| Master | Ubuntu-master | 192.168.5.200 |
|
| Master | Ubuntu-master | 192.168.5.200 |
|
||||||
| Slave | ubuntu-1 | 192.168.5.201 |
|
| Slave | ubuntu-1 | 192.168.5.201 |
|
||||||
| Slave | ubuntu-2 | 192.168.5.202 |
|
| Slave | ubuntu-2 | 192.168.5.202 |
|
||||||
| Slave | ubuntu-3 | 192.168.5.203 |
|
| Slave | ubuntu-3 | 192.168.5.203 |
|
||||||
|
|
||||||
## 准备工作
|
## 准备工作
|
||||||
|
|
||||||
- 默认方式安装Ubuntu Server 版本 16.04
|
- 默认方式安装 Ubuntu Server 版本 16.04
|
||||||
- 配置主机名映射,每个节点
|
- 配置主机名映射,每个节点
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# cat /etc/hosts
|
# cat /etc/hosts
|
||||||
127.0.0.1 localhost
|
127.0.0.1 localhost
|
||||||
192.168.0.200 Ubuntu-master
|
192.168.0.200 Ubuntu-master
|
||||||
192.168.0.201 Ubuntu-1
|
192.168.0.201 Ubuntu-1
|
||||||
192.168.0.202 Ubuntu-2
|
192.168.0.202 Ubuntu-2
|
||||||
192.168.0.203 Ubuntu-3
|
192.168.0.203 Ubuntu-3
|
||||||
|
|
||||||
```
|
```
|
||||||
* 如果连接gcr网站不方便,无法下载镜像,会导致安装过程卡住,可以下载我导出的镜像包,[我导出的镜像网盘链接](https://pan.baidu.com/s/1ZJFRt_UNCQvwcu9UENr_gw),解压缩以后是多个个tar包,使用```docker load< xxxx.tar``` 导入各个文件即可)。
|
|
||||||
## 在所有节点上安装kubeadm
|
- 如果连接 gcr 网站不方便,无法下载镜像,会导致安装过程卡住,可以下载我导出的镜像包,
|
||||||
查看apt安装源如下配置,使用阿里云的系统和kubernetes的源。
|
|
||||||
|
我导出的镜像网盘链接
|
||||||
|
|
||||||
|
,解压缩以后是多个个 tar 包,使用
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
docker load< xxxx.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
导入各个文件即可)。
|
||||||
|
|
||||||
|
## 在所有节点上安装 kubeadm
|
||||||
|
|
||||||
|
查看 apt 安装源如下配置,使用阿里云的系统和 kubernetes 的源。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cat /etc/apt/sources.list
|
$ cat /etc/apt/sources.list
|
||||||
|
@ -48,7 +63,7 @@ deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe
|
||||||
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
|
deb https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main
|
||||||
```
|
```
|
||||||
|
|
||||||
安装docker,可以使用系统源的的docker.io软件包,版本1.13.1,我的系统里是已经安装好最新的版本了。
|
安装 docker,可以使用系统源的的 docker.io 软件包,版本 1.13.1,我的系统里是已经安装好最新的版本了。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# apt-get install docker.io
|
# apt-get install docker.io
|
||||||
|
@ -58,7 +73,8 @@ Reading state information... Done
|
||||||
docker.io is already the newest version (1.13.1-0ubuntu1~16.04.2).
|
docker.io is already the newest version (1.13.1-0ubuntu1~16.04.2).
|
||||||
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
|
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
|
||||||
```
|
```
|
||||||
更新源,可以不理会gpg的报错信息。
|
|
||||||
|
更新源,可以不理会 gpg 的报错信息。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# apt-get update
|
# apt-get update
|
||||||
|
@ -74,7 +90,8 @@ W: The repository 'https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial I
|
||||||
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
|
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
|
||||||
N: See apt-secure(8) manpage for repository creation and user configuration details.
|
N: See apt-secure(8) manpage for repository creation and user configuration details.
|
||||||
```
|
```
|
||||||
强制安装kubeadm,kubectl,kubelet软件包。
|
|
||||||
|
强制安装 kubeadm,kubectl,kubelet 软件包。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated
|
# apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated
|
||||||
|
@ -107,26 +124,27 @@ Preparing to unpack .../socat_1.7.3.1-1_amd64.deb ...
|
||||||
Unpacking ....
|
Unpacking ....
|
||||||
....
|
....
|
||||||
```
|
```
|
||||||
kubeadm安装完以后,就可以使用它来快速安装部署Kubernetes集群了。
|
|
||||||
|
|
||||||
## 使用kubeadm安装Kubernetes集群
|
kubeadm 安装完以后,就可以使用它来快速安装部署 Kubernetes 集群了。
|
||||||
|
|
||||||
|
## 使用 kubeadm 安装 Kubernetes 集群
|
||||||
|
|
||||||
在做好了准备工作之后,下面介绍如何使用 kubeadm 安装 Kubernetes 集群,我们将首先安装 master 节点,然后将 slave 节点一个个加入到集群中去。
|
在做好了准备工作之后,下面介绍如何使用 kubeadm 安装 Kubernetes 集群,我们将首先安装 master 节点,然后将 slave 节点一个个加入到集群中去。
|
||||||
|
|
||||||
### 使用kubeadmin初始化master节点
|
### 使用 kubeadmin 初始化 master 节点
|
||||||
|
|
||||||
因为使用要使用canal,因此需要在初始化时加上网络配置参数,设置kubernetes的子网为10.244.0.0/16,注意此处不要修改为其他地址,因为这个值与后续的canal的yaml值要一致,如果修改,请一并修改。
|
因为使用要使用 canal,因此需要在初始化时加上网络配置参数,设置 kubernetes 的子网为 10.244.0.0/16,注意此处不要修改为其他地址,因为这个值与后续的 canal 的 yaml 值要一致,如果修改,请一并修改。
|
||||||
|
|
||||||
这个下载镜像的过程涉及翻墙,因为会从gcr的站点下载容器镜像。。。(如果大家翻墙不方便的话,可以用我在上文准备工作中提到的导出的镜像)。
|
这个下载镜像的过程涉及翻墙,因为会从 gcr 的站点下载容器镜像。。。(如果大家翻墙不方便的话,可以用我在上文准备工作中提到的导出的镜像)。
|
||||||
|
|
||||||
如果有能够连接gcr站点的网络,那么整个安装过程非常简单。
|
如果有能够连接 gcr 站点的网络,那么整个安装过程非常简单。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.200
|
# kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.200
|
||||||
[init] Using Kubernetes version: v1.10.1
|
[init] Using Kubernetes version: v1.10.1
|
||||||
[init] Using Authorization modes: [Node RBAC]
|
[init] Using Authorization modes: [Node RBAC]
|
||||||
[preflight] Running pre-flight checks.
|
[preflight] Running pre-flight checks.
|
||||||
[WARNING FileExisting-crictl]: crictl not found in system path
|
[WARNING FileExisting-crictl]: crictl not found in system path
|
||||||
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
|
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
|
||||||
[preflight] Starting the kubelet service
|
[preflight] Starting the kubelet service
|
||||||
[certificates] Generated ca certificate and key.
|
[certificates] Generated ca certificate and key.
|
||||||
|
@ -155,7 +173,7 @@ Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
|
||||||
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
|
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests".
|
||||||
[init] This might take a minute or longer if the control plane images have to be pulled.
|
[init] This might take a minute or longer if the control plane images have to be pulled.
|
||||||
[apiclient] All control plane components are healthy after 28.003828 seconds
|
[apiclient] All control plane components are healthy after 28.003828 seconds
|
||||||
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
|
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
|
||||||
[markmaster] Will mark node ubuntu-master as master by adding a label and a taint
|
[markmaster] Will mark node ubuntu-master as master by adding a label and a taint
|
||||||
[markmaster] Master ubuntu-master tainted and labelled with key/value: node-role.kubernetes.io/master=""
|
[markmaster] Master ubuntu-master tainted and labelled with key/value: node-role.kubernetes.io/master=""
|
||||||
[bootstraptoken] Using token: rw4enn.mvk547juq7qi2b5f
|
[bootstraptoken] Using token: rw4enn.mvk547juq7qi2b5f
|
||||||
|
@ -184,23 +202,24 @@ as root:
|
||||||
kubeadm join 192.168.0.200:6443 --token rw4enn.mvk547juq7qi2b5f --discovery-token-ca-cert-hash sha256:ba260d5191213382a806a9a7d92c9e6bb09061847c7914b1ac584d0c69471579
|
kubeadm join 192.168.0.200:6443 --token rw4enn.mvk547juq7qi2b5f --discovery-token-ca-cert-hash sha256:ba260d5191213382a806a9a7d92c9e6bb09061847c7914b1ac584d0c69471579
|
||||||
```
|
```
|
||||||
|
|
||||||
执行如下命令来配置kubectl。
|
执行如下命令来配置 kubectl。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p $HOME/.kube
|
mkdir -p $HOME/.kube
|
||||||
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||||
```
|
```
|
||||||
这样master的节点就配置好了,并且可以使用kubectl来进行各种操作了,根据上面的提示接着往下做,将slave节点加入到集群。
|
|
||||||
|
|
||||||
### Slave节点加入集群
|
这样 master 的节点就配置好了,并且可以使用 kubectl 来进行各种操作了,根据上面的提示接着往下做,将 slave 节点加入到集群。
|
||||||
|
|
||||||
在slave节点执行如下的命令,将slave节点加入集群,正常的返回信息如下:
|
### Slave 节点加入集群
|
||||||
|
|
||||||
|
在 slave 节点执行如下的命令,将 slave 节点加入集群,正常的返回信息如下:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#kubeadm join 192.168.0.200:6443 --token rw4enn.mvk547juq7qi2b5f --discovery-token-ca-cert-hash sha256:ba260d5191213382a806a9a7d92c9e6bb09061847c7914b1ac584d0c69471579
|
#kubeadm join 192.168.0.200:6443 --token rw4enn.mvk547juq7qi2b5f --discovery-token-ca-cert-hash sha256:ba260d5191213382a806a9a7d92c9e6bb09061847c7914b1ac584d0c69471579
|
||||||
[preflight] Running pre-flight checks.
|
[preflight] Running pre-flight checks.
|
||||||
[WARNING FileExisting-crictl]: crictl not found in system path
|
[WARNING FileExisting-crictl]: crictl not found in system path
|
||||||
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
|
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
|
||||||
[discovery] Trying to connect to API Server "192.168.0.200:6443"
|
[discovery] Trying to connect to API Server "192.168.0.200:6443"
|
||||||
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.0.200:6443"
|
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.0.200:6443"
|
||||||
|
@ -215,6 +234,7 @@ This node has joined the cluster:
|
||||||
|
|
||||||
Run 'kubectl get nodes' on the master to see this node join the cluster.
|
Run 'kubectl get nodes' on the master to see this node join the cluster.
|
||||||
```
|
```
|
||||||
|
|
||||||
等待节点加入完毕。加入中状态。
|
等待节点加入完毕。加入中状态。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -225,7 +245,9 @@ ubuntu-2 NotReady <none> 6m v1.10.1
|
||||||
ubuntu-3 NotReady <none> 6m v1.10.1
|
ubuntu-3 NotReady <none> 6m v1.10.1
|
||||||
ubuntu-master NotReady master 10m v1.10.1
|
ubuntu-master NotReady master 10m v1.10.1
|
||||||
```
|
```
|
||||||
在master节点查看信息如下状态为节点加入完毕。
|
|
||||||
|
在 master 节点查看信息如下状态为节点加入完毕。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
root@Ubuntu-master:~# kubectl get pod -n kube-system -o wide
|
root@Ubuntu-master:~# kubectl get pod -n kube-system -o wide
|
||||||
NAME READY STATUS RESTARTS AGE IP NODE
|
NAME READY STATUS RESTARTS AGE IP NODE
|
||||||
|
@ -240,11 +262,11 @@ kube-proxy-rh4lq 1/1 Running 0 18m
|
||||||
kube-scheduler-ubuntu-master 1/1 Running 0 21m 192.168.0.200 ubuntu-master
|
kube-scheduler-ubuntu-master 1/1 Running 0 21m 192.168.0.200 ubuntu-master
|
||||||
```
|
```
|
||||||
|
|
||||||
kubedns组件需要在网络插件完成安装以后会自动安装完成。
|
kubedns 组件需要在网络插件完成安装以后会自动安装完成。
|
||||||
|
|
||||||
## 安装网络插件canal
|
## 安装网络插件 canal
|
||||||
|
|
||||||
从[canal官方文档参考](https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/canal/),如下网址下载2个文件并且安装,其中一个是配置canal的RBAC权限,一个是部署canal的DaemonSet。
|
从 [canal 官方文档参考](https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/canal/),如下网址下载 2 个文件并且安装,其中一个是配置 canal 的 RBAC 权限,一个是部署 canal 的 DaemonSet。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
|
# kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
|
||||||
|
@ -252,9 +274,6 @@ clusterrole.rbac.authorization.k8s.io "calico" created
|
||||||
clusterrole.rbac.authorization.k8s.io "flannel" created
|
clusterrole.rbac.authorization.k8s.io "flannel" created
|
||||||
clusterrolebinding.rbac.authorization.k8s.io "canal-flannel" created
|
clusterrolebinding.rbac.authorization.k8s.io "canal-flannel" created
|
||||||
clusterrolebinding.rbac.authorization.k8s.io "canal-calico" created
|
clusterrolebinding.rbac.authorization.k8s.io "canal-calico" created
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/canal/canal.yaml
|
# kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/canal/canal.yaml
|
||||||
configmap "canal-config" created
|
configmap "canal-config" created
|
||||||
daemonset.extensions "canal" created
|
daemonset.extensions "canal" created
|
||||||
|
@ -267,7 +286,8 @@ customresourcedefinition.apiextensions.k8s.io "networkpolicies.crd.projectcalico
|
||||||
serviceaccount "canal" created
|
serviceaccount "canal" created
|
||||||
```
|
```
|
||||||
|
|
||||||
查看canal的安装状态。
|
查看 canal 的安装状态。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# kubectl get pod -n kube-system -o wide
|
# kubectl get pod -n kube-system -o wide
|
||||||
NAME READY STATUS RESTARTS AGE IP NODE
|
NAME READY STATUS RESTARTS AGE IP NODE
|
||||||
|
@ -286,9 +306,10 @@ kube-proxy-rh4lq 1/1 Running 0 24m
|
||||||
kube-scheduler-ubuntu-master 1/1 Running 0 28m 192.168.0.200 ubuntu-master
|
kube-scheduler-ubuntu-master 1/1 Running 0 28m 192.168.0.200 ubuntu-master
|
||||||
```
|
```
|
||||||
|
|
||||||
可以看到canal和kube-dns都已经运行正常,一个基本功能正常的测试环境就部署完毕了。
|
可以看到 canal 和 kube-dns 都已经运行正常,一个基本功能正常的测试环境就部署完毕了。
|
||||||
|
|
||||||
|
此时查看集群的节点状态,版本为最新的版本 v1.10.1。
|
||||||
|
|
||||||
此时查看集群的节点状态,版本为最新的版本v1.10.1。
|
|
||||||
```bash
|
```bash
|
||||||
# kubectl get node
|
# kubectl get node
|
||||||
NAME STATUS ROLES AGE VERSION
|
NAME STATUS ROLES AGE VERSION
|
||||||
|
@ -298,7 +319,8 @@ ubuntu-3 Ready <none> 27m v1.10.1
|
||||||
ubuntu-master Ready master 31m v1.10.1
|
ubuntu-master Ready master 31m v1.10.1
|
||||||
```
|
```
|
||||||
|
|
||||||
让master也运行pod(默认master不运行pod),这样在测试环境做是可以的,不建议在生产环境如此操作。
|
让 master 也运行 pod(默认 master 不运行 pod), 这样在测试环境做是可以的,不建议在生产环境如此操作。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#kubectl taint nodes --all node-role.kubernetes.io/master-
|
#kubectl taint nodes --all node-role.kubernetes.io/master-
|
||||||
node "ubuntu-master" untainted
|
node "ubuntu-master" untainted
|
||||||
|
@ -306,8 +328,7 @@ taint "node-role.kubernetes.io/master:" not found
|
||||||
taint "node-role.kubernetes.io/master:" not found
|
taint "node-role.kubernetes.io/master:" not found
|
||||||
taint "node-role.kubernetes.io/master:" not found
|
taint "node-role.kubernetes.io/master:" not found
|
||||||
```
|
```
|
||||||
后续如果想要集群其他功能启用,请参考后续文章。
|
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Overview of kubeadm](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/)
|
- [Overview of kubeadm - kubernetest.io](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/)
|
||||||
|
|
|
@ -47,4 +47,4 @@ Kubernetes版本通常支持九个月,在此期间,如果发现严重的错
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Overview of kubeadm](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/)
|
- [Overview of kubeadm - kubernetes.io](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# 安装kubectl命令行工具
|
# 安装 kubectl 命令行工具
|
||||||
|
|
||||||
本文档介绍下载和配置 kubernetes 集群命令行工具 kubelet 的步骤。
|
本文介绍下载和配置 kubernetes 集群命令行工具 kubelet 的步骤。
|
||||||
|
|
||||||
## 下载 kubectl
|
## 下载 kubectl
|
||||||
|
|
||||||
|
@ -39,8 +39,3 @@ kubectl config use-context kubernetes
|
||||||
+ 生成的 kubeconfig 被保存到 `~/.kube/config` 文件;
|
+ 生成的 kubeconfig 被保存到 `~/.kube/config` 文件;
|
||||||
|
|
||||||
**注意:**`~/.kube/config`文件拥有对该集群的最高权限,请妥善保管。
|
**注意:**`~/.kube/config`文件拥有对该集群的最高权限,请妥善保管。
|
||||||
|
|
||||||
## 更多资料
|
|
||||||
|
|
||||||
- [kubectl命令概览](../guide/using-kubectl.md)
|
|
||||||
- [kubectl命令技巧大全](../guide/kubectl-cheatsheet.md)
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
# 安装kubedns插件
|
# 安装 kubedns 插件
|
||||||
|
|
||||||
官方的yaml文件目录:`kubernetes/cluster/addons/dns`。
|
官方的 yaml 文件目录:`kubernetes/cluster/addons/dns`。
|
||||||
|
|
||||||
该插件直接使用kubernetes部署,官方的配置文件中包含以下镜像:
|
该插件直接使用 kubernetes 部署,官方的配置文件中包含以下镜像:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.1
|
gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.1
|
||||||
gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.1
|
gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.1
|
||||||
gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.1
|
gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.1
|
||||||
```
|
```
|
||||||
我clone了上述镜像,上传到我的私有镜像仓库:
|
|
||||||
|
我 clone 了上述镜像,上传到我的私有镜像仓库:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
harbor-001.jimmysong.io/library/k8s-dns-dnsmasq-nanny-amd64:1.14.1
|
harbor-001.jimmysong.io/library/k8s-dns-dnsmasq-nanny-amd64:1.14.1
|
||||||
|
@ -17,9 +18,9 @@ harbor-001.jimmysong.io/library/k8s-dns-kube-dns-amd64:1.14.1
|
||||||
harbor-001.jimmysong.io/library/k8s-dns-sidecar-amd64:1.14.1
|
harbor-001.jimmysong.io/library/k8s-dns-sidecar-amd64:1.14.1
|
||||||
```
|
```
|
||||||
|
|
||||||
以下yaml配置文件中使用的是私有镜像仓库中的镜像。
|
以下 yaml 配置文件中使用的是私有镜像仓库中的镜像。
|
||||||
|
|
||||||
``` ini
|
```ini
|
||||||
kubedns-cm.yaml
|
kubedns-cm.yaml
|
||||||
kubedns-sa.yaml
|
kubedns-sa.yaml
|
||||||
kubedns-controller.yaml
|
kubedns-controller.yaml
|
||||||
|
@ -180,7 +181,6 @@ root@nginx:/# ping kube-dns.kube-system.svc.cluster.local
|
||||||
PING kube-dns.kube-system.svc.cluster.local (10.254.0.2): 56 data bytes
|
PING kube-dns.kube-system.svc.cluster.local (10.254.0.2): 56 data bytes
|
||||||
^C--- kube-dns.kube-system.svc.cluster.local ping statistics ---
|
^C--- kube-dns.kube-system.svc.cluster.local ping statistics ---
|
||||||
6 packets transmitted, 0 packets received, 100% packet loss
|
6 packets transmitted, 0 packets received, 100% packet loss
|
||||||
|
从结果来看,service 名称可以正常解析。
|
||||||
```
|
```
|
||||||
从结果来看,service名称可以正常解析。
|
**注意**:直接 ping ClusterIP 是 ping 不通的,ClusterIP 是根据 **IPtables** 路由到服务的 endpoint 上,只有结合 ClusterIP 加端口才能访问到对应的服务。
|
||||||
|
|
||||||
**注意**:直接ping ClusterIP是ping不通的,ClusterIP是根据**IPtables**路由到服务的endpoint上,只有结合ClusterIP加端口才能访问到对应的服务。
|
|
||||||
|
|
|
@ -1,31 +1,27 @@
|
||||||
# Master节点高可用
|
# Master 节点高可用
|
||||||
作者:[mendickxiao](https://github.com/mendickxiao)
|
经过部署 Kubernetes 集群章节我们已经可以顺利的部署一个集群用于开发和测试,但是要应用到生产就就不得不考虑 master 节点的高可用问题,因为现在我们的 master 节点上的几个服务 `kube-apiserver`、`kube-scheduler` 和 `kube-controller-manager` 都是单点的而且都位于同一个节点上,一旦 master 节点宕机,虽然不应答当前正在运行的应用,将导致 kubernetes 集群无法变更。本文将引导你创建一个高可用的 master 节点。
|
||||||
|
|
||||||
经过部署Kubernetes集群章节我们已经可以顺利的部署一个集群用于开发和测试,但是要应用到生产就就不得不考虑master节点的高可用问题,因为现在我们的master节点上的几个服务`kube-apiserver`、`kube-scheduler`和`kube-controller-manager`都是单点的而且都位于同一个节点上,一旦master节点宕机,虽然不应答当前正在运行的应用,将导致kubernetes集群无法变更。本文将引导你创建一个高可用的master节点。
|
在大神 gzmzj 的 ansible 创建 kubernetes 集群神作中有讲到如何配置多个 Master,但是在实践过程中还是遇到不少坑。需要将坑填上才能工作。 参考[集群规划和基础参数设定](https://github.com/mendickxiao/kubeasz/blob/master/docs/00-集群规划和基础参数设定.md)。
|
||||||
|
|
||||||
在大神gzmzj的ansible创建kubernetes集群神作中有讲到如何配置多个Master,但是在实践过程中还是遇到不少坑。需要将坑填上才能工作。
|
按照神作的描述,实际上是通过 keepalived + haproxy 实现的,其中 keepalived 是提供一个 VIP,通过 VIP 关联所有的 Master 节点;然后 haproxy 提供端口转发功能。由于 VIP 还是存在 Master 的机器上的,默认配置 API Server 的端口是 6443,所以我们需要将另外一个端口关联到这个 VIP 上,一般用 8443。
|
||||||
神作链接地址:[集群规划和基础参数设定](https://github.com/mendickxiao/kubeasz/blob/master/docs/00-%E9%9B%86%E7%BE%A4%E8%A7%84%E5%88%92%E5%92%8C%E5%9F%BA%E7%A1%80%E5%8F%82%E6%95%B0%E8%AE%BE%E5%AE%9A.md)。
|
|
||||||
|
|
||||||
按照神作的描述,实际上是通过keepalived + haproxy实现的,其中keepalived是提供一个VIP,通过VIP关联所有的Master节点;然后haproxy提供端口转发功能。由于VIP还是存在Master的机器上的,默认配置API Server的端口是6443,所以我们需要将另外一个端口关联到这个VIP上,一般用8443。
|
|
||||||
|
|
||||||
![Master HA架构图](../images/master-ha.JPG)
|
![Master HA架构图](../images/master-ha.JPG)
|
||||||
|
|
||||||
|
|
||||||
根据神作的实践,我发现需要在Master手工安装keepalived, haproxy。
|
根据参考文章的实践,我发现需要在Master手工安装keepalived, haproxy。
|
||||||
```bash
|
```bash
|
||||||
yum install keepalived
|
yum install keepalived
|
||||||
yum install haproxy
|
yum install haproxy
|
||||||
```
|
```
|
||||||
|
|
||||||
需要将HAProxy默认的配置文件balance从source修改为`roundrobin`方式。haproxy的配置文件`haproxy.cfg`默认路径是`/etc/haproxy/haproxy.cfg`。另外需要手工创建`/run/haproxy`的目录,否则haproxy会启动失败。
|
需要将 HAProxy 默认的配置文件 balance 从 source 修改为 `roundrobin` 方式。haproxy 的配置文件 `haproxy.cfg` 默认路径是 `/etc/haproxy/haproxy.cfg`。另外需要手工创建 `/run/haproxy` 的目录,否则 haproxy 会启动失败。
|
||||||
|
|
||||||
**注意**
|
**注意**
|
||||||
|
|
||||||
- bind绑定的就是VIP对外的端口号,这里是8443。
|
- bind 绑定的就是 VIP 对外的端口号,这里是 8443。
|
||||||
|
|
||||||
|
- balance 指定的负载均衡方式是 `roundrobin` 方式,默认是 source 方式。在我的测试中,source 方式不工作。
|
||||||
- balance指定的负载均衡方式是`roundrobin`方式,默认是source方式。在我的测试中,source方式不工作。
|
- server 指定的就是实际的 Master 节点地址以及真正工作的端口号,这里是 6443。有多少台 Master 就写多少条记录。
|
||||||
- server指定的就是实际的Master节点地址以及真正工作的端口号,这里是6443。有多少台Master就写多少条记录。
|
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
# haproxy.cfg sample
|
# haproxy.cfg sample
|
||||||
|
@ -55,14 +51,14 @@ listen kube-master
|
||||||
server s2 **Master 2的IP地址**:6443 check inter 10000 fall 2 rise 2 weight 1
|
server s2 **Master 2的IP地址**:6443 check inter 10000 fall 2 rise 2 weight 1
|
||||||
```
|
```
|
||||||
|
|
||||||
修改keepalived的配置文件,配置正确的VIP。keepalived的配置文件`keepalived.conf`的默认路径是`/etc/keepalived/keepalived.conf`
|
修改 keepalived 的配置文件,配置正确的 VIP。keepalived 的配置文件 `keepalived.conf` 的默认路径是 `/etc/keepalived/keepalived.conf`
|
||||||
|
|
||||||
**注意**
|
**注意**
|
||||||
|
|
||||||
- priority决定哪个Master是主,哪个Master是次。数字大的是主,数字小的是次。数字越大优先级越高。
|
- priority 决定哪个 Master 是主,哪个 Master 是次。数字大的是主,数字小的是次。数字越大优先级越高。
|
||||||
- `virtual_router_id`决定当前VIP的路由号,实际上VIP提供了一个虚拟的路由功能,该VIP在同一个子网内必须是唯一。
|
- `virtual_router_id` 决定当前 VIP 的路由号,实际上 VIP 提供了一个虚拟的路由功能,该 VIP 在同一个子网内必须是唯一。
|
||||||
- virtual_ipaddress提供的就是VIP的地址,该地址在子网内必须是空闲未必分配的。
|
- virtual_ipaddress 提供的就是 VIP 的地址,该地址在子网内必须是空闲未必分配的。
|
||||||
- `state` 决定初始化时节点的状态, 建议 `priority` 最高的节点设置为 `MASTER`。
|
- `state` 决定初始化时节点的状态,建议 `priority` 最高的节点设置为 `MASTER`。
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
# keepalived.cfg sample
|
# keepalived.cfg sample
|
||||||
|
@ -73,24 +69,28 @@ global_defs {
|
||||||
|
|
||||||
vrrp_instance VI-kube-master {
|
vrrp_instance VI-kube-master {
|
||||||
state BACKUP
|
state BACKUP
|
||||||
**priority 110**
|
**priority 110**
|
||||||
dont_track_primary
|
dont_track_primary
|
||||||
interface eth0
|
interface eth0
|
||||||
**virtual_router_id 51**
|
**virtual_router_id 51**
|
||||||
advert_int 3
|
advert_int 3
|
||||||
virtual_ipaddress {
|
virtual_ipaddress {
|
||||||
**10.86.13.36**
|
**10.86.13.36**
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
配置好后,那么先启动主Master的keepalived和haproxy。
|
|
||||||
|
配置好后,那么先启动主 Master 的 keepalived 和 haproxy。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl enable keepalived
|
systemctl enable keepalived
|
||||||
systemctl start keepalived
|
systemctl start keepalived
|
||||||
systemctl enable haproxy
|
systemctl enable haproxy
|
||||||
systemctl start haproxy
|
systemctl start haproxy
|
||||||
```
|
```
|
||||||
然后使用ip a s命令查看是否有VIP地址分配。如果看到VIP地址已经成功分配在eth0网卡上,说明keepalived启动成功。
|
|
||||||
|
然后使用 ip a s 命令查看是否有 VIP 地址分配。如果看到 VIP 地址已经成功分配在 eth0 网卡上,说明 keepalived 启动成功。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[root@kube32 ~]# ip a s
|
[root@kube32 ~]# ip a s
|
||||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
|
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
|
||||||
|
@ -103,12 +103,14 @@ systemctl start haproxy
|
||||||
link/ether 00:50:56:a9:d5:be brd ff:ff:ff:ff:ff:ff
|
link/ether 00:50:56:a9:d5:be brd ff:ff:ff:ff:ff:ff
|
||||||
inet 10.86.13.32/23 brd 10.86.13.255 scope global eth0
|
inet 10.86.13.32/23 brd 10.86.13.255 scope global eth0
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
**inet 10.86.13.36/32 scope global eth0**
|
**inet 10.86.13.36/32 scope global eth0**
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
inet6 fe80::250:56ff:fea9:d5be/64 scope link
|
inet6 fe80::250:56ff:fea9:d5be/64 scope link
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
```
|
```
|
||||||
更保险方法还可以通过`systemctl status keepalived -l`看看keepalived的状态
|
|
||||||
|
更保险方法还可以通过 `systemctl status keepalived -l` 看看 keepalived 的状态
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[root@kube32 ~]# systemctl status keepalived -l
|
[root@kube32 ~]# systemctl status keepalived -l
|
||||||
● keepalived.service - LVS and VRRP High Availability Monitor
|
● keepalived.service - LVS and VRRP High Availability Monitor
|
||||||
|
@ -125,7 +127,9 @@ Mar 20 04:51:15 kube32 Keepalived_vrrp[13450]: VRRP_Instance(VI-kube-master) Dro
|
||||||
**Mar 20 04:51:18 kube32 Keepalived_vrrp[13450]: (VI-kube-master): ip address associated with VRID 51 not present in MASTER advert : 10.86.13.36
|
**Mar 20 04:51:18 kube32 Keepalived_vrrp[13450]: (VI-kube-master): ip address associated with VRID 51 not present in MASTER advert : 10.86.13.36
|
||||||
Mar 20 04:51:18 kube32 Keepalived_vrrp[13450]: bogus VRRP packet received on eth0 !!!**
|
Mar 20 04:51:18 kube32 Keepalived_vrrp[13450]: bogus VRRP packet received on eth0 !!!**
|
||||||
```
|
```
|
||||||
然后通过systemctl status haproxy -l看haproxy的状态
|
|
||||||
|
然后通过 systemctl status haproxy -l 看 haproxy 的状态
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[root@kube32 ~]# systemctl status haproxy -l
|
[root@kube32 ~]# systemctl status haproxy -l
|
||||||
● haproxy.service - HAProxy Load Balancer
|
● haproxy.service - HAProxy Load Balancer
|
||||||
|
@ -138,15 +142,17 @@ Mar 20 04:51:18 kube32 Keepalived_vrrp[13450]: bogus VRRP packet received on eth
|
||||||
├─15117 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
|
├─15117 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
|
||||||
└─15118 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
|
└─15118 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds
|
||||||
```
|
```
|
||||||
这个时候通过kubectl version命令,可以获取到kubectl的服务器信息。
|
|
||||||
|
这个时候通过 kubectl version 命令,可以获取到 kubectl 的服务器信息。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[root@kube32 ~]# kubectl version
|
[root@kube32 ~]# kubectl version
|
||||||
**Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommit:"3a1c9449a956b6026f075fa3134ff92f7d55f812", GitTreeState:"clean", BuildDate:"2018-01-03T22:31:01Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
|
**Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommit:"3a1c9449a956b6026f075fa3134ff92f7d55f812", GitTreeState:"clean", BuildDate:"2018-01-03T22:31:01Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
|
||||||
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommit:"3a1c9449a956b6026f075fa3134ff92f7d55f812", GitTreeState:"clean", BuildDate:"2018-01-03T22:18:41Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}**
|
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommit:"3a1c9449a956b6026f075fa3134ff92f7d55f812", GitTreeState:"clean", BuildDate:"2018-01-03T22:18:41Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}**
|
||||||
```
|
```
|
||||||
|
|
||||||
这个时候说明你的keepalived和haproxy都是成功的。这个时候你可以依次将你其他Master节点的keepalived和haproxy启动。
|
这个时候说明你的 keepalived 和 haproxy 都是成功的。这个时候你可以依次将你其他 Master 节点的 keepalived 和 haproxy 启动。 此时,你通过 ip a s 命令去查看其中一台 Master(*非主 Master*)的时候,你看不到 VIP,这个是正常的,因为 VIP 永远只在主 Master 节点上,只有当主 Master 节点挂掉后,才会切换到其他 Master 节点上。
|
||||||
此时,你通过ip a s命令去查看其中一台Master(*非主Master*)的时候,你看不到VIP,这个是正常的,因为VIP永远只在主Master节点上,只有当主Master节点挂掉后,才会切换到其他Master节点上。
|
|
||||||
```bash
|
```bash
|
||||||
[root@kube31 ~]# ip a s
|
[root@kube31 ~]# ip a s
|
||||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
|
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
|
||||||
|
@ -162,6 +168,11 @@ Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.1", GitCommi
|
||||||
inet6 fe80::250:56ff:fea9:723/64 scope link
|
inet6 fe80::250:56ff:fea9:723/64 scope link
|
||||||
valid_lft forever preferred_lft forever
|
valid_lft forever preferred_lft forever
|
||||||
```
|
```
|
||||||
在我的实践过程中,通过大神的脚本快速启动多个Master节点,会导致主Master始终获取不了VIP,当时的报错非常奇怪。后来经过我的研究发现,主Master获取VIP是需要时间的,如果多个Master同时启动,会导致冲突。这个不知道是否算是Keepalived的Bug。但是最稳妥的方式还是先启动一台主Master,等VIP确定后再启动其他Master比较靠谱。
|
|
||||||
|
|
||||||
Kubernetes通过Keepalived + Haproxy实现多个Master的高可用部署,你实际上可以采用其他方式,如外部的负载均衡方式。实际上Kubernetes的多个Master是没有主从的,都可以提供一致性服务。Keepalived + Haproxy实际上就是提供了一个简单的负载均衡方式。
|
在我的实践过程中,通过大神的脚本快速启动多个 Master 节点,会导致主 Master 始终获取不了 VIP,当时的报错非常奇怪。后来经过我的研究发现,主 Master 获取 VIP 是需要时间的,如果多个 Master 同时启动,会导致冲突。这个不知道是否算是 Keepalived 的 Bug。但是最稳妥的方式还是先启动一台主 Master,等 VIP 确定后再启动其他 Master 比较靠谱。
|
||||||
|
|
||||||
|
Kubernetes 通过 Keepalived + Haproxy 实现多个 Master 的高可用部署,你实际上可以采用其他方式,如外部的负载均衡方式。实际上 Kubernetes 的多个 Master 是没有主从的,都可以提供一致性服务。Keepalived + Haproxy 实际上就是提供了一个简单的负载均衡方式。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
注:本文来自 [mendickxiao](https://github.com/mendickxiao) 的贡献。
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# 安装Nginx ingress
|
# 安装Nginx ingress
|
||||||
|
|
||||||
[Nginx ingress](https://github.com/kubernetes/ingress-nginx) 使用ConfigMap来管理Nginx配置,nginx是大家熟知的代理和负载均衡软件,比起[Traefik](https://traefik.io)来说功能更加强大.
|
[Nginx ingress](https://github.com/kubernetes/ingress-nginx) 使用 ConfigMap 来管理 Nginx 配置,nginx 是大家熟知的代理和负载均衡软件,比起 [Traefik](https://traefik.io/) 来说功能更加强大.
|
||||||
|
|
||||||
我们使用[helm](http://helm.sh)来部署,[chart](https://github.com/kubernetes/charts)保存在私有的仓库中,请确保您已经安装和配置好helm,helm安装使用见[使用Helm管理kubernetes应用](helm.md)。
|
我们使用 [helm](http://helm.sh/) 来部署,[chart](https://github.com/kubernetes/charts) 保存在私有的仓库中,请确保您已经安装和配置好 helm,helm 安装使用见[使用 Helm 管理 kubernetes 应用](helm.md)。
|
||||||
|
|
||||||
## 镜像准备
|
## 镜像准备
|
||||||
|
|
||||||
|
@ -164,10 +164,9 @@ curl -v --insecure http://172.20.0.113:30484/
|
||||||
helm delete --purge nginx-ingress
|
helm delete --purge nginx-ingress
|
||||||
```
|
```
|
||||||
|
|
||||||
使用`--purge`参数可以彻底删除release不留下记录,否则下一次部署的时候不能使用重名的release。
|
使用 `--purge` 参数可以彻底删除 release 不留下记录,否则下一次部署的时候不能使用重名的 release。
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Ingress-nginx github](https://github.com/kubernetes/ingress-nginx)
|
- [Ingress-nginx - github.com](https://github.com/kubernetes/ingress-nginx)
|
||||||
- [Nginx chart configuration](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress)
|
- [Nginx chart configuration - github.com](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress)
|
||||||
- [使用Helm管理kubernetes应用](helm.md)
|
|
||||||
|
|
|
@ -405,6 +405,3 @@ Commercial support is available at
|
||||||
|
|
||||||
![nginx欢迎页面](../images/kubernetes-installation-test-nginx.png)
|
![nginx欢迎页面](../images/kubernetes-installation-test-nginx.png)
|
||||||
|
|
||||||
## 参考
|
|
||||||
|
|
||||||
- [Kubelet 的认证授权](../guide/kubelet-authentication-authorization.md)
|
|
||||||
|
|
|
@ -1,79 +1,77 @@
|
||||||
# OpenEBS
|
# OpenEBS
|
||||||
|
|
||||||
[OpenEBS](https://github.com/openebs/openebs)是一款使用Go语言编写的基于容器的块存储开源软件。OpenEBS使得在容器中运行关键性任务和需要数据持久化的负载变得更可靠。
|
[OpenEBS](https://github.com/openebs/openebs) 是一款使用 Go 语言编写的基于容器的块存储开源软件。OpenEBS 使得在容器中运行关键性任务和需要数据持久化的负载变得更可靠。
|
||||||
|
|
||||||
OpenEBS由CloudByte研发,这是一家专业做容器化存储的公司,OpenEBS是其一款开源产品,CloudByte将其在企业级容器存储的经验付诸到该项目中。这个项目的愿景也很简单,就是让需要持久化存储的工作负载中的存储服务能够直接集成在环境中,存储服务可以自动管理,将存储的细节隐藏起来,就像存储系统是另一套基础架构一样。
|
OpenEBS 由 CloudByte 研发,这是一家专业做容器化存储的公司,OpenEBS 是其一款开源产品,CloudByte 将其在企业级容器存储的经验付诸到该项目中。这个项目的愿景也很简单,就是让需要持久化存储的工作负载中的存储服务能够直接集成在环境中,存储服务可以自动管理,将存储的细节隐藏起来,就像存储系统是另一套基础架构一样。
|
||||||
|
|
||||||
我们知道AWS中提供了[EBS](https://amazonaws-china.com/cn/ebs/)(Elastic Block Storage),适用于 Amazon EC2 的持久性块存储,可以满足要求最苛刻的应用程序在功能和性能方面的要求,OpenEBS即其开源实现。
|
我们知道 AWS 中提供了 [EBS](https://amazonaws-china.com/cn/ebs/)(Elastic Block Storage),适用于 Amazon EC2 的持久性块存储,可以满足要求最苛刻的应用程序在功能和性能方面的要求,OpenEBS 即其开源实现。
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
使用OpenEBS,你可以将有持久化数据的容器,像对待其他普通容器一样来对待。OpenEBS本身也是通过容器来部署的,支持Kubernetes、Swarm、Mesos、Rancher编排调度,存储服务可以分派给每个pod、应用程序、集群或者容器级别,包括:
|
使用 OpenEBS,你可以将有持久化数据的容器,像对待其他普通容器一样来对待。OpenEBS 本身也是通过容器来部署的,支持 Kubernetes、Swarm、Mesos、Rancher 编排调度,存储服务可以分派给每个 pod、应用程序、集群或者容器级别,包括:
|
||||||
|
|
||||||
- 跨节点的数据持久化
|
- 跨节点的数据持久化
|
||||||
- 跨可用区和云厂商的数据同步
|
- 跨可用区和云厂商的数据同步
|
||||||
- 使用商业硬件和容器引擎来提供高可扩展的块存储
|
- 使用商业硬件和容器引擎来提供高可扩展的块存储
|
||||||
- 与容器编排引擎集成,开发者的应用程序可以自动的配置OpenEBS
|
- 与容器编排引擎集成,开发者的应用程序可以自动的配置 OpenEBS
|
||||||
- 基于CloudByte在BSD的容器化经验,为用户提供OpenEBS的QoS保证
|
- 基于 CloudByte 在 BSD 的容器化经验,为用户提供 OpenEBS 的 QoS 保证
|
||||||
|
|
||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
OpenEBS存储控制器本身就运行在容器中。OpenEBS Volume由一个或多个以微服务方式运行的容器组成。这种存储控制器功能基于微服务架构——每个卷的数据由其自己的一组容器来提供,而不是由一个统一的同时为多个卷提供控制的,单体(monolithic)存储控制器来提供。这就是OpenEBS与传统存储设备的本质区别。
|
OpenEBS 存储控制器本身就运行在容器中。OpenEBS Volume 由一个或多个以微服务方式运行的容器组成。这种存储控制器功能基于微服务架构 —— 每个卷的数据由其自己的一组容器来提供,而不是由一个统一的同时为多个卷提供控制的,单体(monolithic)存储控制器来提供。这就是 OpenEBS 与传统存储设备的本质区别。
|
||||||
|
|
||||||
OpenEBS的架构可以分为数据平面(Data Plane)和控制平面(Control Plane)两部分:
|
OpenEBS 的架构可以分为数据平面(Data Plane)和控制平面(Control Plane)两部分:
|
||||||
|
|
||||||
- 数据平面:为应用程序提供数据存储
|
- 数据平面:为应用程序提供数据存储
|
||||||
- 控制平面:管理OpenEBS卷容器,这通常会用到容器编排软件的功能
|
- 控制平面:管理 OpenEBS 卷容器,这通常会用到容器编排软件的功能
|
||||||
|
|
||||||
### 数据平面
|
### 数据平面
|
||||||
|
|
||||||
下图是OpenEBS对应在Kubernetes集群上部署的架构图。其中,黄色部分是OpenEBS持久化存储卷,通过Kubernetes的PV来创建,使用iSCSI来实现,数据保存在node节点上或者云中的卷(如EBS、GPD等),这取决于您的集群部署在哪里。OpenEBS的卷完全独立于用户的应用的生命周期来管理,这也是Kuberentes中的PV的基本思路。
|
下图是 OpenEBS 对应在 Kubernetes 集群上部署的架构图。其中,黄色部分是 OpenEBS 持久化存储卷,通过 Kubernetes 的 PV 来创建,使用 iSCSI 来实现,数据保存在 node 节点上或者云中的卷(如 EBS、GPD 等),这取决于您的集群部署在哪里。OpenEBS 的卷完全独立于用户的应用的生命周期来管理,这也是 Kuberentes 中的 PV 的基本思路。
|
||||||
|
|
||||||
![OpenEBS集群数据平面(图片来自https://github.com/openebs/openebs/blob/master/contribute/design/README.md)](../images/OpenEBS-Data-Plane.png)
|
![OpenEBS 集群数据平面(图片来自 https://github.com/openebs/openebs/blob/master/contribute/design/README.md)](../images/OpenEBS-Data-Plane.png)
|
||||||
|
|
||||||
OpenEBS卷为容器提供持久化存储,具有针对系统故障的弹性,更快地访问存储,快照和备份功能。此外,它还提供了监控使用情况和执行QoS策略的机制。
|
OpenEBS 卷为容器提供持久化存储,具有针对系统故障的弹性,更快地访问存储,快照和备份功能。此外,它还提供了监控使用情况和执行 QoS 策略的机制。
|
||||||
|
|
||||||
存储数据的磁盘称为存储后端,可以是主机目录,附加块设备或远程磁盘。每个OpenEBS卷包含一个iSCSI目标容器(在上图中表示为openebs-vol1)和一个或多个副本容器(openebs-vol1-R1和openebs-vol1-R2)。
|
存储数据的磁盘称为存储后端,可以是主机目录,附加块设备或远程磁盘。每个 OpenEBS 卷包含一个 iSCSI 目标容器(在上图中表示为 openebs-vol1)和一个或多个副本容器(openebs-vol1-R1 和 openebs-vol1-R2)。
|
||||||
|
|
||||||
应用程序pod通过iSCSI目标容器访问存储,iSCSI目标容器将数据复制到其所有副本。在发生节点故障时,iSCSI目标容器将从剩余的其中一个在线节点上启动,并通过连接到可用副本容器来提供数据。
|
应用程序 pod 通过 iSCSI 目标容器访问存储,iSCSI 目标容器将数据复制到其所有副本。在发生节点故障时,iSCSI 目标容器将从剩余的其中一个在线节点上启动,并通过连接到可用副本容器来提供数据。
|
||||||
|
|
||||||
**源码**
|
**源码**
|
||||||
|
|
||||||
该部分的实现包括两个容器:
|
该部分的实现包括两个容器:
|
||||||
|
|
||||||
- [openebs/jiva](https://github.com/openebs/jiva):存储控制功能,包括复制逻辑
|
- [openebs/jiva](https://github.com/openebs/jiva):存储控制功能,包括复制逻辑
|
||||||
- [openebs/gotgt](https://github.com/openebs/gotgt):由openebs/jiva使用的iSCSI目标功能
|
- [openebs/gotgt](https://github.com/openebs/gotgt):由 openebs/jiva 使用的 iSCSI 目标功能
|
||||||
|
|
||||||
### 控制平面
|
### 控制平面
|
||||||
|
|
||||||
OpenEBS控制平面又叫做存储编排或maya。目的是为了创建超融合的OpenEBS,将其挂载到如Kubernetes、Swarm、Nomad等容器编排调度引擎上,用来扩展特定的容器编排系统提供的存储功能。
|
OpenEBS 控制平面又叫做存储编排或 maya。目的是为了创建超融合的 OpenEBS,将其挂载到如 Kubernetes、Swarm、Nomad 等容器编排调度引擎上,用来扩展特定的容器编排系统提供的存储功能。
|
||||||
|
|
||||||
![OpenEBS集群的控制平面(图片来自https://github.com/openebs/openebs/blob/master/contribute/design/README.md)](../images/OpenEBS-Control-Plane.png)
|
![OpenEBS 集群的控制平面 (图片来自 https://github.com/openebs/openebs/blob/master/contribute/design/README.md)](../images/OpenEBS-Control-Plane.png)
|
||||||
|
|
||||||
OpenEBS的控制平面也是基于微服务的,它的服务可以分成以下几个部分:
|
OpenEBS 的控制平面也是基于微服务的,它的服务可以分成以下几个部分:
|
||||||
|
|
||||||
- 容器编排插件,用于增加强容器编排框架的功能:
|
- 容器编排插件,用于增加强容器编排框架的功能:
|
||||||
- **Kubernetes动态配置**:[openebs-provisioner](https://github.com/openebs/external-storage/tree/master/openebs)
|
- **Kubernetes 动态配置 **:[openebs-provisioner](https://github.com/openebs/external-storage/tree/master/openebs)
|
||||||
- **Kubernetes-dashboard**:[openebs-dashboard](https://github.com/openebs/dashboard)
|
- **Kubernetes-dashboard**:[openebs-dashboard](https://github.com/openebs/dashboard)
|
||||||
- **扩展的schema**:基于Kubernetes的CRD(自定义资源类型),存储OpenEBS相关的配置数据
|
- **扩展的 schema**:基于 Kubernetes 的 CRD(自定义资源类型),存储 OpenEBS 相关的配置数据
|
||||||
- 集群服务,提供OpenEBS特定的存储智能,如:
|
- 集群服务,提供 OpenEBS 特定的存储智能,如:
|
||||||
- **maya-apiserver**:包含执行卷操作的API,可将请求转换为容器编排系统特定的操作
|
- **maya-apiserver**:包含执行卷操作的 API,可将请求转换为容器编排系统特定的操作
|
||||||
- **maya-mulebot**:使用收集的信息来建议优化的布局和事件处理提示
|
- **maya-mulebot**:使用收集的信息来建议优化的布局和事件处理提示
|
||||||
- **maya-connect**:允许将监控数据上传到`maya-cloud`,以便进一步进行存储访问模式分析
|
- **maya-connect**:允许将监控数据上传到 `maya-cloud`,以便进一步进行存储访问模式分析
|
||||||
- 节点服务,提供OpenEBS特定的随kubelet一起运行的存储智能,如:
|
- 节点服务,提供 OpenEBS 特定的随 kubelet 一起运行的存储智能,如:
|
||||||
- **maya-agent**:包括存储管理功能
|
- **maya-agent**:包括存储管理功能
|
||||||
|
|
||||||
通过使用prometheus、heapster、grafana和jaegar进行上述服务,可以添加监控和跟踪功能。
|
通过使用 Prometheus、Heapster、Grafana 和 Jaegar 进行上述服务,可以添加监控和跟踪功能。
|
||||||
|
|
||||||
**源码**
|
**源码**
|
||||||
|
|
||||||
- [openebs/maya](https://github.com/openebs/maya):所有特定的二进制代码(非插件)都存储在这个仓库中,比如`maya-apiserver`、`maya-agent`、`maya-mulebot`、`maya-connect`、`mayactl`等等。
|
- [openebs/maya](https://github.com/openebs/maya):所有特定的二进制代码(非插件)都存储在这个仓库中,比如 `maya-apiserver`、`maya-agent`、`maya-mulebot`、`maya-connect`、`mayactl` 等等。
|
||||||
- [openebs-dashboard](https://github.com/openebs/dashboard):kubernetes-dashboard项目的分支,扩展了存储功能。
|
- [openebs-dashboard](https://github.com/openebs/dashboard):kubernetes-dashboard 项目的分支,扩展了存储功能。
|
||||||
- [openebs-provisioner](https://github.com/openebs/external-storage/tree/master/openebs):来自Kubernetes孵化器项目的OpenEBS K8s Provisioner。
|
- [openebs-provisioner](https://github.com/openebs/external-storage/tree/master/openebs):来自 Kubernetes 孵化器项目的 OpenEBS Kubernetes Provisioner。
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- https://www.openebs.io/
|
- [OpenEBS 官网 - openebs.io](https://www.openebs.io/)
|
||||||
- https://github.com/openebs/openebs
|
- [Data Scientists adopting tools and solutions that allow them to focus more on Data Science and less on the infrastructure around them - blog.openebs.io](https://blog.openebs.io/data-scientists-adopting-tools-and-solutions-that-allow-them-to-focus-more-on-data-science-and-less-db9654063bd5)
|
||||||
- [Data Scientists adopting tools and solutions that allow them to focus more on Data Science and less on the infrastructure around them](https://blog.openebs.io/data-scientists-adopting-tools-and-solutions-that-allow-them-to-focus-more-on-data-science-and-less-db9654063bd5)
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
# 服务发现与负载均衡
|
# 服务发现与负载均衡
|
||||||
|
|
||||||
Kubernetes在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了Service资源,并通过kube-proxy配合cloud provider来适应不同的应用场景。随着kubernetes用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制。目前,kubernetes中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:
|
Kubernetes 在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了 Service 资源,并通过 kube-proxy 配合 cloud provider 来适应不同的应用场景。随着 kubernetes 用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制。目前,kubernetes 中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:
|
||||||
|
|
||||||
- Service:直接用Service提供cluster内部的负载均衡,并借助cloud provider提供的LB提供外部访问
|
- Service:直接用 Service 提供 cluster 内部的负载均衡,并借助 cloud provider 提供的 LB 提供外部访问
|
||||||
- Ingress Controller:还是用Service提供cluster内部的负载均衡,但是通过自定义LB提供外部访问
|
- Ingress Controller:还是用 Service 提供 cluster 内部的负载均衡,但是通过自定义 LB 提供外部访问
|
||||||
- Service Load Balancer:把load balancer直接跑在容器中,实现Bare Metal的Service Load Balancer
|
- Service Load Balancer:把 load balancer 直接跑在容器中,实现 Bare Metal 的 Service Load Balancer
|
||||||
- Custom Load Balancer:自定义负载均衡,并替代kube-proxy,一般在物理部署Kubernetes时使用,方便接入公司已有的外部服务
|
- Custom Load Balancer:自定义负载均衡,并替代 kube-proxy,一般在物理部署 Kubernetes 时使用,方便接入公司已有的外部服务
|
||||||
|
|
||||||
## Service
|
## Service
|
||||||
|
|
||||||
Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口。借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service通过标签来选取服务后端,一般配合Replication Controller或者Deployment来保证后端容器的正常运行。
|
Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的入口。借助 Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service 通过标签来选取服务后端,一般配合 Replication Controller 或者 Deployment 来保证后端容器的正常运行。
|
||||||
|
|
||||||
Service有三种类型:
|
Service 有三种类型:
|
||||||
|
|
||||||
- ClusterIP:默认类型,自动分配一个仅cluster内部可以访问的虚拟IP
|
- ClusterIP:默认类型,自动分配一个仅 cluster 内部可以访问的虚拟 IP
|
||||||
- NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过`<NodeIP>:NodePort`来访问该服务
|
- NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过`<NodeIP>:NodePort` 来访问该服务
|
||||||
- LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到`<NodeIP>:NodePort`
|
- LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负载均衡器,并将请求转发到`<NodeIP>:NodePort`
|
||||||
|
|
||||||
另外,也可以将已有的服务以Service的形式加入到Kubernetes集群中来,只需要在创建Service的时候不指定Label selector,而是在Service创建好后手动为其添加endpoint。
|
另外,也可以将已有的服务以 Service 的形式加入到 Kubernetes 集群中来,只需要在创建 Service 的时候不指定 Label selector,而是在 Service 创建好后手动为其添加 endpoint。
|
||||||
|
|
||||||
## Ingress Controller
|
## Ingress Controller
|
||||||
|
|
||||||
Service虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制,比如
|
Service 虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制,比如
|
||||||
|
|
||||||
- 对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求kubernetes必须跑在支持的cloud provider上面
|
- 对外访问的时候,NodePort 类型需要在外部搭建额外的负载均衡,而 LoadBalancer 要求 kubernetes 必须跑在支持的 cloud provider 上面
|
||||||
|
|
||||||
Ingress就是为了解决这些限制而引入的新资源,主要用来将服务暴露到cluster外面,并且可以自定义服务的访问策略。比如想要通过负载均衡器实现不同子域名到不同服务的访问:
|
Ingress 就是为了解决这些限制而引入的新资源,主要用来将服务暴露到 cluster 外面,并且可以自定义服务的访问策略。比如想要通过负载均衡器实现不同子域名到不同服务的访问:
|
||||||
|
|
||||||
```
|
```
|
||||||
foo.bar.com --| |-> foo.bar.com s1:80
|
foo.bar.com --| |-> foo.bar.com s1:80
|
||||||
|
@ -33,7 +33,7 @@ foo.bar.com --| |-> foo.bar.com s1:80
|
||||||
bar.foo.com --| |-> bar.foo.com s2:80
|
bar.foo.com --| |-> bar.foo.com s2:80
|
||||||
```
|
```
|
||||||
|
|
||||||
可以这样来定义Ingress:
|
可以这样来定义 Ingress:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
|
@ -56,32 +56,32 @@ spec:
|
||||||
servicePort: 80
|
servicePort: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意:** Ingress本身并不会自动创建负载均衡器,cluster中需要运行一个ingress controller来根据Ingress的定义来管理负载均衡器。目前社区提供了nginx和gce的参考实现。
|
**注意:** Ingress 本身并不会自动创建负载均衡器,cluster 中需要运行一个 ingress controller 来根据 Ingress 的定义来管理负载均衡器。目前社区提供了 nginx 和 gce 的参考实现。
|
||||||
|
|
||||||
## Service Load Balancer
|
## Service Load Balancer
|
||||||
|
|
||||||
在Ingress出现以前,Service Load Balancer是推荐的解决Service局限性的方式。Service Load Balancer将haproxy跑在容器中,并监控service和endpoint的变化,通过容器IP对外提供4层和7层负载均衡服务。
|
在 Ingress 出现以前,Service Load Balancer 是推荐的解决 Service 局限性的方式。Service Load Balancer 将 haproxy 跑在容器中,并监控 service 和 endpoint 的变化,通过容器 IP 对外提供 4 层和 7 层负载均衡服务。
|
||||||
|
|
||||||
社区提供的Service Load Balancer支持四种负载均衡协议:TCP、HTTP、HTTPS和SSL TERMINATION,并支持ACL访问控制。
|
社区提供的 Service Load Balancer 支持四种负载均衡协议:TCP、HTTP、HTTPS 和 SSL TERMINATION,并支持 ACL 访问控制。
|
||||||
|
|
||||||
## Custom Load Balancer
|
## Custom Load Balancer
|
||||||
|
|
||||||
虽然Kubernetes提供了丰富的负载均衡机制,但在实际使用的时候,还是会碰到一些复杂的场景是它不能支持的,比如:
|
虽然 Kubernetes 提供了丰富的负载均衡机制,但在实际使用的时候,还是会碰到一些复杂的场景是它不能支持的,比如:
|
||||||
|
|
||||||
- 接入已有的负载均衡设备
|
- 接入已有的负载均衡设备
|
||||||
- 多租户网络情况下,容器网络和主机网络是隔离的,这样`kube-proxy`就不能正常工作
|
- 多租户网络情况下,容器网络和主机网络是隔离的,这样 `kube-proxy` 就不能正常工作
|
||||||
|
|
||||||
这个时候就可以自定义组件,并代替kube-proxy来做负载均衡。基本的思路是监控kubernetes中service和endpoints的变化,并根据这些变化来配置负载均衡器。比如weave flux、nginx plus、kube2haproxy等。
|
这个时候就可以自定义组件,并代替 kube-proxy 来做负载均衡。基本的思路是监控 kubernetes 中 service 和 endpoints 的变化,并根据这些变化来配置负载均衡器。比如 weave flux、nginx plus、kube2haproxy 等。
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
有几种情况下需要用到没有selector的service。
|
有几种情况下需要用到没有 selector 的 service。
|
||||||
|
|
||||||
- 使用kubernetes集群外部的数据库时
|
- 使用 kubernetes 集群外部的数据库时
|
||||||
- service中用到了其他namespace或kubernetes集群中的service
|
- service 中用到了其他 namespace 或 kubernetes 集群中的 service
|
||||||
- 在kubernetes的工作负载与集群外的后端之间互相迁移
|
- 在 kubernetes 的工作负载与集群外的后端之间互相迁移
|
||||||
|
|
||||||
可以这样定义一个没有selector的service。
|
可以这样定义一个没有 selector 的 service。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -95,7 +95,7 @@ spec:
|
||||||
targetPort: 9376
|
targetPort: 9376
|
||||||
```
|
```
|
||||||
|
|
||||||
定义一个Endpoints来对应该service。
|
定义一个 Endpoints 来对应该 service。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: Endpoints
|
kind: Endpoints
|
||||||
|
@ -109,9 +109,9 @@ subsets:
|
||||||
- port: 9376
|
- port: 9376
|
||||||
```
|
```
|
||||||
|
|
||||||
访问没有selector的service跟访问有selector的service时没有任何区别。
|
访问没有 selector 的 service 跟访问有 selector 的 service 时没有任何区别。
|
||||||
|
|
||||||
使用kubernetes时有一个很常见的需求,就是当数据库部署在kubernetes集群之外的时候,集群内的service如何访问数据库呢?当然你可以直接使用数据库的IP地址和端口号来直接访问,有没有什么优雅的方式呢?你需要用到`ExternalName Service`。
|
使用 kubernetes 时有一个很常见的需求,就是当数据库部署在 kubernetes 集群之外的时候,集群内的 service 如何访问数据库呢?当然你可以直接使用数据库的 IP 地址和端口号来直接访问,有没有什么优雅的方式呢?你需要用到 `ExternalName Service`。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
kind: Service
|
kind: Service
|
||||||
|
@ -126,13 +126,13 @@ spec:
|
||||||
- port: 12345
|
- port: 12345
|
||||||
```
|
```
|
||||||
|
|
||||||
这个例子中,在kubernetes集群内访问`my-service`实际上会重定向到`my.database.example.com:12345`这个地址。
|
这个例子中,在 kubernetes 集群内访问 `my-service` 实际上会重定向到 `my.database.example.com:12345` 这个地址。
|
||||||
|
|
||||||
## 参考资料
|
## 参考资料
|
||||||
|
|
||||||
- https://kubernetes.io/docs/concepts/services-networking/service/
|
- [Service - kubernetes.io](https://kubernetes.io/docs/concepts/services-networking/service/)
|
||||||
- http://kubernetes.io/docs/user-guide/ingress/
|
- [Ingress - kubernetes.io](http://kubernetes.io/docs/user-guide/ingress/)
|
||||||
- https://github.com/kubernetes/contrib/tree/master/service-loadbalancer
|
- [service Loadbalancer - github.com](https://github.com/kubernetes/contrib/tree/master/service-loadbalancer)
|
||||||
- https://www.nginx.com/blog/load-balancing-kubernetes-services-nginx-plus/
|
- [Load Balancing Kubernetes Services with NGINX Plus - nginx.com](https://www.nginx.com/blog/load-balancing-kubernetes-services-nginx-plus/)
|
||||||
- https://github.com/weaveworks/flux
|
- [Flux - github.com](https://github.com/weaveworks/flux)
|
||||||
- https://github.com/AdoHe/kube2haproxy
|
- [kube2haproxy - github.com](https://github.com/adohe-zz/kube2haproxy)
|
||||||
|
|
|
@ -1,28 +1,12 @@
|
||||||
# 安装traefik ingress
|
# 安装 Traefik ingress
|
||||||
|
|
||||||
## Ingress简介
|
[Traefik](https://traefik.io/) 是一款开源的反向代理与负载均衡工具。它最大的优点是能够与常见的微服务系统直接整合,可以实现自动化动态配置。目前支持 Docker, Swarm, Mesos/Marathon, Mesos, Kubernetes, Consul, Etcd, Zookeeper, BoltDB, Rest API 等等后端模型。
|
||||||
|
|
||||||
如果你还不了解,ingress是什么,可以先看下我翻译的Kubernetes官网上ingress的介绍[Kubernetes Ingress解析](https://jimmysong.io/posts/kubernetes-ingress-resource/)。
|
以下配置文件可以在 [../manifests/traefik-ingress/](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/traefik-ingress/) 目录下找到。
|
||||||
|
|
||||||
**理解Ingress**
|
## 创建 ingress-rbac.yaml
|
||||||
|
|
||||||
简单的说,ingress就是从kubernetes集群外访问集群的入口,将用户的URL请求转发到不同的service上。Ingress相当于nginx、apache等负载均衡方向代理服务器,其中还包括规则定义,即URL的路由信息,路由信息得的刷新由[Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers)来提供。
|
将用于 service account 验证。
|
||||||
|
|
||||||
**理解Ingress Controller**
|
|
||||||
|
|
||||||
Ingress Controller 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用。
|
|
||||||
|
|
||||||
## 部署Traefik
|
|
||||||
|
|
||||||
**介绍traefik**
|
|
||||||
|
|
||||||
[Traefik](https://traefik.io/)是一款开源的反向代理与负载均衡工具。它最大的优点是能够与常见的微服务系统直接整合,可以实现自动化动态配置。目前支持Docker, Swarm, Mesos/Marathon, Mesos, Kubernetes, Consul, Etcd, Zookeeper, BoltDB, Rest API等等后端模型。
|
|
||||||
|
|
||||||
以下配置文件可以在[kubernetes-handbook](https://github.com/rootsongjc/kubernetes-handbook)GitHub仓库中的[../manifests/traefik-ingress/](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/traefik-ingress/)目录下找到。
|
|
||||||
|
|
||||||
**创建ingress-rbac.yaml**
|
|
||||||
|
|
||||||
将用于service account验证。
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -47,7 +31,9 @@ roleRef:
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
```
|
```
|
||||||
|
|
||||||
**创建名为`traefik-ingress`的ingress**,文件名ingress.yaml
|
## 创建 Ingress
|
||||||
|
|
||||||
|
创建名为 `traefik-ingress` 的 ingress,文件名 ingress.yaml
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
|
@ -73,15 +59,15 @@ spec:
|
||||||
servicePort: 80
|
servicePort: 80
|
||||||
```
|
```
|
||||||
|
|
||||||
这其中的`backend`中要配置default namespace中启动的service名字,如果你没有配置namespace名字,默认使用default namespace,如果你在其他namespace中创建服务想要暴露到kubernetes集群外部,可以创建新的ingress.yaml文件,同时在文件中指定该`namespace`,其他配置与上面的文件格式相同。。`path`就是URL地址后的路径,如traefik.frontend.io/path,service将会接受path这个路径,host最好使用service-name.filed1.filed2.domain-name这种类似主机名称的命名方式,方便区分服务。
|
这其中的 `backend` 中要配置 default namespace 中启动的 service 名字,如果你没有配置 namespace 名字,默认使用 default namespace,如果你在其他 namespace 中创建服务想要暴露到 kubernetes 集群外部,可以创建新的 ingress.yaml 文件,同时在文件中指定该 `namespace`,其他配置与上面的文件格式相同。。`path` 就是 URL 地址后的路径,如 traefik.frontend.io/path,service 将会接受 path 这个路径,host 最好使用 service-name.filed1.filed2.domain-name 这种类似主机名称的命名方式,方便区分服务。
|
||||||
|
|
||||||
根据你自己环境中部署的service的名字和端口自行修改,有新service增加时,修改该文件后可以使用`kubectl replace -f ingress.yaml`来更新。
|
根据你自己环境中部署的 service 的名字和端口自行修改,有新 service 增加时,修改该文件后可以使用 `kubectl replace -f ingress.yaml` 来更新。
|
||||||
|
|
||||||
我们现在集群中已经有两个service了,一个是nginx,另一个是官方的`guestbook`例子。
|
我们现在集群中已经有两个 service 了,一个是 nginx,另一个是官方的 `guestbook` 例子。
|
||||||
|
|
||||||
**创建DaemonSet**
|
## 创建 DaemonSet
|
||||||
|
|
||||||
我们使用DaemonSet类型来部署Traefik,并使用`nodeSelector`来限定Traefik所部署的主机。
|
我们使用 DaemonSet 类型来部署 Traefik,并使用 `nodeSelector` 来限定 Traefik 所部署的主机。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
|
@ -127,7 +113,7 @@ spec:
|
||||||
edgenode: "true"
|
edgenode: "true"
|
||||||
```
|
```
|
||||||
|
|
||||||
**注意**:我们使用了`nodeSelector`选择边缘节点来调度traefik-ingress-lb运行在它上面,所有你需要使用:
|
**注意**:我们使用了 `nodeSelector` 选择边缘节点来调度 traefik-ingress-lb 运行在它上面,所有你需要使用:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
kubectl label nodes 172.20.0.113 edgenode=true
|
kubectl label nodes 172.20.0.113 edgenode=true
|
||||||
|
@ -135,13 +121,13 @@ kubectl label nodes 172.20.0.114 edgenode=true
|
||||||
kubectl label nodes 172.20.0.115 edgenode=true
|
kubectl label nodes 172.20.0.115 edgenode=true
|
||||||
```
|
```
|
||||||
|
|
||||||
给三个node打标签,这样traefik的pod才会调度到这几台主机上,否则会一直处于`pending`状态。
|
给三个 node 打标签,这样 traefik 的 pod 才会调度到这几台主机上,否则会一直处于 `pending` 状态。
|
||||||
|
|
||||||
关于使用Traefik作为边缘节点请参考[边缘节点配置](../practice/edge-node-configuration.md)。
|
关于使用 Traefik 作为边缘节点请参考[边缘节点配置](../practice/edge-node-configuration.md)。
|
||||||
|
|
||||||
**Traefik UI**
|
**Traefik UI**
|
||||||
|
|
||||||
使用下面的yaml配置来创建Traefik的Web UI。
|
使用下面的 yaml 配置来创建 Traefik 的 Web UI。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
@ -173,23 +159,23 @@ spec:
|
||||||
servicePort: web
|
servicePort: web
|
||||||
```
|
```
|
||||||
|
|
||||||
配置完成后就可以启动treafik ingress了。
|
配置完成后就可以启动 treafik ingress 了。
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl create -f .
|
kubectl create -f .
|
||||||
```
|
```
|
||||||
|
|
||||||
我查看到traefik的pod在`172.20.0.115`这台节点上启动了。
|
我查看到 traefik 的 pod 在 `172.20.0.115` 这台节点上启动了。
|
||||||
|
|
||||||
访问该地址`http://172.20.0.115:8580/`将可以看到dashboard。
|
访问该地址 `http://172.20.0.115:8580/` 将可以看到 dashboard。
|
||||||
|
|
||||||
![kubernetes-dashboard](../images/traefik-dashboard.jpg)
|
![Terafik dashboard](../images/traefik-dashboard.jpg)
|
||||||
|
|
||||||
左侧黄色部分部分列出的是所有的rule,右侧绿色部分是所有的backend。
|
左侧黄色部分部分列出的是所有的 rule,右侧绿色部分是所有的 backend。
|
||||||
|
|
||||||
## 测试
|
## 测试
|
||||||
|
|
||||||
在集群的任意一个节点上执行。假如现在我要访问nginx的"/"路径。
|
在集群的任意一个节点上执行。假如现在我要访问 nginx 的 "/" 路径。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ curl -H Host:traefik.nginx.io http://172.20.0.115/
|
$ curl -H Host:traefik.nginx.io http://172.20.0.115/
|
||||||
|
@ -220,7 +206,7 @@ Commercial support is available at
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
如果你需要在kubernetes集群以外访问就需要设置DNS,或者修改本机的hosts文件。
|
如果你需要在 kubernetes 集群以外访问就需要设置 DNS,或者修改本机的 hosts 文件。
|
||||||
|
|
||||||
在其中加入:
|
在其中加入:
|
||||||
|
|
||||||
|
@ -229,19 +215,14 @@ Commercial support is available at
|
||||||
172.20.0.115 traefik.frontend.io
|
172.20.0.115 traefik.frontend.io
|
||||||
```
|
```
|
||||||
|
|
||||||
所有访问这些地址的流量都会发送给172.20.0.115这台主机,就是我们启动traefik的主机。
|
所有访问这些地址的流量都会发送给 172.20.0.115 这台主机,就是我们启动 traefik 的主机。
|
||||||
|
|
||||||
Traefik会解析http请求header里的Host参数将流量转发给Ingress配置里的相应service。
|
Traefik 会解析 http 请求 header 里的 Host 参数将流量转发给 Ingress 配置里的相应 service。
|
||||||
|
|
||||||
修改hosts后就就可以在kubernetes集群外访问以上两个service,如下图:
|
修改 hosts 后就就可以在 kubernetes 集群外访问以上两个 service,如下图:
|
||||||
|
|
||||||
![traefik-nginx](../images/traefik-nginx.jpg)
|
![Nginx 页面](../images/traefik-nginx.jpg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
![traefik-guestbook](../images/traefik-guestbook.jpg)
|
![Guestbook 页面](../images/traefik-guestbook.jpg)
|
||||||
|
|
||||||
|
|
||||||
## 参考
|
|
||||||
|
|
||||||
- [Traefik简介](http://www.tuicool.com/articles/ZnuEfay)
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
Condiut与[Linkerd](https://linkerd.io)的设计方式不同,它跟[Istio](https://istio.io)一样使用的是Sidecar模式,但架构又没Istio那么复杂。Conduit只支持Kubernetes,且只支持HTTP2(包括gRPC)协议。
|
Condiut与[Linkerd](https://linkerd.io)的设计方式不同,它跟[Istio](https://istio.io)一样使用的是Sidecar模式,但架构又没Istio那么复杂。Conduit只支持Kubernetes,且只支持HTTP2(包括gRPC)协议。
|
||||||
|
|
||||||
Conduit使用Rust和Go语言开发,GitHub地址https://github.com/runconduit/conduit
|
Conduit使用Rust和Go语言开发,GitHub地址 https://github.com/runconduit/conduit
|
||||||
|
|
||||||
安装Conduit必须使用Kubernetes1.8以上版本。
|
安装Conduit必须使用Kubernetes1.8以上版本。
|
||||||
|
|
||||||
|
@ -14,5 +14,3 @@ Conduit使用Rust和Go语言开发,GitHub地址https://github.com/runconduit/c
|
||||||
|
|
||||||
- Conduit GitHub:https://github.com/runconduit/conduit
|
- Conduit GitHub:https://github.com/runconduit/conduit
|
||||||
- 关于Conduit的更多资源请参考官方网站:https://conduit.io/
|
- 关于Conduit的更多资源请参考官方网站:https://conduit.io/
|
||||||
- Conduit的官方文档中文版:https://github.com/doczhcn/conduit
|
|
||||||
- 关于Service Mesh的更多内容请访问ServiceMesher:http://www.servicemesher.com
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# Envoy
|
# Envoy
|
||||||
|
|
||||||
[Envoy](https://github.com/envoyproxy/envoy) 是一款由 Lyft 开源的,使用 C++ 编写的 L7 代理和通信总线,目前是 [CNCF](https://cncf.io) 旗下的开源项目且已经毕业,代码托管在 GitHub 上,它也是 [Istio](https://istio.io) service mesh 中默认的 data plane。
|
[Envoy](https://github.com/envoyproxy/envoy) 是一款由 Lyft 开源的,使用 C++ 编写的 L7 代理和通信总线,目前是 [CNCF](https://cncf.io) 旗下的开源项目且已经毕业,代码托管在 GitHub 上,它也是 [Istio](https://istio.io) service mesh 中默认的 data plane。关于 Envoy 的详情请阅读 [Envoy 中文文档](https://cloudnative.to/envoy/).
|
||||||
|
|
||||||
ServiceMesher 共同联合翻译了 [Envoy 最新版本的官方文档](https://www.envoyproxy.io/docs/envoy/latest/),翻译的代码托管在 <https://github.com/servicemesher/envoy>,Envoy 官方文档中文版地址:<https://www.servicemesher.com/envoy/>。
|
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
|
@ -36,6 +34,5 @@ Matt Klein 是在他的文章中指出 sidecar 模式的 proxy 将取代另外
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- [Introduction to modern network load balancing and proxying](https://blog.envoyproxy.io/introduction-to-modern-network-load-balancing-and-proxying-a57f6ff80236)
|
- [Introduction to modern network load balancing and proxying - blog.envoyproxy.io](https://blog.envoyproxy.io/introduction-to-modern-network-load-balancing-and-proxying-a57f6ff80236)
|
||||||
- 更多信息请参考 [Envoy 官网](https://www.envoyproxy.io/)
|
- [Envoy 官方文档中文版 - cloudnative.to](https://cloudnative.to/envoy/)
|
||||||
- [Envoy官方文档中文版](https://www.servicemesher.com/envoy/)
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
### 使用 Sidecar 模式的优势
|
### 使用 Sidecar 模式的优势
|
||||||
|
|
||||||
使用 sidecar 模式部署服务网格时,无需在节点上运行代理,但是集群中将运行多个相同的 sidecar 副本。在 sidecar 部署方式中,每个应用的容器旁都会部署一个伴生容器(如 [Envoy](https://www.servicemesher.com/istio-handbook/GLOSSARY.html#envoy) 或 [MOSN](https://www.servicemesher.com/istio-handbook/GLOSSARY.html#mosn)),这个容器称之为 sidecar 容器。Sidecar 接管进出应用容器的所有流量。在 Kubernetes 的 Pod 中,在原有的应用容器旁边注入一个 Sidecar 容器,两个容器共享存储、网络等资源,可以广义的将这个包含了 sidecar 容器的 Pod 理解为一台主机,两个容器共享主机资源。
|
使用 sidecar 模式部署服务网格时,无需在节点上运行代理,但是集群中将运行多个相同的 sidecar 副本。在 sidecar 部署方式中,每个应用的容器旁都会部署一个伴生容器,这个容器称之为 sidecar 容器。Sidecar 接管进出应用容器的所有流量。在 Kubernetes 的 Pod 中,在原有的应用容器旁边注入一个 Sidecar 容器,两个容器共享存储、网络等资源,可以广义的将这个包含了 sidecar 容器的 Pod 理解为一台主机,两个容器共享主机资源。
|
||||||
|
|
||||||
因其独特的部署结构,使得 sidecar 模式具有以下优势:
|
因其独特的部署结构,使得 sidecar 模式具有以下优势:
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ $ istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml
|
||||||
Istio 给应用 Pod 注入的配置主要包括:
|
Istio 给应用 Pod 注入的配置主要包括:
|
||||||
|
|
||||||
- Init 容器 `istio-init`:用于 pod 中设置 iptables 端口转发
|
- Init 容器 `istio-init`:用于 pod 中设置 iptables 端口转发
|
||||||
- Sidecar 容器 `istio-proxy`:运行 sidecar 代理,如 [Envoy](https://www.servicemesher.com/istio-handbook/GLOSSARY.html#envoy) 或 [MOSN](https://www.servicemesher.com/istio-handbook/GLOSSARY.html#mosn)
|
- Sidecar 容器 `istio-proxy`:运行 sidecar 代理
|
||||||
|
|
||||||
接下来将分别解析下这两个容器。
|
接下来将分别解析下这两个容器。
|
||||||
|
|
||||||
|
@ -639,7 +639,7 @@ Inbound handler 的流量被 `virtualInbound` Listener 转移到 `172.17.0.15_90
|
||||||
|
|
||||||
我们看其中的 `filterChains.filters` 中的 `envoy.http_connection_manager` 配置部分,该配置表示流量将转交给Cluster`inbound|9080|http|reviews.default.svc.cluster.local` 处理。
|
我们看其中的 `filterChains.filters` 中的 `envoy.http_connection_manager` 配置部分,该配置表示流量将转交给Cluster`inbound|9080|http|reviews.default.svc.cluster.local` 处理。
|
||||||
|
|
||||||
**[Cluster](https://www.servicemesher.com/istio-handbook/GLOSSARY.html#cluster) `inbound|9080|http|reviews.default.svc.cluster.local`**
|
**Cluster `inbound|9080|http|reviews.default.svc.cluster.local`**
|
||||||
|
|
||||||
运行 `istioctl proxy-config cluster reviews-v1-54b8794ddf-jxksn --fqdn reviews.default.svc.cluster.local --direction inbound -o json` 查看该Cluster的配置如下。
|
运行 `istioctl proxy-config cluster reviews-v1-54b8794ddf-jxksn --fqdn reviews.default.svc.cluster.local --direction inbound -o json` 查看该Cluster的配置如下。
|
||||||
|
|
||||||
|
@ -789,7 +789,7 @@ Endpoint 可以是一个或多个,sidecar 将根据一定规则选择适当的
|
||||||
|
|
||||||
本文使用了 Istio 官方提供的 bookinfo 示例,按图索骥得带领读者了解了 sidecar 注入、iptables 透明流量劫持及 sidecar 中流量路由背后的实现细节。Sidecar 模式和流量透明劫持是 Istio 服务网格的特色和基础功能,理解该功能的背后过程及实现细节,将有助于大家理解 Service Mesh 的原理和 [Istio Handbook](https://www.servicemesher.com/istio-handbook/) 后面章节中的内容,因此希望读者可以在自己的环境中从头来试验一遍以加深理解。
|
本文使用了 Istio 官方提供的 bookinfo 示例,按图索骥得带领读者了解了 sidecar 注入、iptables 透明流量劫持及 sidecar 中流量路由背后的实现细节。Sidecar 模式和流量透明劫持是 Istio 服务网格的特色和基础功能,理解该功能的背后过程及实现细节,将有助于大家理解 Service Mesh 的原理和 [Istio Handbook](https://www.servicemesher.com/istio-handbook/) 后面章节中的内容,因此希望读者可以在自己的环境中从头来试验一遍以加深理解。
|
||||||
|
|
||||||
使用 iptables 做流量劫持只是 service mesh 的数据平面中做流量劫持的方式之一,还有更多的流量劫持方案,下面引用自 [云原生网络代理 MOSN 官网中给出的流量劫持](https://mosn.io/zh/docs/concept/traffic-hijack/)部分的描述。
|
使用 iptables 做流量劫持只是 service mesh 的数据平面中做流量劫持的方式之一,还有更多的流量劫持方案,下面引用自 [云原生网络代理 MOSN 官网中给出的流量劫持](https://mosn.io/docs/concept/traffic-hijack/)部分的描述。
|
||||||
|
|
||||||
### 使用 iptables 做流量劫持时存在的问题
|
### 使用 iptables 做流量劫持时存在的问题
|
||||||
|
|
||||||
|
@ -821,4 +821,4 @@ tproxy 可以用于 inbound 流量的重定向,且无需改变报文中的目
|
||||||
|
|
||||||
- [Debugging Envoy and Istiod - istio.io](https://istio.io/docs/ops/diagnostic-tools/proxy-cmd/)
|
- [Debugging Envoy and Istiod - istio.io](https://istio.io/docs/ops/diagnostic-tools/proxy-cmd/)
|
||||||
- [揭开 Istio Sidecar 注入模型的神秘面纱 - istio.io](https://istio.io/zh/blog/2019/data-plane-setup/)
|
- [揭开 Istio Sidecar 注入模型的神秘面纱 - istio.io](https://istio.io/zh/blog/2019/data-plane-setup/)
|
||||||
- [MOSN 作为 Sidecar 使用时的流量劫持方案 - mosn.io](https://mosn.io/zh/docs/concept/traffic-hijack/)
|
- [MOSN 作为 Sidecar 使用时的流量劫持方案 - mosn.io](https://mosn.io/docs/concept/traffic-hijack/)
|
Loading…
Reference in New Issue