mirror of https://github.com/k3s-io/k3s
Merge pull request #73447 from MikeSpreitzer/sample-apiserver-doc-build
Document how to build and deploy the sample-apiserverk3s-v1.15.3
commit
9577cbfb9f
|
@ -24,6 +24,109 @@ HEAD of this repo will match HEAD of k8s.io/apiserver, k8s.io/apimachinery, and
|
||||||
`sample-apiserver` is synced from https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/sample-apiserver.
|
`sample-apiserver` is synced from https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/sample-apiserver.
|
||||||
Code changes are made in that location, merged into `k8s.io/kubernetes` and later synced here.
|
Code changes are made in that location, merged into `k8s.io/kubernetes` and later synced here.
|
||||||
|
|
||||||
|
## Fetch sample-apiserver and its dependencies
|
||||||
|
|
||||||
|
Like the rest of Kubernetes, sample-apiserver has used
|
||||||
|
[godep](https://github.com/tools/godep) and `$GOPATH` for years and is
|
||||||
|
now adopting go 1.11 modules. There are thus two alternative ways to
|
||||||
|
go about fetching this demo and its dependencies.
|
||||||
|
|
||||||
|
### Fetch with godep
|
||||||
|
|
||||||
|
When NOT using go 1.11 modules, you can use the following commands.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get -d k8s.io/sample-apiserver
|
||||||
|
cd $GOPATH/src/k8s.io/sample-apiserver # assuming your GOPATH has just one entry
|
||||||
|
godep restore
|
||||||
|
```
|
||||||
|
|
||||||
|
### When using go 1.11 modules
|
||||||
|
|
||||||
|
When using go 1.11 modules (`GO111MODULE=on`), issue the following
|
||||||
|
commands --- starting in whatever working directory you like.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/kubernetes/sample-apiserver.git
|
||||||
|
cd sample-apiserver
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, however, that if you intend to
|
||||||
|
[generate code](#changes-to-the-types) then you will also need the
|
||||||
|
code-generator repo to exist in an old-style location. One easy way
|
||||||
|
to do this is to use the command `go mod vendor` to create and
|
||||||
|
popdulate the `vendor` directory.
|
||||||
|
|
||||||
|
### A Note on kubernetes/kubernetes
|
||||||
|
|
||||||
|
If you are developing Kubernetes according to
|
||||||
|
https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md
|
||||||
|
then you already have a copy of this demo in
|
||||||
|
`kubernetes/staging/src/k8s.io/sample-apiserver` and its dependencies
|
||||||
|
--- including the code generator --- are in usable locations.
|
||||||
|
|
||||||
|
|
||||||
|
## Normal Build and Deploy
|
||||||
|
|
||||||
|
### Changes to the Types
|
||||||
|
|
||||||
|
If you change the API object type definitions in any of the
|
||||||
|
`pkg/apis/.../types.go` files then you will need to update the files
|
||||||
|
generated from the type definitions. To do this, first
|
||||||
|
[create the vendor directory if necessary](#when-using-go-111-modules)
|
||||||
|
and then invoke `hack/update-codegen.sh` with `sample-apiserver` as
|
||||||
|
your current working directory; the script takes no arguments.
|
||||||
|
|
||||||
|
### Authentication plugins
|
||||||
|
|
||||||
|
The normal build supports only a very spare selection of
|
||||||
|
authentication methods. There is a much larger set available in
|
||||||
|
https://github.com/kubernetes/client-go/tree/master/plugin/pkg/client/auth
|
||||||
|
. If you want your server to support one of those, such as `oidc`,
|
||||||
|
then add an import of the appropriate package to
|
||||||
|
`sample-apiserver/main.go`. Here is an example:
|
||||||
|
|
||||||
|
``` go
|
||||||
|
import _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively you could add support for all of them, with an import
|
||||||
|
like this:
|
||||||
|
|
||||||
|
``` go
|
||||||
|
import _ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build the Binary
|
||||||
|
|
||||||
|
With `sample-apiserver` as your current working directory, issue the
|
||||||
|
following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o artifacts/simple-image/kube-sample-apiserver
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build the Container Image
|
||||||
|
|
||||||
|
With `sample-apiserver` as your current working directory, issue the
|
||||||
|
following commands with `MYPREFIX` and `MYTAG` replaced by something
|
||||||
|
suitable.
|
||||||
|
|
||||||
|
```
|
||||||
|
docker build -t MYPREFIX/kube-sample-apiserver:MYTAG ./artifacts/simple-image
|
||||||
|
docker push MYPREFIX/kube-sample-apiserver:MYTAG
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deploy into a Kubernetes Cluster
|
||||||
|
|
||||||
|
Edit `artifacts/example/rc.yaml`, updating the pod template's image
|
||||||
|
reference to match what you pushed and setting the `imagePullPolicy`
|
||||||
|
to something suitable. Then call:
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl apply -f artifacts/example
|
||||||
|
```
|
||||||
|
|
||||||
## Running it stand-alone
|
## Running it stand-alone
|
||||||
|
|
||||||
During development it is helpful to run sample-apiserver stand-alone, i.e. without
|
During development it is helpful to run sample-apiserver stand-alone, i.e. without
|
||||||
|
@ -40,48 +143,63 @@ only this superuser group is authorized.
|
||||||
|
|
||||||
1. First we need a CA to later sign the client certificate:
|
1. First we need a CA to later sign the client certificate:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
openssl req -nodes -new -x509 -keyout ca.key -out ca.crt
|
openssl req -nodes -new -x509 -keyout ca.key -out ca.crt
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Then we create a client cert signed by this CA for the user `development` in the superuser group
|
2. Then we create a client cert signed by this CA for the user `development` in the superuser group
|
||||||
`system:masters`:
|
`system:masters`:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
openssl req -out client.csr -new -newkey rsa:4096 -nodes -keyout client.key -subj "/CN=development/O=system:masters"
|
openssl req -out client.csr -new -newkey rsa:4096 -nodes -keyout client.key -subj "/CN=development/O=system:masters"
|
||||||
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
|
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
|
||||||
```
|
```
|
||||||
|
|
||||||
3. As curl requires client certificates in p12 format with password, do the conversion:
|
3. As curl requires client certificates in p12 format with password, do the conversion:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
openssl pkcs12 -export -in ./client.crt -inkey ./client.key -out client.p12 -passout pass:password
|
openssl pkcs12 -export -in ./client.crt -inkey ./client.key -out client.p12 -passout pass:password
|
||||||
```
|
```
|
||||||
|
|
||||||
4. With these keys and certs in-place, we start the server:
|
4. With these keys and certs in-place, we start the server:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
etcd &
|
etcd &
|
||||||
sample-apiserver --secure-port 8443 --etcd-servers http://127.0.0.1:2379 --v=7 \
|
sample-apiserver --secure-port 8443 --etcd-servers http://127.0.0.1:2379 --v=7 \
|
||||||
--client-ca-file ca.crt \
|
--client-ca-file ca.crt \
|
||||||
--kubeconfig ~/.kube/config \
|
--kubeconfig ~/.kube/config \
|
||||||
--authentication-kubeconfig ~/.kube/config \
|
--authentication-kubeconfig ~/.kube/config \
|
||||||
--authorization-kubeconfig ~/.kube/config
|
--authorization-kubeconfig ~/.kube/config
|
||||||
```
|
```
|
||||||
|
|
||||||
The first kubeconfig is used for the shared informers to access Kubernetes resources. The second kubeconfig passed to `--authentication-kubeconfig` is used to satisfy the delegated authenticator. The third kubeconfig passed to `--authorized-kubeconfig` is used to satisfy the delegated authorizer. Neither the authenticator, nor the authorizer will actually be used: due to `--client-ca-file`, our development X.509 certificate is accepted and authenticates us as `system:masters` member. `system:masters` is the superuser group
|
The first kubeconfig is used for the shared informers to access
|
||||||
such that delegated authorization is skipped.
|
Kubernetes resources. The second kubeconfig passed to
|
||||||
|
`--authentication-kubeconfig` is used to satisfy the delegated
|
||||||
|
authenticator. The third kubeconfig passed to
|
||||||
|
`--authorized-kubeconfig` is used to satisfy the delegated
|
||||||
|
authorizer. Neither the authenticator, nor the authorizer will
|
||||||
|
actually be used: due to `--client-ca-file`, our development X.509
|
||||||
|
certificate is accepted and authenticates us as `system:masters`
|
||||||
|
member. `system:masters` is the superuser group such that delegated
|
||||||
|
authorization is skipped.
|
||||||
|
|
||||||
5. Use curl to access the server using the client certificate in p12 format for authentication:
|
5. Use curl to access the server using the client certificate in p12 format for authentication:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
curl -fv -k --cert client.p12:password \
|
curl -fv -k --cert client.p12:password \
|
||||||
https://localhost:8443/apis/wardle.k8s.io/v1alpha1/namespaces/default/flunders
|
https://localhost:8443/apis/wardle.k8s.io/v1alpha1/namespaces/default/flunders
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or use wget:
|
||||||
|
``` shell
|
||||||
|
wget -O- --no-check-certificate \
|
||||||
|
--certificate client.crt --private-key client.key \
|
||||||
|
https://localhost:8443/apis/wardle.k8s.io/v1alpha1/namespaces/default/flunders
|
||||||
|
```
|
||||||
|
|
||||||
Note: Recent OSX versions broke client certs with curl. On Mac try `brew install httpie` and then:
|
Note: Recent OSX versions broke client certs with curl. On Mac try `brew install httpie` and then:
|
||||||
|
|
||||||
``` shell
|
``` shell
|
||||||
http --verify=no --cert client.crt --cert-key client.key \
|
http --verify=no --cert client.crt --cert-key client.key \
|
||||||
https://localhost:8443/apis/wardle.k8s.io/v1alpha1/namespaces/default/flunders
|
https://localhost:8443/apis/wardle.k8s.io/v1alpha1/namespaces/default/flunders
|
||||||
```
|
```
|
||||||
|
|
|
@ -25,13 +25,13 @@ CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-
|
||||||
# --output-base because this script should also be able to run inside the vendor dir of
|
# --output-base because this script should also be able to run inside the vendor dir of
|
||||||
# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
|
# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir
|
||||||
# instead of the $GOPATH directly. For normal projects this can be dropped.
|
# instead of the $GOPATH directly. For normal projects this can be dropped.
|
||||||
"${CODEGEN_PKG}/generate-groups.sh" all \
|
bash "${CODEGEN_PKG}/generate-groups.sh" all \
|
||||||
k8s.io/sample-apiserver/pkg/generated k8s.io/sample-apiserver/pkg/apis \
|
k8s.io/sample-apiserver/pkg/generated k8s.io/sample-apiserver/pkg/apis \
|
||||||
"wardle:v1alpha1,v1beta1" \
|
"wardle:v1alpha1,v1beta1" \
|
||||||
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
||||||
--go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt
|
--go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt
|
||||||
|
|
||||||
"${CODEGEN_PKG}/generate-internal-groups.sh" "deepcopy,defaulter,conversion" \
|
bash "${CODEGEN_PKG}/generate-internal-groups.sh" "deepcopy,defaulter,conversion" \
|
||||||
k8s.io/sample-apiserver/pkg/generated k8s.io/sample-apiserver/pkg/apis k8s.io/sample-apiserver/pkg/apis \
|
k8s.io/sample-apiserver/pkg/generated k8s.io/sample-apiserver/pkg/apis k8s.io/sample-apiserver/pkg/apis \
|
||||||
"wardle:v1alpha1,v1beta1" \
|
"wardle:v1alpha1,v1beta1" \
|
||||||
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
--output-base "$(dirname "${BASH_SOURCE[0]}")/../../.." \
|
||||||
|
|
Loading…
Reference in New Issue