实践说明
在Kubernetes中添加一个普通用户,目前有两种通信方式,一种是外部认证,比如AD域管理,另外一种也是常用的TLS及数字证书的通信场景,后者是Kubernetes组件内部基本的安全通信方式。以下操作采用后者进行操作,为了简化操作,将证书和用户创建配置进行脚本化。
实践操作
1. 证书签署请求准备工作
$ cat bin/csr-gen.go
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"os"
)
func main() {
name := os.Args[1]
user := os.Args[2]
key, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
keyDer := x509.MarshalPKCS1PrivateKey(key)
keyBlock := pem.Block {
Type: "RSA PRIVATE KEY",
Bytes: keyDer,
}
keyFile, err := os.Create(name + "-key.pem")
if err != nil {
panic(err)
}
pem.Encode(keyFile, &keyBlock)
keyFile.Close()
//CN值,作为kubeconfig作为用户名使用,非常重要
commonName := user
emailAddress := "someone@myco.com"
//用户组
org := "kubernetes"
orgUnit := "kubernetes"
city := "GuangZhou"
state := "WA"
country := "CN"
subject := pkix.Name {
CommonName: commonName,
Country: []string{country},
Locality: []string{city},
Organization: []string{org},
OrganizationalUnit: []string{orgUnit},
Province: []string{state},
}
asn1, err := asn1.Marshal(subject.ToRDNSequence())
if err != nil {
panic(err)
}
csr := x509.CertificateRequest{
RawSubject: asn1,
EmailAddresses: []string{emailAddress},
SignatureAlgorithm: x509.SHA256WithRSA,
}
bytes, err := x509.CreateCertificateRequest(rand.Reader, &csr, key)
if err != nil {
panic(err)
}
csrFile, err := os.Create(name + ".csr")
if err != nil {
panic(err)
}
pem.Encode(csrFile, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes:bytes})
csrFile.Close()
}
$ cat bin/k8s-gen-cert.sh
#!/bin/bash
#向K8s发起证书申请请求名称
csr_name="my-client-usr"
#Kubeconfig 用户标识名称
name="${1:-lvzhiqiang}"
#证书申请文件
csr="${2}"
cat <<EOF | kubectl create -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: ${csr_name}
spec:
groups:
- system:authenticated
request: $(cat ${csr} | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- client auth
EOF
echo
echo "Approving signing request."
kubectl certificate approve ${csr_name}
echo
echo "Downloading certificate."
kubectl get csr ${csr_name} -o jsonpath='{.status.certificate}' \
| base64 --decode > $(basename ${csr} .csr).crt
echo
echo "Cleaning up"
kubectl delete csr ${csr_name}
echo
echo "Add the following to the 'users' list in your kubeconfig file:"
echo "- name: ${name}"
echo " user:"
echo " client-certficate: ${PWD}/$(basename ${csr} .csr).crt"
echo " client-key: ${PWD}/$(basename ${csr} .csr)-key.pem"
echo
echo "Next you may want to add role-binding for this user."
$ kubectl delete csr my-client-usr
$ go version
go version go1.15.7 linux/amd64
$ go run bin/csr-gen.go client lvzhiqiang
$ sh bin/k8s-gen-cert.sh lvzhiqiang client.csr
certificatesigningrequest.certificates.k8s.io/my-client-usr created
#同意签署请求
Approving signing request.
certificatesigningrequest.certificates.k8s.io/my-client-usr approved
#下载CRT证书文件
Downloading certificate.
Cleaning up
certificatesigningrequest.certificates.k8s.io "my-client-usr" deleted
Add the following to the 'users' list in your kubeconfig file:
- name: lvzhiqiang
user:
#客户端证书文件和Key
client-certficate: /root/create-k8s-user/client.crt
client-key: /root/create-k8s-user/client-key.pem
Next you may want to add role-binding for this user.
2. 配置Kubeconfig和命名空间
$ kubectl config set-credentials lvzhiqiang --client-key=/root/create-k8s-user/client-key.pem --client-certificate=/root/create-k8s-user/client.crt --embed-certs=true
$ kubectl config set-context lvzhiqiang --cluster=kubernetes --user=lvzhiqiang
$ ns="developer"
$ kubectl create namespace ${ns}
$ kubectl annotate namespace ${ns} annotation_key=annotation_value
3. 角色绑定
$ cat rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer
namespace: developer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: lvzhiqiang
$ kubectl apply -f rolebinding.yaml
4. 测试
$ kubectl run demo-dev01 --image=nginx:latest -n developer
$ kubectl config use-context lvzhiqiang
$ kubectl get pods -n developer #这里要指定命名空间,除非在kubeconfig配置的时候指定了默认命名空间
NAME READY STATUS RESTARTS AGE
demo-dev01 1/1 Running 0 21m
5. 补充
复制 /root/.kube/config 一份出来,然后将该文件里关于管理员的配置信息去掉,保留刚创建的普通用户信息,然后拷贝给其他开发用户使用。
实践参考资料
1.https://kubernetes.io/zh/docs/reference/access-authn-authz/certificate-signing-requests/
2.https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/#user-facing-roles3.《Kubernetes实战》