一、概述
有时候我们希望在 k8s 的 pod 中执行一些命令,但是又不想为了一个简单的功能去写代码调用 API,而是直接使用 kubectl 命令
二、制作 kubectl 镜像
FROM debian:bullseye
RUN apt-get update && apt-get install -y curl \
&& curl -Lo /usr/bin/kubectl https://dl.k8s.io/release/v1.20.15/bin/linux/amd64/kubectl \
&& chmod +x /usr/bin/kubectl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
docker build -t win7/kubectl:v1.20.15 .
三、配置 ServiceAccount 及其 RBAC 权限
一般情况下,我们是不期望 kubectl 拥有对 k8s 的所有权限的,而是指定其对某个 namespace 下的某些指定资源拥有权限。
比如我们希望执行 kubectl set image 命令来发布应用,那我们就希望对 deployment 有对应的修改权限, 下面我以 jenkins 为例,希望 jenkins 在构建结束之后,发布 namespace 为 gray 和 stable 下的 deployment app1
---
# 创建一个 sa ,用于发布应用
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-jenkins-release
namespace: jenkins
---
# 创建一个角色,拥有 对 pods、services、deployments 的操作权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: gray
name: role-jenkins-release
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
# 创建一个角色,拥有 对 pods、services、deployments 的操作权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: stable
name: role-jenkins-release
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
# 授予 sa 在 gray 下的权限
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rb-jenkins-release
namespace: gray
subjects:
- kind: ServiceAccount
name: sa-jenkins-release
namespace: jenkins
roleRef:
kind: Role
name: role-jenkins-release
apiGroup: rbac.authorization.k8s.io
---
# 授予 sa 在 stable 下的权限
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rb-jenkins-release
namespace: stable
subjects:
- kind: ServiceAccount
name: sa-jenkins-release
namespace: jenkins
roleRef:
kind: Role
name: role-jenkins-release
apiGroup: rbac.authorization.k8s.io
四、在 gray 和 stable 下创建一个 app1 用于测试
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
k8s.kuboard.cn/name: app1
name: app1
namespace: gray
resourceVersion: '31734'
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s.kuboard.cn/name: app1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
k8s.kuboard.cn/name: app1
spec:
containers:
- image: 'nginx:1.20.0'
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
五、创建一个 kubectl pod
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
k8s.kuboard.cn/name: kubectl
name: kubectl
namespace: jenkins
resourceVersion: '31857'
spec:
progressDeadlineSeconds: 600
replicas: 0
revisionHistoryLimit: 10
selector:
matchLabels:
k8s.kuboard.cn/name: kubectl
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
kubectl.kubernetes.io/restartedAt: '2023-06-18T13:42:43+08:00'
creationTimestamp: null
labels:
k8s.kuboard.cn/name: kubectl
spec:
automountServiceAccountToken: true
containers:
- command:
- tail
- '-f'
- /etc/hosts
image: 'win7/kubectl:v1.20.15'
imagePullPolicy: Always
name: c1
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: sa-jenkins-release
serviceAccountName: sa-jenkins-release
terminationGracePeriodSeconds: 30
这里我指定了 serviceAccount: sa-jenkins-release,这样在 pod 中执行 kubectl 命令时,就会使用 sa-jenkins-release 这个账号,而不是默认的 default 账号
六、在 kubeclt pod 中执行命令
kubectl get pod -n stable
kubectl -n stable set image deployment/app1 nginx=nginx:1.23.0 && kubectl -n stable rollout status deployment/app1