软件开发架构师

京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ

大数据 130 2019-11-09 01:11

随着 Docker 技术的发展和广泛流行,云原生应用和容器调度管理系统爆之也成为 IT 领域大热的词汇。事实上,云原生应用的思想,在 Docker 技术火前,已经由云计算技术的领导者和分布式系统架构的推广者广泛传播,例如云原生应用的 12 要素早在 2011 年就由 Heroku 的工程师提出了;只不过以虚拟机技术作为云原生应用的基础实施,由于虚拟机镜像大、镜像标准不统一以及打包流程和工具不统一,无法业界广泛接受的云原生应用标准,限制了云原生应用的流行。而 Docker 的出现正好解决了这些限制云原生应用构建、交付和运行的瓶颈,使得构建云原生应用成为了使用 Docker 的开发者自然而然的选择。

单机的 Docker 引擎和单一的容器镜像只能解决单一服务的打包和测试问题。而要运行生产级的企业级应用,就需要容器调度管理系统。在这里面,Docker 技术就仿佛运送系统零件的集装箱,把云原生应用的各个标准化零件交付到各个企业的不同码头,而容器调度管理系统就是企业应用的运行车间,把不同的零件组装、运行、维护起来。

1. 京东云 Kubernetes 介绍

Kubernetes 是为生产环境而设计的容器调度管理系统,对于负载均衡、服务发现、高可用、滚动升级、自动伸缩等容器云平台的功能要求有原生支持。由于 Kubernetes 在 K 和 s 间有 8 个字母,因此常简称 K8s。

事实上,随着对 K8s 系统架构与设计理念的了解深入,我们会发现 K8s 系统正是处处为运行云原生应用而设计考虑;同时,随着对 K8s 系统使用的加深和加广,也会有越来越多有关云原生应用的设计模式产生出来,使得基于 K8s 系统设计和开发生产级的复杂云原生应用变得像启动一个单机版容器服务那样简单易用。

根据 CNCF 在 2018 年 8 月进行的第六次测量容器管理市场的温度,83% 的受访者更喜欢 Kubernetes 的容器管理工具,58%的受访者在生产中使用 Kubernetes,42%的受访者正在进行评估以备将来使用,40%的企业(员工规模在 5000+)正在使用 Kubernetes。Kubernetes 在开发人员中已经变得非常流行。

京东云 Kubernetes 集群采用管理节点全托管的方式,为用户提供简单易用、高可靠、功能强大的容器管理服务。该产品完全兼容标准 Kubernetes API ,集成京东云网络、存储等插件。Kubernetes 集群服务简化了 Kubernetes 部署、管理,降低了 Kubernetes 使用门槛,增强应用的可靠性,提升开发的效率,减少资源投入成本。

1.1 产品优势

相较于传统自建 Kubernetes 集群,京东云 Kubernetes 集群服务有如下优势:

  • 易用性:在控制台一键式创建 Kubernetes 集群服务;管理节点采用全托管的方式,免除繁琐的部署、运维、升级等工作;提供工作节点定制镜像,预置集群工作节点所需的各种组件。
  • 可靠性:同地域下,集群的管理、工作节点可跨可用区部署,支持单集群至少运行三台云主机作为管理节点,同时基于京东云高可用组隔离故障域,进一步增强了可靠性。
  • 功能性:基于京东云 SDN 网络,提供 CNI 网络插件,依托京东云私有网络的高可用及可靠性,轻松适应不同规模生产环境的网络需求;提供 CRI 存储插件,集成京东云云硬盘,提供安全可靠的持久化存储;集成京东云负载均衡服务,提供安全、可靠的网络访问。
  • 性价比:京东云 Kubernetes 集群服务本身暂时免费,目前您只需为集群中创建的云主机、公网 IP、云硬盘等云资源按需付费。

1.2 京东云 Kubernetes 部署架构

京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-1

k8s 培训
下面会演示京东云 Kubernetes 集成京东云镜像仓库,构建原生 dashboard 的最佳实践,希望能起到抛砖引玉的作用。

2. 环境准备

2.1 创建 AK、SK

登陆京东云控制台后,点击账号下拉菜单,选择 Access Key 管理。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-2

