2019-012-K8s 实战之概念、部署、服务配置

K8s 实战之概念、集群部署与服务配置
本文是对于
Kubernetes [koo-ber-nay’
设计理念
与一般的

-
基础设施层:包括容器运行时、网络、存储等。
-
核心层:
Kubernetes 最核心的功能,对外提供API 构建高层的应用,对内提供插件式应用执行环境。 -
应用层:部署(无状态、有状态应用、
Job 等)和路由(服务发现、负载均衡等) -
管理层:系统度量(如基础设施、容器和网络的度量
) ,自动化(如自动扩展、动态Provision 等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy 等) -
接口层:
kubectl 命令行工具、客户端SDK 以及集群联邦 -
生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴:日志、监控、配置管理、CI、CD、Workflow、FaaS、
OTS 应用、ChatOps 等外部生态以及CRI 、CNI、CSI、镜像仓库、Cloud Provider、集群自身的配置和管理等内部生态。
相对于命令式操作,声明式操作会更稳定且更容易被用户接受,因为该
组件与对象

类别 | 名称 |
---|---|
资源对象 | Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition |
存储对象 | Volume、PersistentVolume、Secret、ConfigMap |
策略对象 | SecurityContext、ResourceQuota、LimitRange |
身份对象 | ServiceAccount、Role、ClusterRole |
这里我们选择几个关键对象进行介绍。
部署(Deployment)
部署表示用户对
服务(Service)
RC、
一个
-
ClusterIP:默认类型,自动分配一个仅
Cluster 内部可以访问的虚拟IP 。 -
NodePort:在
ClusterIP 基础上为Service 在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort
来访问该服务。 -
LoadBalancer:在
NodePort 的基础上,借助Cloud Provider 创建一个外部的负载均衡器,并将请求转发到<NodeIP>:NodePort
。
在
集群部署
$ docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher

先在

我们需要将脚本复制到对应的机器上运行,然后
Helm

在
$ sudo snap install helm --classic
# 通过键入如下命令,在 Kubernetes 群集上安装 Tiller
$ helm init --upgrade
在缺省配置下,
$ helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.5.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
# 删除默认的源
$ helm repo remove stable
# 增加新的国内镜像源
$ helm repo add stable https://burdenbear.github.io/kube-charts-mirror/
$ helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
# 查看 Helm 源添加情况
$ helm repo list
# 查看在存储库中可用的所有 Helm Charts
$ helm search
# 更新 Charts 列表以获取最新版本
$ helm repo update
# 查看某个 Chart 的变量
$ helm inspect values stable/mysql
# 查看在群集上安装的 Charts 列表
$ helm list
# 删除某个 Charts 的部署
$ helm del --purge wordpress-test
# 为 Tiller 部署添加授权
$ kubectl create serviceaccount --namespace kube-system tiller
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
kubectl
信息检索
$ kubectl get [(-o|--output=)json|yaml|wide|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags] [flags]
运行与管理
$ kubectl run sonarqube --image=sonarqube:5.6.5 --replicas=1 --port=9000
deployment "sonarqube" created
# 该命令为我们创建了一个 Deployment
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
sonarqube 1 1 1 1 5m
我们也可以直接以交互方式运行某个镜像:
$ kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
sonarqube-1880671902-s3fdq 1/1 Running 0 6m
$ 交互式运行 Pod 中的某个命令
$ kubectl exec -it sonarqube-1880671902-s3fdq -- /bin/bash
$ kubectl delete pods sonarqube-1880671902-s3fdq
$ kubectl delete deployment sonarqube
# 创建
$ kubectl create -f yamls/mysql.yaml
# 删除
$ kubectl delete -f yamls/mysql.yaml
# 同时创建多个
$ kubectl create -f yamls/
# 同时删除多个
$ kubectl delete -f yamls/
上下文切换
在
mkdir $HOME/.kube
scp root@<master-public-ip>:/etc/kubernetes/kube.conf $HOME/.kube/config
然后可以来查看当前的上下文
$ unset KUBECONFIG
$ kubectl config current-context # 查看当前载入的上下文
$ kubectl config get-contexts # 浏览可用的上下文
$ kubectl config use-context context-name # 切换到指定上下文
服务配置
Deployment & Service
在 K8s Boilerplates 中我们定义了简单的
# nginx-deployment-service.yaml
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: nginx
replicas: 3 # tells deployment to run 1 pods matching the template
template: # create pods using pod definition in this template
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
externalTrafficPolicy: Local
ports:
- name: http
port: 80
selector:
app: nginx
type: NodePort
$ kubectl create -f https://raw.githubusercontent.com/wx-chevalier/Backend-Boilerplates/master/K8s/Base/nginx-deployment-service.yaml
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-56db997f77-2q6qz 1/1 Running 0 3m21s
nginx-56db997f77-fv2zs 1/1 Running 0 3m21s
nginx-56db997f77-wx2q5 1/1 Running 0 3m21s
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 3m36s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 21h
nginx NodePort 10.43.8.50 <none> 80:32356/TCP 4m5s

Ingress
目前可用的
Helm 安装Ingress
$ helm install --name nginx-ingress --set "rbac.create=true,controller.service.externalIPs[0]=172.19.157.1,controller.service.externalIPs[1]=172.19.157.2,controller.service.$
xternalIPs[2]=172.19.157.3" stable/nginx-ingress
NAME: nginx-ingress
LAST DEPLOYED: Tue Aug 20 14:50:13 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
nginx-ingress-controller 1 0s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5f874f7bf4-nvsvv 0/1 ContainerCreating 0 0s
nginx-ingress-default-backend-6f598d9c4c-vj4v8 0/1 ContainerCreating 0 0s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-controller LoadBalancer 10.43.115.59 172.19.157.1,172.19.157.2,172.19.157.3 80:32122/TCP,443:32312/TCP 0s
nginx-ingress-default-backend ClusterIP 10.43.8.65 <none> 80/TCP 0s
==> v1/ServiceAccount
NAME SECRETS AGE
nginx-ingress 1 0s
==> v1beta1/ClusterRole
NAME AGE
nginx-ingress 0s
==> v1beta1/ClusterRoleBinding
NAME AGE
nginx-ingress 0s
==> v1beta1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-ingress-controller 0/1 1 0 0s
nginx-ingress-default-backend 0/1 1 0 0s
==> v1beta1/PodDisruptionBudget
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
nginx-ingress-controller 1 N/A 0 0s
nginx-ingress-default-backend 1 N/A 0 0s
部署完成后我们可以看到
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 20h
nginx-ingress-controller LoadBalancer 10.43.115.59 172.19.157.1,172.19.157.2,172.19.157.3 80:32122/TCP,443:32312/TCP 77m
nginx-ingress-default-backend ClusterIP 10.43.8.65 <none> 80/TCP 77m
$ kubectl --namespace default get services -o wide -w nginx-ingress-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-ingress-controller LoadBalancer 10.43.115.59 172.19.157.1,172.19.157.2,172.19.157.3 80:32122/TCP,443:32312/TCP 77m app=nginx-ingress,component=controller,release=nginx-ingress
由于我们采用了
$ curl 127.0.0.1/
# default backend - 404
$ curl 127.0.0.1/healthz/
# 返回的是 200
后续我们如果需要创建自身的
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: example
namespace: foo
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
serviceName: exampleService
servicePort: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
如果希望使用
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
WordPress
$ helm install --name wordpress-test --set "ingress.enabled=true,persistence.enabled=false,mariadb.persistence.enabled=false" stable/wordpress
NAME: wordpress-test
...
这里我们使用
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
wordpress.local-wordpress-test wordpress.local 172.19.157.1,172.19.157.2,172.19.157.3 80 59m
$ curl -I http://wordpress.local -x 127.0.0.1:80
HTTP/1.1 200 OK
Server: nginx/1.15.6
Date: Tue, 20 Aug 2019 07:55:21 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/7.0.27
Link: <http://wordpress.local/wp-json/>; rel="https://api.w.org/"
也可以根据
echo Username: user
echo Password: $(kubectl get secret --namespace default wordpress-test-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode)
==> v1beta1/Role
NAME AGE
nginx-ingress 0s
==> v1beta1/RoleBinding
NAME AGE
nginx-ingress 0s
延伸阅读
某熊的技术之路指北 ☯ 就是对笔者不同领域方面沉淀下的知识仓库的导航与索引,便于读者快速地寻找到自己需要的内容。路漫漫其修远兮,吾正上下而求索,也希望能给所有遇见过笔者痕迹的同学些许帮助,在浩瀚银河间能顺利达到一个又一个彼岸。

您还可以前往 NGTE Books 主页浏览包含知识体系、编程语言、软件工程、模式与架构、
