Secret 是 Kubernetes 内的一种资源类型,可以用它来存放一些机密信息(密码,token,密钥等)。信息被存入后,我们可以使用挂载卷的方式挂载进我们的 Pod 内。当然也可以存放docker私有镜像库的登录名和密码,用于拉取私有镜像。
Opaque 类型一般拿来存放密码,密钥等信息,存储格式为 base64。我们可以通过命令行和配置文件两种方式来创建Secret资源。
kubectl create secret generic mysql-account --from-literal=username=zaking--from-literal=password=123456
kubectl get secret
//编辑值 kubectl edit secret account //输出yaml格式 kubectl get secret account -o yaml //输出json格式 kubectl get secret account -o json //对Base64进行解码 echo MTIzNDU2 | base64 -d
创建一个mysql-account.yml文件:
apiVersion: v1 kind: Secret metadata: name: mysql-account stringData: username: root password: root type: Opaque
然后:
kubectl apply -f mysql-account.yaml secret/mysql-account created kubectl get secret mysql-account -o yaml
kubectl create secret docker-registry private-registry \ --docker-username=[用户名] \ --docker-password=[密码] \ --docker-email=[邮箱] \ --docker-server=[私有镜像库地址] //查看私有库密钥组 kubectl get secret private-registry -o yaml echo [value] | base64 -d
vi private-registry-file.yaml
apiVersion: v1 kind: Secret metadata: name: private-registry-file data: .dockerconfigjson: eyJhdXRocyI6eyJodHRwczo type: kubernetes.io/dockerconfigjson
kubectl apply -f ./private-registry-file.yaml kubectl get secret private-registry-file -o yaml
通过存储卷的方式挂载进去,添加文件并书写内容如下:
apiVersion: apps/v1 #API 配置版本 kind: Deployment #资源类型 metadata: name: user-v1 #资源名称 spec: minReadySeconds: 1 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: user-v1 #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值 + replicas: 1 #声明一个 Pod,副本的数量 template: metadata: labels: app: user-v1 #Pod的名称 spec: #组内创建的 Pod 信息 + volumes: + - name: mysql-account + secret: + secretName: mysql-account containers: - name: nginx #容器的名称 image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像 + volumeMounts: + - name: mysql-account + mountPath: /mysql-account + readOnly: true ports: - containerPort: 80 #容器内映射的端口
执行命令:
kubectl describe pods user-v1-b88799944-tjgrs kubectl exec -it user-v1-b88799944-tjgrs -- ls /root
修改之前的deployment-user-v1.yaml文件:
apiVersion: apps/v1 #API 配置版本 kind: Deployment #资源类型 metadata: name: user-v1 #资源名称 spec: minReadySeconds: 1 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: user-v1 #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值 replicas: 1 #声明一个 Pod,副本的数量 template: metadata: labels: app: user-v1 #Pod的名称 spec: #组内创建的 Pod 信息 volumes: - name: mysql-account secret: secretName: mysql-account containers: - name: nginx #容器的名称 + env: + - name: USERNAME + valueFrom: + secretKeyRef: + name: mysql-account + key: username + - name: PASSWORD + valueFrom: + secretKeyRef: + name: mysql-account + key: password image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像 volumeMounts: - name: mysql-account mountPath: /mysql-account readOnly: true ports: - containerPort: 80 #容器内映射的端口
然后:
kubectl apply -f deployment-user-v1.yaml kubectl get pods kubectl describe pod user-v1-5f48f78d86-hjkcl kubectl exec -it user-v1-688486759f-9snpx -- env | grep USERNAME
这种方法只能用来配置私有镜像库认证。添加文件,vi v4.yaml:
image: [仅有镜像库地址]/[镜像名称]:[镜像标签]
kubectl apply -f v4.yaml kubectl get pods kubectl describe pods [POD_NAME]
+imagePullSecrets: + - name: private-registry-file containers: - name: nginx
kubectl apply -f v4.yaml
服务发现是指使用一个注册中心来记录分布式系统中的全部服务的信息,以便其他服务能够快速的找到这些已注册的服务。
Pod 的 IP 常常是漂移且不固定的,所以我们要使用 Service 这个神器来将它的访问入口固定住。可以利用 DNS 的机制给每个 Service 加一个内部的域名,指向其真实的IP。在Kubernetes中,对 Service 的服务发现,是通过一种叫做 CoreDNS 的组件去实现的。
coreDNS 是使用 Go 语言实现的一个DNS服务器
kubectl -n kube-system get all -l k8s-app=kube-dns -o wide
kubectl exec 的作用是可以直接在容器内执行Shell脚本
kubectl exec -it [PodName] -- [Command]
kubectl get pods kubectl get svc kubectl exec -it user-v1-688486759f-9snpx -- /bin/sh curl http://service-user-v2
kubernetes namespace(命名空间)是 kubernetes 里比较重要的一个概念。在启动集群后,kubernetes 会分配一个默认命名空间,叫default。不同的命名空间可以实现资源隔离,服务隔离,甚至权限隔离。因为我们在之前创建的服务,都没有指定 namespace ,所以我们的服务都是在同一个 namespace default下。在同 namespace 下的规则,我们只需要直接访问 http://ServiceName:Port 就可以访问到相应的 Service。不同 namespace 下的规则是 [ServiceName].[NameSpace].svc.cluster.local。
ServiceName 就是我们创建的 Service 名称,NameSpace 则是命名空间。如果你没有命名空间,则这个值为 default。
curl http://service-user-v2.default.svc.cluster.local
Kubernetes Secret 的主要作用是来存放密码,密钥等机密信息。对于环境变量的配置:例如你的数据库地址,负载均衡要转发的服务地址等信息。这部分内容使用 Secret 显然不合适,打包在镜像内耦合又太严重。这里,我们可以借助 Kubernetes ConfigMap 来配置这项事情。ConfigMap 是 Kubernetes 的一种资源类型,我们可以使用它存放一些环境变量和配置文件。信息存入后,我们可以使用挂载卷的方式挂载进我们的 Pod 内,也可以通过环境变量注入。和 Secret 类型最大的不同是,存在 ConfigMap 内的内容不会加密。
创建的方式有很多种,我们下面来一一试一下:
kubectl create configmap [config_name] --from-literal=[key]=[value]
kubectl create configmap mysql-config --from-literal=MYSQL_HOST=192.168.1.172 --from-literal=MYSQL_PORT=3306
需要注意,configmap 的名称必须是全小写,特殊符号只能包含 '-' 和 '.'。可以用下面的这个正则表达式校验下看看符不符合规则:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')。
kubectl get cm kubectl describe cm mysql-config
创建一个mysql-config-file.yaml文件:
apiVersion: v1 kind: ConfigMap metadata: name: mysql-config-file data: MYSQL_HOST: "192.168.1.172" MYSQL_PORT: "3306"
kubectl apply -f ./mysql-config-file.yaml kubectl describe cm mysql-config-file
kubectl create configmap [configname] --from-file=[key]=[file_path]
--from-file
代表一个文件key
是文件在 configmap
内的 keyfile_path
是文件的路径添加env.config文件:
HOST: 192.168.0.1 PORT: 8080
kubectl create configmap env-from-file --from-file=env=./env.config configmap/env-from-file created kubectl get cm env-from-file -o yaml
也可以直接将一个目录下的文件整个存入进去。
kubectl create configmap [configname] --from-file=[dir_path] mkdir env && cd ./env echo 'local' > env.local echo 'test' > env.test echo 'prod' > env.prod kubectl create configmap env-from-dir --from-file=./ kubectl get cm env-from-dir -o yaml
containers: - name: nginx #容器的名称 + env: + - name: MYSQL_HOST + valueFrom: + configMapKeyRef: + name: mysql-config + key: MYSQL_HOST
kubectl apply -f ./v1.yaml
//kubectl exec -it [POD_NAME] -- env | grep MYSQL_HOST kubectl exec -it user-v1-744f48d6bd-9klqr -- env | grep MYSQL_HOST kubectl exec -it user-v1-744f48d6bd-9klqr -- env | grep MYSQL_PORT
containers: - name: nginx #容器的名称 env: + envFrom: + - configMapRef: + name: mysql-config + optional: true image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像 volumeMounts: - name: mysql-account mountPath: /mysql-account readOnly: true ports: - containerPort: 80 #容器内映射的端口
存储卷挂载会将 configmap 里内容中的每个 key 和 value,以独立文件方式以外部挂载卷方式挂载进去( key 是文件名,value 是文件内容)。
template: metadata: labels: app: user-v1 #Pod的名称 spec: #组内创建的 Pod 信息 volumes: - name: mysql-account secret: secretName: mysql-account + - name: envfiles + configMap: + name: env-from-dir containers: - name: nginx #容器的名称 env: - name: USERNAME valueFrom: secretKeyRef: name: mysql-account key: username - name: PASSWORD valueFrom: secretKeyRef: name: mysql-account key: password envFrom: - configMapRef: name: mysql-config optional: true image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像 volumeMounts: - name: mysql-account mountPath: /mysql-account readOnly: true + - name: envfiles + mountPath: /envfiles + readOnly: true ports: - containerPort: 80 #容器内映射的端口
kubectl apply -f deployment-user-v1.yaml kubectl get pods kubectl describe pod user-v1-79b8768f54-r56kd kubectl exec -it user-v1-744f48d6bd-9klqr -- ls /envfiles
可以借助 volumes.configMap.items[] 字段来配置多个 item 项。
spec: #组内创建的 Pod 信息 volumes: - name: mysql-account secret: secretName: mysql-account - name: envfiles configMap: name: env-from-dir + items: + - key: env.local + path: env.local
key=value
,可以自定义自己的内容,就像是一组 Tag 一样kubectl taint nodes [Node_Name] [key]=[value]:NoSchedule //添加污点 kubectl taint nodes node1 user-v4=true:NoSchedule //查看污点 kubectl describe node node1 kubectl describe node master Taints: node-role.kubernetes.io/master:NoSchedule
vi deployment-user-v4.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: user-v4 spec: minReadySeconds: 1 selector: matchLabels: app: user-v4 replicas: 1 template: metadata: labels: app: user-v4 spec: containers: - name: nginx image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 ports: - containerPort: 80
kubectl apply -f deployment-user-v4.yaml
vi deployment-user-v4.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: user-v4 spec: minReadySeconds: 1 selector: matchLabels: app: user-v4 replicas: 1 template: metadata: labels: app: user-v4 spec: + tolerations: + - key: "user-v4" + operator: "Equal" + value: "true" + effect: "NoSchedule" containers: - name: nginx image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 ports: - containerPort: 80
# 修改Node污点 kubectl taint nodes node1 user-v4=1:NoSchedule --overwrite
# 删除Node污点 kubectl taint nodes node1 user-v4-
# 在Master上部署pod kubectl taint nodes node1 user-v4=true:NoSchedule kubectl describe node node1 kubectl describe node master
vi deployment-user-v4.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: user-v4 spec: minReadySeconds: 1 selector: matchLabels: app: user-v4 replicas: 1 template: metadata: labels: app: user-v4 spec: + tolerations: + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" containers: - name: nginx image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 ports: - containerPort: 80
kubectl apply -f deployment-user-v4.yaml