点击创建,并输入相关手机号码。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-3

至此 AK、SK 创建成功。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-4

2.2 容器镜像仓库准备

选择容器镜像仓库:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-5

镜像仓库模板为:registry-URL/repository:tag,所以我们创建顺序为:

1. 创建注册表
2. 创建仓库

2.2.1 创建注册表

点击创建按钮,后输入注册表名称,本例中的名称为:pocexam.
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-6

2.2.2 创建镜像仓库

由于 Kubernetes 官方 dashboard 镜像 kubernetes-dashboard-amd64 为国外资源,国内无法 pull,所以我们需要先从 Google 镜像仓库 push 到本地后再上传到镜像仓库。

此处创建镜像仓库时的名称为:kubernetes-dashboard-amd64。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-7

2.2.3 上传 Kubernetes-dashboard 镜像

此处需要创建一台 Linux 云主机(建议使用 Ubuntu 镜像),并安装 Docker。此处不再赘述。通过 ssh 工具连接,执行如下命令安装 Docker 工具:

复制代码
1apt- get install -y docker.io

由于国内网络原因,Google 官方镜像 k8s.gcr .io/kubernetes-dashboard-amd64:v1.10.1 无法 pull,所以我们需要从 docker.io 仓库的 Google 容器镜像进行拉取:

复制代码
1docker pull mirrorgooglecontainers/kubernetes-dashboard-amd64:v1 .10 .1

然后执行 docker images 会看到拉取到的镜像。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-8

上传至京东云镜像仓库之前,需要有上传权限,可以通过临时令牌的方式登录并上传镜像。
获取临时令牌方法为:京东云控制台–> 容器镜像仓库–> 注册表,选择之前创建的 registry,右侧点击获取临时令牌:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-9

设置有效期:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-10

确认后,可以获得多种格式的登陆方式,本次操作使用Docker 客户端登录命令,点击复制按钮,并在 Linux 云主机中执行。

需要注意:完全复制粘贴到 Linux shell 命令中即可,无需修改任何参数。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-11

京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-12

将 k8s .gcr.io / kubernetes -dashboard-amd64:v1.10.1 修改为 $registry-URL/kubernetes-dashboard-amd64:v1.10.1, 此处的 registry-URL 变量需要替换为你所创建的 registry 的值,或者可以在控制台获取到:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-13
比如本次操作的值为 pocexam-cn-north- 1.jcr.service. jdcloud. com /kubernetes-dashboard-amd64 ,那么操作命令如下:

复制代码
1docker tag mirrorgooglecontainers/kubernetes-dashboard-amd64:v1 .10 .1 pocexam-cn-north -1.jcr.service.jdcloud.com/kubernetes-dashboard-amd64:v1 .10 .1 && docker push !$

修改 tag 并成功上传至京东云镜像仓库的截图如下:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-14

在控制台可以验证到已成功上传:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-15

2.3 创建 Kubernetes 集群

2.3.1 创建 Kubernetes 所需的基础网络

首先创建 VPC:控制台–> 网络–> 私有网络 (VPC)
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-16

划分子网:控制台–> 网络–> 子网
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-17

创建 Kubernetes 集群,控制台–> 弹性计算–>Kubernetes 集群

注意需要选择 AK,修改 node 节点的 CIDR, 避免与集群中的 service、pod 冲突。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-18

京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-19

点击确认后,等待若干分钟,集群创建成功,目前支持的版本为 1.12.3。

2.4 云主机 Kubernetes 客户端配置

在 Linux 云主机上,执行如下 shell 命令:

复制代码
1wget https: //pocexam.s3.cn-north-1.jdcloud-oss.com/kubernetes-client-linux-amd64.tar.gz
2tar zxvf kubernetes-client-linux-amd64.tar.gz && cd kubernetes /client/bin/
3chmod +x kubectl && sudo mv . /kubectl /usr /local/bin/kubectl

2.5 配置集群凭证

在 Linux 云主机执行如下 shell 命令,创建相关配置文件,并将 Kubernetes 的连接信息写入 config 文件,保存退出:

复制代码
1mkdir -p ~/.kube && vi ~/.kube /config

连接信息获取方式为:控制台–> 弹性计算–>Kubernetes 集群,点击创建的 Kubernetes 集群名称。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-20

京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-21

将文本框中的内容保存至~/.kube/config 文件中。然后执行 kubectl version 命令,显示如下信息表示连接成功:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-22

3. Kubernetes 集群集成京东云镜像仓库

参考帮助文档链接

3.1 创建具有时效性的 secret

在 Linux 云主机 shell 中操作:

复制代码
1kubectl create secret docker-registry my-secret -n kube-system --docker-server=pocexam-cn-north-1.jcr.service.jdcloud.com --docker-username=jdcloud --docker-password=z7G4sQTHMaNG0GRN --docker-email=chengchen3@jd.com

需要注意如下参数的值:

  • docker-server:你创建的镜像仓库的注册表 URL。
  • docker-username:默认 jdcloud,无需修改。
  • docker-password:在临时令牌中获取,详情参考下图(获取 secret 所需的临时密码)。
  • docker-email:用户自定义邮箱。
  • -n 参数,默认为 default namespace,本次部署绑定到 kube-system。未来 yaml 配置文件中,你要创建 pod 或者 deployment 所在的 namesapce,必须与本次创建的 secret 所在的 namesapce 保证一直,否则会出现 ErrImagePullw 的问题。

3.1.1 获取 secret 所需的临时密码

在镜像仓库中选择注册表,点击获取临时令牌:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-23

红框中标识的内容即临时密码。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-24

3.2 自动定期获取临时令牌,长期有效

shell 中执行如下命令:

复制代码
1#创建相关基于角色的访问控制(RBAC)
2kubectl apply -f https: //pocexam.s3.cn-north-1.jdcloud-oss.com/jcr-credential-rbac.yaml

下载 jcr-credential-cron.yaml 文件,设定每一个小时获取临时令牌,请使用时添加 JDCLOUD_ACCESS_KEY 和 JDCLOUD_SECRET_KEY 内容。

复制代码
1 cd ~
2wget http s://pocexam.s3. cn-north- 1.jdcloud-oss. com/jcr-credential-cron.yaml

修改部分变量的值:

复制代码
1apiVersion: batch/v1beta1
2kind: CronJob
3metadata:
4 name: jdcloud-jcr-credential-cron
5spec:
6 schedule: "0 */1 * * *" # 0 代表每小时的整点,您可以根据需要修改时间,如改成 15 代表每小时的第 15 分钟获取临时令牌。
7 successfulJobsHistoryLimit: 2
8 failedJobsHistoryLimit: 2
9 jobTemplate:
10 spec:
11 backoffLimit: 4
12 template:
13 spec:
14 serviceAccountName: default
15 terminationGracePeriodSeconds: 0
16 restartPolicy: Never
17 hostNetwork: true
18 containers:
19 - name: jcr-token- refresher
20 imagePullPolicy: Always
21 image: jdcloudcli/jdcloud-cli:latest
22 command:
23 - "/bin/sh"
24 - "-c"
25 - |
26 ##REGISTRY_NAME 变量需要修改为你的的镜像仓库注册表的名称
27 REGISTRY_NAME=XXX
28 ##JCR_REGION 变量需要修改为你的镜像仓库所在的 region
29 JCR_REGION=cn-north -1
30 DOCKER_REGISTRY_SERVER=https: //${REGISTRY_NAME}-${JCR_REGION}.jcr.service.jdcloud.com
31 DOCKER_USER=jdcloud
32 ##JDCLOUD_ACCESS_KEY 和 JDCLOUD_SECRET_KEY 需要修改为你的 pin 的 AK、SK 的值
33 JDCLOUD_ACCESS_KEY=xxxxxxxxxxxxxx
34 JDCLOUD_SECRET_KEY=xxxxxxxxxxxxx
35 jdc configure add --profile ${DOCKER_USER} --access-key ${JDCLOUD_ACCESS_KEY} --secret-key ${JDCLOUD_SECRET_KEY}
36 PRECHECK=`jdc cr get-authorization-token --region-id ${JCR_REGION} --registry-name ${REGISTRY_NAME} |jq .result.authorizationToken`
37 if [ 'null' = "$PRECHECK" ]; then
38 echo "jdc cr call failed no valid content"
39 exit 0
40 else
41 echo "jdc cr call return authentication string"
42 fi;
43 DOCKER_PASSWORD=`echo ${PRECHECK} | base64 -d |cut -d ':' -f2`
44 kubectl delete secret my-secret || true
45 echo "0:"$PRECHECK
46 echo "1:"$DOCKER_REGISTRY_SERVER
47 echo "2:"$DOCKER_USER
48 echo "3:"$DOCKER_PASSWORD46/ 15555780261891.jpg)
49
50
51
52
53
54
55
56
57
58 kubectl create secret docker-registry my-secret \
59 --docker-server=$DOCKER_REGISTRY_SERVER \
60 --docker-username=$DOCKER_USER \
61 --docker-password=$DOCKER_PASSWORD \
62 ##docker-email 修改为你的邮箱地址
63 --docker-email= xxxx@jd.com
64 kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"my-secret"}]}' # kubectl patch $SERVICEACCOUNT xxxxx -n $NAMESPACEOFSERVICEACCOUNT

变量修改完成后,shell 中执行如下命令,创建 Kubernetes 的计划任务:

复制代码
1kubectl apply -f jcr-credential-cron .yaml

4. 部署 dashboard

在 Linux 云主机中执行如下命令,下载 dashboard 相关 yaml 配置文件:

复制代码
1wget http s://pocexam.s3. cn-north- 1.jdcloud-oss. com/db.yml

需要修改镜像地址为之前上传的 Kubernetes-dashboard 地址:

复制代码
1 # Copyright 2017 The Kubernetes Authors.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # ------------------- Dashboard Secret ------------------- #
16
17 apiVersion: v1
18 kind: Secret
19 metadata:
20 labels:
21 k8s-app: kubernetes-dashboard
22 name: kubernetes-dashboard-certs
23 namespace: kube-system
24 type: Opaque
25
26 ---
27 # ------------------- Dashboard Service Account ------------------- #
28
29 apiVersion: v1
30 kind: ServiceAccount
31 metadata:
32 labels:
33 k8s-app: kubernetes-dashboard
34 name: kubernetes-dashboard
35 namespace: kube-system
36
37 ---
38 # ------------------- Dashboard Role & Role Binding ------------------- #
39
40 kind: Role
41 apiVersion: rbac.authorization.k8s.io/v1
42 metadata:
43 name: kubernetes-dashboard-minimal
44 namespace: kube-system
45 rules:
46 # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
47 - apiGroups: [""]
48 resources: ["secrets"]
49 verbs: ["create"]
50 # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
51 - apiGroups: [""]
52 resources: ["configmaps"]
53 verbs: ["create"]
54 # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
55 - apiGroups: [""]
56 resources: ["secrets"]
57 resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs" ]
58 verbs: ["get", "update" , "delete" ]
59 # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
60 - apiGroups: [""]
61 resources: ["configmaps"]
62 resourceNames: ["kubernetes-dashboard-settings"]
63 verbs: ["get", "update" ]
64 # Allow Dashboard to get metrics from heapster.
65 - apiGroups: [""]
66 resources: ["services"]
67 resourceNames: ["heapster"]
68 verbs: ["proxy"]
69 - apiGroups: [""]
70 resources: ["services/proxy"]
71 resourceNames: ["heapster", "http:heapster:" , "https:heapster:" ]
72 verbs: ["get"]
73
74 ---
75 apiVersion: rbac.authorization.k8s.io/v1
76 kind: RoleBinding
77 metadata:
78 name: kubernetes-dashboard-minimal
79 namespace: kube-system
80 roleRef:
81 apiGroup: rbac.authorization.k8s.io
82 kind: Role
83 name: kubernetes-dashboard-minimal
84 subjects:
85 - kind: ServiceAccount
86 name: kubernetes-dashboard
87 namespace: kube-system
88
89 ---
90 # ------------------- Dashboard Deployment ------------------- #
91
92 kind: Deployment
93 apiVersion: apps/v1
94 metadata:
95 labels:
96 k8s-app: kubernetes-dashboard
97 name: kubernetes-dashboard
98 namespace: kube-system
99 spec:
100 replicas: 1
101 revisionHistoryLimit: 10
102 selector:
103 matchLabels:
104 k8s-app: kubernetes-dashboard
105 template:
106 metadata:
107 labels:
108 k8s-app: kubernetes-dashboard
109 spec:
110 containers:
111 - name: kubernetes-dashboard
112 ##此处修改为你之前上传到镜像仓库的 dashboard 地址
113 image: Myregistry-cn-north-1.jcr.service.jdcloud.com/kubernetes-dashboard-amd64:v1.10.1
114 ports:
115 - containerPort: 8443
116 protocol: TCP
117 args:
118 - --auto-generate-certificates
119 # Uncomment the following line to manually specify Kubernetes API server Host
120 # If not specified, Dashboard will attempt to auto discover the API server and connect
121 # to it. Uncomment only if the default does not work.
122 # - --apiserver-host=http://my-address:port
123 volumeMounts:
124 - name: kubernetes-dashboard-certs
125 mountPath: /certs
126 # Create on-disk volume to store exec logs
127 - mountPath: /tmp
128 name: tmp-volume
129 livenessProbe:
130 httpGet:
131 scheme: HTTPS
132 path: /
133 port: 8443
134 initialDelaySeconds: 30
135 timeoutSeconds: 30
136 volumes:
137 - name: kubernetes-dashboard-certs
138 secret:
139 secretName: kubernetes-dashboard-certs
140 - name: tmp-volume
141 emptyDir: {}
142 serviceAccountName: kubernetes-dashboard
143 imagePullSecrets:
144 - name: my-secret
145 # Comment the following tolerations if Dashboard must not be deployed on master
146 tolerations:
147 - key: node-role.kubernetes.io/master
148 effect: NoSchedule
149
150 ---
151 # ------------------- Dashboard Service ------------------- #
152 # ------------------- 此处设置在京东云自动创建 LB 并绑定带宽为 10Mbps 的公网 IP------------------- #
153 kind: Service
154 apiVersion: v1
155 metadata:
156 name: dashboard-lb
157 namespace: kube-system
158 labels:
159 k8s-app: kubernetes-dashboard
160 spec:
161 ports:
162 - protocol: TCP
163 port: 9443
164 targetPort: 8443
165 nodePort: 30063
166 type: LoadBalancer
167 selector:
168 k8s-app: kubernetes-dashboard

shell 中创建 Kubernetes deployment:

复制代码
1kubectl apply -f db .yml

查看集群中所有的 service:

复制代码
1kubectl get svc --all-namespaces

可以看到正在创建 LB 对应的公网 IP:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-25

稍等 1 分钟左右再查看,可以看到 LB 已绑定公网 IP:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-26

查看所有 namespace 的 pod,可以看到已成功 pull:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-27

5. 访问 dashboard

使用 Chrome 或者 Firefox 浏览器访问 service 所绑定的公网 IP 以及对应端口,本次实验中访问,会看到如下信息:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-28

本次访问我们使用令牌访问全部权限。认证时的账号必须为 ServiceAccount,被 dashboard 的 pod 拿来由 kubernetes 进行认证。

5.1 创建 ServiceAccount

复制代码
1kubectl create serviceaccount dashboard- admin -n kube- system

5.2 绑定相关 Role

复制代码
1kubectl create clusterrolebinding dashboard- cluster-admin --clusterrole= cluster-admin --serviceaccount=kube- system:dashboard-admin

相关参数:

  • clusterrole:指定使用的集群角色,系统默认自带很多,建议指定。
  • serviceaccount:指定认证使用的 ServiceAccount,由上一步创建。

5.3 获取 Secret

复制代码
1kubectl describe sa dashboard- admin -n kube- system

京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-29

由此可知,本例中 dashboard-admin-token-wf2tj 为使用的 Secret。

5.4 获取 Token

执行 shell 命令查看对应 secret 相关信息:

复制代码
1kubectl describe secrets -n kube- system dashboard- admin-token-wf2tj

下图中获取到的 token 即访问凭证。
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-30

将其复制粘贴到浏览器中即可登录成功:
京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-31京东云托管Kubernetes集成镜像仓库并部署原生DashBoard-InfoQ-32

文章评论